stake.link

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

Hardcoded `extraArgs` in `WrappedTokenBridge::_buildCCIPMessage()` can make the contract incompatible with future CCIP upgrades

Summary

The WrappedTokenBridge::_buildCCIPMessage() method, responsible for preparing the message that is going to be sent with Chainlink CCIP, is using a hardcoded value for extraArgs parameter. This is explicitly advised against by the Chainlink CCIP documentation, as it may lead to the incompatibility with the future versions of CCIP.

Vulnerability Details

The WrappedTokenBridge::_buildCCIPMessage() method is implemented as follows:

/**
* @notice Builds a CCIP message
* @param _receiver address to receive tokens on destination chain
* @param _amount amount of tokens to transfer
* @param _feeTokenAddress address of token that fees will be paid in
**/
function _buildCCIPMessage(
address _receiver,
uint256 _amount,
address _feeTokenAddress
) internal view returns (Client.EVM2AnyMessage memory) {
Client.EVMTokenAmount[] memory tokenAmounts = new Client.EVMTokenAmount[](1);
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;
}

The method uses a hardcoded value of Ox for the extraArgs parameter of Client.EVM2AnyMessage struct. This value is technically correct for now, as it sets the only member of Client.EVM2AnyMessage struct - gasLimit - to zero.

struct EVMExtraArgsV1 {
uint256 gasLimit;
}

In the case of CCIP token transfer without data, zero is the correct value for gasLimit, as stated in the documentation.

However, the documentation also explicitly states here that the hardcoded value for extraArgs should never be used:

DO NOT HARDCODE EXTRAARGS
To simplify this example, extraArgs are hardcoded in the contract. For production deployments, make sure that extraArgs is mutable. This allows you to build it off-chain and pass it in a call to a function or store it in a variable that you can update on-demand. This makes extraArgs compatible with future CCIP upgrades.

If Chainlink releases the new version of EVMExtraArgs, the hardcoded value may become incompatible. As a result the core contract's funtionality - wstLINK transfer - will cease to work.

Impact

The WrappedTokenBridge can be incompatible with future versions of Chainlink CCIP.

Tools Used

Manual review

Recommendations

Follow the pattern used in RESDLTokenBridge.sol contract. Instead of using a hardcoded value, introduce the state variable extraArgs with a corresponding setter method in order to be able to update the extra arguments whenever needed.

Updates

Lead Judging Commences

0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue
0kage Lead Judge
over 1 year ago
0kage Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

hardcode-extraArgs

Support

FAQs

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