#10 SC10:2026 High NEW for 2026

Proxy & Upgradeability Vulnerabilities

Proxy and upgradeability vulnerabilities describe any situation where a smart contract uses an upgradeable architecture (proxy, beacon, or implementation-swapping pattern) and the upgrade path, initialization, or admin controls are misdesigned or misconfigured.

Official OWASP description, from scs.owasp.org (CC BY-NC-SA 4.0).

Why this rank in 2026

New for 2026. Added because 2025 saw uninitialized ERC1967 proxies become an automated attack campaign - attackers scanned for uninitialized implementations, became the owner, and either drained immediately or planted a dormant backdoor for later activation. The category did not exist in OWASP 2025 but is now the most novel attack class on the list.

Why this is a brand-new 2026 category

OWASP added Proxy & Upgradeability to the Top 10 for 2026 because 2025 was the year uninitialized ERC1967 proxies stopped being a theoretical concern and became an automated campaign. Bots scanned EVM chains for uninitialized implementations, became the owner, and either drained funds immediately or planted a dormant backdoor implementation for activation months later.

How the 2025 incidents played out

  • Kinto Protocol (Jul 2025) lost $1.55M when an uninitialized ERC1967 proxy was claimed by an attacker who installed a malicious implementation. The activation was delayed, which made the incident harder to detect during initial monitoring.

  • ResupplyFi (2025) lost $9.8M - explicitly called out by OWASP's data-sources page as the SC10 archetype.

  • A multi-protocol uninitialized-proxy campaign in 2025 aggregated $10M+ across smaller protocols - automated scanning + delayed backdoor activation.

The six failure modes

OWASP's category covers six patterns:

  • Unprotected upgrade() / upgradeTo() allowing arbitrary implementation swap.

  • Re-initialization attacks that reset ownership or configuration.

  • Storage collision between proxy and implementation layers.

  • Initialization via delegatecall with attacker-controlled parameters.

  • Dormant backdoors planted in a malicious implementation, activated later.

  • Uninitialized ERC1967 proxies discovered by automated scanning.

How AI auditors handle this category

This is one of the deployment-state categories - the bug often is not in the code but in how the code was deployed. AI auditors handle the source-level patterns (proxy detection, unprotected upgrade functions, missing _disableInitializers) well. They struggle with deployment-state questions: Is the multisig correctly configured? Does the timelock match what the audit report assumed? Was the new implementation deployed with the correct storage layout? These are the questions the SCH course teaches because they are the ones that still need human auditors.

2025 incidents tied to this category

Pulled live from the SCH hack database, ordered by amount lost. Click any incident for the full post-mortem.

View the full SCH hack dashboard →

Vulnerable vs secure code

✗ Vulnerable solidity
// Vulnerable: implementation is not locked; anyone can initialize the implementation directly
contract VaultImpl {
    address public owner;
    bool internal initialized;

    function initialize(address _owner) external {
        require(!initialized, "already init");
        initialized = true;
        owner = _owner;
    }
}
✓ Secure solidity
// Secure: lock the implementation in its constructor + OpenZeppelin Initializable
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract VaultImpl is Initializable, OwnableUpgradeable, UUPSUpgradeable {
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() { _disableInitializers(); }

    function initialize(address admin) public initializer {
        __Ownable_init(admin);
        __UUPSUpgradeable_init();
    }

    function _authorizeUpgrade(address) internal override onlyOwner {}
}

AI vs human auditor on this category

Each bar is a detection rate: out of 100 known proxy & upgradeability bugs, how many that auditor type finds. Higher means more reliable. The gap below is the percentage-point difference - the work senior humans still do that AI does not.

AI auditor (frontier LLM)
67%
Human auditor (senior)
88%

% of SC10 bugs caught - higher is better.

Human advantage on SC10
+21 percentage points
Senior auditors catch 21 more proxy & upgradeability bugs per 100 than frontier AI today. That gap is the skill the SCH course teaches.

AI auditors handle the canonical proxy patterns (UUPS, Transparent, Beacon) and detect unprotected upgrade functions. They are weaker on storage-collision risk between proxy and implementation, and on deployment-process issues (is the multisig correctly configured? does the timelock match the audit assumption?). This category is unusually sensitive to *deployment* state, not just code.

