# D1 — VERDICT REFUTED

The clamp-versus-reject difference exists, but the proposed **valid transaction with negative total state gas** is refuted by the accounting rules at the supplied pins. Every state-gas credit either reverses a charge in this transaction, restores a frame's reservoir to its rollback baseline, or returns gas previously forwarded. A child can have negative *local* usage when it clears a slot created by an ancestor; the ancestor retains the matching charge, and failure cancels the child's credit along with its clearing operation. Consequently the completed transaction has nonnegative net state usage. Geth's rejection therefore does not establish a valid-block rejection or consensus split. Confidence: **high for this specific trigger**, based on static accounting analysis, not a formal verification of these clients. The reference implementation's explicit allowance for negative totals remains a defensive/textual inconsistency worth clarifying. Sources: [settlement][settle], [storage charging/refilling][storage], [rollback and gas transfers][gas], [child merge][merge].

Reviewed on 2026-10-28. Scope is this assigned EIP-8037 candidate, not a new inventory of Glamsterdam EIPs or a review of every client. All code was read from public raw sources; Geth code was read at `8817f99f92852f8ac53e596de6202dd9e3494065`, not GitHub HTML. No node, transaction, client executable, or network probe was run. HTTP reads below accessed public source, issue, and CI services only.

## Strongest refutation: transaction-wide conservation

This is a derived invariant, rather than a quoted assertion that the spec explicitly proves:

