freecoding.school100% FREE · NO SIGNUP
The EVM CoreISSUE #21 of 48

access lists · warm vs cold · eip-2929/2930

SoliaVSThe Reentrancy Reaper
Solia saysEIP-2929 doubled SLOAD cold cost to 2100 (warm 100). EIP-2930 access lists let a tx pre-warm slots for 1,900 gas each — saving 200 per access after the first.

Pre-Berlin, every SLOAD cost 800 gas. EIP-2929 repriced them to 2,100 cold (first access in a tx) and 100 warm (subsequent), making first-touch much more expensive. EIP-2930 added an optional access list on a transaction: declare upfront which addresses and slots you will touch, pay 1,900 gas per slot, and every access of those slots is warm. Net savings: 200 gas per access beyond the first.

Access lists pay off when a contract touches the same slot many times or wants to make gas costs more predictable. The demo computes the savings for six accesses across three unique slots.

Power-ups you unlock

The Reentrancy Reaper attacks — common mistakes

Boss battleCompute the gas saved by an access list for 6 accesses across 3 unique slots vs no access list.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
const COLD = 2100, WARM = 100, AL_COST = 1900;
const accesses = ['slot1','slot2','slot1','slot3','slot2','slot3'];   // 6 accesses, 3 unique
const warmed = new Set();
let gasNoAL = 0;
for(const a of accesses){ gasNoAL += warmed.has(a) ? WARM : COLD; warmed.add(a); }
const unique = new Set(accesses);
const gasWithAL = unique.size * AL_COST + accesses.length * WARM;
const savings = gasNoAL - gasWithAL;
document.getElementById('o').textContent = [
  'access pattern: ' + accesses.join(', ') + '   (' + accesses.length + ' accesses, ' + unique.size + ' unique)',
  '',
  'WITHOUT access list:',
  '  ' + Array.from(unique).length + ' cold @ ' + COLD + ' + ' + (accesses.length - unique.size) + ' warm @ ' + WARM + ' = ' + gasNoAL.toLocaleString() + ' gas',
  '',
  'WITH access list (pre-warm ' + unique.size + ' slots @ ' + AL_COST + '):',
  '  ' + (unique.size*AL_COST).toLocaleString() + ' AL + ' + (accesses.length*WARM).toLocaleString() + ' warm accesses = ' + gasWithAL.toLocaleString() + ' gas',
  '',
  'savings: ' + savings.toLocaleString() + ' gas (~' + Math.round(100*savings/gasNoAL) + '%)'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Transient Storage · Eip-1153The Yellow Paper · Formal Evm Semantics ›