A catalogue of smart contract vulnerabilities: 12 classic mistakes and defences
An overview of frequent contract vulnerabilities: reentrancy, access control, overflow, oracles, signature replay, DoS. With examples and the escrow's defences.
In this article
Smart contracts are public programs that hold money, and so they are hunted. The good news: most hacks repeat the same schemes. Knowing the catalogue is the first step both for a developer and for someone assessing a contract (how to verify a contract). For each vulnerability we show the essence, an example and the defence.
1. Reentrancy
The essence. A contract sends money to an external address before updating its own state. In response the recipient calls the contract again and "withdraws" the money once more.
History. The hack of The DAO (2016, about 60 million dollars) split the Ethereum network in two.
Defence. The order "checks - state changes - external calls", the nonReentrant guard, "on request" payments (analysis).
2. Broken access control
The essence. A critical function is available to those who should not have it: a forgotten onlyOwner, an open initialiser, tx.origin instead of msg.sender.
Defence. Explicit checks, least privilege, a multisig for the owner (patterns).
3. Arithmetic: overflow and truncation
The essence. Before Solidity 0.8 numbers "wrapped around zero" with no error. In 0.8+ this is checked, but explicit type conversion (uint96(x)) still truncates silently.
Defence. Version 0.8+, a range check before conversion, SafeCast, care within unchecked (integer math).
4. Unchecked external calls
The essence. A low-level call (call) returns false on error but does not revert the transaction. If the result is ignored, the contract will think the payment went through.
Defence. Always check the result, use SafeERC20 for tokens whose transfer returns no value (token specifics).
5. Price and oracle manipulation
The essence. A contract takes a price from a source that can be distorted, for example from the current state of a pool. With a flash loan (a loan for one transaction) an attacker shifts the price for an instant and takes the profit. This has cost protocols hundreds of millions of dollars.
Defence. Reliable oracles, averaged prices, data-freshness checks (the oracle problem).
6. Front-running
The essence. Transactions are visible in the mempool before being included in a block. An observer can insert their transaction ahead of yours and profit.
Defence. Slippage limits, commit-reveal schemes, private transaction pools (MEV).
7. Signature replay and forgery
The essence. A signature verified without a nonce, deadline and binding to the network can be reused or used on another network. A signature is also "malleable" (signatures).
Defence. EIP-712, nonce, deadline, chainId, library verification.
8. Delegation and proxy mistakes
The essence. delegatecall runs someone else's code with the caller's storage. Mismatched layouts, an unprotected initialiser or a self-destructible library lead to disaster. In 2017 a bug in the Parity wallet library froze about 150 million dollars of ETH.
Defence. Proven patterns, protected initialisation, layout tests (proxies).
9. Denial of service (DoS)
The essence. One "bad" participant blocks everyone. The classic: a loop over a list of recipients where one rejects the payment and the whole operation reverts. Or an unbounded loop for which there is not enough gas.
Defence. The "pick it up yourself" (pull) model, a gas limit on external calls, no unbounded loops.
In the escrow. If a payout to a recipient fails (the address is blocked by the token issuer or the contract does not accept ETH), the amount is recorded as a credit for them and the deal closes. One problematic recipient does not block the others. The recipient call is limited to 50,000 gas (analysis).
10. Forced ether sending
The essence. Anyone can send ETH to a contract even if it has no way to receive (via selfdestruct or as a block reward recipient). If the logic relies on address(this).balance, it can be broken.
Defence. Keep your own accounting rather than rely on the balance. The escrow keeps accounting through reserved, and extra receipts fall into the "unaccounted" category and do not affect deals.
11. Reliance on time and randomness
The essence. block.timestamp can deviate by seconds, and "random" values from a block (hashes, time) are predictable and manipulable by a validator.
Defence. Do not use time for critical checks with a small tolerance; take randomness only from reliable sources.
In the escrow. Terms are measured in days or more; a margin of seconds affects nothing.
12. False assumptions about tokens
The essence. A contract assumes a token behaves like the reference ERC-20, but it takes a fee, changes balances, blocks addresses or has a bug.
Defence. A token whitelist, comparing the amount actually received with the declared one (tokens). The escrow accepts only allowed tokens and rejects a sum mismatch (AmountMismatch).
Bonus: "private" variable data is readable
Any storage slot is public, even for a private variable (storage layout). Secrets must not be kept in a contract.
How the escrow applies protection: a summary
| Threat | Measure |
|---|---|
| Reentrancy | nonReentrant, state is updated before payouts |
| Access control | checks of the deal parties, Ownable2Step, a pause only for new deals |
| Number truncation | the explicit AmountTooLarge check |
| DoS via a recipient | credits and a gas limit |
| Forced sending | reserved accounting instead of the balance |
| Non-standard tokens | a whitelist, checking the amount received |
Not all security is in the code
Vulnerabilities also exist outside the contract: hacked keys, interface substitution, people's erroneous signatures. The largest hack of 2025 (the Bybit exchange, about 1.5 billion dollars) began with the compromise of an interface that showed multisig signers the wrong data. So both personal rules and an audit matter.
What to read next
Learn how contracts are examined before launch: audits and bug bounties. Or how they are protected by tests: testing smart contracts.
Keep reading
- 3 · Under the hood
Audits and bug bounties - how smart contracts are examined and how to read a report
How a smart contract audit proceeds, the severity levels, what an audit is not, how to read a report, and how bug bounties and auditing contests work.
4 min read - 3 · Under the hood
Reentrancy, checks-effects-interactions and pull payments
How the reentrancy attack that hacked The DAO works and how to defend against it: operation order, ReentrancyGuard and deferred payments, using escrow.
6 min read
Mentioned in
- Tokens and NFTs - what they are, how they differ and where they are used
- Bridges between networks - how assets are moved and why it is the riskiest place
- How to verify a smart contract before using it - a step-by-step guide
- ERC-20 from scratch - writing a token in Solidity and analysing every line
- Signatures in Ethereum - ECDSA, ecrecover, personal_sign and EIP-712
- Storage layout and variable packing in Solidity
- Access-control patterns in smart contracts - owner, roles and deal parties
- Reentrancy, checks-effects-interactions and pull payments
- Non-standard tokens: USDT without a return value, fee-on-transfer and blacklists
- Proxies and upgradeable contracts - delegatecall, UUPS and the price of flexibility
- Merkle trees and membership proofs - verifying millions of items with one hash
- Oracles and the oracle problem - how a blockchain learns about the outside world
- Gas optimization in Solidity - 12 techniques and when they apply
- MEV and front-running - who earns from transaction order and how
- Account abstraction (ERC-4337) - smart wallets, gas sponsorship and access recovery
- Testing smart contracts: unit, fuzz, invariants and static analysis
- Audits and bug bounties - how smart contracts are examined and how to read a report
Ready to try it?
Create your first deal in a couple of minutes. The money is locked in a smart contract and paid out by rules you can see in advance.

