# re-initialization vulnerabilities arise when upgrades inadvertently reset initialization state
Since [[uninitialized proxy contracts are vulnerable to re-initialization attacks that hijack ownership]], the initial initialization attack is well-known. Re-initialization is a distinct failure mode: the contract WAS properly initialized, but an upgrade resets the initialization boolean or misuses OpenZeppelin's `reinitializer(n)` modifier, reopening the initializer to attackers.
The mechanism differs from the uninitialized case. In the initial case, the initializer was never called. In re-initialization, a legitimate upgrade either (1) sets the `_initialized` storage variable back to a prior value, (2) deploys a new implementation that does not inherit the initialization state from the previous version, or (3) uses `reinitializer(n)` with a version number that has already been consumed, creating ambiguous initialization state.
**AllianceBlock (August 2024):** An upgrade set the contract's initialized boolean back to false. The attacker re-initialized the contract to reset `rewardToken`, `stakingToken`, and `rewardRate`, redirecting rewards. The contract had been correctly initialized at deployment; the upgrade itself introduced the vulnerability.
Mitigations: use `_disableInitializers()` in implementation constructors (available since OpenZeppelin Contracts v4.3.2). Version-track all `reinitializer(n)` calls and verify that upgrade transactions do not modify the `_initialized` slot. Include initialization state in pre-upgrade storage layout diffs.
---
Relevant Notes:
- [[uninitialized proxy contracts are vulnerable to re-initialization attacks that hijack ownership]]: the initial-case sibling; same root vulnerability, different trigger
- [[openzeppelin initializable with initializer modifier prevents re-initialization attacks on proxy contracts]]: the guard that must survive across upgrades
- [[storage layout must remain consistent across proxy implementation versions]]: storage layout shifts can inadvertently overwrite the _initialized slot
- [[EIP-1822 UUPS upgrade logic in implementation enables permanent proxy bricking if implementation is destroyed or uninitialized]]: UUPS amplifies re-initialization because upgrade authority lives in the implementation
- [[contract upgrade procedures create temporary vulnerability windows when initialization must occur after a state change that disables reentrancy protection]]: the Optimism case shows a related pattern where upgrade procedures temporarily disable security mechanisms during re-initialization
- [[storage gap mismanagement in upgradeable base contracts causes child contract storage collisions]]: gap mismanagement during upgrades can shift the _initialized slot, inadvertently resetting the initialization guard
Topics:
- [[vulnerability-patterns]]