We use necessary cookies for site function. For analytics and marketing, we need your consent. You can change your mind anytime. Privacy Policy
Olvis Gil · September 25, 2026 · 11 min readSmart contracts are immutable programs that custody real money. Once deployed, a bug cannot be patched — it can only be exploited. That single fact explains why blockchain has produced some of the most expensive software bugs in history, and why security auditing is one of the best-paid specializations in the industry. Below are the ten vulnerability classes every developer must recognize before shipping code that holds value.
An attacker's contract calls back into your function before the first call finishes updating state, letting them drain funds repeatedly. This is the bug behind the infamous 2016 DAO hack (~$60M) that split Ethereum.
Prevention: Follow checks-effects-interactions (update state before external calls) and use reentrancy guards.Sensitive functions (mint, withdraw, upgrade) left callable by anyone, or guarded by logic that can be bypassed. Misconfigured admin functions are one of the most exploited bug classes in practice.
Prevention: Use proven role-based access control patterns, least-privilege design, and multisig for admin roles.Contracts that read prices from a single DEX pool or a manipulable feed can be tricked into bad valuations — the basis of many flash loan exploits.
Prevention: Use decentralized oracles with time-weighted average prices and sanity bounds on inputs.Attackers borrow millions with no collateral inside a single transaction, manipulate a protocol's assumptions, exploit it, and repay the loan atomically.
Prevention: Never rely on spot prices or balances within one transaction; design for attacker-controlled capital.Arithmetic that wraps around its type limits (e.g., 0 - 1 producing a huge number), historically allowing unlimited mints or bypassed balance checks.
Prevention: Use checked arithmetic (built into modern Solidity ≥0.8 and Rust) and fuzz arithmetic paths in tests.Ignoring the return value of a call that can fail — the contract proceeds as if a transfer succeeded when it did not.
Prevention: Always check return values and revert on failure.Transactions sit publicly in the mempool before confirmation; bots can insert their own transactions first to profit from yours (sandwich attacks on trades are the classic example).
Prevention: Use commit-reveal schemes, slippage limits, and private mempools where appropriate.Functions that can be griefed — e.g., looping over an unbounded array or pushing refunds to addresses that revert — making the contract unusable for everyone.
Prevention: Use pull-over-push payment patterns and bound or paginate loops.On-chain "randomness" derived from block data is predictable; and business-logic bugs (incorrect math, wrong invariants) slip past tests because they are valid code doing the wrong thing.
Prevention: Use verifiable randomness sources and write invariant/property tests for economic logic.Upgradeable contracts add attack surface: storage collisions, uninitialized implementations, and a compromised admin key that can replace the entire contract.
Prevention: Time-lock and multisig upgrades, validate storage layouts, and consider whether you need upgradeability at all.Most real-world exploits are not exotic — they are the same handful of mistakes repeated. Three habits eliminate the majority:
Checks-effects-interactions: validate inputs, update internal state, and only then interact with external contracts — in that order.
Least privilege: admin functions behind multisig and timelocks; every permission is a target.
Assume hostile inputs: prices can be manipulated, callbacks can re-enter, counterparties can revert. Treat every external dependency as adversarial.
Security is a skill stack, not a checklist: deep knowledge of the execution environment, familiarity with historical exploits, and a systematic review methodology. If you want a structured path, EduNode's Blockchain Security Auditing course covers vulnerability classes, audit methodology, and the tooling professionals use — and pairs naturally with Advanced Smart Contract Development. New to contracts entirely? Start with what smart contracts are.
Reentrancy is the most famous, but access-control failures and logic errors cause more losses in practice today. Oracle manipulation dominates in DeFi specifically, usually combined with flash loans.
Collectively, billions of dollars have been lost to exploits — from the DAO hack in 2016 to DeFi protocol drains and bridge exploits. Individual incidents regularly exceed tens of millions, which is why audits are now standard before launch.
If your contract will hold user funds, yes — an external audit is table stakes. But audits do not replace secure development: most audited hacks exploited code outside the audit scope or assumptions the team never documented.
Many classes carry over (access control, oracle trust, logic errors), but Rust's memory safety and Soroban's design eliminate some EVM-specific vectors like certain reentrancy patterns. The principles — least privilege, checks-effects-interactions, thorough testing — are universal.
Study past exploits (rekt.news post-mortems are a goldmine), practice on wargames like Ethernaut and Damn Vulnerable DeFi, and take a structured course — EduNode's Blockchain Security Auditing course walks through vulnerabilities, audit methodology, and tooling.
[1] Smart Contract Security Best Practices — ConsenSys