Back to Blog
OWASP Smart Contract Top 10 2026: changes and audit guide
AuditWeb3 SecurityHacksDeFi

OWASP Smart Contract Top 10 2026: changes and audit guide

29 min
The OWASP Smart Contract Security project has published the Smart Contract Top 10 for 2026, and it is not a cosmetic refresh of the 2025 list. The framework has been re-anchored to 122 deduplicated incidents from 2025 representing roughly $905M in contract-only losses, and two structural changes matter more than the rest: Business Logic Vulnerabilities has been elevated to SC02:2026, and Proxy & Upgradeability Vulnerabilities is an entirely new category at SC10:2026. Reentrancy — the bug class that has defined Solidity audit folklore for a decade — has been demoted from #2 to #8.
If you read those three changes together, the framework is telling you something specific about how protocols actually fail in 2025/2026. Single-vector exploits are rare. The default chain is now flash loan supplies adversarial capital → oracle manipulation skews a reference → business logic flaw permits an under-collateralized action → unchecked external call or proxy weakness finalizes extraction. Each step in isolation can pass review. The composition violates an invariant nobody declared.
This article walks every category in the 2026 list with primary-source descriptions, real 2025/2026 incidents, and the audit-time response. Where Zealynx has existing public material on a category, we link it. Where we don't, we say so plainly.

TL;DR

  • The 2026 OWASP Smart Contract Top 10 reorders around how protocols actually fail. Access control (SC01), business logic (SC02), oracle manipulation (SC03), and flash-loan-amplified composition (SC04) are now the top four. Proxy & upgradeability has been added as SC10.
  • Reentrancy fell from #2 to #8 because tooling and patterns matured (ReentrancyGuard and ReentrancyGuardTransient are near-universal, Slither and Mythril detect classic reentrancy reliably). The class did not disappear — cross-contract and read-only reentrancy still appear in 2025/2026 findings, with Solv's ERC-3525 incident ($2.7M) as the canonical recent case.
  • Business logic moved to #2 because invariant collapse and economic-edge-case bugs are now the largest single-protocol losses. Yearn's yETH pool collapse (9M,November2025),Cetus(9M, November 2025), Cetus (223M, May 2025), Balancer V2's ComposableStablePool (128M,November2025),andtheAave128M, November 2025), and the Aave 50M slippage event (March 2026) are the worked examples OWASP cites.
  • Proxy & upgradeability is new because uninitialized ERC1967 proxies became a campaign in 2025. Kinto Protocol (1.55M,July2025)isthemostcitedexample;thebroaderuninitializedproxyautomationdrove1.55M, July 2025) is the most-cited example; the broader uninitialized-proxy automation drove 10M+ in aggregate losses across protocols.
  • Detection is structural, not lexical. The audit response across the 2026 list is invariant testing, trust-boundary mapping, and formal verification of high-value properties — not a category-by-category code review.

The 2026 list, in order

The complete OWASP Smart Contract Top 10 2026, taken from the official SCS site and the OWASP/www-project-smart-contract-top-10 repository:
RankIDTitle
1SC01:2026Access control vulnerabilities
2SC02:2026Business logic vulnerabilities
3SC03:2026Price oracle manipulation
4SC04:2026Flash loan–facilitated attacks
5SC05:2026Lack of input validation
6SC06:2026Unchecked external calls
7SC07:2026Arithmetic errors (rounding & precision)
8SC08:2026Reentrancy attacks
9SC09:2026Integer overflow and underflow
10SC10:2026Proxy & upgradeability vulnerabilities
OWASP also explicitly demotes several categories to "honourable mentions" for 2026: permit front-running and nonce DoS, front-running and MEV, cross-chain MEV (Symbiosis aggregated ~$5.27M across August–October 2025), generic DoS via gas/loops/state bloat, governance-specific vectors (flash-loan-amplified voting, timelock bypasses), and cryptographic and signature-scheme issues. These remain real bug classes; they did not produce sufficient 2025 incident volume to displace anything in the top ten.

What changed from 2025 to 2026

What changed from 2025 to 2026
Category2025 Rank2026 RankΔ
Access Control11
Logic Errors → Business Logic Vulnerabilities32+1 (renamed and expanded)
Price Oracle Manipulation23−1
Flash Loan Attacks74+3
Lack of Input Validation45−1
Unchecked External Calls66
Arithmetic Errors (Rounding & Precision)7NEW (split out)
Reentrancy58−3
Integer Overflow and Underflow89−1
Insecure Randomness9removed
Denial of Service10removed
Proxy & Upgradeability Vulnerabilities10NEW
Two structural changes carry the weight of the revision and deserve their own discussion before walking the categories.

