@@ -5,11 +5,13 @@ import { Blockchain } from '@ton/sandbox'
55
66import { FeeQuoterSetup , FeeQuoterFeeSetup , Token } from './FeeQuoterSetup'
77import * as feeQuoter from '../../../wrappers/ccip/FeeQuoter'
8+ import { ExtraArgs } from '../../../wrappers/ccip/Router'
89import * as sendExec from '../../../wrappers/ccip/CCIPSendExecutor'
910import * as rt from '../../../wrappers/ccip/Router'
1011import { asSnakeBytes , asSnakeData , ZERO_ADDRESS } from '../../../src/utils'
1112import { skip } from 'node:test'
1213import { verifyBodyMessage } from '../CCIPRouter.spec'
14+ import { create } from 'domain'
1315
1416describe ( 'FeeQuoter GetValidatedFee' , ( ) => {
1517 let setup : FeeQuoterFeeSetup
@@ -42,7 +44,7 @@ describe('FeeQuoter GetValidatedFee', () => {
4244 premiumMultiplierWeiPerEth
4345 const calldataLen = BigInt ( message . data . beginParse ( ) . remainingBits / 8 )
4446 const dataAvailabilityFeeUSD = await setup . bind . feeQuoter . getDataAvailabilityCost (
45- FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
47+ FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
4648 FeeQuoterSetup . USD_PER_DATA_AVAILABILITY_GAS ,
4749 calldataLen ,
4850 BigInt ( message . tokenAmounts . length ) ,
@@ -57,7 +59,7 @@ describe('FeeQuoter GetValidatedFee', () => {
5759
5860 it ( 'should handle zero data availability multiplier' , async ( ) => {
5961 const destChainConfig = await setup . bind . feeQuoter . getDestChainConfig (
60- FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
62+ FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
6163 )
6264 // Update dest chain config to set data availability multiplier to 0
6365 {
@@ -67,7 +69,7 @@ describe('FeeQuoter GetValidatedFee', () => {
6769 value : toNano ( '1' ) ,
6870 updates : [
6971 {
70- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
72+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
7173 config : {
7274 ...destChainConfig ,
7375 destDataAvailabilityMultiplierBps : 0 ,
@@ -110,7 +112,7 @@ describe('FeeQuoter GetValidatedFee', () => {
110112
111113 for ( const token of testTokens ) {
112114 const message : rt . CCIPSend = {
113- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
115+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
114116 receiver : FeeQuoterSetup . DEST_ADDRESS ,
115117 data : asSnakeBytes ( Buffer . alloc ( customDataSize ) ) ,
116118 tokenAmounts : [ ] ,
@@ -150,7 +152,7 @@ describe('FeeQuoter GetValidatedFee', () => {
150152 premiumMultiplierWeiPerEth
151153
152154 const dataAvailabilityFeeUSD = await setup . bind . feeQuoter . getDataAvailabilityCost (
153- FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
155+ FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
154156 FeeQuoterSetup . USD_PER_DATA_AVAILABILITY_GAS ,
155157 calldataLen ,
156158 BigInt ( message . tokenAmounts . length ) ,
@@ -166,7 +168,7 @@ describe('FeeQuoter GetValidatedFee', () => {
166168
167169 it ( 'should allow out of order execution when not enforced' , async ( ) => {
168170 const message : rt . CCIPSend = {
169- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
171+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
170172 receiver : FeeQuoterSetup . DEST_ADDRESS ,
171173 data : beginCell ( ) . endCell ( ) ,
172174 tokenAmounts : [ ] ,
@@ -188,7 +190,7 @@ describe('FeeQuoter GetValidatedFee', () => {
188190
189191 it ( 'should allow fail when allow out of order execution is false' , async ( ) => {
190192 const message : rt . CCIPSend = {
191- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
193+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
192194 receiver : FeeQuoterSetup . DEST_ADDRESS ,
193195 data : beginCell ( ) . endCell ( ) ,
194196 tokenAmounts : [ ] ,
@@ -209,7 +211,7 @@ describe('FeeQuoter GetValidatedFee', () => {
209211 } )
210212
211213 it ( 'should revert when destination chain not enabled' , async ( ) => {
212- const invalidChainSelector = FeeQuoterSetup . DEST_CHAIN_SELECTOR + 1n
214+ const invalidChainSelector = FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM + 1n
213215 const message : rt . CCIPSend = {
214216 destChainSelector : invalidChainSelector ,
215217 receiver : FeeQuoterSetup . DEST_ADDRESS ,
@@ -260,7 +262,7 @@ describe('FeeQuoter GetValidatedFee', () => {
260262
261263 it ( 'should revert when message too large' , async ( ) => {
262264 const message : rt . CCIPSend = {
263- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
265+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
264266 receiver : FeeQuoterSetup . DEST_ADDRESS ,
265267 data : asSnakeBytes ( Buffer . alloc ( FeeQuoterSetup . MAX_DATA_SIZE + 1 ) ) ,
266268 tokenAmounts : [ ] ,
@@ -310,7 +312,7 @@ describe('FeeQuoter GetValidatedFee', () => {
310312 const tooManyTokens = [ FeeQuoterSetup . SOURCE_FEE_TOKEN ] // We don't support token transfers in TON yet
311313
312314 const message : rt . CCIPSend = {
313- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
315+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
314316 receiver : FeeQuoterSetup . DEST_ADDRESS ,
315317 data : beginCell ( ) . endCell ( ) ,
316318 tokenAmounts : tooManyTokens . map ( ( token ) => ( {
@@ -361,7 +363,7 @@ describe('FeeQuoter GetValidatedFee', () => {
361363
362364 it ( 'should revert when gas limit too high' , async ( ) => {
363365 const message : rt . CCIPSend = {
364- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
366+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
365367 receiver : FeeQuoterSetup . DEST_ADDRESS ,
366368 data : beginCell ( ) . endCell ( ) ,
367369 tokenAmounts : [ ] ,
@@ -411,7 +413,7 @@ describe('FeeQuoter GetValidatedFee', () => {
411413 const notAFeeToken = FeeQuoterSetup . CUSTOM_TOKEN . token
412414
413415 const message : rt . CCIPSend = {
414- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
416+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
415417 receiver : FeeQuoterSetup . DEST_ADDRESS ,
416418 data : beginCell ( ) . endCell ( ) ,
417419 tokenAmounts : [ ] ,
@@ -491,7 +493,7 @@ describe('FeeQuoter GetValidatedFee', () => {
491493 overrides . dataAvailabilityGasPrice !== undefined
492494 ? [
493495 {
494- chainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
496+ chainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
495497 executionGasPrice : overrides . executionGasPrice ?? FeeQuoterSetup . USD_PER_GAS ,
496498 dataAvailabilityGasPrice :
497499 overrides . dataAvailabilityGasPrice ??
@@ -548,7 +550,7 @@ describe('FeeQuoter GetValidatedFee', () => {
548550 value : toNano ( '1' ) ,
549551 updates : [
550552 {
551- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
553+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
552554 config : {
553555 ...FeeQuoterSetup . destChainConfig ,
554556 ...destConfigOverrides ,
@@ -605,7 +607,7 @@ describe('FeeQuoter GetValidatedFee', () => {
605607 const gasLimit = overrides . gasLimit ?? BigInt ( FeeQuoterSetup . MAX_GAS_LIMIT )
606608
607609 const message : rt . CCIPSend = {
608- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
610+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
609611 receiver : FeeQuoterSetup . DEST_ADDRESS ,
610612 data : asSnakeBytes ( Buffer . alloc ( dataSize ) ) ,
611613 tokenAmounts : [ ] ,
@@ -635,7 +637,7 @@ describe('FeeQuoter GetValidatedFee', () => {
635637 const gasLimit = overrides . gasLimit ?? BigInt ( FeeQuoterSetup . MAX_GAS_LIMIT )
636638
637639 const message : rt . CCIPSend = {
638- destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR ,
640+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
639641 receiver : FeeQuoterSetup . DEST_ADDRESS ,
640642 data : asSnakeBytes ( Buffer . alloc ( dataSize ) ) ,
641643 tokenAmounts : [ ] ,
@@ -815,4 +817,177 @@ describe('FeeQuoter GetValidatedFee', () => {
815817 )
816818 } )
817819 } )
820+
821+ // extraArgs validation
822+ const validEVMExtraArgs : ExtraArgs = {
823+ kind : 'generic-v2' ,
824+ gasLimit : BigInt ( FeeQuoterSetup . GAS_LIMIT ) ,
825+ allowOutOfOrderExecution : true ,
826+ }
827+ describe ( 'EVMExtraArgs' , ( ) => {
828+ it ( 'valid extra args' , async ( ) => {
829+ const message : rt . CCIPSend = {
830+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_EVM ,
831+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
832+ data : beginCell ( ) . endCell ( ) ,
833+ tokenAmounts : [ ] ,
834+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
835+ extraArgs : rt . builder . data . extraArgs . encode ( validEVMExtraArgs ) . endCell ( ) ,
836+ }
837+
838+ const result = await setup . getValidatedFee ( message , beginCell ( ) . endCell ( ) )
839+ expect ( result . fee ) . toBeGreaterThan ( 0n )
840+ } )
841+
842+ // NOTE: GasLimitTooHigh already tested above as "should revert when gas limit too high"
843+ } )
844+
845+ describe ( 'SVMExtraArgs' , ( ) => {
846+ const validSVMExtraArgs : ExtraArgs = {
847+ kind : 'svm-v1' ,
848+ computeUnits : BigInt ( FeeQuoterSetup . GAS_LIMIT ) ,
849+ accountIsWritableBitMap : 0n ,
850+ allowOutOfOrderExecution : true ,
851+ tokenReceiver : Buffer . alloc ( 32 ) ,
852+ accounts : [ Buffer . alloc ( 32 ) ] ,
853+ }
854+
855+ it ( 'valid extra args' , async ( ) => {
856+ const message : rt . CCIPSend = {
857+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SVM ,
858+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
859+ data : beginCell ( ) . endCell ( ) ,
860+ tokenAmounts : [ ] ,
861+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
862+ extraArgs : rt . builder . data . extraArgs . encode ( validSVMExtraArgs ) . endCell ( ) ,
863+ }
864+
865+ const result = await setup . getValidatedFee ( message , beginCell ( ) . endCell ( ) )
866+ expect ( result . fee ) . toBeGreaterThan ( 0n )
867+ } )
868+
869+ it ( 'reverts with empty extra args' , async ( ) => {
870+ const message : rt . CCIPSend = {
871+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SVM ,
872+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
873+ data : beginCell ( ) . endCell ( ) ,
874+ tokenAmounts : [ ] ,
875+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
876+ extraArgs : beginCell ( ) . endCell ( ) ,
877+ }
878+ const result = await setup . assertGetFeeValidationError (
879+ message ,
880+ feeQuoter . FeeQuoterError . InvalidExtraArgsData ,
881+ )
882+ } )
883+
884+ it ( 'reverts with invalid tag' , async ( ) => {
885+ const message : rt . CCIPSend = {
886+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SVM ,
887+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
888+ data : beginCell ( ) . endCell ( ) ,
889+ tokenAmounts : [ ] ,
890+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
891+ extraArgs : rt . builder . data . extraArgs . encode ( validEVMExtraArgs ) . endCell ( ) ,
892+ }
893+ const result = await setup . assertGetFeeValidationError (
894+ message ,
895+ feeQuoter . FeeQuoterError . InvalidExtraArgsData ,
896+ )
897+ } )
898+
899+ it ( 'reverts if out of order execution is false' , async ( ) => {
900+ const message : rt . CCIPSend = {
901+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SVM ,
902+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
903+ data : beginCell ( ) . endCell ( ) ,
904+ tokenAmounts : [ ] ,
905+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
906+ extraArgs : rt . builder . data . extraArgs
907+ . encode ( {
908+ ...validSVMExtraArgs ,
909+ allowOutOfOrderExecution : false ,
910+ } )
911+ . endCell ( ) ,
912+ }
913+ const result = await setup . assertGetFeeValidationError (
914+ message ,
915+ feeQuoter . FeeQuoterError . ExtraArgOutOfOrderExecutionMustBeTrue ,
916+ )
917+ } )
918+ } )
919+
920+ describe ( 'SuiExtraArgs' , ( ) => {
921+ const validSVMExtraArgs : ExtraArgs = {
922+ kind : 'sui-v1' ,
923+ gasLimit : BigInt ( FeeQuoterSetup . GAS_LIMIT ) ,
924+ allowOutOfOrderExecution : true ,
925+ tokenReceiver : Buffer . alloc ( 32 ) ,
926+ receiverObjectIds : [ Buffer . alloc ( 32 ) ] ,
927+ }
928+
929+ it ( 'valid extra args' , async ( ) => {
930+ const message : rt . CCIPSend = {
931+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SUI ,
932+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
933+ data : beginCell ( ) . endCell ( ) ,
934+ tokenAmounts : [ ] ,
935+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
936+ extraArgs : rt . builder . data . extraArgs . encode ( validSVMExtraArgs ) . endCell ( ) ,
937+ }
938+
939+ const result = await setup . getValidatedFee ( message , beginCell ( ) . endCell ( ) )
940+ expect ( result . fee ) . toBeGreaterThan ( 0n )
941+ } )
942+
943+ it ( 'reverts with empty extra args' , async ( ) => {
944+ const message : rt . CCIPSend = {
945+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SVM ,
946+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
947+ data : beginCell ( ) . endCell ( ) ,
948+ tokenAmounts : [ ] ,
949+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
950+ extraArgs : beginCell ( ) . endCell ( ) ,
951+ }
952+ const result = await setup . assertGetFeeValidationError (
953+ message ,
954+ feeQuoter . FeeQuoterError . InvalidExtraArgsData ,
955+ )
956+ } )
957+
958+ it ( 'reverts with invalid tag' , async ( ) => {
959+ const message : rt . CCIPSend = {
960+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SUI ,
961+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
962+ data : beginCell ( ) . endCell ( ) ,
963+ tokenAmounts : [ ] ,
964+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
965+ extraArgs : rt . builder . data . extraArgs . encode ( validEVMExtraArgs ) . endCell ( ) ,
966+ }
967+ const result = await setup . assertGetFeeValidationError (
968+ message ,
969+ feeQuoter . FeeQuoterError . InvalidExtraArgsData ,
970+ )
971+ } )
972+
973+ it ( 'reverts if out of order execution is false' , async ( ) => {
974+ const message : rt . CCIPSend = {
975+ destChainSelector : FeeQuoterSetup . DEST_CHAIN_SELECTOR_SUI ,
976+ receiver : FeeQuoterSetup . DEST_ADDRESS ,
977+ data : beginCell ( ) . endCell ( ) ,
978+ tokenAmounts : [ ] ,
979+ feeToken : FeeQuoterSetup . NATIVE_TON . token ,
980+ extraArgs : rt . builder . data . extraArgs
981+ . encode ( {
982+ ...validSVMExtraArgs ,
983+ allowOutOfOrderExecution : false ,
984+ } )
985+ . endCell ( ) ,
986+ }
987+ const result = await setup . assertGetFeeValidationError (
988+ message ,
989+ feeQuoter . FeeQuoterError . ExtraArgOutOfOrderExecutionMustBeTrue ,
990+ )
991+ } )
992+ } )
818993} )
0 commit comments