The amountOutMinimum
calculated as part of the ISwapRouter.ExactInputSingleParams
which should serve as slippage protection will be 0 in certain cases which can lead to catastrophic Sandwich attacks and/or no control over the amount returned from Uniswap.
In the swap function, we're calculating the amountOutMinimum
using the calculateMinimumAmountOut()
function:
Proof of Concept:
Let's take Bob for example who is the owner of the SmartVault and has deposited 2 ETH to the vault. For the sake of simplifying calculations, let's say that 1 ETH is worth 2,000 EUROs, so total collateral would be worth 4,000 EUROs.
This would mean that Bob would be able to mint around 3635 EUROS at a 110% collateralization rate.
Bob has minted 500 EUROs from that vault, which at a collateralization of 110% would need 550 EUROs worth of collateral, leaving out 3135 EUROs left for minting (if he decided to mint more EUROs -> at the price of 2K EUROs per 1 ETH, of course).
According to the sponsor's information, theswap()
function's purpose is to swap between the 5 tokens (ETH, WBTC, ARB, LINK, & PAXG).
Bob decides to exchange one of his 1ETH through the swap()
function for the amountOut in WBTC, which should equal around 0.052 WBTC.
minimumAmountOut:
To calculate the requiredCollateralValue: minted (which is the amount we've minted - 500 EUROs + the minting fee, let's say 505 EUROs in total * 110% collateralization rate = 555 EUROs.
collateralValueMinusSwapValue = The total euro collateral in the system that we have is 2 ETH or 4,000 EUROs ( euroCollateral()
) - the amount we want to swap which would be 1 ETH (2,000 EUROs) = 2,000 EUROs
return collateralValueMinusSwapValue >= requiredCollateralValue
since the if-clause would be true, the output we'd get for minimumAmountOut would be 0.
This would basically mean that the user swapping will have absolutely no slippage protection on that trade.
The result of the scenario explained above would mean no slippage protection on a certain category of swaps which would allow swaps to be sandwiched leading to catastrophic losses for users, as well as no protection when it comes to any kind of drastic price manipulations/changes in Uniswap Pools that would affect the amountOut.
Manual Review
Refactor the calculateMinimumAmountOut()
function to account for scenarios such as the above one.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.