Swap Pools normally allow a user to specifiy a minimum amount out for a swap as a way to mitigate sandwich attacks. SmartVaultV3
calculates this amount for the user. This minimumAmountOut
is calculated to be the minimum amount for which, once the swap goes through, the vault will not be undercollateralized. In reality unless a user is borrowing close to their maxMintable()
, this calculated amount will be very low, opening the opportunity for sandwich attacks and the user having their funds stolen.
A user can swap some of their collateral, directly through the Vault. This is done by calling the swap()
function.
As we can see the user specifies the _inToken
, _outToken
and _amount
.
https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/SmartVaultV3.sol#L214
The minimumAmountOut
required as input by UniSwap to mitigate sandwich attacks is calculated separately and cannot be directly specified by the user. The calculation is used as a means to check if the vault will be undercollateralized after the swap. The calculateMinimumAmountOut()
function looks as follows:
https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/SmartVaultV3.sol#L206
Let's take a look at an example calculation to understand it. Suppose we have the following state and transaction data:
Rate tokenToEur for _inToken
:EUROs
= 1:1
Rate tokenToEur for _outToken
:EUROs
= 1:5
Total collateral in vault in EUROs
= 1000000
(This is returned by euroCollateral()
)
Collateral in vault for _inToken
in EUROs
= 10000
minted
= 10000
collateralRate
= 150%
Swap 1000
_inToken
After plugging the numbers, we get:
This means after the swap, the vault must have at least 15000
EUROs
in collateral value. Let's go to the next one:
As a result we have that 99000>15000
, which will make the function return 0. So the minimumAmountOut
passed to UniSwap will be 0. This will create an opening for a sandwich attack. In reality, unless the user has minted very close to their maximum allowed borrow, the function will not return a reasonable number for minimumAmountOut
, meaning most swaps will be susceptible to this attack.
Stolen funds.
Manual Review.
Allow a user to specify minimumAmountOut as input for the function and use that to check if the vault will be undercollateralized after the swap.
This was somewhat reported in the known issues, but the vulnerability to sandwich attacks it creates is not explicitly mentioned, thus am making this report.
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.