How to Use This Guide: When analyzing a contract, check each vulnerability pattern against
the code. Look for the detection signs listed below. Not all vulnerabilities will be present in every contract.
Core Vulnerabilities
1. Reentrancy Attack
CRITICAL
Reentrancy occurs when a contract makes an external call before updating its internal state. The called
contract can then call back into the original contract, executing code with outdated state values. This
allows attackers to drain funds by repeatedly withdrawing before balances are updated.
Detection Signs:
- External calls (
call,send,transfer) before state updates - Pattern: check → external call → state change (should be: check → state change → external call)
- Missing reentrancy guards or mutex locks
- Functions that both send ETH and modify balances
Attack Scenario:
- Attacker deploys malicious contract with fallback function
- Attacker calls
withdraw()on vulnerable contract - Vulnerable contract sends ETH, triggering attacker's fallback
- Fallback calls
withdraw()again before balance is updated - Process repeats, draining contract funds
Mitigation:
- Use checks-effects-interactions pattern (update state before external calls)
- Implement reentrancy guards (mutex/lock mechanism)
- Use
transfer()orsend()which limit gas (though not foolproof) - Consider pull-over-push payment patterns
Famous Exploit: The DAO Hack (2016) - $60 million stolen using reentrancy, leading to
Ethereum hard fork creating ETH and ETC.
2. Access Control Failure
CRITICAL
Access control vulnerabilities occur when privileged functions lack proper authorization checks, allowing
unauthorized users to execute critical operations like minting tokens, changing ownership, pausing contracts,
or upgrading implementations.
Detection Signs:
- Functions that change critical parameters without
require(msg.sender == owner) - Missing role-based access control on privileged functions
- Owner/admin functions accessible by anyone
- Uninitialized owner variables
Attack Scenario:
- Attacker identifies unprotected
setOwner()function - Attacker calls
setOwner(attackerAddress) - Attacker now has owner privileges
- Attacker can mint unlimited tokens, pause contract, or steal funds
- Original owner loses all control
Mitigation:
- Add
require(msg.sender == owner)to all privileged functions - Use OpenZeppelin's Ownable or AccessControl patterns
- Implement multi-signature requirements for critical operations
- Consider timelock mechanisms for sensitive changes
Famous Exploit: Poly Network Hack (2021) - $600 million exploited through access control
flaw allowing attacker to become contract admin.
3. Integer Overflow/Underflow
HIGH
Integer overflow/underflow occurs when arithmetic operations exceed the maximum (overflow) or go below
minimum (underflow) values for the data type. In Solidity versions before 0.8.0, this wraps around without
reverting, allowing attackers to manipulate balances and bypass checks.
Detection Signs:
- Arithmetic operations (
+,-,*) without checks - Missing SafeMath library (pre-Solidity 0.8.0)
- Subtraction that could go negative (e.g.,
balance -= amountwithout check) - Multiplication or addition that could exceed
uint256max
Attack Scenario (Underflow):
- Attacker has balance of 0 tokens
- Attacker calls
transfer(victim, 1) - Code executes:
balances[attacker] -= 1(0 - 1 = 2^256 - 1) - Attacker now has maximum uint256 tokens
- Attacker can transfer unlimited tokens or drain protocol
Mitigation:
- Use Solidity 0.8.0+ which has built-in overflow/underflow protection
- For older versions, use OpenZeppelin SafeMath library
- Add explicit checks:
require(balance >= amount)before subtraction - Use
uncheckedblocks only when overflow is intentional and safe
Famous Exploit: BEC Token (2018) - Integer overflow in batch transfer function allowed
attacker to create trillions of tokens from nothing, crashing token value.
Advanced Vulnerabilities
4. Flash Loan Attack
CRITICAL
Flash loan attacks exploit the ability to borrow massive amounts of capital within a single transaction
without collateral. Attackers manipulate prices, governance votes, or protocol logic using temporary
capital, then repay the loan in the same transaction.
Detection Signs:
- Price calculations based on single DEX pool balances
- Governance votes weighted by token balance in single transaction
- Reliance on spot prices instead of time-weighted averages
- Pool ratio calculations vulnerable to large trades
Attack Scenario:
- Attacker takes flash loan of 10,000 ETH
- Uses ETH to buy entire supply of token X, spiking price 10x
- Uses manipulated high price to borrow maximum from lending protocol
- Sells token X back, crashing price
- Repays flash loan, keeps borrowed funds, lending protocol left with bad debt
Mitigation:
- Use time-weighted average prices (TWAP) instead of spot prices
- Aggregate prices from multiple independent sources
- Implement price manipulation detection/circuit breakers
- Use Chainlink or other decentralized oracles
- Limit price changes per block/transaction
Famous Exploit: bZx Protocol (2020) - Multiple flash loan attacks totaling $1 million
through price manipulation across DeFi protocols.
5. Oracle Manipulation
HIGH
Oracle manipulation occurs when an attacker can influence the data source that smart contracts rely on for
external information (prices, random numbers, etc.). If oracles use manipulable sources like single DEX
pools, attackers can force incorrect contract behavior.
Detection Signs:
- Price oracles reading from single DEX pool
- Using
balanceOf()or reserves directly for price calculation - No aggregation across multiple price sources
- Instant price updates without time-weighting
Attack Scenario:
- Protocol uses DEX pool for price oracle
- Attacker executes massive buy order on DEX, manipulating pool ratio
- Oracle reports artificially high price
- Attacker uses inflated price to borrow maximum from lending protocol
- Attacker sells tokens back, normalizing price, leaves protocol with bad debt
Mitigation:
- Use multiple independent oracle sources (Chainlink, UMA, Band Protocol)
- Implement median or weighted average across sources
- Use TWAP from multiple DEX pools
- Add price deviation limits and circuit breakers
- Require time delays between oracle updates and critical operations
Famous Exploit: Harvest Finance (2020) - $34 million stolen through oracle manipulation
involving flash loans and price manipulation across multiple pools.
6. Front-Running (MEV)
MEDIUM
Front-running occurs when attackers observe pending transactions in the mempool and submit their own
transactions with higher gas fees to execute first. This allows them to profit from known future price
movements or sandwich trades between buy and sell orders.
Detection Signs:
- Transaction ordering dependency for profits
- Visible trade intentions in mempool before execution
- Lack of slippage protection on swaps
- No commit-reveal schemes for sensitive operations
Attack Scenario (Sandwich Attack):
- Bot detects large buy order in mempool (Alice buying 100 ETH of Token X)
- Bot submits buy order with higher gas (executes first, raising price)
- Alice's transaction executes at higher price (pays more)
- Bot submits sell order (executes after Alice, profiting from price increase)
- Bot extracts value from Alice's trade
Mitigation:
- Implement commit-reveal schemes for sensitive operations
- Use private transaction pools (Flashbots, Eden Network)
- Add slippage protection and max price parameters
- Batch transactions to reduce MEV opportunities
- Use time-locks and randomness for ordering
7. Timestamp Dependence
LOW-MEDIUM
Smart contracts relying on
block.timestamp for critical logic can be manipulated by miners
who have ~15 second wiggle room in setting block timestamps. While small, this can be exploited in
time-sensitive operations like lotteries, auctions, or unlock mechanisms.
Detection Signs:
- Using
block.timestampfor randomness - Critical logic depending on exact timestamp values
- Unlock/vesting mechanisms using
block.timestampcomparisons - Auction or lottery endings determined by timestamps
Attack Scenario:
- Time-locked vault unlocks when
block.timestamp >= unlockTime - Miner calculates that adjusting timestamp by 10 seconds allows unlock
- Miner sets favorable timestamp within acceptable range
- Miner or confederate unlocks funds early
- Process repeats, undermining time-lock security
Mitigation:
- Use
block.numberinstead ofblock.timestampfor time periods - Never use
block.timestampfor randomness (use Chainlink VRF) - Design logic to be safe within ~15 second timestamp variance
- For critical timing, use external time oracles
Additional Resources:
- SWC Registry: Smart Contract Weakness Classification
- ConsenSys Smart Contract Best Practices
- OpenZeppelin Security Audits and Guides
- Immunefi Bug Bounty Reports
© Joerg Osterrieder 2025-2026. All rights reserved.