# uninitialized proxy contracts are vulnerable to re-initialization attacks that hijack ownership
In proxy patterns, constructors run only during deployment and operate on the implementation contract's storage, not the proxy's. Initializer functions replace constructors to set up the proxy's state, but they require explicit guards preventing multiple executions. When these guards are missing or improperly implemented, an attacker can call the initializer to claim ownership of the proxy. Harvest Finance, Teller, and KeeperDAO all had contracts exploited through this pattern.
Since [[openzeppelin initializable with initializer modifier prevents re-initialization attacks on proxy contracts]], the defense is well-established but must be applied to every proxy deployment. The [[parity wallet hack demonstrated that selfdestruct in implementation contracts permanently bricks proxy systems|Parity wallet hack]] exploited exactly this: an uninitialized implementation contract allowed an attacker to call `initWallet`, claim ownership, and then self-destruct the implementation.
A more sophisticated variant of this vulnerability class is since [[CPIMP attacks exploit the gap between proxy deployment and initialization to inject a persistent malicious intermediary that parasitizes the protocol invisibly]]. Rather than claiming ownership (which disrupts protocol functionality), CPIMP inserts a double-delegation intermediary that forwards all calls to the legitimate implementation, preserving normal protocol behavior while granting the attacker a hidden super-admin channel. CPIMP exploits the same root condition — an unprotected initialization window — but through a different mechanism: front-running the initialization transaction to write a shadow implementation address into the ERC1967 slot. The CPIMP variant is harder to detect (the protocol works normally), harder to remove (since the shadow reinstalls itself after every transaction), and was responsible for the July 2025 wave affecting EtherFi, Pendle, Orderly Network, and others. The `initializer` modifier guard does not prevent CPIMP because CPIMP attacks before the initializer ever runs.
---
Relevant Notes:
- [[openzeppelin initializable with initializer modifier prevents re-initialization attacks on proxy contracts]] — the standard defense
- [[delegatecall executes code from another contract using the callers storage context]] — why constructors don't work for proxies
- [[parity wallet hack demonstrated that selfdestruct in implementation contracts permanently bricks proxy systems]] — the canonical exploit of this vulnerability
- [[access control vulnerabilities are the leading cause of smart contract financial losses]] — re-initialization is an access control failure
- [[vyper module composition uses explicit uses initializes and exports keywords preventing accidental state coupling between modules]] — Vyper's `initializes` keyword prevents this class by enforcing exactly-once initialization at the language level
- [[CPIMP attacks exploit the gap between proxy deployment and initialization to inject a persistent malicious intermediary that parasitizes the protocol invisibly]] — the sophisticated variant: same root vulnerability, but inserts a hidden parasitic intermediary rather than claiming ownership; survives upgrade attempts and requires atomic deployment to prevent
- [[non-atomic proxy deployment creates a front-running window where any actor can write to the ERC1967 implementation storage slot before the legitimate initialization transaction confirms]] — the deployment pattern that enables CPIMP; shows the precise mechanism
Topics:
- [[vulnerability-patterns]]