**At settlement, surviving state-gas credits cannot exceed the transaction's corresponding charges.** Equivalently, with initial reservoir `R`, final reservoir `L`, outstanding spill `S`, and committed spill `C`, the spec's net value is `N = R - L + S + C >= 0`. The exact expression is in [`tx_state_gas_used`, gas.py#L558-L591][net]. Do not assume `L <= R` in every child, or that every child's net usage is nonnegative: both would be false. The invariant concerns the transaction after all merges and rollbacks.

For each slot whose original value is zero, the first surviving zero-to-nonzero transition pays one `STORAGE_SET`; a surviving nonzero-to-zero restoration credits exactly one `STORAGE_SET`. Another credit requires another intervening charged set. An initially nonzero slot never earns a **state-gas** credit merely by being cleared: its execution refund counter is separate. Thus each slot's surviving state ledger is zero or one charge, not negative. Transaction-start original storage comes from the block-level state, with newly created accounts treated as originally zero; creation wipes their storage before initcode executes. Sources: [storage.py#L114-L158][storage], [state_tracker.py#L288-L314][original], [interpreter.py#L339-L356][interp].

Rollback preserves this matching globally. A child clearing an ancestor's slot can temporarily hold the credit while the ancestor holds the charge. On success they merge; on failure the child reservoir is **assigned back to its baseline**, rather than credited again, and its storage changes and execution refunds are discarded. If an ancestor later fails, the entire reverted subtree's state changes and state-gas effect are removed together. Account creation refunds are separately guarded by the fact that their corresponding setup charge occurred. Delegation charges that survive execution failure remain committed, never becoming an unmatched credit. Sources: [gas.py#L459-L555][gas], [vm/__init__.py#L188-L244][merge], [interpreter.py#L450-L468][interp], [system.py][system], [delegation][delegation].

**Closest attempted opcode sequence, in words:** a contract sets an originally zero slot to one; it DELEGATECALLs code that clears that same slot, then returns successfully. Write `K = STORAGE_SET`. Parent usage is `+K`, child local usage is `-K`, and the merged transaction usage is zero. Adding more nested DELEGATECALL/CALLCODE frames does not change the sum. If the clearing frame REVERTs, the slot returns to one and its credit is removed, leaving `+K`. If the parent REVERTs after a successful clear, both changes disappear and net usage returns to zero. Repeating set/clear cycles cannot cross below zero. This follows from [storage][storage], [rollback][gas], and [merge][merge]; the pinned public tests contain ancestor-charge, intermediate-revert, and reentrant-credit cases ([test_state_gas_sstore.py#L1197-L1264, #L1408-L1504, #L1505-L1601][sstore-tests]). These tests were read, not executed.

## Exhaustive spec credit/return-site accounting

The Amsterdam Python source tree was enumerated through the [pinned public Git tree][spec-tree]. Reads searched the fork's Python sources for the credit/restore/drain helpers and reservoir assignments. The following covers the sites that can reduce net state usage or return reservoir; ordinary execution-gas refunds are distinguished explicitly.

| Site at execution-specs `7f2f4c9b`, under `src/ethereum/forks/amsterdam/` | Bound against a charge or grant |
| --- | --- |
| `vm/instructions/storage.py#L141-L158` | The credit at L151 requires original zero, current nonzero, and new zero. The earlier zero-to-nonzero write paid the identical `STORAGE_SET` at L144-L146. An unchanged zero earns nothing. Clearing an originally nonzero slot earns no state credit. [Source][storage] |
| `vm/gas.py#L594-L616`, `credit_state_gas_refund` | Implements pool routing, not independent refund eligibility: repay at most outstanding spill, then credit the remainder to the reservoir. Its opcode callers are the SSTORE and conditional account-creation returns listed here. A child may borrow its ancestor's outstanding credit; the whole transaction cannot. [Source][gas] |
| `vm/gas.py#L493-L517`, `restore_state_gas` | Sets reservoir to baseline, clears outstanding spill and execution refund counter, and returns that spill to execution gas. It does not add the baseline or refund gross historical charges. Therefore a negative-local-usage child's enlarged reservoir is reduced on rollback. [Source][gas] |
| `vm/interpreter.py#L380-L385`, `#L450-L468` | Failed code deposit, exceptional halt, and REVERT use the preceding baseline restore; state rollback accompanies it. An exceptional halt then burns execution gas. Nested REVERTs cannot retain credits for reverted clears. [Source][interp] |
| `vm/gas.py#L520-L555`; `vm/interpreter.py#L267-L287` | Pre-dispatch failure restores the immutable entry grant and undoes both ordinary and committed spill. The assertion requires no accrued execution refund; this is before opcode dispatch. Applied authorizations are also rolled back. Restoration leaves no negative state ledger. [Gas][gas], [caller][interp] |
| `vm/gas.py#L619-L647`, `repay_state_gas_spill` | Moves `min(reservoir, spill)` from reservoir to execution gas while reducing spill by the same amount. In `R - L + S + C` the two changes cancel: it creates no net credit. [Source][gas] |
| `vm/gas.py#L689-L734`; `vm/__init__.py#L219-L244` | Parent reservoir is drained to zero before giving the entire grant to a child. Never-entered child restoration returns that same grant. Entered children return their settled meter once; successful spill repayment is a transfer as above. There is no parent-retained duplicate grant. [Gas][gas], [merge][merge] |
| `vm/instructions/system.py#L94-L127, #L171-L180`, CREATE/CREATE2 | Balance/nonce/depth preflight returns before charging; failed state charge halts without a partial charge. Conditional `NEW_ACCOUNT` is charged at L107-L109 in the parent; refund at L178-L180 requires that charge flag and a failed child. Child baseline was taken *after* this charge, so the child's restore does not refund the parent's account charge a second time. Collision has nonzero nonce or code, hence an alive destination and no account charge. The grant is withheld/burnt but no unmatched state credit is issued. [System][system], [deployability][original] |
| `vm/instructions/system.py#L384-L394, #L447-L452, #L539-L560`, CALL family | Positive-value creation sets `new_account_charged` and charges `NEW_ACCOUNT` before forwarding. Preflight failure returns untouched grants and refunds only this charge; entered failure settles the child first, then refunds the same conditional parent charge. These branches are alternatives, not two credits for one call. CALLCODE/DELEGATECALL/STATICCALL use grant returns without inventing an account-creation credit. [Source][system] |
| `vm/eoa_delegation.py#L295-L319`; `vm/interpreter.py#L159-L163`; `vm/gas.py#L459-L490` | EIP-7702 processing charges new authorities and first delegation installation. Clearing delegation provides **no state refill**. Set/clear repetitions retain the installation charge; execution failure protects applied authorization charges via commit/baseline. Only pre-dispatch rollback removes those authorizations and their charges together. The candidate's delegation citation is a charge path, not an extra source of negative usage. [Delegation][delegation], [interpreter][interp], [gas][gas] |
| `vm/interpreter.py#L173-L186, #L261-L287` | Top-level creation/value-transfer setup charges runtime state gas. Its top-level baseline or entry restore reverses the setup charges when their state is undone; authorization commits are kept only when their state survives. [Source][interp] |
| `vm/instructions/system.py#L705-L779`; `vm/interpreter.py#L369-L389` | SELFDESTRUCT can charge for a new beneficiary, but has no success-time state refill for deleting the source, its slots, or code. Code deposit is charged by byte length; failure rolls back that frame. Neither provides a credit for state bought in an earlier transaction. [System][system], [interpreter][interp], [EIP-8037 SELFDESTRUCT rules][eip] |

Gas-meter initialization and baseline commits do not mint credits: initialization uses the transaction/child grant, and commit only lowers the rollback baseline while preserving committed spill. `refund_counter` adjustments in storage are **execution refunds** applied at transaction settlement; they do not lower `state_gas_used`. Sources: [gas.py#L459-L490 and #L1211-L1227][gas], [storage.py#L125-L151][storage].

## Other refutation routes and cross-client correction

1. **Another check producing the clamp's result:** none found on Geth's settlement path. `core/state_transition.go#L1046-L1050` rejects before converting to unsigned, and its caller at L795-L798 propagates that error. This is a literal difference for a supplied negative counter, not evidence of equivalent handling of that counter. `ExitRevert`/`ExitHalt` at `core/vm/gascosts.go#L208-L249` reset frame-local state usage to zero; they are rollback accounting, not a final-transaction clamp. [State transition][geth-st], [gas budgets][geth-gas].

2. **Condition impossible on a valid path:** the transaction-wide invariant above is the decisive refutation. Geth's SSTORE charge/refund conditions match the pairing (`core/vm/gas_table.go#L711-L739`); `RefundState` subtracts the matched amount (`gascosts.go#L159-L166`), `Absorb` sums child usage (`#L273-L292`), and failure resets local usage (`#L208-L249`). Parent-side creation refunds are guarded by `creationCharged` (`instructions.go#L674-L679, #L721-L726`). Top-level creation uses `chargedCreation` (`state_transition.go#L838-L866`); top-level recipient charging precedes the matching failed-transfer refund (`#L1009-L1018`, `#L922-L927`). Thus a negative child alone does not trip the topmost guard. [SSTORE][geth-table], [budget][geth-gas], [instructions][geth-ins], [transaction][geth-st]. This is not a claim that an unrelated future accounting bug could never violate the invariant.

3. **Misread spec:** the clamp was **not** misread. At EELS `vm/gas.py#L1181-L1182`, the docstring says “clamped to zero, since refunds can drive it negative”; L1216 explicitly uses `StateGas(Uint(max(0, state_gas_used)))`. The comment asserts a possibility but supplies no valid whole-transaction example. At the other supplied normative pin, EIP-8037 `d4c57552`, the transaction block-accounting pseudocode instead takes the net counter directly, without a clamp (`eip-8037.md#L272-L279`); its SSTORE, conditional refund, rollback, and SELFDESTRUCT rules support the conservation argument. Thus do not present the EELS comment as proof of reachability or describe the EIP text itself as explicitly requiring the clamp. [EELS][settle], [EIP pin][eip].

4. **Later fix:** no clamp fix found. The [state-transition history API][st-history] and [gas-budget history API][gas-history] were read; the subsequently read [master state-transition raw file][geth-master] still has the negative topmost-state guard at L1047-L1048. Geth [PR #35633][geth-pr], closed/merged, implements merge-time spill repayment; that behavior is already present at the assigned pin (`gascosts.go#L283-L292`). It does not turn rejection into clamping. This is a check of the returned histories/current source, not a claim to have audited every later PR.

The other supplied pins confirm a **counter-handling difference**, but not an input that distinguishes valid-chain behavior:

| Client/pin | Verified behavior and limit of inference |
| --- | --- |
| Nethermind `d48833af` | `src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1967-L1978` returns `InvalidStateGas` when calculated block state gas is negative. Its [merged PR #13178][nm-pr] deliberately treats these as structural accounting invariant failures. This review does not claim to have independently proved every Nethermind gas-policy operation correct. [Pinned source][nm] |
| Erigon `f32a39d1` | `execution/protocol/mdgas/md_gas.go#L79-L88` clamps state usage; `Total()` adds that clamped component to execution. `execution/protocol/txn_executor.go#L687-L709` uses this total for pre-refund gas and uses `combined.Execution` for block execution gas. If negative whole-transaction usage were reachable, equivalence to EELS would need a separate proof; “both clamp” alone is insufficient. Under nonnegative net usage the negative branch cannot distinguish them. [Gas arithmetic][erigon-gas], [settlement][erigon-tx] |
| Reth / evm2 `4a53ec080dfbb904e98e3ca8f0abcc11ab8abae0` | `crates/evm2/src/ethereum/mod.rs#L792-L806` uses remaining gas plus reservoir for total spending and clamps state spending before subtracting authorization state refund. That verifies the cited clamp, not complete EELS equivalence for every fee and floor case. Reth's publicly read [main Cargo.toml][reth] selects this exact evm2 revision. The supplied `4a53ec08` source is under **alloy-rs/evm2**, not paradigmxyz/evm2. [Pinned evm2 source][evm2] |

**Disposition of the candidate record:** retain as an unreachable-counter/spec-clarification observation; remove from confirmed consensus bugs. Trigger: a negative *whole-transaction* net state counter, requiring an additional accounting defect or a future unmatched-credit rule; no valid opcode sequence found under these pins. Conditional impact, if that precondition were independently demonstrated: **valid block rejected / consensus split** between reject and accepting implementations. Observed severity: **no demonstrated consensus impact**; a cosmetic/defensive implementation difference at this boundary. No corrected exploitable-bug record is warranted.

## Known-check and public test evidence

- **Nethermind #13178:** closed and merged, 2026-09-29. The PR's own classification is diagnostic/invariant enforcement, not a demonstrated input-triggered consensus correctness fix. Its later discussion explains explicit failed transaction results and rollback, replacing earlier exception-based drafts. This is evidence of intentional rejection, not independent proof of the invariant. [PR metadata/body API][nm-pr], [discussion API][nm-comments].
- **execution-specs #3518:** closed, 2026-09-17; a `tests-glamsterdam-devnet@v8.1.4` release tracker for EIP-8037 spill repayment and associated tests, **not** a clamp-versus-reject bug report. It records fixture publication and downstream Hive integration. [Issue API][tracker].
- **execution-specs #3478 and #3490:** both closed/merged. They implement merge-time repayment and cross-frame placement/settlement coverage respectively. They do not provide a negative whole-transaction witness. [#3478][eels-pr], [#3490][tests-pr]. **EIPs #12256 and #12265:** both closed/merged; the rollback-baseline and successful-merge explanations directly support the refutation, including cancellation of a clearing child's credit on failure. [#12256][rollback-pr], [#12265][merge-pr].
- **Geth #35633:** closed/merged, matching the pinned debt-repayment code; related repair, not a final-settlement clamp fix. [PR API][geth-pr].
- API searches over open **and** closed Geth issues/PRs for `"negative" "state gas"` returned five results, none identifying this clamp-versus-reject condition; `"8037" "clamp"` returned zero. Subsequent searches for Nethermind, Erigon, evm2, EELS and EIPs hit HTTP 403 rate limits. Supplemental public web searches did not identify a specific matching report. Therefore **no exact duplicate found in the material retrieved**, not “no such issue exists.” [Geth search 1][search1], [Geth search 2][search2].
- **Public execution tests read:** pinned `test_state_gas_sstore.py` includes multi-frame ancestor charges, subframe/ancestor reverts, refund advances and CREATE-init success/failure cases; `test_state_gas_cross_frame_refund.py` includes settlement, inner-frame repayment, delegation spill and reservoir-grant cases; `test_state_gas_selfdestruct.py` explicitly contains no-refund cases. These are source-level coverage observations; no tests were run and no all-client pass result is claimed. [SSTORE tests][sstore-tests], [cross-frame tests][cross-tests], [SELFDESTRUCT tests][sd-tests].
- **Hive/EST result check:** public [discovery configuration][discovery] points to Glamsterdam quick runs; the [workflow source][workflow] accepts a fixtures tag and publishes results. The [completed-run API][runs] returned runs **40548729228** and **40534015764**, both `success`, dated 2026-10-27. Workflow success does not establish that every client/test passed or that these exact pins were tested. Direct dashboard access at `https://hive.ethpandaops.io/` was blocked by the retrieval sandbox, so individual simulator outputs and a D1-specific result could not be verified. This limits the known-results check; it is not positive evidence for D1.

## URLs read and relied on

The source links below use raw content for code; line numbers in the report are one-based positions in those raw files. API links supply public issue/PR states and histories. Unpinned `master`/`main` reads are identified as current observations rather than substitutes for the assigned pins.

[settle]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/gas.py#L1181-L1227
[gas]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/gas.py
[net]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/gas.py#L558-L591
[storage]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/instructions/storage.py#L114-L158
[merge]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/__init__.py#L188-L244
[interp]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/interpreter.py
[system]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/instructions/system.py
[original]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/state_tracker.py
[delegation]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/src/ethereum/forks/amsterdam/vm/eoa_delegation.py#L239-L319
[eip]: https://raw.githubusercontent.com/ethereum/EIPs/d4c57552/EIPS/eip-8037.md
[spec-tree]: https://api.github.com/repos/ethereum/execution-specs/git/trees/7f2f4c9b?recursive=1
[geth-st]: https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/state_transition.go
[geth-gas]: https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/vm/gascosts.go
[geth-table]: https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/vm/gas_table.go#L680-L739
[geth-ins]: https://raw.githubusercontent.com/ethereum/go-ethereum/8817f99f92852f8ac53e596de6202dd9e3494065/core/vm/instructions.go
[geth-master]: https://raw.githubusercontent.com/ethereum/go-ethereum/master/core/state_transition.go
[nm]: https://raw.githubusercontent.com/NethermindEth/nethermind/d48833af/src/Nethermind/Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1967-L1978
[erigon-gas]: https://raw.githubusercontent.com/erigontech/erigon/f32a39d1/execution/protocol/mdgas/md_gas.go#L79-L88
[erigon-tx]: https://raw.githubusercontent.com/erigontech/erigon/f32a39d1/execution/protocol/txn_executor.go#L687-L709
[evm2]: https://raw.githubusercontent.com/alloy-rs/evm2/4a53ec08/crates/evm2/src/ethereum/mod.rs#L792-L806
[reth]: https://raw.githubusercontent.com/paradigmxyz/reth/main/Cargo.toml
[nm-pr]: https://api.github.com/repos/NethermindEth/nethermind/pulls/13178
[nm-comments]: https://api.github.com/repos/NethermindEth/nethermind/issues/13178/comments
[tracker]: https://api.github.com/repos/ethereum/execution-specs/issues/3518
[eels-pr]: https://api.github.com/repos/ethereum/execution-specs/pulls/3478
[tests-pr]: https://api.github.com/repos/ethereum/execution-specs/pulls/3490
[geth-pr]: https://api.github.com/repos/ethereum/go-ethereum/pulls/35633
[rollback-pr]: https://api.github.com/repos/ethereum/EIPs/pulls/12256
[merge-pr]: https://api.github.com/repos/ethereum/EIPs/pulls/12265
[st-history]: https://api.github.com/repos/ethereum/go-ethereum/commits?path=core/state_transition.go&per_page=30
[gas-history]: https://api.github.com/repos/ethereum/go-ethereum/commits?path=core/vm/gascosts.go&per_page=20
[search1]: https://api.github.com/search/issues?q=repo%3Aethereum/go-ethereum%20%22negative%22%20%22state%20gas%22&per_page=20
[search2]: https://api.github.com/search/issues?q=repo%3Aethereum/go-ethereum%20%228037%22%20%22clamp%22&per_page=20
[sstore-tests]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_sstore.py
[cross-tests]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_cross_frame_refund.py
[sd-tests]: https://raw.githubusercontent.com/ethereum/execution-specs/7f2f4c9b/tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_selfdestruct.py
[discovery]: https://raw.githubusercontent.com/ethpandaops/hive-ui/master/public/discovery.json
[workflow]: https://raw.githubusercontent.com/ethpandaops/hive-tests/master/.github/workflows/hive-glamsterdam-quick.yaml
[runs]: https://api.github.com/repos/ethpandaops/hive-tests/actions/workflows/hive-glamsterdam-quick.yaml/runs?status=completed&per_page=2
