The Standard

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

AmountOutMinimum calculation doesn't account for fees

Summary

The calculation for the amountOutMinimum doesn't account for fees that is reduced from the amountIn. This can result in a constant revert due to slippage and the fact that the amountIn is insufficient.

Vulnerability Details

In the swap() function we can see that a swapFee is charged to the user whenever they are executing a swap. This can be seen from the code snippet below:

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
});

We can see that the amountIn value reflects that a swap fee reduction is factored in. But at the same time the calculation for the amountOutMinimum does not factor this in, we can see this from the the code below:

uint256 minimumAmountOut = calculateMinimumAmountOut(_inToken, _outToken, _amount);
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);
}

Here we see that the function call calculateMinimumAmountOut() does not factor in the reduction in amount to be swapped due to the fees.

Impact

This can result in the swap() transaction constantly reverting due to the failure in accounting for the swap amount. In times of high volatility this can result in a user being liquidated when they should've been able to swap their funds, but instead losing it all to liquidations.

Tools Used

Manual Review

Recommendations

To solve this issue, the following code change can be made to reflect the change in amount to be swapped due to the value of fees charged to the user.

uint256 minimumAmountOut = calculateMinimumAmountOut(_inToken, _outToken, _amount - swapFee);
Updates

Lead Judging Commences

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

swapfee-incorrect-calc

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

swapfee-incorrect-calc

Support

FAQs

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