The Standard

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

`SmartVaultV3` Insufficient Slippage Protection

Summary

The swap function in SmartVaultV3 lacks slippage protection for users,which expose users to sandwich attack resulting in users receiving less than expected from trades.

Vulnerability Details

  • In SmartVaultV3, the swap function uses calculateMinimumAmountOut to determine the minimum amount of output tokens for a swap. However, if the user's collateral minus the swap amount is still enough to cover the minted EUROs, this function returns zero as the minimum amount out. This means there is no floor to the number of tokens the user should receive, leaving them vulnerable to market manipulation and sandwich attacks .

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);
}
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 setOwner(address _newOwner) external onlyVaultManager {
owner = _newOwner;
}

Impact

Users can suffer financial losses due to receiving far fewer tokens than expected when swapping. T

Tools Used

manual review

Recommendations

  • Modify the swap function to allow users to set their own minimumAmountOut, and then do check that the user given minAmountOut , not make the vault undercollateralised after the swap

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.