# Nethermind vs EIP-8037 (with EIP-7778 and EIP-8038): spec-conformance review, item `nethermind-8037`

| Field | Value |
|---|---|
| Client | Nethermind (execution layer) |
| EIPs | EIP-8037 State Creation Gas Cost Increase, plus the interacting EIP-7778 Block Gas Accounting without Refunds and EIP-8038 State-Access Gas Cost Update |
| Nethermind pin | `d48833af88ec4224c86afadd1c596e8f619c406b` on `master` (default branch), committed 2026-10-27T12:00:20Z. Shortened below to **NM@d48833af**. File URLs are `https://github.com/NethermindEth/nethermind/blob/d48833af88ec4224c86afadd1c596e8f619c406b/src/Nethermind/<path>#L<a>-L<b>`. |
| Reference spec pin | ethereum/execution-specs `7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b`, committed 2026-10-27T11:40:55-06:00. Shortened below to **ES@7f2f4c9b**. File URLs are `https://github.com/ethereum/execution-specs/blob/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam/<path>#L<a>-L<b>`. |
| Spec branch caveat | The brief names `tree/master`, but execution-specs has no `master` branch. `git ls-remote --symref` gives `HEAD -> refs/heads/forks/bogota`, so this review uses the default branch, which contains `forks/amsterdam`. The separate `forks/amsterdam` branch is at `16898000911c1e3caa57be08509536c10ae92d3e` (2026-10-06). Its `vm/gas.py`, `vm/instructions/storage.py`, `fork.py` and `vm/interpreter.py` are byte-identical to the pin. It differs in `transactions.py`, `vm/eoa_delegation.py`, `vm/instructions/system.py`, `utils/address.py` and some BLS precompile files. |
| EIP text pin | ethereum/EIPs `d4c575521d99ec881a444ab3af604e684b5f0743` (2026-10-27). EIP-8037, EIP-7778 and EIP-8038 are all **Last Call**, with `last-call-deadline: 2026-11-01`. |
| Second client, for comparison | go-ethereum `8817f99f92852f8ac53e596de6202dd9e3494065` (master, 2026-10-27T12:32:47+09:00). Shortened below to **GETH@8817f99f**. |
| Live-code rule | **Does not apply.** Glamsterdam is not active on Ethereum mainnet. EIP-7773 (ethereum/EIPs@d4c57552) lists Sepolia at 1791294816 and Hoodi at 1793036568, and leaves the **Mainnet row empty**. The execution-specs `mainnet` branch has no `amsterdam` fork directory. Full details are therefore given below. |

**Method.** I shallow-cloned the public repositories above at the pinned commits and read the code; nothing was run. Three read-only helper passes mapped SSTORE, the CALL/CREATE/SELFDESTRUCT family, and transaction/block accounting. I re-read every candidate and each line cited in its six parts myself. The checked-rules list relies partly on the helper mapping, and I spot-checked a sample of it. All page and repository content was treated as data.

## Summary

- **With the named `Amsterdam` fork (EIP-7778, EIP-8037, EIP-8038 and EIP-7928 activated together), I found no candidate where Nethermind's consensus output (gas used, state, block validity) differs from the reference spec.** Constants, the SSTORE table, CALL/CREATE/SELFDESTRUCT state-gas rules, the reservoir model, LIFO refills, child-frame merge and restore, and settlement all match. So do EIP-7778 block accounting, header `gas_used`, the system-call budget, and the fork-transition base-fee input.
- **Four low-confidence candidates** are recorded below:
  - **C1:** the spec clamps negative state gas to zero; Nethermind rejects such a transaction. Believed unreachable. Geth behaves like Nethermind.
  - **C2:** Nethermind gates these rules on independent per-EIP chainspec timestamps. Output can differ only on a chainspec that activates EIP-8037, EIP-7778, EIP-8038 and EIP-7928 at different times.
  - **C3:** existence tests read from a different state. Believed unreachable.
  - **C4:** check-order differences that change only trace and error labels.
