The Standard

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

Vault executes swaps without slippage protection

The vault executes swaps without slippage protection. That will cause a loss of funds because of sandwich attacks.

Links to affected code

https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/SmartVaultV3.sol#L217-L227
https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/SmartVaultV3.sol#L210-L211

Vulnerability Details

It can happen that the calculateMinimumAmountOut results 0 when the collateralValueMinusSwapValue is larger or equal as the requiredCollateralValue, this can happen when the PriceCalculator returns a wrong result. This leads to a swap without slippage protection.

Impact

Swaps will be sandwiched causing a loss of funds for the users.

UniswapV3 Docs

we are setting to zero, but this is a significant risk in production.
For a real deployment, this value should be calculated using our SDK or an onchain price oracle -
this helps protect against getting an unusually bad price for a trade due to a front running sandwich or another type of price manipulation

Recommended mitigation steps

Validate the return value of the minimumAmountOut. When 0 is returned the vault doesn't have the balance to perform the swap and it should revert. This will also protect the user from sandwich attacks.

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);
+ require(minimumAmountOut > 0, "swap not possible");
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);
}
Updates

Lead Judging Commences

hrishibhat Lead Judge almost 2 years 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.