---
eip: 8037
title: State Creation Gas Cost Increase
description: Harmonization, increase and separate metering of state creation gas costs to mitigate state growth and unblock scaling
author: Maria Silva (@misilva73), Carlos Perez (@CPerezz), Jochem Brouwer (@jochem-brouwer), Ansgar Dietrichs (@adietrichs), Łukasz Rozmej (@LukaszRozmej), Anders Elowsson (@anderselowsson), Francesco D'Amato (@fradamt)
discussions-to: https://ethereum-magicians.org/t/eip-8037-state-creation-gas-cost-increase/25694
status: Draft
type: Standards Track
category: Core
created: 2025-10-01
requires: 2780, 7702, 7825, 8011
---

## Abstract

This proposal increases the cost of state creation operations, thus avoiding excessive state growth under increased block gas limits. It dynamically sets the unit cost per new state byte at a given block gas limit, by targeting an average state growth of 100 GiB per year based on current network usage. 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.

## Motivation

State creation does not have a harmonized cost, with different methods incurring varied costs for creating the same size of new state. For instance, while contract deployment only costs 202 gas units per new byte created, new storage slots cost 625 gas units per new byte created. Also, deploying duplicated bytecode costs the same as deploying new bytecode, even though clients don't store duplicated code in the database. This proposal establishes a standard to harmonize all state creation operations.

Additionally, state growth will become a bottleneck for scaling under higher block limits. As of May 2025, the current database size in a Geth node dedicated to state is ~340 GiB. After the increase in gas limit from 30M to 36M gas units, the median size of new state created each day doubled, from ~102 MiB to ~205 MiB. This results in an annual growth of ~73 GiB per year.

![new_state_added](../assets/eip-8037/new_state_added.png)

The relationship we are seeing in this example is not linear as expected. This is likely due to other factors impacting user behavior. However, all else being equal, we expect a proportional increase in the number of new states created as gas limits increase. At a 60M gas limit (and a proportional increase in new state per day of 1.7x), we would see a daily state growth of ~349 MiB and a yearly state growth of ~124 GiB. Similarly, at a 100M gas limit, the state would grow at a rate of ~553 MiB per day and 197 GiB per year. This level of state growth would give us less than 2.5 years until the size of the state database exceeds the threshold of 650 GiB, at which point nodes will begin experiencing a degradation in performance.

## Specification

### New parameters

| **Parameter** | **Value** |
|:---:|:---:|
| `TARGET_STATE_GROWTH_PER_YEAR` | 100 × 1024^3 bytes |
| `CPSB_SIGNIFICANT_BITS` | 5 |
| `CPSB_OFFSET` | 9578 |

Besides these fixed parameters, this EIP introduces a dynamic variable that controls the cost per byte of state created for a given block gas limit. The variable is `cost_per_state_byte` and is calculated as follows:

```python
raw = ceil((gas_limit * 2_628_000) / (2 * TARGET_STATE_GROWTH_PER_YEAR))
shifted = raw + CPSB_OFFSET
shift = max(bit_length(shifted) - CPSB_SIGNIFICANT_BITS, 0)
cost_per_state_byte = max(((shifted >> shift) << shift) - CPSB_OFFSET, 1)
```

