Closed howlbot-integration[bot] closed 3 months ago
koolexcrypto marked the issue as primary issue
We manage this situation offchain, since points depend on the Locked event. Claimed event is used as a safeguard against tricky withdrawals and cannot boost points the way mentioned above. We might implement filter on ETH receive but not for this reason
koolexcrypto marked the issue as duplicate of #33
koolexcrypto marked the issue as partial-75
@koolexcrypto Forgive me, but I do not understand why this issue is graded partial-75 when it identifies the full impact and exploit scenario related to #33 and builds upon it for the staking part. I have two issues marked as duplicates of #33
Since code4rena only awards one of 2 duplicates when a researcher has more than 1 duplicate tied to a primary issue, I think it is unfair to grade issue #48 as partial-75 when in fact it elaborates on the full impact and will then mess up rewarding for my issues. Making issue #48 a full duplicate will resolve this.
Could you please take a look at this? Thanks!
Hi @rexjoseph
I do agree. marking this as a full credit.
koolexcrypto marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2024-05-loop/blob/main/src/PrelaunchPoints.sol#L226-L235 https://github.com/code-423n4/2024-05-loop/blob/main/src/PrelaunchPoints.sol#L263 https://github.com/code-423n4/2024-05-loop/blob/main/src/PrelaunchPoints.sol#L262
Vulnerability details
Impact
A user can lock up a very small amount of
LRT
e.g 0.5rsETH
while earning 10x+ more staking rewards compared to another user who locked up 10rsETH
effectively taking most of the staking reward pool from other honest stakers who are unaware of the exploit path.Proof of Concept
rsETH
rsETH
lpETH
claimslpETH
is setrsETH
for 9.99lpETH
(assuming he swapped at a favorable price)rsETH
while ending up staking 10.05lpETH
each time which shouldn't be because they only locked 0.5rsETH
. User B can do this 10+ times since 0.05 is only 10% of his 0.5rsETH
deposit which means they get to redeem and stake 100.5lpETH
altogether when they initially only locked 0.5rsETH
.lpETH
and no more. With that being the case, User B now keeps 90+% of the reward pool to themself.address(this).balance
which user B leverages as a backdoor entry to successfully put in a direct ether transfer into the contract before executing theclaimAndStake()
forlpETH
staking which then associates the ether balance in the contract to them allowing them to stake morelpETH
even though their initial lockedrsETH
was very little ~ 0.5rsETH
. This can then be automated to slowly siphon rewards from other users by callingclaimAndStake()
. This is possible because of theLRT
claim process which differs from theETH
andWETH
one.Summarization is to transfer ether into the contract directly slightly before or while executing
claimAndStake()
for yourLRT
each call which will allow you to redeem then stake morelpETH
than it should since lock-up periods are long past.Paste the POC test into the
PreLaunchPoints.t.sol
test file and run the code withforge test --mt testSiphonStakeRewardsPOC
Test result
Tools Used
Manual review
Recommended Mitigation Steps
The contract's usage of
address(this).balance
during claiming oflpETH
is flawed. Rather than assuming the only ether in the contract at that time is the one gotten from the swap transaction for a claim, use a before and after balance to track and properly record the actual balance the swap resulted in. Then, use that delta as the amount to mint to the user inlpETH
that is then staked.Assessed type
Timing