Why business logic moved up

The 2025 entry was titled "Logic Errors." For 2026 it has been renamed to Business Logic Vulnerabilities and pushed to second place. The rename signals scope expansion: it is no longer just incorrect conditionals or swapped variables. OWASP's 2026 framing covers reward and fee logic flaws, eligibility and limit bypasses, path-dependent state machines, and cross-module or cross-chain assumptions. The unifying property is that every individual low-level check passes — type safety, reentrancy guards, access control are all correctly applied — and the protocol still fails because the rules being enforced do not match the rules the protocol needed to enforce.
Three 2025/2026 incidents make this concrete:
  • Yearn yETH (~$9M, November 2025). A weighted stableswap pool's fixed-point iteration solver was forced into a divergent regime by sufficiently imbalanced add and remove liquidity calls. The product term Π collapsed to zero, and the s invariant degenerated from hybrid stableswap into constant-sum. Roughly 2.35×10⁵⁶ yETH LP tokens were minted without backing collateral.
  • Cetus Protocol (~$223M, May 22, 2025). A checked_shlw overflow check in a u256 fixed-point library on Sui was structurally flawed. Shifting bits beyond type capacity did not abort. The attacker manipulated a liquidity parameter so the get_delta_a calculation overflowed silently and returned that only one unit of token A was needed to mint a massive LP position. Multiple audits — MoveBit, OtterSec, Zellic in April 2025 — had reviewed the protocol; library-level numerical code was effectively out of audit scope.
  • **Aave 50Mslippageevent(March2026).Atraderswappedroughly50M slippage event (March 2026).** A trader swapped roughly 50.4M USDT for ~36KofAAVEthroughaninterfaceroutedviaathinSushiSwappool.Sandwichextractionapproached36K of AAVE through an interface routed via a thin SushiSwap pool. Sandwich extraction approached 44M. The frontend warned. The contract did not enforce a protocol-level cap.
The pattern across all three is that the code does what it says and what it says is the bug. That is not a class of finding a static analyzer can catch.

Why proxy & upgradeability is new

SC10:2026 exists because uninitialized ERC1967 proxies became an automated campaign in 2025. The pattern is mechanical: deployers ship an ERC1967Proxy and intend to call initialize in a follow-up transaction. Bots watching new contracts on multiple EVM chains race-initialize the proxy first, embedding a dormant backdoor in a malicious implementation. The legitimate initialize later reverts (or, worse, is silently overridden), the protocol launches, the backdoor sits, and the implementation is later upgraded to drain. Kinto Protocol (1.55M,July2025)isthemostcitedspecificcase;aggregatelossesacrossthecampaignexceeded1.55M, July 2025) is the most-cited specific case; aggregate losses across the campaign exceeded 10M.
OWASP's SC10 page groups four sub-issues:
  1. Upgrade and admin role hijack — who can change implementation, and is the storage layout compatible.
  2. Initialization and re-initialization — unprotected initialize, missing initializer guards, initialization front-running.
  3. Delegatecall context errorsmsg.sender, msg.value, and storage context confusion.
  4. Storage layout collisions — slot collisions between proxy and implementation, unreserved gaps, missing append-only discipline.
The PROXION research published in 2025 found that around 54% of Ethereum contracts are proxies, many with unverified implementations. CRUSH symbolic-execution work attributed >$6M to type-collision bugs where a V2 implementation re-interpreted slot 0 differently than V1. The OWASP framing notes SC10 "often overlaps with access control (SC01) but warrants separate attention due to the systemic impact." That overlap is real — proxy admin compromise is access control — but the failure modes specific to upgradeability (storage layout, initialization, delegatecall context) are not adequately covered by SC01 alone, which is why OWASP carved out a separate category.

Why reentrancy dropped

Reentrancy dropped six places because the controls matured, not because the bug class is solved. OpenZeppelin's ReentrancyGuard is near-universal; the post-Cancun ReentrancyGuardTransient lowered the gas cost of protection by an order of magnitude; Checks-Effects-Interactions is taught from day one; Slither, Mythril, and Aderyn detect classic reentrancy reliably. What remains in production findings is callback-driven reentrancy (ERC-721/1155/3525/777 hooks, ERC-4626 deposit/withdraw hooks, flash-loan callbacks) and read-only reentrancy — the variant where a view function reads stale state during a callback even though no state mutation re-enters. Solv Protocol's ERC-3525 incident ($2.7M, 2026) is the canonical recent case. The category remains in the top ten precisely because these variants are still landing.

