LoopFi - XDZIBECX's results

A dedicated lending market for Ethereum carry trades. Users can supply a long tail of Liquid Restaking Tokens (LRT) and their derivatives as collateral to borrow ETH for increased yield exposure.

General Information

Platform: Code4rena

Start Date: 01/05/2024

Pot Size: $12,100 USDC

Total HM: 1

Participants: 47

Period: 7 days

Judge: Koolex

Id: 371

League: ETH

LoopFi

Findings Distribution

Researcher Performance

Rank: 29/47

Findings: 1

Award: $71.11

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

Awards

71.1111 USDC - $71.11

Labels

bug
3 (High Risk)
partial-25
sufficient quality report
:robot:_07_group
duplicate-33

External Links

Lines of code

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

Vulnerability details

Impact

The bug can lead to incorrect issuance of lpETH tokens during the claim process, potentially resulting in financial loss or discrepancy for users. If the contract holds any ETH before a swap, the claimedAmount calculation will be incorrect, causing either over-minting or under-minting of lpETH.

Root of the bug

the bug is in the assumption that the entire ETH balance of the contract post-swap corresponds to the amount of _token swapped. And The current implementation does not account for any pre-existing ETH balance in the contract. We have The _claim function is designed to allow users to claim their vested lpETH. If the _token is ETH, it calculates claimedAmount based on the user's share of totalLpETH. If the _token is not ETH, it calls _fillQuote to swap the token to ETH and then converts the received ETH to lpETH.

if (_token == ETH) {
    claimedAmount = userStake.mulDiv(totalLpETH, totalSupply);
    balances[msg.sender][_token] = 0;
    lpETH.safeTransfer(_receiver, claimedAmount);
} else {
    uint256 userClaim = userStake * _percentage / 100;
    _validateData(_token, userClaim, _exchange, _data);
    balances[msg.sender][_token] = userStake - userClaim;

    // Swap token to ETH
    _fillQuote(IERC20(_token), userClaim, _data);

    // Convert swapped ETH to lpETH (1 to 1 conversion)
    claimedAmount = address(this).balance;
    lpETH.deposit{value: claimedAmount}(_receiver);
}

The vulnerability Is in this line :

claimedAmount = address(this).balance;

Here in this calculation assumes that the entire ETH balance of the contract after calling _fillQuote is the result of the token swap. This assumption fails if the contract had any pre-existing ETH balance.

The calculation does not isolate the ETH received from the swap but instead uses the total ETH balance of the contract, which can be misleading if there was already ETH in the contract before the swap.

Proof of Concept

Here is the scenario that I test with:

Scenario Demonstration

Consider the following scenario:

  • letโ€™s say The contract has a pre-existing balance of 10 ETH.
  • A user claims 1,000 units of _token that are swapped for 1 ETH via _fillQuote.
  • Post-swap, the contract's balance becomes 11 ETH.
  • The line claimedAmount = address(this).balance; assigns claimedAmount as 11 ETH.
  • lpETH is minted based on 11 ETH instead of the correct 1 ETH, leading to over-minting of lpETH.
  • And as result: Claimed Amount (ETH): 11 Contract lpETH Balance: 11 Itโ€™s show the incorrect claimed amount due to pre-existing ETH in the contract.

Tools Used

Manual review

the ETH received from the swap should be calculated separately

Assessed type

Other

#0 - c4-judge

2024-05-15T13:36:09Z

koolexcrypto marked the issue as duplicate of #18

#1 - c4-judge

2024-05-15T13:36:20Z

koolexcrypto marked the issue as partial-75

#2 - c4-judge

2024-06-05T07:29:36Z

koolexcrypto changed the severity to 2 (Med Risk)

#3 - c4-judge

2024-06-05T09:37:27Z

koolexcrypto marked the issue as partial-50

#4 - c4-judge

2024-06-05T09:41:00Z

koolexcrypto changed the severity to 3 (High Risk)

#5 - c4-judge

2024-06-05T09:41:25Z

koolexcrypto marked the issue as duplicate of #33

#6 - c4-judge

2024-06-11T07:48:14Z

koolexcrypto marked the issue as partial-25

#7 - c4-judge

2024-06-11T07:50:02Z

koolexcrypto marked the issue as not a duplicate

#8 - c4-judge

2024-06-11T07:50:07Z

koolexcrypto changed the severity to QA (Quality Assurance)

#9 - c4-judge

2024-06-11T07:50:15Z

koolexcrypto marked the issue as grade-c

#10 - c4-judge

2024-06-11T08:17:45Z

koolexcrypto removed the grade

#11 - c4-judge

2024-06-11T08:17:57Z

This previously downgraded issue has been upgraded by koolexcrypto

#12 - c4-judge

2024-06-11T08:18:11Z

koolexcrypto marked the issue as duplicate of #33

#13 - c4-judge

2024-06-11T08:18:14Z

koolexcrypto marked the issue as partial-25

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax ยฉ 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter