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

Users can bypass locking funds and use claim directly

howlbot-integration opened this issue · 3 comments

Lines of code

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

Vulnerability details

Impact

Users can bypass _processLock and use claim when the start claim date is active. This breaks a core concept in the protocol to lock funds within the period of 120 days at max.

Proof of Concept

Users will call _processLock to transfer thier tokens to PrelaunchPoints contract to be locked, then they have to wait for a period of time until the deposits are paused then after 7 days the claim date is activeted, and only then they can start to claim lpETH.

An attacker can deposit small amount using _processLock let's say 100 WEI amount before the 7 days start, then he will wait for the owner to call convertAllETH, after that he will send an amount of X Native ETH let's say 100e18, and call claim, the attacker will receive an amount of lpETH while he didn't lock any amount before except for 100 WEI.

Break down the Scenario:

  • Bob will deposit 100 WEI of LRT token (e.g stETH).
  • Deposit period is done and now the 7 days started with deposits being paused.
  • The Owner convert all ETH and now the start claim date is active.
  • Pay attention to the comment // At this point there should not be any ETH in the contract, it's true since the conversion is done now there no ETH in the contract.
  • Bob will send 10e18 ETH to PrelaunchPoints contract address.
  • Bob will call claim with 1 WEI amount for stETH Token.
  • _claim will pass if (userStake == 0) since Bob balance is 100 WEI.
  • The block else will be triggerd since it's ERC20 token.
  • _fillQuote will swap 100 WEI to ETH and succeed.
  • Now on L262 the claimedAmount will consider address(this).balance as the amount for the _receiver (Bob).
  • A deposit is done by lpETH.deposit{value: claimedAmount}(_receiver)
  • Bob now receive 10e18 lpETH tokens.

The reason behind this issue, that claimedAmount always consider address(this).balance as the amount that the receiver will get.

Tools Used

Manual Review

Recommended Mitigation Steps

Return the amount that was swapped and use it instead of address(this).balance

Assessed type

Other

koolexcrypto marked the issue as duplicate of #6

koolexcrypto marked the issue as duplicate of #33

koolexcrypto marked the issue as satisfactory