SC01:2026 — Access control vulnerabilities

Definition. Access control vulnerabilities are conditions where unauthorized callers invoke privileged functions or modify critical state. OWASP 2026 framing extends beyond onlyOwner modifiers into governance, upgrade authority, and the entire administrative trust graph — including off-chain components of the trust graph.
Worked example: Bybit (February 21, 2025, ~$1.5B). This is the largest case study OWASP and downstream commentary cite, and it is instructive precisely because it does not look like an "access control bug" in the Solidity sense. The signers approved what their UI showed as a routine cold-to-warm ETH transfer. According to NCC Group, Sygnia, Verichains, and BlockSec post-mortems, attackers had compromised a Safe{Wallet} developer's macOS workstation, gained access to the AWS S3 bucket serving app.safe.global JavaScript, and replaced the bundle on February 19. When the three signers approved on February 21, the malicious bundle silently rewrote the calldata into a delegatecall to attacker-controlled code, transferring control of the Safe to the attacker who then drained ~401,347 ETH. The hardware wallets blind-signed because they could not parse the modified Safe transaction payload.
The lesson is that access control is no longer a Solidity property in isolation; it is a property of the entire chain from developer laptop → CI/CD → frontend bundle → signer interface → on-chain function selector.
Detection.
  • Manual review — enumerate every external/public function and prove a path to a documented role; verify all administrative addresses are multisig + timelock; check ownership transfer is two-step (Ownable2Step or equivalent); look for tx.origin use; look for selfdestruct exposure on implementations.
  • Tooling — Slither's arbitrary-send, unprotected-upgrade, suicidal, and incorrect-modifier detectors are first pass; Aderyn for cross-checks; Halmos to symbolically prove that only authorized callers reach state mutations.
  • Process — threat-model the off-chain signing pipeline; require raw-calldata clear-signing or transaction simulation on hardware wallets that support it.
Zealynx coverage. The 2025 exploit lessons post walks Bybit/Cetus/Balancer in detail. The ERC-4337 six failure modes post covers programmable-account access patterns. The DAO governance attacks post extends the access-control surface into protocol governance.

SC02:2026 — Business logic vulnerabilities

Definition. Per OWASP, business logic vulnerabilities are situations where a smart contract's intended economic or functional behavior can be subverted even though every individual low-level check is correct. The category groups four sub-classes:
  1. Reward and fee logic flaws (double counting, wrong beneficiary, miscounted accrual).
  2. Eligibility and limit bypasses (borrowing caps, mint limits, liquidation thresholds).
  3. Path-dependent state machines (the same end state reached via two paths produces different outcomes).
  4. Cross-module and cross-chain assumptions (one contract assumes a property the other does not enforce).
This is the category responsible for the largest single-protocol losses in 2025/2026 and the one least caught by automated scanning, because correctness is protocol-specific. Smart contract vulnerabilities in 2026 are increasingly business logic vulnerabilities in raw dollar terms, and the SC02 elevation is OWASP's recognition of that fact.
Worked examples.
  • Yearn yETH (~$9M, November 2025). Detailed in the previous section — fixed-point solver collapse converting a stableswap invariant into constant-sum.
  • Cetus ($223M, May 2025). Library-level u256 overflow check that did not abort. Detailed in the previous section.
  • Balancer V2 ComposableStablePool (~$128.64M, November 3, 2025). Per Trail of Bits attribution: a rounding-error vulnerability in _upscaleArray combined with crafted batchSwap operations let the attacker artificially inflate share prices. This straddles SC02 (business logic) and SC07 (rounding) — which is the point. Compound failures rarely live in a single category.
  • Abracadabra (~$13M, March 2025). GMX-liquidity-token cauldrons. Attacker exploited interactions between liquidation logic and the GLP underlying.
The structural precedent worth keeping in mind is Euler Finance (March 2023, ~$197M). The donateToReserves function — exploited by the attacker — was introduced as a patch for a smaller first-depositor inflation issue. The patched function lacked a health check. The auditor that signed off was also the protocol's insurer. That story is the structural template for SC02-class incidents: the bug enters via well-intentioned remediation; the math works locally; the invariant breaks globally.
Detection.
The SC02 audit response is structural and runs in this order:
  1. Threat model first. Define the protocol's invariants explicitly. For a lending protocol: Σ user_balances ≤ totalAssets, health_factor ≥ 1 after every state-changing path including donate*, migrate*, and rebalance*. For an AMM: x · y ≥ k after fee. For a stableswap: bounds on the iteration solver under all liquidity ratios.
  2. Invariant fuzzing. Foundry stateful fuzz, Echidna, or Medusa run randomized call sequences against those invariants. This is non-negotiable for any protocol with composable state.
  3. Formal verification of high-value properties. Halmos symbolically proves invariants across all bounded inputs; Certora's CVL covers protocol-level rules.
  4. Adversarial economic simulation. Agent-based models that assume infinite-capital flash loans, MEV mempool ordering, and adversarial sequencing.
