Renzo - RamenPeople'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: 23/122

Findings: 3

Award: $599.00

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

0.4071 USDC - $0.41

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
:robot:_224_group
duplicate-326

External Links

Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/519e518f2d8dec9acf6482b84a181e403070d22d/contracts/Withdraw/WithdrawQueue.sol#L229

Vulnerability details

Impact

Holders of wBETH and other tokens that will be accepted by Renzo can compensate for their losses resulting from price drop (e.g. slashing) using the funds of Renzo users. Very quickly after this system weakness will be discovered by the first attacker, it can be automated and exploited by bots as an arbitrage opportunity creating a growing loss for Renzo depositors.

Proof of Concept

Renzo creates a system that allows for restaking various tokens and receive their Liquid Restaking Token (LRT) EzETH in return. Example ERC20 used by the protocol ezETH, stETH, wBETH.

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 wBETH, 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 wBETH
  • there are price drops for assets like wBETH, wstETH, cbETH, but most of the time these are temporary,
  • things that can cause price drops for assets like wBETH 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 (wBETH) to get ezETH, and then request to withdraw asset2 (ETH).

Consider the following scenario (values used for ease of calculation and to illustrate the attack, real values will be presented later in this description):

  1. 200 ETH is deposited inside Renzo by users and 200 ezETH were minted.

  2. The attacker (wBETH staker) has 100 wBETH (price is e.g. 1 wBETH = 2 ETH, their wBETH is worth 200 ETH)

  3. The attacker knows through monitoring slashing events and big withdrawalas that price will drop soon.

  4. The attacker deposit their 100 wBETH to Renzo to get 200 ezETH (as current price is still 1 wBETH = 2 ETH)

Total value locked on Renzo will increase from 200 ETH to 400 ETH (200 eth and 100 wBETH). Users posses 200 ezETH, Attacker posses 200 ezETH.

  1. Price of wBETH now drops by 50% (so now 1 wBETH = 1 ETH)

Total value locked on Renzo will decrease from 400 ETH to 300 ETH (as 100 wBETH is now worth only 100 ETH). That causes value drop for ezETH value (1 ezETH = 0,75 ETH).

  1. The attacker decides to request withdraw all of their wBETH by burning only ~134 ezETH (instead of 200 ezETH) so 66 ezETH will remain for them. They use them to another withdraw of ~50 ETH by burning another 66 ezETH.

Attacker gets 200 wBETH back (current price is 100 ETH) and additional 50 ETH.

Attacker buys additional wBETH for their additional 50 ETH, so know they have 250 wBETH (from another source, outside protocol)

Now price recover, so its again 1 wBETH = 2 ETH.

Attacker now have 250 wBETH worth 500 ETH, and Renzo users have 150 ETH (lost 50 ETH, as attacker delegeted their risk to Renzo users).

However, the price will not drop by 50%. The real numbers could be up to 10%.

