---
eip: 8038
title: State-access gas cost update
description: Increases the gas cost of state-access operations to reflect Ethereum’s larger state
author: Maria Silva (@misilva73), Wei Han Ng (@weiihann), Ansgar Dietrichs (@adietrichs)
discussions-to: https://ethereum-magicians.org/t/eip-8038-state-access-gas-cost-update/25693
status: Last Call
last-call-deadline: 2026-11-01
type: Standards Track
category: Core
created: 2025-10-03
requires: 8037
---

## Abstract

This EIP updates the gas cost of state-access operations to reflect Ethereum's larger state and the consequent slowdown of these operations. It dissects the cost of state-touching operations into three components — access, write, and state creation: the cold account access cost (`COLD_ACCOUNT_ACCESS`) is raised, explicit write surcharges (`ACCOUNT_WRITE`, `STORAGE_WRITE`) are introduced, state-creation costs are left to [EIP-8037](./eip-8037.md), and `EXTCODESIZE` and `EXTCODECOPY` are charged for their second database read.

## Motivation

The gas price of accessing state has not been updated for quite some time. [EIP-2929](./eip-2929.md) was included in the Berlin fork in March 2021 and raised the costs of state-accessing opcodes. Yet, since then, Ethereum's state has grown significantly, thus deteriorating the performance of these operations. This proposal further raises state access costs to better align them with the current performance of state access operations, in relation to other operations.

Additionally, `EXTCODESIZE` and `EXTCODECOPY` have the same access cost as `BALANCE` and `EXTCODEHASH`. However, `EXTCODESIZE` and `EXTCODECOPY` require two database reads - first to load the account object (which includes the `nonce`, `balance`, `codeHash` and `storageRoot`), and second to collect the required information (the code size and bytecode respectively). Therefore, the access cost of `EXTCODESIZE` and `EXTCODECOPY` should be higher when compared with the other account read operations.

## Specification

### Cost components

The gas cost of a state-touching operation is the sum of up to three independent components:

1. **Access** — the cost of loading an account or storage slot from the database: `COLD_ACCOUNT_ACCESS`, `COLD_STORAGE_ACCESS` and `WARM_ACCESS`, renamed by this EIP from the [EIP-2929](./eip-2929.md) parameters. This EIP raises `COLD_ACCOUNT_ACCESS`, while `COLD_STORAGE_ACCESS` and `WARM_ACCESS` are unchanged; the [EIP-2929](./eip-2929.md) rules that determine whether an access is cold or warm are unchanged.
2. **Write** — the cost of writing an object's leaf values when they change, whether or not the leaf already exists: `STORAGE_WRITE` for a storage slot and `ACCOUNT_WRITE` for an account's leaf values (nonce, balance, code hash), both introduced by this EIP. The pre-existing schedule has no standalone constant for this component; it is fused into composites such as `GAS_STORAGE_UPDATE` ([EIP-2200](./eip-2200.md)'s `SSTORE_RESET_GAS`), `CALL_VALUE` (the Yellow Paper's `G_callvalue`) and `GAS_CREATE` (`G_create`). The two write surcharges follow different charging disciplines, stated once here and applying everywhere below:
   - `STORAGE_WRITE` is net-metered within a transaction: it is charged by each `SSTORE` that moves a slot away from its transaction-start value and credited back by each later `SSTORE` that restores that value (refund rule 3 below), so a slot that ends the transaction with a changed value pays it exactly once and a slot that ends unchanged pays only access costs, subject to the refund cap.
   - `ACCOUNT_WRITE` is charged per operation that writes an account's leaf values. For every operation specified in this EIP there is no per-account tracking and no refund: a value-bearing `CALL` to the same recipient pays it on each call. ([EIP-2780](./eip-2780.md) charges it at most once per authority per transaction when processing [EIP-7702](./eip-7702.md) authorizations; that first-write rule is defined there and applies only to authorization processing.)
