ECIP 1111: Base Fee Market and Redirection
| Author | Cody Burns, Chris Mercer |
|---|---|
| Discussions-To | https://github.com/orgs/ethereumclassic/discussions/530 |
| Status | Draft |
| Type | Standards Track |
| Category | Core |
| Created | 2025-07-04 |
Simple Summary
Activates EIP-1559 and EIP-3198 on Ethereum Classic. Where Ethereum Mainnet destroys the base fee, Ethereum Classic credits it at the consensus layer to a permanent address held in chain configuration, changeable only by a further hard fork. Miner block rewards and priority-fee tips are unaffected.
Abstract
This ECIP activates two Ethereum protocol upgrades on Ethereum Classic:
- EIP-1559 — dynamic base-fee adjustment.
- EIP-3198 — the
BASEFEEopcode, for EVM opcode compatibility.
The base fee charged to each transaction is credited to the SOVEREIGNTY_VAULT address rather than destroyed. A permanent minimum base fee is applied at every block. This ECIP defines the consensus-layer rule and nothing above it: what is deployed at that address, and how the balance held there is governed and spent, are outside its scope and do not affect its correctness.
Motivation
EIP-1559 and EIP-3198 are standard across the EVM ecosystem, and adopting them gives contracts fee-aware logic through the BASEFEE opcode.
Modern EVM tooling assumes EIP-1559. Foundry sends a Type-2 transaction to any chain absent from its legacy registry, Ethereum Classic among them, while libraries that probe the chain fall back correctly — so support here rests on a code path each integrator maintains for this network alone, and activating EIP-1559 and EIP-3198 removes that path rather than documenting it.
Crediting the base fee rather than destroying it converts a flow EIP-1559 charges anyway into a funding source the network raises from its own use. It accrues without a foundation, a donor, or a grant, and reduces no miner compensation, and a permanent floor keeps it from falling to zero when blocks are empty — which on Ethereum Classic they usually are. The network has had no such source, its execution layer trails four Ethereum upgrades, and ECIP-1017’s emission schedule declines on a fixed timetable regardless.
Activating EIP-1559 is consistent with Ethereum Classic’s immutability and censorship-resistance principles: it reinterprets no historical block, and requires no trust in any off-chain actor.
Specification
All EIPs below are implemented exactly as canonically defined, except where noted for the consensus-layer base-fee credit.
Protocol Changes (from Ethereum’s London Hard Fork)
- EIP-1559 — new transaction format with a dynamically adjusting base fee and optional miner tip (
priorityFee). On Ethereum Classic the base fee is not destroyed — it is credited at the consensus layer to theSOVEREIGNTY_VAULTaddress. Miner tips continue to be paid directly to miners, unchanged. - EIP-3198 — opcode
0x48(BASEFEE), giving contracts access to the current block’s base fee.
No other EVM changes, consensus rules, or opcodes are introduced.
Consensus-Layer Redirection
EIP-1559 charges every transaction a base fee and destroys it. This ECIP credits that amount to a fixed address instead, and changes nothing else about the fee mechanism.
The credit is made within the transaction’s own state transition, at the point in EIP-1559’s block-validation pseudocode where the base fee is otherwise destroyed — immediately after the miner is credited its priority fee, and after the signer has been refunded for unused gas:
# Unchanged from EIP-1559: the miner only receives the priority fee.
self.account(block.author).balance += gas_used * priority_fee_per_gas
# EIP-1559 destroys the remainder at this point. This ECIP credits it instead.
self.account(SOVEREIGNTY_VAULT).balance += gas_used * block.base_fee_per_gas
The second line is the whole of the change, including EIP-1559’s own base-fee adjustment arithmetic, which is unchanged.
The credit is per transaction. Implementations MUST NOT compute it as a single block-level product at finalization, and MUST NOT do both. block.gasUsed × block.baseFeePerGas yields the same total for the block, so the two rules agree on the state root at a block boundary and disagree everywhere inside one: under this ECIP, transaction N+1 observes a Vault balance that already carries the base fees of transactions 1..N of the same block, and that balance is readable by BALANCE.
The amount credited MUST equal the base fee charged to the sender for that transaction, computed on the same gas quantity that transaction contributes to block.gasUsed.
Every transaction included in a block pays the base fee on the gas it consumes, and every such payment is credited. A transaction that reverts still consumes gas, still pays the base fee, and its credit MUST occur.
The credit MUST be a direct addition to the account’s balance, and MUST NOT be implemented as a call to the destination. No EVM code executes: no fallback or receive function body runs, no log is emitted, no gas is consumed, and the receiving account can neither observe nor refuse the credit. The destination may hold a contract with a payable fallback, so a credit performed as a call would enter that code, consume gas, and create a failure path where none may exist.
The Destination Address
SOVEREIGNTY_VAULT is a chain-configuration parameter holding one address per network, carried in the chain specification each participating client ships — the same configuration surface §Rationale shows Nethermind and Erigon already exposing for this purpose. Changing it therefore costs a coordinated client release, and no on-chain party can change it at all. ECIP-1112 specifies what is deployed at it and how its value is published.
Base Fee Constants and the Minimum Base Fee Floor
Two constants govern the base fee, and they are distinct values that MUST be declared separately in client configuration:
| Constant | Value | Role |
|---|---|---|
INITIAL_BASE_FEE |
1,000,000,000 wei (1 gwei) | EIP-1559’s one-shot value, used for the base fee of the fork block itself |
MIN_BASE_FEE |
1,000,000,000 wei (1 gwei) | a permanent floor, applied to the result at every block |
They share a value here and are not the same constant. Deriving one from the other, or expressing one in terms of the other, is a conflation this ECIP forbids.
baseFeePerGas = max(eip1559BaseFee(parent), MIN_BASE_FEE)
Both constants are carried in chain configuration.
eip1559BaseFee(parent) is EIP-1559’s expected_base_fee_per_gas, computed exactly as that EIP specifies. This ECIP changes the destination of the base fee and clamps its value; it changes nothing about the adjustment arithmetic. The clamp interacts with that arithmetic, and the interaction admits two errors that leave a client correct on this chain and wrong elsewhere:
| Parent block | Result before the clamp |
|---|---|
| Fork block (parent precedes the transition) | INITIAL_BASE_FEE |
gasUsed == gasTarget |
parent’s baseFeePerGas, unchanged |
gasUsed > gasTarget |
parent + max(parentBaseFee × gasUsedDelta ÷ gasTarget ÷ BASE_FEE_MAX_CHANGE_DENOMINATOR, 1) |
gasUsed < gasTarget |
parent − parentBaseFee × gasUsedDelta ÷ gasTarget ÷ BASE_FEE_MAX_CHANGE_DENOMINATOR |
The max(…, 1) applies to the increase delta only. EIP-1559 places no floor on the decrease delta, and an implementation MUST NOT add one: doing so over-decrements small base fees relative to EIP-1559. The error is unobservable on any chain whose MIN_BASE_FEE exceeds the value at which the decrease delta truncates to zero — which is every chain conforming to this ECIP — so an implementation that shares this code path with an unfloored network is correct here and forks there.
The clamp MUST be applied to the result on every path above, including the fork block. Applying it only on the decreasing path yields correct results solely while MIN_BASE_FEE == INITIAL_BASE_FEE: the other paths are non-decreasing from the parent, so the floor survives by induction from a base case the fork block supplies. That equality is a coincidence of the values chosen here, not a property of the design, and an implementation relying on it produces sub-floor base fees for any other pairing.
The clamp MUST be applied in both block production and block validation, so that a produced block and a validated block cannot disagree, and a block whose baseFeePerGas differs from the value this section specifies MUST be rejected — exactly as EIP-1559 already requires for its own computation.
Rationale
Credit, not destroy — and the mechanism is a shipped client feature rather than a modification. Redirecting the EIP-1559 base fee to an address held in chain configuration is implemented generically by more than one independent Ethereum client, and is active on the production networks tabulated below. Nethermind exposes it as the chain-specification parameters feeCollector and eip1559FeeCollectorTransition; Erigon exposes it as burntContract, a map from activation block to destination address. Neither is a fork or a patch: both are ordinary configuration surfaces that any chain those clients serve may set.
| Network | Destination held in chain configuration | Active from |
|---|---|---|
| Gnosis (and its Chiado testnet) | 0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92 |
block 19,040,000 |
| Polygon PoS (and its Amoy testnet) | 0x70bcA57F4579f58670aB2d18Ef16e02C17553C38, later 0x7A8ed27F4C30512326878652d20fC85727401854 |
block 23,850,000, later 50,523,000 |
| Taiko Alethia (and its Hoodi testnet) | 0x1670000000000000000000000000000000010001 |
genesis |
| POA Core | 0x517F3AcfF3aFC2fb45e574718bca6F919b798e10 |
block 24,090,200 |
| Ronin, in its Layer 1 era | 0xb903E3936d3ca90b69b29F1df2810083a2DC0d71 |
block 43,447,600 |
Linea declares the same transition in its chain specification. What differs between these networks is policy at the far end, not mechanism: some destinations forward value onward for destruction, others fund network operations. The consensus rule is the same one this ECIP specifies.
Holding the destination in chain configuration is what makes it costly to change, and there is a worked precedent for exactly that. Polygon PIP-24, “Change EIP-1559 Policy”, moved that network’s base-fee recipient by “adding a new entry in burntContract with the hardfork block number and the new address in Bor’s Genesis file” — a coordinated client release activating at a scheduled block. That is the property this ECIP relies on: an address in chain configuration cannot be changed by any on-chain party, only by the same instrument that installed it. A destination held instead in a contract could be changed by whoever controls that contract, which would make a consensus parameter mutable by a party outside consensus.
Enforcing the credit at the consensus layer, rather than at the application layer, guarantees deterministic and identical behavior across all clients. An application-layer mechanism could not make the same guarantee without trusting a specific contract’s correctness at every block.
Per transaction, because that is where EIP-1559 itself puts it. EIP-1559’s block-validation pseudocode destroys the base fee inside its per-transaction loop: the signer is debited the effective gas price, the miner is credited the priority fee, and the difference — the base fee — is destroyed at that point, with the EIP’s own comment marking the line. Crediting it there is therefore a one-line change to the mechanism being activated, in the position the mechanism already defines. Computing a block-level total at finalization would be a structurally different rule that happens to agree on totals.
The same placement is what production clients implement. Nethermind, Erigon, and Ronin’s Layer 1 client each credit the configured destination inside the per-transaction state transition, immediately after the producer’s tip, and each excludes transactions that pay no base fee. Aligning with them means a conforming Ethereum Classic client sets a configuration value on an existing code path rather than adding a finalization hook that no such client has.
A fixed floor preserves EIP-1559’s adjustment mechanics above it while guaranteeing a non-zero base to operate from, and it is set at one gwei — one unit of the denomination in which gas prices are expressed, and the magnitude EIP-1559 itself uses for INITIAL_BASE_FEE. At fixed demand, revenue is directly proportional to the floor, so the value is a user-cost decision rather than a revenue-maximizing one.
A permanent floor distinct from EIP-1559’s one-shot initial value is established practice across independent client frameworks, and they differ in where the value is held rather than in whether to have one:
| Framework | Permanent floor | Where the value is held | What can change it |
|---|---|---|---|
| Ronin | 1 gwei, declared as MinimumBaseFee alongside a separate InitialBaseFee of the same value |
client constant | a client release |
| OP Stack, as configured by Base | 5,000,000 wei (0.005 gwei) on both of its networks | the SystemConfig contract, propagated into block header extra data |
setMinBaseFee(uint64), restricted to that contract’s owner |
| Avalanche subnet-evm | a required, non-nil field of every chain’s fee configuration; 25 gwei by default | chain fee configuration | the FeeManager precompile, under its allow-list admin |
| Taiko | 5,000,000 wei, clamped during header validation | client constant | a client release |
Ronin’s two-constant declaration is the pattern this ECIP adopts, and the reason is the same one that decides the destination: two of the four frameworks above hold the floor where a party outside consensus can raise or lower it. Ethereum Classic has no such party, so the value belongs where changing it requires a coordinated client release.
Measured from ETC Mainnet block headers on 2026-08-11, over blocks 24,950,000 to 25,128,560 at a stride of 180 — 993 headers spanning 28.0 days, read independently from two public RPC endpoints then listed for this network at chainlist.org, which agreed on every sampled header:
| Quantity | Measured |
|---|---|
| Mean gas used per block | 35,414 |
| Aggregate utilization | 0.4427 % against an 8,000,000 limit |
| Empty blocks | 76.3 % (758 of 993) |
Revenue scales linearly with gas consumed, so it grows with adoption without governance action, and while blocks remain largely empty it is bounded by MIN_BASE_FEE.
Backwards Compatibility
Fully additive: a new transaction type (Type-2) and a new opcode (BASEFEE, 0x48). Type-0 and Type-1 transactions, existing deployed contracts, and historical state are unaffected. Clients that do not implement this ECIP will fork from the canonical chain at the activation block, as with any consensus change.
Monetary policy (ECIP-1017) is unchanged — this ECIP replaces destruction with accumulation, and alters neither Ethereum Classic’s total supply nor its issuance schedule.
Test Cases
Cross-client state-transition equivalence MUST be demonstrated on Mordor Testnet before a Mainnet activation block is scheduled. Vectors MUST cover:
| Case | Expected |
|---|---|
| Base-fee adjustment across empty, partial and full blocks | matches EIP-1559 mechanics above the floor |
| Sustained empty blocks, 1,000 or more consecutive | baseFeePerGas never falls below MIN_BASE_FEE |
MIN_BASE_FEE configured strictly greater than INITIAL_BASE_FEE |
the fork block, and every subsequent block at or above target, MUST still return MIN_BASE_FEE. A vector run only where the two constants are equal cannot distinguish an enforced floor from a coincidental one, and does not discharge this row |
MIN_BASE_FEE configured strictly below the parent’s base fee, parent at target |
result is the parent’s base fee — the clamp raises, never lowers |
Decrease delta truncating to zero (parent base fee small enough that parentBaseFee ÷ 8 floors to 0, floor disabled) |
base fee is unchanged, not decremented by 1. An implementation flooring the decrease delta at 1 MUST fail this vector |
| Increase delta truncating to zero | base fee increases by exactly 1 — the max(…, 1) on the increasing path only |
| Fork block | equals max(INITIAL_BASE_FEE, MIN_BASE_FEE); INITIAL_BASE_FEE is applied once and is a distinct constant from the floor |
| Vault credit, per transaction | after each transaction, the Vault’s balance has increased by exactly that transaction’s gasUsed × block.baseFeePerGas |
| Vault credit observed mid-block | a transaction reading BALANCE of the Vault address observes the base fees of all preceding transactions in the same block. An implementation crediting a block-level total at finalization MUST fail this vector, and it is the vector that distinguishes the two rules |
| Vault credit under double accounting | an implementation that credits per transaction and adds a block-level total at finalization MUST fail |
| Reverted transaction | consumes gas, pays the base fee, and credits the Vault exactly as a successful transaction does |
| EVM code executed by the credit | none. No fallback or receive body runs at the destination, no log is emitted, no gas is consumed, and the credit cannot revert. A vector asserting only the resulting balance does not discharge this row |
| Miner credit | gasUsed × priorityFeePerGas only; unaffected by the Vault credit |
BASEFEE opcode (0x48) |
returns the current block’s baseFeePerGas, including on the fork block |
| Every transaction type valid at the activation block | the base fee applies uniformly across all of them, with legacy pricing handled per EIP-1559. Vectors MUST be derived from the set the chain’s active fork configuration admits at that block, rather than from a fixed enumeration here |
| Fork ID | validates across the activation block |
| Both networks | identical results on ETC Mainnet (chainId 61) and Mordor Testnet (chainId 63) |
Security Considerations
This ECIP introduces no consensus-critical logic beyond EIP-1559 and EIP-3198. The only functional deviation from Ethereum’s own EIP-1559 is the destination of the base fee, enforced identically to any other consensus rule.
The credit executes no EVM code, consumes no gas, and cannot fail. It therefore introduces no new failure path into the state transition, and this ECIP’s correctness does not depend on what is deployed at the destination address, on that contract’s behavior, or on any later change to it. A contract at the address cannot refuse the credit, cannot observe it as it happens, and cannot cause a transaction to fail by receiving it. A compromise of that account therefore costs the balance held rather than the correctness of any block.
The failure mode that does exist is client divergence, and it is the ordinary one. An implementation that credits a different amount, credits at a different point in the state transition, or performs the credit as a call rather than as a balance addition produces a different intermediate state, and forks. That risk is a risk of incorrect implementation rather than a novel vulnerability class, and §”Test Cases” carries a vector for each way of getting it wrong.
Step Changes to the Minimum Base Fee
A future hard fork that changes MIN_BASE_FEE applies the new value as an immediate step at the activation block, with no EIP-1559-style adjustment ramp. This is consistent with the fork block itself, where INITIAL_BASE_FEE is applied as a discontinuous jump from no base fee to 1 gwei. Both are consensus parameter changes gated by hard fork, and both take effect at a single block by design. Smoothing a floor change would introduce transition-state tracking not required by any other rule in this ECIP, contradicting its minimal-surface intent. This is an accepted design property, not an omission.
Implementation
Activation blocks are to be finalized through open coordination among client implementers, node operators, miners, exchanges, and infrastructure providers:
- Mordor Testnet:
TBD - ETC Mainnet:
TBD
This ECIP is the only document in which these blocks are recorded.
Cross-client agreement is evidence that this specification is unambiguous only where the implementations do not share a state-transition codebase. Before this ECIP advances to Final, the vectors above MUST be executed on at least two implementations whose state-transition code derives from unrelated upstreams, and both the vectors and their results MUST be published as data a third party can re-execute.
References
Where a third-party repository is cited, the ref is a commit rather than a branch or tag: a commit cannot move, while a branch resolves to different code over time and is therefore not a citation.
-
EIP-1559, “Fee market change for ETH 1.0 chain” (Final), https://eips.ethereum.org/EIPS/eip-1559 — including the block-validation pseudocode whose per-transaction loop §”Consensus-Layer Redirection” extends
-
EIP-3198, “BASEFEE opcode” (Final), https://eips.ethereum.org/EIPS/eip-3198
-
Nethermind, https://github.com/NethermindEth/nethermind @
2706ce9e02— the generic fee-collector mechanism named in §Rationale: thefeeCollectorandeip1559FeeCollectorTransitionchain-specification parameters, and their application in the per-transaction fee payment. The Gnosis, Chiado, Taiko Alethia, Taiko Hoodi, POA Core and Linea chain specifications distributed with that client are where the per-network values in §Rationale are read -
Erigon, https://github.com/erigontech/erigon @
527e210d7a— theburntContractchain-configuration parameter, a map from activation block to destination address, and its application in the per-transaction state transition. The Gnosis, Chiado, Polygon PoS and Polygon Amoy chain specifications distributed with that client are where those networks’ values are read -
Foundry, https://github.com/foundry-rs/foundry @
3c16e23—crates/cast/src/tx.rsandcrates/forge/src/cmd/create.rs, where a legacy transaction is sent only on an explicit flag or on a chain the registry reports as pre-EIP-1559. That registry isalloy-rs/chains, https://github.com/alloy-rs/chains @e30fd86, whoseChain::is_legacy()returnsfalsefor any chain it does not name and which names none at chain ID 61 -
Polygon Improvement Proposal 24, “Change EIP-1559 Policy” (Final), https://github.com/0xPolygon/Polygon-Improvement-Proposals/blob/1b5292a57ac0846f4f9157062b9e7cd844713c5c/PIPs/PIP-24.md — the destination change quoted in §Rationale, and the statement that it is made by adding an entry to
burntContractwith a hard-fork block number -
Sky Mavis,
ronin-chain/ronin, https://github.com/ronin-chain/ronin. The Layer 1 base-fee handling cited in §Rationale is at commitse7ef8ca8c,37d10f703andeaef5a292; the migration to a Layer 2 at09f2d2d3candfb7fc1fa8. The two base-fee constants and their enforcement are read ate8679e9f8,params/protocol_params.goandconsensus/misc/eip1559/eip1559.go. The repository is tagged, but its newest tag predates every commit cited here, so a commit is the only ref that reaches them -
OP Stack Specification, Jovian execution engine, https://specs.optimism.io/protocol/jovian/exec-engine.html — the minimum-base-fee clamp cited in §Rationale. The value is configured in the
SystemConfigcontract, https://github.com/ethereum-optimism/optimism/blob/0f21af947798a94aa50e797c61f576ca18b1334d/packages/contracts-bedrock/src/L1/SystemConfig.sol, whosesetMinBaseFee(uint64)is restricted to that contract’s owner -
Base, “Network fees”, https://docs.base.org/base-chain/network-information/network-fees — the 5,000,000 wei (0.005 gwei) figure, stated for both Base networks
-
Ava Labs,
subnet-evm, https://github.com/ava-labs/subnet-evm @edc9ebe712—commontype/fee_config.go, the required, non-nilMinBaseFeefield of every chain’s fee configuration, andprecompile/contracts/feemanager/contract.go, theFeeManagerprecompile whosesetFeeConfigchanges it under that precompile’s allow-list -
ECIP-1000, “ECIP Purpose and Guidelines”
-
ECIP-1017 (2016), “Monetary Policy and Final Modification to the Ethereum Classic Emission Schedule”
-
Chainlist, “Ethereum Classic”, https://chainlist.org/chain/61 — a stable address at which the public RPC endpoints currently serving chain ID 61 are listed. The set changes as operators start and stop serving, which is why this reference names the list rather than an endpoint. The endpoints a measurement is read from are an instrument and not evidence: the block headers §Rationale measures are canonical chain data, re-readable from any Ethereum Classic node.
Copyright
Copyright and related rights waived via CC0.