The raw value is the unquantized cost derived from targeting `TARGET_STATE_GROWTH_PER_YEAR` at 50% average gas utilization (see [Deriving the cost per byte](#deriving-the-cost-per-byte)). Quantization retains the top `CPSB_SIGNIFICANT_BITS` significant bits after applying `CPSB_OFFSET`, producing a stepped function that avoids frequent small changes as the gas limit fluctuates (see [Quantization](#quantization-of-cost_per_state_byte)).

### Parameter changes

Upon activation of this EIP, the following parameters of the gas model are updated. The "New State Gas" column shows the state gas cost (charged to the `state_gas` dimension), while the "New Regular Gas" column shows additional regular gas costs that accompany the state gas charge.

| **Parameter** | **Current** | **New State Gas** | **New Regular Gas** | **Operations affected** |
|---|---|---|---|---|
| `GAS_CREATE` | 32,000 | 112 × `cpsb` | 9,000 (assuming same as `GAS_CALL_VALUE`)  | `CREATE`, `CREATE2`, contract creation txs |
| `GAS_CODE_DEPOSIT` | 200/byte | `cpsb` per byte | `6 × ceil(len/32)` (hash cost) | `CREATE`, `CREATE2`, contract creation txs |
| `GAS_NEW_ACCOUNT` | 25,000 | 112 × `cpsb` | 0 (already has `GAS_CALL_VALUE` 9,000) | `CALL*` |
| `GAS_STORAGE_SET` | 20,000 | 32 × `cpsb` | 2,900 (`GAS_STORAGE_UPDATE - GAS_COLD_SLOAD`) | `SSTORE` |
| `PER_EMPTY_ACCOUNT_COST` | 25,000 | 112 × `cpsb` | 0 (included in `PER_AUTH_BASE_COST`) | EOA delegation |
| `PER_AUTH_BASE_COST` | 12,500 | 23 × `cpsb` | 7,500 | EOA delegation |

Where `cpsb` = `cost_per_state_byte`. The values assigned to regular gas will be updated based on [EIP-8038](./eip-8038.md).

The `PER_AUTH_BASE_COST` regular gas of 7,500 is derived from [EIP-7702](./eip-7702.md)'s cost analysis, excluding the code deployment cost (now charged as state gas):

- Calldata cost: ~1,616 (101 bytes × 16)
- Recovering authority address (ecrecover): 3,000
- Reading nonce and code of authority (cold access): 2,600
- Storing values in already warm account: 200
- ~~Code deployment cost: 4,600 (200 × 23)~~ → now in state gas

Total regular gas: 1,616 + 3,000 + 2,600 + 200 ≈ 7,500

In addition, `GAS_SELF_DESTRUCT_NEW_ACCOUNT` is removed and replaced by `GAS_NEW_ACCOUNT`.

### Multidimensional metering for state creation costs

Besides the parameter changes, this proposal introduces an independent metering for state creation costs. The specification is derived from [EIP-8011](./eip-8011.md). However, it only requires two dimensions, namely, `regular_gas` and `state_gas`. For state creation operations, the "new state costs" are charged to `state_gas`, while the "new regular costs" are charged to `regular_gas`. The costs of all other operations are also charged to `regular_gas`.

At transaction level, the user pays for both `regular_gas` and `state_gas`. The total gas cost of a transaction is the sum of both dimensions. In addition, the transaction gas limit set in [EIP-7825](./eip-7825.md) only applies to `regular_gas`, while `state_gas` is only capped by `tx.gas`.

At the block level, only the gas used in the bottleneck resource is considered when checking if the block is full and when updating the base fee for the next block. This gives a new meaning to the block’s gas limit and the block’s gas target, which now corresponds to the maximum gas that can be metered in the bottleneck resource.

#### Transaction validation

Before transaction execution, `calculate_intrinsic_cost` returns three values: `intrinsic_regular_gas`, `intrinsic_state_gas`, and `calldata_floor_gas_cost`. State gas components of intrinsic cost (e.g., account creation for contract deployment transactions, [EIP-2780](./eip-2780.md) charges, [EIP-7702](./eip-7702.md) authorization charges) are included in `intrinsic_state_gas`. All other intrinsic costs (base transaction cost, calldata, access lists, authorization base costs) are included in `intrinsic_regular_gas`.

`validate_transaction` rejects transactions where:

```python
max(intrinsic_regular_gas, calldata_floor_gas_cost) > TX_MAX_GAS_LIMIT
```

`validate_transaction` also returns `intrinsic_regular_gas`, `intrinsic_state_gas`, and `calldata_floor_gas_cost`.

#### Transaction-level gas accounting (reservoir model)

Since transactions have a single gas limit parameter (`tx.gas`), gas accounting is enforced through a **reservoir model**, in which `gas_left` and `state_gas_reservoir` are initialized as follows:

```python
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
```

The `state_gas_reservoir` holds gas that exceeds the [EIP-7825](./eip-7825.md)'s budget. The two counters operate as follows:

- **Regular gas** charges deduct from `gas_left` only.
- **State gas** charges deduct from `state_gas_reservoir` first; when the reservoir is exhausted, from `gas_left`. The charge increments `execution_state_gas_used` by its full amount regardless of whether it was satisfied from the reservoir, from `gas_left`, or partially from both; a state gas charge never increments `execution_regular_gas_used`.
- When an opcode requires both regular and state gas, the regular gas charge MUST be applied first. If the regular gas charge triggers an out-of-gas error, the state gas charge is not applied.
- The `GAS` opcode returns `gas_left` only (excluding the reservoir).
- The reservoir is passed **in full** to child frames (no 63/64 rule). On child success, the remaining `state_gas_reservoir` is returned to the parent and the child's `execution_state_gas_used` is added to the parent's `execution_state_gas_used`. On child **revert** or **exceptional halt**, all state gas consumed by the child, both from the reservoir and any that spilled into `gas_left`, is restored to the parent's `state_gas_reservoir`; the child's `execution_state_gas_used` is **not** added to the parent's `execution_state_gas_used`, because state changes are rolled back and no state was actually grown. On child **exceptional halt**, the child's `gas_left` is additionally consumed (zeroed).
- On **revert** or **exceptional halt** at the top level (no parent frame), all state gas consumed during execution — both from the `state_gas_reservoir` and any that spilled into `gas_left` — is restored to the `state_gas_reservoir`, and `execution_state_gas_used` is reset to zero, because state changes are fully reverted and no state was actually grown. This mirrors the child frame restoration: the sender is refunded the full execution state gas via the reservoir. On **exceptional halt** specifically, remaining `gas_left` is additionally set to zero (all regular gas consumed), consistent with existing EVM out-of-gas semantics. System transactions are not subject to the `TX_MAX_GAS_LIMIT` cap, their entire `execution_gas` is placed in `gas_left` with `state_gas_reservoir = 0`.

The two counters are returned by the transaction output. Besides the two counters, the EVM also keeps track of `execution_state_gas_used` and `execution_regular_gas_used` during transaction execution. `state_gas` costs are added to `execution_state_gas_used` while `regular_gas` costs are added to `execution_regular_gas_used`. These two counters are also returned by the transaction output.

#### Pre-state and post-state gas validation

[EIP-7928](./eip-7928.md) defines two-phase gas validation for state-accessing opcodes: pre-state costs (determinable without state access) and post-state costs (requiring state access). Pre-state validation must pass before any state access occurs. Under the reservoir model, both regular and state gas portions of pre-state costs must be satisfiable; regular gas is checked against `gas_left`, state gas against `state_gas_reservoir` (then `gas_left`). If either check fails, the state access does not occur.

The cost parameters introduced by this EIP map to validation phases as follows:

| Cost Parameter | Validation Phase | State Gas | Regular Gas |
|---|---|---|---|
| `GAS_CREATE` | Pre-state | 112 × `cpsb` | 9,000 |
| `GAS_CODE_DEPOSIT` | Post-state (on deployment success) | `cpsb` × L | 6 × ⌈L/32⌉ |
| `GAS_NEW_ACCOUNT` | Post-state (requires account existence check) | 112 × `cpsb` | 0 |
| `GAS_STORAGE_SET` | Post-state (requires reading current value) | 32 × `cpsb` | 2,900 |

For `SSTORE`, the `GAS_CALL_STIPEND` pre-state check ([EIP-7928](./eip-7928.md)) applies to `gas_left` only, excluding the `state_gas_reservoir`.

#### Transaction gas used

At the end of transaction execution, the gas used before and after refunds is defined as:

```python
tx_gas_used_before_refund = tx.gas - tx_output.gas_left - tx_output.state_gas_reservoir
tx_gas_refund = min(tx_gas_used_before_refund // 5, tx_output.refund_counter)
tx_gas_used_after_refund = tx_gas_used_before_refund - tx_gas_refund
```

The refund cap remains at 20% of gas used.

#### Block-level gas accounting

At block level, instead of tracking a single `gas_used` counter, we keep track of two counters, one for `state_gas` and one for `regular_gas`:

```python
tx_regular_gas = intrinsic_regular_gas + tx_output.execution_regular_gas_used
tx_state_gas = intrinsic_state_gas + tx_output.execution_state_gas_used

tx_gas_used = max(tx_gas_used_after_refund, calldata_floor_gas_cost)
block_output.block_regular_gas_used += max(tx_regular_gas, calldata_floor_gas_cost)
block_output.block_state_gas_used += tx_state_gas
```

Note: `tx_gas_used` applies the [EIP-7623](./eip-7623.md) calldata floor after refunds, so the floor can effectively negate part of a refund when `calldata_floor_gas_cost > tx_gas_used_after_refund`. The receipt `cumulative_gas_used` uses this post-floor value.

The block header `gas_used` field is set to:

```python
gas_used = max(block_output.block_regular_gas_used, block_output.block_state_gas_used)
```

The block validity condition uses this value:

```python
assert gas_used <= block.gas_limit, 'invalid block: too much gas used'
```

The base fee update rule is also modified accordingly:

```python
gas_used_delta = parent.gas_used - parent.gas_target
```

### `SSTORE` refund for slot restoration

When a storage slot is set to a non-zero value and then restored to zero within the same transaction (0 to X to 0 pattern), the state gas and regular gas refunds are handled separately:

- State gas: `32 × cost_per_state_byte` is refunded directly to `state_gas_reservoir` (and `execution_state_gas_used` is decremented). The refund happens immediately at the X to 0 SSTORE, not via `refund_counter`. This ensures the full state gas amount is returned regardless of the 20% refund cap.
- Regular gas: `GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS` is added to `refund_counter`, subject to the 20% cap.

The net cost after refund is `GAS_WARM_ACCESS`, consistent with pre-[EIP-8037](./eip-8037.md) `SSTORE` restoration behavior.

### State gas on frame failure

State gas is deducted at the point of the operation (`CREATE`, `CALL` to new account, EOA delegation). If the frame subsequently reverts or halts, the deduction is not undone within that frame — but the parent reclaims the child's consumed state gas via the reservoir restoration described above. At the top level, the same restoration applies: all consumed execution state gas (from the reservoir and any spillover from `gas_left`) is moved back into the `state_gas_reservoir`, and `execution_state_gas_used` is reset to zero. In both cases, state gas is refunded because state changes are reverted and no state was actually grown. This departs from pre-[EIP-8037](./eip-8037.md) behavior where `GAS_NEW_ACCOUNT` was consumed on revert, but is more consistent with the principle that state gas exclusively pays for long-term state growth.

### State gas refund on CREATE failure

`CREATE`/`CREATE2` charges `112 × cost_per_state_byte` upfront (pay-before-execute). If the creation fails at the opcode level before a child frame is entered — silent failures such as insufficient balance, nonce overflow, stack depth limit, or address collision — the account creation state gas is refunded to `state_gas_reservoir` (and `execution_state_gas_used` is decremented). No account was created, so no state gas should be paid. This preserves the pay-before-execute model while ensuring state gas is only consumed when state is actually created. Child frame revert and exceptional halt are handled by the general frame failure rule above.

### State gas refund on same-tx SELFDESTRUCT

When an account is created and self-destructed in the same transaction ([EIP-6780](./eip-6780.md)), the state does not persist. At the end of the transaction, when the actual account and storage removal occurs, all state gas for that account is refunded to `state_gas_reservoir` (and `execution_state_gas_used` is decremented). The refund scope includes:

- Account creation: `112 × cost_per_state_byte`
- Created storage slots: `32 × cost_per_state_byte` per non-zero slot
- Code deposit: `len(code) × cost_per_state_byte`

This refund must be applied before `tx_gas_used_before_refund` is computed so the sender is not charged for state that was destroyed. Storage slots that were restored to zero during execution (0 to X to 0) already have a final value of 0 and are not counted, avoiding a double refund with the SSTORE restoration refund.

### CALL with value to the selfdestructed account in the same transaction

When an account is created and then selfdestructed in the same transaction ([EIP-6780](./eip-6780.md)), deletion is deferred to the end of the transaction. During the transaction the account is still present in the state with a nonce of 1 from the CREATE, and is therefore neither empty nor nonexistent. A subsequent `CALL` with value to that address does **not** trigger a new account creation and therefore does **not** charge `GAS_NEW_ACCOUNT` state gas.

The end of the transaction destruction still removes the account regardless of any value received after the SELFDESTRUCT, so no persisted state results from the CALL. Any value transferred is burned when the account is destroyed. Combined with the same transaction SELFDESTRUCT refund above, the net state gas across the CREATE, SELFDESTRUCT, and CALL with value lifecycle is zero, matching the zero persisted state.

#### [EIP-7702](./eip-7702.md) authorizations

For [EIP-7702](./eip-7702.md) authorizations, the intrinsic state gas assumes account creation for each authorization: `(112 + 23) × cost_per_state_byte` per authorization. When an authorization targets an existing account (no account creation needed), the `112 × cost_per_state_byte` portion is refunded directly to `state_gas_reservoir` during authorization processing.

`intrinsic_state_gas` is immutable after transaction validation and is not modified by this refund. Block accounting uses the original worst-case `intrinsic_state_gas`; the refunded gas is reflected in the final `state_gas_reservoir` rather than in a mutated intrinsic value.

#### Receipt semantics

Receipt `cumulative_gas_used` tracks the cumulative sum of `tx_gas_used_after_refund` (post-refund, post-floor) across transactions, instead of the block's `gas_used`. This means `receipt[i].cumulative_gas_used - receipt[i-1].cumulative_gas_used` equals the gas paid by transaction `i`.

### Contract deployment cost calculation

When a contract creation transaction or opcode (`CREATE`/`CREATE2`) is executed, gas is charged differently based on whether the deployment succeeds or fails. Given bytecode `B` (length `L`) returned by initcode and `H = keccak256(B)`:

1. **When opcode execution starts:** Always charge `GAS_CREATE`
2. **During initcode execution:** Charge the actual gas consumed by the initcode execution
3. **Success path** (no error, not reverted, and `L ≤ MAX_CODE_SIZE`):
   - Charge `GAS_CODE_DEPOSIT * L` and persist `B` under `H`, then link `codeHash` to `H`
   - Charge `HASH_COST(L)` where `HASH_COST(L) = 6 × ceil(L / 32)` to compute `H`
4. **Failure paths** (REVERT, OOG/invalid during initcode, OOG during code deposit, or `L > MAX_CODE_SIZE`):
   - Do NOT charge `GAS_CODE_DEPOSIT * L` or `HASH_COST(L)`
   - No code is stored; no `codeHash` is linked to the account
   - The account remains unchanged or non-existent

**Important:** The gas for code deposit (`GAS_CODE_DEPOSIT * L`) is checked before hash computation. This means that if a deployment runs out of gas, it will fail during the deposit gas check before the hash is computed. This maintains consistency with post-Homestead behavior where any deployment failure (including OOG) reverts all state changes - no account is created, and no gas is charged beyond `GAS_CREATE` and the actual initcode execution cost consumed.

**Total gas formulas:**

```
SUCCESS_PATH_TOTAL_GAS =
    GAS_CREATE
  + initcode_execution_cost
  + GAS_CODE_DEPOSIT * L
  + HASH_COST(L)

FAILURE_PATH_TOTAL_GAS =
    GAS_CREATE
  + initcode_execution_cost
```

### `CREATE` vs `CREATE2`

`CREATE2` already charges for hashing the init code when deriving the address. That cost remains unchanged. The bytecode hash (`keccak256(B)`) must be computed on success to store the code, incurring `HASH_COST(L)` as specified above.

## Rationale

### Deriving the cost per byte

The variable `cost_per_state_byte` is a dynamic parameter that depends on the block gas limit. The idea is to have a cost that scales as the block gas limit increases, thus avoiding excessive state growth. To compute this variable, we target a specific state growth per year, which we set to 100 GiB. Then, we assume this growth rate is achieved at an average gas utilization.

With multidimensional metering, blocks can be filled up to 50% of the target for both regular gas and state gas. Thus, we consider that on average, blocks can use half of the entire available gas in the block for state creation. This leads to a total of `(gas_limit/2) * 7200 * 365` gas units used for state creation in a year. Dividing this by the target state growth per year gives us the cost per byte of state created.

### Quantization of `cost_per_state_byte`

Without quantization, `cost_per_state_byte` changes by 1 for every ~81,715 change in gas limit, which is 0.13% of the current block gas limit of 60M gas units. This creates unnecessary churn for tooling and gas estimation, since the cost can change almost every block even when the gas limit is relatively stable.

The quantization scheme retains the top 5 significant bits of `(raw + CPSB_OFFSET)`, zeroes the remaining bits, then subtracts `CPSB_OFFSET`. This is equivalent to binary floating-point rounding: each power-of-2 band has exactly 16 distinct levels, and the step size doubles at each band boundary while remaining perfectly uniform within a band.

The offset (`CPSB_OFFSET = 9578`) shifts quantization boundaries away from common gas limit targets. It was chosen by brute-force search over 0–10000 to maximize the minimum distance from any quantization boundary to gas limits from 100M to 1000M (in 50M increments). This prevents `cost_per_state_byte` from flipping between adjacent values due to small gas limit fluctuations near popular targets. The following table shows the resulting boundary distances:

| Gas Limit | `cost_per_state_byte` | Distance to boundary | Blocks to boundary |
| :---------: | :---------------------: | :--------------------: | :------------------: |
| 100M | 1,174 | 4.15% | 42.5 |
| 150M | 1,686 | 8.21% | 84.0 |
| 200M | 2,198 | 10.24% | 104.8 |
| 250M | 2,710 | 5.28% | 54.1 |
| 300M | 3,222 | 1.68% | 17.2 |
| 350M | 4,246 | 0.89% | 9.1 |
| 400M | 4,758 | 2.82% | 28.9 |
| 450M | 5,270 | 4.32% | 44.2 |
| 500M | 5,782 | 2.85% | 29.2 |
| 550M | 6,294 | 1.10% | 11.3 |
| 600M | 6,806 | 6.63% | 67.8 |
| 650M | 7,830 | 1.58% | 16.1 |
| 700M | 7,830 | 3.35% | 34.3 |
| 750M | 8,854 | 3.54% | 36.3 |
| 800M | 8,854 | 0.89% | 9.1 |
| 850M | 9,878 | 4.80% | 49.1 |
| 900M | 10,902 | 1.02% | 10.5 |
| 950M | 10,902 | 2.57% | 26.4 |
| 1000M | 11,926 | 2.55% | 26.2 |

The worst-case minimum distance is 0.89% of the gas limit (at 350M and 800M). Since the gas limit can deviate from its parent by at most 1/1024, `cost_per_state_byte` remains stable for at least ~9 consecutive blocks of same-direction gas limit changes at any gas limit in the 100M–1000M range (in 50M increments).

### Harmonization across state creation

With the current pricing, the gas cost of creating 1 byte of state varies depending on the method used. The following table shows the various methods and their gas cost per byte. The calculation ignores the transaction intrinsic cost (21k gas units) and the costs of additional opcodes and scaffolding needed to execute such a transaction.

| Method                                                      | What is written                                | Intrinsic gas                                                                                 | Bytes → state | Gas / byte |
| ----------------------------------------------------------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------- | ---------- |
| Deploy 24kB contract ([EIP-170](./eip-170.md) limit)        | Runtime code + account trie node               | 32,000 CREATE + 200 × 24,576 code deposit = 4,947,200 gas                | 24,688 B      | ~200 gas   |
| Fund fresh EOA with 1 wei                                   | Updated account leaf                           | 25,000 new account                                                                            | ~112 B        | ~223 gas   |
| Add delegate flag to funded EOA ([EIP-7702](./eip-7702.md)) | 23 B (0xef0100‖address) + updated account leaf | 25,000 PER_EMPTY_ACCOUNT + 12,500 PER_AUTH_BASE + 1,616 calldata - 7,823 refund = ~31,300 gas | ~135 B        | ~232 gas   |
| [EIP-7702](./eip-7702.md) authorization to empty address    | 23 B (0xef0100‖address) + updated account leaf | 25,000 PER_EMPTY_ACCOUNT + 12,500 PER_AUTH_BASE + 1,616 calldata = 39,116 gas                 | ~135 B        | ~289 gas   |
| Fill new storage slots (SSTORE 0→x)                         | Slot in storage trie                           | 20,000 gas/slot                                                                               | 32 B          | 625 gas    |

To harmonize costs, we first set the gas cost of a single state byte, `cost_per_state_byte`, as explained above. This is a dynamic parameter that depends on the block gas limit. Now that we have a standardized cost per byte, we can derive the various costs parameters by multiplying the unit cost by the increase in bytes any given operation creates in the database (i.e., 32 bytes per slot, 112 bytes per account and 23 bytes per authorization).

Note that the fixed cost `GAS_CREATE` for contract deployments assumes the same cost as a new account creation.

### Multidimensional metering

This proposal is consistent with [EIP-8011](./eip-8011.md). However, it only requires two dimensions, namely, `regular_gas` and `state_gas`. If [EIP-8011](./eip-8011.md) is not implemented, a two-dimensional version of [EIP-8011](./eip-8011.md) is still required.

#### EIP-7825 limit on contract size

[EIP-7825](./eip-7825.md) introduces `TX_MAX_GAS_LIMIT` (16.7M) as the maximum gas for a single transaction, in particular stipulating `tx.gas < TX_MAX_GAS_LIMIT`as a validity condition. Were we to continue enforcing this validity condition, with a block limit of 100M gas units, this proposal would limit the maximum contract size that can be deployed to roughly 9.9kB ($\frac{16,777,216 - 21,000 - 5,000,000 - 112 \times 1174}{1174} = 9'902$). This maximum size would only decrease as we increase the gas limit and the `cost_per_state_byte`.

To solve this issue, we only apply this gas limit to regular gas, not state gas. Doing so does not weaken the intended scaling effect of [EIP-7825](./eip-7825.md), because regular gas meters all resources that benefit from parallelization. In particular, state growth does not: growing the state always requires writing to disk, a parallelizable operation, but crucially this part of the cost of a state growth operation has to be metered in regular gas, not state gas. In other words, any operation that grows the state should consume both regular gas and state gas, and the regular gas should fully account for all costs other than the long term effect of growing the state.

However, we cannot statically enforce a regular gas consumption of `TX_MAX_GAS_LIMIT`, while still allowing a higher state gas consumption, because transactions only have a single gas limit parameter, `tx.gas`. This is solved through a **reservoir model**: at transaction start, execution gas is split into `gas_left` (capped at `TX_MAX_GAS_LIMIT - intrinsic_regular_gas`) and a `state_gas_reservoir` (the overflow). State gas charges draw from the reservoir first, then from `gas_left` when the reservoir is empty. Regular gas charges draw from `gas_left` only. Exceeding the regular gas budget behaves identically to running out of gas — no special error is needed.

#### Higher throughput

Another advantage of metering contract creation separately is that increasing the cost of state creation operation in line with the block limit will not affect the available gas for other operations. This allows for higher throughput, as explained in the original multidimensional gas metering introduced in [EIP-8011](./eip-8011.md).

## Backwards Compatibility

This is a backwards-incompatible gas repricing that requires a scheduled network upgrade.

Wallet developers and node operators MUST update gas estimation handling to accommodate the new calldata cost rules. Specifically:

- Wallets: Wallets using `eth_estimateGas` MUST be updated to ensure that they correctly account for the updated gas parameters. Failure to do so could result in underestimating gas, leading to failed transactions.
- Node Software: RPC methods such as `eth_estimateGas` MUST incorporate the updated formula for gas calculation with the new floor cost values.

Users can maintain their usual workflows without modification, as wallet and RPC updates will handle these changes.

### Estimated price impacts at various block gas limits

Users and dApp developers will experience an increase in transaction costs associated with creating a new state. The next table summarizes the state creation costs for common operations at different block gas limits.

| Case | cost_per_state_byte | Cost of a new account | Cost increase | Cost of a new slot | Cost increase | 24kB contract deployment | Cost increase |
|:---:|:---:|---|---|---|---|---|---|
| Current cost | NA | 25,000 | NA | 20,000 | NA | 4,947,200 | NA |
| Proposed cost at 60M block limit | 662 | 74,144 | 3 | 24,084 | 1 | 16,357,064 | 3 |
| Proposed cost at 100M block limit | 1,174 | 131,488 | 5 | 40,468 | 2 | 28,997,320 | 6 |
| Proposed cost at 200M block limit | 2,198 | 246,176 | 10 | 73,236 | 4 | 54,277,832 | 11 |
| Proposed cost at 300M block limit | 3,222 | 360,864 | 14 | 106,004 | 5 | 79,558,344 | 16 |

We should note that as the block limit increases, the base fee is expected to reduce due to the higher capacity of the network. This reduction in base fee will offset, in part, the costs from state creation operations. Some analysis is needed to quantify this effect.

## Security Considerations

Increasing the cost of state creation operations could impact the usability of certain applications. More analysis is needed to understand the potential effects on various dApps and user behaviors.

### Mispricing with respect to ETH transfers

One potential concern is the cost of creating a new account (`112 × cost_per_state_byte` gas units, e.g., 131,488 at a 100M gas limit), compared to transferring ETH to a fresh account (21,000 gas units). With this mismatch, users wishing to create new account are incentivized to first send a normal transaction (costing 21k) to this account to create it, thus avoiding the `GAS_NEW_ACCOUNT` charge.

[EIP-2780](./eip-2780.md) solves this mispricing by adding a new component to the intrinsic gas cost of transactions. If a non-create transaction has value > 0 and targets a non-existent account, the `GAS_NEW_ACCOUNT` is added to intrinsic cost.

### Added complexity in block building

Optimal block construction becomes more complex, since builders must now balance resource usage across multiple dimensions rather than a single gas metric. Sophisticated builders may gain an advantage by applying advanced optimization techniques, raising concerns about further builder centralization. However, practical heuristics (e.g., greedily filling blocks until one resource dimension saturates) remain effective for most use cases. These heuristics limit centralization pressure by keeping block construction feasible for local and less sophisticated builders.

### Testing requirements for increasing block limits

With a dynamic cost per byte, every time the block gas limit is increased, clients and testing frameworks need to test for backward compatibility issues. This changes the testing framework for increasing the block limit. A way to mitigate this is to introduce a max cost per byte and do the analysis once on the impact of this max cost.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
