Alert Source Discuss
⚠️ Draft Standards Track: Core

EIP-8358: Net Gas Metering for Account Changes

Make repeated value transfers cheaper by charging account changes once per transaction and refunding accounts that return to original state

Authors Dragan Rakita (@rakita), Charles Cooper (@charles-cooper)
Created 2026-07-26
Discussion Link https://ethereum-magicians.org/t/eip-8358-net-gas-metering-for-account-changes/29304
Requires EIP-161, EIP-2200, EIP-2780, EIP-2929, EIP-3529, EIP-7702, EIP-7708, EIP-8037, EIP-8038

Abstract

This EIP applies net gas metering to account balance changes. A value-bearing CALL pays a base cost and a charge for each account it changes for the first time in the transaction. Later changes to the same accounts cost less, and restoring an account’s original balance earns a refund if its nonce is also unchanged. The gas stipend becomes a minimum callee gas limit. An applied EIP-7702 authorization marks its authority as changed for later calls.

Motivation

The gas cost of a value-bearing CALL is flat per call: CALL_VALUE is ACCOUNT_WRITE + CALL_STIPEND = 11300, or 9000 when the unused 2300 stipend returns to the caller. This cost does not depend on earlier changes to the accounts. The dominant resource behind that cost is the state write: at the end of a block, each account whose balance or nonce changed requires one update of its account trie leaf. That write happens once per modified account, not once per transfer. A transaction that moves ether through the same accounts repeatedly pays for state writes that never happen.

Storage received net gas metering through EIP-2200, later updated by EIP-8038: the first change to a slot pays its write cost, later changes pay the access cost, and restoring its original value earns a refund. Account balances have no equivalent rule. EIP-8038 charges ACCOUNT_WRITE on every value-bearing call, even if the same accounts were changed earlier in the transaction. The result is that a token balance implemented in contract storage enjoys accurate metering while native ether does not. Ether is the only asset on Ethereum whose repeated movement is priced as if every hop were an independent state write.

This cost penalizes common composition patterns:

  • Forwarders and routers that receive msg.value and pass it on pay twice for a balance change that cancels out. Under this EIP the pass-through hop nets 4000 gas, since the intermediary’s balance returns to its original value.
  • Refund patterns where a contract returns excess ether to the payer pay full price for balance changes that cancel. A complete round trip (deposit and return within one transaction) drops from 18000 to 8000 gas before the refund cap.
  • Batched operations, including EIP-7702 delegated accounts executing multiple transfers, pay the full cost per transfer even when the same accounts are touched repeatedly. A contract distributing ether to N recipients pays the sender-side write N times; under this EIP it pays it once — and a delegated account’s authorization already marks it as changed before execution begins.

An N-hop pass-through chain costs 9000 * N today; under this EIP it nets 9000 + 4000 * (N - 1) before the refund cap.

Pricing of the transaction-level value transfer is handled by EIP-2780 (TX_VALUE_COST); this EIP extends net metering to transfers performed during execution.

Specification

Parameters

Constant Value
CALL_VALUE_BASE_GAS 4000
CLEAN_BALANCE_CHANGE_GAS (ACCOUNT_WRITE - CALL_VALUE_BASE_GAS) / 2 (= 2500)
BALANCE_RESET_REFUND CLEAN_BALANCE_CHANGE_GAS (= 2500)
CALL_STIPEND 2300 (unchanged value; now a floor on the subcall gas limit)

ACCOUNT_WRITE is 9000 under EIP-8038. The base accounts for the 2300 stipend and the EIP-7708 transfer log. Its 4000 value is close to their combined 4056 gas cost. Since CALL_VALUE_BASE_GAS + 2 * CLEAN_BALANCE_CHANGE_GAS = ACCOUNT_WRITE, a call that changes two clean accounts consumes 9000 gas, the same as CALL_VALUE - CALL_STIPEND under EIP-8038.

Definitions

  • Original balance and original nonce: the values at the start of the transaction, adjusted for the sender’s upfront gas debit and nonce increment, and for the transaction’s value transfer. A self-transfer changes neither balance. A contract-creation transaction transfers value to its deployment address. No EIP-7702 authorization is included in these original values.
  • Current balance and current nonce: the values an account holds immediately before the metered operation.
  • New balance: the balance an account would hold immediately after the metered transfer.

An account is clean if its current balance equals its original balance and its current nonce equals its original nonce; it is dirty (changed) otherwise.

