Attackers could steal the ETH contained in the PrelaunchPoints contract
howlbot-integration opened this issue · 5 comments
Lines of code
Vulnerability details
Impact
When users claim lpETH and the specified _token is not ETH, if there is ETH in the PrelaunchPoints contract transferred by mistake by others, the contract will also convert this part of ETH into lpETH for the user. This is because the amount of lpETH calculated for the user's claim in the _claim function is address(this).balance, rather than the actual amount of ETH obtained through exchangeProxy with the _token in the _fillQuote function.
_fillQuote(IERC20(_token), userClaim, _data);
// Convert swapped ETH to lpETH (1 to 1 conversion)
claimedAmount = address(this).balance;
lpETH.deposit{value: claimedAmount}(_receiver);Although the comment states, "At this point there should not be any ETH in the contract," this is an ideal situation. In reality, it is highly possible that someone could mistakenly transfer ETH to the PrelaunchPoints contract.
Proof of Concept
- User A calls the
lockfunction, locking an amount of_tokeninto thePrelaunchPointscontract. - The owner calls the
convertAllETHfunction to convert the ETH in thePrelaunchPointscontract into lpETH and updates thestartClaimDatevariable, allowing users who have locked assets in the contract to start claiming lpETH. - User B mistakenly transfers 10 ETH to the
PrelaunchPointscontract. - User A observes User B's mistaken transfer and immediately calls the
claimfunction to claim lpETH. Theclaimfunction calls the_claimfunction for the actual operation. In the_claimfunction,_fillQuoteis invoked, which converts User A's _token into ETH held within thePrelaunchPointscontract. - The contract converts the amount of ETH denoted as
claimedAmountinto lpETH for User A’s specified_receiver. Note that theclaimedAmounthere isaddress(this).balance, which includes User B's 10 ETH, not just theboughtETHAmountcalculated in the final_fillQuotefunction. - User A successfully steals User B's 10 ETH.
Tools Used
None
Recommended Mitigation Steps
- It is suggested that the
_fillQuotefunction return the final calculatedboughtETHAmountto the_claimfunction. In the_claimfunction, convert the amount of ETH denoted asboughtETHAmountinto lpETH for the_receiver. - It is recommended to implement a revert logic in the
receivefunction to prevent users from mistakenly transferring ETH into the contract.
Assessed type
Other
koolexcrypto changed the severity to 2 (Med Risk)
koolexcrypto marked the issue as partial-50
koolexcrypto changed the severity to 3 (High Risk)