TL;DR
The OWASP Smart Contract Top 10: 2026 is live. Based on 2025 incident data and practitioner surveys, it reshuffles the risk landscape. Reentrancy dropped from #2 to #8. Proxy & Upgradeability Vulnerabilities entered at #10 — a brand new category. And Business Logic Vulnerabilities climbed to #2, reflecting where the real money is being lost.
If you're still auditing like it's 2023, this ranking is your wake-up call.
What Changed (and Why It Matters)
The 2026 Ranking
| # | Category | Trend |
|---|---|---|
| SC01 | Access Control Vulnerabilities | → Stable at #1 |
| SC02 | Business Logic Vulnerabilities | ↑ New to Top 3 |
| SC03 | Price Oracle Manipulation | → Stable |
| SC04 | Flash Loan–Facilitated Attacks | → Stable |
| SC05 | Lack of Input Validation | ↑ Climbed |
| SC06 | Unchecked External Calls | → Stable |
| SC07 | Arithmetic Errors | ↓ Dropped |
| SC08 | Reentrancy Attacks | ↓↓ Fell from #2 |
| SC09 | Integer Overflow and Underflow | ↓ Dropped |
| SC10 | Proxy & Upgradeability Vulns | 🆕 New entry |
Three shifts stand out. Let's unpack each.
1. Reentrancy: From #2 to #8 — Progress, Not Safety
Reentrancy falling six spots is a success story with a footnote.
Why it dropped
- OpenZeppelin's
nonReentrantmodifier is now near-universal - The Checks-Effects-Interactions pattern is drilled into every Solidity bootcamp
- Post-Cancun
ReentrancyGuardTransientmade protection cheaper (transient storage = lower gas) - Static analysis tools (Slither, Mythril) catch basic reentrancy reliably
Why you can't ignore it
Cross-contract reentrancy is alive and well. When Contract A calls Contract B which calls back into Contract A through Contract C, single-contract reentrancy guards don't help. The 2025 incident data shows these multi-contract chains are where reentrancy still bites.
Read-only reentrancy is the silent killer. If your view function reads state that's mid-update during an external call, an attacker can get stale data. The fix: use _reentrancyGuardEntered() checks even in view functions.
// ❌ Vulnerable: view function reads inconsistent state
function getPrice() public view returns (uint256) {
return totalAssets / totalShares; // stale during reentrant call
}
// ✅ Protected: fails if reentrancy guard is active
function getPrice() public view returns (uint256) {
require(!_reentrancyGuardEntered(), "ReentrancyGuard: reentrant view");
return totalAssets / totalShares;
}
Takeaway: Reentrancy at #8 means the simple variants are solved. The subtle ones are now the actual threat.
2. Business Logic Vulnerabilities at #2 — The Auditor's Nightmare
This is the category that keeps auditors up at night because there's no static analysis tool that catches it.
Business logic vulnerabilities are flaws in the economic design — reward calculations, fee structures, liquidation thresholds, governance mechanics — that work exactly as coded but break under adversarial conditions.
Real examples from 2025-2026
Reward draining: A lending protocol's reward distribution calculated interest per-block but didn't account for flash-loan deposits lasting exactly one block. Attacker deposits $50M via flash loan, claims rewards, repays — net profit on "one-block lending."
Liquidation cascades: Oracle update timing + liquidation thresholds created a window where healthy positions could be liquidated. Not a bug — a design flaw.
Governance capture: Protocol required 10% quorum for proposals. Attacker flash-loaned governance tokens, passed a proposal to drain the treasury, all in one transaction.
What to do about it
- Economic modeling before code. Build a state machine of your protocol's economic flows. Identify every path where value can be extracted.
-
Invariant testing with Foundry. Define economic invariants (
totalDeposits >= totalWithdrawals + fees) and fuzz against them aggressively. - Adversarial thinking workshops. Before audit, have your team spend a day trying to break your own protocol's economics with pen and paper.
// Foundry invariant test example
function invariant_solvency() public {
uint256 totalDeposits = vault.totalAssets();
uint256 totalShares = vault.totalSupply();
// Vault should never be insolvent
assert(totalDeposits >= totalShares * vault.minSharePrice() / 1e18);
// No single user should hold >50% of shares (governance risk)
assert(vault.balanceOf(largestHolder) <= totalShares / 2);
}
3. Proxy & Upgradeability Vulnerabilities — The New #10
This is the first time proxy bugs have their own OWASP category, and it's overdue. 2025 saw several high-profile incidents where the upgrade mechanism itself was the attack vector.
The three proxy pitfalls
1. Unprotected initialize() functions
After deploying a proxy, the implementation contract needs to be initialized. If initialize() isn't protected or can be called twice, an attacker can reinitialize with their own parameters.
// ❌ No protection against re-initialization
function initialize(address _owner) public {
owner = _owner;
}
// ✅ Using OpenZeppelin's initializer modifier
function initialize(address _owner) public initializer {
__Ownable_init(_owner);
}
2. Storage collisions
Proxy patterns (UUPS, Transparent, Beacon) store implementation addresses in specific storage slots. If your implementation contract accidentally uses the same slot for a state variable, upgrading corrupts your data.
// EIP-1967 implementation slot:
// bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)
// = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
//
// If your contract stores a variable at this exact slot → catastrophic
3. Governance key compromise
The most expensive variant. If the key that controls upgrades is compromised (or is a single EOA), an attacker can upgrade the implementation to a malicious contract that drains everything.
The audit checklist for proxies
- [ ]
initialize()usesinitializermodifier and can only be called once - [ ] Storage layout is verified between upgrade versions (use
hardhat-upgradesorforge inspect) - [ ] Upgrade authority is a multisig or timelock, not an EOA
- [ ] UUPS proxies include
_authorizeUpgrade()with proper access control - [ ] Implementation contracts are initialized or have
_disableInitializers()in constructor - [ ] No storage slot collisions between proxy and implementation
Updated Audit Priority Matrix
Based on the 2026 ranking, here's how to allocate audit time:
Tier 1: Spend 50% of audit hours here
- Access Control (SC01) — Who can call what? Every external/public function.
- Business Logic (SC02) — Does the economic model hold under adversarial conditions?
- Oracle Integration (SC03) — Can prices be manipulated? TWAP vs spot? Staleness checks?
Tier 2: Spend 30% here
- Flash Loan Resilience (SC04) — Does any logic assume multi-block participation?
- Input Validation (SC05) — Zero addresses, extreme values, empty arrays
- External Call Safety (SC06) — Return value checks, callback safety
Tier 3: Spend 20% here
- Arithmetic (SC07) — Precision loss in share calculations, rounding direction
- Reentrancy (SC08) — Cross-contract and read-only variants
- Overflow/Underflow (SC09) — Unchecked blocks, assembly, non-Solidity contracts
- Proxy Safety (SC10) — Storage layout, initialization, upgrade governance
The Honourable Mentions You Shouldn't Ignore
OWASP also listed categories that didn't make the top 10 but are increasingly relevant:
Cross-Chain MEV — Source-chain event leakage enabling sandwich attacks on destination chains. The Symbiosis incident ($5.27M extracted) demonstrated this in 2025.
Permit Front-Running & Nonce DoS — Attackers front-run
permit()calls to consume nonces, causing legitimate transactions to revert. If your protocol composes permit into deposit flows without a fallback, this is a DoS vector.Governance Attack Vectors — Flash-loan voting, rushed proposals, timelock bypasses. If your protocol has on-chain governance, this deserves dedicated review time.
What This Means for Solana
The OWASP list is EVM-focused, but the patterns translate:
| EVM Category | Solana Equivalent |
|---|---|
| Access Control | Missing signer/owner checks on program instructions |
| Business Logic | Same — economic design flaws are chain-agnostic |
| Oracle Manipulation | Pyth/Switchboard staleness, confidence interval checks |
| Reentrancy | CPI (Cross-Program Invocation) reentrancy |
| Proxy/Upgradeability | Program upgrade authority management |
Solana developers should read the OWASP list through the lens of their own runtime. The vulnerability classes are universal even when the implementations differ.
Action Items
- Download the full OWASP Smart Contract Top 10: 2026 at scs.owasp.org/sctop10
- Participate in the 2026 survey if you have security practitioner experience — the ranking improves with community input
- Update your audit checklist using the priority matrix above
- Don't drop reentrancy from your radar — it dropped in ranking, not in danger
- Add proxy/upgradeability checks to every audit that involves upgradeable contracts
The OWASP Smart Contract Top 10 is derived from 2025 incident data and practitioner surveys. The 2026 list is forward-looking — projecting which risks will be most significant based on observed trends. Full methodology available at scs.owasp.org/sctop10/methodology.
What's your take — is reentrancy really less dangerous, or just less visible? Drop your thoughts in the comments.
Top comments (0)