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
Rank: 89/122
Findings: 2
Award: $0.41
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: guhu95
Also found by: 0rpse, 0x007, 0x73696d616f, 0xCiphky, 0xabhay, Audinarey, Bauchibred, Fassi_Security, GalloDaSballo, GoatedAudits, KupiaSec, LessDupes, MSaptarshi, OMEN, Ocean_Sky, RamenPeople, SBSecurity, Tendency, WildSniper, aslanbek, bill, blutorque, crypticdefense, cu5t0mpeo, d3e4, gjaldon, grearlake, gumgumzum, honey-k12, ilchovski, jokr, josephdara, kennedy1030, p0wd3r, peanuts, stonejiajia, t0x1c, tapir, underdog, zzykxx
0.4071 USDC - $0.41
https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Withdraw/WithdrawQueue.sol#L206-L263
users stops earning rewards once they submit withdrawal request leading to unfair distribution of rewards to people that didn't submit withdrawals yet
in WithdrawQueue::withdraw()
when users submit withdrawal request the protocol check for amount to redeem and it applies cooldownperiod
but as long as this cooldown period stays the amount to withdraw is already declared and stored
this may be unfair for stakers that their money is still there laying in the protocol contract
manual review
Account for the accumulate rewards during the withdrawal period
Other
#0 - C4-Staff
2024-05-15T14:33:33Z
CloudEllie marked the issue as duplicate of #259
#1 - c4-judge
2024-05-17T12:28:23Z
alcueca marked the issue as satisfactory
#2 - c4-judge
2024-05-17T12:35:36Z
alcueca changed the severity to 3 (High Risk)
#3 - c4-judge
2024-05-17T12:35:50Z
alcueca marked the issue as duplicate of #326
🌟 Selected for report: guhu95
Also found by: 0rpse, 0x007, 0x73696d616f, 0xCiphky, 0xabhay, Audinarey, Bauchibred, Fassi_Security, GalloDaSballo, GoatedAudits, KupiaSec, LessDupes, MSaptarshi, OMEN, Ocean_Sky, RamenPeople, SBSecurity, Tendency, WildSniper, aslanbek, bill, blutorque, crypticdefense, cu5t0mpeo, d3e4, gjaldon, grearlake, gumgumzum, honey-k12, ilchovski, jokr, josephdara, kennedy1030, p0wd3r, peanuts, stonejiajia, t0x1c, tapir, underdog, zzykxx
0.4071 USDC - $0.41
https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/RestakeManager.sol#L491-L576
The current idea of ​​creating ezETH and accepting several different assets in it exposes users to losses.
After the release of LRT, which will include the ability to deposit native eth and wrapped staking tokens like cbETH and others, renzo users will be exposed to additional economic risks that may lead to loss of capital. In case of a predictable price drop (e.g. caused by a slashing event in an external liquid staking provider), external users can deposit their funds into renzo before the price drop. They will receive the LRT (corresponding to the value before the price drop, as priceFeed displays the changed price only when it actually happens) and withdraw them once the price drops, sharing their loss with renzo users.
renzo creates a network for issuing Liquid Restaking Tokens (LRTs) that have an underlying asset mix. The idea is to have multiple LRTs like: cbETH,and others reXXX, and for ezETH underlying asset mix will include native ETH and e.g. cbETH (as it is used in tests), or wstETH.
Users depositing their funds into renzo are encouraged by the rewards of staking and re-staking through EigenLayer, but they also bear the risk of penalties and slashing of their deposited funds. However, in case of ezETH , the 3rd party users who are not associated in any way with renzo ecosystem can take advantage of such LRT and make renzo users bear their losses.
Keeping in mind these things:
value of assets like wstETH, cbETH generally increase over time, there are price drops for assets like cbETH and others, but most of the time these are temporary, things that can cause price drops for assets like wstETH, cbETH include: slashing, lower demand / lack of trust for particular asset, withdrawal caused by people who accumulated big rewards over time, lower demand / lack of trust is unpredictable, however, big withdrawals can be monitored and slashing is a process spread over time, so there is a time when you know the value of asset will drop, liquid staking providers like LIDO etc., protects themselves from "withdrawal before slashing" by making withdrawal process long enough so that slashing can affect the users who request to withdraw, user within renzo ecosystem can deposit asset1 to get LRT, and then request to withdraw asset2. Consider the following scenario (values used for ease of calculation and to illustrate the attack, real values will be presented later in this description):
renzo issues LRT (ezETH) that supports LSD assets (ie. cbETH and native ETH).
200 ETH is deposited inside renzo by users and 200 ezETH were minted.
The attacker (cbETH staker) has 100 cbETH (price is e.g. 1 cbETH = 2 ETH, their cbETH is worth 200 ETH)
The attacker knows through monitoring slashing events and big withdrawalas that price will drop soon.
The attacker deposit their 100 cbETH to renzo to get 200 ezETH (as current price is still 1 cbETH = 2 ETH) Total value locked on renzo will increase from 200 ETH to 400 ETH (200 eth and 100 cbETH)
Price of cbETH now drops by 50% (so now 1 cbETH = 1 ETH)
Total value locked on renzo will decrease from 400 ETH to 300 ETH (as 200cbETH is now worth only 100 ETH).
The attacker decides to request withdraw all of their cbETH by burning only 150 ezETH and they also request to withdraw 50 ETH by burning another 100 ezETH.
Attacker gets 200 cbETH back (current price is 100 ETH) and additional 50 ETH.
Attacker buys additional cbETH for their additional 50 ETH, so know they have 250 cbETH (from another source)
Now price recover, so its again 1 cbETH = 2 ETH.
Attacker now have 250 cbETH worth 500 ETH, and renzo users have 150 ETH (lost 50 ETH, as attacker delegeted their risk to ernzo users).
However, the price will not drop by 50%. The real numbers could be up to 10%.
Looking this examples of assets that are considered to be added to ezETH(ie. cbETH ) we can observe the following:
cbETH (https://coinmarketcap.com/currencies/coinbase-wrapped-staked-eth/) there are price drops based on data from last 365 days the biggest percentage drop in price occurred on March 11, 2023, with a drop of approximately 8.25%
manual review
The problem is not easy to fix and several security mechanisms can be used:
users could be allowed to withdraw only the type of assets they deposit you can monitor price drop events and temporarily freeze deposits you can set a minimum period for the user between his deposit and withdrawal so that he cannot take advantage of price fluctuations single LRTs can be issued for assets that are subject to such events (price drops predicted some time in advance)
Context
#0 - C4-Staff
2024-05-15T16:35:14Z
CloudEllie marked the issue as duplicate of #34
#1 - alcueca
2024-05-16T13:52:55Z
@itsmetechjay, this is suspiciously similar to #34. I'd invalidate it on those grounds.
#2 - c4-judge
2024-05-16T14:03:20Z
alcueca marked the issue as duplicate of #326
#3 - c4-judge
2024-05-17T12:48:31Z
alcueca marked the issue as satisfactory
🌟 Selected for report: guhu95
Also found by: 0rpse, 0x007, 0x73696d616f, 0xCiphky, 0xabhay, Audinarey, Bauchibred, Fassi_Security, GalloDaSballo, GoatedAudits, KupiaSec, LessDupes, MSaptarshi, OMEN, Ocean_Sky, RamenPeople, SBSecurity, Tendency, WildSniper, aslanbek, bill, blutorque, crypticdefense, cu5t0mpeo, d3e4, gjaldon, grearlake, gumgumzum, honey-k12, ilchovski, jokr, josephdara, kennedy1030, p0wd3r, peanuts, stonejiajia, t0x1c, tapir, underdog, zzykxx
0.4071 USDC - $0.41
Detailed description of the impact of this finding.
Validators can lose part of their deposit via penalties or slashing events:
In case of penalties Eigenlayer can be notified of the balance drop via the permissionless function EigenPod::verifyBalanceUpdates()
.
In case of slashing the validator is forced to exit and Eigenlayer can be notified via the permissionless function EigenPod::verifyAndProcessWithdrawals()
because the slashing event is effectively a full withdrawal.
As soon as either EigenPod::verifyBalanceUpdates()
or EigenPod::verifyAndProcessWithdrawals()
is called the TVL drops instantly. This is because both of the functions update the variable podOwnerShares[podOwner]
:
this is the same attack vector mentioned in this report
manual review
when penalties or slashing events happened during the epoch being settled, distribute the correct amount of penalties to all the LRTTokens
withdrawn in the current epoch, including the ones that requested the withdrawal before the drop.
MEV
#0 - C4-Staff
2024-05-15T14:45:56Z
CloudEllie marked the issue as duplicate of #442
#1 - c4-judge
2024-05-23T14:04:55Z
alcueca changed the severity to 3 (High Risk)
#2 - c4-judge
2024-05-23T14:05:25Z
alcueca marked the issue as duplicate of #326
#3 - c4-judge
2024-05-24T10:11:35Z
alcueca marked the issue as satisfactory
🌟 Selected for report: Sathish9098
Also found by: 0x73696d616f, 0xCiphky, 0xmystery, ABAIKUNANBAEV, Bauchibred, BiasedMerc, Fassi_Security, FastChecker, GalloDaSballo, GoatedAudits, K42, KupiaSec, LessDupes, Limbooo, ReadyPlayer2, Rhaydden, SBSecurity, Sabit, Sparrow, WildSniper, ZanyBonzy, adam-idarrha, adeolu, araj, aslanbek, atoko, b0g0, carlitox477, crypticdefense, fyamf, gesha17, gjaldon, grearlake, gumgumzum, hihen, honey-k12, hunter_w3b, inzinko, jesjupyter, jokr, kennedy1030, kind0dev, kinda_very_good, ladboy233, lanrebayode77, oakcobalt, oualidpro, pauliax, rbserver, t0x1c, tapir, underdog, xg, zzykxx
0 USDC - $0.00
https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/Deposits/DepositQueue.sol#L254-L277 https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/RestakeManager.sol#L352
unfair lower TVL calculation for users that submits withdraw request before a sweepERC20
function called
in restakeManager::calculateTVL()
the function calculates adds only the native balance of DepositQueue
to total TVL but doesn't account for the ERC20 tokens held there as rewards that will be swept using depositQueue::sweepERC20
this will harm users that will submit withdrawals before the sweep is called giving them lower amount redeemed due to lower TVL miscalculated
manual review
account for erc20 tokens held in DepositQueue
when calculating restakeManager::calculateTVL()
Other
#0 - c4-judge
2024-05-16T05:43:40Z
alcueca marked the issue as not a duplicate
#1 - c4-judge
2024-05-16T06:01:44Z
alcueca marked the issue as duplicate of #383
#2 - c4-judge
2024-05-16T06:01:47Z
alcueca marked the issue as satisfactory
#3 - c4-judge
2024-05-27T09:30:29Z
alcueca changed the severity to QA (Quality Assurance)
#4 - c4-judge
2024-05-28T11:01:32Z
alcueca marked the issue as grade-b