A first-pass property file for an ERC-4626 vault might look like:
1// foundry-rs/forge-std invariant test
2function invariant_solvency() public {
3 assertLe(vault.totalSupply() * vault.convertToAssets(1e18) / 1e18, vault.totalAssets());
4}
5
6function invariant_round_trip_loss() public {
7 uint256 shares = vault.convertToShares(amount);
8 uint256 assets = vault.convertToAssets(shares);
9 assertLe(assets, amount); // round against the user
10}
Four lines. Run them at scale with random call sequences and you catch a non-trivial fraction of SC02 findings before they reach production.
Zealynx coverage. Strong, with several pillars already published:

SC03:2026 — Price oracle manipulation

Definition. Any situation where a smart contract relies on price or valuation data that can be directly or indirectly influenced by an attacker. Oracles are trust boundaries; the contract implicitly trusts the source.
Worked examples. sDOLA / Llamalend on Curve (~240K,2025)singlesourceonchainoracleonathinliquiditypool,attackermanipulatedthefeedandtriggeredartificialliquidations.Makina(240K, 2025) — single-source on-chain oracle on a thin-liquidity pool, attacker manipulated the feed and triggered artificial liquidations. Makina (4.13M, January 2026) — flash-loan-funded oracle skew on a DUSD/USDC Curve pool.
Detection. Verify multi-source decentralized oracles where possible (Chainlink Price Feeds, Pyth); enforce TWAP windows ≥30 minutes for any spot-price-derived oracle; require staleness checks on updatedAt and answeredInRound; require sanity bounds (minPrice/maxPrice); design failsafes (pause on stale feed). Read-only reentrancy via Balancer-style getReserves() calls must be modeled — see SC08.
1function getPrice() internal view returns (uint256) {
2 (, int256 answer,, uint256 updatedAt, uint80 answeredInRound) = feed.latestRoundData();
3 require(answer > 0, "negative price");
4 require(updatedAt + STALENESS_THRESHOLD >= block.timestamp, "stale feed");
5 require(answeredInRound > 0, "incomplete round");
6 require(uint256(answer) >= MIN_PRICE && uint256(answer) <= MAX_PRICE, "out of band");
7 return uint256(answer);
8}
That is what an oracle read should look like. Most oracle-manipulation findings happen because two or three of those checks are missing.
Zealynx coverage. Moving averages in DeFi, the Uniswap V2 deep dive covering TWAP construction, and the oracle manipulation pillar.

SC04:2026 — Flash loan–facilitated attacks

Definition. Atomic, uncollateralized borrowing that magnifies any latent vulnerability. The +3 jump in 2026 reflects that flash-loan amplification is now the default exploit primitive, not an exotic one.
Worked examples. Makina (4.13M,January2026)isthecleanestrecentcaseflashloanfundedtheoracleskew.The2023EulerFinanceattackremainsthecanonicalworkedexamplefortheaudittimediscussion:30MDAIflashloanleveragedeDAI/dDAIpositiondonateToReserves(nohealthcheck)selfliquidationunderthedynamicclosefactor 4.13M, January 2026) is the cleanest recent case — flash loan funded the oracle skew. The 2023 Euler Finance attack remains the canonical worked example for the audit-time discussion: 30M DAI flash loan → leveraged eDAI/dDAI position → `donateToReserves` (no health check) → self-liquidation under the dynamic close-factor → ~197M extracted.
Compound exploit chain: flash loan to extraction
Detection. Treat every external entry point as if the attacker has unlimited single-block capital. Use multi-block TWAP oracles. Add minimum holding periods between deposit and borrow. Add post-operation health checks. For governance, use multi-block voting weight snapshots (Merkle proofs or Snapshot-style off-chain) so flash-loaned tokens cannot cast votes.
Zealynx coverage. The glossary entry on flash loans covers definitions and defense patterns; the MEV protection post covers full-stack flash-loan and MEV defense.

SC05:2026 — Lack of input validation

