What Are the Most Common Smart Contract Vulnerabilities — and How Should Teams Defend Against Them?

Security · 2026-05-30 · 比特三棱镜编辑部
Ask AI

Every few weeks a contract gets exploited and the number — anywhere from a few million to a few hundred million — flashes across timelines. But aggregate the past three or four years of public post-mortems and you reach an unflattering conclusion. Most of the losses are not caused by exotic zero-days; they are caused by teams falling into the same old buckets over and over. Reentrancy, oracle manipulation, sloppy access control, broken proxy upgrades — auditors, researchers, and white hats have written about each of these endlessly, yet they reappear on the loss list year after year. This piece sorts them into four categories and itemizes what the project side can actually do.

Overview of four categories of common smart contract vulnerabilities

Category one: logic bugs — the classic trio keeps harvesting

Logic bugs are what auditors see most. They share a property — the bug sits in the code; one careful read finds it — yet deadlined devs still ship them. The trio:

  • Reentrancy — contract hands control to an external address, which re-enters withdraw logic before state was finalized. Fix is Checks-Effects-Interactions or ReentrancyGuard;
  • Integer overflow / underflow — pre-0.8 was common; post-0.8 built-in checks catch most, but custom unchecked blocks still hide landmines;
  • Missing access control — critical functions without onlyOwner. Sounds elementary, but 2025 still had eight-figure losses.

Cheapest defenses: Solidity 0.8+ with every unchecked reviewed separately; CEI on every critical state change; explicit permission model on every external/public function; Slither and Mythril in CI.

If you want to see what auditors actually do, smart contract audit explained offers a fair walk-through.

Category two: economic model bugs — price, slippage, flash loans

If category one is “bugs in the code”, category two is “bugs in the mechanism”. The code is clean but the team’s assumptions about incentives, price sources, or capital flow are wrong, and the whole mechanism gets drained through legal calls.

The most common subtype is price oracle manipulation. Some lending or options protocol takes the spot price of a single DEX pool as its quote; an attacker uses a flash loan to slam the pool sideways, triggers a favorable liquidation or redemption, and repays the loan. The playbook has been reused countless times, yet a fresh project trips on it every few months.

Defense:

  • Do not rely on the spot price of a single DEX pool — prefer aggregated oracles like Chainlink or Pyth, with deviation thresholds;
  • If you must use an on-chain pool, at least use TWAP (time-weighted average price), and pick a pool with enough depth;
  • Treat “flash loans are available” as a default assumption in your threat model — never assume “no one has that much money”;
  • For every critical path that consumes an external price, write a flash-loan simulation test.

Economic model bugs also include incentive mis-design — for example a farming contract where the cost of a self-loop is less than the emission, getting arb’d to zero. Static analysis cannot catch these — only human reasoning and simulation can.

Schematic of price oracle manipulation via flash loan attack chain

Category three: external dependency bugs

Smart contracts are not islands — they call ERC-20s, oracles, bridges, and other protocols. When an external dependency misbehaves, the calling contract often misbehaves too.

Common subtypes:

  • Non-standard ERC-20 — some tokens take a transfer fee, some do not return bool; a contract that assumes “standard token” will see balances diverge;
  • Upgradable external contracts — the contract you call today is benign; tomorrow it is upgraded to malicious logic. The risk is especially live when you call proxies;
  • Forgeable cross-chain messages — a contract that consumes cross-chain messages without verifying source must assume an attacker on the other side can fabricate them;
  • Abusable callbacks — you ship a “call this from anywhere” callback for integration friendliness; an attacker chains calls through it.

Bridges are a particularly heavy contributor — crosschain bridge hack history walks through the major past incidents.

What the project side should do:

  • Maintain a written “trust assumption list” for every external dependency — “I assume this contract will not turn malicious / this token is a standard ERC-20”;
  • Do not assume return values — use SafeERC20, not bare require(token.transfer(...));
  • Validate cross-chain messages on three axes — source chain ID, source address, nonce;
  • Ship an emergency pause, but balance the centralization risk of the pause role itself.

Category four: operations bugs — keys, upgrades, multisig

The last category is not a code bug — it is a human bug. You can write perfect code and still get drained if key management is loose, upgrade flow is chaotic, or multisig is theatre.

Subtype Typical scenario Defense
Key leak Deployer key in cloud notes or repo Hardware wallet, tiered cold storage
Multisig theatre All signers are the same internal team Add independent external signers
Over-broad upgrade rights Single owner can change any contract Timelock + public proposals
Pause role abuse Pause key gets phished Pause role on dedicated cold key

Teams keep treating these as “we will fix it later”, but they are the deadliest category over the past few years. Code bugs can be patched; stolen keys cannot.

Pair this section with hardware wallet supply chain risk for a more concrete picture of operational risk. If your project also faces regulatory pressure, countries with strictest crypto regulation helps you decide where to be more conservative.

Overview of project ops flow with multisig and timelock defenses

A non-complicated project-side defense checklist

Folding the four categories together, here is a plain checklist that blocks most of the accidents:

  1. Code side — Solidity 0.8+, Slither/Mythril clean, templated reentrancy and access control, full unit and fuzz tests on critical paths;
  2. Economic model — aggregated oracles with deviation thresholds, flash-loan attack scenarios on critical paths, incentive loops simulated;
  3. External dependencies — written trust assumption list, SafeERC20 everywhere, cross-chain message triple-check;
  4. Ops — hardware wallets for deploy keys, external signers in the multisig, Timelock on upgrades, dedicated cold key for pause;
  5. Post-launch — bug bounty sized 500K to 5M USD (scaled to TVL), dedicated white-hat channel, minute-grade monitoring;
  6. Audit — at least two independent audits, an in-house security engineer, treat audit as a recurring practice not a one-shot event.

Running this checklist does not make you immune — zero-days still exist and novel attacks still appear. But it guarantees you will not die in the buckets that have been post-mortemed dozens of times in the past three years — and that already covers 80% of what security work means in 2026.

Make defense part of the development rhythm

Back to the question “how should we defend”. The honest answer is — do not treat security as a launch checkpoint; treat it as a muscle that runs through the whole development cycle. Every PR gets a reentrancy and access-control pass. Every external dependency gets the question “what if this turns evil”. Every upgrade goes through Timelock. Every deployment uses a hardware wallet. No single move is hard, but once these become team muscle memory, the four categories above stay outside the door — and what is left to deal with shrinks to audits, white hats, and luck.