# 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]]