stake.link

stake.link
DeFiHardhatBridge
27,500 USDC
View results
Submission Details
Severity: low
Valid

Insufficient Gas Limit Specification for Cross-Chain Transfers in _buildCCIPMessage() method. WrappedTokenBridge.sol #210

Summary

The _buildCCIPMessage() function in the WrappedTokenBridge contract does not specify a gasLimit for the execution of the ccipReceive() function on the destination blockchain. This omission can lead to unpredictable gas costs and potential failure of the message processing due to out-of-gas errors.

Vulnerability Details

The Client.EVM2AnyMessage struct created by _buildCCIPMessage() is used to define the details of a cross-chain message, including the tokens to be transferred and the receiver's address. However, the struct lacks a gasLimit field in the extraArgs, which is crucial for determining the maximum amount of gas that can be consumed when the ccipReceive() function is called on the destination chain.

Without a specified gasLimit, the default gas limit set by the CCIP router or the destination chain's infrastructure is used. This default may not align with the actual gas requirements of the ccipReceive() function, potentially leading to failed transactions or higher-than-expected fees.

`
function _buildCCIPMessage(
address _receiver,
uint256 _amount,
address _feeTokenAddress
) internal view returns (Client.EVM2AnyMessage memory) {
Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount;
Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({token: address(wrappedToken), amount: _amount});
tokenAmounts[0] = tokenAmount;

    Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
        receiver: abi.encode(_receiver),
        data: "",
        tokenAmounts: tokenAmounts,
        extraArgs: "0x",
        feeToken: _feeTokenAddress
    });

    return evm2AnyMessage;
}

`

Impact

If the default gas limit is too low, the ccipReceive() function may run out of gas, causing the transaction to fail on the destination chain.

Without a specified gasLimit, the cost of sending a message can vary, making it difficult for users to predict the required fees.

If the default gas limit is higher than necessary, users may overpay for gas that is not used, as unspent gas is not refunded.

Tools Used

Manual inspection.

https://docs.chain.link/ccip/best-practices
..Gas Limit

CCIP Lending example. sendMessage()
https://github.com/smartcontractkit/ccip-defi-lending/blob/main/contracts/Protocol.sol#170

Recommendations

To address the issue of not including a gasLimit in the _transferTokens method, we can take inspiration from the sendMessage() example and modify the _buildCCIPMessage function within the WrappedTokenBridge contract to include a gasLimit in the extraArgs field of the EVM2AnyMessage struct. This will ensure that the CCIP message sent to the destination blockchain includes a specified maximum amount of gas that can be consumed during the execution of the ccipReceive() function.

function _buildCCIPMessage(
address _receiver,
uint256 _amount,
address _feeTokenAddress
) internal view returns (Client.EVM2AnyMessage memory) {
Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount;
Client.EVMTokenAmount memory tokenAmount = Client.EVMTokenAmount({
token: address(wrappedToken),
amount: _amount
});
tokenAmounts[0] = tokenAmount;

// // Include a gasLimit in the extraArgs
Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({
receiver: abi.encode(_receiver),
data: "",
tokenAmounts: tokenAmounts,
extraArgs: Client._argsToBytes(
Client.EVMExtraArgsV1({gasLimit: 200_000, strict: false}) // Additional arguments, setting gas limit and non-strict sequency mode
),
feeToken: _feeTokenAddress
});

return evm2AnyMessage;

}

Includes a gasLimit field, which is set to 200,000 in this example. This value should be adjusted based on the expected gas consumption of the ccipReceive() function on the destination chain.
By including the gasLimit in the extraArgs, you ensure that the CCIP message has a specified maximum gas limit for execution, which can prevent out-of-gas errors and control the cost of the cross-chain transfer.

Updates

Lead Judging Commences

0kage Lead Judge
over 1 year ago
0kage Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

hardcode-extraArgs

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.