Light ModeLight
Light ModeDark

One Bug Per Day

One H/M every day from top Wardens

Checkmark

Join over 1145 wardens!

Checkmark

Receive the email at any hour!

Ad

Refunds for unconsumed gas will be lost due to incorrect refund chain ID

mediumCode4rena

Lines of code

https://github.com/code-423n4/2024-05-olas/blob/3ce502ec8b475885b90668e617f3983cea3ae29f/tokenomics/contracts/staking/WormholeDepositProcessorL1.sol#L97

Vulnerability details

The WormholeDepositProcessorL1 contract allows sending tokens and data via the Wormhole bridge from L1 to L2. It uses the sendTokenWithPayloadToEvm() function from the TokenBase contract in the Wormhole Solidity SDK to send the tokens and payload.

The sendTokenWithPayloadToEvm() function takes several parameters, including:

  • targetChain - the Wormhole chain ID of the destination chain
  • refundChain - the Wormhole chain ID of the chain where refunds for unconsumed gas should be sent

In the WormholeDepositProcessorL1._sendMessage() function, the refundChain parameter is incorrectly set to l2TargetChainId, which is the EVM chain ID of the receiving L2 chain:

solidity
File: WormholeDepositProcessorL1.sol 94: // The token approval is done inside the function 95: // Send tokens and / or message to L2 96: sequence = sendTokenWithPayloadToEvm(uint16(wormholeTargetChainId), l2TargetDispenser, data, 0, 97: gasLimitMessage, olas, transferAmount, uint16(l2TargetChainId), refundAccount);

However, it should be set to wormholeTargetChainId, which is the Wormhole chain ID classification corresponding to the L2 chain ID. Passing the l2TargetChainId as targetChain and casting it to uint16 will lead to refunds for unconsumed gas being sent to an altogether different chain (only if they are sufficient to be delivered, as explained in the Wormhole docs here) or lost.

Impact

Refunds for unconsumed gas paid by users when sending tokens from L1 to L2 via the Wormhole bridge will likely be lost. This results in users overpaying for gas.

Proof of Concept

  1. User calls claimStakingIncentives() on the Dispenser contract for a nominee on Celo
  2. WormholeDepositProcessorL1._sendMessage() is called internally, which calls TokenBase.sendTokenWithPayloadToEvm()
  3. The refundChain parameter in sendTokenWithPayloadToEvm() is set to l2TargetChainId instead of wormholeTargetChainId
  4. Refunds for unconsumed gas are sent to the wrong chain ID or lost

Tools Used

Manual review

Recommended Mitigation Steps

Change the refundChain parameter in the sendTokenWithPayloadToEvm() call to use wormholeTargetChainId instead of l2TargetChainId. ``

Assessed type

Other