Renzo - Stefanov's results

A protocol that abstracts all staking complexity from the end-user and enables easy collaboration with EigenLayer node operators and a Validated Services (AVSs).

General Information

Platform: Code4rena

Start Date: 30/04/2024

Pot Size: $112,500 USDC

Total HM: 22

Participants: 122

Period: 8 days

Judge: alcueca

Total Solo HM: 1

Id: 372

League: ETH

Renzo

Findings Distribution

Researcher Performance

Rank: 104/122

Findings: 1

Award: $0.00

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/RestakeManager.sol#L274

Vulnerability details

Impact

totalWithdrawalQueueValue is added to the totalTVL, which is used to calculate ezETH tokens that a user can mint after deposit and depositETH. If totalWithdrawalQueueValue is calculated incorectly, then users will take incorrect ezETH amount.

Proof of Concept

calculateTVLs function calculates the TVLs for each operator delegator by individual token, total for each operator delegator, and total for the protocol.

totalTVL is combination of each operator delegator TVL + address(depositQueue).balance, (address(withdrawQueue).balance & totalWithdrawalQueueValue. However, totalWithdrawalQueueValue is not calculated properly.

Total withdrawal queue value get calculated in the second of 2 for cycles. The first one cycles through all operator delegators, which we don't need for our equation, and the second cycles through all collateral tokens, which is all we need to calculate totalWithdrawalQueueValue. Unfortunately, the index from the first cycle is used. So we are taking the same collateralToken address (collateralTokens[i]) and calculating every token balance (collateralTokens[j].balanceOf(withdrawQueue)) with it.This means that every token balance will have the collateral value of collateralTokens[0]

https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/RestakeManager.sol#L317


        // record token value of withdraw queue
        if (!withdrawQueueTokenBalanceRecorded) {
@>          totalWithdrawalQueueValue += renzoOracle.lookupTokenValue(
                collateralTokens[i],
                collateralTokens[j].balanceOf(withdrawQueue)
            );
        }

Tools Used

Manual Review

Use the same collateralToken address position both for the token and balance position


        // record token value of withdraw queue
        if (!withdrawQueueTokenBalanceRecorded) {
            totalWithdrawalQueueValue += renzoOracle.lookupTokenValue(
-               collateralTokens[i],
+               collateralTokens[j],
                collateralTokens[j].balanceOf(withdrawQueue)
            );
        }

Assessed type

Math

#0 - c4-judge

2024-05-16T10:36:52Z

alcueca marked the issue as satisfactory

#1 - c4-judge

2024-05-16T10:38:47Z

alcueca changed the severity to 2 (Med Risk)

#2 - c4-judge

2024-05-16T10:39:08Z

alcueca changed the severity to 3 (High Risk)

#3 - c4-judge

2024-05-20T04:26:26Z

alcueca changed the severity to 2 (Med Risk)

#4 - c4-judge

2024-05-23T13:47:20Z

alcueca changed the severity to 3 (High Risk)

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