DELEGATECALL Vulnerabilities
delegatecall is one of the most powerful — and most dangerous — opcodes in Solidity. It runs external code inside your contract's own storage context. A bug in any library you delegate to is effectively a bug in your contract.
How delegatecall works
Normally, when contract A calls contract B, B's code runs using B's own storage, B's address, and the caller's msg.sender. With delegatecall, B's code runs but everything else belongs to A: A's storage, A's address, A's ETH balance.
This is intentional and useful — it's how proxy contracts work. But it creates a fundamental risk: anything B's code does to "its own" variables actually modifies A's storage slots. If an attacker can influence what B does, they control A.
User-controlled delegate target
The address passed to delegatecall comes from user input. Attacker supplies their own malicious contract.
Unprotected initializer
Library or implementation contract has no access control on initialize(). Anyone can call it and become owner.
Storage layout mismatch
Proxy and implementation define storage variables in different orders. Write to slot 0 in impl overwrites slot 0 (owner) in proxy.
Self-destruct in delegate target
Implementation contract contains selfdestruct. If called, it kills the proxy (not the impl), since delegatecall runs in proxy's context.
Real-world exploits
| Protocol | Year | Pattern | Loss |
|---|---|---|---|
| Parity Multi-Sig | 2017 | Unprotected initializer in shared library | $30M frozen forever |
| Parity Multi-Sig v1 | 2017 | User-controlled delegatecall target | $31M drained |
| Wormhole Bridge | 2022 | Delegatecall in guardian verification logic | $320M |
| Ronin Bridge | 2022 | Proxy upgrade without sufficient multisig | $625M |
Related vulnerabilities
Proxy Upgrade Vulnerabilities
Upgradeable proxy patterns introduce additional risks around storage collision and unprotected upgrade functions.
Access Control Flaws
Missing or bypassable access controls are what allow attackers to trigger delegatecall and initializer exploits.
Reentrancy Attacks
Delegatecall can introduce reentrancy if the called contract makes external calls before updating state.