The Standard

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

wrong minimumAmountOut value used when swaping tokens in SmartVaultV3

Summary

In contracts/SmartVaultV3::swap() method, we execute the swap with a minimumAmountOut that is in reality greater than the actual minimumAmountOut taking into account the real value of the amountIn.

Vulnerability Details

In contracts/SmartVaultV3::swap() method, we determin the value of the minimumAmountOut variable based on the actual value the vault owner wants to swap( let's call that value _amount). This effectively assumes that, amountIn in during the swap equals _amount. But then when constructing the swap params we indicate that, the amountIn is less than the amount the user wished to swap by a delta of swapFee. This goes against the assumption a few sentences back and thus, the minimumAmountOut used during the swap is actually greater than what it is really supposed to be and may cause the swap to fail in situations it should not have. For example, when the swap result in the amount out to be less than minimumAmountOut but still is greater than the minimumAmountOut for an amountIn that is amountIn = _amount - swapFee

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); // => notice this amount.
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: inToken,
tokenOut: getSwapAddressFor(_outToken),
fee: 3000,
recipient: address(this),
deadline: block.timestamp,
amountIn: _amount - swapFee, // => notice how we're reducing the swapFee
amountOutMinimum: minimumAmountOut, // => notice this amount
sqrtPriceLimitX96: 0
});

Impact

Swaps may fail due to the minimumAmountOut value not being met during the swap even though minimumAmountOut might be an incorrect value for the value provided in amountIn

Tools Used

Manual review

Recommendations

calculate the minimumAmountOut based on the actual value that is used on amountIn during the swap.

//SmartVaultV3.sol
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);
+ uint256 minimumAmountOut = calculateMinimumAmountOut(_inToken, _outToken, _amount - swapFee);
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 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.