Due to the first in last out nature of the poolsFeeData, attacker can prevent users from withdrawing liquidity permanently by transferring to them millions of dust NFT positions over filling the feeData[] and causing OOG errors during withdrawals
during withdrawals in UpliftOnlyExample::onAfterRemoveLiquidity() we start looping from the last deposit (localData.feeDataArrayLength - 1)
This opens up an attack on large valuable positions by malicious BOTs (especially in L2s where gas price is very cheap), here what would happen:
1- Attacker sees very large valuable deposit position
2- Attacker deposit dust value positions and transfer the NFT to the victim (taking advantage of afterUpdate hook in NFT transfer, pushing the position to the end of feeDataArray of victim)
3- Attack is repeated millions of times, causing any attempt to withdraw the actual first position of the user to cause OOG reverts
4- The victim can't transfer his valuable LP NFT position to other wallet as a solution, since transfer will try to re-order the array of the sender that will cause OOG reverts too
5- the victim will try to remove those dust positions batch by batch to reach his first position, but the malicious bot of the attacker will track the victim poolsFeeData after each block (no need to front run, valid attack path on L2s), adding more position to the victim if needed
Attack is feasible since its on L2s and using dust positions to DOS (very small loss overall to attacker to keep the attack running)
This was possible due to:
when transferring we don't check the array size of to if it has passed 100 or not
the FILO nature when withdrawing, and re-ordering when transferring
any one can enlarge the size of other people by transferring to them the NFT, and array will grow in afterUpdate hook
no minimum LP deposits to prevent dusts deposits
Freeze of funds to the victim
Manual Review
implement minimum LP deposits
check for length of feeDataArray of the to during transfers and prevent it it will exceed
give a way to withdraw specific position index (if FILO implementation is not very important)
give the ability to guard against who can transfer his NFT position to me (set by user him self)
Likelihood: Medium/High, anyone can receive an unlimited NFT number but will cost creation of LP tokens and sending them. Impact: Low/Medium, DoS the afterUpdate and addLiquidityProportional but will be mitigable on-chain because a lot of those NFT can be burn easily in onAfterRemoveLiquidity.
Likelihood: Medium/High, anyone can receive an unlimited NFT number but will cost creation of LP tokens and sending them. Impact: Low/Medium, DoS the afterUpdate and addLiquidityProportional but will be mitigable on-chain because a lot of those NFT can be burn easily in onAfterRemoveLiquidity.
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.