Anti-Correlation Attestation Penalties
Scales penalties for fully-offline validators by the excess of concurrently offline stake over its trailing average
Abstract
The decentralization of the validator set is one of the most important properties of Ethereum for credible neutrality and censorship resistance. This EIP scales the attestation penalty of validators that fail to attest as a function of how many other validators failed at the same time. Each slot receives a penalty_factor proportional to the excess of that slot's offline balance over a slow-moving average of offline balance, capped at MAX_PENALTY_FACTOR. Validators whose failures are uncorrelated with the rest of the network pay the same penalties as today; validators that fail together — same node, cloud provider, client, geography, or operator — pay up to MAX_PENALTY_FACTOR times more during the onset of a correlated outage.
The penalty factor is deliberately front-loaded: it is highest in the first hours of a correlated failure and decays as the moving average absorbs the event, so that the marginal cost of remaining offline returns toward the status quo. This punishes correlated setups without punishing slow rectification, which disproportionately affects smaller operators.
Motivation
During normal network operation there is no economic incentive to diversify node operations across nodes, geographies, clients, Internet Service Providers (ISPs), or cloud providers, other than reducing the chance that all of one's validators fail simultaneously. Attestation penalties are agnostic to the behavior of other participants: a validator that fails alone and a validator that fails together with 30% of the network pay exactly the same penalty per epoch.
Correlation is the natural discriminator between large and small staking operations. Empirical analysis of historical attestation data shows strong excess correlated failures within operator clusters: validators belonging to the same entity miss together far more often than chance predicts, while solo stakers behave almost independently. Penalizing correlated failure therefore reduces the economies of scale of large, homogeneous staking setups without requiring the protocol to identify entities, and without harming solo stakers on average.
The protocol already prices correlated failure — but only above the finality threshold. If more than one third of stake goes offline, the inactivity leak imposes quadratic, principal-level losses. Below one third, correlation is free: the protocol prices it as a step function at 33%. This EIP extends correlation pricing smoothly into the 1%–33% band, front-loaded at outage onset, with severity that scales with the size of the correlated event. The existing inactivity leak remains unchanged and continues to own principal-level punishment for finality failures; the two mechanisms layer naturally.
Specification
| Parameter | Value | Description |
|---|---|---|
MAX_PENALTY_FACTOR | uint64(256) | Ceiling on the penalty factor; the single severity parameter |
PENALTY_SLOPE | uint64(765) | Slope of the penalty factor in excess offline stake; equal to 3 * (MAX_PENALTY_FACTOR - 1), which makes the cap bind at exactly one third of stake |
OFFLINE_BALANCE_SMOOTHING_FACTOR | uint64(2**16) | Smoothing divisor of the offline balance moving average; half-life of roughly 45,500 slots (~6.3 days) |
This document follows the conventions of the Ethereum consensus specifications. Gwei is a uint64 amount denominated in gwei (10^9 wei), and Gwei(x) constructs a value of that type; all balances in this document are Gwei. Constants and types not defined here — SLOTS_PER_EPOCH, TIMELY_SOURCE_FLAG_INDEX, TIMELY_TARGET_FLAG_INDEX, TIMELY_HEAD_FLAG_INDEX, TIMELY_SOURCE_WEIGHT, TIMELY_TARGET_WEIGHT, WEIGHT_DENOMINATOR, BeaconState, Slot — carry their consensus-specification (Altair and later) definitions and values. The pseudocode is illustrative rather than executable: helper functions used without a definition (get_committee_assignment_indices, get_previous_epoch_slots, is_offline, get_assigned_slot, slot_index, mean_per_slot_offline_balance_of_previous_epoch) have their evident meanings, and the executable definitions live in the Ethereum consensus specifications.
Beacon state
Add a single field to the BeaconState:
smoothed_offline_balance: Gweismoothed_offline_balance is an exponential moving average of the per-slot offline balance, defined below.
Offline balance
A validator is offline for an epoch if it is active, not slashed, and has neither the timely source nor the timely target participation flag set for that epoch. Validators that attested with an incorrect target but a correct and timely source are not offline: they demonstrated liveness, and their failure is a view disagreement rather than an infrastructure fault.
def get_slot_offline_balance(state: BeaconState, slot: Slot) -> Gwei:
"""
Sum of effective balances of offline validators whose committees
were assigned to ``slot`` in the previous epoch.
"""
offline_indices = [
index for index in get_eligible_validator_indices(state)
if index in get_committee_assignment_indices(state, slot)
and not has_flag(state.previous_epoch_participation[index], TIMELY_SOURCE_FLAG_INDEX)
and not has_flag(state.previous_epoch_participation[index], TIMELY_TARGET_FLAG_INDEX)
]
return Gwei(sum(state.validators[index].effective_balance for index in offline_indices))Penalty factor
At the start of epoch processing, before process_rewards_and_penalties, compute one penalty_factor per slot of the previous epoch, updating the moving average slot by slot:
def get_slot_reference_balance(state: BeaconState) -> Gwei:
return Gwei(get_total_active_balance(state) // SLOTS_PER_EPOCH)
def process_penalty_factors(state: BeaconState) -> Sequence[uint64]:
factors = []
for slot in get_previous_epoch_slots(state):
offline_balance = get_slot_offline_balance(state, slot)
excess = offline_balance - min(offline_balance, state.smoothed_offline_balance)
penalty_factor = min(
uint64(1) + PENALTY_SLOPE * excess // get_slot_reference_balance(state),
MAX_PENALTY_FACTOR,
)
factors.append(penalty_factor)
# Moving average update
if offline_balance > state.smoothed_offline_balance:
state.smoothed_offline_balance += (offline_balance - state.smoothed_offline_balance) // OFFLINE_BALANCE_SMOOTHING_FACTOR
else:
state.smoothed_offline_balance -= (state.smoothed_offline_balance - offline_balance) // OFFLINE_BALANCE_SMOOTHING_FACTOR
return factorsWhen the offline balance does not exceed the moving average, penalty_factor is exactly 1. The factor is never below 1: there are no discount windows. The moving average sets only the subtracted baseline; the slope is normalized by per-slot active balance, so the shape of the penalty curve does not depend on the network's prevailing participation rate.
Penalty application
In get_flag_index_deltas, the timely target penalty of an offline validator (as defined above) is scaled by the penalty_factor of the slot its committee was assigned to. Only the existing penalty branch changes — the branch reached exclusively by eligible validators that do not have the flag set; who is penalized, and every reward, is unchanged:
for index in get_eligible_validator_indices(state):
if index in unslashed_participating_indices:
... # rewards, unchanged
elif flag_index != TIMELY_HEAD_FLAG_INDEX:
# Existing penalty branch: ``index`` lacks this flag for the epoch
if flag_index == TIMELY_TARGET_FLAG_INDEX and is_offline(state, index):
# Offline: missed both timely source and timely target
slot = get_assigned_slot(state, index)
penalty_factor = penalty_factors[slot_index(slot)]
penalties[index] += Gwei(penalty_factor * base_reward * weight // WEIGHT_DENOMINATOR)
else:
penalties[index] += Gwei(base_reward * weight // WEIGHT_DENOMINATOR)All other rewards and penalties are unchanged:
- The timely source penalty is not scaled.
- Timely head misses carry no penalty, as today.
- Proposer and sync committee rewards and penalties are unchanged.
- Inactivity leak penalties are unchanged.
Fork transition
At the fork epoch, initialize:
smoothed_offline_balance = mean_per_slot_offline_balance_of_previous_epoch(pre_state)This seeds the reference with the observed pre-fork baseline so that no spurious penalty factor occurs at activation.
Rationale
Relative-to-trailing-average design
The penalty factor compares the current slot's offline balance to a slowly-updating exponential moving average of the same quantity. This has three consequences:
- Front-loading. At the onset of a correlated outage the factor jumps to a value proportional to the size of the anomaly, then decays over roughly a day as the moving average absorbs the event. The marginal cost of each additional hour offline falls back toward the status quo. Operators are punished for being correlated, not for taking time to recover — the latter would disproportionately harm small operators, who rectify more slowly than professional ones.
- Severity scales with the event, across the entire sub-finality band, independently of the baseline. Onset factors are
1 + PENALTY_SLOPE * spike: a 1% correlated failure opens at ~9x, 5% at ~39x, 10% at ~78x, and 20% at ~154x. BecausePENALTY_SLOPE = 3 * (MAX_PENALTY_FACTOR - 1), the cap binds at exactly one third of stake — the finality threshold where the inactivity leak takes over — as an identity rather than a calibration. Uncorrelated failures continue to pay ~1x. - Predictable steady state. Under stable participation the factor is exactly 1 for every slot. There is no penalty noise for ordinary uncorrelated misses, and no below-1 discount windows that would reward being offline during recovery periods.
Normalization by active balance
The excess is divided by get_slot_reference_balance (per-slot active balance) rather than by the moving average itself. Dividing by the moving average would make every onset factor, and the point at which the cap binds, proportional to the network's baseline offline rate: at the ~0.3% offline rate observed on mainnet in mid-2026, a moving-average-relative curve calibrated against a 0.5% assumption steepens by two thirds and saturates near 19% instead of one third. Normalizing by active balance makes the curve invariant to participation drift, and reduces the value of manipulating the reference: inflating the moving average now only shifts the subtracted baseline instead of rescaling the slope.
Committee selection is not stake-weighted, so realized per-slot committee balances vary with the mix of consolidated (EIP-7251) and 32-ETH validators. This variance is small — roughly 1.2% relative standard deviation at the current validator count, and near 2% even under heavy consolidation — and the reference balance used in the denominator is the deterministic per-slot average, so sampling noise enters only through the numerator, where the moving average absorbs it.
Linearity
A non-linear (convex) factor was considered and rejected. The aggregate network-wide penalty under a linear individual factor is already quadratic in event size — the affected stake and the factor each grow linearly — mirroring the structure of the existing correlated slashing penalty, where the individual penalty is linear in the slashed cohort fraction. A convex individual factor would push the aggregate to cubic while removing deterrence from the 1–15% band, which is where the events controlled by any single operator's choices (client, cloud, geography) actually occur; events above 20% arise from combinations of operators that no single decision controls.
Replacement of the earlier NET_EXCESS_PENALTIES mechanism
Earlier drafts of this EIP tracked a NET_EXCESS_PENALTIES counter with a fixed decrement per slot. That mechanism has an invariant: the sum of factor-above-one over any step change in participation equals a fixed budget, independent of MAX_PENALTY_FACTOR and of outage duration. Three defects follow at deterrent magnitudes:
- The cap is nearly irrelevant to total penalties — raising it only concentrates the same budget into fewer slots. At the previous constants (
PENALTY_ADJUSTMENT_FACTOR = 4096, cap 4), a correlated outage of any size and duration cost at most a few percent more than the status quo. - At mainnet participation rates the counter's equilibrium is below 1, so it oscillates around zero and ordinary uncorrelated misses draw random factors between 0 and the cap.
- The counter decays by 1 per slot, so at magnitudes large enough to deter, the post-event recovery window stretches to months, during which the mechanism is blind to further correlated events.
An explicit moving-average reference fixes all three: totals are governed by the factor curve rather than a fixed budget, the steady state is exactly 1, and the mechanism re-arms with a fixed ~one-week half-life regardless of event size.
Scope: timely target only, offline validators only
Scaling is restricted to the timely target penalty of validators that missed both source and target, for robustness rather than leniency:
- Target has the widest inclusion window (the entire next epoch), so a target flag reliably reflects validator liveness rather than block-space or timing luck. Source timeliness fails after five slots without a block, so a builder, relay, or proposer outage can fabricate source misses for perfectly healthy validators; it cannot fabricate target misses short of a halted chain.
- The both-flags requirement excludes view disagreements. A validator that attests with a correct source but a wrong target — because an epoch-boundary block was late, because a proposer split views, or because its (correct-minority) client disagreed with a buggy majority — demonstrated liveness and pays only today's unscaled penalty. Only validators that produced no timely attestation at all, the signature of an infrastructure failure, are subject to scaling. This eliminates the profitable variants of proposer view-splitting attacks and avoids punishing operators who correctly remain on a minority client during a majority-client incident. The largest such disagreement is systematic and measurable: because the target checkpoint for an epoch is today anchored to the epoch's first block, the first slot's committee races the checkpoint block itself, and in the historical replay 91–97% of alive-but-wrong-target stake at baseline sits in slot 0 of the epoch. None of it is scaled under this gate (the scaled cohort is uniform across slots), and none of it enters the offline balance that drives the factor. EIP-8333 removes that artifact at the root by anchoring the checkpoint to the last block before the epoch; this EIP composes with it but does not depend on it.
- Gating on source votes instead was considered and rejected. The timely source flag expires five slots after the attested slot, so runs of missed blocks mark live validators as offline precisely when the penalty factor is elevated — at the May 2023 plateau, 5.3% of stake had a timely target but no timely source (alive, denied inclusion by the missed-slot storm), against 0.11% the other way around. A source-gated indicator also shrinks the censorship-griefing surface from a full epoch of inclusion opportunities to five slots, and during finality stress desynced validators sign stale justified checkpoints, making source-side signals unreliable in exactly the events this mechanism prices. Target-side artifacts are constant-rate baseline noise that the moving average absorbs into the reference; source-side artifacts are event-correlated.
- Timely head misses remain unpenalized, as today; head voting is the flag most sensitive to proposer timing games.
Parameter calibration
Illustrative costs per 32 ETH of stake, assuming ~40M ETH staked and expressing losses as multiples of expected total staking rewards (consensus and execution layer). The figures are independent of the baseline offline rate: under the active-balance normalization, the excess above the moving average — and therefore every penalty factor — depends only on the size of the anomaly. "Down for" is the individual operator's rectification time within an event where the correlated cohort is offline for 24 hours:
| Correlated offline stake | Down for | Cost vs today | Total loss | Share of 32 ETH principal |
|---|---|---|---|---|
| uncorrelated (any) | 24 h | 1.0x | ~1 day of rewards | ~0.01% |
| 1% | 24 h | ~3x | ~half a week of rewards | 0.03% |
| 5% | 24 h | ~11x | ~2 weeks of rewards | 0.12% |
| 10% | 6 h | ~22x | ~1 week of rewards | 0.06% |
| 10% | 24 h | ~21x | ~3.6 weeks of rewards | 0.22% |
| 10% | 72 h | ~8x | ~4 weeks of rewards | 0.24% |
| 20% | 24 h | ~41x | ~7 weeks of rewards | 0.43% |
| 40% (leak active) | 24 h | ~5.6x | ~3.4 months of rewards | 0.90% (0.75% this EIP + 0.15% leak) |
| 40%, 3-day outage (leak active) | 72 h | ~2.5x | ~13.5 months of rewards | 3.5% (2.2% this EIP + 1.4% leak) |
Note the 72-hour rows: a straggler that recovers two days after its cohort pays little more than a 24-hour rectifier, because the factor collapses once the aggregate anomaly ends. In the leak-active rows the totals are decomposed because the inactivity leak already exists today and is unchanged by this EIP: above one third offline the two mechanisms layer, with the quadratic leak growing to dominate multi-day finality failures — by design. Per-validator numbers understate what the mechanism means to the operators it targets: 0.23% of principal for the 10%/24h row is roughly 900 ETH per 1% of total stake an operator runs — an operator whose 10%-of-stake fleet fails together for a day forfeits on the order of 9,000 ETH.
Validation against historical incidents
Both mechanisms were replayed over per-slot offline balances reconstructed from public chain data for four mainnet incidents, each scored under the participation-flag rules in force at its epoch and its era's measured execution-layer income. Days-to-recoup is per 32 ETH over the incident window:
| Incident | Peak offline stake | As drafted | This revision |
|---|---|---|---|
| May 11+12 2023 finality incidents | 69% (cap binds) | 1.16x | 79x (1.9 days) |
| Besu halt, 2024-01-06 | 12.4% | 1.04x | 3.4x (4.3 hours) |
| Nethermind consensus bug, 2024-01-21 | 18.8% | 1.01x | 14x (21 hours) |
| Prysm post-Fusaka outage, 2025-12-04 | 29.8% | 1.01x | 45x (4.7 days) |
The drafted mechanism is within a few percent of the status quo on all four incidents — including the May 2023 events that motivated it — confirming the fixed-budget invariant on real data. The revision scales with severity, and the cap binds only in the single incident that crossed one third of stake. In operator terms, the 2025 incident prices at roughly 240 ETH per 1% of total stake run — around 2,400 ETH for a 10%-of-stake operator caught for the full 4.5 hours — against low single-digit ETH under current rules. Because the reconstruction records each validator's offline epochs individually, the front-loading claim is also measurable. Among validators offline from the 2025 incident's onset, one recovering at 24–36 hours paid 1.5x one recovering at 6–8 hours, versus 4.7x for the same spread under current rules — equivalently, the multiple over today's cost falls from ~57x for the fastest responders to ~9x for the slowest, because the charge is concentrated at onset. Validators whose outages began after the cohort recovered paid near today's rates for the same durations.
Smoothing window
OFFLINE_BALANCE_SMOOTHING_FACTOR = 2**16 gives the reference a half-life of ln(2)·2^16 slots ≈ 6.3 days. Replaying the four incidents above under half-lives from 1.6 to 25 days moves none of them materially: recorded outages are cliffs, hours-scale against any days-scale window, so their severity is set by the slope and cap (the December 2025 replay moves from 44.6x to 44.8x between 2^16 and 2^17). What the window prices is sustained correlated absence, and — because the excess integral has a closed form (see Security Considerations) — it is also the hard bound on how much an extended outage can ever cost. 2^16 was selected over 2^17 on exactly that trade: it halves the never-recover worst case (a one-third outage is bounded at ~2.6 years of rewards rather than ~5.2) while retaining ~84% of the week-one sustained deterrent (a 10%-of-stake cohort down for a week forfeits roughly 134 days of income at current economics) and 99% of the re-arm behavior (a repeat of the 2025 incident three days later would have met 99% of the original onset factor). The value also aligns with existing protocol timescales: 2^16 slots is exactly eight sync-committee periods and half the blob-sidecar retention window, and its half-life matches the weak subjectivity period after EIP-8061 (~7 days at current stake) — the mechanism forgets an outage on roughly the timescale a node can remain offline and still trustlessly rejoin the chain.
An asymmetric variant — a reference that rises with an hours-scale half-life so the factor decays with time since onset regardless of cohort behavior — was evaluated and rejected. For any per-slot factor computed from aggregate balances, forgiveness for slow-recovering individuals and forgiveness for deliberately sustained outages are the same quantity: a reference fast enough to spare a 24-hour straggler also prices a 20%-of-stake, 3-day outage at a mean factor in the low single digits, removing the sustained deterrent entirely, while improving the measured straggler premium only from 1.40x to roughly 1.2x.
MAX_PENALTY_FACTOR
The cap serves three purposes: it bounds the worst-case bleed rate (at cap 256 with target-only scope, a fully offline validator loses at most ~0.75% of a 32 ETH principal per day), it bounds the payoff of any attack that manufactures misses, and it bounds collateral damage to uncorrelated validators that happen to be offline during someone else's crisis. Because PENALTY_SLOPE is derived from it, MAX_PENALTY_FACTOR is the single severity parameter: raising or lowering the cap rescales the whole curve while saturation stays at one third. Attestation-penalty scaling is deliberately a flow-level deterrent: principal-level punishment remains reserved for finality failures (the leak) and equivocation (slashing).
The value 256 was selected from a severity sweep over the historical incidents. Caps from 128 to 512 (slope tied at 3 * (cap - 1)) and slope-decoupled variants (steeper slope, cap held at 128, saturation below one third) were each scored on the four replayed events plus the worst-case scenarios. Cap 512 was rejected because its tails overreach — a solo staker caught in a majority-client bug during a three-day finality loss approaches 6% of principal, and an innocent bystander offline six hours during a 40% crisis pays six weeks of income. Slope-decoupled variants keep every worst-case bound at the cap-128 level but price a 17% event and a 30% event identically and forfeit the saturation-at-one-third identity. Cap 256 doubles the deterrent across the band where operator choices live while keeping the three-day-finality-loss worst case near 3.6% of principal, most of the gap to which is the pre-existing leak.
FAQ
Could this cost me my stake? No. The mechanism scales an existing flow-level penalty. Its hard ceiling is ~0.75% of principal per day of full offline-ness during a maximal correlated event, and realistic events cost days-to-weeks of rewards. Principal-level losses remain exclusive to the inactivity leak and slashing, both unchanged.
Does this hurt solo stakers? Solo staker failures are almost entirely uncorrelated, so they pay factor ~1 — exactly today's penalties. Historical backtesting of correlation penalties consistently shows small and solo operators paying less than large clusters relative to the status quo. Even the nightmare framing bounds itself: solo and home stakers are collectively a low single-digit percent of stake, so a failure mode that hits every consumer-grade setup at once (a hard-to-fix home-network exploit, say) is still only a small event to the mechanism — a 3% cohort draws a ~24x onset factor and a lifetime bound near 0.6% of principal, months of rewards, even if recovery takes indefinitely long. The residual exposure is being offline by coincidence during someone else's crisis (see Security Considerations).
Does this discourage minority clients? No; if anything it encourages them. A minority client bug takes down a small fraction of stake and draws a small factor, while a majority client bug takes down a large fraction and draws the cap. Operators on a correct minority client during a majority-client incident are online with correct sources, and are therefore not scaled at all.
Can a large operator just consolidate validators (EIP-7251) to dodge this? No. All quantities are balance-weighted; 4,000 ETH failing together is penalized identically whether it is two consolidated validators or 125 32-ETH ones.
What about a relay or builder outage? Missing blocks do not prevent attesting; attesters vote the prior head and retain full credit. The only artifact — timely-source loss when five or more consecutive slots are empty — is excluded because scaling requires missing the target flag too, which has a full-epoch inclusion window.
Doesn't a late epoch-boundary block make target votes wrong through no fault of the validator? Yes — the first slot's committee races the checkpoint block, and measurably ~92% of alive-but-wrong-target stake at baseline sits in slot 0. Those validators keep their timely source, so they are never scaled and never counted in the offline balance; they pay exactly today's penalty. EIP-8333 fixes the race itself by anchoring the checkpoint before the epoch starts, which makes a wrong target an even cleaner desync signal; this mechanism works either way.
What if an outage flaps on and off? The moving average remains elevated after the first onset, so repeated flapping within the ~one-week half-life is charged less than the equivalent number of isolated events. Oscillation cannot compound the penalty.
What happens above one third offline? The factor saturates at the cap, and the inactivity leak — which activates once finality is lost — provides the escalation: quadratic, principal-level losses that dwarf attestation penalties within days. The two mechanisms are calibrated to hand over at the same point.
Does this punish operators who are slow to apply a patch? Far less than current rules do, relative to their peers. The factor tracks the current excess offline balance, so it collapses as the cohort recovers; whoever is still down afterwards pays close to today's rates. Measured on the December 2025 incident's onset cohort: recovering at 24–36 hours cost 1.5x recovering at 6–8 hours, versus 4.7x under current rules — and the straggler's multiple over today's cost is ~9x against the fast responder's ~57x. The mechanism charges for joining the correlation, not for leaving it slowly.
Why are the increased penalties burned rather than redistributed? Redistributing them across time (the drafted mechanism's sub-1x recovery windows) restores the fixed-budget no-op and subsidizes misses during post-crisis recovery. Redistributing them to online validators would fund discouragement attacks: a large correlated event creates a pool worth thousands of ETH, and any staker able to cause a competitor outage would collect its stake-share of that pool — whereas a burn pays attackers nothing, consistent with every existing penalty in the protocol. The issuance impact of the burn is event-contingent and small: replayed over the historical incidents above, the worst single event reduces issuance by roughly 0.6% of one year's issuance, once, and the steady-state impact is zero because the factor is exactly 1 at baseline participation.
Is this compatible with decoupling finality from fork choice? Yes. Proposed fast-finality designs split today's attestation into separate fork-choice and finality votes. This mechanism scales only the finality-side penalty (timely target) and gates on the source and target flags, deliberately leaving head votes untouched — so the scaled signal lives entirely in the component that remains a full-validator-set finality vote under such designs, while the fork-choice message, which may move to small committees, is the part this EIP never scales. Nothing in the mechanism depends on epoch structure beyond the smoothing constant, which is a tunable.
Backwards Compatibility
This is a backwards incompatible adjustment of attestation penalties that requires a scheduled network upgrade. Rewards are unchanged; only the penalty of validators missing both source and target votes is scaled. Staking-reward estimators and dashboards that model penalties should incorporate the per-slot penalty factor.
Security Considerations
Manufactured misses (view splitting, timing games)
A proposer can attempt to split views or release blocks late so that some committees attest incorrectly, hoping to inflate their penalties. Under this design those strategies are unprofitable: head votes are never penalized, wrong-target-but-live attestations are never scaled, and a validator can only be scaled if it produces no timely attestation at all, which a proposer cannot induce in a healthy validator. The residual vector is suppressing a validator's attestations entirely (censorship of its aggregates across a full epoch of inclusion opportunities); this requires sustained control of block space, is publicly visible, and its payoff per affected validator is bounded by the cap.
Reference suppression (griefing the moving average)
An entity could sustain elevated offline balance for weeks to inflate smoothed_offline_balance, cheapening a future correlated event. This costs the griefer full attestation penalties on the sustained offline stake for the duration and is publicly visible on-chain. Because the slope is normalized by active balance, inflating the moving average only shifts the subtracted baseline: reducing a future 10% event's factor by half would require sustaining roughly 5% of stake offline for weeks. The inactivity leak is unaffected by any reference manipulation.
Collateral damage to bystanders
During a large correlated event, an uncorrelated validator that is coincidentally offline pays the same elevated factor as the correlated cohort — roughly three weeks of rewards for six hours of downtime during a 40% crisis at the calibrated constants. This is an unavoidable property of statistical correlation penalties, since the protocol cannot observe membership in the failing cluster. The cap bounds the exposure, the expected cost is small because such coincidences are rare, and remaining online during network-wide incidents is the behavior the mechanism is designed to reward. The historical replay bounds the realized exposure: in the May 2023 finality incidents — the worst case for bystanders, since stalled block production left even healthy validators' attestations unincluded under that era's inclusion rules — a validator swept in for one or two epochs would have paid about 0.44 days of income at the calibrated constants, and 90% of the non-attesting stake at the plateau had produced no timely attestation at all.
Repeated events and re-arming
Because the reference decays with a fixed half-life, the mechanism re-arms within weeks regardless of event size, unlike counter-based designs whose blind window scales with event magnitude. Sawtooth outage patterns are charged strictly less than the same downtime as isolated events. A cohort that remains offline keeps paying an elevated factor until the moving average absorbs the event (on the order of the half-life); an individual validator's scaling ends the moment it resumes attesting.
Interaction with the inactivity leak
Above one third offline, both mechanisms are active: this EIP front-loads the first day of losses while the quadratic leak grows to dominate multi-day finality failures. Their combined effect at the calibrated constants is roughly 1–3% of principal for multi-day finality-losing outages, preserving the leak's role as the primary recovery mechanism. No change to leak behavior is made.
Worst-case bounds
The maximum penalty flow, sustained only while roughly a third of stake is newly offline and the validator itself is fully offline, is (TIMELY_SOURCE_WEIGHT + MAX_PENALTY_FACTOR * TIMELY_TARGET_WEIGHT) / WEIGHT_DENOMINATOR base rewards per epoch — approximately 0.75% of principal per day at current network size. That flow rate is not sustainable: the moving average chases any persistent outage with a ~6.3-day half-life, so the rate itself halves every half-life even if the cohort never recovers. Integrating the excess over an unbounded outage of size m below the cap gives a closed-form lifetime bound of PENALTY_SLOPE * m * (TIMELY_TARGET_WEIGHT / WEIGHT_DENOMINATOR) * OFFLINE_BALANCE_SMOOTHING_FACTOR // SLOTS_PER_EPOCH base rewards — the moving average's time constant is OFFLINE_BALANCE_SMOOTHING_FACTOR slots, but each validator is charged its factor once per epoch, on its one assigned slot — approximately 0.2 × m of principal at current network size. The worst case the mechanism can ever inflict — joining a one-third outage and never returning — is therefore bounded at ~6.7% of principal, about 2.6 years of rewards; a 30% outage is bounded at ~6% and a 10% outage at ~2%, however long the bug takes to fix. Recovery ends the scaling immediately, exiting is also an off-ramp (EIP-8061 churn drains a 30% cohort in ~44 days), and above one third the pre-existing inactivity leak dominates this bound within days. Integer arithmetic is total-order safe: the divisor is per-slot active balance (nonzero for any non-empty validator set), and smoothed_offline_balance is bounded above by per-slot active balance.
Copyright
Copyright and related rights waived via CC0.