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

the diamond standard · eip-2535 facets

SoliaVSThe Reentrancy Reaper
Solia saysThe Diamond Standard (EIP-2535) splits one contract into many "facets" routed by function selector — letting you ship contracts larger than the 24KB code limit and upgrade pieces independently.

Ethereum caps contract code at 24 KB (EIP-170). For complex protocols this is painful: a full ERC-20 + ERC-721 + governance contract bursts the limit. EIP-2535 Diamonds solve this with a proxy that routes calls based on the 4-byte function selector to one of many facets — separate implementation contracts each holding some subset of the protocol's functions.

You can add, replace, or remove facets via a diamondCut call, independently per function. The trade-off is complexity: storage must use a shared layout (DiamondStorage pattern), and the routing table itself takes storage. The demo dispatches four selectors to their facets.

Power-ups you unlock

The Reentrancy Reaper attacks — common mistakes

Boss battleDispatch four function selectors to a 3-facet diamond and identify which facet each routes to.

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 facets = {
  '0xa9059cbb': { facet:'ERC20Facet',   fn:'transfer' },
  '0x70a08231': { facet:'ERC20Facet',   fn:'balanceOf' },
  '0xb88d4fde': { facet:'NFTFacet',     fn:'safeTransferFrom' },
  '0xab2af3f4': { facet:'GovernanceFacet', fn:'castVote' }
};
function diamondCall(selector){
  return facets[selector] ? 'routes → ' + facets[selector].facet + '.' + facets[selector].fn : 'no facet → REVERT';
}
const calls = ['0xa9059cbb','0x70a08231','0xb88d4fde','0xab2af3f4','0xdeadbeef'];
document.getElementById('o').textContent = [
  'diamond proxy routing table:',
  ...Object.entries(facets).map(([s,f]) => '  ' + s + ' → ' + f.facet + '.' + f.fn),
  '',
  'dispatch:',
  ...calls.map(s => '  ' + s + ' → ' + diamondCall(s))
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Proxy Patterns · Transparent Vs UupsBeacon Proxies · Mass Upgrades ›