The order is: derive the original values from the pre-transaction state; check intrinsic gas, debit the sender’s gas, and increment its nonce; initialize the gas counters and process authorizations; warm the recipient and apply the remaining runtime charges; apply the transaction-level transfer; then enter the first EVM frame. EIP-2780 specifies the pre-execution charges. The original values are a comparison baseline, not a snapshot taken during execution. They exclude authorization changes even though authorizations are processed before the transaction-level transfer.

Value transfer cost

Replace the flat CALL_VALUE charge for a nonzero-value CALL (0xF1) or CALLCODE (0xF2) with the following:

  • Charge CALL_VALUE_BASE_GAS.
  • Apply the balance change charge to the account being debited (the currently executing account), with new balance equal to current balance minus the transferred value.
  • Apply the balance change charge to the account being credited (the call target), with new balance equal to current balance plus the transferred value.
  • A self-transfer via CALL changes no balance, so it pays only CALL_VALUE_BASE_GAS. The same applies to CALLCODE with nonzero value.

When the transferred value is nonzero, the gas stipend acts as a floor on the subcall’s gas limit. Let gas limit be the gas the caller makes available to the callee, after the 63/64 rule is applied. The gas limit is evaluated against CALL_STIPEND: if it is at least CALL_STIPEND, the call proceeds with ordinary call semantics and no adjustment; if it is lower, the callee’s gas limit is raised to CALL_STIPEND. No gas is added on top of the gas limit — the additive stipend is removed. Gas granted by the raise is prepaid by CALL_VALUE_BASE_GAS and is not returned. On success or revert, the caller receives min(callee_gas_remaining, gas limit), using the original gas limit. If the call fails before entering a child frame because of insufficient balance or call depth, the caller receives the original gas limit.

All other components of the call cost are unchanged:

  • The EIP-2929 account access cost, memory expansion cost and the base call cost are charged as before.
  • The new-account state-gas charge of EIP-8037 continues to apply when the transferred value is nonzero and the call target is dead, as defined in EIP-161.
  • The EIP-7708 transfer log continues to be emitted for nonzero-value calls to a different account; its cost is a component of CALL_VALUE_BASE_GAS.
  • Calls with zero value are unaffected by this EIP.

The charges above are applied at the time the call instruction executes, before computing the 63/64 rule’s gas limit for the callee, exactly as the replaced CALL_VALUE charge was. If the call subsequently fails without performing the transfer — because the debited account’s balance is insufficient or the call depth limit is reached — the charges are still consumed, matching current behavior, but no refund is issued and no balance changes.

Balance change charge

For an account with a given original balance, current balance and new balance, where new balance differs from current balance:

  • If the account is clean, charge CLEAN_BALANCE_CHANGE_GAS.
  • If the account is dirty, charge nothing. Additionally, if new balance equals original balance and current nonce equals original nonce (the account has returned to its original state), add BALANCE_RESET_REFUND to the refund counter.

The refund counter is the existing transaction-scoped counter used by SSTORE refunds: additions revert together with the call frame they were made in, and the total refund applied at the end of the transaction is capped as specified in EIP-3529. This EIP never removes gas from the refund counter.

EIP-7702 authorization processing

Applying a valid EIP-7702 authorization tuple increments the authority’s nonce and sets its code. Because the original nonce excludes authorization processing, an applied authorization leaves the authority dirty for later calls. Its nonce cannot return to the original value within the transaction, so a balance change involving that authority cannot earn BALANCE_RESET_REFUND. Authorization charges, including the first-write ACCOUNT_WRITE rule of EIP-2780, remain unchanged.

Interaction with other account-modifying operations

Dirtiness is derived solely from comparing balances and nonces against their original values, so a change effected by any means updates the metering of subsequent operations. In particular, the value endowment of CREATE and CREATE2 and the balance sweep of SELFDESTRUCT make the affected accounts dirty, as do nonce changes: a CREATE or CREATE2 increments the creator’s nonce and initializes the created account’s nonce, and authorization processing increments the authority’s nonce.

The gas costs of CREATE, CREATE2 and SELFDESTRUCT (as restricted by EIP-6780) are themselves unchanged by this EIP, to keep the change minimal.

Gas costs and semantics not specified above remain unchanged. DELEGATECALL and STATICCALL transfer no value and are unaffected.

Rationale

