One-epoch inactivation and Rifle attacks

Three kinds of one-epoch inactivation attack

One-epoch inactivation attack is a method that can harm Ethereum liveness even under synchronous assumptions: it can render one epoch inactive by preventing the checkpoint justification update during the attacked epoch. We propose three variants of one-epoch inactivation attacks, each augmented with specific sly strategies. These extend and refine existing attacks (the ex-ante attack, the sandwich attack, and the 1/3-slot-withhold attack) so that—while preserving the original reorg or withholding effects—they achieve additionally liveness degradation or less Byzantine loss.

1. Sly-ex-ante attack

The sly-ex-ante attack occurs when slot t is the first slot of an epoch and the proposer at slot t is honest, while the proposers at slots t-2 and t-1 are Byzantine. The modified ex-ante reorg attack in [1] demonstrates how to bypass proposer boosting; our sly-ex-ante attack further optimizes the attacker’s strategy on that basis.

The attack proceeds as follows (notation: blocks proposed in slot t-2, t-1, and t are denoted b_i, b_{i2}, and b_t, respectively):

  1. Delayed release within slot t. The Byzantine proposers in slots t-2 and t-1 propose blocks b_i and b_{i2} but delay releasing these blocks and their corresponding attestations until slot t. Specifically, the Byzantine blocks or their votes in slots t-2, t-1, and t are released during the interval 8–12s into slot t (instead of the earlier 0–4s window). As a result, validators at the start of slot t+1 will observe the two attacker blocks and their attestations.

  2. Byzantine voting target choice. Byzantine attestors present at slot t vote for b_{i2} (i.e., their target is b_{i2}) and delay broadcasting those votes so that they remain valid during the attack. Honest attestors at slot t still vote for b_t (i.e., their target is b_t).

  3. HLMD GHOST weight calculus and canonical change. Under the HLMD GHOST rule, the attacker’s branch accumulates weight roughly equal to (1/32) \cdot (1/3) \cdot 3 \approx 1/32 (slightly less than that), which exceeds the honest branch weight near (2/3)\cdot(1/32) (slightly greater than that). Thus the canonical chain selection favors the attacker branch, causing subsequent proposers (including the proposer at slot t+1) to build on b_{i2}.

  4. Epoch inactivity. In epoch e, all Byzantine attestors except those in slot t withhold their votes. Although the attacker injects approximately 1/32 \cdot 1/3 Byzantine votes targeting b_{i2} in epoch e, the total votes targeting b_{i2} still amount to roughly 31/32 \cdot 2/3 + 1/32 \cdot 1/3 < 2/3. Consequently, the checkpoint of epoch e cannot be justified; therefore, the attack both reverts the honest block b_t and renders epoch e inactive (no newly justified checkpoint).

  5. Take use of a Deneb patch. This attack exploits the fact that—even if the attacker branch cannot justify cp_{e-1} at slot t, HLMD GHOST can still consider the attacker branch a candidate for the canonical chain. The attacker therefore gains a path for reorg despite the Deneb patch for [2] intended to mitigate related attacks.

2. Sly-sandwich attack

The sly-sandwich attack occurs when slot t is the first slot of an epoch, the proposer at slot t is honest, and proposers at slots t-1 and t+1 are Byzantine. Our sly-sandwich attack extends the sandwich reorg attack in [1] by adding sly timing and vote-routing strategies.


Key elements of the sly-sandwich attack:

  1. Delayed proposer block from slot t-1. The block b_i proposed at slot t-1 is withheld and released at slot t. Byzantine attestations for b_i may also be withheld and released after b_i is released, ensuring these attestations are counted as valid attack votes.

  2. Canonical change with proposer boosting. After b_{i2} (the attacker-controlled block in the sandwich sequence) is released, the branch led by b_{i2} becomes the canonical chain (assisted by proposer boosting), and honest attestors in slots [t+1, t+31] will vote with b_i as target, while honest attestations from slot t are targeted at b_t.

  3. Epoch inactivity. In epoch e, all Byzantine attestors except those in slot t withhold their votes. Although the attacker injects approximately 1/32 \cdot 1/3 Byzantine votes targeting b_{i} in epoch e, the total votes targeting b_{i} still amount to roughly 31/32 \cdot 2/3 + 1/32 \cdot 1/3 < 2/3. Consequently, the checkpoint of epoch e cannot be justified; therefore, the attack both reverts the honest block b_t and renders epoch e inactive.

  4. Rifle-attack linkage (vote routing). We propose a linked sly strategy with the Rifle attack family: not all Byzantine votes for b_i in slots t-1 or t are broadcast to the whole network immediately. Instead, some votes are selectively delivered only to Byzantine proposers appearing later. This effectively concentrates weight on the attacker branch (slot t-1 or t Byzantine weight, approximate (1/32)\cdot(1/3), plus proposer boosting weight in slot t+1 of roughly 0.4\cdot(1/32)), which still exceeds the honest branch weight near (1/32)\cdot(2/3), enabling the attack to succeed.

  5. Exploiting a Deneb patch. Similar to sly-ex-ante, sly-sandwich leverages the Deneb patch relaxation that may avoid pruning the attacker branch even when it cannot justify cp_{e-1} at slot t, leaving a vector for the attacker to become canonical.

3. Sly-1/3-slot-withhold attack

