The Standard

The Standard
DeFiHardhat
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

Insufficient slippage protection in the `swap` function

Summary

Users who take a loan can trade on uniswap with their locked up collateral. The protocol calculates the minimum amount of tokens that need to be returned to the vault to stay in a healthy CR. This calculation is done in the calculateMinimumAmountOut function. But the protocol does not take into account the slippage of the swap. This enables MEV bots to sandwich the swap and steal funds from the vault.

Vulnerability Details

Here we can see the swap function and how it calculates the amountOutMinimum parameter passed to uniswap:

function swap(bytes32 _inToken, bytes32 _outToken, uint256 _amount) external onlyOwner {
uint256 swapFee = _amount * ISmartVaultManagerV3(manager).swapFeeRate() / ISmartVaultManagerV3(manager).HUNDRED_PC();
address inToken = getSwapAddressFor(_inToken);
uint256 minimumAmountOut = calculateMinimumAmountOut(_inToken, _outToken, _amount);
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: inToken,
tokenOut: getSwapAddressFor(_outToken),
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amount - swapFee,
amountOutMinimum: minimumAmountOut,
sqrtPriceLimitX96: 0
});
inToken == ISmartVaultManagerV3(manager).weth() ?
executeNativeSwapAndFee(params, swapFee) :
executeERC20SwapAndFee(params, swapFee);
}
function calculateMinimumAmountOut(bytes32 _inTokenSymbol, bytes32 _outTokenSymbol, uint256 _amount) private view returns (uint256) {
ISmartVaultManagerV3 _manager = ISmartVaultManagerV3(manager);
uint256 requiredCollateralValue = minted * _manager.collateralRate() / _manager.HUNDRED_PC();
uint256 collateralValueMinusSwapValue = euroCollateral() - calculator.tokenToEur(getToken(_inTokenSymbol), _amount);
return collateralValueMinusSwapValue >= requiredCollateralValue ?
0 : calculator.eurToToken(getToken(_outTokenSymbol), requiredCollateralValue - collateralValueMinusSwapValue);
}
  1. If more than enough collateral is in the vault it passes 0 as amountOutMinimum to uniswap therefore no protection at all against sandwich attacks.

  2. If this is not the case, it passes the amount which is needed so that the collateral rate is not broken to uniswap. This can potentially also be way to less. If a trade about 1000e18 tokens takes place and only 1e18 token is needed to not break the collateral rate than there is not much difference to passing 0 as amountOutMinimum.

Therefore, swap are most likely not or insufficiently protected against sandwich attacks.

Impact

MEV bots can take opportunity of the vaults swaps.

Recommendations

Add a minAmtOut parameter to the swap function input as this should be calculated off chain and pass this parameter or the calculated parameter to uniswap depending on which is higher.

Updates

Lead Judging Commences

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Slippage-issue

hrishibhat Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

Slippage-issue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.