Closing an IchiVaultSpell position is susceptible to slippage when swapping tokens
Summary
The token swap performed in the IchiVaultSpell.withdrawInternal function is vulnerable to slippage and can result in a reduction in the expected profits when closing an IchiVaultSpell position.
Vulnerability Detail
The withdrawInternal function in the IchiVaultSpell contract redeems the Ichi Vault LP tokens and subsequently swaps the withdrawn tokens to the borrowToken token to repay the outstanding debt. The remaining borrowToken tokens are potential profits for the user and will be refunded later on.
The sqrtPriceLimitX96 parameter for the IUniswapV3Pool.swap function is set to UniV3WrappedLibMockup.MAX_SQRT_RATIO - 1 or UniV3WrappedLibMockup.MIN_SQRT_RATIO + 1 depending on the borrowToken token. Using these constants is equal to using sqrtPriceLimitX96 = 0 when utilizing the Uniswap V3 SwapRouter (see SwapRouter.sol#L105-L107).
Consequently, slippage can occur, causing users to receive fewer borrowToken tokens than expected and reducing their profits.
Please note that having the sqrtPriceLimitX96 parameter provided by the user can result in a token swap that is only partially filled, and the remaining unswapped tokens are locked in the contract.
Impact
A user closing a position can possibly receive fewer profits than expected due to slippage when swapping the withdrawn tokens to the borrowed token.
Consider adding a user-controllable slippage protection parameter (e.g. amountOutMinimum - as used by Uniswap V3 SwapRouter.sol#L128) to specify the minimum amount of borrowToken tokens to receive after the swap.
berndartmueller
medium
Closing an
IchiVaultSpell
position is susceptible to slippage when swapping tokensSummary
The token swap performed in the
IchiVaultSpell.withdrawInternal
function is vulnerable to slippage and can result in a reduction in the expected profits when closing anIchiVaultSpell
position.Vulnerability Detail
The
withdrawInternal
function in theIchiVaultSpell
contract redeems the Ichi Vault LP tokens and subsequently swaps the withdrawn tokens to theborrowToken
token to repay the outstanding debt. The remainingborrowToken
tokens are potential profits for the user and will be refunded later on.The
sqrtPriceLimitX96
parameter for theIUniswapV3Pool.swap
function is set toUniV3WrappedLibMockup.MAX_SQRT_RATIO - 1
orUniV3WrappedLibMockup.MIN_SQRT_RATIO + 1
depending on theborrowToken
token. Using these constants is equal to usingsqrtPriceLimitX96 = 0
when utilizing the Uniswap V3SwapRouter
(see SwapRouter.sol#L105-L107).Consequently, slippage can occur, causing users to receive fewer
borrowToken
tokens than expected and reducing their profits.Please note that having the
sqrtPriceLimitX96
parameter provided by the user can result in a token swap that is only partially filled, and the remaining unswapped tokens are locked in the contract.Impact
A user closing a position can possibly receive fewer profits than expected due to slippage when swapping the withdrawn tokens to the borrowed token.
Code Snippet
spell/IchiVaultSpell.sol#L312-L314
Tool used
Manual Review
Recommendation
Consider adding a user-controllable slippage protection parameter (e.g.
amountOutMinimum
- as used by Uniswap V3SwapRouter.sol#L128
) to specify the minimum amount ofborrowToken
tokens to receive after the swap.Duplicate of #130