EIP-2929 & 2930: pricing state access by what it really costs
Reading state is the most disk-expensive thing a node does, but the EVM charged a flat, far-too-cheap price for it — so an attacker could touch thousands of slots for almost nothing and grind every node to a halt. The fix prices the first touch at its real cost and makes repeats cheap; access lists let a transaction pre-declare what it will touch.
- the gas model
- storage & SLOAD
Gas is supposed to track the real cost of work, so the chain can’t be cheaply overloaded. But for years the EVM mispriced its most expensive operation: reading state. An SLOAD or an account lookup forces a node to chase data through the Merkle-Patricia trie and off disk — slow, real work — yet it was billed a flat, tiny fee. That gap was more than inefficiency; it was an attack surface, and in 2016 it was used to bring Ethereum to a crawl. EIP-2929 repriced state access, and EIP-2930 softened the side effects with access lists. Let’s derive both.
The problem: a flat price far below the real cost
Accessing state is the most expensive thing a node does per unit of gas, because it means a trie lookup To read a storage slot or account, a node walks the Merkle-Patricia trie, fetching nodes from disk along the path. It's I/O-bound and far slower than in-memory EVM computation — the real bottleneck in block validation. and disk I/O. Earlier repricings had already raised the flat price — after EIP-150 and EIP-1884, SLOAD sat at 800 gas and touching an account at 700 — yet a single flat number is still the wrong shape. Price it for a cold first touch that genuinely hits disk and you overcharge the common case of reading the same slot again from memory; price it for that common case and a transaction that touches thousands of distinct slots or accounts pays almost nothing per touch, forcing every node on Earth to do enormous disk work to validate your block.
This isn’t hypothetical: the 2016 “Shanghai” attacks spammed state-touching opcodes — then priced at just 20–50 gas — to drag block processing to tens of seconds. The flat raises of EIP-150 and EIP-1884 were the immediate patch; EIP-2929 is the structural fix they pointed to.
→ Step 2: notice that repeats aren’t expensive.
Why a flat increase is the wrong fix
The obvious move — make SLOAD cost, say, 2100 gas across the board — overcharges the most common honest pattern. The first time you read slot X, the node really does pay for the trie lookup. But the second and third reads of the same slot in the same transaction are nearly free: the data is already loaded into the node’s memory. A flat high price bills all three at full cost, making ordinary contracts that re-read a slot in a loop dramatically more expensive for work the node isn’t actually redoing.
So a single number can’t be right. The cost depends on whether you’ve already touched this thing in this transaction. That’s the insight the real fix is built on.
→ Step 3: split the price in two.
EIP-2929: cold the first time, warm after that
Price by novelty. The EVM keeps a per-transaction access set Two sets the EVM tracks during a transaction — accessed_addresses and accessed_storage_keys. Touching an address or slot adds it to the set; the set determines whether the next access is cold (first) or warm (repeat). of every address and slot you’ve touched. The first access to a given address or slot is cold access The first touch of an address or storage slot in a transaction. It pays the real, high cost — 2600 gas for an account, 2100 for a storage slot — reflecting the trie/disk lookup. and pays the real cost — 2600 gas for an account, 2100 for a storage slot. Every subsequent access in the same transaction is warm and costs just 100 gas. The dangerous case (touch thousands of distinct slots) now pays full freight each time and is priced out of being a DoS; the common case (re-read the same slot) stays cheap. One distinction fixes both.
- 1 first touch in the tx: a slot costs 2100, an account 2600 — the real disk cost
- 2 every later touch: already cached, so nearly free
→ Step 4: let the transaction warm things up in advance.
EIP-2930: declare what you’ll touch, and pre-warm it
Give transactions a way to pre-pay and pre-warm. An access list An optional list of (address, storage keys) a transaction declares it will access. Listed entries start the transaction already warm, so their first in-execution access is charged the warm price. Carried by the type-0x01 transaction. is a list of (address, storage keys) the transaction states up front. Everything declared is added to the access set before execution, so its first in-contract access is charged the warm price instead of cold. You pay a modest upfront fee for declaring — 2400 gas per address and 1900 per slot, slightly below the cold costs — so it’s a small discount, but more importantly it removes the cold-access surprise and was the escape hatch for contracts the repricing would otherwise have broken. And this is delivered by a brand-new transaction type, 0x01 — the very first user of the EIP-2718 typed-transaction envelope.