Unrealized manipulating attack

Unrealized manipulation attack

Building on the 3 kinds of one-epoch inactivation attack in [1] and collusive Byzantine strategies, we propose six new Unrealized manipulation attack strategies. These attacks exploit collusion among adversaries to keep the honest chain inactive, and then use a single adversarial block with sufficient votes to connect to an unrealized block and reorganize the honest blocks on the chain, causing losses to honest validators. The specific strategy below illustrates the idea:

Strategy 1

  1. During epochs e and e\!+\!1, except for slot t and slot t\!+\!32, all Byzantine votes are collusively sent only to the final Byzantine proposer v_k in epoch e\!+\!1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t\!+\!18), and withholds releasing b_k.
  2. Launch a sly-ex-ante attack against the honest validators in epoch e, and perform a single sly-sandwich attack against the honest validators in epoch e\!+\!1.
  3. In epoch e\!+\!2, the Byzantine proposer at slot t\!+\!64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Strategy 2

  1. During epochs e and e+1, except for slot t, all Byzantine votes are collusively sent only to the final Byzantine proposer v_k in epoch e+1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t+18), and withholds releasing b_k.
  2. Launch a sly-ex-ante attack against the honest validators in epoch e, and perform one sly-1/3-slot-withhold attack against the honest validators in epoch e+1.
  3. In epoch e+2, the Byzantine proposer at slot t+64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Strategy 3

  1. During epochs e and e+1, except for slot t+32, all Byzantine votes are collusively sent only to the final Byzantine proposer v_k in epoch e+1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t+18), and withholds releasing b_k.
  2. Launch a sly-sandwich attack against the honest validators in epoch e, and also launch a sly-sandwich attack against the honest validators in epoch e+1.
  3. In epoch e+2, the Byzantine proposer at slot t+64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Strategy 4

  1. During epochs e and e+1, all Byzantine votes are collusively sent only to the final Byzantine proposer v_k in epoch e+1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t+18), and withholds releasing b_k.
  2. Launch a sly-sandwich attack against the honest validators in epoch e, and launch a sly-1/3-slot-withhold attack against the honest validators in epoch e+1.
  3. In epoch e+2, the Byzantine proposer at slot t+64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Strategy 5

  1. During epochs e and e+1, except for slot t+32, all Byzantine votes are collusively sent only to the Byzantine proposer v_k in the last slot of epoch e+1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t+18), and withholds releasing b_k.
  2. Launch a sly-1/3-slot-withhold attack against the honest validators in epoch e, and launch a sly-sandwich attack against the honest validators in epoch e+1.
  3. In epoch e+2, the Byzantine proposer at slot t+64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Strategy 6

  1. During epochs e and e+1, all Byzantine votes are collusively sent only to the Byzantine proposer v_k in the last slot of epoch e+1. This proposer does not continue to extend the current honest chain; instead, it sets the parent to be the first block in epoch e that contains 1/3 voting weight (the block proposed at slot t+18), and withholds releasing b_k.
  2. Launch a sly-1/3-slot-withhold attack against the honest validators in epoch e, and also launch a sly-1/3-slot-withhold attack against the honest validators in epoch e+1.
  3. In epoch e+2, the Byzantine proposer at slot t+64 proposes b_{k2} with parent b_k, and releases b_k and b_{k2} simultaneously within the first 4 seconds so as to justify cp_e and roll back the honest branch.

Attack Extension Strategies

In fact, the six attack strategies we described above are only the most basic “take-what-you-get” strategies. In real attack scenarios, we can further leverage the three kinds of one-epoch inactivation attack in [1] to keep additional epochs inactive, thereby amplifying the attack. For example, for the six strategies above, if the proposer at slot t+64 is Byzantine; or if the proposer at slot t+64 is honest while the proposers at slots t+63 and t+62 are both Byzantine; or if the proposer at slot t+64 is honest while the proposers at slots t+63 and t+65 are Byzantine, then the adversaries can proceed to launch a third-stage one-epoch inactivation attack that causes epoch e+2 to become inactive. Immediately afterwards, the Byzantine proposer in the last slot of epoch e+2 can set as parent the first block in epoch e that contains \frac{1}{3} of the voting weight, thereby rolling back an additional epoch of honest blocks and attestations…

By the way, for all the attack strategies above, if b_{k2} is the block of the first slot then it is unnecessary to launch a one-epoch inactivation attack against epoch e+1. If b_{k2} is a later block, then that one-epoch inactivation attack must be carried out.

References

[1]Fang, Y. (2025, October 27). One-Epoch Inactivation and Pistol Attacks. Ethresear.Ch. https://ethresear.ch/t/one-epoch-inactivation-and-pistol-attacks/23351

2 Likes

Hello, thank you for your efforts. I would like to ask the following questions:

  1. Why should the byzantine votes be sent to the last Byzantine proposer in epoch e+1?
  2. I think once b_k is released, it can already justify the checkpoint of epoch e. Why is b_{k2} still needed?

Thank you very much for your questions. First, b_k can be sent to any Byzantine proposer in epoch e+1 that is not involved in the one-epoch inactivation attack, and it can be released before the unrealized justified slot of the next epoch.
Second, if b_k is released with a delay, then b_{k2} is not necessary to justify cp_e. Thanks again.

Hello, thank you for the post and your work. Just to clarify, cp_e refers to bi2, right? If yes, it means that the 2 branches from slot t+18 share a justified checkpoint, and the LMD-Ghost would prefer the honest branch, right? How is the adversarial branch favored once bk2 is proposed? To my understanding the only difference between the adversarial and honest branch (starting from slot t+18) is that we could justify cp_e. Thank you!

1 Like

Thank you for your question. First, on the honest chain, cp_e is exactly b_{i2}. Second, after discussing with @Tuoeth, if b_k is released with a delay until epoch e+2, then cp_e can be justified directly during epoch e+2 without requiring b_{k2}.

for some reason @nagyabi cannot answer directly within 24 hours, so I send his message instead:

“I understand that cp_e is justified because we accumulated 2/3 of the votes. I refered to Strategy 1, how does justifying cp_e help us forking out the blocks between slot t+19 and t+62?“

Thanks for your question. Even if b_{i2} is shared by two branches, during filter_block_tree LMD-GHOST will first recursively check whether each branch satisfies:

correct_justified = (
    store.justified_checkpoint.epoch == GENESIS_EPOCH
    or voting_source.epoch == store.justified_checkpoint.epoch
    or voting_source.epoch + 2 >= current_epoch
)

In this attack scenario, the honest branch cannot justify b_{i2} due to two epochs of inactivity. Its voting_source.epoch is epoch e−1, while current_epoch is epoch e+2. Therefore it does not meet the correct_justified condition. As a result, the honest branch is filtered out before weight aggregation and thus is not considered by LMD-GHOST.
In fact, the reorg slots is not necessarily confined to slot [t+19, t+62]. The block b_k can be delayed and released as late as just before the unrealized justified state of cp_e+2, yielding a maximum attack window of slot [t+17, t+85].

1 Like