Chainlink Local uses the EVM2AnyMessage `gasLimit` in tests for custom token pools
Opened this issue · 0 comments
Expected Behaviour
The EVM2AnyMessage
struct contains the field extraArgs
in which you can pass _argsToBytes(EVMExtraArgsV1)
in which EVMExtraArgsV1
has the member gasLimit
. This custom gas limit is used for sending data with your cross chain message via the data
member of EVM2AnyMessage
. When sending a cross-chain message with no data data: ""
, the gasLimit
can be set to zero.
Issue
In a fork test, the test fails due to an OutOfGas
error. This same test passes if using the default gasLimit
of 200_000
. This implies that CLL is using the custom gas limit to execute the cross-chain transfer in the case of custom token pools.
Steps to Reproduce
Create a Foundry fork test that calls the following function to create and send a CCIP message:
function bridgeTokens(
uint256 amountToBridge,
uint256 localFork,
uint256 remoteFork,
Register.NetworkDetails memory localNetworkDetails,
Register.NetworkDetails memory remoteNetworkDetails,
RebaseToken localToken,
RebaseToken remoteToken
) public {
vm.selectFork(localFork);
// struct EVM2AnyMessage {
// bytes receiver; // abi.encode(receiver address) for dest EVM chains
// bytes data; // Data payload
// EVMTokenAmount[] tokenAmounts; // Token transfers
// address feeToken; // Address of feeToken. address(0) means you will send msg.value.
// bytes extraArgs; // Populate this with _argsToBytes(EVMExtraArgsV2)
// }
Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1);
tokenAmounts[0] = Client.EVMTokenAmount({token: address(localToken), amount: amountToBridge});
Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
receiver: abi.encode(user),
data: "",
tokenAmounts: tokenAmounts,
feeToken: localNetworkDetails.linkAddress,
extraArgs: ""
});
// extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: 0}))
uint256 fee =
IRouterClient(localNetworkDetails.routerAddress).getFee(remoteNetworkDetails.chainSelector, message);
ccipLocalSimulatorFork.requestLinkFromFaucet(user, fee);
vm.prank(user);
IERC20(localNetworkDetails.linkAddress).approve(localNetworkDetails.routerAddress, fee);
vm.prank(user);
IERC20(address(localToken)).approve(localNetworkDetails.routerAddress, amountToBridge);
uint256 localBalanceBefore = localToken.balanceOf(user);
vm.prank(user);
IRouterClient(localNetworkDetails.routerAddress).ccipSend(remoteNetworkDetails.chainSelector, message);
uint256 localBalanceAfter = localToken.balanceOf(user);
assertEq(localBalanceAfter, localBalanceBefore - amountToBridge);
uint256 localUserInterestRate = localToken.getUserInterestRate(user);
vm.selectFork(remoteFork);
vm.warp(block.timestamp + 20 minutes);
uint256 remoteBalanceBefore = remoteToken.balanceOf(user);
ccipLocalSimulatorFork.switchChainAndRouteMessage(remoteFork);
uint256 remoteBalanceAfter = remoteToken.balanceOf(user);
assertEq(remoteBalanceAfter, remoteBalanceBefore + amountToBridge);
assertEq(remoteToken.getUserInterestRate(user), localUserInterestRate);
}
Outcome
The test fails unless using the default value for gasLimit