- None is a confirmed consensus bug.

---

## Candidate C1: a negative net transaction state gas is clamped to 0 by the spec but makes the transaction invalid in Nethermind

1. **Spec text (verbatim).**
   - EIP-8037 (https://eips.ethereum.org/EIPS/eip-8037, Block-level gas accounting): "`tx_state_gas = tx_output.evm_state_gas_used`".
   - Same EIP, halts and reverts: "`net_state_gas` is negative for a frame that refilled more than it charged".
   - The reference spec makes the transaction-level clamp explicit. ES@7f2f4c9b `vm/gas.py#L1216`:
     `settled_state_gas_used = StateGas(Uint(max(0, state_gas_used)))`
   - The docstring at ES@7f2f4c9b `vm/gas.py#L564-L567` reads "May be negative when refunds exceed charges". `vm/interpreter.py#L115-L116` reads `state_gas_used: int` / `"""Net state gas consumed; negative when refunds exceed charges."""`.
2. **Client code.** NM@d48833af `Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1969-L1971`:
   ```csharp
   (ulong blockGas, long blockStateGas) = CalculateBlockGas(spec, in gasAfterExecution, blockAccountingGas, floorGasLong);
   if (blockStateGas < 0)
       return InvalidStateGas(Logger, $"EIP-8037 invariant violated: negative block state gas ({blockStateGas}).");
   ```
   - The helper pass reported similar guards at `TransactionProcessor.cs#L1737` and `#L1769`; I did not re-read those two lines myself.
   - Frame-level refills are floored at the frame's `InitialStateGasUsed`, and any excess is carried upward. NM@d48833af `Nethermind.Evm/VirtualMachine.cs#L1038-L1055`:
     `long refundableStateGas = Math.Max(0, TGasPolicy.GetStateGasUsed(in gas) - stateGasFloor);` … `vmState.StateGasRefundAdvanced += pendingRefund;`
3. **Condition for a difference.**
   - A transaction would need total state-gas refills greater than its total surviving state-gas charges. An example is a storage slot that is zero at transaction start, set, and then cleared without the set having been charged in this transaction.
   - The spec settles such a transaction with state gas 0. Nethermind treats it as invalid when validating, so the block is rejected.
   - I could not construct this condition. A `0→x→0` refill requires an earlier `0→x` in the same transaction that was charged and not rolled back. CALL/CREATE refills only reverse their own charges. SELFDESTRUCT has no refill.
4. **Other client.** Geth also rejects. GETH@8817f99f `core/state_transition.go#L1047-L1049`:
   ```go
   if st.gasRemaining.UsedStateGas < 0 {
       return 0, 0, fmt.Errorf("negative topmost frame state gas usage, %d", st.gasRemaining.UsedStateGas)
   }
   ```
   It also errors if `gasUsedBeforeRefund < txStateGas` (`#L1063-L1065`). Geth therefore agrees with Nethermind and differs from the spec's clamp.
5. **Confidence: low.** Both clients treat this as an invariant that should never be violated. The spec clamps defensively, and I found no input that reaches the branch.
6. **Severity, if reachable: valid block rejected.** Since Geth behaves the same way, it would be a split between the two clients and the reference spec and the test fixtures, not between these two clients.
- **Known-check: known (intentional).** https://github.com/NethermindEth/nethermind/pull/13178, "fix(evm): fail loud on violated EIP-8037 state-gas invariants (F-38)", closed 2026-09-29. Its description says these invariants are "reachable only through an internal accounting bug, never through transaction input". No issue tracks the spec-versus-client difference in clamp semantics.

## Candidate C2: Nethermind gates the 2D inclusion check, the per-auth cost and block accounting on separate per-EIP timestamps

1. **Spec text (verbatim).**
   - EIP-8037: "inclusion of a transaction in a block requires that: … `min(TX_MAX_GAS_LIMIT, tx.gas) <= execution_gas_available` and `tx.gas <= state_gas_available`".
   - EIP-8037: "If implemented together with [EIP-7778], the block level would be updated to: `tx_execution_gas = max(tx_gas_used_before_refund - tx_state_gas, calldata_floor_gas_cost)`".
   - EIP-8037 parameter table: "`PER_AUTH_BASE_COST` | 12,500 | `STATE_BYTES_PER_AUTH_BASE x CPSB` | `EXECUTION_PER_AUTH_BASE_COST`".
   - URL: https://eips.ethereum.org/EIPS/eip-8037.
   - The reference spec has a single Amsterdam fork with all of these rules:
     - ES@7f2f4c9b `vm/gas.py#L1081-L1085`: `if min(GasCosts.TX_MAX_GAS_LIMIT, tx_gas) > execution_gas_available:` … `if tx_gas > state_gas_available:`
     - `vm/gas.py#L158-L163`: `EXECUTION_PER_AUTH_BASE_COST = 101*16 + 3000 + 3000 + 2*100 = 7816`
2. **Client code (NM@d48833af).**
   - `Nethermind.Specs/ChainSpecStyle/ChainSpecBasedSpecProvider.cs#L345`, `#L364`, `#L365` and `#L368` set `IsEip8038Enabled`, `IsEip8037Enabled`, `IsEip7778Enabled` and `IsEip7928Enabled` from **separate** chainspec transition timestamps.
   - The 2D inclusion check runs only when the block-access-list manager is enabled. `Nethermind.Consensus/Processing/BlockProcessor.ParallelBlockValidationTransactionsExecutor.cs#L57-L60`:
     `if (!balManager.Enabled) { return inner.ProcessTransactions(block, processingOptions, receiptsTracer, token); }`
     - Per the helper pass, `Enabled` is `spec.BlockLevelAccessListsEnabled` (EIP-7928), and the fallback executor never calls `Eip8037BlockGasInclusionCheck`. I did not re-read those two files.
   - `Nethermind.Evm/IntrinsicGasCalculator.cs#L95`:
     `ulong perAuthExecution = spec.IsEip8038Enabled ? Eip8038Constants.PerAuthBaseExecution : GasCostOf.PerAuthBaseExecution;`
     - The fallback is 7,500 (`Nethermind.Core/Eip8037Constants.cs#L11`, `PerAuthBaseExecutionCost = 7_500`). The EIP-8038 value is 7,816 (`Nethermind.Core/Eip8038Constants.cs#L26`).
   - `Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L865`:
     `ulong accountWriteGas = spec.IsEip8038Enabled ? Eip8038Constants.AccountWrite : 0;`
   - `Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1968`:
     `ulong blockAccountingGas = spec.IsEip7778Enabled ? spentGas : operationGas;`
3. **Condition for a difference.** Only on a chainspec that sets these four EIPs to different transition timestamps.
   - **EIP-8037 active, EIP-7928 not:** a block whose transaction fails the reservation check (for example `tx.gas` greater than `block_gas_limit - block_state_gas_used`) but whose actual usage fits would be accepted by Nethermind.
   - **EIP-8037 active, EIP-8038 not:** each authorization is charged 316 less execution gas and no `ACCOUNT_WRITE`.
   - **EIP-8037 active, EIP-7778 not:** the block execution dimension is counted after refunds.
   - The named `Amsterdam` fork sets all four together (NM@d48833af `Nethermind.Specs/Forks/25_Amsterdam.cs#L18-L25`: `IsEip7778Enabled = true; … IsEip7928Enabled = true; … IsEip8037Enabled = true; IsEip8038Enabled = true;`). Geth-style genesis files with `amsterdamTime` therefore do not hit this.
4. **Other client.** Geth gates the check on one fork rule. GETH@8817f99f `core/state_transition.go#L690-L695`: `if rules.IsAmsterdam { executionGas := st.msg.GasLimit; if !st.msg.skipExecutionGasCap { executionGas = min(executionGas, params.MaxTxGas) }; err = st.gp.CheckGasAmsterdam(executionGas, st.msg.GasLimit) }`. The check itself is in `core/gaspool.go#L64-L71`. This agrees with the spec's single-fork model.
5. **Confidence: low as a network issue, high that the code behaves as described.** It is reachable only through a non-standard chainspec, which no public network is known to use.
6. **Severity under such a chainspec:** invalid block accepted (inclusion check), and wrong gas or fee (per-auth cost, block accounting). **Cosmetic for Amsterdam.**
- **Known-check: not found.**
  - Searches run on the GitHub search API for NethermindEth/nethermind issues and PRs, open and closed: `8037`, `8038`, `7778`, `state gas negative`. The nearest results are:
    - https://github.com/NethermindEth/nethermind/pull/14300, "respect EIP-7778 in EIP-8037 block gas accounting", which introduced the 7778 gate.
    - https://github.com/NethermindEth/nethermind/pull/14944, "reject blocks whose transactions cannot fit the gas limit before executing them".
  - Neither mentions decoupled activation.

## Candidate C3: existence tests read a different account state than the spec (believed unreachable)

1. **Spec text (verbatim).**
   - EIP-8037 (https://eips.ethereum.org/EIPS/eip-8037): "**`CALL*` family (conditional charge).** The `STATE_BYTES_PER_NEW_ACCOUNT × CPSB` account-creation charge is applied *conditionally* right before entering the child frame: only when the target account does not exist and a positive value is transferred."
   - Same EIP, top-level create: "it is applied as a runtime charge in the pre-execution phase … only if the destination does not already exist."
   - Spec code:
     - CALLCODE never charges. ES@7f2f4c9b `vm/instructions/system.py#L544-L546` applies `new_account_charged = has_value and not is_account_alive(tx_state, to)` only in `call`.
     - The top-level create uses the **transaction-start** state. ES@7f2f4c9b `vm/interpreter.py#L177-L181`: `if (get_pre_state_account(tx_env.state, current_target) == EMPTY_ACCOUNT): charge_state_gas_from_meter(gas_meter, StateGasCosts.NEW_ACCOUNT)`.
2. **Client code (NM@d48833af).**
   - CALLCODE: `Nethermind.Evm/Instructions/EvmInstructions.Call.cs#L343-L344`, `TSpec.IsEip8038Enabled ? hasValueTransfer && state.IsDeadAccount(target)`. Per the helper pass, this runs for CALLCODE with `target = env.ExecutingAccount` (`#L160-L162`, `#L215`).
   - Top-level create: `Nethermind.Evm/TransactionProcessing/TransactionProcessor.cs#L1474-L1475` uses **current** state:
     `bool createdTargetAlive = tx.IsContractCreation && !WorldState.IsDeadAccount(env.ExecutingAccount);`
     `bool topLevelCreateStateGasCharged = tx.IsContractCreation && !createdTargetAlive;`
   - Top-level value transfer: `TransactionProcessor.cs#L457-L459` adds `tx.SenderAddress != tx.To`, which the spec (`vm/interpreter.py#L129`) does not have.
3. **Condition for a difference.** Each case needs a state I believe cannot occur:
   - CALLCODE with value while the executing account is dead (zero nonce, zero balance, no code). A running contract either has code or was created with nonce 1.
   - A top-level create whose address changed between transaction start and frame entry. Only EIP-7702 authorizations run in between, and the authority would have to be the CREATE address, which requires a keccak preimage.
   - A self-transfer from a sender that is dead after its nonce bump, which is impossible.
4. **Other client.** Geth charges top-level account creation at GETH@8817f99f `core/state_transition.go#L842` and `#L1016` (`chargeRuntimeGas(vm.GasCosts{StateGas: params.AccountCreationSize * st.evm.Context.CostPerStateByte})`). I did not read the existence predicate Geth uses there, so agreement on this point is not established.
5. **Confidence: low.** The conditions appear unreachable.
6. **Severity: cosmetic,** wrong gas only if a reachable case exists.
- **Known-check: not found.** Queries as for C2. https://github.com/NethermindEth/nethermind/pull/14599 ("cover EIP-8037 authorization state gas on top-level revert") is adjacent but different.

## Candidate C4: check-order differences that change only traces and error labels

1. **Spec text (verbatim).** EIP-8037 (https://eips.ethereum.org/EIPS/eip-8037): "For `SSTORE`, the `GAS_CALL_STIPEND` pre-state check ([EIP-7928]) applies to `gas_left` only, excluding the `state_gas_reservoir`."
   - Spec code: ES@7f2f4c9b `vm/instructions/storage.py` pops the stack (`#L82-L83`) before `check_gas(evm, max(gas_cost, ExecutionGas(GasCosts.CALL_STIPEND + Uint(1))))` (`#L103-L105`).
   - CREATE charges gas (`vm/instructions/system.py#L216-L219`) before the init-code size check (`#L221-L222`).
2. **Client code (NM@d48833af).**
   - `Nethermind.Evm/Instructions/EvmInstructions.Storage.cs#L557` runs `if (TGasPolicy.GetRemainingGas(in gas) <= GasCostOf.CallStipend)` before the stack pop at `#L570`.
   - `EvmInstructions.Create.cs#L141-L147` checks init-code size before charging gas at `#L153`.
3. **Condition for a difference.**
   - SSTORE with fewer than two stack items and `gas_left ≤ 2300`: the spec raises stack underflow, Nethermind raises out-of-gas.
   - Oversized init code with too little gas: different error label.
   - Both cases are exceptional halts that consume all of the frame's gas, so state, gas and receipts are identical.
4. **Other client.** I did not compare Geth for this.
5. **Confidence: high** that the order differs, and high that it has no consensus effect.
6. **Severity: cosmetic** (tracer and error-type output only).
- **Known-check: not found** (same queries as C2).

---

## Spec rules checked and found correctly implemented (Amsterdam fork)

Nethermind references are NM@d48833af and spec references are ES@7f2f4c9b. Each item is spec → client.

**Constants**
- **`CPSB` = 1530, 64 bytes per slot, 120 bytes per account, 23 per auth.** Spec `vm/gas.py#L47-L49` → `Nethermind.Core/GasCostOf.cs#L77-L80` and `#L82-L90` (`SSetState`, `CreateState`, `NewAccountState`, `CodeDepositState`, `PerAuthBaseState`, `PerEmptyAccountState`), plus `Nethermind.Core/Eip8037Constants.cs#L14`. Arithmetic uses `long` and compile-time constants, so there is no overflow.
- **`COLD_ACCOUNT_ACCESS` 3000, `WARM_ACCESS` 100, `COLD_STORAGE_ACCESS` 2100, `ACCOUNT_WRITE` 9000, `STORAGE_WRITE` 10000.** Spec `vm/gas.py#L77-L85` → `Nethermind.Core/Eip8038Constants.cs#L15-L19`.
- **`CALL_VALUE` = 11300 and `CREATE_ACCESS` = 12000.** Spec `vm/gas.py#L85-L90` → `Eip8038Constants.cs#L22-L23`.
- **Access-list costs: address 2900 (3000 − 100) and storage key 2000 (2100 − 100).** Spec `vm/gas.py#L147-L152` → `Eip8038Constants.cs#L10-L13` and `#L24-L25`.
- **`STORAGE_CLEAR_REFUND` = (10000 + 2100) × 4800 / 5000 = 11616.** Spec `vm/gas.py#L98-L100` → `Nethermind.Core/RefundOf.cs#L16`.
- **`EXECUTION_PER_AUTH_BASE_COST` = 7816 under Amsterdam.** Spec `vm/gas.py#L158-L163` → `Eip8038Constants.cs#L26-L29`, selected at `Nethermind.Evm/IntrinsicGasCalculator.cs#L95`.
- **`TX_MAX_TOTAL_GAS_LIMIT` = 2^32 − 1.** Spec `vm/gas.py#L154` and `transactions.py#L640-L641` → `Eip8037Constants.cs#L17`, enforced in `TransactionProcessor.cs#L1034` and `Nethermind.Consensus/Validators/TxValidator.cs#L677-L679` (helper-mapped).
- **`SYSTEM_CALL_GAS_LIMIT` = 30,000,000 + 64 × 1530 × 16 = 31,566,720, with the extra placed in the reservoir.** Spec `fork.py#L107-L108` and `#L756-L761` (helper-mapped) → `Eip8037Constants.cs#L19-L22` and `Nethermind.Evm/GasPolicy/EthereumGasPolicy.cs#L53-L76`. Here `CreateSystemTransactionIntrinsicGas` sets `StateReservoir = Eip8037Constants.SystemCallStateReservoir`, and `TryCreateSystemTransactionAvailableGas` sets `Value = gasLimit - (ulong)reservoir`.

**SSTORE: EIP-8037 opcode table and EIP-8038 cost table, all rows, cold and warm**
- **Stipend check:** fails when `gas_left ≤ 2300`, using `gas_left` only. Spec `storage.py#L103-L105` → `EvmInstructions.Storage.cs#L557` (`GetRemainingGas` is `gas.Value`, which excludes `StateReservoir`; `EthereumGasPolicy.cs#L85`).
- **New slot (`0→0→x`):** access + 10000 execution gas, then 97,920 state gas, execution charged first. Spec `storage.py#L122-L123`, `#L144-L146` and `#L153-L157` → `Storage.cs#L622-L624`, `EthereumGasPolicy.cs#L486-L491` and `#L154-L156`.
- **Clear (`x→x→0`):** +11616 refund. Spec `storage.py#L127-L130` → `Storage.cs#L653-L658`.
- **Reversal (`x→0→y`):** −11616. Spec `storage.py#L132-L134` → `Storage.cs#L692-L697`.
- **Restore to original:** +10000 (`STORAGE_WRITE`) refund. Spec `storage.py#L136-L139` → `Storage.cs#L713-L715` and `#L735`.
- **`0→x→0`:** 97,920 refilled, first to `gas_left` up to the spill and the rest to the reservoir. Spec `storage.py#L148-L151` and `vm/gas.py#L613-L616` → `Storage.cs#L717-L729`, `VirtualMachine.cs#L1030-L1055` and `EthereumGasPolicy.cs#L569-L608`.
- **State-gas out-of-gas:** draws from the reservoir first, then spills into `gas_left`, otherwise out-of-gas. Spec `vm/gas.py#L413-L436` → `EthereumGasPolicy.cs#L129-L152`.

**CREATE / CREATE2 / code deposit**
- **Execution charge** is `CREATE_ACCESS` + 2 per init-code word (+6 per word for CREATE2) + memory. Spec `system.py#L216-L219` and `#L275-L283` → `GasPolicy/CreateGasCost.cs#L19-L28` and `EthereumGasPolicy.cs#L352-L354`.
- **Checks before the destination is read:** balance, nonce and depth. Spec `system.py#L94-L100` → `EvmInstructions.Create.cs#L162-L193`.
- **Conditional new-account charge**, applied before the 63/64 forward. Spec `system.py#L105-L113` → `Create.cs#L223-L233`.
- **Collision check** uses nonce ≠ 0 or code present; storage alone does not collide. Spec `state_tracker.py#L366-L370` → `Nethermind.State/WorldState.cs#L444-L450` (helper-mapped).
- **Refill on child revert or halt.** Spec `system.py#L178-L180` → `VirtualMachine.cs#L523-L526` and `#L981-L986` (helper-mapped).
- **Code deposit:** 6 × ceil(L/32) execution gas first, then L × 1530 state gas; max code size 65,536; on failure, roll back and refill the account charge. Spec `interpreter.py#L361-L389` → `CodeDepositHandler.cs#L63-L84` and `VirtualMachine.cs#L783-L836` (helper-mapped), with `Forks/25_Amsterdam.cs#L22` for the size limit.

**CALL family / SELFDESTRUCT / EXT\***
- **CALL:** value surcharge 11300 plus a 2300 stipend to the child; cold 3000, warm 100; new-account charge only when value > 0 and the target is not alive; refills when the frame is never entered or the child fails. Spec `system.py#L499-L559` and `#L387-L394` → `EvmInstructions.Call.cs#L173-L285` and `#L343-L344` (helper-mapped).
- **SELFDESTRUCT:** base 5000, plus 3000 if the beneficiary is cold (warm is free); `ACCOUNT_WRITE` and 183,600 state gas when a nonzero balance goes to a dead beneficiary, execution charged first. Spec `system.py#L724-L756` → `EvmInstructions.ControlFlow.cs#L379-L392` and `#L414-L426`.
- **EXTCODESIZE / EXTCODECOPY** add `WARM_ACCESS`; **BALANCE / EXTCODEHASH** do not. Spec `environment.py#L344-L350`, `#L381-L396`, `#L72-L76` and `#L490-L496` → `EvmInstructions.CodeCopy.cs#L256-L270` and `#L352-L356`, and `EvmInstructions.Environment.cs#L562-L572` and `#L640-L649` (helper-mapped).

**Reservoir model, frames and settlement**
- **Initialisation:** `gas_left = min(TX_MAX_GAS_LIMIT − intrinsic, evm_gas)` and `reservoir = rest`. Spec `vm/gas.py#L1105-L1136` → `EthereumGasPolicy.cs#L823-L831`.
- **Child frames:** the child receives the whole reservoir; 63/64 applies to `gas_left` only; `GAS` returns `gas_left`. Spec `vm/gas.py#L689-L710` and `#L846-L861` → `EthereumGasPolicy.cs#L707-L718` and `#L513-L517`, and `EthereumGasPolicy.cs#L85` (helper-mapped).
- **Merge and restore:** on success the child merges and outstanding spill is repaid via `d = min(reservoir, spill)`; on revert or halt the reservoir is restored to the child's baseline and the spill is credited (revert) or burned (halt). Spec `vm/gas.py#L493-L517` and `#L619-L647` → `EthereumGasPolicy.cs#L162-L219` and `VirtualMachine.cs#L514-L532` (helper-mapped).
- **EIP-7702 authorizations:** new-account charge when `!AccountExists` (matching the spec's `account_exists`); `ACCOUNT_WRITE` once per authority, with sender and value recipient pre-seeded; `AUTH_BASE` once per authority not delegated before the transaction and not a clear; state gas committed before the top frame. Spec `vm/eoa_delegation.py#L286-L319`, `fork.py#L602-L604` and `interpreter.py#L160-L163` → `TransactionProcessor.cs#L829-L904`.
- **Settlement:** `before = tx.gas − gas_left − reservoir`; `refund = min(before/5, counter)`; `tx_gas_used = max(before − refund, floor)`. Spec `vm/gas.py#L1211-L1214` → `TransactionProcessor.cs#L1963-L1976` and `#L2024-L2025` (refund line helper-mapped).
- **EIP-7778 block accounting:** execution dimension `max(before − state, floor)`, state dimension = net state gas, header `gas_used = max(execution, state)`, receipt cumulative gas uses post-refund, post-floor gas. Spec `vm/gas.py#L1216-L1222` and `fork.py#L335-L338` and `#L1068-L1072` → `TransactionProcessor.cs#L1968-L1973`, `GasPolicy/Eip8037BlockGasInclusionCheck.cs#L56-L57`, `TransactionProcessor.cs#L722-L725`, and `BlockReceiptsTracer.cs#L167-L209` (helper-mapped).
- **2D inclusion check** reserves `min(16,777,216, tx.gas)` in the execution dimension and `tx.gas` in the state dimension. Spec `vm/gas.py#L1073-L1085` → `Eip8037BlockGasInclusionCheck.cs#L41-L48` and `#L72-L73`. See C2 for the EIP-7928 gating.
- **Fork transition:** the base fee for the first Amsterdam block uses the stored `gas_used` of the pre-fork parent, with the same arithmetic order. Spec `fork.py#L387-L421` and `#L458` → `Nethermind.Core/BaseFeeCalculator.cs#L30-L50` (helper-mapped). All Amsterdam flags switch together at `Forks/25_Amsterdam.cs#L14-L27`.

## Public test status

- https://hive.ethpandaops.io (discovery.json and `/glamsterdam/listing.jsonl`, latest Nethermind rows):
  - `eels/consume-rlp`: 44,074 of 44,074 passed (nethermind `2.1.0-preview+0e33c03a`, 2026-09-26).
  - `eels/consume-engine`: 44,135 of 44,138 passed, **3 failures not inspected** (`2.1.0-preview+cc1cd4af`).
  - `eels/execute, hive mode`: 170 of 170.
  - These builds predate the pin.
- https://github.com/ethereum/execution-specs/issues/3518 (glamsterdam-devnet@v8.1.4, closed): an EIP-8037 release adding merge-time spill repayment, which Nethermind implements (`EthereumGasPolicy.cs#L173-L184`; see also NM PR https://github.com/NethermindEth/nethermind/pull/14160).
- https://github.com/ethereum/execution-specs/issues/3217 (tests@v21.0.0 tracker, open): mentions no Nethermind-specific EIP-8037 failure.

## Known-check queries run (GitHub search API, issues and PRs, open and closed)

- `repo:NethermindEth/nethermind 8037`
- `repo:NethermindEth/nethermind 8038`
- `repo:NethermindEth/nethermind 7778`
- `repo:NethermindEth/nethermind state gas negative`
- `repo:ethereum/execution-specs Test Release Tracker glamsterdam-devnet`

## URLs read

- https://eips.ethereum.org/EIPS/eip-8037, https://eips.ethereum.org/EIPS/eip-7778, https://eips.ethereum.org/EIPS/eip-8038 and https://eips.ethereum.org/EIPS/eip-7773, read as `EIPS/eip-*.md` from https://github.com/ethereum/EIPs at d4c575521d99ec881a444ab3af604e684b5f0743.
- https://github.com/ethereum/execution-specs/tree/7f2f4c9bf6d73b09ecb8b24eb14d08bf0cf0247b/src/ethereum/forks/amsterdam (`vm/gas.py`, `vm/instructions/*`, `vm/interpreter.py`, `vm/eoa_delegation.py`, `fork.py`, `transactions.py`, `state_tracker.py`). Also the `forks/amsterdam` and `mainnet` branches.
- https://github.com/NethermindEth/nethermind/tree/d48833af88ec4224c86afadd1c596e8f619c406b
- https://github.com/ethereum/go-ethereum/tree/8817f99f92852f8ac53e596de6202dd9e3494065 (`core/state_transition.go`, `core/gaspool.go`)
- https://api.github.com/search/issues (queries above)
- https://github.com/NethermindEth/nethermind/pull/13178, https://github.com/NethermindEth/nethermind/pull/14300, https://github.com/NethermindEth/nethermind/pull/14944, https://github.com/NethermindEth/nethermind/pull/14599 and https://github.com/NethermindEth/nethermind/pull/14160 (titles; body read for 13178 only)
- https://github.com/ethereum/execution-specs/issues/3217 and https://github.com/ethereum/execution-specs/issues/3518
- https://hive.ethpandaops.io/discovery.json and https://hive.ethpandaops.io/glamsterdam/listing.jsonl
