Part III · Chapter 8 of 43 · Tangerine Whistle

EIP-150: when gas became a security parameter

In 2016 an attacker discovered that Ethereum's most expensive operations — reading storage, loading accounts — were priced far below what they actually cost a node. A few cheap transactions could grind every node on Earth to a crawl. EIP-150 repriced them, and in doing so turned gas from a nominal fee into a line of defense.

Updated Sep 13, 2026 · 10 min
Assumed
  • the EVM & gas
  • storage & state access

The EVM chapter sold gas as the thing that makes computation paid-for and bounded. That framing has a hidden assumption: that each opcode’s price actually reflects the work it causes a node to do. In October 2016, at the Tangerine Whistle fork, Ethereum learned the hard way what happens when that assumption is false. Some operations — the ones that reach into state and disk — were priced at a small fraction of their real cost, and an attacker turned that gap into a weapon that nearly stopped the chain. EIP-150 is the fix, and it’s where the community internalized that gas isn’t a fee schedule — it’s a security parameter. Let’s derive it.

1 step Cheap ops, heavy cost

The problem: the price tag didn’t match the work

Most EVM opcodes are pure computation — add, compare, hash — and their cost is honest. But the opcodes that touch state are different: SLOAD chases a key through the state trie and off disk; CALL, BALANCE, EXTCODESIZE, and EXTCODECOPY each load another account’s data. Those are the slowest things a node does — and in 2015’s gas schedule they were nearly free: SLOAD cost 50 gas, account-touching opcodes 20–40. The price tag sat far below the real burden.

the price tag sat far below the real cost SLOAD 50 gas ≫ disk read CALL 40 gas ≫ loads account EXTCODESIZE 20 gas ≫ reads code BALANCE 20 gas ≫ reads state attacker tx call ×5000, cheap node work / block ~30s/block · stalls cheap-but-heavy opcodes, called thousands of times, froze block processing the 2016 Shanghai denial-of-service attacks
SLOAD, CALL, BALANCE, and EXTCODESIZE all reach into state and disk — the most expensive work a node does — yet were priced at 20–50 gas. A transaction that invokes them thousands of times costs the attacker almost nothing but forces every node into enormous disk I/O.

That gap is a resource-exhaustion attack Crafting cheap transactions that trigger disproportionately expensive work on every validating node — here, spamming underpriced state-access opcodes so block processing slows to a crawl, threatening liveness. . In September–October 2016 the Shanghai DoS attacks A series of 2016 denial-of-service attacks that spammed underpriced IO-heavy opcodes (EXTCODESIZE, then SUICIDE/SLOAD variants), pushing some blocks to tens of seconds of processing time and threatening to stall Ethereum. did exactly this: transactions that hammered these opcodes pushed block processing to tens of seconds, and the network came close to grinding to a halt.

→ Step 2: raise the prices to match the cost.

2 step Reprice to reality

Gas is a security parameter — so align it to real cost

The fix isn’t clever, it’s corrective: raise the gas cost of the IO-heavy opcodes until it reflects what they actually make a node do. EIP-150 pushed SLOAD from 50 to 200, BALANCE and EXTCODESIZE and the account-loading opcodes up to 400–700, CALL to 700, and so on. Once the price matches the burden, the very attack that stalled the chain now costs the attacker real gas — and is simply priced out of a block.

reprice to real cost — the bar grows to match SLOAD 50 200 BALANCE 20 400 EXTCODESIZE 20 700 CALL 40 700 EXTCODESIZE jumps 20 → 700 — 35× — so the attack no longer fits in a block
EIP-150 raises the IO-heavy opcodes to reflect their real cost — SLOAD 50 → 200, BALANCE 20 → 400, EXTCODESIZE 20 → 700, CALL 40 → 700. The same spam transaction now costs far too much gas to fit in a block, so the denial-of-service evaporates.

The lasting lesson is bigger than the numbers. gas as a security parameter The principle, cemented by EIP-150, that opcode gas costs must track the real CPU, disk, and state-growth burden each operation imposes on nodes — because any operation priced below its true cost is a potential denial-of-service vector, not just a bargain. means the gas schedule is part of Ethereum’s threat model, not just its fee model. Every later repricing — and there have been many — traces back to this realization.

→ Step 3: never forward the last drop of gas.

3 step Keep gas in reserve

The 63/64 rule: always keep a sliver back

EIP-150 shipped a second, subtler change alongside the repricing. When a contract calls another, it may forward at most 63/64 of its remaining gas — it always keeps at least 1/64 for itself. So no matter how deeply calls nest or how greedily a callee burns what it’s handed, the caller is guaranteed to survive the sub-call with a little gas left: enough to notice the failure, clean up, and return an error instead of dying outright.

cap forwarded gas — always keep 1/64 back caller's gas budget G forwarded ≤ 63/64 1/64 callee runs, may burn it all survives ✓ the kept 1/64 lets the caller handle the failure cleanly so a deep call can never strand the caller with zero gas
A call forwards at most 63/64 of the caller's remaining gas and keeps at least 1/64 in reserve. Even if the callee consumes everything it's given, the caller retains a sliver — enough to handle the failure cleanly rather than being left stranded with zero gas.
04 Go Deeper Where to take it from here