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

Description:
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.\\nThe 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.\\nWithout 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.\\n` 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;\\n```\\n    Client.EVM2AnyMessage memory evm2AnyMessage = Client.EVM2AnyMessage({\\n        receiver: abi.encode(_receiver),\\n        data: "",\\n        tokenAmounts: tokenAmounts,\\n        extraArgs: "0x",\\n        feeToken: _feeTokenAddress\\n    });\\n\\n    return evm2AnyMessage;\\n}\\n```\\n\\n`

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.\\nWithout a specified gasLimit, the cost of sending a message can vary, making it difficult for users to predict the required fees.\\nIf the default gas limit is higher than necessary, users may overpay for gas that is not used, as unspent gas is not refunded.

Recommended mitigation:
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.\\nfunction _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;\\n// // 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 });\\n```\\nreturn evm2AnyMessage;\\n```\\n\\n}\\nIncludes 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.