3. **State creation** — the cost of adding a new leaf to the state: `GAS_STORAGE_SET` for a new storage slot and `GAS_NEW_ACCOUNT` for a new account. This EIP does not reprice these constants; they are repriced by [EIP-8037](./eip-8037.md) and charged to its state-gas dimension. This EIP states where the component applies so that each operation's complete cost is visible in one place.

The sections below specify each operation as a consumer of this model: which access cost applies, whether and when a write surcharge applies, and which state-creation charge accompanies it.

### Parameters

Upon activation of this EIP, the following parameters of the gas model are introduced/updated:

| **Parameter** | **Component** | **Description** | **Current value** | **New value** | **Increase** | **Operations affected** |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| `COLD_ACCOUNT_ACCESS` | Access | Cold touch of an account. Renamed from `COLD_ACCOUNT_ACCESS_COST` ([EIP-2929](./eip-2929.md)) | 2,600 | 3,000 | +15% | `*CALL` opcodes, `BALANCE`, `SELFDESTRUCT`, `EXT*` opcodes, EOA delegation resolution, EOA delegation setting (5), contract creation txs / `CREATE` / `CREATE2` (4), and ETH transfers |
| `COLD_STORAGE_ACCESS` | Access | Cold touch of a storage slot. Renamed from `COLD_SLOAD_COST` ([EIP-2929](./eip-2929.md)) | 2,100 | 2,100 | +0% | `SSTORE` and `SLOAD` |
| `WARM_ACCESS` | Access | Touch of an already-warm account or storage slot. Renamed from `WARM_STORAGE_READ_COST` ([EIP-2929](./eip-2929.md)) | 100 | 100 | +0% | `SSTORE`, `SLOAD`, `*CALL` opcodes, `BALANCE`, `EXT*` opcodes, EOA delegation resolution, EOA delegation setting (5) |
| `ACCOUNT_WRITE` | Write | Write to an account's leaf values (nonce, balance, code hash); charged per operation. New named parameter (previously embedded in `CALL_VALUE`, see footnote 1) | 6,700 (1) | 9,000 | +34% | value-transferring `*CALL` opcodes, `SELFDESTRUCT`, contract creation txs / `CREATE` / `CREATE2` (4), EOA delegation setting |
| `STORAGE_WRITE` | Write | Write that changes a storage slot's value; net-metered per transaction. New named parameter (previously derived, see footnote 2) | 2,800 (2) | 10,000 | +257% | `SSTORE` |
| `CREATE_ACCESS` | Access + write | Combined access-and-write cost of contract deployment: `ACCOUNT_WRITE` + `COLD_ACCOUNT_ACCESS`. New named parameter (previously derived, see footnote 3) | 7,000 (3) | 12,000 | +71% | contract creation txs / `CREATE` / `CREATE2` |
| `STORAGE_CLEAR_REFUND` | Refund | Refund for clearing a storage slot. Renamed from `SSTORE_CLEARS_SCHEDULE` ([EIP-3529](./eip-3529.md)) | 4,800 | 11,616 | +142% | `SSTORE` |
| `ACCESS_LIST_STORAGE_KEY_COST` | Access (prepaid) | Gas charged per storage key included in a transaction's access list. Unchanged name from [EIP-2930](./eip-2930.md) | 1,900 | 2,000 | +5% | `SSTORE` and `SLOAD` |
| `ACCESS_LIST_ADDRESS_COST` | Access (prepaid) | Gas charged per address included in a transaction's access list. Unchanged name from [EIP-2930](./eip-2930.md) | 2,400 | 2,900 | +21% | `*CALL` opcodes, `BALANCE`, `SELFDESTRUCT` and `EXT*` opcodes |

