User Stories for RPIP-71: rETH Withdrawal Liquidity via EIP-7002¶
RPIP-71 lets rETH holders redeem at the protocol rate instead of selling into open-market liquidity. A holder deposits rETH into a Withdrawal Queue, and the protocol settles the request from incoming deposits and a reserved deposit-pool buffer — falling back to automatically exiting validators only when those sources cannot cover it.
Exit selection runs in two phases:
- Phase 1 — minipools. The oDAO votes to request minipool exits, prioritising higher-commission operators.
- Phase 2 — megapools. Once minipools are largely exited, the pDAO flips the irreversible
megapool_exit_phasetoggle and a permissionless tournament selects megapool validators to exit.
Operators whose validators are exited for liquidity receive a priority reentry ticket so they can redeploy that capital ahead of the normal deposit queue.
Withdrawal Lifecycle Diagram¶
flowchart TD
Staker([rETH holder wants to unstake]) --> Request[Deposit rETH into Withdrawal Queue]
Request --> Record["Record ETH value of rETH at request time"]
Record --> Fulfil{Liquidity available?}
Fulfil -- "New mints + deposit-pool buffer" --> Burn[Burn rETH, pay out min redemption rate]
Fulfil -- "Shortfall >= exit_hysteresis" --> Phase{megapool_exit_phase?}
Phase -- "false (Phase 1)" --> ODAO[oDAO votes to exit minipools]
Phase -- "true (Phase 2)" --> Tournament[Tournament selects megapool validators]
ODAO --> BeaconExit([Validators exit on beacon chain])
Tournament --> BeaconExit
BeaconExit --> Ticket[Operator granted reentry_queue_ticket]
Ticket --> Proceeds[Withdrawal proceeds top up deposit pool]
Proceeds --> Burn
Actors¶
- rETH holder: Wants to exit their rETH position at the protocol rate without selling at a market discount. Initiates withdrawal requests.
- Node Operator: May have minipools or megapool validators selected for exit to fund withdrawals. Receives a reentry ticket when this happens.
- oDAO: In Phase 1, votes to request minipool exits to source liquidity.
- pDAO: Tunes the withdrawal parameters and flips the irreversible
megapool_exit_phasetoggle to move from Phase 1 to Phase 2.
Protocol Parameters¶
New parameters¶
| Parameter | Type | Initial Value | Constraint | Description |
|---|---|---|---|---|
deposit_pool_collateral_target |
pct |
1 |
— | Share of ETH backing rETH reserved in the deposit pool as a buffer for rETH burns. |
exit_hysteresis |
ETH |
120 |
> 32 |
Withdrawal shortfall at which additional validators must be selected for exit. |
megapool_exit_phase |
bool |
false |
irreversible once true |
Switches exit sourcing from minipools (Phase 1) to megapools (Phase 2). |
staking_delay |
Days |
28 |
> 7 |
Delay after stake before a megapool validator joins the eligible exit set. |
tournament_size |
int |
4 |
< 20 |
Number of validators (k) sampled per tournament round. |
Modified parameters¶
| Parameter | Old Value | New Value | Description |
|---|---|---|---|
network.reth.collateral.target |
1% |
0% |
rETH collateral target moves to 0%, with the withdrawal buffer handled by deposit_pool_collateral_target instead. |
Epic 1: rETH Withdrawal¶
1.1: Withdrawal Queue Deposit¶
As a rETH holder,
I want to deposit my rETH into the Withdrawal Queue to signal that I wish to unstake at the protocol rate,
So that I am not forced to sell on the open market at a discount when the deposit pool lacks liquidity.
- Acceptance Criteria:
- The Withdrawal Queue begins accepting rETH deposits a fixed 28 days after the upgrade.
- The ETH value of the rETH at the time of the request is recorded.
- A request, once submitted, cannot be cancelled by the user.
- Emits an event.
1.2: Withdrawal Liquidity¶
As the protocol,
I want to fulfil withdrawal redemptions using deposits, rewards, and natural exits before triggering any validator exits,
So that validator churn is minimised and exits are only used when genuinely needed.
- Acceptance Criteria:
- Incoming deposits are routed to the withdrawal queue first (then deposit pool if withdrawals are satisfied).
- Megapool reward distributions are routed to the deposit pool (not the rETH contract), funding the withdrawal queue indirectly via the deposit-pool buffer rather than going to the queue directly.
- Exited ETH is routed to the withdrawal queue first
- Validator exits are only triggered once the withdrawal shortfall reaches
exit_hysteresis, where the shortfall is pending Withdrawal Queue requests minus (requested_exit_eth+voluntary_exit_eth[RPIP-80] + ETH held by the rETH contract + ETH held by the deposit pool).
1.3: Withdrawal Queue Redemption¶
As a rETH holder,
I want to receive the lesser of the rETH value recorded at request time and the value at burn time,
So that the redemption is fair to remaining rETH holders and cannot be gamed by timing.
- Acceptance Criteria:
- On fulfilment, the corresponding rETH is burned.
- The user receives the stored ETH value at request time or at burn time, whichever is smaller.
Epic 2: Selecting Validators to Exit¶
2.1: Phase 1 — oDAO Minipool Exits¶
As the oDAO,
I want to vote to request minipool exits to source withdrawal liquidity while megapool_exit_phase is false,
So that legacy minipool capital is wound down first.
- Acceptance Criteria:
- The oDAO may, by majority vote, request minipools to exit as specified in RPIP-80.
- The amount requested MUST NOT exceed the withdrawal shortfall minus
exit_hysteresis(a hard cap). - The oDAO SHOULD monitor and account for minipools already voluntarily exiting before requesting further exits.
- Selection should prioritise higher-commission minipools.
- Selection should ignore any minipool that received a
did_not_exit_penaltywithin the lastdid_not_exit_cooldown. - The oDAO MAY use time until the next validator sweep as a tie-breaker between minipools with equal commission.
2.2: Phase 2 — Megapool Exit Tournament¶
As the protocol,
I want to select megapool validators to exit via a sampling tournament once megapool_exit_phase is true,
So that exits are sourced fairly and permissionlessly without a centralised selector.
- Acceptance Criteria:
k = tournament_sizedistinct validators (orNiftournament_size > N) are sampled uniformly at random, without replacement, from the eligible megapool validator set.- Exactly one validator from the sampled set is selected to exit — the highest-priority one according to the Exit Criterion.
- Sampling and selection repeat while the withdrawal shortfall is at least
exit_hysteresisand the eligible set is non-empty. - A megapool validator joins the eligible set only
staking_delayafterstakeis called for it. - A validator MUST be removed from the eligible set (or its scheduled inclusion cancelled) if it receives an exit request under RPIP-80, or if
notifyExitis called for it while still pending eligibility.
2.3: Phase Transition¶
As the pDAO,
I want to flip the irreversible megapool_exit_phase toggle, via an on-chain governance proposal, once minipools are largely exited,
So that the protocol moves from minipool-sourced to megapool-sourced liquidity.
- Acceptance Criteria:
- Only an on-chain pDAO proposal can toggle the
megapool_exit_phase. megapool_exit_phasecan be set fromfalsetotrueby the pDAO and can never be set back tofalse.
- Only an on-chain pDAO proposal can toggle the
Epic 3: Reentry After Exit¶
3.1: Priority Reentry Ticket¶
As a Node Operator whose validator was exited for liquidity,
I want to receive a reentry_queue_ticket so that I can redeploy my capital ahead of the normal deposit queue,
So that I am not penalised for an exit I did not choose.
- Acceptance Criteria:
- A
reentry_queue_ticketis granted when a minipool requested to exit for liquidity is distributed. - A
reentry_queue_ticketis granted whennotifyFinalBalanceis called for a megapool validator that was requested to exit for liquidity. - Tickets are not granted for voluntary exits (RPIP-44) or underperformance exits (RPIP-73).
- No ticket is granted if a minipool requested to exit for liquidity does not actually exit.
- The reentry queue is implemented as a new
reentry_queue, alongside RPIP-59's existingstandard_queueandexpress_queue; a node operator spends onereentry_queue_ticketto place a deposit there. - When matching deposit-pool ETH to queued deposits, ETH is matched first to the oldest deposit in the
reentry_queue.
- A
Epic 4: Permissionless Minipool Distribution¶
4.1: Distribute on Proof of Withdrawal¶
As a protocol participant,
I want to prove that a minipool has been withdrawn and immediately call distributeBalance,
So that exited minipool capital reaches the deposit pool without waiting for the usual distribution window.
- Acceptance Criteria:
- On proof that a minipool has been withdrawn, the 90-day distribution window restriction is temporarily removed so anyone can distribute immediately.
- The 90-day distribution window value is governance-immutable — it cannot be modified via a pDAO proposal.
Epic 5: Monitoring & Tooling¶
5.1: Withdrawal Queue Status¶
As a rETH holder,
I want to see the current depth of the Withdrawal Queue and an estimate of my fulfilment time,
So that I can understand how long my unstake will take.
- Acceptance Criteria:
- A UI surfaces queue depth, current shortfall, and an estimated wait bounded by the beacon chain exit queue.
5.2: Operator Exit Alerting¶
As a Rocket Pool Node Operator,
I want to my dashboard to show when one of my validators is selected for a liquidity exit and receives a reentry ticket,
So that I can plan to redeploy the returned capital.
- Acceptance Criteria:
- The Grafana dashboard flags validators selected for liquidity exit and any
reentry_queue_ticketheld.
- The Grafana dashboard flags validators selected for liquidity exit and any
Questions¶
- The Exit Criterion that picks the tournament winner is referenced but not defined in RPIP-71 — what factors does it score (commission, bond, age, size), and where is it specified?
- How do RPIP-71 liquidity exits interact with RPIP-44 forced exits and RPIP-73 performance exits when a validator is eligible under more than one?