code-423n4 / 2024-05-loop-findings

4 stars 4 forks source link

The `withdraw()` function forces users to claim `lpETH` even in emergency mode #77

Closed howlbot-integration[bot] closed 4 months ago

howlbot-integration[bot] commented 4 months ago

Lines of code

https://github.com/code-423n4/2024-05-loop/blob/0dc8467ccff27230e7c0530b619524cc8401e22a/src/PrelaunchPoints.sol#L292

Vulnerability details

Impact

With the current implementation of the withdraw() function ETH is impossible to withdraw after startClaimDate in emergency mode. It can cause an issue, as when the Loop protocol chooses to go into emergency mode, the lpETH is likely to be illiquid on all DEXes, meaning that unless the issue which caused emergency is resolved, the users essentially lost their money. Not only it heavily impacts the trust to the Loop protocol's owner who can at any time decide to start the emergency mode, but also it incentivizes users to only use LRTs as their stake that can be easily withdrawn in case of such situation.

Proof of Concept

  1. User stakes ETH
  2. After time passes, the owner starts the claim period
  3. For any reason, the owner starts emergency mode
  4. The user tries call withdraw() but it reverts due to:
    if (block.timestamp >= startClaimDate) {
                revert UseClaimInstead();
            }

    Tools Used

    Manual Review

Recommended Mitigation

Instead of converting all ETH to lpETH when calling convertAllETH and then transferring it to users the contract could use lpETH.deposit() function just like for LRTs stake. This way no lpETH has to be held in the PrelaunchPoints contract making it more encouraging for the users to lock ETH rather than only LRTs and it increases the reliability of the protocol.mmended Mitigation Steps

Assessed type

Token-Transfer

c4-judge commented 4 months ago

koolexcrypto marked the issue as primary issue

c4-judge commented 4 months ago

koolexcrypto marked the issue as duplicate of #81

c4-judge commented 3 months ago

koolexcrypto marked the issue as unsatisfactory: Invalid