feat: clear queued beacon-chain-ETH withdrawals on pod disable#2
Open
MC1823315 wants to merge 3 commits into
Open
feat: clear queued beacon-chain-ETH withdrawals on pod disable#2MC1823315 wants to merge 3 commits into
MC1823315 wants to merge 3 commits into
Conversation
Motivation: With share re-crediting blocked and REL zeroed on disable, a pod owner's queued beacon-chain-ETH withdrawals become permanently uncompletable but linger in the DelegationManager queue forever, polluting queue views and leaving a standing "pending but uncompletable" invariant violation. Modifications: - Added DelegationManager.clearQueuedWithdrawalsForDisabledPod (onlyEigenPodManager), which removes the staker's queued beacon-chain-ETH withdrawal entries without re-crediting shares or changing delegation (both were already decremented at queue time). Pure-LST withdrawals are left untouched. - Added an EigenPodManager passthrough (onlyEigenPod) and wired the call into EigenPod.permanentlyDisableRestaking, after zeroing REL. - Added QueuedWithdrawalClearedForDisabledPod event and interface entries. - Updated mocks, docs, and added unit + integration tests. The disable integration test now asserts the withdrawal is removed from the queue. Result: Disabling a pod cleans up its dead beacon-chain-ETH queue entries instead of leaving them inert. Value is still recovered via withdrawNonRestakedBalance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4a291cb to
893ef3d
Compare
Motivation: clearQueuedWithdrawalsForDisabledPod performs an irreversible delete of a staker's beacon-chain-ETH queue entries. The non-beacon-chain leg of a mixed withdrawal is unrecoverable once cleared (its deposit shares were already decremented at queue time, and the pod's non-restaked sweep only recovers ETH). The safety check that prevents this lived solely in EigenPod's disable preconditions (MixedWithdrawalPending), one contract away from the destructive operation. Modifications: - Added a defense-in-depth require(!hasOther, MixedWithdrawalNotClearable()) in DelegationManager.clearQueuedWithdrawalsForDisabledPod, before the delete, so the value-destroying operation is self-guarding rather than dependent on a caller invariant. - Added the MixedWithdrawalNotClearable error to IDelegationManager. - Added test_Revert_mixedWithdrawal unit test asserting a mixed bc-ETH + LST withdrawal reverts instead of being cleared. Result: If a mixed withdrawal ever reaches this function through a future caller or an upstream regression, it reverts instead of silently destroying unrecoverable value. Reachable behavior is unchanged today. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tion Motivation: A review of the disabling-restaking documentation surfaced terminology, accuracy, and completeness gaps between the docs/comments and the implementation. Modifications: - Renamed "cross-pod consolidation" to "external consolidation" across EigenPod.sol, IEigenPod.sol, EigenPod.md, and tests (including the integration test name), since the target may be any validator, not only one in another pod. - Completed the permanentlyDisableRestaking precondition narrative (beacon-chain slashing and per-withdrawal AVS-slashing checks) and synced the Effects/Requirements lists to the implementation (REL zeroing, queue clearing, MixedWithdrawalPending, the delegatedTo == address(0) skip). Trimmed redundant rationale prose. - Fixed EIP-7521 -> EIP-7251 typo. - Clarified withdrawNonRestakedBalance: restakedExecutionLayerGwei is always 0 once disabled, so the method sweeps the full pod balance; the subtraction is retained only to mirror the general free-balance formula. Updated the code comment to match. Result: The disabling-restaking documentation and code comments accurately and consistently describe the implemented behavior. No production logic changed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation:
Builds on the inert-withdrawal approach. With share re-crediting blocked and REL zeroed on disable, a pod owner's queued beacon-chain-ETH withdrawals become permanently uncompletable but linger in the DelegationManager queue forever, polluting queue views and leaving a standing "pending but uncompletable" invariant violation.
Modifications:
DelegationManager.clearQueuedWithdrawalsForDisabledPod(onlyEigenPodManager), which removes the staker's queued beacon-chain-ETH withdrawal entries without re-crediting shares or changing delegation (both were already decremented at queue time). Pure-LST withdrawals are left untouched.EigenPodManagerpassthrough (onlyEigenPod) and wired the call intoEigenPod.permanentlyDisableRestaking, after zeroing REL.QueuedWithdrawalClearedForDisabledPodevent and interface entries.Result:
Disabling a pod cleans up its dead beacon-chain-ETH queue entries instead of leaving them inert. Value is still recovered via
withdrawNonRestakedBalance. Compare against the inert-withdrawal PR to weigh the added cross-contract surface against cleaner queue state.🤖 Generated with Claude Code