wBETH (https://coinmarketcap.com/currencies/wrapped-beacon-eth/) there are price drops (https://coinmarketcap.com/currencies/wrapped-beacon-eth/historical-data/)

Looking also at 2 examples of similar assets to those that are considered (cbETH and wstETH) 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% (https://coinmarketcap.com/currencies/coinbase-wrapped-staked-eth/historical-data/)

wstETH (https://coinmarketcap.com/currencies/lido-finance-wsteth/) there are price drops, based on data from last 365 days the biggest percentage drop in price occurred also on March 11, 2023, with a drop of approximately 9.28% (https://coinmarketcap.com/currencies/lido-finance-wsteth/historical-data/)

Tools Used

Manual Review

Set a minimum period for the user between their deposit and withdrawal so that they cannot take advantage of price fluctuations. Right know, their redeem amount is calculted as soon as withdraw is called.

Assessed type

Other

#0 - c4-judge

2024-05-16T13:59:56Z

alcueca marked the issue as not a duplicate

#1 - c4-judge

2024-05-16T14:00:06Z

alcueca marked the issue as duplicate of #326

#2 - c4-judge

2024-05-17T12:48:32Z

alcueca marked the issue as satisfactory

Findings Information

🌟 Selected for report: LessDupes

Also found by: RamenPeople, SBSecurity, bill, guhu95, ilchovski, peanuts

Labels

bug
3 (High Risk)
satisfactory
sufficient quality report
upgraded by judge
:robot:_39_group
duplicate-282

Awards

598.5522 USDC - $598.55

External Links

Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/519e518f2d8dec9acf6482b84a181e403070d22d/contracts/RestakeManager.sol#L491 https://github.com/code-423n4/2024-04-renzo/blob/519e518f2d8dec9acf6482b84a181e403070d22d/contracts/Withdraw/WithdrawQueue.sol#L206

Vulnerability details

Impact

Loss of capital of users who withdraw stETH. Their LST rewards will be miscalculated. Loss will constantly grow over time.

Proof of Concept

The general questions section in the readme.md states that the ERC20s used by the protocol are ezETH, stETH, and wBETH. https://github.com/code-423n4/2024-04-renzo/blob/main/README.md#scoping-q--a

However, stETH is a rebase token and the amount of stETH in a user/platform balance will not be constant - it changes daily as staking rewards arrive.

The current deposit/withdraw flow does not handle rebasing tokens at all.

In the case of wrapped tokens such as used here wBETH, although the exact amountToRedeem amount is calculated during the withdrawal request WithdrawQueue#L229 user will continue to earn part of rewards as their value is determined by price that increases over time.

Even though the user has to wait 7 days (according to the readme) for a claim, the same amountToRedeem of wBETH will be worth more after this 7 days.

In the case of stETH, rebase token the exact amountToRedeem will be calculated in the same way. However, rebase token value remains 1:1 and its value changes through balance updates, not increasing the price.

Here, after 7 days, this amountToRedeem will not be updated. Users who decide to withdraw stETH will always lose their accumulating rewards before they will be able to claim.

Tools Used

Manual Review

Consider the non-rebasing wrapped version of stETH instead (wstETH) or re-calculate amountToRedeem to adjust it's balance.
https://help.lido.fi/en/articles/5231836-what-is-lido-s-wsteth

Assessed type

Other

#0 - c4-judge

2024-05-17T12:46:27Z

alcueca marked the issue as duplicate of #326

#1 - c4-judge

2024-05-17T12:48:14Z

alcueca marked the issue as satisfactory

#2 - c4-judge

2024-05-27T08:46:52Z

alcueca marked the issue as not a duplicate

#3 - c4-judge

2024-05-27T08:46:57Z

alcueca changed the severity to 2 (Med Risk)

#4 - c4-judge

2024-05-27T08:47:08Z

alcueca marked the issue as duplicate of #282

#5 - c4-judge

2024-05-27T08:51:57Z

alcueca changed the severity to 3 (High Risk)

#6 - alcueca

2024-05-27T08:55:58Z

While this issue doesn't point out that deposits and withdrawals will revert on balance decreases of stEth due to slashing, it points out that it shouldn't be treated as non-rebasing LSTs in the withdrawal queue.

Awards

0.0402 USDC - $0.04

Labels

bug
2 (Med Risk)
satisfactory
sufficient quality report
:robot:_20_group
duplicate-198

External Links

Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/519e518f2d8dec9acf6482b84a181e403070d22d/contracts/RestakeManager.sol#L562 https://github.com/code-423n4/2024-04-renzo/blob/519e518f2d8dec9acf6482b84a181e403070d22d/contracts/RestakeManager.sol#L549

Vulnerability details

Impact

Under specific conditions, user deposits will always revert.

Proof of Concept

When a user deposits funds through RestakeManager, the function checks the withdraw buffer and fill it if it is below the buffer target determined by bufferToFill.

If it needs to be filled, line RestakeManager#L547 checks whether the transferred _amount is less than or equal to bufferToFill.

bufferToFill = (_amount <= bufferToFill) ? _amount : bufferToFill;

The case where _amount is equal to bufferToFill is incorrectly handled as after subtraction the _amount value will be 0 RestakeManager#L549.

_amount -= bufferToFill;

That leads to a revert during operatorDelegator.deposit line RestakeManager#L562, as it will not be able to pass the requirement for tokenAmount in OperatorDelegator#L147

        if (address(tokenStrategyMapping[token]) == address(0x0) || tokenAmount == 0)

Tools Used

Manual Review

Handle separately the case in which the entire _amount goes towards filling the bufferToFill (_amount == bufferToFill). If the amount equals 0 after paying bufferToFill, do not try to deposit it to operatorDelegator, allocate the appropriate amount of tokens to the user.

Assessed type

Token-Transfer

#0 - c4-judge

2024-05-20T05:02:09Z

alcueca marked the issue as satisfactory

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