Definition. OWASP defines this as situations where a smart contract processes external data — function parameters, calldata, cross-chain messages, signed payloads — without enforcing that the data is well-formed, within expected bounds, and authorized for the intended operation.
Worked examples. YO Protocol (3.71M,January2026)slippageparameteracceptedwithoutboundsandapermissivedefaultindeploymentconfiguration.Aave3.71M, January 2026) — slippage parameter accepted without bounds and a permissive default in deployment configuration. Aave 50M slippage event (March 2026) — UI warned, contract did not enforce.
Detection. Treat the frontend as nonexistent. Every external input gets explicit require bounds; every address parameter gets a zero-address check and where applicable a codesize/contract-existence check; every numeric parameter has min and max; every deadline is bounded. Calldata length validation must precede abi.decode.
1function swap(address tokenIn, uint256 amountIn, uint256 minAmountOut, uint256 deadline) external {
2 require(tokenIn != address(0), "zero token");
3 require(amountIn > 0, "zero amount");
4 require(minAmountOut > 0, "zero min out"); // critical — prevents trivial sandwich
5 require(deadline >= block.timestamp, "deadline passed");
6 require(deadline <= block.timestamp + MAX_DEADLINE, "deadline too far");
7 // ...
8}
The minAmountOut > 0 line is the one Aave's $50M event would have prevented at the protocol level, regardless of UI.

Get the DeFi Protocol Security Checklist

15 vulnerabilities every DeFi team should check before mainnet. Used by 30+ protocols.

No spam. Unsubscribe anytime.

Zealynx coverage. Indirect — input validation is referenced across the Solana security checklist and the proxy & upgradeability checklist but not as its own pillar.

SC06:2026 — Unchecked external calls

Definition. Unsafe interactions with external contracts where failures, reverts, or callbacks are not safely handled. This category captures the broad surface where one contract trusts another without validation.
Worked example. CrossCurve Bridge ($3M, February 2026) — missing access control on Axelar's expressExecute function let any caller invoke the express-execution path and redirect bridged funds. The function existed for liquidity-provider reimbursement; it was reachable by anyone.
Detection. Every low-level call and delegatecall checks the success boolean; every transfer and transferFrom uses SafeERC20 (or its equivalent); CEI is enforced; try/catch covers calls that may revert without aborting upstream logic; never trust tx.origin. For bridges, validate chainId and proof of cross-chain message.
1// wrong
2token.transfer(recipient, amount);
3
4// right (OZ SafeERC20)
5token.safeTransfer(recipient, amount);
6
7// wrong
8(bool ok,) = target.call(data);
9
10// right
11(bool ok, bytes memory ret) = target.call(data);
12require(ok, _getRevertMsg(ret));

SC07:2026 — Arithmetic errors (rounding & precision)

Definition. New for 2026 as a split-out category. Smart contracts are limited to integer arithmetic; division, fixed-point scaling, and conversion between units lose precision, introduce asymmetric rounding, or — when combined with unchecked blocks or non-EVM semantics — cause overflow and underflow (which is now SC09).
Canonical pattern: ERC-4626 first-depositor inflation. Attacker mints 1 wei share, donates assets directly to the vault to inflate totalAssets, victim's deposit then rounds down to zero shares. OpenZeppelin's mitigation is the _decimalsOffset virtual-shares-and-assets pattern.
Worked example. Balancer V2 ComposableStablePool (~$128.64M, November 3, 2025). Trail of Bits attributed the incident to a rounding-error vulnerability in _upscaleArray combined with crafted batchSwap operations. The math was correct in isolation; the rounding direction across composed operations was not.
Detection. Round against the user — down on deposit, up on withdrawal. Use virtual offsets for new ERC-4626 vaults. Fuzz with extremes (1 wei, type(uint256).max). Formally verify the conversion identity:
1∀ x: convertToAssets(convertToShares(x)) ≤ x
That property, written in Halmos's check_* form or Certora CVL, takes minutes to prove on a clean implementation and is the cheapest insurance against the category.
Zealynx coverage. The Solidity overflow & underflow post covers the underlying mechanics with real audit findings; the Balancer architecture post discusses precision fatigue across V1→V3.

SC08:2026 — Reentrancy attacks

