A math error calculating fees in UpliftOnlyExample.sol causes removeLiquidityProportional to revert with an underflow error when there has been a significant price change (51x in the POC below). Funds are then stuck in the vault until the price drops back to a supported range.
A workaround exists: users can transfer the LPNFT to another account (and optionally back again) to eliminate fees and therefor avoid this revert as well. However I believe that's a bug to be addressed and not an intentional workaround for this.
The impacted code is in the onAfterRemoveLiquidity hook function.
lpTokenDepositValueChange is a ratio. It's equal to 51 in the POC of the revert below, representing a 51x price increase (or a 52x price change) since deposit:
Source: UpliftOnlyExample.sol#L474-L476
Then that ratio is multiplied by the fee. In the POC below, the fee is 2% so a 50x price increase charges 100%:
Source: UpliftOnlyExample.sol#L481-L483
The feePerLP multiplied by the amount being removed, so when the feePerLP is > 100% we have a feeAmount > the deposit:
Source: UpliftOnlyExample.sol#L495
Now we calculate a feePercentage by comparing that feeAmount to bptAmountIn -- this value is equivalent to the feePerLP calculated above but averaged across LPNFTs:
Source: UpliftOnlyExample.sol#L514
The exit fee is calculated using that percentage, which may be > 100% -- resulting in an exitFee > the amount available:
Source: UpliftOnlyExample.sol#L523
Now when we attempt to subtract that fee from the amount being withdrawn, the transaction reverts with an underflow error on fees > 100%:
Source: UpliftOnlyExample.sol#L530
When upliftFeeBps is 2% then a 50x price increase charges 100% fees and anything greater will revert. If upliftFeeBps is increased to 5% than it breaks when over a 20x price increase. These are large but not unreasonable price changes and it's possible the price will never come back down within range again.
Assets become locked within the Vault, preventing users from removing liquidity.
The workaround is clunky at best, and may be considered a bug to be removed (I'll report that as a separate issue).
This POC updates UpliftExample.t.sol, modifying testRemoveLiquidityDoublePositivePriceChange which was testing a 2x price change. We increase the price change to 52x and confirm it reverts.
Additionally we can validate the transferFrom workaround by uncommenting that section and noting that it no longer reverts.
Bound the fee to be <= a reasonable max, e.g.
Likelihood: Low, will happen only if benefits are huge. (x50 to take 100%, x25 to take 50%). Impact: feePerLP will indefinitely increase, taking users profits and finaly DoS the function.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.