fix(tx-filter): emergency EIP-7702 lockdown for the audit#838 nonce halt#389
Merged
nekomoto911 merged 1 commit intoJul 12, 2026
Merged
Conversation
4d952ad to
d757fa7
Compare
Neutralise the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction filter, gated by a compile-time const EIP7702_LOCKDOWN (currently `true` — this build ships it active) until the durable executor-skip fix (gravity-reth Galxe#388 + grevm Galxe#110) is deployed. Three deterministic drops against certified block-start state, applied when the lockdown is on: L1 reject every type-4 (SetCode) tx - no new delegations (covers audit#822) L2 drop any tx FROM a delegated account - its execution-time CREATE cannot leave a same-block stale tx (audit#838) L3 drop any tx TO a delegated account - no inbound CALL triggers the delegated CREATE The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822) but not the execution-time CREATE bump (audit#838): a delegated account's current-nonce tx reached the executor as NonceTooLow and panicked it at lib.rs:1137. Dropped txs are excluded via the existing invalid_tx_idxs path, so the drop itself cannot halt the chain. EIP7702_LOCKDOWN is a compile-time const (not a CLI/env flag) because it is consensus-critical: a per-node value would fork the chain, so fleet-consistency is made structural by baking it into the binary — the coordinated upgrade IS the binary version. Set it back to false and rebuild to revert once the skip fix is deployed and 7702 can be re-enabled. Trade-off: freezes delegated accounts' tx origination and disables new 7702 usage while active. Tests: filter_invalid_txs takes an eip7702_lockdown param so the unit tests cover both states (L1/L2/L3 + the audit#838 attack shape + non-delegated-traffic-unaffected). The full-pipeline regression test test_finding_a_lockdown_survives_grevm drives OrderedBlock -> filter_invalid_txs -> executor: with the lockdown the attack block survives; without it the executor panics at lib.rs:1137 with NonceTooLow{tx:0,state:1}. The P-13/P-14 7702-delegation positive controls are #[ignore]'d while the lockdown ships (7702 delegation is disabled by it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d757fa7 to
9c861e8
Compare
nekomoto911
approved these changes
Jul 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Emergency stopgap that neutralises the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction filter (
filter_invalid_txs), until the durable executor-skip fix (gravity-reth #388 + grevm #110) is deployed.Gated by a compile-time const
gravity_primitives::EIP7702_LOCKDOWN(currentlytrue— this build ships the lockdown active). It is a const rather than a CLI/env flag on purpose: the toggle is consensus-critical (it changes which txs execute), so a per-node value would fork the chain — baking it into the binary makes fleet-consistency structural (the coordinated upgrade is the binary version). Revert = set it back tofalseand rebuild.Three deterministic drops when active, all evaluated against certified block-start state:
0xef0100…designator)Why
The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822), but not the execution-time CREATE bump: a delegated account
Awhose delegated code runsCREATEbumpsA's own nonce mid-block, so a same-block current-nonce txA@MbecomesNonceTooLowand panics the executor atlib.rs:1137. This is reachable using an account delegated in any prior (permissionless) block.#387's filter stopgap only covered the same-block variant; this closes the already-delegated variant too.Dropped txs are excluded via the existing
invalid_tx_idxspath (pre-execution), so the drop itself cannot halt the chain.Trade-off
While active, this freezes delegated accounts' tx origination and disables new 7702 usage. Revert (flip
EIP7702_LOCKDOWNtofalse) once the skip fix (#388 + grevm #110) is deployed and 7702 can be re-enabled.Validation
filter_invalid_txstakes aneip7702_lockdownparam, so both states are covered: L1/L2/L3, the audit#838 attack shape (X→A + A@M both dropped), and a precision test proving non-delegated traffic is unaffected.test_finding_a_lockdown_survives_grevm— drivesOrderedBlock → filter_invalid_txs → executorwithAgenesis-delegated to a CREATE contract: with the lockdown the attack block survives (zero user txs, chain advances); without it (control) the executor panics atlib.rs:1137withNonceTooLow{tx:0,state:1}.#[ignore]'d while the lockdown ships (7702 delegation is intentionally disabled by it; un-ignore when the const is flipped back tofalse).Deployment
STF change — all full nodes must upgrade together. Because the toggle is a compile-time const, every binary from this build carries the identical value, so nodes cannot diverge on it. Coordinated v1.7.5 release; flip
EIP7702_LOCKDOWNback tofalse+ rebuild to revert.🤖 Generated with Claude Code