Closed howlbot-integration[bot] closed 4 months ago
koolexcrypto marked the issue as duplicate of #18
koolexcrypto changed the severity to 2 (Med Risk)
koolexcrypto marked the issue as partial-75
koolexcrypto changed the severity to 3 (High Risk)
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/0dc8467ccff27230e7c0530b619524cc8401e22a/src/PrelaunchPoints.sol#L321-L322
Vulnerability details
Impact
One of the main invariants of the protocol states, "Users that deposit ETH/WETH get the correct amount of lpETH on claim (1 to 1 conversion)." However there is a critial vulnerability and if it is exploited, it would break this invariant, resulting in users not receiving lpETH at the 1:1 peg. Consequently, operations dependent on this invariant, such as determining the rewards from staking lpETH could be affected, calculating the lpETH price which in turn will affect integrating Loopfi with other protocols, because other protocols that accept lpETH as collateral might experience liquidation events and more. This will significantly impair the usability of the protocol.
Proof of Concept
This vulnerability arises due to the susceptibility of the initial ETH amount that should be deposited to the lpETH contract to manipulation, primarily through the risk of direct ETH transfer by malicious actors to the protocol. Let's examine how this issue can be exploited:
In order to convert all the ETH initially locked by users to lpETH, the contract owner should invoke the
convertAllETH()
function. The balance that should be deposited to lpETH contract is calculated by retrieving thePrelaunchPoints
contract's balance, which should represent the total ETH deposited by users:However, because this contract can accept direct ETH transfers through its
receive()
function, the calculation of the lpETH deposit amount can be disrupted. A malicious actor can front run the owner before he callconvertAllETH()
and send ETH to the contract, breaking this invariant.This results in
totalLpETH
being higher than it should be, leading to incorrect calculations wherever it is used. For example, in the_claim()
function, the amount a user is entitled to claim should be calculated by(user ETH deposit amount * totalLpETH) / totalSupply
. However, due to this vulnerability,totalLpETH
will be much higher thantotalSupply
, leading to incorrect calculations of the lpETH user's claim and consequently other issues such as incorrect staking reward amounts. For example in the following functionclaimedAmount
will be much higher than it should beI've created the following test to visualize the consequences of this bug. It can be simply copied and pasted into
PrelaunchPoints.t.sol
. Additionally, I've developed a helper function to visualize the amount of lpETH that a user is entitled to. This function should be included inPrelaunchPoints.sol
, it calculates entitlements in the same manner as the_claim()
function and it is used withing the PoC test:helper function:
PoC test: Run command:
forge test --match-test testDirectETHTransferExploit -vv
Console output:
Tools Used
VSCode, Foundry
Recommended Mitigation Steps
Since a 1:1 peg with ETH is expected, the calculation of the amount to be deposited to lpETH can be directly retrieved from the
totalSupply
state variable. This variable accurately tracks the amount of ETH deposited by users.Assessed type
ETH-Transfer