The sly-1/3-slot-withhold attack extends the warm-up attack described in [2]. This attack can cause one epoch to be inactive, but it cannot roll back honest blocks; therefore its immediate threat is less severe than the previous two variants. A single Byzantine proposer—if selected as the proposer of the first slot t in epoch e can execute this attack independently.

Attack description:

  • A Byzantine proposer v_i proposes a block at slot t but withholds its broadcast for 4 seconds, releasing it later within the same slot. Consequently, approximately 1/32 of honest validators cast their votes targeting fb_{e-1} (the finalized-block target from the prior epoch), while other honest attestations target b_i. This split prevents epoch e from being justified.

We add the following sly refinements to the warm-up attack from [2]:

  1. Partial vote broadcasting. During slot t Byzantine voters broadcast only about 20% of the slot’s Byzantine votes, which reduces the chance that b_i will be rolled back by honest reorg behavior.

  2. Rifle-style vote routing. The remaining (non-broadcast) Byzantine votes are selectively delivered only to Byzantine proposers that appear later in epoch e, thereby increasing the attacker branch’s weight while minimizing the attackers’ exposure to slashing/punishment.


Rifle attack

Rifle attack amplifies the impact of the three kinds of one-epoch inactivation attacks by composing them in a coordinated, multi-stage manner. By combining two-stage one-epoch inactivation attacks with Byzantine collusion primitives — specifically one-way transfer (unidirectional forwarding of attestations) and delayed release of attacker blocks — the attacker can roll back multiple honest blocks and repeatedly prevent checkpoint justification across several epochs.

Overview

Rifle attack uses two core techniques:

  • One-way transfer (unidirectional attestations): Byzantine attestors in earlier slots forward their attestations only to a designated later Byzantine proposer (rather than broadcasting them to the network). This concentrates weight on the attacker chain while keeping most honest validators unaware.
  • Delayed release: The designated Byzantine proposer delays releasing their attack block until a carefully chosen slot t_{rel} in a later epoch, so that when it is finally released it has just enough weight (including forwarded Byzantine attestations) to justify a previous checkpoint on the attacker branch.

By selecting which slots/validators participate (e.g., the last Byzantine proposer in an epoch, or the penultimate Byzantine proposer), and by combining different one-epoch inactivation primitives (sly-ex-ante, sly-sandwich, sly-1/3-slot-withhold) in phase 1 and phase 2, the attacker derives a family of Rifle attack strategies that differ in which Byzantine votes and blocks are forwarded/delayed.

Notation and timing constraint

  • Let t denote the first slot of epoch e.
  • Let t_j denote the slot of a selected (e.g., penultimate or last) Byzantine proposer in epoch e who will propose attack block b_j.
  • Let t_k denote the slot in the later epoch (such as epoch e+2) of the Byzantine proposer v_k who will ultimately release a delayed block (or be the focal point of the next loop).
  • Let t_{rel} denote the release slot (modulo 32 within the epoch) when the delayed attack block is broadcast.

The concrete 6 strategies of Rifle attack

Strategy 1

Byzantine validators at slots t-2, t-1, and t collude to launch a sly-ex-ante attack, causing the honest block b_t to be rolled back and resulting in an honest-vote loss at slot t (approximately 1/32 \times 2/3 of the total stake).
In addition, let t_j denote the slot of the penultimate Byzantine proposer in epoch e, who proposes block b_j. All Byzantine attestors in slots [t+1, t_j) of epoch e unidirectionally transfer their attestations to the penultimate Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
Furthermore, Byzantine proposers at slots t+31 \sim t+33 collude to launch a sly-sandwich attack using a sly strategy—only broadcasting the Byzantine votes at slot t+32—thereby causing an honest-vote loss at slot t+32 (approximately 1/32 \times 2/3 of the total stake).
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1 except slot t+32, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k, using a sly strategy that sets the source as b_{i2} and the target as b_j.
As a result, honest validators fail to justify any checkpoint in epochs e and e+1, while b_j can justify b_{i2} after t_{rel}. Therefore, the honest branch after t_j is pruned (indicated by red crosses in the figure). Attestations included in the honest branch are discarded.

Strategy 2

Byzantine validators at slots t-2, t-1, and t collude to launch a sly-ex-ante attack, causing the honest block b_t to be rolled back and resulting in an honest-vote loss at slot t (approximately 1/32 \times 2/3 of the total stake).
All Byzantine attestors in slots [t+1, t_j) of epoch e unidirectionally transfer their attestations to the last Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
In epoch e+1, the Byzantine proposer at slot t+32 launches a sly-1/3-slot-withhold attack.
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k, using a sly strategy that sets the source as b_{i2} and the target as b_j.
As a result, honest validators fail to justify any checkpoint in epochs e and e+1, while b_j can justify b_{i2} after t_{rel}. Therefore, the honest branch after t_j is pruned (indicated by red crosses in the figure). Attestations included in the honest branch are discarded.

Strategy 3

Byzantine validators at slots t-1, t, and t+1 collude to launch a sly-sandwich attack, adopting a sly strategy — only broadcasting the Byzantine votes at slot t-1. This causes the honest block b_t to be rolled back and results in an honest-vote loss at slot t.
All Byzantine attestors in slots [t, t_j) of epoch e unidirectionally transfer their attestations to the penultimate Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
Furthermore, Byzantine proposers at slots t+31 \sim t+33 collude to launch another sly-sandwich attack, using a sly strategy — only broadcasting the Byzantine votes at slot t+32 — thereby causing an honest-vote loss at slot t+32.
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1 except slot t+32, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k.
As a result, b_j can justify b_{l} after t_{rel}, and the honest branch following t_j is pruned, with all attestations included in it being discarded.

