A proxy declares its own state variables in low slots that overlap the implementation's storage, or a new implementation reorders/inserts variables. Reads and writes then hit the wrong slot, silently corrupting balances, ownership, or guards after an upgrade.
// V2 inserts `uint newVar;` before `address owner;`. // owner now reads the slot that held newVar (=0) -> owner is address(0) // or an attacker-controlled value; admin takeover.
// use unstructured storage (ERC-1967) for proxy slots; never reorder // implementation state - only append, and keep a __gap. bytes32 constant _IMPL = keccak256("eip1967.proxy.implementation");
Largest recorded losses in the same failure class — related, not the same bug:
The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0230 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.