From cb02389d005cde7105de80b69ed20ae0f582e185 Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Thu, 14 May 2026 19:39:24 +0200 Subject: [PATCH 1/6] Draft without minipools --- RPIPs/RPIP-71.md | 161 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 10 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index 13433fcf..d6bec7bf 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -2,7 +2,7 @@ rpip: 71 title: rETH Withdrawal liquidity via EIP-7002 description: Enable Rocket Ether stakers to trigger validator exits to access protocol liquidity for unstaking from Rocket Pool. -author: Ramana (@xrchz), Samus (@orangesamus) +author: knoshua (@knoshua) discussions-to: TODO status: Draft type: Protocol @@ -12,23 +12,164 @@ requires (*optional): 44 --- ## Abstract -Rocket ether is by design fully backed by staked ether, so that pool stakers with Rocket Pool can be confident that (modulo a major slashing event) their funds are safe with the protocol and can in principle be retrieved. However, there is no direct mechanism by which pool stakers can signal that they wish to access ether locked in the protocol. As a result, they are left only with the slow indirect method of selling their rETH on the market leading to incentives for node operators to voluntarily exit their validators to capture a market discount for rETH. With the adoption of [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) by Ethereum, it is possible in principle for Rocket Pool to capture a direct signal from pool stakers that they wish to unstake their ether and automatically trigger appropriate validator exits to make this happen in a timely fashion. Delays for unstaking will then come only from factors truly outside of Rocket Pool's control (such as the beacon chain exit queue). +rETH is fully backed by staked ether but currently lacks a direct mechanism for stakers to signal a desire to exit. With the adoption of [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), Rocket Pool can implement execution-layer-triggered exits that respond to explicit rETH withdrawal requests without requiring coordination with node operators. + +This RPIP specifies a Withdrawal Queue and validator selection that avoids introducing a new oDAO duty or a challenge mechanism. ## Motivation -Rocket ether is an unnecessarily risky product for any investor who might want to have reliable and timely access to their capital, since it can remain locked up on the beacon chain by the permissionless node operator set of Rocket Pool until they choose to exit. This RPIP seeks to remedy this situation and thereby make Rocket ether a more attractive and competitive product in the marketplace of Liquid Staking Tokens. + +rETH currently exposes stakers to liquidity risk: although their stake can in principle be withdrawn from the beacon chain, there is no direct protocol mechanism by which rETH holders can access this stake. Instead, they must rely on limited in-protocol liquidity or sell rETH on the open market. This creates a dependence on secondary market liquidity and can make rETH less attractive especially for larger investors and users with time-sensitive liquidity needs. ## Specification -- This specification SHALL be implemented in Saturn 2. -- Pool stakers MUST be able to signal that they wish to exit at the protocol rate. -- The delay to burn rETH after such a signal MUST be short and bounded except for factors outside of protocol control. - - There MUST NOT be any required actions by node operators to ensure a short delay. -- Validators exited via this RPIP SHALL be randomly chosen. + +This specification introduces the following pDAO protocol parameters: + +| Name | Type | Initial Value | Guardrail
| +| -------------------------------- | ---- | ------------- | ------------- | +| `deposit_pool_collateral_target` | pct | 1 | | +| `staking_delay` | Days | 28 | < 7 | +| `tournament_size`
| | 4 | < 20 | + + +This specification changes the following pDAO protocol parameters: + +| Name | Type | Current Value | New Value | +| -------------------------------- | ---- | ------------- | --------- | +| `network.reth.collateral.target` | pct | 1 | 0 | + +### Withdrawal Queue + +- A Withdrawal Queue contract MUST exist to provide the interface by which pool stakers request exits at the protocol rate. +- Starting 28 days after the upgrade that implements this RPIP, the Withdrawal Queue MUST accept rETH deposits from users to create withdrawal requests. +- The ETH value of the rETH at the time of a withdrawal request MUST be recorded. +- Canceling a withdrawal request and exiting the queue SHALL NOT be possible. + +### Fulfilling Withdrawal Requests + +- While the Withdrawal Queue is not empty: + - ETH from new rETH mints SHALL first go towards the Withdrawal Queue. + - Redemption of rETH outside the queue SHALL be prevented as far as possible. + - The protocol SHALL allow the Withdrawal Queue to burn rETH. +- `network.reth.collateral.target` SHALL be set to 0 and a new buffer for withdrawals SHALL be implemented in the deposit pool, reserving up to `deposit_pool_collateral_target` percent of ETH backing rETH for rETH burns. +- When megapools distribute rewards, they SHALL send ETH to the deposit pool rather than rETH. +- When a withdrawal request is fulfilled, the Withdrawal Queue SHALL burn the corresponding rETH. The user SHALL receive the stored ETH value at the time of the request or the value at time of rETH burn, whichever is smaller. +- Any remaining ETH corresponding to that rETH burn SHALL be transferred to the deposit pool. + +### Tracking Exiting ETH + +- Expected user capital is defined as `32 ETH - validator bond`. (This should be fixed under bond curve changes.) +- When `notifyExit` is called for a megapool validator that wasn't requested to exit, a variable `exiting_eth` SHALL be increased by the expected user capital of that validator. +- When `notifyFinalBalance` is called for a megapool validator that wasn't requested to exit, `exiting_eth` SHALL be decreased by the expected user capital. If the megapool validator was requested to exit, `requested_eth` SHALL be decreased instead. + +### Validator Exit Selection + +For the purposes of this section, the withdrawal shortfall is defined as the remaining ETH required to fully satisfy all pending Withdrawal Queue requests after accounting for: +- `requested_eth` (as defined in RPIP‑80), +- `exiting_eth`, +- ETH held by the rETH contract, and +- ETH held by the deposit pool. + +If the withdrawal shortfall is at least 32 ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. + +#### Eligible megapool validator set + +With the upgrade that implements this proposal, the protocol SHALL initialize a set of eligible megapool validators from which validators can be selected for exit under this proposal. A megapool validator MUST satisfy all of the following conditions in order to be included in this set: +- `stake` was already called for the validator. +- The validator is not already exiting. + +After the upgrade that implements this RPIP: +- When `stake` is called for a megapool validator, the protocol SHALL schedule the addition of that validator to the eligible megapool validator set after a pDAO‑configurable `staking_delay`. +- When an exit request is made for a megapool validator under RPIP‑80, that validator MUST be removed from the eligible megapool validator set. +- When `notifyExit` is called for a megapool validator that is still in the eligible megapool validator set, that validator MUST be removed from it. + +#### Tournament-based selection + +Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow to repeatedly select validators while: +- the withdrawal shortfall is at least 32 ETH, and +- the eligible megapool validator set is non‑empty. + +1. The protocol MUST sample `k` distinct validators uniformly at random without replacement from the eligible megapool validator set. +2. For each sampled validator, the protocol MUST compute an exit score according to the chosen Exit Criterion. +3. The protocol MUST select exactly one validator from the sampled set to request for exit: the validator that is determined to be the highest priority to exit according to the Exit Criterion. +4. The protocol SHALL request this validator to exit as defined by RPIP-80. ## Rationale -Node Operator performance was ommitted from the selection criteria due to the necessity to comprehensively address this topic independently from the unique circumstances where withdrawal initiated exits are enacted. Other means, such as Node Operator defined commission, staked RPL exposure, or megapool size were ommitted to maintain simplicity. + +### Withdrawal Queue + +The Withdrawal Queue opens 28 days after the upgrade containing this RPIP is deployed to give node operators an opportunity to upgrade to the new delegate and update smartnode to a version that supports exit request fulfillment. It also aims to ensure that validators in the eligible set are actively staking. + +The protocol is potentially exiting validators to fulfill a withdrawal request. If users could cancel withdrawal requests, they can trigger unneeded exits and reduce rETH APR. + +Changing `network.reth.collateral.target` from 1 to 0 is needed so that ETH from exiting validators flows into the deposit pool rather than remaining as excess collateral in the rETH contract. Including Withdrawal Queue demand in `RocketDepositPool.getExcessBalance()` ensures that ETH freed from exits and new deposits can preferentially be used to satisfy withdrawal requests, rather than being available for rETH burns outside the queue. + +The redemption rate at which a request is fulfilled is chosen as the minimum between rate at time of request and time of fulfillment. rETH in the Withdrawal Queue cannot keep earning staking rewards or there would be an incentive to always keep rETH in the queue and mint new rETH once it can be fulfilled, as this improves liquidity of the position without losing rewards. At the same time, being in the Withdrawal Queue should not protect against rETH losing value in extreme slashing scenarios. + +### Fulfilling Withdrawal Requests + +Since the rETH contract is not upgradeable and has built-in redemption via the `burn` method, ensuring that the Withdrawal Queue gets prioritized requires a bit of thought. + +Setting the collateral target to 0 ensures that fully withdrawn minipool user ETH goes to the deposit pool. Reward distributions from old minipool delegates will still stay in the rETH contract and can be used to redeem rETH outside the Withdrawal Queue, this is why the specification calls for "as far as possible". + +rETH also uses ETH from the deposit pool for `burn`, based on what `RocketDepositPool.getExcessBalance()` returns. The Deposit Pool contract can be upgraded, but we need to ensure that rETH burns are possible for the Withdrawal Queue and at the same time rejected when someone other than the Withdrawal Queue attempts to burn. This may involve setting a state flag in the deposit pool to change the behavior of `RocketDepositPool.getExcessBalance()` during a burn transaction from the Withdrawal Queue. + +## Validator Exit Selection + +The withdrawal shortfall is defined in terms of `requested_eth`, `exiting_eth`, and the ETH held by the rETH contract and deposit pool so that the selection mechanism only triggers when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH in minipool contracts is not included here). Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. + +How to initialize the eligible megapool validator set at upgrade time is left as an implementation detail. + +The `staking_delay` applied after the `stake` call is meant to ensure that validators are only added to the eligible set after they made it through the beacon chain queue, to avoid requests that would take a long time to be executed. This also protects new validators from immediately being exited. + +The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score among that subset, the protocol achieves a decent approximation of full ordering according to the Exit Criterion. For the initial `tournament_size = 4`, on average we will select someone around the 20%-percentile according to the Exit Criterion (https://gist.github.com/knoshua/c71b78f5b2888b1b10800a0b8c4f45c5). ## Security Considerations -Due consideration may need to be paid to any opportunities for gaming the exit system. Additionally, the incentives for node operators to continue staking with Rocket Pool should be considered (with the pool staker incentives given priority in case of conflict). + +### Fulfilling Withdrawal Requests and rETH Updates + +Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become "sandwichable": someone could mint a large amount of rETH right before the update and burn it right after to make a profit at the expense of rETH holders. +However, rETH protects against this type of exploit with a pDAO configurable rETH mint fee that is currently set to 0.05%. This means for example that if 30% of rETH supply are in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for sandwiching to become profitable is lower. For example a day with an 80 ETH MEV block together with 20% of rETH supply in the queue for two weeks can be sandwiched. +If the pDAO wants to protect against even more extreme scenarios, the mint fee could be slightly increased. + +### Protection Against Repeated Minting and Withdrawing + +A concern is that a malicious actor could lower the yield of rETH by repeatedly minting and withdrawing rETH, because this would put a share of staked ETH constantly into an unproductive state. The design makes this kind of attack both costly and mostly ineffective. + +There already is a mint fee on rETH, so an attacker would (currently) lose 0.05% per round trip. They also would not earn any yield, since they would get the minimum rate between the time they entered queue and the time their withdrawal request is filled. + +Furthermore, the new withdrawal buffer in the deposit pool means that a repeatable attack requires more capital than the buffer size (controlled by `deposit_pool_collateral_target`) and only the amount above the buffer size can create validator churn. + + +## Open Questions + +### Withdrawal Queue: NFT and Partial Filling + +A position in the Withdrawal Queue could be represented by an NFT. Since the specification does not allow leaving the Withdrawal Queue by canceling a request, users could instead sell their NFT to immediately liquidate their position in the queue. +On the other hand, people that don't want to wait through the Withdrawal Queue already have the option to sell rETH instead, it may be more difficult to find buyers for a non-fungible queue position, and implementing the NFT would create extra gas overhead (~100k gas?) for everyone. + +Another question is if users in queue should be able to do partial withdrawals as ETH becomes available. It may increase implementation complexity, especially in combination with NFTs. +Without partial filling, users would be able to achieve similar behavior with splitting withdrawal requests into multiple smaller ones. Without partial filling, it may also make sense to limit the ETH per request to avoid users having to wait a long time for their request to be completely filled. +### Megapool Exit Criterion + +We could simply to random selection, or pick any criterion that can be check on-chain, candidates include: + +- lower RPL stake first +- first in, first out +- together with increasing bond requirement, exiting from megapools the furthest below bond requirement + +### Liquidity Buffer and Exiting to Fill Buffer + +In order to ensure that the Withdrawal Queue can be serviced before rETH redemptions outside the queue, we need to set the liquidity buffer (rETH collateral target) to 0. The current proposal replaces it with a new buffer at the deposit pool level. +A buffer contributes to peg stability and it protects against the validator churn griefing discussed in Security Considerations, but unproductive ETH sitting in it hurts rETH yield. Arguably a buffer is less necessary with a proper withdrawal mechanism. + +A related question is if we should exit to fill the Withdrawal Queue or exit to fill the liquidity buffer. Exiting to fill the buffer would lead to a nicer UX for rETH stakers: as long as demand for withdrawals is low, people could instantly redeem rETH at protocol rate, at the cost of reduced rETH APR. + +### Distribution Delay + +Minipools don't immediately make ETH available for rETH burns. ETH first needs to be distributed, which initially is exclusive to the node operator and very delayed for others (currently 90 days after starting the distribution window). Therefore, if we are exiting minipools to fill the Withdrawal Queue, it is possible that queue wait time is unexpectedly long. +Because minipool delegate upgrades are opt-in, this can't be reliably addressed with a delegate upgrade. Potential options include: +- Lowering the delay before permissionless distribution. Security implications would need to be considered. +- Automate distribution in smartnode and introduce a penalty for failing to distribute. Unclear how this could work for Allnodes. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 434b71081dcc26082dc833e3deccf58878f7a96d Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Wed, 20 May 2026 20:44:11 +0200 Subject: [PATCH 2/6] Add minipools - add oDAO-trusted design for minipools with rationale - move tracking ETH fully to RPIP-80 - Open Questions: new idea for distribution delay - Open Questions: Restitution for exited NOs - minor tweaks --- RPIPs/RPIP-71.md | 73 +++++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index d6bec7bf..4a8c4210 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -15,7 +15,7 @@ requires (*optional): 44 rETH is fully backed by staked ether but currently lacks a direct mechanism for stakers to signal a desire to exit. With the adoption of [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), Rocket Pool can implement execution-layer-triggered exits that respond to explicit rETH withdrawal requests without requiring coordination with node operators. -This RPIP specifies a Withdrawal Queue and validator selection that avoids introducing a new oDAO duty or a challenge mechanism. +This RPIP specifies a Withdrawal Queue and validator selection mechanisms for minipools and megapool validators. ## Motivation rETH currently exposes stakers to liquidity risk: although their stake can in principle be withdrawn from the beacon chain, there is no direct protocol mechanism by which rETH holders can access this stake. Instead, they must rely on limited in-protocol liquidity or sell rETH on the open market. This creates a dependence on secondary market liquidity and can make rETH less attractive especially for larger investors and users with time-sensitive liquidity needs. @@ -24,11 +24,12 @@ rETH currently exposes stakers to liquidity risk: although their stake can in pr This specification introduces the following pDAO protocol parameters: -| Name | Type | Initial Value | Guardrail
| -| -------------------------------- | ---- | ------------- | ------------- | -| `deposit_pool_collateral_target` | pct | 1 | | -| `staking_delay` | Days | 28 | < 7 | -| `tournament_size`
| | 4 | < 20 | +| Name | Type | Initial Value | Guardrail
| +| -------------------------------- | ------- | ------------- | ----------------------- | +| `deposit_pool_collateral_target` | pct | 1 | | +| `megapool_exit_phase` | boolean | `false` | can't be set to `false` | +| `staking_delay` | Days | 28 | < 7 | +| `tournament_size`
| | 4 | < 20 | This specification changes the following pDAO protocol parameters: @@ -55,33 +56,31 @@ This specification changes the following pDAO protocol parameters: - When a withdrawal request is fulfilled, the Withdrawal Queue SHALL burn the corresponding rETH. The user SHALL receive the stored ETH value at the time of the request or the value at time of rETH burn, whichever is smaller. - Any remaining ETH corresponding to that rETH burn SHALL be transferred to the deposit pool. -### Tracking Exiting ETH - -- Expected user capital is defined as `32 ETH - validator bond`. (This should be fixed under bond curve changes.) -- When `notifyExit` is called for a megapool validator that wasn't requested to exit, a variable `exiting_eth` SHALL be increased by the expected user capital of that validator. -- When `notifyFinalBalance` is called for a megapool validator that wasn't requested to exit, `exiting_eth` SHALL be decreased by the expected user capital. If the megapool validator was requested to exit, `requested_eth` SHALL be decreased instead. - ### Validator Exit Selection For the purposes of this section, the withdrawal shortfall is defined as the remaining ETH required to fully satisfy all pending Withdrawal Queue requests after accounting for: -- `requested_eth` (as defined in RPIP‑80), -- `exiting_eth`, +- `requested_exit_eth` (defined in RPIP‑80), +- `voluntary_exit_eth` (defined in RPIP-80), - ETH held by the rETH contract, and - ETH held by the deposit pool. If the withdrawal shortfall is at least 32 ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. +### If `megapool_exit_phase = false` +- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall SHALL act as a hard cap on the possible exit requests. +- The oDAO SHOULD monitor the number of voluntarily exiting minipools and only request exits to cover the withdrawal shortfall after accounting for them. +- The oDAO SHOULD select minipools by prioritizing higher-commission minipools and SHOULD ignore any minipool that has received a `did_not_exit_penalty` within the last `did_not_exit_cooldown` (defined in RPIP-80). +- The oDAO MAY use time until the next validator sweep as a tie-breaker between minipools with equal commission. +### If `megapool_exit_phase = true` #### Eligible megapool validator set -With the upgrade that implements this proposal, the protocol SHALL initialize a set of eligible megapool validators from which validators can be selected for exit under this proposal. A megapool validator MUST satisfy all of the following conditions in order to be included in this set: +The protocol SHALL initialize a set of eligible megapool validators from which validators can be selected for exit under this proposal. A megapool validator MUST satisfy all of the following conditions in order to be included in this set: - `stake` was already called for the validator. - The validator is not already exiting. -After the upgrade that implements this RPIP: - When `stake` is called for a megapool validator, the protocol SHALL schedule the addition of that validator to the eligible megapool validator set after a pDAO‑configurable `staking_delay`. -- When an exit request is made for a megapool validator under RPIP‑80, that validator MUST be removed from the eligible megapool validator set. -- When `notifyExit` is called for a megapool validator that is still in the eligible megapool validator set, that validator MUST be removed from it. - +- When an exit request is made for a megapool validator under RPIP‑80, that validator MUST be removed from the eligible megapool validator set or the scheduled inclusion MUST be canceled. +- When `notifyExit` is called for a megapool validator that is still in the eligible megapool validator set, that validator MUST be removed or the scheduled inclusion MUST be canceled. #### Tournament-based selection Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow to repeatedly select validators while: @@ -103,7 +102,7 @@ The protocol is potentially exiting validators to fulfill a withdrawal request. Changing `network.reth.collateral.target` from 1 to 0 is needed so that ETH from exiting validators flows into the deposit pool rather than remaining as excess collateral in the rETH contract. Including Withdrawal Queue demand in `RocketDepositPool.getExcessBalance()` ensures that ETH freed from exits and new deposits can preferentially be used to satisfy withdrawal requests, rather than being available for rETH burns outside the queue. -The redemption rate at which a request is fulfilled is chosen as the minimum between rate at time of request and time of fulfillment. rETH in the Withdrawal Queue cannot keep earning staking rewards or there would be an incentive to always keep rETH in the queue and mint new rETH once it can be fulfilled, as this improves liquidity of the position without losing rewards. At the same time, being in the Withdrawal Queue should not protect against rETH losing value in extreme slashing scenarios. +The redemption rate at which a request is fulfilled is chosen as the minimum between the rate at time of request and time of fulfillment. rETH in the Withdrawal Queue cannot keep earning staking rewards or there would be an incentive to always keep rETH in the queue and mint new rETH once it can be fulfilled, as this improves liquidity of the position without losing rewards. At the same time, being in the Withdrawal Queue should not protect against rETH losing value in extreme slashing scenarios. ### Fulfilling Withdrawal Requests @@ -113,11 +112,22 @@ Setting the collateral target to 0 ensures that fully withdrawn minipool user ET rETH also uses ETH from the deposit pool for `burn`, based on what `RocketDepositPool.getExcessBalance()` returns. The Deposit Pool contract can be upgraded, but we need to ensure that rETH burns are possible for the Withdrawal Queue and at the same time rejected when someone other than the Withdrawal Queue attempts to burn. This may involve setting a state flag in the deposit pool to change the behavior of `RocketDepositPool.getExcessBalance()` during a burn transaction from the Withdrawal Queue. -## Validator Exit Selection +### Minipool Exit Phase + +This design chooses a phased approach in which minipools are exited before moving on to megapools. + +The definition of the withdrawal shortfall aims to only trigger exits when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH rewards in minipool contracts are not included here). While minipools are still around, we rely on the oDAO to track voluntary minipool exits off-chain, because tracking these on-chain would be challenging. Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. + +Using the oDAO for minipools also allows us to order exits based on commission, which marginally improves rETH APR in response to rETH demand reduction. -The withdrawal shortfall is defined in terms of `requested_eth`, `exiting_eth`, and the ETH held by the rETH contract and deposit pool so that the selection mechanism only triggers when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH in minipool contracts is not included here). Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. +We focus on minipools in the first phase, not only to keep the reliance on the oDAO as short as possible, but also because this aligns with the overall desire to move away from minipools and towards megapools: to support the new RPL tokenomics, the new UARS mechanism, and to reduce complexity of future upgrades. -How to initialize the eligible megapool validator set at upgrade time is left as an implementation detail. +We also considered a trustless design for minipools. This would increase complexity and come with additional gas cost that the protocol or pDAO would either have to fund in some way or add to oDAO duties. The trusted oDAO duty appears preferable, because of its temporary nature, limited risk, reduced complexity and lower gas cost. + +The `megapool_exit_phase` toggle allows the pDAO to switch to a megapool-centric exit mechanism once minipools are largely exited or known to be unresponsive. This choice is left to the pDAO because we cannot exactly define it ahead of time. +### Megapool Exit Phase + +Once the protocol is in a state of only megapool validators, it becomes feasible to implement exit selection with a trustless and permissionless proposal-and-challenge mechanism. How to initialize the eligible megapool validator set at upgrade time is left as an implementation detail. The `staking_delay` applied after the `stake` call is meant to ensure that validators are only added to the eligible set after they made it through the beacon chain queue, to avoid requests that would take a long time to be executed. This also protects new validators from immediately being exited. @@ -128,17 +138,19 @@ The tournament‑based mechanism is chosen because maintaining a full global ord ### Fulfilling Withdrawal Requests and rETH Updates Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become "sandwichable": someone could mint a large amount of rETH right before the update and burn it right after to make a profit at the expense of rETH holders. -However, rETH protects against this type of exploit with a pDAO configurable rETH mint fee that is currently set to 0.05%. This means for example that if 30% of rETH supply are in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for sandwiching to become profitable is lower. For example a day with an 80 ETH MEV block together with 20% of rETH supply in the queue for two weeks can be sandwiched. +However, rETH protects against this type of exploit with a pDAO configurable rETH mint fee that is currently set to 0.05%. This means for example that if 30% of rETH supply are in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for profitably sandwiching is lower. For example a day with an 80 ETH MEV block together with 20% of rETH supply in the queue for two weeks can be sandwiched. If the pDAO wants to protect against even more extreme scenarios, the mint fee could be slightly increased. ### Protection Against Repeated Minting and Withdrawing A concern is that a malicious actor could lower the yield of rETH by repeatedly minting and withdrawing rETH, because this would put a share of staked ETH constantly into an unproductive state. The design makes this kind of attack both costly and mostly ineffective. -There already is a mint fee on rETH, so an attacker would (currently) lose 0.05% per round trip. They also would not earn any yield, since they would get the minimum rate between the time they entered queue and the time their withdrawal request is filled. +There already is a mint fee on rETH, so an attacker would (currently) lose 0.05% per round trip. They also would not earn any yield, based on how the redemption rate is defined. Furthermore, the new withdrawal buffer in the deposit pool means that a repeatable attack requires more capital than the buffer size (controlled by `deposit_pool_collateral_target`) and only the amount above the buffer size can create validator churn. +### oDAO selecting minipools +The oDAO has discretion in selecting minipools during the initial phase and is responsible for factoring in voluntarily exiting minipools to determine how many to exit. However, the withdrawal shortfall limits the amount of exits. At most the oDAO could exit unnecessary minipools equal to currently voluntarily exiting minipools and only if there is also enough withdrawal demand at the same time. So the exposure here is mostly limited to ordering and only a small amount of extra exits. Since the rules are known and the actions are transparent, the oDAO properly executing this duty can be monitored. ## Open Questions @@ -151,7 +163,7 @@ Another question is if users in queue should be able to do partial withdrawals a Without partial filling, users would be able to achieve similar behavior with splitting withdrawal requests into multiple smaller ones. Without partial filling, it may also make sense to limit the ETH per request to avoid users having to wait a long time for their request to be completely filled. ### Megapool Exit Criterion -We could simply to random selection, or pick any criterion that can be check on-chain, candidates include: +We could simply do random selection, or pick any criterion that can be checked on-chain, candidates include: - lower RPL stake first - first in, first out @@ -170,6 +182,15 @@ Minipools don't immediately make ETH available for rETH burns. ETH first needs t Because minipool delegate upgrades are opt-in, this can't be reliably addressed with a delegate upgrade. Potential options include: - Lowering the delay before permissionless distribution. Security implications would need to be considered. - Automate distribution in smartnode and introduce a penalty for failing to distribute. Unclear how this could work for Allnodes. +- Allow user Distributions with a final validator balance proof without the delay. This could be implemented by lowering the delay setting, distributing, and setting the delay setting back in one call. + +### Restitution for Exited NOs + +In contrast to RPIP-73, where node operators are exited for bad performance, under this RPIP we are exiting people that may have been doing a perfectly fine job and we may be choosing them with at least some level of randomness. So one question that has come up is if we should offer some kind of restitution for exited validators. Ideas that have been brought up so far include: + +- Giving express tickets for exited validators. This one seems quite easy to do, but may not be all that impactful. +- Some way for exited node operators to skip ahead of people already in queue. +- A direct ETH payment, financed from rETH in the withdrawal queue that stops earning rewards. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 3e8f1c6d26cbd1cb0d43f48b5bf17223a8fea826 Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Thu, 21 May 2026 15:57:44 +0200 Subject: [PATCH 3/6] minor fixes --- RPIPs/RPIP-71.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index 4a8c4210..b88dd7a2 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -8,7 +8,7 @@ status: Draft type: Protocol category: Core created: 2025-05-14 -requires (*optional): 44 +requires (*optional): 80 --- ## Abstract @@ -28,8 +28,8 @@ This specification introduces the following pDAO protocol parameters: | -------------------------------- | ------- | ------------- | ----------------------- | | `deposit_pool_collateral_target` | pct | 1 | | | `megapool_exit_phase` | boolean | `false` | can't be set to `false` | -| `staking_delay` | Days | 28 | < 7 | -| `tournament_size`
| | 4 | < 20 | +| `staking_delay` | days | 28 | > 7 | +| `tournament_size`
| integer | 4 | < 20 | This specification changes the following pDAO protocol parameters: @@ -78,18 +78,18 @@ The protocol SHALL initialize a set of eligible megapool validators from which v - `stake` was already called for the validator. - The validator is not already exiting. -- When `stake` is called for a megapool validator, the protocol SHALL schedule the addition of that validator to the eligible megapool validator set after a pDAO‑configurable `staking_delay`. +- When `stake` is called for a megapool validator, the protocol SHALL schedule the addition of that validator to the eligible megapool validator set after a pDAO-configurable `staking_delay`. - When an exit request is made for a megapool validator under RPIP‑80, that validator MUST be removed from the eligible megapool validator set or the scheduled inclusion MUST be canceled. - When `notifyExit` is called for a megapool validator that is still in the eligible megapool validator set, that validator MUST be removed or the scheduled inclusion MUST be canceled. #### Tournament-based selection -Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow to repeatedly select validators while: +Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow repeated selection of validators while: - the withdrawal shortfall is at least 32 ETH, and - the eligible megapool validator set is non‑empty. 1. The protocol MUST sample `k` distinct validators uniformly at random without replacement from the eligible megapool validator set. 2. For each sampled validator, the protocol MUST compute an exit score according to the chosen Exit Criterion. -3. The protocol MUST select exactly one validator from the sampled set to request for exit: the validator that is determined to be the highest priority to exit according to the Exit Criterion. +3. The protocol MUST select exactly one validator from the sampled set to request exit for: the validator that is determined to be the highest priority to exit according to the Exit Criterion. 4. The protocol SHALL request this validator to exit as defined by RPIP-80. ## Rationale @@ -116,7 +116,7 @@ rETH also uses ETH from the deposit pool for `burn`, based on what `RocketDeposi This design chooses a phased approach in which minipools are exited before moving on to megapools. -The definition of the withdrawal shortfall aims to only trigger exits when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH rewards in minipool contracts are not included here). While minipools are still around, we rely on the oDAO to track voluntary minipool exits off-chain, because tracking these on-chain would be challenging. Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. +The definition of the withdrawal shortfall aims to only trigger exits when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH rewards in minipool contracts are not included here). While minipools are still around, we rely on the oDAO to track voluntary minipool exits off-chain, because tracking this on-chain would be challenging. Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. Using the oDAO for minipools also allows us to order exits based on commission, which marginally improves rETH APR in response to rETH demand reduction. @@ -131,13 +131,13 @@ Once the protocol is in a state of only megapool validators, it becomes feasible The `staking_delay` applied after the `stake` call is meant to ensure that validators are only added to the eligible set after they made it through the beacon chain queue, to avoid requests that would take a long time to be executed. This also protects new validators from immediately being exited. -The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score among that subset, the protocol achieves a decent approximation of full ordering according to the Exit Criterion. For the initial `tournament_size = 4`, on average we will select someone around the 20%-percentile according to the Exit Criterion (https://gist.github.com/knoshua/c71b78f5b2888b1b10800a0b8c4f45c5). +The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score among that subset, the protocol achieves a decent approximation of a full ordering according to the Exit Criterion. For the initial `tournament_size = 4`, on average we will select someone around the 20th-percentile according to the Exit Criterion (https://gist.github.com/knoshua/c71b78f5b2888b1b10800a0b8c4f45c5). ## Security Considerations ### Fulfilling Withdrawal Requests and rETH Updates -Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become "sandwichable": someone could mint a large amount of rETH right before the update and burn it right after to make a profit at the expense of rETH holders. +Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become "sandwichable": someone could mint a large amount of rETH right before the update and burn it right after to profit at the expense of rETH holders. However, rETH protects against this type of exploit with a pDAO configurable rETH mint fee that is currently set to 0.05%. This means for example that if 30% of rETH supply are in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for profitably sandwiching is lower. For example a day with an 80 ETH MEV block together with 20% of rETH supply in the queue for two weeks can be sandwiched. If the pDAO wants to protect against even more extreme scenarios, the mint fee could be slightly increased. @@ -145,25 +145,25 @@ If the pDAO wants to protect against even more extreme scenarios, the mint fee c A concern is that a malicious actor could lower the yield of rETH by repeatedly minting and withdrawing rETH, because this would put a share of staked ETH constantly into an unproductive state. The design makes this kind of attack both costly and mostly ineffective. -There already is a mint fee on rETH, so an attacker would (currently) lose 0.05% per round trip. They also would not earn any yield, based on how the redemption rate is defined. +There is already a mint fee on rETH, so an attacker would currently lose 0.05% per round trip. They also would not earn any yield, based on how the redemption rate is defined. Furthermore, the new withdrawal buffer in the deposit pool means that a repeatable attack requires more capital than the buffer size (controlled by `deposit_pool_collateral_target`) and only the amount above the buffer size can create validator churn. ### oDAO selecting minipools -The oDAO has discretion in selecting minipools during the initial phase and is responsible for factoring in voluntarily exiting minipools to determine how many to exit. However, the withdrawal shortfall limits the amount of exits. At most the oDAO could exit unnecessary minipools equal to currently voluntarily exiting minipools and only if there is also enough withdrawal demand at the same time. So the exposure here is mostly limited to ordering and only a small amount of extra exits. Since the rules are known and the actions are transparent, the oDAO properly executing this duty can be monitored. +The oDAO has discretion in selecting minipools during the initial phase and is responsible for factoring in voluntarily exiting minipools to determine how many to exit. However, the withdrawal shortfall limits the amount of exits. At most the oDAO could exit unnecessary minipools equal to currently voluntarily exiting minipools and only if there is enough withdrawal demand at the same time. So the exposure here is mostly limited to ordering and a small amount of extra exits. Since the rules are known and the actions are transparent, the oDAO properly executing this duty can be monitored. ## Open Questions ### Withdrawal Queue: NFT and Partial Filling -A position in the Withdrawal Queue could be represented by an NFT. Since the specification does not allow leaving the Withdrawal Queue by canceling a request, users could instead sell their NFT to immediately liquidate their position in the queue. -On the other hand, people that don't want to wait through the Withdrawal Queue already have the option to sell rETH instead, it may be more difficult to find buyers for a non-fungible queue position, and implementing the NFT would create extra gas overhead (~100k gas?) for everyone. +A position in the Withdrawal Queue could be represented by an NFT. Since the specification does not allow users to leave the Withdrawal Queue by canceling a request, they could instead sell their NFT to liquidate their position immediately. +On the other hand, people that don't want to wait through the Withdrawal Queue already have the option to sell rETH instead. It may be more difficult to find buyers for a non-fungible queue position, and implementing the NFT would create extra gas overhead (~100k gas?) for everyone. Another question is if users in queue should be able to do partial withdrawals as ETH becomes available. It may increase implementation complexity, especially in combination with NFTs. Without partial filling, users would be able to achieve similar behavior with splitting withdrawal requests into multiple smaller ones. Without partial filling, it may also make sense to limit the ETH per request to avoid users having to wait a long time for their request to be completely filled. ### Megapool Exit Criterion -We could simply do random selection, or pick any criterion that can be checked on-chain, candidates include: +We could simply do random selection or pick any criterion that can be checked on-chain, candidates include: - lower RPL stake first - first in, first out @@ -174,7 +174,7 @@ We could simply do random selection, or pick any criterion that can be checked o In order to ensure that the Withdrawal Queue can be serviced before rETH redemptions outside the queue, we need to set the liquidity buffer (rETH collateral target) to 0. The current proposal replaces it with a new buffer at the deposit pool level. A buffer contributes to peg stability and it protects against the validator churn griefing discussed in Security Considerations, but unproductive ETH sitting in it hurts rETH yield. Arguably a buffer is less necessary with a proper withdrawal mechanism. -A related question is if we should exit to fill the Withdrawal Queue or exit to fill the liquidity buffer. Exiting to fill the buffer would lead to a nicer UX for rETH stakers: as long as demand for withdrawals is low, people could instantly redeem rETH at protocol rate, at the cost of reduced rETH APR. +A related question is if we should exit to fill the Withdrawal Queue or exit to fill the liquidity buffer. Exiting to fill the buffer would lead to a nicer UX for rETH stakers: as long as demand for withdrawals is low, people could instantly redeem rETH at the protocol rate, at the cost of reduced rETH APR. ### Distribution Delay @@ -182,13 +182,13 @@ Minipools don't immediately make ETH available for rETH burns. ETH first needs t Because minipool delegate upgrades are opt-in, this can't be reliably addressed with a delegate upgrade. Potential options include: - Lowering the delay before permissionless distribution. Security implications would need to be considered. - Automate distribution in smartnode and introduce a penalty for failing to distribute. Unclear how this could work for Allnodes. -- Allow user Distributions with a final validator balance proof without the delay. This could be implemented by lowering the delay setting, distributing, and setting the delay setting back in one call. +- Allow user distributions with a final validator balance proof without the delay. This could be implemented by lowering the delay, distributing, and setting the delay back in one call. ### Restitution for Exited NOs In contrast to RPIP-73, where node operators are exited for bad performance, under this RPIP we are exiting people that may have been doing a perfectly fine job and we may be choosing them with at least some level of randomness. So one question that has come up is if we should offer some kind of restitution for exited validators. Ideas that have been brought up so far include: -- Giving express tickets for exited validators. This one seems quite easy to do, but may not be all that impactful. +- Giving express tickets for exited validators. This seems quite easy to do, but may not be all that impactful. - Some way for exited node operators to skip ahead of people already in queue. - A direct ETH payment, financed from rETH in the withdrawal queue that stops earning rewards. From 66380851b098af29ac3589766d00a94d5dee1828 Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:27:36 +0200 Subject: [PATCH 4/6] Update based on pDAO feedback - new `withdrawal_hysteresis` parameter - reentry queue - permissionless distribution of minipools - removed open questions section - refined language --- RPIPs/RPIP-71.md | 156 ++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 71 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index b88dd7a2..6e4d9b3c 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -3,7 +3,7 @@ rpip: 71 title: rETH Withdrawal liquidity via EIP-7002 description: Enable Rocket Ether stakers to trigger validator exits to access protocol liquidity for unstaking from Rocket Pool. author: knoshua (@knoshua) -discussions-to: TODO +discussions-to: https://dao.rocketpool.net/t/rpip-71-reth-withdrawal-liquidity/3947 status: Draft type: Protocol category: Core @@ -15,10 +15,11 @@ requires (*optional): 80 rETH is fully backed by staked ether but currently lacks a direct mechanism for stakers to signal a desire to exit. With the adoption of [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002), Rocket Pool can implement execution-layer-triggered exits that respond to explicit rETH withdrawal requests without requiring coordination with node operators. -This RPIP specifies a Withdrawal Queue and validator selection mechanisms for minipools and megapool validators. +This RPIP specifies a Withdrawal Queue and validator-selection mechanisms for minipools and megapool validators. + ## Motivation -rETH currently exposes stakers to liquidity risk: although their stake can in principle be withdrawn from the beacon chain, there is no direct protocol mechanism by which rETH holders can access this stake. Instead, they must rely on limited in-protocol liquidity or sell rETH on the open market. This creates a dependence on secondary market liquidity and can make rETH less attractive especially for larger investors and users with time-sensitive liquidity needs. +rETH currently exposes stakers to liquidity risk: although their stake can, in principle, be withdrawn from the beacon chain, there is no direct protocol mechanism for rETH holders to access it. Instead, they must rely on limited in-protocol liquidity or sell rETH on the open market. This creates a dependence on secondary-market liquidity and can make rETH less attractive, especially for larger investors and users with time-sensitive liquidity needs. ## Specification @@ -27,6 +28,7 @@ This specification introduces the following pDAO protocol parameters: | Name | Type | Initial Value | Guardrail
| | -------------------------------- | ------- | ------------- | ----------------------- | | `deposit_pool_collateral_target` | pct | 1 | | +| `withdrawal_hysteresis` | ETH | 120 | > 32 | | `megapool_exit_phase` | boolean | `false` | can't be set to `false` | | `staking_delay` | days | 28 | > 7 | | `tournament_size`
| integer | 4 | < 20 | @@ -40,7 +42,7 @@ This specification changes the following pDAO protocol parameters: ### Withdrawal Queue -- A Withdrawal Queue contract MUST exist to provide the interface by which pool stakers request exits at the protocol rate. +- A Withdrawal Queue contract MUST exist to provide the interface for pool stakers to request exits at the protocol rate. - Starting 28 days after the upgrade that implements this RPIP, the Withdrawal Queue MUST accept rETH deposits from users to create withdrawal requests. - The ETH value of the rETH at the time of a withdrawal request MUST be recorded. - Canceling a withdrawal request and exiting the queue SHALL NOT be possible. @@ -49,11 +51,11 @@ This specification changes the following pDAO protocol parameters: - While the Withdrawal Queue is not empty: - ETH from new rETH mints SHALL first go towards the Withdrawal Queue. - - Redemption of rETH outside the queue SHALL be prevented as far as possible. + - Redemption of rETH outside the queue SHALL be prevented to the extent possible. - The protocol SHALL allow the Withdrawal Queue to burn rETH. - `network.reth.collateral.target` SHALL be set to 0 and a new buffer for withdrawals SHALL be implemented in the deposit pool, reserving up to `deposit_pool_collateral_target` percent of ETH backing rETH for rETH burns. - When megapools distribute rewards, they SHALL send ETH to the deposit pool rather than rETH. -- When a withdrawal request is fulfilled, the Withdrawal Queue SHALL burn the corresponding rETH. The user SHALL receive the stored ETH value at the time of the request or the value at time of rETH burn, whichever is smaller. +- When a withdrawal request is fulfilled, the Withdrawal Queue SHALL burn the corresponding rETH. The user SHALL receive the stored ETH value at the time of the request or at the time of the rETH burn, whichever is smaller. - Any remaining ETH corresponding to that rETH burn SHALL be transferred to the deposit pool. ### Validator Exit Selection @@ -64,15 +66,18 @@ For the purposes of this section, the withdrawal shortfall is defined as the rem - ETH held by the rETH contract, and - ETH held by the deposit pool. -If the withdrawal shortfall is at least 32 ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. -### If `megapool_exit_phase = false` +If the withdrawal shortfall is at least `withdrawal_hysteresis` ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. + +#### If `megapool_exit_phase = false` -- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall SHALL act as a hard cap on the possible exit requests. -- The oDAO SHOULD monitor the number of voluntarily exiting minipools and only request exits to cover the withdrawal shortfall after accounting for them. +- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall minus `withdrawal_hysteresis` SHALL act as a hard cap on the possible exit requests. +- The oDAO SHOULD monitor the number of voluntarily exiting minipools and only request exits after accounting for them. - The oDAO SHOULD select minipools by prioritizing higher-commission minipools and SHOULD ignore any minipool that has received a `did_not_exit_penalty` within the last `did_not_exit_cooldown` (defined in RPIP-80). - The oDAO MAY use time until the next validator sweep as a tie-breaker between minipools with equal commission. -### If `megapool_exit_phase = true` -#### Eligible megapool validator set + +#### If `megapool_exit_phase = true` + +##### Eligible megapool validator set The protocol SHALL initialize a set of eligible megapool validators from which validators can be selected for exit under this proposal. A megapool validator MUST satisfy all of the following conditions in order to be included in this set: - `stake` was already called for the validator. @@ -81,116 +86,125 @@ The protocol SHALL initialize a set of eligible megapool validators from which v - When `stake` is called for a megapool validator, the protocol SHALL schedule the addition of that validator to the eligible megapool validator set after a pDAO-configurable `staking_delay`. - When an exit request is made for a megapool validator under RPIP‑80, that validator MUST be removed from the eligible megapool validator set or the scheduled inclusion MUST be canceled. - When `notifyExit` is called for a megapool validator that is still in the eligible megapool validator set, that validator MUST be removed or the scheduled inclusion MUST be canceled. -#### Tournament-based selection + +##### Tournament-based selection Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow repeated selection of validators while: -- the withdrawal shortfall is at least 32 ETH, and +- the withdrawal shortfall is at least `withdrawal_hysteresis` ETH, and - the eligible megapool validator set is non‑empty. 1. The protocol MUST sample `k` distinct validators uniformly at random without replacement from the eligible megapool validator set. 2. For each sampled validator, the protocol MUST compute an exit score according to the chosen Exit Criterion. -3. The protocol MUST select exactly one validator from the sampled set to request exit for: the validator that is determined to be the highest priority to exit according to the Exit Criterion. -4. The protocol SHALL request this validator to exit as defined by RPIP-80. +3. The protocol MUST select exactly one validator from the sampled set to exit request: the one determined to be the highest-priority according to the Exit Criterion. +4. The protocol SHALL request that validator to exit, as defined by RPIP-80. + +### Reentry Queue + +This section modifies the behavior of the deposit queue defined in [RPIP-59](RPPIP-59.md). + +- In addition to the `standard_queue` and `express_queue`, there SHALL be a `reentry_queue`. +- When adding a validator, users SHALL be able to place their deposit in the `reentry_queue` by spending one `reentry_queue_ticket`. +- When matching ETH from the deposit pool to queued deposits, ETH SHALL first be matched to the oldest deposit in the `reentry_queue`. +- If the `reentry_queue` is empty, ETH from the deposit pool SHALL be matched to queued deposits as specified in RPIP-59. +- Node operators SHALL receive a `reentry_queue_ticket` when: + - A minipool was requested to exit for withdrawal liquidity and that minipool was distributed (either `finalise = true` or `userDistributed = true`). + - A megapool validator was requested to exit for withdrawal liquidity and `notifyFinalBalance` was called for that validator. +- Node operators SHALL NOT receive a reentry_queue_ticket when a validator exits voluntarily, when a validator is requested to exit for underperformance, or when a minipool is requested to exit for liquidity and does not exit. + +### Permissionless Distribution of Minipools + +- The protocol SHALL allow anyone to prove that a minipool has been withdrawn and immediately `distributeBalance` for that minipool. +- To achieve this: + - `RocketDAOProtocolSettingsMinipool.getUserDistributeWindowStart()` SHALL return a value stored in `RocketStorage`. + - That value SHALL be set to 90 days initially. + - That value SHALL not be modifiable with a pDAO Proposal. + - When a withdrawal is proven for a minipool, the value SHALL be temporarily set to 0 until `distributeBalance` is called. ## Rationale ### Withdrawal Queue -The Withdrawal Queue opens 28 days after the upgrade containing this RPIP is deployed to give node operators an opportunity to upgrade to the new delegate and update smartnode to a version that supports exit request fulfillment. It also aims to ensure that validators in the eligible set are actively staking. +The Withdrawal Queue opens 28 days after the upgrade containing this RPIP is deployed, giving node operators an opportunity to upgrade to the new delegate and update their smartnode to a version that supports exit request fulfillment. It also aims to ensure that validators in the eligible set are actively staking. The protocol is potentially exiting validators to fulfill a withdrawal request. If users could cancel withdrawal requests, they can trigger unneeded exits and reduce rETH APR. Changing `network.reth.collateral.target` from 1 to 0 is needed so that ETH from exiting validators flows into the deposit pool rather than remaining as excess collateral in the rETH contract. Including Withdrawal Queue demand in `RocketDepositPool.getExcessBalance()` ensures that ETH freed from exits and new deposits can preferentially be used to satisfy withdrawal requests, rather than being available for rETH burns outside the queue. -The redemption rate at which a request is fulfilled is chosen as the minimum between the rate at time of request and time of fulfillment. rETH in the Withdrawal Queue cannot keep earning staking rewards or there would be an incentive to always keep rETH in the queue and mint new rETH once it can be fulfilled, as this improves liquidity of the position without losing rewards. At the same time, being in the Withdrawal Queue should not protect against rETH losing value in extreme slashing scenarios. +The redemption rate at which a request is fulfilled is set to the minimum of the rate at the time of the request and the time of fulfillment. rETH in the Withdrawal Queue cannot keep earning staking rewards or there would be an incentive to always keep rETH in the queue and mint new rETH once it can be fulfilled, as this improves liquidity of the position without losing rewards. At the same time, being in the Withdrawal Queue should not protect against rETH losing value in extreme slashing scenarios. ### Fulfilling Withdrawal Requests -Since the rETH contract is not upgradeable and has built-in redemption via the `burn` method, ensuring that the Withdrawal Queue gets prioritized requires a bit of thought. +Since the rETH contract is not upgradeable and has built-in redemption via the `burn` method, ensuring that the Withdrawal Queue is prioritized requires some thought. -Setting the collateral target to 0 ensures that fully withdrawn minipool user ETH goes to the deposit pool. Reward distributions from old minipool delegates will still stay in the rETH contract and can be used to redeem rETH outside the Withdrawal Queue, this is why the specification calls for "as far as possible". - -rETH also uses ETH from the deposit pool for `burn`, based on what `RocketDepositPool.getExcessBalance()` returns. The Deposit Pool contract can be upgraded, but we need to ensure that rETH burns are possible for the Withdrawal Queue and at the same time rejected when someone other than the Withdrawal Queue attempts to burn. This may involve setting a state flag in the deposit pool to change the behavior of `RocketDepositPool.getExcessBalance()` during a burn transaction from the Withdrawal Queue. - -### Minipool Exit Phase +Setting the collateral target to 0 ensures that fully withdrawn minipool user ETH goes to the deposit pool. Reward distributions from old minipool delegates will still stay in the rETH contract and can be used to redeem rETH outside the Withdrawal Queue; this is why the specification calls for "to the extent possible". -This design chooses a phased approach in which minipools are exited before moving on to megapools. +rETH also uses ETH from the deposit pool for `burn`, based on the value `RocketDepositPool.getExcessBalance()` returns. The Deposit Pool contract can be upgraded, but we need to ensure that rETH burns are possible for the Withdrawal Queue and rejected when someone other than the Withdrawal Queue attempts to burn. This may involve setting a state flag in the deposit pool to change the behavior of `RocketDepositPool.getExcessBalance()` during a burn transaction from the Withdrawal Queue. -The definition of the withdrawal shortfall aims to only trigger exits when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue as far as feasible (for example, ETH rewards in minipool contracts are not included here). While minipools are still around, we rely on the oDAO to track voluntary minipool exits off-chain, because tracking this on-chain would be challenging. Requiring additional exits only when the shortfall is at least 32 ETH ensures that the mechanism is not forced to exit a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. +### Withdrawal Hysteresis -Using the oDAO for minipools also allows us to order exits based on commission, which marginally improves rETH APR in response to rETH demand reduction. +The design only allows exits when the withdrawal shortfall is at least `withdrawal_hysteresis` ETH. This ensures that we are not exiting a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. -We focus on minipools in the first phase, not only to keep the reliance on the oDAO as short as possible, but also because this aligns with the overall desire to move away from minipools and towards megapools: to support the new RPL tokenomics, the new UARS mechanism, and to reduce complexity of future upgrades. +The initial value is chosen based on the expected time between validator exit and ETH becoming available and the expected rewards earned during that time, using the following values: +- 890k active validators +- no beacon chain exit queue +- 380k ETH in rETH +- 2.3% rETH APR -We also considered a trustless design for minipools. This would increase complexity and come with additional gas cost that the protocol or pDAO would either have to fund in some way or add to oDAO duties. The trusted oDAO duty appears preferable, because of its temporary nature, limited risk, reduced complexity and lower gas cost. +With these values, on average it will take ~5 days for ETH to become available and in that time, rETH earns ~120 ETH in rewards. In other words, if the withdrawal shortfall is below 120 ETH, withdrawals will be filled from rewards before ETH from exited validators becomes available. withdrawal_hysteresis is implemented as a tunable parameter so that pDAO can fine-tune it when the assumptions underlying it change significantly. -The `megapool_exit_phase` toggle allows the pDAO to switch to a megapool-centric exit mechanism once minipools are largely exited or known to be unresponsive. This choice is left to the pDAO because we cannot exactly define it ahead of time. -### Megapool Exit Phase +### Minipool Exit Phase -Once the protocol is in a state of only megapool validators, it becomes feasible to implement exit selection with a trustless and permissionless proposal-and-challenge mechanism. How to initialize the eligible megapool validator set at upgrade time is left as an implementation detail. +This design uses a phased approach, with minipools exited before moving to megapools. -The `staking_delay` applied after the `stake` call is meant to ensure that validators are only added to the eligible set after they made it through the beacon chain queue, to avoid requests that would take a long time to be executed. This also protects new validators from immediately being exited. +The definition of the withdrawal shortfall aims to trigger exits only when existing sources of liquidity are insufficient to satisfy the Withdrawal Queue, to the extent feasible (for example, ETH rewards in minipool contracts are not included here). While minipools are still around, we rely on the oDAO to track voluntary minipool exits off-chain, because tracking this on-chain would be challenging. -The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score among that subset, the protocol achieves a decent approximation of a full ordering according to the Exit Criterion. For the initial `tournament_size = 4`, on average we will select someone around the 20th-percentile according to the Exit Criterion (https://gist.github.com/knoshua/c71b78f5b2888b1b10800a0b8c4f45c5). +Using the oDAO for minipools also allows us to order exits by commission, which marginally improves the rETH APR in response to rETH demand reduction. -## Security Considerations +We focus on minipools in the first phase, not only to keep the reliance on the oDAO as short as possible, but also because this aligns with the overall desire to move away from minipools and towards megapools: to support the new RPL tokenomics, the new Universal Adjustable Revenue Split mechanism ([RPIP-46](RPIP-46.md)), and to reduce complexity of future upgrades. -### Fulfilling Withdrawal Requests and rETH Updates +We also considered a trustless design for minipools. This would increase complexity and incur additional gas costs that the protocol or pDAO would either have to fund in some way or add to oDAO's duties. The trusted oDAO duty appears preferable because of its temporary nature, limited risk, reduced complexity and lower gas cost. -Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become "sandwichable": someone could mint a large amount of rETH right before the update and burn it right after to profit at the expense of rETH holders. -However, rETH protects against this type of exploit with a pDAO configurable rETH mint fee that is currently set to 0.05%. This means for example that if 30% of rETH supply are in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for profitably sandwiching is lower. For example a day with an 80 ETH MEV block together with 20% of rETH supply in the queue for two weeks can be sandwiched. -If the pDAO wants to protect against even more extreme scenarios, the mint fee could be slightly increased. +The `megapool_exit_phase` toggle allows the pDAO to switch to the second phase once minipools are largely exited or known to be unresponsive. This choice is left to the pDAO because we cannot precisely define it in advance. -### Protection Against Repeated Minting and Withdrawing +### Megapool Exit Phase -A concern is that a malicious actor could lower the yield of rETH by repeatedly minting and withdrawing rETH, because this would put a share of staked ETH constantly into an unproductive state. The design makes this kind of attack both costly and mostly ineffective. +Once the protocol is in a state with only megapool validators, it becomes feasible to implement exit selection using a trustless, permissionless proposal-and-challenge mechanism. How to initialize the eligible megapool validator set at upgrade time is left as an implementation detail. -There is already a mint fee on rETH, so an attacker would currently lose 0.05% per round trip. They also would not earn any yield, based on how the redemption rate is defined. +The staking_delay applied after the stake call is meant to ensure that validators are added to the eligible set only after they have made it through the beacon chain queue, to avoid requests that would take a long time to execute. This also protects new validators from immediately being exited. -Furthermore, the new withdrawal buffer in the deposit pool means that a repeatable attack requires more capital than the buffer size (controlled by `deposit_pool_collateral_target`) and only the amount above the buffer size can create validator churn. -### oDAO selecting minipools +The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score in that subset, the protocol achieves a decent approximation of a full ordering by the Exit Criterion. For the initial tournament_size = 4, on average we will select someone around the 20th percentile according to the Exit Criterion. -The oDAO has discretion in selecting minipools during the initial phase and is responsible for factoring in voluntarily exiting minipools to determine how many to exit. However, the withdrawal shortfall limits the amount of exits. At most the oDAO could exit unnecessary minipools equal to currently voluntarily exiting minipools and only if there is enough withdrawal demand at the same time. So the exposure here is mostly limited to ordering and a small amount of extra exits. Since the rules are known and the actions are transparent, the oDAO properly executing this duty can be monitored. +### Reentry Queue -## Open Questions +From the perspective of node operators, the reentry queue is a form of restitution for being chosen for liquidity, with at least some randomness and while meeting the performance threshold set by [RPIP-73](RPIP-73.md). From the protocol's perspective, prioritizing proven node operators that met the performance threshold over unknown (potentially underperforming) node operators is rational. -### Withdrawal Queue: NFT and Partial Filling +We also considered a direct ETH payment, financed from rETH in the withdrawal queue that stops earning rewards, as restitution. This appears more challenging to implement and is harder to justify from the protocol's perspective. Withdrawal liquidity exits mean there is less demand than supply and this would be paying the supply side. Contrarily, the benefit from the reentry queue is conditional on demand returning to the previous level. -A position in the Withdrawal Queue could be represented by an NFT. Since the specification does not allow users to leave the Withdrawal Queue by canceling a request, they could instead sell their NFT to liquidate their position immediately. -On the other hand, people that don't want to wait through the Withdrawal Queue already have the option to sell rETH instead. It may be more difficult to find buyers for a non-fungible queue position, and implementing the NFT would create extra gas overhead (~100k gas?) for everyone. +### Permissionless Distribution of Minipools -Another question is if users in queue should be able to do partial withdrawals as ETH becomes available. It may increase implementation complexity, especially in combination with NFTs. -Without partial filling, users would be able to achieve similar behavior with splitting withdrawal requests into multiple smaller ones. Without partial filling, it may also make sense to limit the ETH per request to avoid users having to wait a long time for their request to be completely filled. -### Megapool Exit Criterion +Minipools don't immediately make ETH available for rETH burns. ETH first needs to be distributed, which is initially exclusive to the node operator and is very delayed for others (currently 90 days after starting the distribution window). Therefore, if we are exiting minipools to fill the Withdrawal Queue and node operators don’t distribute themselves, the wait time may be unexpectedly long. -We could simply do random selection or pick any criterion that can be checked on-chain, candidates include: +This can’t be reliably addressed with a delegate upgrade, since these are opt-in. Instead, the design allows distribution without delay by temporarily removing the restriction and requiring a proof that the validator has already been withdrawn. -- lower RPL stake first -- first in, first out -- together with increasing bond requirement, exiting from megapools the furthest below bond requirement +## Security Considerations -### Liquidity Buffer and Exiting to Fill Buffer +### Fulfilling Withdrawal Requests and rETH Updates -In order to ensure that the Withdrawal Queue can be serviced before rETH redemptions outside the queue, we need to set the liquidity buffer (rETH collateral target) to 0. The current proposal replaces it with a new buffer at the deposit pool level. -A buffer contributes to peg stability and it protects against the validator churn griefing discussed in Security Considerations, but unproductive ETH sitting in it hurts rETH yield. Arguably a buffer is less necessary with a proper withdrawal mechanism. +Without further changes to the oDAO balance tracking duty that informs the rETH exchange rate, the proposed mechanism leads to a re-distribution of staking rewards from rETH in the Withdrawal Queue to other rETH holders at the time a withdrawal request is fulfilled. Potentially, this could lead to a very large rETH rate increase with the following update that could become “sandwichable”: someone could mint a large amount of rETH right before the update and burn it right after to profit at the expense of rETH holders. +However, rETH protects against this type of exploit with a pDAO-configurable rETH mint fee, currently set to 0.05%. This means, for example, that if 30% of rETH supply is in the Withdrawal Queue for 2 weeks, the resulting rETH rate update still could not be profitably sandwiched when rETH yield for that day is approximately average. If a large request fulfillment coincides with a high yield day for rETH, the threshold for profitably sandwiching is lower. For example, a day with an 80ETH MEV block, together with 20% of the rETH supply in the queue for two weeks, can be sandwiched. +If the pDAO wants to protect against even more extreme scenarios, the mint fee could be slightly increased. -A related question is if we should exit to fill the Withdrawal Queue or exit to fill the liquidity buffer. Exiting to fill the buffer would lead to a nicer UX for rETH stakers: as long as demand for withdrawals is low, people could instantly redeem rETH at the protocol rate, at the cost of reduced rETH APR. +### Protection Against Repeated Minting and Withdrawing -### Distribution Delay +A concern is that a malicious actor could reduce the yield of rETH by repeatedly minting and withdrawing rETH, as this would keep a share of staked ETH constantly in an unproductive state. The design makes this kind of attack both costly and mostly ineffective. -Minipools don't immediately make ETH available for rETH burns. ETH first needs to be distributed, which initially is exclusive to the node operator and very delayed for others (currently 90 days after starting the distribution window). Therefore, if we are exiting minipools to fill the Withdrawal Queue, it is possible that queue wait time is unexpectedly long. -Because minipool delegate upgrades are opt-in, this can't be reliably addressed with a delegate upgrade. Potential options include: -- Lowering the delay before permissionless distribution. Security implications would need to be considered. -- Automate distribution in smartnode and introduce a penalty for failing to distribute. Unclear how this could work for Allnodes. -- Allow user distributions with a final validator balance proof without the delay. This could be implemented by lowering the delay, distributing, and setting the delay back in one call. +There is already a mint fee on rETH, so an attacker would currently lose 0.05% per round trip. They also would not earn any yield, based on how the redemption rate is defined. -### Restitution for Exited NOs +Furthermore, the new withdrawal buffer in the deposit pool means that a repeatable attack requires more capital than the buffer size (controlled by deposit_pool_collateral_target) and only the amount above that buffer can create validator churn. -In contrast to RPIP-73, where node operators are exited for bad performance, under this RPIP we are exiting people that may have been doing a perfectly fine job and we may be choosing them with at least some level of randomness. So one question that has come up is if we should offer some kind of restitution for exited validators. Ideas that have been brought up so far include: +### oDAO selecting minipools -- Giving express tickets for exited validators. This seems quite easy to do, but may not be all that impactful. -- Some way for exited node operators to skip ahead of people already in queue. -- A direct ETH payment, financed from rETH in the withdrawal queue that stops earning rewards. +The oDAO has discretion in selecting minipools during the initial phase and is responsible for factoring in voluntarily exiting minipools to determine how many to exit. However, the withdrawal shortfall limits the amount of exits. At most, the oDAO could exit unnecessary minipools equal to the currently voluntarily exiting minipools, provided there is sufficient withdrawal demand at the same time. So the exposure here is mostly limited to ordering and a small amount of extra exits. Since the rules are known and the actions are transparent, the oDAO properly executing this duty can be monitored. ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 45fbe8602697b54b9e8c0263a11fbd2678b3bd1c Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Thu, 11 Jun 2026 10:04:43 +0200 Subject: [PATCH 5/6] clearer naming --- RPIPs/RPIP-71.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index 6e4d9b3c..42e6cb57 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -28,7 +28,7 @@ This specification introduces the following pDAO protocol parameters: | Name | Type | Initial Value | Guardrail
| | -------------------------------- | ------- | ------------- | ----------------------- | | `deposit_pool_collateral_target` | pct | 1 | | -| `withdrawal_hysteresis` | ETH | 120 | > 32 | +| `exit_hysteresis` | ETH | 120 | > 32 | | `megapool_exit_phase` | boolean | `false` | can't be set to `false` | | `staking_delay` | days | 28 | > 7 | | `tournament_size`
| integer | 4 | < 20 | @@ -66,11 +66,11 @@ For the purposes of this section, the withdrawal shortfall is defined as the rem - ETH held by the rETH contract, and - ETH held by the deposit pool. -If the withdrawal shortfall is at least `withdrawal_hysteresis` ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. +If the withdrawal shortfall is at least `exit_hysteresis` ETH, additional megapool validators MUST be selected and added to the exit list as defined in this section. #### If `megapool_exit_phase = false` -- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall minus `withdrawal_hysteresis` SHALL act as a hard cap on the possible exit requests. +- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall minus `exit_hysteresis` SHALL act as a hard cap on the possible exit requests. - The oDAO SHOULD monitor the number of voluntarily exiting minipools and only request exits after accounting for them. - The oDAO SHOULD select minipools by prioritizing higher-commission minipools and SHOULD ignore any minipool that has received a `did_not_exit_penalty` within the last `did_not_exit_cooldown` (defined in RPIP-80). - The oDAO MAY use time until the next validator sweep as a tie-breaker between minipools with equal commission. @@ -90,7 +90,7 @@ The protocol SHALL initialize a set of eligible megapool validators from which v ##### Tournament-based selection Let `N` be the current size of the eligible megapool validator set. Let `k` be `tournament_size` (or `N` if `tournament_size > N`). The protocol SHALL allow repeated selection of validators while: -- the withdrawal shortfall is at least `withdrawal_hysteresis` ETH, and +- the withdrawal shortfall is at least `exit_hysteresis` ETH, and - the eligible megapool validator set is non‑empty. 1. The protocol MUST sample `k` distinct validators uniformly at random without replacement from the eligible megapool validator set. @@ -140,9 +140,9 @@ Setting the collateral target to 0 ensures that fully withdrawn minipool user ET rETH also uses ETH from the deposit pool for `burn`, based on the value `RocketDepositPool.getExcessBalance()` returns. The Deposit Pool contract can be upgraded, but we need to ensure that rETH burns are possible for the Withdrawal Queue and rejected when someone other than the Withdrawal Queue attempts to burn. This may involve setting a state flag in the deposit pool to change the behavior of `RocketDepositPool.getExcessBalance()` during a burn transaction from the Withdrawal Queue. -### Withdrawal Hysteresis +### Exit Hysteresis -The design only allows exits when the withdrawal shortfall is at least `withdrawal_hysteresis` ETH. This ensures that we are not exiting a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. +The design only allows exits when the withdrawal shortfall is at least `exit_hysteresis` ETH. This ensures that we are not exiting a whole validator to cover a residual amount that can reasonably be filled by future rewards or natural inflows. The initial value is chosen based on the expected time between validator exit and ETH becoming available and the expected rewards earned during that time, using the following values: - 890k active validators @@ -150,7 +150,7 @@ The initial value is chosen based on the expected time between validator exit an - 380k ETH in rETH - 2.3% rETH APR -With these values, on average it will take ~5 days for ETH to become available and in that time, rETH earns ~120 ETH in rewards. In other words, if the withdrawal shortfall is below 120 ETH, withdrawals will be filled from rewards before ETH from exited validators becomes available. withdrawal_hysteresis is implemented as a tunable parameter so that pDAO can fine-tune it when the assumptions underlying it change significantly. +With these values, on average it will take ~5 days for ETH to become available and in that time, rETH earns ~120 ETH in rewards. In other words, if the withdrawal shortfall is below 120 ETH, withdrawals will be filled from rewards before ETH from exited validators becomes available. exit_hysteresis is implemented as a tunable parameter so that pDAO can fine-tune it when the assumptions underlying it change significantly. ### Minipool Exit Phase From d9d5774eceabd726cea4e53299bf2bcf82e791a1 Mon Sep 17 00:00:00 2001 From: knoshua <86415413+knoshua@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:02:21 +0200 Subject: [PATCH 6/6] Fix formatting and clarify exit_hysteresis references --- RPIPs/RPIP-71.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/RPIPs/RPIP-71.md b/RPIPs/RPIP-71.md index 42e6cb57..c81ef10d 100644 --- a/RPIPs/RPIP-71.md +++ b/RPIPs/RPIP-71.md @@ -28,7 +28,7 @@ This specification introduces the following pDAO protocol parameters: | Name | Type | Initial Value | Guardrail
| | -------------------------------- | ------- | ------------- | ----------------------- | | `deposit_pool_collateral_target` | pct | 1 | | -| `exit_hysteresis` | ETH | 120 | > 32 | +| `exit_hysteresis` | ETH | 120 | > 32 | | `megapool_exit_phase` | boolean | `false` | can't be set to `false` | | `staking_delay` | days | 28 | > 7 | | `tournament_size`
| integer | 4 | < 20 | @@ -54,7 +54,7 @@ This specification changes the following pDAO protocol parameters: - Redemption of rETH outside the queue SHALL be prevented to the extent possible. - The protocol SHALL allow the Withdrawal Queue to burn rETH. - `network.reth.collateral.target` SHALL be set to 0 and a new buffer for withdrawals SHALL be implemented in the deposit pool, reserving up to `deposit_pool_collateral_target` percent of ETH backing rETH for rETH burns. -- When megapools distribute rewards, they SHALL send ETH to the deposit pool rather than rETH. +- When megapools distribute rewards, they SHALL send ETH to the deposit pool rather than the rETH contract. - When a withdrawal request is fulfilled, the Withdrawal Queue SHALL burn the corresponding rETH. The user SHALL receive the stored ETH value at the time of the request or at the time of the rETH burn, whichever is smaller. - Any remaining ETH corresponding to that rETH burn SHALL be transferred to the deposit pool. @@ -70,13 +70,15 @@ If the withdrawal shortfall is at least `exit_hysteresis` ETH, additional megapo #### If `megapool_exit_phase = false` -- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall minus `exit_hysteresis` SHALL act as a hard cap on the possible exit requests. +- The protocol SHALL allow the oDAO, by majority vote, to request minipools to exit as specified in RPIP-80. The amount necessary to cover the withdrawal shortfall minus `exit_hysteresis` SHALL act as a hard cap on the possible exit requests. - The oDAO SHOULD monitor the number of voluntarily exiting minipools and only request exits after accounting for them. - The oDAO SHOULD select minipools by prioritizing higher-commission minipools and SHOULD ignore any minipool that has received a `did_not_exit_penalty` within the last `did_not_exit_cooldown` (defined in RPIP-80). - The oDAO MAY use time until the next validator sweep as a tie-breaker between minipools with equal commission. #### If `megapool_exit_phase = true` + + ##### Eligible megapool validator set The protocol SHALL initialize a set of eligible megapool validators from which validators can be selected for exit under this proposal. A megapool validator MUST satisfy all of the following conditions in order to be included in this set: @@ -119,7 +121,6 @@ This section modifies the behavior of the deposit queue defined in [RPIP-59](RPP - That value SHALL be set to 90 days initially. - That value SHALL not be modifiable with a pDAO Proposal. - When a withdrawal is proven for a minipool, the value SHALL be temporarily set to 0 until `distributeBalance` is called. - ## Rationale ### Withdrawal Queue @@ -174,6 +175,19 @@ The staking_delay applied after the stake call is meant to ensure that validator The tournament‑based mechanism is chosen because maintaining a full global ordering of all eligible validators by the Exit Criterion may not be feasible. By sampling a small, random subset of eligible validators and exiting the validator with the worst Exit Criterion score in that subset, the protocol achieves a decent approximation of a full ordering by the Exit Criterion. For the initial tournament_size = 4, on average we will select someone around the 20th percentile according to the Exit Criterion. +#### Megapool Exit Criterion + +No clear consensus on what criterion should be used has emerged yet. Options that have been discussed so far include: + +- random +- lower RPL stake first +- first in, first out +- together with increasing bond requirement, exiting from megapools the furthest below bond requirement +- biasing towards larger nodes +- bias towards not hitting same node again (this seems to be ~biasing towards smaller nodes) + +The pDAO will vote on an exit criterion before Saturn 2 is deployed. + ### Reentry Queue From the perspective of node operators, the reentry queue is a form of restitution for being chosen for liquidity, with at least some randomness and while meeting the performance threshold set by [RPIP-73](RPIP-73.md). From the protocol's perspective, prioritizing proven node operators that met the performance threshold over unknown (potentially underperforming) node operators is rational.