# unrestricted delegatecall allowing user-specified target addresses enables fund drainage and state manipulation When a contract performs a delegatecall to an address supplied by the caller without validating it against an allowlist, the attacker can execute arbitrary code in the caller's storage context. Since [[delegatecall executes code from another contract using the callers storage context]], this means the attacker's code runs with full access to the victim contract's storage, including token approvals and ownership state. The vulnerable pattern is a `forward()` or `proxy()` function that accepts a user-supplied `callee` address and passes it directly to `delegatecall(callee, msg.data)`. The [[furucombo exploit demonstrated unrestricted delegatecall enabling storage approval manipulation|Furucombo exploit]] ($14M, 2021) is the canonical demonstration. Since [[restricting delegatecall to pre-verified logic contracts prevents arbitrary code execution]], the defense requires maintaining a strict allowlist of valid delegation targets. When the target address originates from user input, it must be validated against the allowlist before dispatch. **Delegatecall + selfdestruct chaining via service registries** Even when delegatecall targets are restricted to a known registry, the registry itself can serve as a gadget pool for code reuse attacks. If an attacker can invoke delegatecall to any service in a registry, and one of those services contains a selfdestruct gadget, the attacker can chain delegatecalls to destroy core infrastructure. This demonstrates that restricted delegatecall to a verified registry is insufficient when the aggregate capability set of registered services includes destructive operations, a pattern analogous to return-oriented programming in binary exploitation. **Proxy-specific context:** Arbitrary delegatecall in an implementation contract behind a proxy is particularly dangerous because it executes in the proxy's storage context, not the implementation's. An attacker can chain to a selfdestruct gadget that destroys the proxy itself (see [[selfdestruct in implementation contracts can permanently brick proxy systems]]), or to arbitrary code that manipulates the proxy's storage (ownership, token balances, implementation pointer). The proxy amplifies the impact because the delegatecall's context is the high-value contract holding user funds. **Relationship to other unvalidated-dispatch patterns:** This vulnerability belongs to a family of failures where user-supplied dispatch parameters bypass validation. Since [[unvalidated user-supplied contract addresses enable arbitrary code execution when protocols call interfaces on attacker-controlled deployments]], the same root — trusting a user-supplied address without verification — produces code execution via ordinary `call`; delegatecall is the more severe variant because the attacker's code also gains write access to the caller's storage. --- Relevant Notes: - [[delegatecall executes code from another contract using the callers storage context]]: the mechanism that makes this dangerous - [[furucombo exploit demonstrated unrestricted delegatecall enabling storage approval manipulation]]: the canonical exploit - [[restricting delegatecall to pre-verified logic contracts prevents arbitrary code execution]]: the defense pattern - [[selfdestruct in implementation contracts can permanently brick proxy systems]]: the destructive primitive available as a gadget in service registries - [[ERC-7579 modules executing via delegatecall in account storage context allow malicious or buggy modules to overwrite arbitrary storage slots and brick or drain the account]]: the account abstraction analogue where delegatecall modules have unrestricted access to account storage - [[access control vulnerabilities are the leading cause of smart contract financial losses]]: unrestricted delegatecall is fundamentally an access control failure on the most dangerous EVM primitive - [[unvalidated user-supplied contract addresses enable arbitrary code execution when protocols call interfaces on attacker-controlled deployments]]: the call-based analogue; same root cause (unvalidated address) but attacker code executes without storage write access Topics: - [[vulnerability-patterns]]