Definition. External calls re-entering vulnerable functions before state is fully updated. OWASP enumerates four variants in 2026: single-function, cross-function, cross-contract, and read-only reentrancy. Read-only reentrancy is the variant most underestimated post-2024 — external callers read stale getReserves()-style data during a callback even though no state mutation re-enters.
Worked example. Solv Protocol ERC-3525 ($2.7M, 2026) — semi-fungible tokens with transfer callbacks reentered the minting function before transfer state finalized, creating duplicate positions.
Why the rank dropped. Mature controls. ReentrancyGuard is near-universal. CEI is internalized. Slither and Mythril detect the classic pattern reliably. The remaining surface is callback-driven (ERC-721/1155/3525/777 hooks, ERC-4626 deposit/withdraw hooks, flash-loan callbacks) and read-only. The category drops in rank but does not disappear, and the variants that remain are subtler than the 2016 The DAO archetype most security curricula still teach.
Detection. nonReentrant (or nonReentrantTransient) on every state-changing external entry; CEI everywhere; explicit modeling of ERC-777/1155/3525/4626 callbacks; read-only reentrancy review on every view function consumed by another protocol as an oracle. The rule of thumb: if your getReserves()-equivalent is callable mid-transaction, model what an external reader sees during that window.
Zealynx coverage. The reentrancy attacks pillar covers the modern variants; the Uniswap V2 post and Balancer architecture post cover read-only reentrancy in production-style codebases; the divide and conquer methodology explains read-only reentrancy at the trust-boundary level.

SC09:2026 — Integer overflow and underflow

Definition. Solidity 0.8+ checks arithmetic by default and reverts on overflow/underflow. The remaining surface is unchecked blocks (used for gas optimization), inline assembly, custom math libraries, and non-EVM platforms with different overflow semantics — Move/Sui, Solana/Rust.
Worked examples.
  • TrueBit ($26.2M, January 2026). Pre-0.8 contract, unprotected addition in getPurchasePrice overflowed to zero, minting massive TRU at zero cost. A 2026 incident on a 2018-era codebase.
  • Cetus ($223M, May 2025). Sui's u256 checked_shlw left-shift did not abort on overflow. Move's design choice for left-shift, combined with a flawed safety check on the high bits, produced the SC07/SC09 hybrid.
Detection. Solidity ≥0.8 mandatory. Every unchecked block annotated with proof of impossibility (a comment showing the bound that prevents overflow). SafeCast on all explicit downcasts. On Solana, checked_add and checked_mul exclusively — never raw + or * on financial values. For Move/Sui, audit shift operations and library numerical code explicitly. This was the demonstrably under-scoped surface in Cetus across three audits.

SC10:2026 — Proxy & upgradeability vulnerabilities

Definition. OWASP's full description: 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. The category groups four sub-issues — covered earlier in this article. This is the structurally most important addition to the OWASP smart contract top 10 2026 because it takes a failure surface that previously sat half-inside SC01 and half-inside SC02 and gives it the dedicated attention the 2025 incident data justified.
Uninitialized ERC1967 proxy attack flow
Worked examples.
  • **Kinto Protocol (1.55M,July2025).AttackersdetectedfreshlydeployedbutnotyetinitializedERC1967proxies.Calledinitializethemselveswithmaliciousimplementationscontainingdormantbackdoors.Monthslater,thebackdoorwasactivated,theproxywasupgradedtomaliciouscode,andKtokensweremintedtodrain1.55M, July 2025).** Attackers detected freshly deployed but not-yet-initialized ERC1967 proxies. Called `initialize` themselves with malicious implementations containing dormant backdoors. Months later, the backdoor was activated, the proxy was upgraded to malicious code, and K tokens were minted to drain 1.55M.
  • The broader uninitialized-proxy campaign (2025, $10M+ aggregate). Automated scanners watched for new ERC1967 proxies on multiple EVM chains, race-initialized them before the legitimate deployer's transaction landed, and embedded dormant backdoors that survived later audits.
  • FOOMCASH ($2.26M, 2025). Upgradeable proxy fronting a zkSNARK verifier; misconfigured verification key allowed forged proofs; upgrade mechanism lacked timelock and proper access control.
