🎫Missing Checks

Missing fromToken != toToken check

Vulnerability Details

Description:

The vulnerability emerges when the MarginRouter.crossSwapExactTokensForTokens function is invoked with a counterfeit pair where token[0] is equivalent to token[1]. In the scenario where the function is called as crossSwapExactTokensForTokens(1000 WETH, 0, [ATTACKER_CONTRACT], [WETH, WETH]), the function attempts to compute amounts via UniswapStyleLib.getAmountsOut(amountIn - fees, pairs, tokens); However, this process is manipulated as the attacker's contract returns falsified reserves, yielding zero output.

Code Snippet:

In the _swapExactT4T function, funds are withdrawn and sent to the attacker's contract:

solidityCopy codefunction _swapExactT4T() {
    Fund(fund()).withdraw(tokens[0], pairs[0], amounts[0]); // Withdrawal occurs here
    _swap(amounts, pairs, tokens, fund());
}

The _swap function checks are passed since startingBalance is recorded post the initial fund withdrawal to the pair:

solidityCopy codefunction _swap() {
    uint256 startingBalance = IERC20(outToken).balanceOf(_to);
    uint256 endingBalance = IERC20(outToken).balanceOf(_to);
    require(
        endingBalance >= startingBalance + amounts[amounts.length - 1],
        "Defective AMM route; balances don't match" // Check passes as startingBalance == endingBalance + 0
    );
}

Impact:

The exact ramifications of this vulnerability are yet to be fully grasped. The registerTrade function may still falter during the process of subtracting inAmount and adding a zero outAmount. This vulnerability closely resembles a withdrawal attack that typically would be restricted by a coolingOffPeriod—a security measure this attack ingeniously sidesteps.

Last updated