sherlock-audit / 2023-05-ironbank-judging

2 stars 2 forks source link

n33k - Multihop uniV3SwapExactOut does not work #381

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

n33k

medium

Multihop uniV3SwapExactOut does not work

Summary

For the ACTION_UNISWAP_V3_EXACT_OUTPUT action, token transfer is mistakenly put inside the else block. Multihop swap will not be able to transfer asset to pools correctly.

Vulnerability Detail

This is the ACTION_UNISWAP_V3_EXACT_OUTPUT handling logic in uniswapV3SwapCallback. safeTransfer is put inside the else block. The right way is to put it outside.

if (data.path.hasMultiplePools()) {
    data.path = data.path.skipToken();

    // Make this pool as the recipient of the next swap.
    uniV3ExactOutputInternal(amountToPay, pool, data);
} else {
    require(tokenOut == data.swapInAsset, "mismatch swap in asset");

    uniV3AmountInCached = amountToPay;

    if (data.subAction == SUB_ACTION_OPEN_LONG_POSITION || data.subAction == SUB_ACTION_SWAP_DEBT) {
        ironBank.borrow(data.caller, address(this), data.swapInAsset, amountToPay);
    } else if (data.subAction == SUB_ACTION_CLOSE_SHORT_POSITION) {
        ironBank.redeem(data.caller, address(this), data.swapInAsset, amountToPay);
    } else {
        revert("invalid sub-action");
    }

    // Transfer the asset to the pool.
    IERC20(tokenOut).safeTransfer(pool, amountToPay);
}

Impact

Multihop ACTION_UNISWAP_V3_EXACT_OUTPUT does not work.

Code Snippet

https://github.com/sherlock-audit/2023-05-ironbank/blob/main/ib-v2/src/extensions/UniswapExtension.sol#L317

Tool used

Manual Review

Recommendation

Move the statement outside the else block.