Per-account decomposition of the value transfer cost

The CALL_VALUE charge is a lump sum: EIP-8038 defines it as ACCOUNT_WRITE + CALL_STIPEND, charged on every value-bearing call. The unused stipend normally returns to the caller, making the effective cost ACCOUNT_WRITE = 9000. The base of 4000 prices the stipend and the EIP-7708 transfer log together. The account access cost is already charged separately under EIP-2929. The remaining 5000 is split between the two accounts: each clean account that changes pays 2500. A dirty account pays no further balance-change charge. Thus, a call changing two clean accounts costs 9000, while one changing two dirty accounts costs 4000.

EIP-7973 proposes a similar discount for repeated account writes. This EIP uses the cost components of EIP-8038, specifies a refund when a balance change is undone, and leaves SSTORE pricing unchanged.

A self-transfer, or CALLCODE with value, changes no balance and costs the base alone. They emit no EIP-7708 log, but still pay the same base so the cost rule stays simple.

Gas stipend as a gas limit floor

The stipend guarantees a callee at least 2300 gas when the caller forwards none, as Solidity’s transfer and send do. The floor keeps that guarantee. A caller that forwards more gas no longer receives an additional 2300.

Under the old additive rule, unused stipend gas returns to the caller. With a 4000 base and no clean-account charges, returning that gas would make a repeated transfer cost as little as 1700. The new rule prepays any gas needed to reach the floor and does not return that extra gas.

Nonce as part of the dirtiness predicate

An account leaf contains its balance and nonce. CREATE/CREATE2 and EIP-7702 authorizations can change the nonce without changing the balance. Including the nonce prevents a refund when the balance returns to its original value but the leaf still needs a write. Code changes in these operations also increment the nonce. Storage-root changes are outside this EIP’s predicate.

Baseline at the start of execution

The baseline includes the transaction-level transfer so a sender and recipient without authorizations start EVM execution clean. Otherwise, the transfer could make an account appear dirty without paying this EIP’s clean-account charge, and a later return to the baseline could earn a refund without a prior charge.

Authorizations are excluded so that an authority’s nonce increment remains visible to subsequent calls. The sender’s transaction nonce increment is included because it is already covered by TX_BASE_COST.

Refund soundness

For each account, a BALANCE_RESET_REFUND must be backed by an earlier charge. A balance change from a clean account pays CLEAN_BALANCE_CHANGE_GAS, equal to the refund. A CREATE/CREATE2 endowment or a SELFDESTRUCT sweep also pays more than the refund. An account whose nonce changes cannot earn the refund. After a refund, the account is clean again, so another round trip pays the clean charge again. The EIP-3529 cap of gas_used // MAX_REFUND_QUOTIENT bounds total refunds as defense in depth.

Backwards Compatibility

This EIP requires a hard fork, since it modifies gas metering rules.

The value-transfer charge is no higher than the current effective 9000 gas for a call that changes two clean accounts, and is lower when either account is dirty. The changed stipend can still affect execution: a callee given an explicit gas limit above zero may receive less gas and may fail where it previously succeeded.

Two observable behaviors change. A callee’s gas limit becomes max(gas_limit, CALL_STIPEND) instead of gas_limit + CALL_STIPEND: a callee invoked with an explicitly chosen gas limit receives up to 2300 less gas than before, while the stipend guarantee that deployed zero-forwarding patterns (transfer/send) rely on is preserved exactly. The caller also no longer receives unused gas from a stipend-funded increase to the callee’s limit. A contract that reads gasleft() around a value call can observe a different amount, especially if the callee follows a different execution path.

Two economic (non-consensus) effects should be noted:

  • Contracts that rely on the cost of a value transfer as an implicit rate limit on repeated deposits or withdrawals within one transaction will find repetition cheaper.
  • Gas estimation becomes order-dependent, as it already is for EIP-2929 warm and cold access: the cost of a value call depends on prior account changes within the transaction. Wallets and RPC providers must estimate against the transaction’s actual starting state.

Test Cases

The table below lists the value-transfer component of gas consumed by the caller, excluding the EIP-2929 access cost, base call cost and memory costs. All accounts are warm and existing, have sufficient balances (except where noted), callees consume no gas, and x and y are distinct nonzero values. Arrows denote a CALL transferring the indicated value. The “Before this EIP” column is effective consumption: the CALL_VALUE charge (11300) less the 2300 unused stipend returned under current rules. “Net” subtracts the refund earned in these examples before applying the transaction refund cap. Calls that create a new account additionally incur the unchanged EIP-8037 new-account state-gas charges under both columns.

