diff --git a/contracts/.changeset/wet-eyes-accept.md b/contracts/.changeset/wet-eyes-accept.md new file mode 100644 index 00000000000..ea783366220 --- /dev/null +++ b/contracts/.changeset/wet-eyes-accept.md @@ -0,0 +1,7 @@ +--- +'@chainlink/contracts': patch +--- + +Refactor MockCCIPRouter to support EVMExtraArgsV2 + +PR issue : CCIP-4288 diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 54b9cdf22d7..d864b30804d 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -257,11 +257,14 @@ MerkleMultiProofTest:test_EmptyLeaf_Revert() (gas: 3563) MerkleMultiProofTest:test_MerkleRoot256() (gas: 394891) MerkleMultiProofTest:test_MerkleRootSingleLeaf_Success() (gas: 3661) MerkleMultiProofTest:test_SpecSync_gas() (gas: 34152) -MockRouterTest:test_ccipSendWithInsufficientNativeTokens_Revert() (gas: 34081) -MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60886) -MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126575) -MockRouterTest:test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() (gas: 63499) -MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 44056) +MockRouterTest:test_ccipSendWithEVMExtraArgsV1_Success() (gas: 110095) +MockRouterTest:test_ccipSendWithEVMExtraArgsV2_Success() (gas: 132614) +MockRouterTest:test_ccipSendWithInsufficientNativeTokens_Revert() (gas: 34059) +MockRouterTest:test_ccipSendWithInvalidEVMExtraArgs_Revert() (gas: 106706) +MockRouterTest:test_ccipSendWithInvalidMsgValue_Revert() (gas: 60864) +MockRouterTest:test_ccipSendWithLinkFeeTokenAndValidMsgValue_Success() (gas: 126685) +MockRouterTest:test_ccipSendWithLinkFeeTokenbutInsufficientAllowance_Revert() (gas: 63477) +MockRouterTest:test_ccipSendWithSufficientNativeFeeTokens_Success() (gas: 44070) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ConfigRateMoreThanCapacity_Revert() (gas: 16554) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_ConfigRateZero_Revert() (gas: 16634) MultiAggregateRateLimiter_applyRateLimiterConfigUpdates:test_DiableConfigCapacityNonZero_Revert() (gas: 16585) diff --git a/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol index 0abe4fdb7e5..3ded9fd78f0 100644 --- a/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol +++ b/contracts/src/v0.8/ccip/test/mocks/MockRouter.sol @@ -121,12 +121,19 @@ contract MockCCIPRouter is IRouter, IRouterClient { function _fromBytes( bytes calldata extraArgs - ) internal pure returns (Client.EVMExtraArgsV1 memory) { + ) internal pure returns (Client.EVMExtraArgsV2 memory) { if (extraArgs.length == 0) { - return Client.EVMExtraArgsV1({gasLimit: DEFAULT_GAS_LIMIT}); + return Client.EVMExtraArgsV2({gasLimit: DEFAULT_GAS_LIMIT, allowOutOfOrderExecution: false}); } - if (bytes4(extraArgs) != Client.EVM_EXTRA_ARGS_V1_TAG) revert InvalidExtraArgsTag(); - return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV1)); + + bytes4 extraArgsTag = bytes4(extraArgs); + if (extraArgsTag == Client.EVM_EXTRA_ARGS_V2_TAG) { + return abi.decode(extraArgs[4:], (Client.EVMExtraArgsV2)); + } else if (extraArgsTag == Client.EVM_EXTRA_ARGS_V1_TAG) { + return Client.EVMExtraArgsV2({gasLimit: abi.decode(extraArgs[4:], (uint256)), allowOutOfOrderExecution: false}); + } + + revert InvalidExtraArgsTag(); } /// @notice Always returns true to make sure this check can be performed on any chain. diff --git a/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol index cd0aabf1776..549d6b8f843 100644 --- a/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol +++ b/contracts/src/v0.8/ccip/test/mocks/test/MockRouterTest.t.sol @@ -65,4 +65,24 @@ contract MockRouterTest is TokenSetup { mockRouter.ccipSend(MOCK_CHAIN_SELECTOR, message); } + + function test_ccipSendWithEVMExtraArgsV1_Success() public { + Client.EVMExtraArgsV1 memory extraArgs = Client.EVMExtraArgsV1({gasLimit: 500_000}); + message.extraArgs = Client._argsToBytes(extraArgs); + mockRouter.ccipSend{value: 0.1 ether}(MOCK_CHAIN_SELECTOR, message); + } + + function test_ccipSendWithEVMExtraArgsV2_Success() public { + Client.EVMExtraArgsV2 memory extraArgs = Client.EVMExtraArgsV2({gasLimit: 500_000, allowOutOfOrderExecution: true}); + message.extraArgs = Client._argsToBytes(extraArgs); + mockRouter.ccipSend{value: 0.1 ether}(MOCK_CHAIN_SELECTOR, message); + } + + function test_ccipSendWithInvalidEVMExtraArgs_Revert() public { + uint256 gasLimit = 500_000; + bytes4 invalidExtraArgsTag = bytes4(keccak256("CCIP EVMExtraArgsInvalid")); + message.extraArgs = abi.encodeWithSelector(invalidExtraArgsTag, gasLimit); + vm.expectRevert(MockCCIPRouter.InvalidExtraArgsTag.selector); + mockRouter.ccipSend{value: 0.1 ether}(MOCK_CHAIN_SELECTOR, message); + } }