Skip to content

Latest commit

 

History

History
68 lines (49 loc) · 2.37 KB

077.md

File metadata and controls

68 lines (49 loc) · 2.37 KB

Bright Violet Crocodile

Medium

Defi swaps will modify ss.oAmount but not ss.tAmount or ss.feeAmount, leading to under/overpayment

Summary

Defi swaps via AmirX::swap() modify the ss.oAmount to take slippage and fees into account and not transfer ss.origin tokens out of the wallet. However, it does not update ss.tAmount or ss.feeAmount which means users always get these same amounts and pay the same fees regardless of the slippage that happened in the swap, ending up paying too much or too little compared to the amount received.

Root Cause

In AmirX:93, ss.tAmount and ss.feeAmount are not updated according to the amounts swapped.

Internal pre-conditions

None.

External pre-conditions

None.

Attack Path

  1. Swapper calls AmirX::swap() with directional to true.

Impact

ss.oAmount is updated to fBalance - iBalance to reflect the slippage that happened but ss.tAmount and ss.feeAmount remain the same regardless of slippage. Thus, users will under/overpay for the same ss.tAmount.

PoC

function swap(
    address wallet,
    bool directional,
    StablecoinSwap memory ss,
    DefiSwap memory defi
) external payable onlyRole(SWAPPER_ROLE) whenNotPaused {
    // checks if it will fail
    if (ss.destination != address(0)) _verifyStablecoinSwap(wallet, ss);
    if (defi.walletData.length != 0) _verifyDefiSwap(wallet, defi);

    if (directional) {
        // if only defi swap
        if (ss.destination == address(0)) _defiSwap(wallet, defi);
        else {
            // if defi then stablecoin swap
            //check balance to adjust second swap
            uint256 iBalance = ERC20(ss.origin).balanceOf(wallet);
            if (defi.walletData.length != 0) _defiSwap(wallet, defi);
            uint256 fBalance = ERC20(ss.origin).balanceOf(wallet);
            //change balance to reflect change
            if (fBalance - iBalance != 0) ss.oAmount = fBalance - iBalance;
            _stablecoinSwap(wallet, ss);
        }
    } else {
        // if stablecoin swap
        _stablecoinSwap(wallet, ss);
        // if only stablecoin swap
        if (defi.walletData.length != 0) _defiSwap(wallet, defi);
    }
}

Mitigation

Update ss.tAmount and ss.feeAmount according to the slippage that took place.