Scenario Charged Refund Net Before this EIP
A→B x 9000 0 9000 9000
A→B x; A→B x 13000 0 13000 18000
A→B x; B→C x 15500 2500 13000 18000
A→B x; B→C y 15500 0 15500 18000
A→B x; B→A x 13000 5000 8000 18000
A→A x (self-transfer) 4000 0 4000 9000
CALLCODE with value x 4000 0 4000 9000
A→B x, balance of A less than x 9000 0 9000 9000

Worked example for A→B x; B→C x: the first call charges 4000 + 2500 + 2500 = 9000 (both accounts clean). The second call charges the 4000 base, nothing for dirty B, and 2500 for clean C, totaling 6500; because B’s new balance equals its original balance, 2500 is added to the refund counter.

Gas stipend floor cases, for a value call with subcall gas limit g and a callee that consumes s gas:

  • g = 0 (e.g. Solidity transfer): the gas limit is raised to 2300; no gas returns to the caller.
  • 0 < g < 2300: the gas limit is raised to 2300; min(2300 - s, g) gas returns to the caller.
  • g >= 2300: no raise occurs; the callee runs with g gas and unused gas returns in full — ordinary call semantics, with no additive stipend.
  • The call fails on insufficient balance or depth limit: g gas is returned.

Account-change cases involving nonces and EIP-7702 authorizations:

  • A transaction carrying an authorization for B, whose execution then performs A→B x: the transfer charges 4000 + 2500 = 6500, since the applied authorization left B dirty.
  • An authorization for tx.sender leaves the sender dirty for later calls, while its ACCOUNT_WRITE charge remains governed by EIP-2780.
  • Contract A performs a CREATE and then A→B x: A’s nonce differs from its original, so the transfer charges 4000 + 2500 = 6500.
  • A→B x, then B performs a CREATE, then B→A x: A earns BALANCE_RESET_REFUND, but B does not — its balance came full circle while its nonce changed, so its account leaf must still be written.

Tests should additionally cover: reverted sub-frames restoring cleanliness and rolling back refunds; the gas stipend floor under callee revert; transfers interleaved with CREATE endowments and SELFDESTRUCT sweeps; cleanliness of the transaction sender and recipient at the start of execution, including a self-sponsored authorization dirtying the sender; and the EIP-3529 refund cap. Test cases in ethereum/execution-spec-tests are to be added.

Security Considerations

Gas stipend amplification

A value-bearing call runs its callee with a gas limit of at least CALL_STIPEND. Gas above the caller’s chosen gas limit exists only when that limit is below CALL_STIPEND; it is bounded by CALL_STIPEND, prepaid by the base charge, and never returned. If a value call could be charged less than that floor, floor gas could recursively fund further value calls, each level of such a self-sustaining chain running on a fresh floor and producing call frames, balance updates and EIP-7708 transfer logs paid for by gas the transaction never supplied. Under this EIP the cheapest value call costs CALL_VALUE_BASE_GAS = 4000 > 2300, so a callee running on the floor can never fund another value-bearing call, and a transaction with gas limit G can never cause more than G gas of execution, with no dependence on the size of the per-account charge. Any future cost change must preserve CALL_VALUE_BASE_GAS > CALL_STIPEND, currently 4000 > 2300.

Transfer log volume

EIP-7708 emits a transfer log for every nonzero-value CALL to a different account and relies on the transfer cost to bound log volume. Even the cheapest log-emitting transfer pays the 4000 base, more than the 1756 gas cost of the equivalent LOG3 with 32 data bytes. Self-transfers emit no log but still pay the base. Refunds cannot push the per-log cost below this floor, since every BALANCE_RESET_REFUND is preceded by an equal clean charge on the same account and every transfer consumes the full base. Emitting logs through value transfers therefore never becomes cheaper than emitting them directly with the LOG opcodes, and the worst-case log volume per block remains governed by the LOG opcodes themselves.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Dragan Rakita (@rakita), Charles Cooper (@charles-cooper), "EIP-8358: Net Gas Metering for Account Changes [DRAFT]," Ethereum Improvement Proposals, no. 8358, July 2026. Available: https://eips.ethereum.org/EIPS/eip-8358.