Strategy 4

Byzantine validators at slots t-1, t, and t+1 collude to launch a sly-sandwich attack, adopting a sly strategy — only broadcasting the Byzantine votes at slot t-1. This causes the honest block b_t to be rolled back and results in an honest-vote loss at slot t.
All Byzantine attestors in slots [t, t_j) of epoch e unidirectionally transfer their attestations to the penultimate Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
In epoch e+1, the Byzantine proposer at slot t+32 launches a sly-1/3-slot-withhold attack, causing an honest-vote loss at that slot.
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k.
Therefore, b_j can justify b_{i} after t_{rel}, and the honest branch following t_j is pruned, with all attestations included in it being discarded.

Strategy 5

Byzantine validators at slot t launch a sly-1/3-slot-withhold attack, causing an honest-vote loss at slot t.
All Byzantine attestors in slots [t, t_j) of epoch e unidirectionally transfer their attestations to the penultimate Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
Furthermore, Byzantine proposers at slots t+31 \sim t+33 collude to launch a sly-sandwich attack, adopting a sly strategy — only broadcasting the Byzantine votes at slot t+32.
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1 except slot t+32, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k.
Therefore, b_j can justify b_{i} after t_{rel}, and the honest branch following t_j is pruned, with all attestations included in it being discarded.

Strategy 6

Byzantine validators at slot t launch a sly-1/3-slot-withhold attack, causing an honest-vote loss at slot t.
All Byzantine attestors in slots [t, t_j) of epoch e unidirectionally transfer their attestations to the penultimate Byzantine proposer v_j in the same epoch. After proposing the attack block b_j, v_j delays its release until t_{rel}.
In epoch e+1, the Byzantine proposer at slot t+32 launches another sly-1/3-slot-withhold attack, causing an additional honest-vote loss at that slot.
All Byzantine votes from epoch e slots [t_j, t+31], from all slots in epoch e+1, and from epoch e+2 slots [t+64, t_k) are unidirectionally transferred to v_k.
The result of this attack is similar to the previous strategies — b_j can justify b_{i} after t_{rel}, and the honest branch following t_j is pruned, with all attestations included on it being discarded.

Rifle attack-II

Rifle attack leverages a two-stage composition of the three one-epoch inactivation attacks, combined with collusion-based unidirectional transfer of attestations and delayed-release strategies among Byzantine validators, to realize block reorgs. From this construction we can readily conceive another class of attacks, which we call Rifle attack-II. The distinguishing feature of Rifle attack-II is that the delayed release of the attack block is deferred until after the one-epoch inactivation attack in the second phase; in other words, the collusion-driven delayed-release primitive is postponed by one inactivation-attack stage. This postponement likewise enables reorg attacks against the honest branch.
The six Rifle attack-II strategies are listed as follows:

Strategy 7