(1): 6,700 = `CALL_VALUE` (the Yellow Paper's `G_callvalue`, 9,000) - `CALL_STIPEND` (`G_callstipend`, 2,300)

(2): 2,800 = `GAS_STORAGE_UPDATE` ([EIP-2200](./eip-2200.md)'s `SSTORE_RESET_GAS`, 5,000) - `GAS_COLD_SLOAD` (2,100) - `GAS_WARM_ACCESS` (100)

(3): 7,000 = `GAS_CREATE` (the Yellow Paper's `G_create`, 32,000) - `GAS_NEW_ACCOUNT` (`G_newaccount`, 25,000)

(4): Charged only as part of `CREATE_ACCESS`, not separately — these operations pay `CREATE_ACCESS` once, and never `COLD_ACCOUNT_ACCESS` or `ACCOUNT_WRITE` on top of it. The `CREATE`/`CREATE2` charge is specified in the `CREATE`/`CREATE2` section below; the contract-creation transaction charge is specified in [EIP-2780](./eip-2780.md).

(5): Charged only as part of [EIP-8037](./eip-8037.md)'s `EXECUTION_PER_AUTH_BASE_COST`. Setting a delegation is distinct from resolving one: resolution loads the delegation target's code at runtime and is charged the standard cold or warm access directly.

`ACCOUNT_WRITE`, `STORAGE_WRITE` and `CREATE_ACCESS` are new parameters with no pre-existing counterpart; their "Current value" column shows the equivalent cost extracted from the pre-existing composite constants per the footnotes above. The pre-existing schedule is not exactly separable into these components, so these equivalents are approximate: footnote 2 yields the write component of the current warm-case `SSTORE` charge exactly (2,900 = `GAS_WARM_ACCESS` + 2,800), while the cold-case charge of 5,000 exceeds the sum of its components by 100; footnote 3 is discussed in the `CREATE`/`CREATE2` section below.

### `SSTORE` pricing

In addition, the `SSTORE` cost formula is updated. As in [EIP-2200](./eip-2200.md), the *original value* is the slot's value at the start of the current transaction and the *current value* is its value just before the `SSTORE` executes. The complete `SSTORE` charge is the sum of its three cost components:

1. Access component: `COLD_STORAGE_ACCESS` or `WARM_ACCESS`, depending on whether the storage slot is cold or warm.
2. Write component: additionally charge `STORAGE_WRITE` if the new value is different from the current value and the current value equals the original value (the write moves the slot away from its transaction-start value).
3. State-creation component: additionally charge `GAS_STORAGE_SET` (per [EIP-8037](./eip-8037.md), metered in state-gas) if the original value is zero, the current value is zero, and the new value is non-zero.

Refunds are also updated as follows. Each rule is an adjustment to the transaction's refund counter and is evaluated on every `SSTORE`:

1. `STORAGE_CLEAR_REFUND` is added if the original value is non-zero, the current value is non-zero and the new value is zero (a slot is cleared).
2. `STORAGE_CLEAR_REFUND` is subtracted if the original value is non-zero, the current value is zero and the new value is non-zero (a slot that was cleared earlier in the same transaction is set to a non-zero value again, whether or not that value is its original one). This reverses the refund granted by rule 1, so that clearing and then re-setting a slot within the same transaction is never net-profitable.
3. `STORAGE_WRITE` is refunded if the new value equals the original value and differs from the current value (a change made earlier in the same transaction is undone, restoring the slot's transaction-start value).

Rules 2 and 3 mirror the refund accounting of [EIP-2200](./eip-2200.md) and [EIP-3529](./eip-3529.md) for slots that are modified more than once within a transaction: a `STORAGE_WRITE` charge or `STORAGE_CLEAR_REFUND` granted on an earlier `SSTORE` to the same slot is undone when a later `SSTORE` returns the slot to its original value. Without these reversals, a round trip such as `x → 0 → x` would yield a net refund even though the slot ends the transaction unchanged. Net over the whole transaction, a slot that ends at a changed value pays its write and state-creation components exactly once, and a slot that ends at its original value pays only its access costs — in both cases regardless of how often the slot was written, and subject to the refund cap.

These refunds go to the transaction's refund counter and are capped to 20% of the total gas used by the transaction, as per the current refund mechanism.

The rules for state creation cost charges and refills are addressed in [EIP-8037](./eip-8037.md).

Cases and their corresponding costs are detailed in the table below:

| Original value | Current value | New value | Access status | Description | Execution-gas charges/refunds | State-gas charges/refills |
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| 0 | 0 | x | Cold | New slot | `COLD_STORAGE_ACCESS` + `STORAGE_WRITE` charged | `GAS_STORAGE_SET` charged |
| 0 | 0 | x | Warm | New slot | `WARM_ACCESS` + `STORAGE_WRITE` charged | `GAS_STORAGE_SET` charged |
| x | x | y | Cold | Existing slot, first change | `COLD_STORAGE_ACCESS` + `STORAGE_WRITE` charged | no state-gas adjustments |
| x | x | y | Warm | Existing slot, first change | `WARM_ACCESS` + `STORAGE_WRITE` charged | no state-gas adjustments |
| x | x | 0 | Cold | Cleared slot, non-zero at transaction start | `COLD_STORAGE_ACCESS` + `STORAGE_WRITE` charged, `STORAGE_CLEAR_REFUND` refunded | no state-gas adjustments |
| x | x | 0 | Warm | Cleared slot, non-zero at transaction start | `WARM_ACCESS` + `STORAGE_WRITE` charged, `STORAGE_CLEAR_REFUND` refunded | no state-gas adjustments |
| 0 | x | 0 | Warm | Set slot reset to zero (zero at transaction start) | `WARM_ACCESS` charged, `STORAGE_WRITE` refunded | `GAS_STORAGE_SET` refilled |
| 0 | x | y | Warm | Slot set earlier in the transaction written to a different non-zero value | `WARM_ACCESS` charged | no state-gas adjustments |
| x | y | x | Warm | Previously-modified slot reset to original value | `WARM_ACCESS` charged, `STORAGE_WRITE` refunded | no state-gas adjustments |
| x | y | 0 | Warm | Previously-modified slot cleared, non-zero at transaction start | `WARM_ACCESS` charged, `STORAGE_CLEAR_REFUND` refunded | no state-gas adjustments |
| x | 0 | x | Warm | Cleared slot restored to original value | `WARM_ACCESS` charged, `STORAGE_WRITE` refunded, `STORAGE_CLEAR_REFUND` reversed | no state-gas adjustments |
| x | 0 | y | Warm | Cleared slot written to a new non-zero value | `WARM_ACCESS` charged, `STORAGE_CLEAR_REFUND` reversed | no state-gas adjustments |
| x | y | z | Warm | Previously-modified slot written to another non-zero value | `WARM_ACCESS` charged | no state-gas adjustments |

### Account access pricing

The [EIP-2929](./eip-2929.md) rules that determine whether an account access is cold or warm are unchanged; this EIP raises the cold access cost and states explicitly, per operation below, where the write and state-creation components apply.

#### `CALL`/`CALLCODE`

For `CALL` and `CALLCODE` operations, `CALL_VALUE` (the Yellow Paper's `G_callvalue`) is redefined as `ACCOUNT_WRITE + CALL_STIPEND`, where `CALL_STIPEND` (`G_callstipend`, 2,300) is unchanged. `ACCOUNT_WRITE` here prices the write to the recipient's balance leaf and, per its charging discipline, is paid on every value-transferring call. The state-creation component of a value-transferring `CALL` to a dead account (as defined in [EIP-161](./eip-161.md)) is `GAS_NEW_ACCOUNT`, which this EIP does not reprice; it is repriced and metered in state gas by [EIP-8037](./eip-8037.md). `CALLCODE` never incurs it: its recipient is the calling account itself, which already exists.

#### `CREATE`/`CREATE2`

`CREATE` and `CREATE2` operations don't have explicit warm/cold pricing. Instead, the flat `GAS_CREATE` (the Yellow Paper's `G_create`, 32,000) is replaced by `CREATE_ACCESS`, charged in execution gas, plus `GAS_NEW_ACCOUNT`, charged in state gas (per [EIP-8037](./eip-8037.md)). `CREATE_ACCESS`, defined as `ACCOUNT_WRITE` + `COLD_ACCOUNT_ACCESS`, is the combined access-and-write component of the deployment; `GAS_NEW_ACCOUNT` is its state-creation component and is not repriced by this EIP.

Note: this definition does not exactly match the legacy decomposition shown in footnote 3 of the Parameters table (`GAS_CREATE` - `GAS_NEW_ACCOUNT` = 7,000). The pre-existing accounting in the protocol is not internally consistent here, and this EIP keeps the discrepancy rather than attempting to reconcile it.

#### `SELFDESTRUCT`

For `SELFDESTRUCT`, charge `COLD_ACCOUNT_ACCESS` in execution gas if the beneficiary is cold, regardless of the balance being transferred. A warm beneficiary incurs no access charge: the [EIP-2929](./eip-2929.md) exemption from `WARM_ACCESS` is preserved, including when the beneficiary is the executing account itself or a precompile. The opcode base cost and the rules for determining and updating the beneficiary's cold or warm status are unchanged.

For `SELFDESTRUCT`, an additional charge of `ACCOUNT_WRITE` is added if a positive balance is sent to a dead account (as defined in [EIP-161](./eip-161.md)) — the write component of creating the beneficiary's leaf. The state-creation component in this same case is `GAS_NEW_ACCOUNT`, which remains in place alongside the new `ACCOUNT_WRITE` charge and is metered in state-gas by [EIP-8037](./eip-8037.md).

#### `EXT*` family update

Besides the current access costs, `EXTCODESIZE` and `EXTCODECOPY` are charged an additional `WARM_ACCESS`.

#### Overview

The cases for account-related operations and their corresponding cost components are summarized in the table below. The state-creation column is charged in state-gas and is not repriced by this EIP (see [EIP-8037](./eip-8037.md)).

| Operation | Access component | Write component (`ACCOUNT_WRITE`) | State-creation component |
| :--- | :---: | :--- | :--- |
| `CALL` / `CALLCODE` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | when value is transferred (via `CALL_VALUE` = `ACCOUNT_WRITE` + `CALL_STIPEND`) | `GAS_NEW_ACCOUNT` when `CALL` transfers value to a dead account; never for `CALLCODE`, whose recipient is the calling account |
| `DELEGATECALL` / `STATICCALL` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never (no value transfer) | — |
| `CREATE` / `CREATE2` | folded into `CREATE_ACCESS` | always (folded into `CREATE_ACCESS` = `ACCOUNT_WRITE` + `COLD_ACCOUNT_ACCESS`, replacing `GAS_CREATE`) | `GAS_NEW_ACCOUNT`, plus the per-byte code-deposit cost |
| `SELFDESTRUCT` | `COLD_ACCOUNT_ACCESS` if cold; zero if warm | when a positive balance is sent to a dead account | `GAS_NEW_ACCOUNT` in the same case |
| `BALANCE` / `EXTCODEHASH` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never | — |
| `EXTCODESIZE` / `EXTCODECOPY` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS`, plus `WARM_ACCESS` for the second database read | never | — |

## Rationale

### Empirical Estimation of Gas Costs

The [supporting gas cost report](../assets/eip-8038/gas-cost-report.md) contains the latest evm-gasfit runtime and glue-opcode reports, the gas estimates converted at 75 Mgas/s, and a comparison with the values selected in this EIP.

#### Data Collection

The gas costs proposed in this EIP are based on the actual time each execution client takes to run a specific set of benchmarks. Similar to the methodology used in the Gas Cost Estimator project, we generate synthetic blocks that isolate and stress individual EVM operations and use them to derive the various gas parameters.

Concretely, to benchmark a single operation/parameter, different blocks are created by varying the number of times the target operation is executed and by changing the parameter values to the operation. The EEST benchmark suite contains the tests used to generate these blocks.

Then, the `Benchmarkoor` tool is used to collect the needed metrics. This tool returns the total execution time of the block and the number of times each operation was executed. Each test block is run multiple times on each client to account for variability in execution time.

All benchmarks were run on top of a snapshot with the same size as mainnet in March 2026, so they reflect the current performance of state access operations.

**What about differences between client implementations?**

Ultimately, we require a single cost model that is independent of the client's implementation. Although the decision may be different in a specific situation, the general rule is to take the worst client result that cannot be optimized. This means that the worst-performing client on a given operation and resource combination will define the cost of that operation for the entire network. This is the safer and most conservative choice.

The [supporting report](../assets/eip-8038/gas-cost-report.md#relationship-to-the-eip-values) documents how the gas costs of each client compare with the final proposed values in this EIP.

#### Runtime Estimation

To estimate the runtime of a single operation from the total execution time of the corresponding synthetic blocks, a **Non-Negative Least Squares Linear Regression** is used. This model enforces that all coefficients are non-negative, thus ensuring execution time cannot be negative. The model estimates runtime as a linear combination of:

- **Constant term (intercept)**: Base overhead for executing the test, which includes setup and tear-down time
- **Operation count (slope)**: Number of times the operation is executed in the test. This parameter is the one that allows us to estimate the per-operation runtime.

The model estimates: `runtime = intercept + slope × operation_count`

Independent models are created for each client, operation, and configuration. Only operations and parameters with good model fits (R² ≥ 0.5 and p-value < 0.05) are included in the gas cost proposal to ensure the reliability of the estimates. The results of all the regression models can be found in the [runtime estimation report](../assets/eip-8038/runtime_estimation_autogenerated_report.md).

**Glue opcode adjustment**

Each benchmark test includes auxiliary "glue" opcodes that scale linearly with the main opcode count. The regression slope captures the combined runtime of both the target opcode and its glue opcodes, so we subtract the estimated glue opcode runtime to isolate the true per-execution cost:

```
adjusted_slope = slope - sum(ratio_i * glue_runtime_i)
```

Where, for each glue opcode `i`:

- `ratio_i` is the number of executions of glue opcode `i` per execution of the target opcode in the benchmark test.
- `glue_runtime_i` is the estimated per-execution runtime of glue opcode `i`, taken from its own regression model.

A glue opcode contribution is subtracted only if its fit has a p-value below 0.05 and R² of at least 0.5. Contributions from fits that fail either threshold remain in the target runtime estimate. The adjusted slope is clipped to a minimum of zero. The results of glue adjustment estimation can be found in the [dedicated report](../assets/eip-8038/glue_opcodes_autogenerated_report.md).

**Parameter mapping**

Each gas parameter is derived from one or more benchmark models by selecting its slope after applying the relevant filters (test name, cache strategy, account mode). Access cases and combined access and write cases are fitted separately. Their slopes, after glue adjustment, estimate access costs and combined access and write costs. The write cost is derived by subtraction. The state-creation component is not estimated from runtime at all — it prices durable state growth rather than execution time — which is why it is derived separately in [EIP-8037](./eip-8037.md) and left unchanged here.

For each parameter and client, the worst-case value across all matching model configurations is used. The final proposal takes the worst case across clients.

The following table lists the directly estimated parameters and their mapping to the regression models:

| Test name | Configuration | Parameter mapping |
| :---: | :---: | :---: |
| `test_account_access` | `CacheStrategy = NO_CACHE`, `value_sent = 0` | slope → `COLD_ACCOUNT_ACCESS` |
| `test_account_access` | `CacheStrategy = NO_CACHE`, `value_sent = 1` | slope → `COLD_ACCOUNT_WRITE`; subtract access estimates to derive `ACCOUNT_WRITE` |
| `test_sload_bloated` | `CacheStrategy = NO_CACHE` | slope → `COLD_STORAGE_ACCESS` |
| `test_sstore_bloated` | `CacheStrategy = NO_CACHE`, `write_new_value = False` | slope → `COLD_STORAGE_ACCESS` |
| `test_sstore_bloated` | `CacheStrategy = NO_CACHE`, `write_new_value = True` | slope → `COLD_STORAGE_WRITE`; subtract access to derive `STORAGE_WRITE` |
| `test_sload_same_key_benchmark` | — | slope → `WARM_ACCESS` |
| `test_ext_account_query_warm` | — | slope → `WARM_ACCESS` |

`test_sstore_bloated` and `test_sload_bloated` targeted a bespoke contract with a storage size of 10 gigabytes, which is the size of the largest mainnet contract.

#### Conversion to gas costs

New gas costs are calculated using the target performance of 75 Mgas/s. The formula used is:

```
raw_gas = ceil(anchor_rate * runtime_ms / 1000)
```

Where:

- `anchor_rate` is the target performance expressed in gas per second (e.g., `75_000_000` for the 75 Mgas/s target).
- `runtime_ms` is the estimated runtime per operation, in milliseconds, taken from the regression models (the `adjusted_slope` defined above).
- The factor `1000` converts `runtime_ms` from milliseconds to seconds, so that the product with `anchor_rate` (gas/second) yields a result in gas units.

The raw estimate uses the unrounded runtime and is rounded up to a whole gas unit. The two raw write costs are then derived from the rounded estimates:

```
STORAGE_WRITE = max(0, COLD_STORAGE_WRITE - COLD_STORAGE_ACCESS)
ACCOUNT_WRITE = max(0,
    COLD_ACCOUNT_CODE_WRITE - COLD_ACCOUNT_CODE_ACCESS,
    COLD_ACCOUNT_NOCODE_WRITE - COLD_ACCOUNT_NOCODE_ACCESS)
```

The following parameters use the values selected for the EIP:

```
STORAGE_CLEAR_REFUND         = (STORAGE_WRITE + COLD_STORAGE_ACCESS) * (4800/5000)
ACCESS_LIST_STORAGE_KEY_COST = COLD_STORAGE_ACCESS - WARM_ACCESS
ACCESS_LIST_ADDRESS_COST     = COLD_ACCOUNT_ACCESS - WARM_ACCESS
CREATE_ACCESS                = ACCOUNT_WRITE + COLD_ACCOUNT_ACCESS
```

The two access-list parameters price the same database load as their cold counterparts, so they are derived from those cold costs. `WARM_ACCESS` is subtracted because a slot or account named in the access list is already warm when the transaction touches it and is therefore still charged `WARM_ACCESS` at that point: prepaying via the access list must not cost more in access gas than taking the cold access. Without the subtraction, an access-list entry that is used exactly once would cost `COLD_ACCESS + WARM_ACCESS` in access gas, making the list strictly more expensive than not using it.

### Interaction with [EIP-7928](./eip-7928.md)

[EIP-7928](./eip-7928.md) introduces Block-Level Access Lists, which enable parallel disk reads, parallel transaction validation, and state updates without execution through client optimizations. Our benchmarks already consider these optimization gains by running on clients with the optimizations implemented.

### Special case for `EXTCODESIZE` and `EXTCODECOPY`

Differently from other account read operations, `EXTCODESIZE` and `EXTCODECOPY` make two reads to the database. The first read is the same, where the object of the target account is loaded. This object includes the account's `nonce`, `balance`, `codeHash` and `storageRoot`. Then, these operations do another read to collect either the code size or the bytecode of the account. This second read is to an already warmed account, and thus we propose to price it as `WARM_ACCESS` for consistency.

## 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 state access 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 state access cost values.

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

## Security Considerations

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

## Copyright

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