Solia saysBeacon proxies point every clone at a single Beacon contract holding the implementation address — flip the beacon and all proxies upgrade atomically.
Mass-cloning a contract via EIP-1167 gives a fixed implementation per clone. If you want to upgrade them all, you have to redeploy each. Beacon proxies add one indirection: every proxy asks a beacon contract for the current implementation address. Updating the beacon upgrades every proxy in one transaction.
Used by OpenZeppelin's UpgradeableBeacon, the pattern is ideal for systems with many homogeneous instances: per-user vaults, NFT collections sharing logic, marketplaces. The demo upgrades a beacon and shows all 100 proxies switch atomically.
Power-ups you unlock
Every proxy reads its implementation from a beacon contract
Update the beacon → every proxy upgrades atomically
Ideal for many homogeneous instances (vaults, NFTs)
Adds one external call per proxy invocation
Beacon admin must be carefully secured (single upgrade key)
The Reentrancy Reaper attacks — common mistakes
Concentrating beacon admin in one EOA
Forgetting storage layout drift across upgrades affects all proxies at once
Using a beacon when only one or two instances exist (overkill)
Coupling beacon proxies with per-instance state migration without a plan
Boss battleDeploy 100 beacon-backed proxies, upgrade the beacon, and confirm every proxy uses the new implementation.
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 beacon = { impl: 'v1.0' };
const proxies = Array.from({length:100}, (_,i) => ({ id:'proxy-' + i }));
const readImpl = () => beacon.impl;
const upgrade = (newImpl) => beacon.impl = newImpl;
const before = proxies.map(_ => readImpl());
upgrade('v2.0');
const after = proxies.map(_ => readImpl());
const allBefore = before.every(i => i === 'v1.0');
const allAfter = after.every(i => i === 'v2.0');
document.getElementById('o').textContent = [
'100 proxies pointing at beacon (impl = ' + 'v1.0' + ')',
' all on v1.0? ' + allBefore,
'',
'beacon.upgradeTo("v2.0") — one transaction',
'',
'100 proxies now read impl = ' + beacon.impl,
' all on v2.0? ' + allAfter + ' (atomic upgrade of every clone)'
].join('\n');
</script></body></html>