Detection. Proxy and upgradeability findings live at the intersection of pattern selection, initializer hygiene, storage discipline, and governance. The audit checklist is structural:
  1. Pattern selection. Choose proxy pattern (Transparent, UUPS, Beacon, Diamond) before writing code; use OpenZeppelin Upgrades plugins, not bespoke implementations. Bespoke proxies are the highest-risk subset of the category.
  2. Initializer hygiene. initializer and reinitializer modifiers correctly applied. Implementation contracts call _disableInitializers() in the constructor. Initialization performed atomically with proxy deployment via ERC1967Proxy calldata to prevent the Kinto-class race.
  3. Storage discipline. Reserve gaps via uint256[50] __gap, or — better — use ERC-7201 namespaced storage. Verify storage layout compatibility across versions with the OpenZeppelin Upgrades plugin. UUPS implementations must include proxiableUUID() (slot 60894...) and override _authorizeUpgrade` with access control.
  4. Upgrade governance. Timelock + multisig. On-chain announcement. Review window. Rollback capability. Single-EOA upgrade authority is automatic critical finding.
  5. Special cases. Beacon upgrades require auth on the beacon; shared proxy-admin and logic-owner keys must be split; selfdestruct exposure on implementations is fatal.
The minimal correct implementation pattern:
1contract MyImplementation is UUPSUpgradeable, OwnableUpgradeable {
2 /// @custom:oz-upgrades-unsafe-allow constructor
3 constructor() {
4 _disableInitializers(); // prevents implementation initialization
5 }
6
7 function initialize(address owner_) public initializer {
8 __Ownable_init(owner_);
9 __UUPSUpgradeable_init();
10 }
11
12 function _authorizeUpgrade(address newImpl) internal override onlyOwner {
13 require(newImpl != address(0), "zero impl");
14 require(newImpl.code.length > 0, "not a contract");
15 }
16}
Three lines (_disableInitializers(), the initializer modifier, the _authorizeUpgrade check) prevent the dominant 2025 failure modes. They are rarely all present.
Zealynx coverage. This is a category Zealynx already covers in unusual depth:

How to actually run an audit against the 2026 list

Audit response framework against the 2026 OWASP list
The 2026 list is not a checklist. It is a prioritization signal. The audit response across all ten categories shares a common shape:
  1. Map the trust boundaries. Every external/public function, every external call out, every cross-contract dependency, every off-chain input. Diagrams help. The divide-and-conquer methodology Zealynx publishes is the framing we use internally.
  2. Define the invariants in plain English. Ten or more for any non-trivial protocol. Σ user_balances ≤ totalAssets. health_factor ≥ 1 after every state-changing path. convertToAssets(convertToShares(x)) ≤ x. Solvency. Conservation. Accessibility.
  3. Translate invariants into property tests. Foundry stateful fuzz, Echidna, Medusa for randomized search. Halmos and Certora for the high-value subset that needs proof rather than search.
  4. Apply per-category tooling. Slither and Aderyn for SC01/SC06/SC09. Halmos for SC07 conversion identities. Echidna for SC02 invariant collapse. The OpenZeppelin Upgrades plugin for SC10 storage-layout checks.
  5. Manual review of what the tooling cannot reach. Business logic correctness against protocol intent. Off-chain trust assumptions. Composability with external protocols not in scope. Game-theoretic edge cases.
  6. Continuous verification post-deployment. The same invariants run as on-chain monitors. The same property tests run in CI on every commit. The same readiness check runs before every upgrade.
The compound-attack pattern — flash loan → oracle skew → business logic break → extraction — is the reason this needs to be a system rather than a category-by-category review. Each step in isolation passes. The composition fails.
For teams getting started, our pre-audit technical checklist covers repo hygiene, invariant documentation, and static-analysis triage, and the audit ROI framework explains how to justify the spend internally before booking time with auditors.

Get in touch with Zealynx

At Zealynx, we audit against the 2026 OWASP smart contract top 10 the way the 2025 incident data demands: structural invariant testing, formal verification of high-value properties, trust-boundary mapping that extends to off-chain components, and adversarial economic simulation. We write the property tests, not just the report.
If your protocol holds user funds and you have not run a stateful invariant fuzzer against it, that is the most cost-effective hour of security spend you can buy this quarter. Talk to us before the upgrade ships.

FAQ: OWASP smart contract top 10 2026

1. What is OWASP and why does it publish a smart contract top 10?
OWASP — the Open Worldwide Application Security Project — is a non-profit foundation that has published the canonical "top 10" lists for web application risks since 2003. The Smart Contract Security (SCS) project is the OWASP working group that maintains the smart contract top 10, an empirically-anchored ranking of the most impactful smart contract vulnerability classes from the prior year's incidents. The 2026 list is anchored to 122 deduplicated 2025 incidents representing roughly $905M in contract-only losses. It is the closest thing the smart-contract industry has to a shared language for prioritizing security work.
2. What is invariant testing and why does the 2026 list lean on it so heavily?
An invariant is a property that must hold for every reachable state of a protocol — for example, "the sum of user balances never exceeds total assets" or "every borrow position has health factor ≥ 1 after any state-changing call." Invariant testing (also called stateful fuzzing) runs randomized sequences of contract calls and asserts those properties hold after every step. Tools like Foundry's invariant suite, Echidna, and Medusa do this automatically. The 2026 list emphasizes invariant testing because business-logic vulnerabilities (SC02), the largest dollar-loss category in 2025, are exactly the bugs that pass code-level review but break invariants under composed operations. Our fuzzing and formal verification post is the long version.
3. What is "read-only reentrancy" and why is it different from classic reentrancy?
Classic reentrancy exploits a contract that calls an external address before updating its own state — the external address re-enters the function and acts on stale state. Read-only reentrancy is subtler: an attacker triggers a callback that causes a view function (typically getReserves(), latestPrice(), or similar) to return temporarily inconsistent data, and a third contract that uses that view function as an oracle reads the wrong value during the callback window. No state is corrupted in the original contract — but the protocol consuming its view function makes a wrong decision. Curve and Balancer V2 read-only reentrancy patterns drained tens of millions across 2022–2023, and the variant continues to land in 2025/2026.
4. What is an ERC1967 proxy and why are uninitialized ones an automated attack campaign?
ERC1967 is the Ethereum standard for proxy contracts: a thin contract that delegates all calls to a separate "implementation" contract whose address is stored in a fixed storage slot. Proxies enable upgradeability — swap the implementation, the proxy address stays the same, users' state and balances are preserved. The attack: if the deployer creates the proxy and the initialize call (which sets the owner) in two separate transactions, automated bots watching mempools on every EVM chain can race-call initialize first, embedding a malicious owner or implementation. Kinto Protocol (1.55M,July2025)isthemostcitedcase;aggregatelossesacrossthecampaignexceeded1.55M, July 2025) is the most-cited case; aggregate losses across the campaign exceeded 10M. The fix is calling initialize atomically as part of the proxy deployment calldata. Our 33-check proxy & upgradeability checklist walks the full attack and remediation surface.
5. What does "compound exploit" mean and why does the 2026 list emphasize composition over single-category bugs?
A compound exploit is an attack that chains multiple weaknesses across different OWASP categories, where each step in isolation might pass review but the composition breaks an invariant. The canonical 2026 chain is: flash loan supplies adversarial capital (SC04) → oracle manipulation skews a price reference (SC03) → business logic flaw permits an under-collateralized action (SC02) → unchecked external call or proxy weakness finalizes extraction (SC06/SC10). The Euler Finance attack (197M,March2023)andtheMakinaexploit(197M, March 2023) and the Makina exploit (4.13M, January 2026) are textbook compound exploits. The 2026 list emphasizes composition because static analyzers, manual review, and category-by-category checklists all operate on isolated pieces of code — they can miss the attack that only exists when three pieces interact. The audit response is invariant testing, which models the system as a whole.
6. The 2026 list demoted reentrancy from #2 to #8 — does that mean reentrancy is solved?
No. The category dropped because the common mitigations — OpenZeppelin's ReentrancyGuard modifier, the Checks-Effects-Interactions pattern, and the post-Cancun ReentrancyGuardTransient (which lowered the gas cost of guards by an order of magnitude) — are now near-universal in modern Solidity codebases, and tools like Slither and Mythril detect the classic single-function pattern reliably. What remains in production findings is callback-driven reentrancy through ERC-721/1155/3525/777 hooks, ERC-4626 deposit/withdraw hooks, flash-loan callbacks, and read-only reentrancy (see Q3 above). The Solv Protocol ERC-3525 incident ($2.7M, 2026) is the canonical recent case. So: the surface shrunk, but the remaining surface is harder to find than what most audit curricula still teach. The category stays in the top ten precisely because these subtler variants are still landing.

Glossary

TermDefinition
Access ControlSecurity mechanisms restricting which addresses can call privileged functions.
Flash LoanUncollateralized loan borrowed and repaid within a single transaction.
Reentrancy AttackExploit where an external call re-enters a contract before state is updated.
Read-Only ReentrancyVariant where a view function returns inconsistent data during a callback.
Price Oracle ManipulationManipulation of price feeds to exploit oracle-dependent logic.
Proxy PatternUpgradeable contract architecture using delegatecall to an implementation.
Trust BoundaryEdge between two systems with different security or trust assumptions.
Invariant TestingStateful fuzzing that asserts protocol properties hold across call sequences.
OWASP Smart Contract Top 10Annual ranking of the most impactful smart contract vulnerability classes.

Get the DeFi Protocol Security Checklist

15 vulnerabilities every DeFi team should check before mainnet. Used by 30+ protocols.

No spam. Unsubscribe anytime.

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx