From 81402c693ffc54feeba3acf99ceab0ad80c9c772 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Mon, 22 Jun 2026 16:56:58 +0700 Subject: [PATCH 01/13] Update eip-7778.md --- EIPS/eip-7778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index ce17d00b834103..18bafbefa7c89b 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,6 +1,6 @@ --- eip: 7778 -title: Block Gas Accounting without Refunds +title: Block Gas Accounting without Refunds description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 From 7e73d5aa42b54f75027537a311eb2c564e552849 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Mon, 22 Jun 2026 20:39:08 +0700 Subject: [PATCH 02/13] Update eip-7778.md --- EIPS/eip-7778.md | 108 ++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 18bafbefa7c89b..2ef8fa2e982bd4 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,82 +1,92 @@ --- -eip: 7778 -title: Block Gas Accounting without Refunds -description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting -author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) -discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 -status: Draft -type: Standards Track -category: Core +eip: 7778 +title: Remove the Refund Mechanism description: Removes gas refunds to simplify transaction-level gas accounting +author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) +discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 +status: Draft +type: Standards Track +category: Core created: 2024-10-01 --- -## Abstract +## Abstract -This EIP modifies the block gas accounting mechanism to prevent the circumvention of block gas limits. It proposes that gas refunds, particularly those from SSTORE operations setting storage slots to zero, should not reduce the gas counted toward the block gas limit, while still being applied to transaction gas costs for users. +This EIP removes the gas refund mechanism retained after [EIP-3529](./eip-3529.md). Users no longer receive gas refunds for clearing storage slots. -## Motivation +## Motivation -Currently, gas refunds from operations like clearing storage slots (setting to zero) reduce both the transaction gas cost for users and the gas counted toward the block gas limit. This creates a discrepancy between the computational work performed and the gas accounted for in the block. +The removal of gas refunds has been discussed for many years. Following the Pectra and Fusaka upgrades, transaction costs measured in ETH have decreased substantially due to significant Layer 1 scaling and larger block capacities. Further scaling is expected to continue at an accelerated pace in Glamsterdam. -Example: Block `20878522` shows a net usage of 28.5 MGas, but contains 4.01 MGas of refunds, bringing the gross usage to 32.51 MGas—exceeding the block gas limit by 2.51 MGas. +As a result, reductions in transaction costs are increasingly driven by Layer 1 scalability improvements rather than by gas refunds. This proposal provides the following benefits: -This mechanism can be exploited to perform more operations in a block than the gas limit intends to allow, potentially leading to: +Aligns transaction costs with actual gas consumption. Transactions that clear storage slots should pay for the computational resources they consume, just like transactions that do not perform storage clearing. This simplifies revenue estimation and transaction selection for validators. -1. Network instability due to oversized blocks -2. Denial-of-service vectors -3. Computational loads exceeding the intended block gas limit +Simplifies client specifications and implementations by eliminating refund-related accounting complexity, allowing client developers to focus on transaction execution optimizations. -## Specification +Removes remaining concerns associated with the refund mechanism, including block-level refund accounting. -### Gas Accounting Changes +## Specification -1. **User Gas Accounting (Unchanged):** +### Gas Accounting Changes - - Users continue to receive gas refunds for operations that qualify (e.g., setting storage to zero) - - Transaction gas: `gas_spent = max(tx_gas_used - gas_refund, calldata_floor_gas_cost)` +1. **User Gas Accounting (Modified)** -2. **Block Gas Accounting (Modified):** +- Users no longer receive refunds arising from state changes performed in previous transactions (for example, creating a storage slot in transaction A and clearing it in transaction B). Consequently, the refund counter defined prior to [EIP-3529](./eip-3529.md) is removed. +- Refund-like adjustments that arise entirely within a single transaction (for example, writing to a storage slot and subsequently restoring its original value) SHOULD be tracked using a separate internal counter. This counter preserves gas reuse between operations and is not subject to the 20% refund cap introduced by [EIP-3529](./eip-3529.md). +- Transaction gas: `gas_spent = max(tx_gas_used, calldata_floor_gas_cost)` - - When calculating gas for block gas limit enforcement, refunds are not subtracted - - Block gas accounting becomes: `block.gas_used += max(tx_gas_used, calldata_floor_gas_cost)` (incorporating the calldata floor from [EIP-7623](./eip-7623.md)) - - Storage discounts that reflect actual reduced computational work (e.g., warm storage access, reverting to original values) remain applied to block gas accounting +2. **Block Gas Accounting (Modified)** -## Rationale +- Refunds are no longer deducted when enforcing the block gas limit. +- Block gas accounting becomes: `block.gas_used += max(tx_gas_used, calldata_floor_gas_cost)` incorporating the calldata floor introduced by [EIP-7623](./eip-7623.md). +- Storage discounts that reflect actual reductions in computational work, such as warm storage accesses or restoring original values, remain reflected in block gas accounting. -### Aligning Gas Limits with Computational Work +## Rationale -The block gas limit is designed to constrain the computational load per block. Gas refunds were introduced to incentivize "cleaning up" the state, not to allow exceeding computational limits. By excluding refunds from block gas accounting, we ensure the block gas limit effectively constrains computational load +### Removal of the Refund Counter -### Preserving User Incentives +Historically, the refund mechanism was reduced gradually to minimize disruption while transaction fees remained relatively high. However, Layer 1 scaling has progressed more rapidly than anticipated. -Users still receive gas refunds, maintaining incentives for efficient state management. Only the accounting for block-level constraints changes, not the economics for individual users +Maintaining refund incentives now provides diminishing benefits compared to the advantages of removing them entirely. Eliminating the refund counter simplifies implementations, reduces protocol complexity, and removes a potential attack surface. -## Backwards Compatibility +### Potential Objections -- This change is not backwards compatible and requires a hard fork -- User and developer experience for individual transactions remains unchanged -- Block producers need to adjust their transaction selection algorithms to account for the new gas accounting rules +#### Higher Transaction Costs + +Gas consumption measured in gas units may increase because transactions no longer receive refund discounts. However, transaction costs measured in ETH are expected to remain largely unchanged because increased network capacity has reduced fee pressure and lowered base fees. + +Priority fees remain the dominant component of transaction costs during periods of low congestion. Wallets are encouraged to set reasonable priority fees in an environment where block space is becoming increasingly abundant. + +#### Reduced Incentive for State Cleanup + +State management should ultimately be addressed through long-term protocol mechanisms such as state expiration rather than refund incentives. + +Furthermore, most storage-clearing operations occur as a side effect of normal user activity, such as emptying an account balance or revoking ERC-20 approvals, rather than as deliberate refund-seeking behavior. Historical refund farming mechanisms such as GasToken have already been largely mitigated by [EIP-3529](./eip-3529.md). + +## Backwards Compatibility + +This change is not backwards compatible and requires a hard fork. + +Transaction gas usage measured in gas units may increase because refund discounts are no longer available. However, lower fee levels resulting from network scaling are expected to significantly offset this effect. + +Block producers must update transaction selection algorithms to account for the revised gas accounting rules. ## Test Cases -1. **SSTORE Operations:** - - Setting storage to zero: User receives refund, but block gas accounting uses full cost - - Verify blocks containing many storage-clearing operations still adhere to gas limits +### SSTORE Operations + +`SSTORE` pricing remains as specified by [EIP-8037](./eip-8037.md) and [EIP-8038](./eip-8038.md). + +### Transaction Gas vs Block Gas -2. **Block Gas Limit Edge Cases:** - - Construct blocks with varying amounts of refundable operations - - Ensure blocks cannot exceed gas limits through refund mechanisms +Verify that refunds are fully removed from both transaction-level and block-level gas accounting. -3. **Transaction Gas vs Block Gas:** - - Verify that transaction costs for users remain unchanged - - Confirm block gas accounting properly excludes refunds +## Security Considerations -## Security Considerations +This EIP removes the refund counter entirely, simplifying client implementations and eliminating a potential block-level attack vector. -- Eliminates potential denial-of-service vectors that exploit gas refunds to exceed block computational limits -- Improves predictability of block processing times by enforcing stricter limits on computational work -- Prevents miners/validators from including transactions that collectively contain more computational work than intended +The proposal also unifies validator revenue accounting and prevents transactions from exploiting refund mechanics to occupy more computational resources than intended under block gas limit enforcement. -## Copyright +## Copyright Copyright and related rights waived via [CC0](../LICENSE.md). From 2d818b8c52e44cfb976ad913f98687ffed880e1a Mon Sep 17 00:00:00 2001 From: Helkomine Date: Mon, 22 Jun 2026 20:43:57 +0700 Subject: [PATCH 03/13] Update eip-7778.md --- EIPS/eip-7778.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 2ef8fa2e982bd4..059e8509cf919e 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,6 +1,7 @@ --- -eip: 7778 -title: Remove the Refund Mechanism description: Removes gas refunds to simplify transaction-level gas accounting +eip: 7778 +title: Remove the Refund Mechanism +description: Removes gas refunds to simplify transaction-level gas accounting author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 status: Draft From 5878f38058d4da4b1d63b5ff91453f18ba1c10e5 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Mon, 22 Jun 2026 20:52:56 +0700 Subject: [PATCH 04/13] fix walidator --- EIPS/eip-7778.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 059e8509cf919e..c97a488b1cd5e2 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,12 +1,12 @@ --- eip: 7778 -title: Remove the Refund Mechanism -description: Removes gas refunds to simplify transaction-level gas accounting -author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) -discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 -status: Draft -type: Standards Track -category: Core +title: Remove the Refund Mechanism +description: Removes gas refunds to simplify transaction-level gas accounting +author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) +discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 +status: Draft +type: Standards Track +category: Core created: 2024-10-01 --- From 303d364b9c73be0d8f2e928a93bc6e16ca6ce08c Mon Sep 17 00:00:00 2001 From: Helkomine Date: Mon, 22 Jun 2026 23:11:56 +0700 Subject: [PATCH 05/13] Add the old note to the accounting method --- EIPS/eip-7778.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index c97a488b1cd5e2..e482f6b9d8f04d 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,7 +1,7 @@ --- eip: 7778 -title: Remove the Refund Mechanism -description: Removes gas refunds to simplify transaction-level gas accounting +title: Remove the Old Refund Mechanism +description: Removes old gas refunds to simplify transaction-level gas accounting author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 status: Draft From b68c32b77c098b1dec932bda389af9fc6e1e265e Mon Sep 17 00:00:00 2001 From: Helkomine Date: Tue, 23 Jun 2026 00:09:04 +0700 Subject: [PATCH 06/13] Update eip-8038.md --- EIPS/eip-8038.md | 1 - 1 file changed, 1 deletion(-) diff --git a/EIPS/eip-8038.md b/EIPS/eip-8038.md index 6f857659593fa7..e18266201f751f 100644 --- a/EIPS/eip-8038.md +++ b/EIPS/eip-8038.md @@ -34,7 +34,6 @@ Upon activation of this EIP, the following parameters of the gas model are intro | `COLD_STORAGE_ACCESS` | Cold touch of a storage slot | 2,100 | 3,000 | +43% | `SSTORE` and `SLOAD` | | `STORAGE_WRITE` | Surcharge for when writing to a storage slot changes its value for the first time | 2,800² | 10,000 | +257% | `SSTORE` | | `WARM_ACCESS` | Touch of an already-warm account or storage slot | 100 | 100 | +0% | `SSTORE`, `SLOAD`, `*CALL` opcodes, `BALANCE` and `EXT*` opcodes | -| `STORAGE_CLEAR_REFUND` | Refund for clearing a storage slot | 4,800 | 12,480 | +160% | `SSTORE` | | `CREATE_ACCESS` | State access costs for contract deployment (include account cold access and account write) | 7,000³ | 11,000 | +57% | `CREATE`/ `CREATE2` | | `ACCESS_LIST_STORAGE_KEY_COST` | Gas charged per storage key included in a transaction's access list | 1,900 | 3,000 | +58% | `SSTORE` and `SLOAD` | | `ACCESS_LIST_ADDRESS_COST` | Gas charged per address included in a transaction's access list | 2,400 | 3,000 | +25% | `*CALL` opcodes, `BALANCE`, `SELFDESTRUCT` and `EXT*` opcodes | From 10ce92208af3f6d594589881576f57d8efe67b64 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Tue, 23 Jun 2026 10:50:33 +0700 Subject: [PATCH 07/13] Update eip-8038.md --- EIPS/eip-8038.md | 129 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 34 deletions(-) diff --git a/EIPS/eip-8038.md b/EIPS/eip-8038.md index e18266201f751f..dd2dbc2a968ea1 100644 --- a/EIPS/eip-8038.md +++ b/EIPS/eip-8038.md @@ -33,7 +33,8 @@ Upon activation of this EIP, the following parameters of the gas model are intro | `ACCOUNT_WRITE` | Surcharge for when writing to an account changes one account leaf value for the first time | 6,700¹ | 8,000 | +19% | `*CALL` opcodes, `SELFDESTRUCT`, EOA delegations and ETH transfers | | `COLD_STORAGE_ACCESS` | Cold touch of a storage slot | 2,100 | 3,000 | +43% | `SSTORE` and `SLOAD` | | `STORAGE_WRITE` | Surcharge for when writing to a storage slot changes its value for the first time | 2,800² | 10,000 | +257% | `SSTORE` | -| `WARM_ACCESS` | Touch of an already-warm account or storage slot | 100 | 100 | +0% | `SSTORE`, `SLOAD`, `*CALL` opcodes, `BALANCE` and `EXT*` opcodes | +| `LOW_WARM_ACCESS` | Warm access cost for a read-only opcodes | - | 5 | - | `SLOAD`, `BALANCE` and `EXT*` opcodes | +| `WARM_ACCESS` | Warm access cost for opcodes includes processing the `REVERT` path. | 100 | 100 | +0% | `SSTORE`, `*CALL` opcodes, and `CREATE*` opcodes | | `CREATE_ACCESS` | State access costs for contract deployment (include account cold access and account write) | 7,000³ | 11,000 | +57% | `CREATE`/ `CREATE2` | | `ACCESS_LIST_STORAGE_KEY_COST` | Gas charged per storage key included in a transaction's access list | 1,900 | 3,000 | +58% | `SSTORE` and `SLOAD` | | `ACCESS_LIST_ADDRESS_COST` | Gas charged per address included in a transaction's access list | 2,400 | 3,000 | +25% | `*CALL` opcodes, `BALANCE`, `SELFDESTRUCT` and `EXT*` opcodes | @@ -44,40 +45,70 @@ Upon activation of this EIP, the following parameters of the gas model are intro ³: 7,000 = `GAS_CREATE` (32,000) - `GAS_NEW_ACCOUNT` (25,000) -### `SSTORE` pricing +### Introduce `state_access_gas_reservoir` + +A new counter, `state_access_gas_reservoir`, is introduced to replace the refund counter removed by [EIP-7778](./eip-7778.md). + +The counter is initialized to zero at the beginning of each transaction. Its behavior is analogous to `state_gas_reservoir` defined in [EIP-8037](./eip-8037.md). It accumulates all gas refills associated with valid state-access operations. + +Any state-access charge (excluding the base cost of an opcode) MUST first consume gas from `state_access_gas_reservoir` before consuming gas from `gas_left`. + +### Introduce `balance_updated` and `account_updated` + +Two new global sets are introduced: + +- `balance_updated` +- `account_updated` + +`balance_updated` tracks accounts whose balances have been modified during the transaction. These updates are temporary. + +`account_updated` tracks accounts that have undergone permanent state changes, including account creation and account state-root updates. -In addition, the `SSTORE` cost formula is updated to include the following independent costs: +These sets are global transaction-scoped data structures and operate similarly to existing sets such as `accessed_addresses`. -1. Access costs: `COLD_STORAGE_ACCESS` or `WARM_ACCESS`, depending on whether the storage slot is cold or warm. -2. Write cost: additionally charge `STORAGE_WRITE` if the new value is different from the present value and the present value equals the original value (First time change). -3. State creation cost: additionally charge `GAS_STORAGE_SET` (per [EIP-8037](./eip-8037.md)) if the original value is zero, the current value is zero, and the new value is non-zero. +The rules for inserting and removing addresses from these sets are defined by the opcode semantics specified below. -Refunds are also updated as follows. Each rule is an adjustment to the transaction's refund counter and is evaluated on every `SSTORE`: +### `SLOAD` pricing -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 restored). This reverses the refund granted by rule 1, so that clearing and then restoring 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 first-time change made earlier in the same transaction is reset back to its original value). +The base cost of `SLOAD` is set to `LOW_WARM_ACCESS`. + +If the accessed storage slot is cold, an additional `COLD_STORAGE_ACCESS` charge is applied. + +### `BALANCE` and `EXTCODEHASH` pricing + +The base cost of `BALANCE` and `EXTCODEHASH` is set to `LOW_WARM_ACCESS`. + +If the accessed account is cold, an additional `COLD_ACCOUNT_ACCESS` charge is applied. + +### `EXT*` family update + +The base cost of `EXTCODESIZE` and `EXTCODECOPY` is set to 2 * `LOW_WARM_ACCESS`. + +If the accessed account is cold, an additional `COLD_ACCOUNT_ACCESS` charge is applied. + +### `SSTORE` pricing -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. +The base cost of `SSTORE` is set to `WARM_ACCESS`. -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. +If the accessed storage slot is cold, an additional `COLD_STORAGE_ACCESS` charge is applied. -The rules for state creation cost charges and refills are addressed in [EIP-8037](./eip-8037.md). +[EIP-7778](./eip-7778.md) removes the refund counter and therefore removes refunds associated with clearing storage slots. -Cases and their corresponding costs are detailed in the table below: +Transaction-internal refunds are instead redirected to: -| Original value | Current value | New value | Access status | Description | Regular-gas charges/refunds | State-gas charges/refills | +- `state_access_gas_reservoir` for state-access costs. +- `state_gas_reservoir` for state-creation costs. + +The corresponding charging and refill rules are shown below: + +| Original value | Current value | New value | Access status | Description | Regular-gas charges/refills | State-gas charges/refills | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| 0 | 0 | x | Cold | New slot | `COLD_STORAGE_ACCESS` + `STORAGE_WRITE` charged | `GAS_STORAGE_SET` charged | +| 0 | 0 | x | Cold | New slot | `WARM_ACCESS` + `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 | Cold | Existing slot, first change | `WARM_ACCESS` + `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 | -| x | y | x | Warm | Previously-modified slot reset to original value | `WARM_ACCESS` charged, `STORAGE_WRITE` 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 | +| 0 | x | 0 | Warm | Set slot reset to zero (zero at transaction start) | `WARM_ACCESS` charged, `STORAGE_WRITE` refilled | `GAS_STORAGE_SET` refilled | +| x | y | x | Warm | Previously-modified slot reset to original value | `WARM_ACCESS` charged, `STORAGE_WRITE` refilled | no state-gas adjustments | | x | y | z | Warm | Previously-modified slot written to again | `WARM_ACCESS` charged | no state-gas adjustments | ### Account access pricing @@ -86,21 +117,51 @@ The rules that determine when `COLD_ACCOUNT_ACCESS` and `WARM_ACCESS` are charge #### `CALL`/`CALLCODE` -For `CALL` and `CALLCODE` operations, `CALL_VALUE` is set to `ACCOUNT_WRITE + CALL_STIPEND`, where `CALL_STIPEND` = 2,300. +The base cost of the `*CALL` family is set to `WARM_ACCESS`. + +If the target account is cold, an additional `COLD_ACCOUNT_ACCESS` charge is applied. + +During transaction execution, each account maintains the following values: + +-`original_balance`: the account balance at the beginning of the transaction. This value remains constant throughout the transaction. +-`current_balance`: the current account balance. +-`new_balance`: the balance after the pending update. + +For `CALL` and `CALLCODE`, `CALL_VALUE` is defined as `CALL_VALUE = ACCOUNT_WRITE + CALL_STIPEND` where `CALL_STIPEND` = 2300. This represents the maximum state-access charge for a value-transferring call. Upon entering the call frame, gas accounting is performed according to the table below: + +| `original_balance` | `current_balance` | `new_balance` | `account_updated` | `balance_updated` update | Description | Regular-gas charges/ State-access-gas refills | +| :---: | :---: | :---: | :---: | :---: | :---: | :---: | +| x | x | y | false | added | First temporary update | no adjustments | +| x | x | y | true | unchanged | First permanent update | refilled `ACCOUNT_WRITE` | +| x | y | x | false | removed | Temporary reset | refilled 2 * `ACCOUNT_WRITE` | +| x | y | x | true | unchanged | Permanent reset | refilled `ACCOUNT_WRITE` | +| x | y | z | false | unchanged | Subsequent temporary update | refilled `ACCOUNT_WRITE` | +| x | y | z | true | unchanged | Subsequent permanent update | refilled `ACCOUNT_WRITE` | #### `CREATE`/`CREATE2` -`CREATE` and `CREATE2` operations don't have explicit warm/cold pricing. Instead, they are charged `CREATE_ACCESS` in regular-gas and `GAS_NEW_ACCOUNT` in state-gas (per [EIP-8037](./eip-8037.md)). `CREATE_ACCESS` is defined as `ACCOUNT_WRITE` + `COLD_STORAGE_ACCESS`. +The base cost of the `CREATE*` family is set to `WARM_ACCESS`. + +This charge is applied uniformly to operations that require `REVERT`-path handling. + +`CREATE` and `CREATE2` do not use explicit warm/cold pricing. Instead, they charge: + +- `CREATE_ACCESS` in regular gas. +- `GAS_NEW_ACCOUNT` in state gas, as specified by [EIP-8037](./eip-8037.md). + +`CREATE_ACCESS` is defined as `CREATE_ACCESS = ACCOUNT_WRITE + COLD_ACCOUNT_ACCESS`. This represents the maximum state-access charge associated with account creation. Note: this definition does not exactly match the legacy decomposition shown in footnote ³ 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` +When entering a creation frame, refund accounting is performed if the target account was previously updated before becoming the destination of the creation operation (for example, an account that received ETH before contract creation). -For `SELFDESTRUCT`, an additional charge of `ACCOUNT_WRITE` is added if a positive balance is sent to an empty account. +The account MUST be permanently inserted into `account_updated`. + +If the account exists in `balance_updated`, `ACCOUNT_WRITE` MUST be refilled into `state_access_gas_reservoir`, and the account MUST be removed from `balance_updated`. -#### `EXT*` family update +#### `SELFDESTRUCT` -Besides the current access costs, `EXTCODESIZE` and `EXTCODECOPY` are charged an additional `WARM_ACCESS`. +For `SELFDESTRUCT`, an additional charge of `ACCOUNT_WRITE` is added if a positive balance is sent to an empty account. #### Overview @@ -108,12 +169,12 @@ The cases for account-related operations and their corresponding costs are summa | Operation | Access charge | `ACCOUNT_WRITE` charged | Additional charge | | :--- | :---: | :--- | :--- | -| `CALL` / `CALLCODE` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | when value is transferred (via `CALL_VALUE` = `ACCOUNT_WRITE` + `CALL_STIPEND`) | — | -| `DELEGATECALL` / `STATICCALL` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never (no value transfer) | — | -| `CREATE` / `CREATE2` | `CREATE_ACCESS` (= `ACCOUNT_WRITE` + `COLD_STORAGE_ACCESS`) | always (folded into `CREATE_ACCESS`) | `GAS_NEW_ACCOUNT` in state-gas (per [EIP-8037](./eip-8037.md)) | +| `CALL` / `CALLCODE` | `WARM_ACCESS + COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | when value is transferred (via `CALL_VALUE` = `ACCOUNT_WRITE` + `CALL_STIPEND`) | — | +| `DELEGATECALL` / `STATICCALL` | `WARM_ACCESS + COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never (no value transfer) | — | +| `CREATE` / `CREATE2` | `WARM_ACCESS + CREATE_ACCESS` (= `WARM_ACCESS + ACCOUNT_WRITE` + `COLD_STORAGE_ACCESS`) | always (folded into `CREATE_ACCESS`) | `GAS_NEW_ACCOUNT` in state-gas (per [EIP-8037](./eip-8037.md)) | | `SELFDESTRUCT` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | when a positive balance is sent to an empty account | — | -| `BALANCE` / `EXTCODEHASH` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never | — | -| `EXTCODESIZE` / `EXTCODECOPY` | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` | never | `WARM_ACCESS` (second database read) | +| `BALANCE` / `EXTCODEHASH` | `LOW_WARM_ACCESS + COLD_ACCOUNT_ACCESS` or `LOW_WARM_ACCESS` | never | — | +| `EXTCODESIZE` / `EXTCODECOPY` | `LOW_WARM_ACCESS + COLD_ACCOUNT_ACCESS` or `LOW_WARM_ACCESS` | never | `LOW_WARM_ACCESS` (second database read) | | EOA delegation ([EIP-7702](./eip-7702.md)) | `COLD_ACCOUNT_ACCESS` or `WARM_ACCESS` per authority | per authorization (intrinsic cost) | see authorizations table below | ### [EIP-7702](./eip-7702.md) authorizations pricing From d1869a77412a2c8378d70a6d92f62bbe1eccba56 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Wed, 24 Jun 2026 17:04:51 +0700 Subject: [PATCH 08/13] Keep the original EIP parameters and add Refund Routing --- EIPS/eip-7778.md | 97 +++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index e482f6b9d8f04d..ceeaeefec23696 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,7 +1,7 @@ --- eip: 7778 -title: Remove the Old Refund Mechanism -description: Removes old gas refunds to simplify transaction-level gas accounting +title: Block Gas Accounting without Refunds and Route Refunds +description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting and Implement Refund Routing based on Their Origin author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 status: Draft @@ -10,83 +10,94 @@ category: Core created: 2024-10-01 --- -## Abstract +## Abstract -This EIP removes the gas refund mechanism retained after [EIP-3529](./eip-3529.md). Users no longer receive gas refunds for clearing storage slots. +This EIP modifies the block gas accounting mechanism to prevent the circumvention of block gas limits. It proposes that gas refunds, particularly those from `SSTORE` operations setting storage slots to zero, should not reduce the gas counted toward the block gas limit, while still being applied to transaction gas costs for users. -## Motivation +Additionally, this EIP introduces refund routing based on the origin of refunds in order to further improve gas accounting. These rules apply retroactively to existing gas refunds but do not modify the value of any refund mechanism. -The removal of gas refunds has been discussed for many years. Following the Pectra and Fusaka upgrades, transaction costs measured in ETH have decreased substantially due to significant Layer 1 scaling and larger block capacities. Further scaling is expected to continue at an accelerated pace in Glamsterdam. +## Motivation -As a result, reductions in transaction costs are increasingly driven by Layer 1 scalability improvements rather than by gas refunds. This proposal provides the following benefits: +Currently, gas refunds from operations like clearing storage slots (setting to zero) reduce both the transaction gas cost for users and the gas counted toward the block gas limit. This creates a discrepancy between the computational work performed and the gas accounted for in the block. -Aligns transaction costs with actual gas consumption. Transactions that clear storage slots should pay for the computational resources they consume, just like transactions that do not perform storage clearing. This simplifies revenue estimation and transaction selection for validators. +Example: Block `20878522` shows a net usage of 28.5 MGas, but contains 4.01 MGas of refunds, bringing the gross usage to 32.51 MGas—exceeding the block gas limit by 2.51 MGas. -Simplifies client specifications and implementations by eliminating refund-related accounting complexity, allowing client developers to focus on transaction execution optimizations. +This mechanism can be exploited to perform more operations in a block than the gas limit intends to allow, potentially leading to: -Removes remaining concerns associated with the refund mechanism, including block-level refund accounting. +1. Network instability due to oversized blocks +2. Denial-of-service vectors +3. Computational loads exceeding the intended block gas limit -## Specification +Furthermore, existing refunds (for example, the authorization refunds introduced by [EIP-7702](./eip-7702.md) are routed through the single refund counter retained after [EIP-3529](./eip-3529.md). As a result, refunded gas remains unavailable until the end of the transaction and is subject to the 20% refund cap. Separating these refunds according to their origin improves gas accounting and can reduce transaction costs by making refunded gas available through more appropriate accounting mechanisms. -### Gas Accounting Changes +## Specification -1. **User Gas Accounting (Modified)** +### Gas Accounting Changes -- Users no longer receive refunds arising from state changes performed in previous transactions (for example, creating a storage slot in transaction A and clearing it in transaction B). Consequently, the refund counter defined prior to [EIP-3529](./eip-3529.md) is removed. -- Refund-like adjustments that arise entirely within a single transaction (for example, writing to a storage slot and subsequently restoring its original value) SHOULD be tracked using a separate internal counter. This counter preserves gas reuse between operations and is not subject to the 20% refund cap introduced by [EIP-3529](./eip-3529.md). -- Transaction gas: `gas_spent = max(tx_gas_used, calldata_floor_gas_cost)` +1. **User Gas Accounting (Unchanged):** -2. **Block Gas Accounting (Modified)** + - Users continue to receive gas refunds for operations that qualify (e.g., setting storage to zero) + - Transaction gas: `gas_spent = max(tx_gas_used - gas_refund, calldata_floor_gas_cost)` -- Refunds are no longer deducted when enforcing the block gas limit. -- Block gas accounting becomes: `block.gas_used += max(tx_gas_used, calldata_floor_gas_cost)` incorporating the calldata floor introduced by [EIP-7623](./eip-7623.md). -- Storage discounts that reflect actual reductions in computational work, such as warm storage accesses or restoring original values, remain reflected in block gas accounting. +2. **Block Gas Accounting (Modified):** -## Rationale + - When calculating gas for block gas limit enforcement, refunds are not subtracted + - Block gas accounting becomes: `block.gas_used += max(tx_gas_used, calldata_floor_gas_cost)` (incorporating the calldata floor from [EIP-7623](./eip-7623.md)) + - Storage discounts that reflect actual reduced computational work (e.g., warm storage access, reverting to original values) remain applied to block gas accounting -### Removal of the Refund Counter +### Refund Routing -Historically, the refund mechanism was reduced gradually to minimize disruption while transaction fees remained relatively high. However, Layer 1 scaling has progressed more rapidly than anticipated. +This EIP defines two categories of gas refunds according to their origin: -Maintaining refund incentives now provides diminishing benefits compared to the advantages of removing them entirely. Eliminating the refund counter simplifies implementations, reduces protocol complexity, and removes a potential attack surface. +- `external refund`: a refund originating from state changes performed by previous transactions. For example, transaction A creates a storage slot and transaction B subsequently clears it. +- `internal refund`: a refund originating from state changes or overcharges within the same transaction. For example, refunds resulting from the overcharging of EIP-7702(./eip-7702.md) authorizations. -### Potential Objections +The refund counter only accepts refunds belonging to the `external refund` category. -#### Higher Transaction Costs +Refunds belonging to the `internal refund` category MUST NOT be added to the refund counter and instead MUST be accounted for using alternative mechanisms, such as dedicated refund reservoirs or counters. -Gas consumption measured in gas units may increase because transactions no longer receive refund discounts. However, transaction costs measured in ETH are expected to remain largely unchanged because increased network capacity has reduced fee pressure and lowered base fees. +## Rationale -Priority fees remain the dominant component of transaction costs during periods of low congestion. Wallets are encouraged to set reasonable priority fees in an environment where block space is becoming increasingly abundant. +### Aligning Gas Limits with Computational Work -#### Reduced Incentive for State Cleanup +The block gas limit is designed to constrain the computational load per block. Gas refunds were introduced to incentivize "cleaning up" the state, not to allow exceeding computational limits. By excluding refunds from block gas accounting, we ensure the block gas limit effectively constrains computational load -State management should ultimately be addressed through long-term protocol mechanisms such as state expiration rather than refund incentives. +### Preserving User Incentives -Furthermore, most storage-clearing operations occur as a side effect of normal user activity, such as emptying an account balance or revoking ERC-20 approvals, rather than as deliberate refund-seeking behavior. Historical refund farming mechanisms such as GasToken have already been largely mitigated by [EIP-3529](./eip-3529.md). +Users still receive gas refunds, maintaining incentives for efficient state management. Only the accounting for block-level constraints changes, not the economics for individual users -## Backwards Compatibility +### Refund Routing -This change is not backwards compatible and requires a hard fork. +Separating refunds according to their origin further improves gas accounting while preserving the existing refund mechanisms. This proposal changes how refunds are accounted for but does not alter the economic value of existing refunds. -Transaction gas usage measured in gas units may increase because refund discounts are no longer available. However, lower fee levels resulting from network scaling are expected to significantly offset this effect. +## Backwards Compatibility -Block producers must update transaction selection algorithms to account for the revised gas accounting rules. +- This change is not backwards compatible and requires a hard fork +- User and developer experience for individual transactions remains unchanged +- Block producers need to adjust their transaction selection algorithms to account for the new gas accounting rules ## Test Cases -### SSTORE Operations +1. **SSTORE Operations:** + - Setting storage to zero: User receives refund, but block gas accounting uses full cost + - Verify blocks containing many storage-clearing operations still adhere to gas limits -`SSTORE` pricing remains as specified by [EIP-8037](./eip-8037.md) and [EIP-8038](./eip-8038.md). +2. **Block Gas Limit Edge Cases:** + - Construct blocks with varying amounts of refundable operations + - Ensure blocks cannot exceed gas limits through refund mechanisms -### Transaction Gas vs Block Gas +3. **Transaction Gas vs Block Gas:** + - Verify that transaction costs for users remain unchanged + - Confirm block gas accounting properly excludes refunds -Verify that refunds are fully removed from both transaction-level and block-level gas accounting. +4. **Refund Routing:** + - Verify that only `external refunds` are added to the refund counter. -## Security Considerations +## Security Considerations -This EIP removes the refund counter entirely, simplifying client implementations and eliminating a potential block-level attack vector. - -The proposal also unifies validator revenue accounting and prevents transactions from exploiting refund mechanics to occupy more computational resources than intended under block gas limit enforcement. +- Eliminates potential denial-of-service vectors that exploit gas refunds to exceed block computational limits +- Improves predictability of block processing times by enforcing stricter limits on computational work +- Prevents miners/validators from including transactions that collectively contain more computational work than intended ## Copyright From 2ebac999097fe9b0f40c150f3cbb9a62af54bc82 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Wed, 24 Jun 2026 17:13:31 +0700 Subject: [PATCH 09/13] Shorten the name to accommodate linter. --- EIPS/eip-7778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index ceeaeefec23696..0cd0970b54026c 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,6 +1,6 @@ --- eip: 7778 -title: Block Gas Accounting without Refunds and Route Refunds +title: Block Gas Accounting and Refund Routing description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting and Implement Refund Routing based on Their Origin author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 From 218ca6952726c2bb2e7c0b884bc37608d64e38f0 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Wed, 24 Jun 2026 17:18:53 +0700 Subject: [PATCH 10/13] fix spelling --- EIPS/eip-7778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 0cd0970b54026c..084db21aec60e1 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -50,7 +50,7 @@ Furthermore, existing refunds (for example, the authorization refunds introduced This EIP defines two categories of gas refunds according to their origin: - `external refund`: a refund originating from state changes performed by previous transactions. For example, transaction A creates a storage slot and transaction B subsequently clears it. -- `internal refund`: a refund originating from state changes or overcharges within the same transaction. For example, refunds resulting from the overcharging of EIP-7702(./eip-7702.md) authorizations. +- `internal refund`: a refund originating from state changes or overcharges within the same transaction. For example, refunds resulting from the overcharging of [EIP-7702](./eip-7702.md) authorizations. The refund counter only accepts refunds belonging to the `external refund` category. From d19eb0fca6c339dcc68e1888a9c7859e1c088914 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Fri, 26 Jun 2026 18:21:36 +0700 Subject: [PATCH 11/13] revert title --- EIPS/eip-7778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 084db21aec60e1..16b4446c4001f4 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,6 +1,6 @@ --- eip: 7778 -title: Block Gas Accounting and Refund Routing +title: Block Gas Accounting without Refunds description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting and Implement Refund Routing based on Their Origin author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 From c2ebc08ac7f111c5eff9629fd3df1e5385761838 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Fri, 3 Jul 2026 10:18:40 +0700 Subject: [PATCH 12/13] Implement -> Introduce --- EIPS/eip-7778.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-7778.md b/EIPS/eip-7778.md index 16b4446c4001f4..02c8aa2d366209 100644 --- a/EIPS/eip-7778.md +++ b/EIPS/eip-7778.md @@ -1,7 +1,7 @@ --- eip: 7778 title: Block Gas Accounting without Refunds -description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting and Implement Refund Routing based on Their Origin +description: Prevent Block Gas Limit Circumvention by Excluding Refunds from Block Gas Accounting and Introduce Refund Routing based on Their Origin author: Ben Adams (@benaadams), Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7778-prevent-block-gas-smuggling/21234 status: Draft From 6f38449fbd9f129d275ba7e4674fa006aa3120b6 Mon Sep 17 00:00:00 2001 From: Helkomine Date: Fri, 3 Jul 2026 10:25:52 +0700 Subject: [PATCH 13/13] Update eip-8037.md --- EIPS/eip-8037.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EIPS/eip-8037.md b/EIPS/eip-8037.md index 1c8d868604f425..788ffc9584f97a 100644 --- a/EIPS/eip-8037.md +++ b/EIPS/eip-8037.md @@ -115,7 +115,7 @@ The gas counters operate as follows: - The `GAS` opcode returns `gas_left` only (excluding the reservoir). - State-gas is metered at the end of all state-mutating opcodes, call-frame boundaries (in case of exceptional halts and reverts) and at the end of the transaction. -##### Gas accounting for SSTORE (opcode-level) +##### Gas accounting for `SSTORE` (opcode-level) | Original value | Current value | New value | Description | State-gas charges/refills | |---|---|---|---|---|