Methodology: EVMbench, Cecuro purpose-built agent benchmarks, and senior-auditor self-reported catch rates. SCH editorial, not OWASP-authored.

Prevention checklist

  • Use established proxy patterns (OpenZeppelin UUPS or Transparent).
  • Protect upgrade roles with multisig governance, never a single EOA.
  • Apply initializer and reinitializer modifiers correctly on every implementation.
  • Call _disableInitializers() in the implementation constructor to lock it.
  • Add timelocks and multi-step upgrade processes.
  • Maintain upgrade runbooks and migration tests for every release.
  • Verify new implementation code AND storage-layout compatibility before any upgrade.
  • Simulate upgrade steps on-chain (Tenderly, Foundry) before mainnet execution.

Detection tools

Industry-standard tools that detect this category. Tool mappings are SCH editorial - OWASP's per-category pages do not list specific tools.

Slither
static

unprotected-upgrade, uninitialized-state, incorrect-equality

OpenZeppelin Upgrades Plugin
lint

storage-layout diff and safety checks

Aderyn
static

uninitialized-state-variable, centralization-risk

Manual review
human

deployment-process category - heavy on runbooks

Deep dive: related SCH attack pages

FAQ

What is OWASP SC10 Proxy & Upgradeability?
SC10 is a brand-new 2026 category covering vulnerabilities in upgradeable smart contracts: unprotected upgrade functions, re-initialization attacks, storage collisions, uninitialized proxies, and dormant backdoors planted in malicious implementations. It is #10 in the OWASP Smart Contract Top 10 2026 and the only fully new entry on the 2026 list.
Why was Proxy & Upgradeability added to OWASP 2026?
2025 was the year uninitialized ERC1967 proxies stopped being a theoretical concern and became an automated attack campaign. Bots scanned EVM chains for uninitialized implementations, became the owner, and either drained funds immediately or planted a dormant backdoor implementation for activation months later. Kinto Protocol ($1.55M, Jul 2025) and ResupplyFi ($9.8M) are the canonical 2025 cases.
What is an uninitialized proxy attack?
A proxy whose implementation contract was deployed without calling _disableInitializers() in its constructor. Anyone can call initialize() on the implementation, become the owner, and either upgrade it to a malicious version or drain funds directly. Automated bots scan EVM chains for these and claim them within minutes of deployment. The fix is _disableInitializers() in every implementation constructor plus the initializer modifier on initialize().
What is a storage collision in a Solidity proxy?
When the proxy contract and the implementation contract declare state variables in incompatible storage slots, an upgrade can corrupt or overwrite critical data. UUPS, Transparent, and Beacon proxies use specific storage slots (EIP-1967) to isolate proxy state from implementation state. The OpenZeppelin Upgrades plugin validates storage-layout compatibility before every upgrade.
How do you prevent proxy and upgradeability vulnerabilities?
Use established proxy patterns (OpenZeppelin UUPS or Transparent). Call _disableInitializers() in every implementation constructor. Protect upgrade roles with multisig governance plus a timelock, never a single EOA. Apply initializer and reinitializer modifiers correctly. Maintain upgrade runbooks. Verify storage-layout compatibility before every upgrade with the OpenZeppelin Upgrades plugin. Simulate upgrades on a fork (Tenderly, Foundry) before mainnet execution.
Can AI auditors detect proxy and upgradeability bugs?
AI auditors handle source-level patterns well (UUPS, Transparent, Beacon detection; unprotected upgrade functions; missing _disableInitializers) - around 67% catch rate. Senior humans detect around 88%. The gap is deployment-state questions: Is the multisig correctly configured? Does the timelock match the audit assumption? Was the new implementation deployed with the correct storage layout? These are deployment-process issues, not source code.

Master the techniques that make this category exploitable

The SCH Smart Contract Hacking Course teaches the exploit primitives, audit techniques, and tool workflows for proxy & upgradeability vulnerabilities and every other OWASP 2026 category.