Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unvalidated msg.value in AggregateRouter::execute() Allows Unauthorized WRAP_ETH and UNWRAP_WETH Operations, Potentially Leading to Contract Fund Drain #8

Closed
howlbot-integration bot opened this issue Nov 4, 2024 · 3 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working primary issue Highest quality submission among a set of duplicates 🤖_50_group AI based duplicate group recommendation sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@howlbot-integration
Copy link

Lines of code

https://github.com/ronin-chain/katana-operation-contracts/blob/27f9d28e00958bf3494fa405a8a5acdcd5ecdc5d/src/aggregate-router/AggregateRouter.sol#L37
https://github.com/ronin-chain/katana-operation-contracts/blob/27f9d28e00958bf3494fa405a8a5acdcd5ecdc5d/src/aggregate-router/base/Dispatcher.sol#L164-L180

Vulnerability details

Summary

A vulnerability exists in the AggregateRouter::execute() function when handling the Commands.WRAP_ETH command on the Dipacther.sol. This vulnerability allows an attacker to attempt wrapping Ether without sending the corresponding amount of Ether (msg.value), potentially leading to unexpected behavior or financial loss.

Vulnerability Details

The dispatch function within the Dispatcher contract, specifically when processing the Commands.WRAP_ETH command.

function dispatch(bytes1 commandType, bytes calldata inputs) internal returns (bool success, bytes memory output) {
    uint256 command = uint8(commandType & Commands.COMMAND_TYPE_MASK);
    //... 
    // @audit msg.value not checked
    else if (command == Commands.WRAP_ETH) {
        // equivalent: abi.decode(inputs, (address, uint256))
        address recipient;
        uint256 amountMin;
        assembly {
          recipient := calldataload(inputs.offset)
          amountMin := calldataload(add(inputs.offset, 0x20))
        }
        Payments.wrapETH(map(recipient), amountMin);
}
  function wrapETH(address recipient, uint256 amount) internal {
    if (amount == Constants.CONTRACT_BALANCE) {
      amount = address(this).balance;
    } else if (amount > address(this).balance) {
      revert InsufficientETH();
    }
    if (amount > 0) {
      WETH9.deposit{ value: amount }();
      if (recipient != address(this)) {
        WETH9.transfer(recipient, amount);
      }
    }
  }

The attacker prepares the WRAP_ETH command with a fake amount.
The attacker can call the execute function without sending the required Ether (msg.value). Since the dispatch function does not validate msg.value, the wrapETH function could be executed with an incorrect amount, potentially leading to unintended WETH transfers. A similar issue exists with the UNWRAP_WETH command, which could lead to the contract's funds being completely drained.

Impact

this could lead to incorrect Ether wrapping, resulting in financial discrepancies or loss.

Tools Used

Manual Review

Recommendations

Add a check to ensure that the amount to be wrapped does not exceed msg.value.

Use msg.value directly if applicable, to ensure consistency.

Assessed type

ETH-Transfer

@howlbot-integration howlbot-integration bot added 3 (High Risk) Assets can be stolen/lost/compromised directly 🤖_50_group AI based duplicate group recommendation bug Something isn't working primary issue Highest quality submission among a set of duplicates sufficient quality report This report is of sufficient quality labels Nov 4, 2024
howlbot-integration bot added a commit that referenced this issue Nov 4, 2024
@khangvv
Copy link

khangvv commented Nov 4, 2024

This aligns with the native design of the AggregateRouter (or its inherited implementation from Uniswap), where users are required to pre-deposit the amount before executing the wrap command. And to clarify, no value is stored in the contract that could be drained. Any minor dust amounts should be freely claimable.

@khangvv khangvv added the sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue label Nov 4, 2024
@alex-ppg
Copy link

The Warden claims that the ETH wrapping operation of the Dispatch contract does not ensure adequate msg.value has been supplied to it. This validation is not meant to be applied to it as the Dispatch contract is an "ephemeral" implementation, meaning that it is never meant to hold funds at rest and is simply meant to process them.

@c4-judge
Copy link

alex-ppg marked the issue as unsatisfactory:
Invalid

@c4-judge c4-judge added the unsatisfactory does not satisfy C4 submission criteria; not eligible for awards label Nov 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working primary issue Highest quality submission among a set of duplicates 🤖_50_group AI based duplicate group recommendation sponsor disputed Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

3 participants