Safety Analysis of Balance Drift
The Safety Margin Formula
Key Variables and Notation
Let the trusted, finalized checkpoint be denoted by the pair , and the target checkpoint whose finality is being proven be . The number of elapsed epochs is . We define the following:
-
Validator Sets:
- : The set of active validators at .
- : The set of active validators at .
- : The subset of validators that have attested to the supermajority link required to justify .
-
Total Active Balance:
- : The total effective balance of all validators in , measured at . This is the value
get_total_active_balance
would return at . - : The total effective balance of all validators in , measured at .
- : The total effective balance of all validators in , measured at . This is the value
-
Attesting Weight:
- : The sum of the effective balances of the validators in , as measured from the trusted state at . This is the value our zkVM guest program calculates.
- : The sum of the effective balances of the validators in , as measured by the canonical protocol at . This is the value we are trying to safely reason about.
Derivation
The canonical requirement for finality is that the attesting weight at meets the two-thirds threshold:
To create a bound verifiable from the trusted state at , we must account for the maximum possible "balance drift". As slashings that occur after cannot be known from the trusted state, the total balance of these slashed validators must be provided as a separate input, . We then define:
- A: The maximum possible increase in the effective balance of the non-attesting validators () between and .
- E: The maximum possible decrease in the effective balance of the attesting validators () between and .
- S: The total effective balance of validators slashed between and . While slashed validators are penalized, their balance still contributes to the total active balance () for the supermajority calculation, but they are excluded from the attesting weight ().
The safety condition, as viewed from , can be expressed as:
Rearranging this to solve for the required attesting weight gives us our safety margin, : Thus, the safety margin is:
Unless otherwise stated, every - or -sub-term, and therefore , itself is expressed in ETH. When a term is derived from a raw validator count we implicitly multiply by 1 ETH per validator.
Bounding Balance Fluctuation Sources
We now derive conservative upper bounds for and over epochs, based on the Ethereum Electra specification.
Validator Churn and Consolidations
- Activations: In the current model, the set of validators that can become active during the lookahead period is completely determined by the trusted state at . A validator's activation requires that its
activation_eligibility_epoch
is less than or equal to thefinalized_checkpoint.epoch
.1 Since thefinalized_checkpoint
is fixed at for the entire verification process, any validator not already in the activation pipeline at cannot become active. Therefore, the increase in attesting weight from these known activations can be calculated precisely by the guest and is not a source of unbounded drift. - Exits & Consolidations: For the zkVM guest to compute correct committee shuffles, it must account for any validator exits or consolidations that occur after the trusted checkpoint. This information is provided as part of the untrusted witness data. From the perspective of the validator registry, a voluntary exit and a consolidation are indistinguishable. To create a single, safe upper bound for balance churn, their respective churn limits must be combined. This combined value corresponds to the
get_balance_churn_limit
in the specification, which is based on the constantCHURN_LIMIT_QUOTIENT
(65536). The official specification calculates this dynamic churn limit against the current total active balance at any given epoch , with a floor ofMIN_PER_EPOCH_CHURN_LIMIT_ELECTRA
(128 ETH). To prevent a malicious prover from supplying fraudulent data, the guest program validates the witness against a hardcoded churn limit. Simply using a limit based on could be unsafe, as the total active balance might increase over epochs, thus increasing the real churn limit. To account for this potential growth, the implementation uses a conservative factor of two. While a full formal analysis of this factor is complex, it serves as a safe, static bound for a reasonably small lookahead period . Because the guest strictly enforces this specific check, our formal analysis must adopt the exact same bound:
Rewards and Penalties
The total issuance per epoch is a function of the total active balance, in Gwei. It is a well-known design choice that per epoch the total issuance is Even with a total active balance as high as 100 million ETH, the total issuance would be only a little over 20 ETH. For simplicity and to be highly conservative, we use a constant upper bound of 48 ETH per epoch for both rewards and penalties. This is more than enough to account for future balance increases or "catch up" rewards for missed attestations due to skipped slots in the previous epoch
- Rewards (contributing to A):
- Penalties (contributing to E):
Inactivity Leak Penalty
During a prolonged non-finality event (an "inactivity leak"), inactive validators are penalized with increasing severity. The penalty over epochs for validator with effective balance is .2 This quadratic penalty growth is a key feature of the inactivity leak.
To derive a conservative upper bound for this penalty's contribution to , we make the following worst-case assumptions:
- All attesting validators in our set () are considered inactive from the beginning of the period.
- The inactivity leak starts at the first epoch, i.e. we are not considering
MIN_EPOCHS_TO_INACTIVITY_PENALTY
. - The total balance of these attesting validators is bounded by the total active balance of the entire network, .
Slashing
The slashing penalty has two parts: an initial penalty and a larger correlation penalty.
- Initial Penalty: This penalty is immediately applied but does not change the total active balance (it's redistributed). Its primary effect is that the slashed validator's weight is removed from the attesting set (even though they may still attest), which is already captured by the term in our formula.
- Correlation Penalty: This is applied much later, after the validator is already withdrawable and thus no longer part of the active set. It can be ignored for this analysis.
Hysteresis
The protocol updates a validator’s effective_balance
only when
the actual balance
crosses a hysteresis band.3 This creates two distinct sources of drift we must account for: a baseline drift from ordinary rewards and a large, event-driven jump from EIP-7251.
- Baseline Hysteresis Drift: For any validator, ordinary rewards and penalties can cause their
balance
to cross a threshold, changing theireffective_balance
by at most 1 ETH. This creates a baseline drift potential for every validator in the set. - EIP-7251 Compounding Switch: With EIP-7251, a validator can submit a
ConsolidationRequest
to switch to compounding credentials, raising their maximum effective balance fromMIN_ACTIVATION_BALANCE
(32 ETH) toMAX_EFFECTIVE_BALANCE_ELECTRA
(2048 ETH). This can trigger a one-time jump of up to 2016 ETH. However, the number of these "switch" events is strictly limited by the protocol. TheBeaconBlockBody
can contain at mostMAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD
(2) per block. With 32 slots per epoch, a maximum of 64 switches can be processed per epoch.
To construct our final bound, we combine these two effects. We assume the worst case where all 64n
possible switches occur and all benefit non-attesting validators. Each switch contributes an additional 2015 ETH of drift on top of the 1 ETH baseline drift already accounted for.
- (The decrease remains bounded by the 1 ETH baseline drift)
From Formal Model to Implemented Parameter
While this document derives a dynamic safety margin, , the implementation employs a simplified, fixed supermajority threshold. For instance, the default configuration requires a justification of 85% (justification_threshold_factor: 85
, justification_threshold_quotient: 100
).
This fixed threshold is not an alternative to the analysis; it is a practical parameter chosen based on it. The formal derivation of allows us to calculate the worst-case balance drift for the configured epoch_lookahead_limit
. The implemented 85% threshold is a conservative value chosen to exceed for all permissible lookahead scenarios, thereby guaranteeing safety without requiring the zkVM guest to perform the complex calculation at runtime. The formal analysis thus serves as the fundamental justification for the safety of the implemented fixed threshold.
Bounding the Total Safety Margin
By combining the individual components for the maximum possible increase in non-attesting weight () and the maximum decrease in attesting weight (), we get the following bounds:
Substituting these into the safety margin formula, , yields the final comprehensive bound:
To make this formula computable, we replace the unknown values at epoch with conservative upper bounds derived from the trusted state at . While the balance from validators activating during the lookahead period can be calculated precisely, it is simpler for the purpose of this meta-analysis to use a conservative upper bound. The upper bound for the total active balance is thus composed of the initial balance, a bound on balance from new activations (MAX_PER_EPOCH_ACTIVATION_EXIT_CHURN_LIMIT
), the maximum rewards, and the maximum hysteresis drift:
Similarly, the upper bound for the number of validators is:
The resulting safety margin can be calculated programmatically as shown in the Python implementation below.
def calculate_delta(B_0: int, V_0: int, S: int, n: int) -> int:
"""
Calculates a conservative safety margin delta for TSEth.
Args:
B_0: Total active effective balance at the trusted epoch (in ETH).
V_0: Number of active validators at the trusted epoch.
S: Total slashed balance since the trusted epoch (in ETH).
n: Number of epochs to look ahead.
"""
# An upper bound for the total active balance at the target epoch
# +V_0 (≤1 ETH hysteresis jump per validator)
B_n = B_0 + (256 * n) + (48 * n) + V_0 + 128960 * n
# An upper bound for the active validators at the target epoch
V_n = V_0 + (8 * n)
churn_term = n * 2 * max(128, B_0 / 65536)
reward_term = 48 * n
inactivity_term = (B_n * n * (n + 1)) / 100663296
hysteresis_term = 2 * (V_n + 128960 * n) / 3
delta = reward_term + churn_term + inactivity_term + hysteresis_term + S
# Return the final margin, rounded up for a conservative estimate.
return math.ceil(delta)
Conclusion
This analysis provides a self-contained, conservative bound for the safety margin , depending only on the initial state at , the slashed balance , and the lookahead period . The model's robustness is best illustrated by examining its sensitivity to these parameters.
With the current TSEth default configuration requiring ≥85% voting participation and a finalization lookahead of at most 10 epochs, the system maintains strong security guarantees. For instance, using Ethereum mainnet data from July 2025 (35,475,927 ETH staked by 1,087,747 active validators), TSEth can safely finalize checkpoints even if validators with a combined effective balance of over 4.9 million ETH were slashed.
The safety margin is most sensitive to the lookahead period, . While a short lookahead results in a modest , the margin grows quadratically as increases due to the inactivity leak term, demonstrating the importance of the configured epoch_lookahead_limit
. Similarly, the model correctly scales with the total slashed balance, , ensuring that large-scale slashing events are safely accounted for. This framework provides a transparent and verifiable method for ensuring the safety of a ZKVM-based FFG implementation.