EIP-2200: the storage price that postponed a fork
Writing the same storage slot three times in one transaction paid full price three times — even though only the final value ever reaches disk. Net gas metering fixed that, but the first attempt (EIP-1283) made writes so cheap that a 2300-gas stipend call could suddenly modify storage, reopening reentrancy — and got Constantinople postponed. EIP-2200 re-ships it with a sentry.
- state & storage (SSTORE)
- gas & the reentrancy stipend
Istanbul, December 2019. Every write to contract storage — an SSTORE — costs gas, and pricing it fairly is harder than it looks. The original scheme charged per operation: touch a slot, pay the full price. But a transaction often writes the same slot several times before it ends, and only the last value is ever persisted to disk. Charging full freight for each intermediate write overcharges some of the most common patterns on the chain. The fix — net gas metering — is elegant. It’s also the change that, on its first attempt, quietly reopened a reentrancy hole and got an entire hard fork postponed hours before launch. EIP-2200 is the version that got it right. Let’s derive it, mistake and all.
The problem: you pay per write, but only the net change persists
The original SSTORE pricing was per-operation: setting a slot from zero to non-zero cost 20000 gas, changing an existing non-zero value cost 5000, and clearing a slot back to zero earned a refund. Simple — but it ignores that a transaction is a unit. Only the slot’s value at the transaction’s end is written to the state trie; everything in between is scratch work. So a contract that increments a counter three times in one call pays 5000 × 3, even though the disk only ever sees the single net change from the start value to the final one. The same tax hits reentrancy lock A storage flag a contract sets on entry and clears on exit to prevent a function from being re-entered mid-execution. Under per-operation pricing, the set-then-clear round-trip pays full price both ways, making a basic safety pattern expensive. s (set the flag, do work, clear it) and any use of storage as a scratchpad.
→ Step 2: price the net effect instead — but watch what it unlocks.
Net gas metering, and the bug that postponed Constantinople
The fix is net gas metering Pricing SSTORE by comparing the new value to the slot's value at the start of the transaction (the 'original' value), rather than charging a flat fee per write. No-op writes and repeated writes to an already-dirty slot cost a small 'warm' fee; refunds are tuned so that round-trips like A→B→A are nearly free. : compare each write to the slot’s value at the start of the transaction, and charge accordingly. A write that doesn’t change the original value, or that re-touches an already-modified slot, costs only a small “dirty” fee — as little as 200 gas — while genuine first-time changes still pay full price. Counters, locks, and scratchpads get dramatically cheaper. This first shipped as EIP-1283, slated for the Constantinople fork.
And that’s where it went wrong. Ethereum has a safety convention: a plain value transfer (.transfer() / .send()) forwards a fixed 2300-gas stipend The small, fixed amount of gas forwarded with a plain Ether transfer. It was deliberately chosen to be enough to log an event but too little to modify storage — so a recipient's fallback couldn't perform a reentrancy attack. EIP-1283's 200-gas writes broke that guarantee. to the recipient — deliberately too little to modify storage, which is what kept a recipient’s fallback function from mounting a reentrancy attack. But once SSTORE could cost 200 gas, a fallback running on just the 2300-gas stipend could write to storage after all. Security researchers spotted this days before Constantinople was due to activate. The fork was postponed and EIP-1283 pulled.
→ Step 3: keep the savings, restore the guarantee — with a guard.
EIP-2200: net metering behind a sentry
EIP-2200 re-introduces net gas metering in Istanbul with one crucial addition: a sentry A guard at the top of SSTORE (SSTORE_SENTRY_GAS = 2300): if the gas remaining is at or below 2300, SSTORE reverts outright. This restores the invariant that a 2300-gas stipend can never modify storage, closing the reentrancy hole while keeping net metering's savings for calls that have real gas. . Before doing anything, SSTORE checks the gas remaining: if it’s 2300 or less, the operation reverts. A fallback running on only the transfer stipend therefore cannot write storage — the exact invariant the old 5000-gas floor gave for free — while any call with real gas keeps net metering’s cheap repeated and temporary writes. The savings survive; the reentrancy hole closes.