stake.link

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

There is not protection for fees increment while the `reSDL` is transferring to another chain

Summary

When an reSDL token is transferring to another chain, it is necessary to pay a gas fee in native token, those gas fee can be increased while the transaction is in the mempool causing the user to pay undesired amounts of fees.

Vulnerability Details

The function RESDLTokenBridge.transferRESDL() helps to send a reSDL token to another chain. In order to send the token to another chain it is necessary to pay a fee which will be calculated depending on the message created.

The problem arises when the user wants to pay the fees in native token and there is an increase in the fees while the transaction is in process. It is important to note that CCIP allows you to specify an extraArgs in the message that is going to be sent to the other chain:

struct EVM2AnyMessage {
bytes receiver;
bytes data;
struct Client.EVMTokenAmount[] tokenAmounts;
address feeToken;
bytes extraArgs;
}

Inside the extraArgs it can be specified the gasLimit to use. The gasLimit is a very important variable to be able to determine the gas fees, as it says in its documentation: It is the main factor in determining the fee to send a message. Unspent gas is not refunded.. Taking into account that the extraArgs can be modified using the function RESDLTokenBridge::setExtraArgs() then the following scenario may arise:

  1. The user determines that the fees to sent his tokens are 10e13 native tokens.

  2. The transaction is sent and waits in the mempool.

  3. The admin changes the values of extraArgs and now the fees increase to 20e13 native tokens. This transaction occurs before step 2.

  4. Now the transaction from step 2 is executed with an unwanted increase in fees.

Likewise, the fee calculation may be increased by Chainlink while the sending token transaction is waiting in the mempool.

The parameter _maxLINKFee helps determine the maximum in the LINK token, however, there is no validation for the native token.

Impact

The user will pay unwanted fees if those are increased while the sending transaction is waiting to be executed.

Tools used

Manual review

Recommendations

Add a parameter that helps specify the maximum fee in native tokens that the user is willing to pay:

function transferRESDL(
uint64 _destinationChainSelector,
address _receiver,
uint256 _tokenId,
bool _payNative,
-- uint256 _maxLINKFee
++ uint256 _maxFee
) external payable returns (bytes32 messageId) {
...
...
...
uint256 fees = IRouterClient(sdlPoolCCIPController.getRouter()).getFee(_destinationChainSelector, evm2AnyMessage);
++ if (fees > _maxFee) revert FeeExceedsLimit();
if (_payNative) {
if (fees > msg.value) revert InsufficientFee();
messageId = sdlPoolCCIPController.ccipSend{value: fees}(_destinationChainSelector, evm2AnyMessage);
if (fees < msg.value) {
(bool success, ) = msg.sender.call{value: msg.value - fees}("");
if (!success) revert TransferFailed();
}
} else {
-- if (fees > _maxLINKFee) revert FeeExceedsLimit();
linkToken.safeTransferFrom(msg.sender, address(sdlPoolCCIPController), fees);
messageId = sdlPoolCCIPController.ccipSend(_destinationChainSelector, evm2AnyMessage);
}
...
...
...
}
Updates

Lead Judging Commences

0kage Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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