By the same reasoning, and differing from Strategy 1 of the original Rifle attack, in this variant the Byzantine attestators in slots [t+1,\,t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. Validator v_j then proposes the attack block b_j and delays its release until slot t_{rel} of epoch e+2. All Byzantine votes in slots [t_j,\,t_k) are unidirectionally passed to v_k. Consequently, after t_{rel}, b_j can justify b_{l2}, causing the honest branch to be pruned.

Strategy 8

Different from Strategy 2 of the Rifle attack, the Byzantine attestors in slots [t+1, t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. After proposing the attack block b_j, v_j delays its release until slot t_{rel} in epoch e+2.
All Byzantine votes from slots [t_j, t_k) are unidirectionally transferred to v_k. Therefore, after t_{rel}, b_j can justify b_l, resulting in the honest branch being pruned.

Strategy 9

Different from Strategy 3 of the Rifle attack, the Byzantine attestors in slots [t, t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. After proposing the attack block b_j, v_j delays its release until slot t_{rel} in epoch e+2.
All Byzantine votes from slots [t_j, t_k) are unidirectionally transferred to v_k. Therefore, after t_{rel}, b_j can justify b_l, resulting in the honest branch being pruned.

Strategy 10

Different from Strategy 4 of the Rifle attack, the Byzantine attestors in slots [t, t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. After proposing the attack block b_j, v_j delays its release until slot t_{rel} in epoch e+2.
All Byzantine votes from slots [t_j, t_k) are unidirectionally transferred to v_k. Therefore, after t_{rel}, b_j can justify b_l, resulting in the honest branch being pruned.

Strategy 11

Different from Strategy 5 of the Rifle attack, the Byzantine attestors in slots [t, t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. After proposing the attack block b_j, v_j delays its release until slot t_{rel} in epoch e+2.
All Byzantine votes from slots [t_j, t_k) are unidirectionally transferred to v_k. Therefore, after t_{rel}, b_j can justify b_{l2}, resulting in the honest branch being pruned.

Strategy 12

Different from Strategy 6 of the Rifle attack, the Byzantine attestors in slots [t, t_j) unidirectionally transfer their attestations to the last Byzantine proposer v_j in epoch e+1. After proposing the attack block b_j, v_j delays its release until slot t_{rel} in epoch e+2.
All Byzantine votes from slots [t_j, t_k) are unidirectionally transferred to v_k. Therefore, after t_{rel}, b_j can justify b_l, resulting in the honest branch being pruned.


Discussion on the Delayed Release Time of the Attacker’s Block

For the 12 attack strategies of the two types of Rifle attacks mentioned above, the attacker can choose between two different attack modes, “single-shot Rifle” and “looping Rifle,” based on their attack objectives. The former seeks to cause the maximum honest incentive loss in a single attack; however, if multiple attacks are desired, a two-stage one-epoch inactivation attack must be repeated at the start of each attack. On the other hand, the latter dynamically adjusts the attack strategy to ensure that the attack cycle occurs while maximizing the attack’s intensity in each cycle. This approach aims to reduce the difficulty of the attack by leveraging accumulated advantages across multiple cycles.

“Single-shot Rifle”

If executed only once, it is sufficient to release block b_j at the final slot of the last attack epoch to achieve maximal influence — just like epoch e+2 in the previous figures. At this point, strategy 6 of our Rifle attack is similar to Staircase Attack-II[3], and strategy 6 of our Rifle attack-II is similar to the modified staircase attack in [1]. Therefore, our “single-shot Rifle” can be viewed as an extension of the staircase attack: under the non-attack condition that the first slot t is held by an honest proposer, we add checks on the identities of the block proposers at slots t-2, t-1, and t+1 to produce 10 additional attack strategies, thereby increasing the probability that the attack occurs on time.

“Looping Rifle”

If we want the Rifle attack and Rifle attack-II to repeat and maximize their impact, we must release b_j as late as possible, under the constraint:

1 \le t_{rel} \le \min \left( t_k,\; \frac{3t_k - 64}{2} \right)

Specifically, each epoch that updates the checkpoint’s justified state (releases the attack block) needs to satisfy the following conditions:
First, we need to confirm the selection of v_k in the epoch:
For Rifle attack:

  • If the epoch is e+2, e+5, e+8, e+11, …, then the attack can be initiated without requiring the next epoch to suffer 1/32 honest vote loss. Therefore, v_k should be the last Byzantine proposer in the epoch.
  • If the epoch is e+3, e+6, e+9, e+12, …, then it is necessary to ensure that the next epoch incurs 1/32 honest vote loss. Therefore, v_k should be selected as the 3rd last, 2nd last, or last Byzantine proposer in the epoch, depending on the occurrence conditions of the 3 different one-epoch inactivation attack strategies.

For Rifle attack-II:

  • If the epoch is e+2, e+5, e+8, e+11, …, it is necessary to ensure that the next epoch incurs 1/32 honest vote loss. Therefore, v_k should be selected as the 3rd last, 2nd last, or last Byzantine proposer in the epoch, based on the occurrence conditions of the 3 different one-epoch inactivation attack strategies.
  • If the epoch is e+4, e+7, e+10, e+13, …, then the attack can be initiated without requiring the next epoch to suffer 1/32 honest vote loss. Therefore, v_k should be selected as the last Byzantine proposer in that epoch.

Additionally, it is necessary to ensure that b_k can justify the epoch it was proposed in, and that it cannot be justified by honest votes alone. The following three conditions must be met (all time values are taken modulo 32):

  1. The proportion of Byzantine votes in [0, t_k) plus the proportion of honest votes in [t_{rel}, t_k) must be \geq 2/3.
  2. The proportion of honest votes in [t_{rel}, 31] must be < 2/3.
  3. t_{rel} \leq t_k.

By satisfying these conditions, we obtain an approximate constraint for t_{rel}. Using this constraint for the delayed release of b_k, we can ensure that the attack cycle occurs without needing to repeat the two-stage one-epoch inactivation attack.

For example, for Rifle attack:

  • If t_k in epoch e+2 = 31, then t_{rel} in epoch e+2 can be 14, meaning that b_j proposed in epoch e is released at slot 14 in epoch e+2, and the justified checkpoint is updated to cp_e.
  • If t_k in epoch e+3 = 30, then t_{rel} in epoch e+3 can be 13, meaning that b_k proposed in epoch e+2 is released at slot 13 in epoch e+3, and the justified checkpoint is updated to cp_{e+2}.
  • Based on the actual situation, perform a one-epoch inactivation attack to epoch e+4.
  • If t_k in epoch e+5 = 29, then t_{rel} in epoch e+5 can be 11, meaning that b_k proposed in epoch e+3 is released at slot 11 in epoch e+5, and the justified checkpoint is updated to cp_{e+3}.
  • If t_k in epoch e+6 = 30, then t_{rel} in epoch e+5 can be 13, meaning that b_k proposed in epoch e+5 is released at slot 13 in epoch e+6, and the justified checkpoint is updated to cp_{e+5}.
  • Continue executing the looping Rifle attack according to this pattern…

For Rifle attack-II:

  • If t_k in epoch e+2 = 31, then t_{rel} in epoch e+2 can be 14, meaning that b_j proposed in epoch e+1 is released at slot 14 in epoch e+2, and the justified checkpoint is updated to cp_{e+1}.
  • Based on the actual situation, perform a one-epoch inactivation attack in epoch e+3.
  • If t_k in epoch e+4 = 30, then t_{rel} in epoch e+4 can be 13, meaning that b_k proposed in epoch e+2 is released at slot 13 in epoch e+4, and the justified checkpoint is updated to cp_{e+2}.
  • If t_k in epoch e+5 = 29, then t_{rel} in epoch e+5 can be 11, meaning that b_k proposed in epoch e+4 is released at slot 11 in epoch e+5, and the justified checkpoint is updated to cp_{e+4}.
  • Based on the actual situation, perform a one-epoch inactivation attack in epoch e+6.
  • If t_k in epoch e+7 = 30, then t_{rel} in epoch e+7 can be 13, meaning that b_k proposed in epoch e+5 is released at slot 13 in epoch e+7, and the justified checkpoint is updated to cp_{e+5}.
  • Continue executing the looping Rifle attack-II according to this pattern…

Scalable Delay Strategy

In fact, the 12 Rifle attack strategies we introduced above are merely the basic “take advantage of the situation” Rifle attacks. In real attack scenarios, whether in the “single-shot Rifle” or “looping Rifle,” within each layer of the loop, we can further leverage the three kinds of one-epoch inactivation attacks described above to create more epochs of inactivity, thus increasing the attack intensity. For example, for the 12 Rifle attack strategies mentioned above, if slot t+64 is a Byzantine proposer, or if slot t+64 is an honest proposer and both slots t+63 and t+62 are Byzantine proposers, or if slot t+64 is an honest proposer and both slots t+63 and t+65 are Byzantine proposers, a third-phase one-epoch inactivation attack can be triggered, resulting in inactivity in epoch e+2. This would allow the attack block b_j to be released at t_{rel} in epoch e+3, thereby causing an additional rollback of 1 epoch’s honest blocks and attestations.
Similarly, for the “looping Rifle” mode of the Rifle attack, if epoch e+6 meets the conditions for a one-epoch inactivation attack, the block b_k proposed by epoch e+5 can be delayed and released in epoch e+7 rather than epoch e+6, justifying cp_{e+5}. Similarly, for the “looping Rifle” mode of Rifle attack-II, if epoch e+8 satisfies the conditions for a one-epoch inactivation attack, the block b_k proposed by epoch e+7 can be delayed and released in epoch e+9 rather than epoch e+8, justifying cp_{e+7}.

Furthermore, we can extend the range of epochs covered by a single delay: if slot t+96 is a Byzantine proposer, or if slot t+96 is an honest proposer and both slots t+95 and t+94 are Byzantine proposers, or if slot t+96 is an honest proposer and both slots t+95 and t+97 are Byzantine proposers, block b_j can be delayed and released at t_{rel} in epoch e+4… Readers can extend this approach to generate infinite variations of more powerful Pistol attack strategies.

References

We would like to especially thank all the authors for their efforts and contributions :
[1] Zhang, Mingfei, et al. “Available Attestation: Towards a Reorg-Resilient Solution for Ethereum Proof-of-Stake.” Cryptology ePrint Archive (2025).
[2] Zhang, Mingfei, Rujia Li, and Sisi Duan. “Max attestation matters: Making honest parties lose their incentives in ethereum {PoS}.” 33rd USENIX Security Symposium (USENIX Security 24). 2024.
[3] Zhang, M. (2025, April 7). Staircase Attack-II in Ethereum PoS . Ethereum Research. https://ethresear.ch/t/staircase-attack-ii-in-ethereum-pos/22099

Figure 2 of [2] provides a formalized description of the Ethereum PoS protocol from the perspective of a validator, while Figure 3 of [2] explains the meanings of the legends used throughout that paper’s figures. For clarity of exposition, we adopt the formal description style of Figure 2 in [2] to present the Rifle attack, and we use the legend and visualization conventions of Figure 3 in [2] for our diagrams. Readers are encouraged to consult [1~3] directly for further details. Thanks again.

2 Likes

Thanks for writing this up — the “sly” timing refinements (delayed release + selective vote routing) make it much easier to see how an attacker can get both a fork-choice swing and a justification failure inside the same epoch boundary.

A couple clarifying questions / reactions (to make sure I’m reading the model correctly):

  1. Network model / propagation assumptions.
    A lot of the success seems to hinge on the attacker being able to (a) delay-release blocks into the 8–12s window and (b) “one-way transfer” attestations so that some weight is visible to chosen Byzantine proposers but not broadly gossiped. Are you assuming a fully synchronous network for honest-to-honest propagation, with the attacker exercising selective disclosure only among Byzantine participants? Or is the model closer to “honest propagation is good, but the attacker can strategically withhold their own messages” (i.e., no network partitions required)?

  2. Where exactly the Deneb patch relaxation is being exploited.
    In the sly-ex-ante and sly-sandwich cases you note that—even if the attacker branch cannot justify cpe−1cp_{e-1}cpe−1​ at slot ttt—HLMD-GHOST may still keep the attacker branch as a viable candidate, enabling the canonical flip. Is the key point that the pruning condition is now weaker, so a branch can remain fork-choice-competitive despite lacking the expected justified link at the epoch boundary? If there’s a crisp condition you have in mind (“branch remains eligible if …”), it would help readers map this to the fork-choice spec.

  3. A “threshold” way to summarize the attack.
    It might be helpful to restate the core of each variant as a simple inequality: attacker engineers a temporary fork-choice advantage in the first few slots of an epoch while simultaneously ensuring the epoch’s voting mass splits so that no target reaches 2/32/32/3 for justification. That mental model makes the liveness degradation feel less like an artifact of the specific strategies and more like a general template (“fork-choice tilt + justification starvation”).

  4. Observer-facing implication.
    These attacks are framed as liveness failures under synchronous assumptions, but they also seem to create an interval where different nodes could have very different local views of “what the chain is” (because vote routing and delayed release control what information is globally visible). Do you think it’s accurate to say the attacker is not only degrading liveness, but also degrading verifiability for late or partially-synced observers during the attacked epochs?

If you have a preferred way to describe the security model (what the attacker can and cannot do with message dissemination, especially for the “one-way transfer” primitive), I think tightening that upfront would make the whole Rifle family much easier to reason about and compare to prior reorg / withholding work.

Thank you for the thoughtful questions. I’ll address them in order and try to keep the security model and the role of each “sly-*” variant as explicit as possible.


(1) Network model / propagation assumptions

Your reading is essentially right: the model assumes honest-to-honest propagation is “good” (synchronous / bounded delay), while the attacker’s advantage comes from strategically controlling the dissemination timing of their own blocks and votes, rather than from partitioning or delaying honest messages.

  • No partition / no selective delay of honest gossip is required. The threat model allows the attacks even under a synchronous network with bounded message delays.
  • The key lever is attacker-controlled timing within slot sub-windows. In particular, the attacker can withhold an attacker-proposed block until the last ~4 seconds of a 12-second slot, while honest validators follow the protocol’s fixed proposer/voter windows.
  • “One-way transfer” is modeled as private, selective delivery of attacker votes. Attacker votes from earlier slots can be sent only to a chosen later attacker proposer (instead of being broadcast to the whole network), and then released publicly only at a later time chosen by the attacker.

(2) Where the “Deneb patch relaxation” is being exploited (and how)

In the fork-choice model, the key mechanics are exactly these two pieces:

  1. Lagging-branch filtering + pruning-protection (the “relaxation”).
    Fork choice labels a branch as lagging when the epoch of its most recent justified checkpoint, U(br).e, is behind the global justified checkpoint, GJC.e.
    However, a lagging branch is still kept as a canonical candidate as long as U(br).e is within 2 epochs of the current epoch (the pruning-protection condition).
    This is the rule referred to in the post as the “Deneb patch relaxation.”

  2. Head selection remains weight-driven among eligible candidates.
    After the lagging-branch filter (including pruning-protection), fork choice selects the canonical branch as the candidate with the largest weight induced by the valid votes.

How the two “sly-*” boundary attacks use this

The sly-ex-ante / sly-sandwich attacks shown in the post use the mild sly strategy primarily to ensure that the slot-t honest voters suffer a vote loss (their vote does not land on the eventual canonical head). This can make epoch e fail to justify on time, and thereby serves as a trigger condition for the Rifle family that amplifies honest vote loss and incentive penalties. This amplification is centered on the epoch boundary where head selection is still weight-driven among eligible candidate branches.

How the pruning-protection “relaxation” can be additionally exploited

The proposed extension—delaying the release of attacker (Byzantine) votes from slots [t-32,,t-3] until after slot t, while keeping the rest of the sly strategy unchanged—creates an additional lever:

  • Why epoch e-1 can be pushed toward “inactivation.”
    Justification requires observing more than 2/3 of validators voting with the same source–target pair. With 32 slots per epoch, if (i) one slot’s honest votes are effectively not contributing to the would-be canonical branch (as in the slot-t vote-loss setup), and (ii) attacker votes from most of epoch e-1 are withheld until after slot t, then during epoch e-1 the branch can “see” at most roughly the honest share across only 31/32 of the epoch’s slots:

    \frac{31}{32}\cdot\frac{2}{3}<\frac{2}{3}.

    This makes it plausible that the epoch-(e-1) checkpoint is not justified on time under that public view (i.e., an “extra inactivation” effect).

  • Why the branch remains eligible anyway (this is the exploitation of the patch).
    Even if that branch becomes lagging in the formal sense U(br).e < GJC.e, fork choice does not immediately discard it: it remains a canonical candidate under pruning-protection so long as U(br).e is within 2 epochs of the current epoch.

  • How it can still win at the epoch boundary.
    Once that lagging-but-protected branch is still in the candidate set, fork choice compares candidates by valid-vote-induced weight, and the attacker can choose a release schedule so that the protected lagging branch becomes heavier at the boundary and is selected as canonical.

  • Why releasing after slot t is technically meaningful.
    The validator-centric workflow allows votes created in epoch e to be included as late as epoch e+1; equivalently, votes created in epoch e-1 can still be included in epoch e. So “delayed release until after slot t” can still affect what gets included/realized shortly after the boundary.


(3) A “threshold” way to summarize the attack

I agree that a compact “fork-choice tilt + justification starvation” mnemonic can help build intuition. But I would not treat it as the core of the construction, because it captures only part of the high-level symptoms and not the mechanism that makes those symptoms achievable under the protocol’s actual constraints.

  1. The core is the strategy that exploits concrete timing and scoring constraints, not the slogan.
    The decisive behaviors are tied to slot sub-windows—voters act in the 4–8s window while the proposer acts in the first 4s of the slot. The variants differ in how the attacker schedules block/vote release relative to these windows and how that interacts with head selection by “largest weight induced by the valid votes.” These details determine whether a boundary “tilt” can actually be realized.

  2. Split votes alone do not explain rollback / large honest vote loss.
    In the extended (Rifle-family) construction, the major effect is not merely that votes are split. The attacker later releases an “attack block” that justifies the relevant checkpoint, after which fork choice makes the attacker branch canonical and filters the honest branch; votes carried by the filtered honest branch are discarded, producing honest incentive losses. This is why I hesitate to reduce everything to “tilt + starvation”: the rollback (and associated vote invalidation) depends on attacker actions that steer fork choice into pruning/filtering the honest branch, not on vote-splitting by itself.

  3. Different variants have different tight constraints, so collapsing them can hide what actually matters.
    Fork choice includes both the “largest valid-vote weight” rule and the honest reorg rule requiring at least 20% voting power in the proposal slot for adoption. Some strategies are built around satisfying that adoption constraint while still setting up later filtering/rollback dynamics; that is not visible if everything is summarized as a single inequality.

I think your suggestion (adding a brief “template + inequality” summary up front) is a good idea and would make the post easier to skim. I would still keep the variant-specific step descriptions, because they make explicit which protocol rules are being exercised (timing windows, adoption threshold, candidate filtering, and the later filtering/discarding of the honest branch), which helps prevent the mechanism from being misread as a generic “any tilt + any split” phenomenon.


(4) Observer-facing implication (verifiability / local views)

Yes—if “verifiability” is understood as an observer’s ability (from locally visible data) to confidently determine which branch will remain canonical and which votes will ultimately count, not as the cryptographic verifiability of individual blocks/votes.

  • Under this model, honest-to-honest propagation can be synchronous/bounded-delay, but the attacker still creates an interval where publicly visible information is intentionally incomplete: (i) “one-way transfer” concentrates attacker votes to chosen proposers rather than broadly gossiping them, and (ii) delayed release withholds the attacker block until a later, strategically chosen slot.
  • During that interval, a late or partially-synced observer may see an “apparently canonical” honest head with apparently coherent voting, yet the attacker can later release withheld weight and an attack block that re-anchors fork choice and prunes/displaces the honest branch—changing what is counted on the canonical chain. This creates a real observer-facing loss of confidence about near-term chain history/settlement, even if the network is otherwise synchronous.

Crucially, this observer-facing effect is not just a side note: the attack target is incentives. Vote incentives dominate Ethereum’s reward/penalty weight (vote rewards 84.4% of reward weight; vote penalties 95.3% of penalty weight). The intended mechanism is that boundary weight comparisons make an attacker branch become canonical, and then honest votes are no longer counted, so honest validators lose vote incentives. The post also frames “single-shot Rifle” as maximizing honest incentive loss as an objective. In that sense: beyond degrading liveness, the attacks also degrade observer settlement confidence (especially for late/partially-synced observers) in a way that is aligned with the incentive-distortion goal, because the payoff comes from making honest votes end up “valid but uncounted” after the delayed-release/pruning sequence resolves.


Security model clarification (message dissemination + “one-way transfer”)

A tighter way to state the security model (especially the “one-way transfer” primitive) is to make dissemination assumptions explicit as a two-channel message model plus clear “cannot do” constraints:

Public channel (honest view)

  • The network is synchronous with a bounded delay: if a message is publicly broadcast, it is delivered to all honest nodes within some bound.
  • Honest validators follow the protocol’s timing: in each 12-second slot, the proposer acts in the first 4 seconds, and assigned voters cast at most one vote during the 4–8 second window.

Private channel (attacker internal coordination)

  • Colluding validators have an out-of-band/private coordination channel enabling them to send their own signed votes to selected colluding parties without broadcasting them to the public channel.
  • “One-way transfer” means colluding attacker votes are relayed privately to a designated attacker proposer (or a small subset of the coalition), rather than being gossiped to everyone; that proposer can later use them when releasing an attack block.

Attacker capabilities over their own messages

  • The attacker can choose when attacker-produced blocks are made public (e.g., withholding until the last ~4 seconds of a slot, then releasing).
  • The attacker can choose which attacker votes become public and when (e.g., revealing only a fraction initially to satisfy adoption constraints).

Attacker limitations (important for comparison to prior network-assisted work)

  • The model does not give the attacker power to steer honest blocks/votes into disjoint subnetworks or selectively delay honest messages.
  • Standard constraints still apply: the attacker controls <1/3 of validators/stake and cannot forge honest signatures. Role assignments are assumed known two epochs ahead, which the attacker can use to plan delayed release / one-way transfer.
  • Finally, the construction relies only on the PoS protocol’s specified timing windows (the fixed ~4-second proposer/voter sub-windows inside each slot) and does not depend on uncontrollable local scheduling quirks or transient task-execution behavior inside honest clients beyond what the protocol timing already specifies.

Thanks — this clarifies the model a lot. The distinction between the synchronous public channel and attacker-controlled timing of their own messages makes the construction much easier to reason about.

One quick clarification: in the extension where Byzantine votes from [t−32,t−3][t-32, t-3][t−32,t−3] are withheld and revealed after slot ttt, the intent is that those attestations remain slash-safe and protocol-valid when eventually revealed (i.e., no equivocation, only delayed publication), correct?

If so, that seems like the key lever enabling the attacker to reveal previously invisible weight and shift fork choice among still-eligible branches.

Thank you for the clarification.

In that extension, the withheld attestations are meant to remain slash-safe and protocol-valid when eventually revealed, i.e., no equivocation, only delayed publication. In other words, colluding validators still produce at most one attestation per assigned duty window, and “withholding” is purely a dissemination choice (private routing + later public release), not signing conflicting attestations.

That said, I would sharpen one point: in this particular extension, the withheld votes from ([t-32,t-3]) are pre-fork in the setup, so they do not materially shift the head among candidate branches by themselves — because they contribute essentially symmetrically to both branches (they sit on the shared prefix). Their primary role here is to strengthen the justification-delay / inactivation effect by keeping cp_{e-1} from becoming justifiable on time in the public view (thus widening the inactivation window), while the actual head shift is driven by the boundary-local asymmetry engineered around the fork window (e.g., the sly-* boundary region around slot (t) and the associated HLMD-GHOST weight comparison).

More generally, delayed publication does become a direct head-shifting lever when the attacker withholds votes whose valid vote points into different descendants on the competing branches (i.e., branch-differentiating weight). The ([t-32,t-3]) batch in this extension is mainly about delaying timely justification, not directly swinging head selection.

I find this area particularly interesting, especially the interaction between fork-choice weight, justification timing, and information visibility in PoS networks. Your clarification helped make that interaction much clearer.

So in this extension, the withheld attestations remain slash-safe and protocol-valid, with the only adversarial capability being control over dissemination timing rather than equivocation. In other words, colluding validators still sign at most one attestation per duty window, but selectively delay publication.

Your point about the [t−32,t−3][t-32, t-3][t−32,t−3] votes is also helpful. Since those votes sit on the shared prefix, they contribute essentially symmetrically to both candidate branches and therefore do not directly shift fork choice. Their primary effect is instead on the justification timeline: by delaying the public visibility of those attestations, the attacker can prevent cpe−1c_{pe-1}cpe−1​ from becoming justifiable on schedule, thereby widening the inactivation window.

So the actual fork-choice asymmetry in this setup seems to arise from the boundary-local behavior near the fork itself (e.g., the sly-* region around slot ttt), where the HLMD-GHOST weight comparison becomes branch-differentiating.

More generally, it seems useful to distinguish two roles delayed publication can play in PoS systems:

  1. Justification timing manipulation, where withheld votes primarily affect checkpoint justification and finality timing but do not directly alter fork-choice weights (as in the [t−32,t−3][t-32,t-3][t−32,t−3] batch here), and

  2. Fork-choice weight manipulation, where withheld votes point into different descendants across competing branches and therefore directly influence HLMD-GHOST head selection once revealed.

Framing the mechanism this way helped clarify the role the withheld attestations play in the extension. Thanks again for the detailed explanation.

Thank you — that’s a very helpful clarification. I agree with your framing for the sly- variants: in this extension, withholding ([t-32, t-3]) mainly affects justification timing / inactivation, while the boundary-local, branch-differentiating votes near slot (t) are what can drive a GHOST head shift via weight.

One additional nuance for the broader Rifle attack family: affecting the eventual fork-choice outcome is not only about weight manipulation. In Rifle executions, the attacker’s block b_j does not need to have higher GHOST weight; instead, the Byzantine strategy uses a delayed-release / justification sequence to make the honest branch fall outside the 2-epoch pruning-protection window (so it is no longer an eligible candidate). Once the honest branch is filtered out by the fork-choice eligibility rule, the attacker branch can become the new canonical branch even without winning a pure weight comparison.

Your point about the Rifle construction is important. If I understand correctly, the decisive step is not necessarily winning a direct GHOST weight comparison. Instead, the strategy manipulates the set of eligible fork-choice candidates. By delaying the release of the attacker’s block b_j and the associated votes until the right moment, the honest branch can drift beyond the two-epoch pruning-protection window. Once that branch is no longer considered an eligible candidate under the fork-choice rules, the attacker branch can become canonical even if it never strictly dominates in visible GHOST weight.

From an observer’s perspective, that dynamic is particularly interesting because it means the apparent fork-choice state can remain stable for some time while important information (votes or blocks) is still withheld. When that delayed information is eventually revealed, fork choice may resolve in a way that invalidates what previously appeared to be a well-supported branch.

I’m curious how people here think about this from a verification standpoint, especially for observers who are syncing or monitoring the chain. In particular, whether scenarios like this are primarily viewed as validator incentive attacks, or whether they also highlight limits on how confidently observers can interpret locally visible fork-choice state during those intervals.

Would be interested to hear how others working on fork choice and long-range verification think about that boundary.

1 Like

Thanks for the thoughtful question. We would primarily view this as an incentive attack, although it also highlights an important observability boundary for fork-choice monitoring.

First, in our analysis we assume that all honest validators continue to follow the protocol and the default client behavior throughout the attack. Even under that standard assumption, the attack is already sufficient to impose systematic incentive losses on honest validators. So the core issue exists at the incentive layer itself, without needing to assume that honest participants deviate, stop voting, or exit.

Second, from a verification or monitoring perspective, the attack also shows that locally visible fork-choice state before finalization should be interpreted with caution. During the withholding interval, observers may see a branch that appears stable, while still-valid but not-yet-revealed blocks or votes can later change which branch remains eligible or becomes canonical.

More broadly, if such deviations from expected protocol behavior were to persist, they could weaken validator confidence in the protocol’s normal operation and potentially worsen participation incentives, which would only make these incentive vulnerabilities more concerning.