User Stories for RPIP-44: Integrating Execution Layer Triggerable Exits¶
RPIP-44 integrates execution layer triggerable exits into megapools, allowing validators to be exited without their validator signing keys.
RPIP-44 decides which megapool validators should exit; it does not exit them directly. In both cases below, the selected validators are submitted as exit requests to RPIP-80, which carries out the actual exit lifecycle (the cooperative exit phase followed by the permissionless EIP-7002 trigger).
It serves two purposes:
- Operator-initiated exits. A megapool's withdrawal address can request the exit of its validators at any time — to wind down an operation, reclaim bonded ETH, or recover staked funds if the validator signing keys have been lost. The request is carried out through RPIP-80.
- Forced exits on debt. When a megapool's
deficitreaches theexit_deficitthreshold, any user can permissionlessly force the exit of just enough validators to clear it. Those validators are likewise submitted to RPIP-80 to be exited. This protects rETH performance by reclaiming protocol funds without depending on a negligent or malicious operator to act, and is motivated chiefly by deterring MEV and block reward theft.
Exit Lifecycle Diagram¶
The diagram below illustrates the two exit paths under RPIP-44:
flowchart TD
Start([Megapool with active validators]) --> Who{Who initiates?}
Who -- Withdrawal Address --> NOExit[Withdrawal address selects own validators to exit]
NOExit --> Request["Submit exit request(s) to RPIP-80"]
Who -- Any user --> CheckDeficit{"deficit >= exit_deficit?"}
CheckDeficit -- No --> Revert[Reverts: not permissionlessly exitable]
CheckDeficit -- Yes --> Minimum[Select minimum validators to bring deficit below exit_deficit]
Minimum --> Request
Request --> RPIP80[["RPIP-80 carries out the exit: cooperative phase, then EIP-7002 trigger, then beacon-chain exit"]]
RPIP80 --> Settle[Withdrawn funds applied to debt before release]
Actors¶
- Withdrawal Address: The node operator's primary withdrawal address.
- Forced Exiter (any user): Any participant who triggers a permissionless forced exit on a megapool whose
deficithas reachedexit_deficit, reclaiming protocol funds without relying on the operator. - pDAO: The governance body responsible for tuning the
exit_deficitthreshold via on-chain governance. - rETH Holders: The beneficiaries of the forced exit path, whose yield is protected when negligent or malicious operators are forced to exit and settle their debt.
Megapool Accounting¶
RPIP-44 relies on megapool fund accounting to determine when a forced exit is permitted. Funds are tracked across the following categories:
| Variable | Description |
|---|---|
debt |
Penalties or shortfall from exited validators. |
received |
Funds provided that can be used towards validator deposits; sources include deposits from the node operator and ETH staked on behalf of the node. |
credit |
Funds already in the protocol that can be used towards validator deposits; sources include ETH already staked on the beacon chain for a migrating validator. |
withdrawn |
Funds received into the megapool via withdrawals from the beacon chain. |
The forced exit trigger is derived from these balances:
Implementation status
The debt accounting and much of the debt-payback logic already exist in the v1.4 (Saturn 1) megapool delegate — debt is netted against the node share during reward distribution (_distributeAmount), during claim (_claim), and on validator exit (_notifyFinalBalance), and can be repaid directly via repayDebt. There are no standalone received/credit/withdrawn storage variables today; those are RPIP-44's conceptual aggregation. What RPIP-44 / Saturn 2 adds on top is the unified deficit calculation, the exit_deficit threshold, and the operator-initiated and permissionless forced exit triggers — both of which hand the selected validators to RPIP-80 to carry out the EIP-7002 exit.
Protocol Parameters¶
| Parameter | Type | Initial Value | Description |
|---|---|---|---|
exit_deficit |
ETH |
0.2 |
The deficit threshold at or above which a megapool's validators become permissionlessly exitable. |
Epic 1: Withdrawal Address Voluntary Exit¶
1.1: Exit Own Validators¶
As the Primary Withdrawal Address,
I want to request the exit of one or more of the megapool's validators through the megapool contract,
So that I can wind down the operation without using the validator signing keys directly.
- Acceptance Criteria:
- Only the node operator's primary withdrawal address can call the megapool exit function for its own validators.
- The withdrawal address can call it at any time, regardless of
deficit. - One or more validators may be specified in a single request.
- The specified validators are submitted as exit requests to RPIP-80, which carries out the exit (cooperative phase, then EIP-7002 trigger).
- Emits an event.
Epic 2: Forced Exit on Debt¶
2.1: Permissionless Forced Exit¶
As a protocol participant,
I want to permissionlessly trigger a forced exit on any megapool where deficit >= exit_deficit,
So that the protocol can reclaim funds and limit ongoing losses from negligence or block reward theft without relying on the misbehaving operator to act.
- Acceptance Criteria:
- The megapool exit function is permissionlessly callable when
deficit >= exit_deficit. - The transaction reverts when
deficit < exit_deficitfor a non-operator caller. - A forced exit removes only the minimum number of validators needed to bring
deficitbelowexit_deficit, so the operator is not over-penalised and unnecessary validator churn is avoided. - The transaction reverts if it would exit more validators than necessary.
- The selected validators are submitted as exit requests to RPIP-80, which carries out the exit.
- Emits an event.
- The megapool exit function is permissionlessly callable when
2.2: Apply Debt Before Withdrawal¶
As the protocol,
I want to apply withdrawn, credit, and received balances against outstanding debt before releasing any funds to the operator,
So that the protocol's claim is settled first and the deficit is correctly reduced.
- Acceptance Criteria:
- Existing
debtis repaid in priority before any node-side funds are released to the operator:debt- direct repayment must be available viarepayDebt.received—_distributeAmountmust repay debt from the node reward share;_claimmust repay debt fromrefundValue.withdrawn—_notifyFinalBalancemust repay debt from the node share of the beacon-chain withdrawal.credit—withdrawCredit/withdrawCreditFormust repay debt from node credit.
- Existing
Epic 3: Governance¶
3.1: Exit Deficit Threshold Management¶
As a the pDAO,
I want to update the exit_deficit threshold via on-chain governance,
So that the forced exit trigger can be tuned as the protocol matures and economic conditions change.
- Acceptance Criteria:
exit_deficitcan only be updated by pDAO proposal.- The update emits an event.
Epic 4: Monitoring & Tooling¶
4.1: Smart Node Alerting¶
As a Rocket Pool Node Operator,
I want to see on my Grafana dashboard if any of my megapools have debt and how close I am to the exit_deficit,
So that I can settle my debt before my validators are forcibly exited.
- Acceptance Criteria:
- The dashboard surfaces the current
debtper megapool and flags whendeficitnears or reachesexit_deficit.
- The dashboard surfaces the current
4.2: Community Monitoring¶
As the Rocket Pool community,
I want to see which megapools have debt or a deficit,
So that we can observe the protocol reclaiming funds from negligent or malicious operators.
- Acceptance Criteria:
- Website feature that displays a summary of debt and forced exits.
Questions¶
- Missing debt-reclaim path for
credit. Thedeficitformula netscreditagainstdebt, but there is no on-chain mechanism that applies a node's deposit-pool credit toward megapool debt —received(via_distributeAmount/_claim) andwithdrawn(via_notifyFinalBalance) both have reclaim paths, butcreditdoes not. In fact_withdrawCreditForrequiresdebt == 0, so credit is locked rather than usable while debt exists. Do we need acredit→debtrepayment path for the accounting to be consistent? - Missing debt-reclaim path for the "ETH staked on behalf of the node" portion of
received. ETH staked on behalf of the node is itself implemented in v1.4, but — likecredit— there is no on-chain mechanism that applies it toward outstandingdebt. Thereceiveddebt-reclaim paths that do exist (_distributeAmount/_claim) cover the node reward share andrefundValue, not this staked-on-behalf portion. Do we need a reclaim path so it can reducedeficitconsistently with the rest ofreceived? - Is there any incentive (e.g. gas reimbursement) for the user who triggers a permissionless forced exit?
- How does this interact with RPIP-71 (withdrawal liquidity) and RPIP-73 (performance) exits when multiple exit conditions apply to the same megapool?