How to read this page
This is EIP-8037 with a commentary track. The proposal is dense and assumes you already hold a stack of other EIPs in your head — so each idea is shown twice.
The blue panels reproduce or faithfully paraphrase what EIP-8037 actually says — the parameters, formulas, tables, and rules. Numbers and code here match the EIP.
The teal panels are commentary: why the rule exists, what problem it solves, which other EIP it leans on, and where each magic number comes from.
References to other proposals look like EIP-8011 and link to the canonical text. Three widgets let you turn the dials yourself: a CPSB derivation, a cost calculator, and a reservoir model. Everything runs locally — no network needed.
The big picture
Before the details: hold these three sentences in your head and the whole EIP falls into place.
bytes_created × CPSB.
How the pieces fit
EIP-8037 sits at the center of a cluster of "make-Ethereum-scale-safely" proposals. It requires ten of them. Here they are, grouped by the role they play in 8037's design.
🧱 The metering foundation
The framework EIP-8037 instantiates and the charging model it borrows.
- EIP-8011 Multidimensional Gas Metering.Gives gas a 6-component cost vector and meters each block by its bottleneck resource. 8037 is the first concrete instance: it activates the state dimension.
- EIP-7928 Block-Level Access Lists.Splits state-opcode gas into pre-state (no DB needed) and post-state (needs a read) phases. 8037 reuses this two-phase model to decide when state-gas is charged.
🤝 The companion
The other half of the repricing; they cross-reference each other.
- EIP-8038 State-access Gas Cost Update.8037 prices state creation; 8038 prices state access (reads/writes to existing state). 8038 defines the regular-gas surcharges (
ACCOUNT_WRITE,CREATE_ACCESS,COLD_ACCOUNT_ACCESS) that ride alongside 8037's state-gas charges.
📦 Block-size & throughput levers
The sibling EIPs that make room to raise the gas limit. 8037 is the state-growth lever in this family.
- EIP-7825 Transaction Gas Limit Cap (2²⁴).Caps any tx at 16,777,216 gas. 8037 must work around this cap (see the reservoir) so deployments stay possible.
- EIP-7904 Compute Gas Cost Increase.Reprices underpriced compute opcodes/precompiles. Supplies the updated
PRECOMPILE_ECRECOVERused in 8037's auth-cost math. - EIP-7623 Increase Calldata Cost.Introduces the calldata floor. 8037's final
tx_gas_usedapplies this floor after refunds. - EIP-7976 Increase Calldata Floor Cost (64/64).Raises the 7623 floor further. Part of the same shrink-the-worst-case-block program.
- EIP-7981 Increase Access List Cost.Charges access-list data so it can't dodge the calldata floor. Same family.
- EIP-7778 Block Gas Accounting without Refunds.Stops refunds from letting a block exceed its real compute budget. 8037 specifies how its two-dimensional accounting composes with 7778.
👤 Account & state model
The rules that define what counts as new state — and a mispricing 8037 must patch.
- EIP-7702 Set Code for EOAs.A new state-creation vector: writing a 23-byte
0xef0100‖addrdelegation. 8037 must meter it, henceSTATE_BYTES_PER_AUTH_BASE = 23. - EIP-6780 SELFDESTRUCT only in same tx.Determines when an account is actually removed from state — which determines when state-gas should (not) be refilled.
- EIP-2780 Reduce intrinsic transaction gas.Fixes the mispricing 8037 creates: a value-transfer to a fresh account would be far cheaper than the new-account charge, so 2780 adds the surcharge back at the intrinsic level.
- EIP-161 State trie clearing.The canonical definition of an "empty"/"existent" account that 8037 uses to decide if a leaf is new.
- EIP-684 Revert on creation collision.Defines valid CREATE/CREATE2 targets — e.g. an address with balance but no code is a valid target whose leaf already exists.
- EIP-170 Contract code size limit (24,576 B).The 24 kB ceiling used in 8037's "deploy a max-size contract" cost examples.
⚙️ System contracts
Protocol-invoked contracts that write storage every block — 8037 raises their system-call gas limit so they don't break.
§Abstract
This proposal increases the cost of state creation operations, thus avoiding excessive state growth under increased block gas limits. It introduces a new variable, CPSB (cost per state byte), and sets this unit of gas cost per new state byte by targeting an average state growth of 120 GiB per year at a reference block gas limit of 150M gas units.
It also introduces an independent metering for state creation costs, thus allowing for increased throughput and for larger contract deployments without being limited by the single transaction gas limit.
The abstract quietly contains both halves of the EIP:
- A price. One unit —
CPSB— derived from a policy target ("don't grow state faster than 120 GiB/yr at a 150M limit"). Everything that makes state is charged in multiples of it. - A meter. State creation gets its own gas dimension, so the price can be cranked up without shrinking the budget for compute — and so the EIP-7825 per-tx cap stops blocking large deployments.
"Average state growth" and "reference gas limit" are the tell that CPSB is a policy knob, not a measured constant — unlike the benchmark-derived numbers in EIP-8038 / EIP-7904.
§Motivation
Two distinct problems: (a) state creation is priced inconsistently, and (b) under higher gas limits, unbounded state growth becomes the binding constraint on the whole network.
State creation does not have a harmonized cost. Contract deployment costs only ~200 gas/byte created, while new storage slots cost ~313 gas/byte. Deploying duplicated bytecode costs the same as new bytecode, even though clients don't store duplicated code in the database.
Gas is supposed to track real cost to a node. But a byte that lands in the state trie costs a node the same regardless of which opcode put it there. The pre-8037 schedule charges by opcode (a 20k flat SSTORE, a 200/byte code deposit) rather than by bytes-of-state, so identical disk impact carries different prices. EIP-8037's fix is to price the byte, not the opcode.
As of January 2026, a Geth node's state DB is ~390 GiB. After the gas limit went 30M → 60M, average new state per day more than tripled (~105 MiB → ~326 MiB), i.e. ~116 GiB/year.
The response is not linear: a 2× limit bump produced a ~3× jump in daily new state. Extrapolating to a 200M limit gives ~387 GiB/year — which from 390 GiB breaches the 650 GiB performance-degradation threshold in under a year.
The scary part is the super-linear response. Naively you'd assume 2× the gas → 2× the state. Reality was ~3×, because cheap state invites behavior that wasn't worth it before. So as the community pushes toward 150M–300M to scale L1, the state-growth curve bends upward faster than the limit does.
650 GiB is the soft wall where ordinary nodes start to degrade — and degraded nodes mean fewer people can run them, which is a decentralization problem, not just a UX one. This is the same scaling-safety program as 7825, 7623, 7904 — each removes one bottleneck that would otherwise cap the gas limit.
§New parameters
| Parameter | Value |
|---|---|
CPSB | 1530 |
STATE_BYTES_PER_STORAGE_SET | 64 |
STATE_BYTES_PER_NEW_ACCOUNT | 120 |
STATE_BYTES_PER_AUTH_BASE | 23 |
SYSTEM_MAX_SSTORES_PER_CALL | 16 |
CPSB = 1530— gas charged per byte of new state. Derived from the 120 GiB/yr @ 150M policy target →64— on-disk bytes for a new storage slot: 32-byte key hash + 32-byte value. Breakdown →120— on-disk bytes for a new account leaf (key + nonce + balance + codeHash + storageRoot).23— bytes for a 7702 delegation:0xef0100(3) + address (20).16— borrowed from 7002'sMAX_WITHDRAWAL_REQUESTS_PER_BLOCK; the most storage writes any system call is expected to do. Used here →
Notice the pattern: a state op's state-gas is always bytes × CPSB. The three "bytes" constants are the only per-op variation.
§Parameter changes
Every state-creating cost is re-expressed as bytes × CPSB charged to state-gas, plus a separate regular-gas charge for the transient work (hashing, account touch). The split is the whole point.
| Parameter | Current | New state-gas | New regular-gas | Ops |
|---|---|---|---|---|
GAS_CREATE | 32,000 | 120 × CPSB | CREATE_ACCESS | CREATE(2) |
GAS_CODE_DEPOSIT | 200/byte | CPSB /byte | 6 × ceil(len/32) | CREATE(2) |
GAS_NEW_ACCOUNT | 25,000 | 120 × CPSB | 0 | CALL, SELFDESTRUCT |
GAS_STORAGE_SET | 20,000 | 64 × CPSB | 0 | SSTORE |
PER_EMPTY_ACCOUNT_COST | 25,000 | 120 × CPSB | ACCOUNT_WRITE | 7702 deleg. |
PER_AUTH_BASE_COST | 12,500 | 23 × CPSB | REGULAR_PER_AUTH_BASE_COST | 7702 deleg. |
CREATE_ACCESS, ACCOUNT_WRITE, COLD_ACCOUNT_ACCESS are defined & valued in EIP-8038 (not yet final). REGULAR_PER_AUTH_BASE_COST = calldata (1,616) + ecRecover + cold account access + 2× warm access.
This table is the cleanest place to see the dimension split:
- New state-gas = the permanent cost of the byte sitting in everyone's database forever. Always
bytes × CPSB. - New regular-gas = the transient work that happens once: hashing the code (
6 × ceil(len/32)), touching/writing the account leaf (ACCOUNT_WRITE,CREATE_ACCESS).
Why charge regular-gas at all for a state op? Because writing to disk is real, parallelizable work that belongs on the throughput-metered axis. Only the long-term storage belongs on state-gas. (The Rationale is explicit: "any operation that grows the state should consume both.")
GAS_CODE_DEPOSIT dropping the duplicate-code subsidy and adding a hash cost reflects that clients dedupe identical bytecode — you pay CPSB/byte for the storage but a small hash fee for the compute.
§Multidimensional metering for state creation
Two gas dimensions are introduced: regular-gas and state-gas. "New state costs" go to state-gas; "new regular costs" and everything else go to regular-gas.
At the transaction level the user pays for both; the total cost is their sum. The EIP-7825 transaction gas limit applies only to regular-gas; state-gas is capped only by tx.gas.
At the block level, only the gas used in the bottleneck resource counts toward "is the block full?" and the base-fee update. Each of the block gas limit and target now bounds the bottleneck dimension, not a single combined counter.
EIP-8011 proposed the abstract machinery: give gas a cost vector, and meter the block by max() over dimensions instead of sum(). 8037 is the first EIP to actually switch one dimension on — state — and leaves the rest collapsed into "regular."
Why max() not sum()? A block is "full" when it would overload the network. Different resources overload independently: a block can be heavy on compute or heavy on new state. Summing them double-penalizes a tx that's heavy on one and light on the other. Metering each axis separately lets the builder pack a compute-heavy tx and a state-heavy tx into the same block — that's the throughput win.
The subtle, powerful consequence: you can raise the state price arbitrarily (to protect disk) and it never steals from the compute budget, because they're now separate axes.
sum ≥ limitmax(regular, state) ≥ limit§The reservoir model
A transaction has only one gas field, tx.gas. So how do you cap regular-gas at the 7825 limit while letting state-gas run higher? You split tx.gas into two buckets at the start, and drain them by different rules.
intrinsic_gas = intrinsic_regular_gas + intrinsic_state_gas
execution_gas = tx.gas - intrinsic_gas
regular_gas_budget = TX_MAX_GAS_LIMIT - intrinsic_regular_gas
gas_left = min(regular_gas_budget, execution_gas)
state_gas_reservoir = execution_gas - gas_left
Charging rules:
- Regular-gas charges deduct from
gas_leftonly. - State-gas charges deduct from
state_gas_reservoirfirst; when empty, fromgas_left. - Undoing a state creation refills the reservoir.
- The
GASopcode returnsgas_leftonly — the reservoir is invisible to it.
gas_left is clamped to at most TX_MAX_GAS_LIMIT − intrinsic_regular_gas. Any gas the user supplied beyond that cap can't be regular-gas — so it lands in state_gas_reservoir, where only state charges can reach it.
This statically enforces "regular-gas ≤ 7825 cap" with a single gas field. Running out of gas_left just looks like ordinary out-of-gas — no new error type. Meanwhile a giant contract deploy can pour, say, 38M of state-gas through the reservoir while its compute stays under the 16.7M cap.
Why hide the reservoir from GAS? Contracts use gasleft() to budget sub-calls; exposing reservoir gas would let a contract accidentally forward state-only gas into a compute context. (This is also the root of the ERC-4337 caveat.)
🪣 Try it — the reservoir split
Set a transaction's gas and its fixed (intrinsic) costs. Watch how tx.gas divides into the capped gas_left and the overflow state_gas_reservoir. TX_MAX_GAS_LIMIT = 16,777,216 (2²⁴), per EIP-7825.
§Gas accounting for SSTORE
| orig | cur | new | Description | State-gas |
|---|---|---|---|---|
| 0 | x | 0 | Cleared slot, zero at tx start | 64·CPSB refilled |
| 0 | 0 | x | New slot | 64·CPSB charged |
| x | x | 0 | Cleared, non-zero at tx start | no adjustment |
| x | 0 | x | Cleared slot restored | no adjustment |
| x/0 | y | z | All other writes to existing slot | no adjustment |
State-gas is charged exactly when a slot goes from "absent" to "present" in the trie, and refilled when that's undone within the same tx. The guiding question is always: "does a new leaf exist at the end of this transaction?"
- Row 2 (
0→0→x): a genuinely new slot → charge. - Row 1 (
0→x→0): a slot that was created and then zeroed in the same tx → no net new leaf → refill the charge. - Rows 3–5: the slot already existed at tx start (orig ≠ 0) or no creation happened → state size is unchanged → state-gas is untouched. Clearing an old slot is handled by the ordinary regular-gas refund in EIP-8038, not here.
This mirrors the classic EIP-2200 original/current/new state machine — but split so the creation piece lives on the new axis.
§Gas accounting for new accounts
| Operation | State-gas charged |
|---|---|
CALL* with value → non-existent account | 120·CPSB |
CREATE/CREATE2 size L → existent account | L·CPSB |
CREATE/CREATE2 size L → non-existent account | (120+L)·CPSB |
SELFDESTRUCT transfer creates new account | 120·CPSB |
An account is existent if it already has a leaf in the state trie per EIP-161 (nonzero balance, nonzero nonce, or non-empty code). An address with only a balance is existent and a valid EIP-684 CREATE target — so deploying there charges only L·CPSB.
Charged just before the call frame; refilled if the frame reverts/halts or the op fails before entering (insufficient balance, stack depth).
The whole table reduces to one rule: charge 120·CPSB only if a brand-new account leaf appears, and L·CPSB for the L bytes of code.
The 684/161 distinction is the interesting case: an address that someone pre-funded with ETH (balance, but no code, zero nonce) already has a leaf. Deploying a contract there updates that leaf rather than adding one — so you skip the 120-byte account charge and pay only for the code. The EIP is careful to get this right because counterfactual / pre-funded deployment addresses are common (think CREATE2 factories, smart-wallet deployment).
Charge-then-refill (rather than charge-on-success) keeps metering conservative: the gas must be reserved before the frame runs, so a tx can't sneak in a creation it didn't budget for. If the creation doesn't stick, the reservation comes back.
§SELFDESTRUCT, halts & reverts
For an account created in the same transaction, SELFDESTRUCT removes it (and its data) so it never lands in the trie — but this produces no state-gas refill, and no change to execution_state_gas_used.
For an account that existed before the tx, SELFDESTRUCT only transfers balance and the account is not removed — so no refill. This is consistent with EIP-6780.
This looks asymmetric with the SSTORE/CREATE refill rules — and it's deliberate. EIP-6780 already restricts real account deletion to the same-transaction-as-creation case. EIP-8037 chooses not to reward that path with a refill, because offering a refund for create-then-destroy would re-open exactly the kind of gas-refund gaming that 3529 and 7778 spent years closing. You paid to create; the transient work was real; no money back.
Revert: child-frame state changes roll back; state-gas charged in the child is refunded to the parent's state_gas_reservoir; remaining gas_left returns to the parent — standard EVM semantics. execution_state_gas_used decreases accordingly.
Exceptional halt: the reservoir resets to its value at the start of the child frame (all child state-gas refunded), and the child's gas_left is fully consumed.
Same rules apply at the top frame and for create-tx address collisions.
The mental model: state_gas_reservoir behaves like a second gas counter that obeys the same frame semantics gas always has. Revert → unused/charged-but-undone gas flows back up. Exceptional halt (e.g. invalid opcode, out-of-gas) → that frame's allotted gas_left is burned, but state-gas it never committed is still refunded, because the state change it would have caused didn't happen.
Keeping these aligned with existing semantics is what lets clients implement the second dimension without rewriting their call-frame machinery — a recurring design goal across 8011/8037 ("minimal changes to the protocol").
§Accounting for EIP-7702 authorizations
At intrinsic time, each 7702 authorization is charged the worst-case delegation cost. During processing, per authorization:
- If the authority's leaf already exists → refill the
120·CPSBportion to the reservoir, and refund theACCOUNT_WRITEportion. - If the authority's
codeHashis already a delegation, or the authorization is clearing the delegation (address == 0) → also refill the23·CPSBportion.
Because execution_state_gas_used starts at 0, these refills can push it negative before any execution charge; implementations may track the refill separately.
A 7702 authorization's true state impact depends on the authority's current on-chain state, which isn't known at intrinsic-gas time (before execution). Two unknowns:
- Does a fresh account leaf get created? (→ the 120-byte charge)
- Are the 23 delegation bytes genuinely new, or is the slot already a delegation / being cleared? (→ the 23-byte charge)
The EIP charges the maximum up front (new account + new delegation) and refunds whichever pieces turn out not to apply. This is the same conservative "reserve worst case, refill on discovery" pattern as the new-account rules — it guarantees a tx always pre-pays for the most state it could create.
This mirrors 7702's own structure, where PER_EMPTY_ACCOUNT_COST is charged then partially refunded if the authority already existed — 8037 just re-expresses that refund in the two-dimensional world.
§Pre/post-state validation & block-level accounting
EIP-7928 defines two-phase validation for state opcodes: pre-state costs (determinable without touching state) and post-state costs (need a state read).
Under 8037, the regular-gas portion follows 7928 unchanged and is charged at opcode time against gas_left. The state-gas portion is computed and deducted at the end of the opcode, drawing from the reservoir first, then gas_left. For SSTORE, the GAS_CALL_STIPEND pre-state check applies to gas_left only.
You can't know how much new state an opcode makes until you've read the current state (is the slot empty? does the account exist?). That's exactly 7928's post-state bucket. So 8037 naturally slots state-gas into the post-state phase — charged at end-of-opcode, once the answer is known — while the predictable warm/cold access fees stay in the pre-state phase on gas_left.
Excluding the reservoir from the GAS_CALL_STIPEND check keeps the 2,300-gas stipend's meaning intact: the stipend is about compute headroom, which lives in gas_left.
tx_state_gas = intrinsic_state_gas + execution_state_gas_used
tx_regular_gas = tx_gas_used_after_refund - tx_state_gas
block_regular_gas_used += tx_regular_gas
block_state_gas_used += tx_state_gas
gas_used = max(block_regular_gas_used, block_state_gas_used)
assert gas_used <= block.gas_limit
gas_used_delta = parent.gas_used - parent.gas_target
Receipt cumulative_gas_used tracks the per-tx tx_gas_used (post-refund, post-floor), so receipt[i] − receipt[i−1] is what tx i actually paid.
max() at the block, sum() at the wallet
This is the 8011 rule in code. The header's gas_used is the bottleneck dimension — the taller of the two bars — and that's what's checked against the limit and what drives the base fee. A user still pays the sum of their two dimensions, so UX is unchanged; only the block-fullness arithmetic differs.
The 7778 variant swaps tx_gas_used_after_refund for the pre-refund value, so refunds don't shrink the block's accounted compute — closing the same loophole 7778 targets, now per-dimension.
§System contracts & system transactions
SYSTEM_CALL_GAS_LIMIT =
30_000_000 + STATE_BYTES_PER_STORAGE_SET × CPSB × SYSTEM_MAX_SSTORES_PER_CALL
= 30_000_000 + 64 × 1530 × 16
= 31_566_720
Applies to system contracts invoked at block boundaries: 2935, 4788, 7002, 7251. SYSTEM_MAX_SSTORES_PER_CALL = 16 matches MAX_WITHDRAWAL_REQUESTS_PER_BLOCK (7002), the largest per-block write bound. The extra budget sits in the reservoir; system calls aren't subject to the 7825 cap and don't count against the block limit.
System contracts run with a fixed 30M gas budget every block. They write storage (a ring buffer of block hashes, beacon roots, a withdrawal queue…). If a storage write suddenly costs 64·CPSB = 97,920 state-gas instead of 20,000, a system call that used to fit in 30M might run dry — and a failing system call is a consensus problem, not a user inconvenience.
So 8037 hands them exactly enough extra headroom to absorb the worst case: 16 fresh slots × the new per-slot state cost. Pinning 16 to 7002's existing bound means the margin tracks the real worst case rather than a guess. Putting the surplus in the reservoir keeps it usable only for state, so the change can't silently expand their compute budget.
§Rationale — deriving CPSB
CPSB isn't measured; it's solved for. Pick a state-growth budget and a reference gas limit, assume the fee market sits at its target on average, and the cost-per-byte falls out by division.
Inputs: target 120 GiB/yr (= 128,849,018,880 B); reference limit 150M; 12s slots → 2,628,000 blocks/yr; average state-gas utilization 50% (the base fee equilibrates at the target = half the limit).
total_state_gas_per_year
= (150,000,000 / 2) × 2,628,000
= 1.971 × 10¹⁴ gas
CPSB = total_state_gas_per_year / target_bytes
= 1.971×10¹⁴ / 128,849,018,880
≈ 1530 gas / byte
- 50% utilization is the keystone. Under EIP-1559-style fees, the base fee pushes usage toward the target, which is half the limit. So on average only half a block's gas is available for state before the base fee bites — hence the
/2. - 150M reference is a deliberate middle ground between today's 60M and a hoped-for ~300M: high enough that
CPSBwon't need re-deriving immediately, low enough that the day-one price hike isn't brutal. - 120 GiB/yr is the policy choice — slow enough to keep nodes under the 650 GiB wall for years, given the ~390 GiB starting point.
Because it's a policy number, the EIP says plainly: if a future limit increase changes expected growth, just re-derive CPSB in a follow-up EIP. Turn the dials below to feel how sensitive it is.
🧮 Try it — derive CPSB yourself
Adjust the policy inputs. The EIP's defaults (120 GiB, 150M, 50%, 12s) give 1530. The lower table shows the equilibrium state growth this CPSB implies at other block limits — reproducing the EIP's worst-case table.
| Block limit | Equilibrium growth (GiB/yr) |
|---|
§Rationale — harmonization across state creation
Under current pricing, the gas cost to create one byte of state depends entirely on the method (intrinsic tx cost ignored):
| Method | Gas/byte |
|---|---|
| Deploy 24kB contract | ~200 |
| Fund fresh EOA with 1 wei | ~208 |
| Add delegate flag to funded EOA (7702) | ~219 |
| 7702 authorization to empty address | ~274 |
| Fill new storage slot (SSTORE 0→x) | ~313 |
Fix CPSB once, then derive each op's cost as bytes_created × CPSB (64/slot, 120/account, 23/auth).
The disk doesn't care whether a byte arrived via SSTORE or CODECOPY — but the gas schedule charged anywhere from 200 to 313 gas/byte for it, a ~1.5× spread with no physical justification. That spread is an arbitrage surface: rational actors route state creation through the cheapest opcode, distorting behavior for no reason.
8037 collapses the whole column to a single number, CPSB, and lets the only legitimate variable — how many bytes — set the price. Same disk impact, same cost, regardless of path. The bars below show the "before" spread snapping to one harmonized height (and rising to the level needed to actually bound growth).
💸 Try it — what does creating state cost now?
Pick an operation and see its state-gas under EIP-8037 (= bytes × CPSB), the multiple over today's cost, and the ETH price at a chosen base fee. EIP-8037's own table uses 0.08 Gwei (the post-60M-increase average).
State-gas only; EIP-8038 regular-gas surcharges (account write, hashing) apply on top.
§Rationale — where the byte counts come from
New account = 120 bytes
| Account hash (key) | 32 |
| Nonce | 8 |
| Balance | 16 |
| Code hash | 32 |
| Storage root | 32 |
| Total | 120 |
New slot = 64 B (32 key hash + 32 value). 7702 auth = 23 B (0xef0100 3 + address 20).
These count only the leaf payload + its keccak key — not intermediate trie nodes — so they're a lower bound on real growth.
The byte counts are the literal fields a client must persist for a new leaf, hashed key included. There's no fudge factor.
The footnote matters: real state growth is worse than these numbers, because inserting a leaf also rewrites intermediate trie nodes (branch/extension nodes, RLP encoding overhead). By pricing only the lower bound, 8037 errs toward under-charging — a conscious choice to avoid over-penalizing users while still bending the growth curve. If anything, it leaves room to raise CPSB later.
The 23-byte auth figure is why 7702 is in the requires list at all: the delegation indicator is a genuinely new kind of state, and it had to be assigned a byte cost like everything else.
§Rationale — EIP-7825 & the contract-size trap
EIP-7825 caps any transaction at TX_MAX_GAS_LIMIT = 16,777,216. If that cap applied to state-gas too, then with CPSB = 1530 the largest deployable contract would be only ~7.5 kB:
(16,777,216 − 21,000 − 5,000,000 − 120×1530) / 1530 ≈ 7,564 bytes
Fix: apply the 7825 cap to regular-gas only. This doesn't weaken 7825's scaling intent, because regular-gas meters everything that benefits from parallelization; state growth doesn't (it's a disk write, and that write's transient cost is already in regular-gas). The reservoir then carries the overflow state-gas.
This is the most elegant bit of the whole proposal. 7825 caps per-tx gas to bound worst-case block-validation time (a DoS / sync-time concern). 8037 makes state expensive. Stack them naively and you've accidentally banned contracts bigger than 7.5 kB — well under the EIP-170 24 kB limit. That would break real deployments.
The resolution rests on a clean principle: 7825's cap exists to bound the work that can't be parallelized away. Compute and the act of writing fit that. But the long-term cost of state existing doesn't threaten single-block validation time at all — it's a slow, cumulative, disk-capacity problem, governed by the block-level state-gas limit, not the per-tx cap. So state-gas is rightly exempt from 7825, and the reservoir is just the plumbing that delivers that exemption through a one-field gas API.
The example budgets 5M regular gas for constructor execution on top of the base costs — realistic for a heavy deploy — and still only clears ~7.5 kB without the fix.
Metering state separately also means raising state costs in line with the block limit won't shrink the gas available for everything else — yielding higher throughput, per the original argument in EIP-8011.
Put the pieces together and you get a virtuous loop: separate metering → state price can rise to whatever protects the disk → that price increase doesn't tax compute → so the block gas limit can keep rising for throughput → which is the original goal. 8037 isn't just a tax; it's the piece that makes future gas-limit increases safe on the state axis.
§Backwards compatibility
A backwards-incompatible repricing requiring a network upgrade. Wallets & nodes MUST update eth_estimateGas to account for state-gas, the reservoir model, and two-dimensional block accounting — or risk underestimating and producing failed txs. End users keep their workflows.
If implemented with EIP-7778, block accounting uses tx_gas_used_before_refund instead of the after-refund value.
Users won't notice the two dimensions — but eth_estimateGas absolutely must. A naive estimator that still thinks in one combined number could under-fund the state dimension and silently bounce transactions. This is the practical reason the EIP keeps the per-tx interface single-valued (tx.gas) even while the accounting is two-dimensional: minimize the blast radius on tooling.
Pre-signed, hardcoded-gas deployment factories (Nick's method @ 100k gas; ERC-2470, Create2Deployer, ImmutableCreate2Factory, CreateX) will no longer execute, because state-creation cost now exceeds their fixed gas limit.
Existing networks (mainnet, L2s) are unaffected — the factories are already deployed there. Only new networks (devnets/testnets) activating 8037 from genesis must regenerate the pre-signed txs or pre-deploy the factories at genesis.
Nick's-method factories rely on a transaction signed by a key nobody controls, with a gas limit frozen at signing time. You can't bump that gas limit without the key — so once deployment costs more than the frozen limit, that exact transaction is dead on any chain where it hasn't already run.
It's a non-issue for chains where these canonical addresses already exist, and a genesis-time chore for brand-new chains. The EIP flags it because so much tooling assumes CreateX et al. live at fixed addresses everywhere.
§Security considerations
Creating a new account now costs 120×CPSB (≈183,600 gas), but transferring ETH to a fresh account costs 21,000. Users could dodge the new-account charge by first sending a plain 21k transfer to instantiate the account.
EIP-2780 closes this: a non-create tx with value > 0 targeting a non-existent account adds GAS_NEW_ACCOUNT to intrinsic cost.
This is why 2780 is a hard dependency. The instant new accounts get expensive inside the EVM but a top-level value transfer that creates the very same account stays at 21k, you've built an arbitrage: route account creation through a cheap transfer. The same byte of state would have two wildly different prices again — re-introducing exactly the inconsistency harmonization set out to kill.
2780 restores the symmetry by charging the new-account surcharge at the transaction's entry point too, so every path that births an account pays the same. (2780 does much more — it overhauls intrinsic gas — but this surcharge is the part 8037 leans on.)
Optimal block construction now balances usage across two dimensions, not one. Sophisticated builders may extract an edge, raising centralization concerns. But greedy heuristics (fill until one dimension saturates) stay effective and keep building feasible for local/less-sophisticated builders.
One-dimensional block packing is "fill to the limit." Two dimensions turns it into a knapsack-flavored problem: you want to fill both the regular and state axes efficiently, and the most profitable mix is non-obvious. That's a real lever for sophisticated builders. The EIP's honest position is that the harm is bounded — simple "greedy until something saturates" still gets you most of the way — and this concern is inherited directly from 8011, which carries the same caveat.
The GAS opcode returns gas_left only and can't see the reservoir. Bundlers that meter sub-calls via gasleft() deltas (e.g. the ERC-4337 EntryPoint) can't attribute state-gas funded by the reservoir. Because all user-ops in a bundle share one reservoir, one op's state refunds can subsidize another's charges invisibly. Bundlers/EntryPoint MUST account for state-gas explicitly, not via gasleft() deltas.
Hiding the reservoir from GAS is what makes the reservoir model safe for ordinary contracts — but it has a cost. ERC-4337 account abstraction meters how much gas each user-operation consumes by sampling gasleft() before and after — and that sample is now blind to state-gas. Worse, the reservoir is shared across the whole bundle, so accounting done purely with gasleft() deltas can mis-attribute or cross-subsidize between users.
The mandate is therefore unavoidable: 4337 infrastructure must track state-gas charges and refills explicitly, out of band from gasleft(). It's a concrete example of how a clean protocol-level abstraction (one gas field, hidden reservoir) pushes complexity outward to the layers that were exploiting the old transparency.
§Glossary
The vocabulary EIP-8037 invents or repurposes.
- CPSB
- Cost Per State Byte = 1530 gas. The single unit; every state op's state-gas is
bytes × CPSB. - regular-gas
- The dimension that meters transient, parallelizable work — compute, access, the act of writing. Subject to the EIP-7825 per-tx cap.
- state-gas
- The dimension that meters permanent state growth. Charged at
bytes × CPSB; exempt from the 7825 cap; lives in the reservoir. - state_gas_reservoir
- A second per-tx gas bucket holding gas beyond the 7825 regular-gas budget. State charges drain it first; the
GASopcode can't see it. - gas_left
- The regular-gas bucket, clamped to
TX_MAX_GAS_LIMIT − intrinsic_regular_gas. WhatGAS/gasleft()returns. - bottleneck resource
- The dimension with the highest cumulative block gas.
block.gas_used = max(regular, state)drives fullness & base fee. - existent account
- Per EIP-161: has nonzero balance, nonzero nonce, or non-empty code — i.e. already has a state-trie leaf. Determines whether the 120-byte charge applies.
- STATE_BYTES_PER_*
- The per-op byte footprints:
NEW_ACCOUNT=120,STORAGE_SET=64,AUTH_BASE=23. - SYSTEM_MAX_SSTORES_PER_CALL
- 16 — the most new slots a system call should write, = 7002's
MAX_WITHDRAWAL_REQUESTS_PER_BLOCK. Sets the system-call gas headroom.
§All referenced EIPs
Everything EIP-8037 names, with one line on why. draft = still moving; final = shipped.
- 8011draft — Multidimensional Gas Metering. The framework 8037 instantiates.
- 8038draft — State-access gas update. Companion; defines the regular-gas surcharges.
- 7928draft — Block-Level Access Lists. Pre/post-state two-phase charging model.
- 7825final — Transaction Gas Limit Cap (2²⁴). The cap state-gas escapes via the reservoir.
- 7904draft — Compute Gas Cost Increase. Supplies updated
ECRECOVER. - 7778draft — Block Gas Accounting without Refunds. Composes with 8037's block accounting.
- 7702final — Set Code for EOAs. The 23-byte delegation state vector.
- 7623final — Increase Calldata Cost. The calldata floor 8037 applies post-refund.
- 7976draft — Increase Calldata Floor (64/64). Same block-shrinking family.
- 7981draft — Increase Access List Cost. Closes the calldata-floor bypass.
- 6780final — SELFDESTRUCT only in same tx. Governs when state is removed (→ refill rules).
- 2780draft — Reduce intrinsic tx gas. Patches the ETH-transfer mispricing 8037 creates.
- 161final — State trie clearing. Defines "empty"/"existent" accounts.
- 684final — Revert on creation collision. Valid CREATE targets.
- 170final — Contract code size limit (24,576 B).
- 2935final — Historical block hashes in state. System contract.
- 4788final — Beacon block root in the EVM. System contract.
- 7002final — EL-triggerable withdrawals. Source of the
16bound. System contract. - 7251final — MAX_EFFECTIVE_BALANCE / consolidations. System contract.
- ERC-4337— Account Abstraction. The bundler
gasleft()caveat.