Unaccounted ETH Deposits May Lead to Unintended `lpETH` Minting and Staking
Closed this issue · 6 comments
Lines of code
Vulnerability details
Summary:
The PrelaunchPoints contract currently contains logic that allows users to claim their locked funds as lpETH during a claim period. However, there exists a vulnerability where ETH sent to the contract via direct transfer (fallback function) is not accounted for and may result in more lpETH being minted and potentially staked than intended based on a user's legitimate locked tokens balance.
Description:
In the _claim function, after swapping a user's ERC20 tokens for ETH using _fillQuote, the contract mints lpETH using the entire balance of ETH within the contract, rather than only the amount of ETH that was specifically obtained from the swap. This behavior opens up an opportunity for a user to "front-run" their claim by transferring ETH directly to the contract at the time of calling the claim function, leading to a larger amount of lpETH being minted than is due from their locked ERC20 token balance alone.
Impact:
By sending additional ETH to the contract before claiming, a user can artificially inflate the amount of lpETH that they receive, which could lead to an unfair advantage in the staking process. This may, in turn, distort the staking rewards and undermine the prelaunch point system's integrity and intended economics, leading to possible reputational damage and potential financial loss for legitimate participants.
Steps To Reproduce:
- Lock an ERC20 token in the contract that is approved for conversion to
lpETH. - Call the
claimfunction with parameters to trade the ERC20 for ETH and then mintlpETH. - Immediately before the
claimtransaction is mined, send ETH directly to the contract's address, triggering the fallback function. - Observe that the contract uses the entire ETH balance, which includes the additional ETH sent unintentionally, to mint
lpETH.
Recommendation:
To mitigate this issue, the contract should clearly track and account for the ETH received solely from the execution of the token swap. Only this amount of ETH should be used for the minting of lpETH. The contract can achieve this by checking the ETH balance before and after the swap transaction, using the difference between these balances for minting:
uint256 preSwapBalance = address(this).balance;
// Execute the token to ETH swap
_fillQuote(IERC20(_token), _amount, _swapCallData);
uint256 postSwapBalance = address(this).balance;
// Calculate ETH obtained from the swap
uint256 swappedETHAmount = postSwapBalance - preSwapBalance;
// Only use the swapped ETH amount for lpETH minting
lpETH.deposit{value: swappedETHAmount}(_receiver);Implementing these changes would ensure that only the ETH obtained from swapping locked ERC20 tokens is used for claiming, thereby preventing manipulation by front-running with direct ETH transfers to the contract.
Assessed type
Other
koolexcrypto changed the severity to 3 (High Risk)
koolexcrypto changed the severity to 2 (Med Risk)
koolexcrypto marked the issue as partial-75
koolexcrypto changed the severity to 3 (High Risk)