Assessment reports>SushiSwap RouteProcessor3>Informational findings>The RouteProcessor3 should not hold nontransient tokens
Category: Business Logic

The RouteProcessor3 should not hold nontransient tokens

Informational Severity
Informational Impact
N/A Likelihood

Description

There are numerous ways in which tokens can be stolen if they are held by the RouteProcessor3.

For example, one way is by directly asking the contract to wrap or unwrap Ether and transfer it to the user.

function wrapNative(uint256 stream, address from, address tokenIn, uint256 amountIn) private {
    uint8 directionAndFake = stream.readUint8();
    address to = stream.readAddress();

    if (directionAndFake & 1 == 1) {  // wrap native
        address wrapToken = stream.readAddress();
        if (directionAndFake & 2 == 0) IWETH(wrapToken).deposit{value: amountIn}();
        if (to != address(this)) IERC20(wrapToken).safeTransfer(to, amountIn);
    } else { // unwrap native
        if (directionAndFake & 2 == 0) {
            if (from != address(this)) IERC20(tokenIn).safeTransferFrom(from, address(this), amountIn);
            IWETH(tokenIn).withdraw(amountIn);
        }
        payable(to).transfer(address(this).balance);
    }
}

The wrapNative function can be reached with from == address(this) by going from processRouteInternal to processNative, listed below,

function processNative(uint256 stream) private {
    uint256 amountTotal = address(this).balance;
    distributeAndSwap(stream, address(this), NATIVE_ADDRESS, amountTotal);
}

then requesting a wrapNative operation in the swap. The tokens belonging to RouteProcessor3 will then be wrapped or unwrapped and transferred to the user.

Impact

The RouteProcessor3 contract should not hold tokens except transiently, in the middle of a transaction.

Recommendations

Document prominently that the RouteProcessor3 contract should not hold tokens.

Remediation

This issue has been acknowledged by Sushiswap.

Zellic © 2024Back to top ↑