This repository has been archived by the owner on May 26, 2024. It is now read-only.
xiaoming90 - Fewer than expected LP tokens if the pool is imbalanced during vault restoration #82
Labels
Has Duplicates
A valid issue with 1+ other issues describing the same vulnerability
High
A valid High severity issue
Reward
A payout will be made for this issue
Sponsor Confirmed
The sponsor acknowledged this issue is valid
Will Fix
The sponsor confirmed this issue will be fixed
xiaoming90
high
Fewer than expected LP tokens if the pool is imbalanced during vault restoration
Summary
The vault restoration function intends to perform a proportional deposit. If the pool is imbalanced due to unexpected circumstances, performing a proportional deposit is not optimal. This results in fewer pool tokens in return due to sub-optimal trade, eventually leading to a loss for the vault shareholder.
Vulnerability Detail
Per the comment on Line 498, it was understood that the
restoreVault
function intends to deposit the withdrawn tokens back into the pool proportionally.https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/common/SingleSidedLPVaultBase.sol#L501
The main reason to join with all the pool's tokens in exact proportions is to minimize the price impact or slippage of the join. If the deposited tokens are imbalanced, they are often swapped internally within the pool, incurring slippage or fees.
However, the concept of proportional join to minimize slippage does not always hold with the current implementation of the
restoreVault
function.Proof-of-Concept
This issue affects both Curve and Balancer pools since joining an imbalanced pool will always incur a loss.
Explantation of imbalance pool
A Curve pool is considered imbalanced when there is an imbalance between the assets within it. For instance, the Curve stETH/ETH pool is considered imbalanced if it has the following reserves:
If a Curve Pool is imbalanced, attempting to perform a proportional join will not give an optimal return (e.g. result in fewer Pool LP tokens received).
In Curve Pool, there are penalties/bonuses when depositing to a pool. The pools are always trying to balance themselves. If a deposit helps the pool to reach that desired balance, a deposit bonus will be given (receive extra tokens). On the other hand, if a deposit deviates from the pool from the desired balance, a deposit penalty will be applied (receive fewer tokens).
The following is the source code of
add_liquidity
function taken from https://github.com/curvefi/curve-contract/blob/master/contracts/pools/steth/StableSwapSTETH.vy. As shown below, the function attempts to calculate thedifference
between theideal_balance
andnew_balances
, and uses thedifference
as a factor of the fee computation, which is tied to the bonus and penalty.Following is the mathematical explanation of the penalties/bonuses extracted from Curve's Discord channel:
Impact
There is no guarantee that a pool will always be balanced. Historically, there have been multiple instances where the largest curve pool (stETH/ETH) has become imbalanced (Reference #1 and #2).
If the pool is imbalanced due to unexpected circumstances, performing a proportional deposit is not optimal, leading to the deposit resulting in fewer LP tokens than possible due to the deposit penalty or slippage due to internal swap.
The side-effect is that the vault restoration will result in fewer pool tokens in return due to sub-optimal trade, eventually leading to a loss of assets for the vault shareholder.
Code Snippet
https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/common/SingleSidedLPVaultBase.sol#L501
https://github.com/sherlock-audit/2023-10-notional/blob/main/leveraged-vaults/contracts/vaults/BalancerComposableAuraVault.sol#L48
Tool used
Manual Review
Recommendation
Consider providing the callers the option to deposit the reward tokens in a "non-proportional" manner if a pool becomes imbalanced. For instance, the function could allow the caller to swap the withdrawn tokens in external DEXs within the
restoreVault
function to achieve the most optimal proportion to minimize the penalty and slippage when re-entering the pool. This is similar to the approach in the vault's reinvest function.The text was updated successfully, but these errors were encountered: