Closed howlbot-integration[bot] closed 3 months ago
koolexcrypto marked the issue as duplicate of #33
koolexcrypto marked the issue as partial-25
koolexcrypto marked the issue as not a duplicate
koolexcrypto marked the issue as duplicate of #33
koolexcrypto marked the issue as partial-25
Lines of code
https://github.com/code-423n4/2024-05-loop/blob/40167e469edde09969643b6808c57e25d1b9c203/src/PrelaunchPoints.sol#L240-L266 https://github.com/code-423n4/2024-05-loop/blob/40167e469edde09969643b6808c57e25d1b9c203/src/PrelaunchPoints.sol#L405-L442 https://github.com/code-423n4/2024-05-loop/blob/40167e469edde09969643b6808c57e25d1b9c203/src/PrelaunchPoints.sol#L491-L505
Vulnerability details
Impact
User can by passing 0 as a
_percentage
, receivelpETH
based on the ethers in the contract.Proof of Concept
If the
PrelaunchPoints.sol
contract has native ether, any user can getlpETH
for them without sending anything.The user only needs to have a balance in the contract of the token that passes when he perform the attack to pass this check - it can be 1 wei.
User will call
claim()
with:_token
- anyToken_percentage
- 0Exchange
- TransformERC20_data
:Then in
_claim()
it will enter the else statement,userClaim
will become 0 because its - *`userStake 0 / 100 = 0`**.Then
_validateData()
will pass correctly, his balance will not be changed. When_fillQuote()
is called, nothing will be exchanged because it will passuserClaim
which is 0, so no ethers will enter the contract, andboughtETHAmount
will remain the same. TheclaimedAmount
will then be the contract balance and will be deposited intolpETH
, by passing him as receiver, causing him to receivelpETH
based on the Ether balance in the contract without having to sent anything.PrelaunchPoints.sol#L240-L266
PrelaunchPoints.sol#L405-L442
PrelaunchPoints.sol#L491-L505
Tools Used
Manual Review
Recommended Mitigation Steps
I think the purpose of
boughtETHAmount
was to deposit inlpETH
only if there is some swap that increases the native balance, so_claim()
should be changed to deposit inlpETH
onlyboughtETHAmount
which is calculated in_fillQuote()
this can be done by returningboughtETHAmount
from_fillQuote()
and then passing it tolpETH.deposit{value: boughtETHAmount}(_receiver)
.Assessed type
Math