Open c4-bot-10 opened 4 months ago
The Warden outlines an issue with the fee collection mechanism whenever a position is claimed that would result in the contract claiming more funds than the user is due and the fee taker acquiring this difference.
In turn, this will result in all consequent claim operations of other NFT IDs on the same tick range (i.e. the same pool) to fail potentially permanently due to being unable to capture the fee-related portion. I consider this to be a significant flaw and one that merits a high-risk severity rating.
alex-ppg marked the issue as satisfactory
alex-ppg marked the issue as selected for report
alex-ppg marked the issue as primary issue
Lines of code
https://github.com/code-423n4/2024-06-vultisig/blob/main/src/ILOPool.sol#L246-L247
Vulnerability details
Impact
Users should be able to claim Uniswap fees for their current liquidity position regardless of their pending vestings, or cliff.
But most users won't be able to claim those Uniswap fees.
It is also possible that they won't be able to claim their vesting if they accumulate sufficient unclaimed Uniswap fees.
Vulnerability Details
The root issue is that the
claim()
function collects ALL the owed tokens at once, including the ones from the burnt liquidity, but also the fees corresponding to ALL positions:https://github.com/code-423n4/2024-06-vultisig/blob/main/src/ILOPool.sol#L246-L247
Then the platform fees are sent alongside the Uniswap fees from the users that still didn't claim
amountCollected - amount
:https://github.com/code-423n4/2024-06-vultisig/blob/main/src/ILOPool.sol#L252-L260
The next time a user calls
claim()
,pool.collect()
will not contain any Uniswap fees as all of them have already been claimed and sent to the first claimer + the rest to the fee taker.If the platform fees are enough to cover the owed fees for the claiming user, the transaction might succeed (this may be possible if the burnt liquidity is enough).
As time passes, more fees will be accumulated, and when Uniswap fees > platform fees, the transaction will also revert even for unclaimed vestings with liquidity to burn.
In addition, in most cases after the initial vesting, users won't be able to claim Uniswap fees, as no fees will be collected, and the contract doesn't hold those assets (they have been sent to the fee taker).
Proof of Concept
This POC shows how after one user claims their share of the fees, there are no more fee tokens to collect for the next claims, and the transactions revert.
test/ILOPool.t.sol
ILOPoolTest
contract intest/ILOPool.t.sol
forge test --mt testClaimFeesRevert
Recommended Mitigation Steps
Here's an suggestion on how this could be solved. The idea is to only
collect()
the tokens corresponding to the liquidity of thetokenId
position. So that the next user can also claim their share.Assessed type
Uniswap