Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions EIPS/eip-0000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
eip: 0000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
eip: 0000
eip: 8069

title: Prevent consolidation overflow withdrawals
description: Limit a source validator's movable balance by the target validator's available room, accounting for already-reserved incoming consolidations
author: Anders Elowsson (@anderselowsson)
discussions-to: https://ethereum-magicians.org/t/eip-0000-prevent-consolidation-overflow-withdrawals/26016
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
discussions-to: https://ethereum-magicians.org/t/eip-0000-prevent-consolidation-overflow-withdrawals/26016
discussions-to: https://ethereum-magicians.org/t/eip-8069-prevent-consolidation-overflow-withdrawals/26016

Updated with assigned number

status: Draft
type: Standards Track
category: Core
created: 2025-10-29
requires: 7251
---

## Abstract

This EIP modifies EIP-7251 by limiting the balance a source validator can consolidate into a target validator. The transferable amount is capped by the target validator's available room, defined as `MAX_EFFECTIVE_BALANCE_ELECTRA` minus its current effective balance and any other incoming consolidations already reserved in the queue. This prevents consolidation overflow withdrawals which side-step the intended churn budgets. Incoming consolidations are tracked by adding a `reserved_balance` field to the `BeaconState`.

## Motivation

Electra introduces a churn consolidation budget separate from the churn activation/exit budget. This separation enables a validator to route effective balance through the consolidation queue even when the exit queue is congested. Specifically, when the consolidation’s target has `0x02` (compounding) credentials, any post-consolidation balance in excess of `MAX_EFFECTIVE_BALANCE_ELECTRA` (`2048` ETH) is after consolidation churning eligible for the partial-withdrawal sweep, paying the target’s withdrawal address.

To prevent stakers from side-stepping the intended churn budgets, this EIP bounds a source validator's `movable_balance` by the actual room available on the target validator, accounting for any other consolidations already enqueued for the target validator. This is achieved via a limited set of changes to two existing functions and by adding a new field in two separate containers.

## Specification

### Modified containers

Add an explicit record of the amount reserved from the consolidation churn at request time:

```python
class PendingConsolidation(Container):
source_index: ValidatorIndex
target_index: ValidatorIndex
reserved_amount: Gwei # Amount of balance reserved in churn
```

Aggregate incoming consolidation reservations per target validator:

```python
class BeaconState(Container):
...
reserved_balance: List[Gwei, VALIDATOR_REGISTRY_LIMIT] # Sum of reserved_amounts
```

### Modified functions

In `process_consolidation_request()`, bound the consolidation by current room on the target validator:

```python
def process_consolidation_request(state: BeaconState, consolidation_request: ConsolidationRequest) -> None:
...
# After this existing line
if get_pending_balance_to_withdraw(state, source_index) > 0:
return

# Bound the consolidation by effective + reserved (er) balance on the target validator.
target_er_balance = target_validator.effective_balance + state.reserved_balance[target_index]
if target_er_balance >= MAX_EFFECTIVE_BALANCE_ELECTRA:
return
target_room = MAX_EFFECTIVE_BALANCE_ELECTRA - target_er_balance
movable_balance = min(source_validator.effective_balance, target_room)
state.reserved_balance[target_index] += movable_balance

...
# Finally, adjust two existing lines as follows
source_validator.exit_epoch = compute_consolidation_epoch_and_update_churn(state, movable_balance)
...
state.pending_consolidations.append(PendingConsolidation(
source_index=source_index,
target_index=target_index,
reserved_amount=movable_balance,
))
```

In `process_pending_consolidations()`, reduce the `reserved_balance` on the target validator after processing the `pending_consolidation`:

```python
def process_pending_consolidations(state: BeaconState) -> None:
...
# After this existing line
if source_validator.slashed:
# Ensure we release the per-target reservation when dropping this pending consolidation
state.reserved_balance[pending_consolidation.target_index] -= pending_consolidation.reserved_amount
...
# Adjust the source_effective_balance calculation to also account for
amount = min(
state.balances[pending_consolidation.source_index],
source_validator.effective_balance,
pending_consolidation.reserved_amount)

# Move amount to target. Excess balance is withdrawable.
decrease_balance(state, pending_consolidation.source_index, amount)
increase_balance(state, pending_consolidation.target_index, amount)

# Ensure we release the per-target reservation when this pending consolidation is executed
state.reserved_balance[pending_consolidation.target_index] -= pending_consolidation.reserved_amount
...
```

In `add_validator_to_registry`, add the reserved balance: `set_or_append_list(state.reserved_balance, index, Gwei(0))`

## Rationale

The primary motivation for this EIP is to maintain the integrity of the consolidation churn budget. This is also why over-reservation is bounded already at request time in `process_consolidation_request()`. By checking the target validator's `effective_balance` plus its already `reserved_balance`, we determine the *actual* available room. The `movable_balance` is capped at this room, ensuring that the amount added to the consolidation churn accurately reflects the balance that can *actually* be processed. Thus, the consoliddation churn will produce consolidated validators.

While a target validator's balance might have increased (e.g., via attestations) *after* the request was enqueued, reducing the available room, this specification does not add a *second* check to cap the transfer. Such sub-ETH "overflows" are not an issue and do not justify the added complexity of re-evaluating the cap during processing.

## Security Considerations

This EIP mitigates a known live economic attack vector. To the best of the authors' knowledge, there are no security risks associated with the proposal.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).