Back to Security

Smart Contract Vulnerabilities

A comprehensive guide to the most common and dangerous smart contract vulnerabilities. Learn how they work and how to prevent them.

Reentrancy

Critical

Allows attackers to repeatedly call back into the vulnerable contract before the first execution completes.

Impact

Complete fund drainage

Famous Exploit

The DAO ($60M, 2016)

Frequency

35% of exploits

Integer Overflow/Underflow

High

Arithmetic operations that exceed the maximum or minimum value wrap around, causing unexpected behavior.

Impact

Token theft, balance manipulation

Famous Exploit

BEC Token ($900M market cap, 2018)

Frequency

15% of exploits

Access Control

Critical

Missing or incorrect access modifiers allow unauthorized users to call privileged functions.

Impact

Contract takeover, fund theft

Famous Exploit

Parity Wallet ($280M, 2017)

Frequency

25% of exploits

Flash Loan Attacks

Critical

Exploits that leverage uncollateralized loans to manipulate prices or governance in a single transaction.

Impact

Protocol manipulation, arbitrage

Famous Exploit

Euler Finance ($197M, 2023)

Frequency

12% of exploits

Oracle Manipulation

Critical

Manipulating price feeds that smart contracts rely on for accurate external data.

Impact

Incorrect liquidations, fund theft

Famous Exploit

Cream Finance ($130M, 2021)

Frequency

18% of exploits

Front-Running / MEV

Medium

Miners or bots observe pending transactions and insert their own to profit at users' expense.

Impact

Sandwich attacks, failed trades

Famous Exploit

Ongoing across all DEXs

Frequency

8% of exploits

Signature Replay

High

Valid signatures can be reused across different contexts or chains when not properly validated.

Impact

Unauthorized transactions

Famous Exploit

Wormhole ($326M, 2022)

Frequency

5% of exploits

Unsafe Delegatecall

Critical

Improper use of delegatecall can allow attackers to execute arbitrary code in the context of the calling contract.

Impact

Complete contract takeover

Famous Exploit

Poly Network ($600M, 2021)

Frequency

4% of exploits

Deep Dive: Reentrancy

Vulnerable Code
// VULNERABLE - DO NOT USE
function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount);

    // External call BEFORE state update
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success);

    // State updated AFTER external call
    balances[msg.sender] -= amount; // TOO LATE!
}

The attacker's fallback function can call withdraw() again before the balance is updated.

Secure Code
// SECURE - Checks-Effects-Interactions Pattern
function withdraw(uint256 amount) external nonReentrant {
    // CHECKS
    require(balances[msg.sender] >= amount, "Insufficient");

    // EFFECTS - Update state BEFORE external call
    balances[msg.sender] -= amount;

    // INTERACTIONS - External call last
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success, "Transfer failed");
}

State is updated before the external call, and nonReentrant modifier prevents recursive calls.

How the Attack Works

1

Deposit

Attacker deposits funds into the contract

2

Withdraw

Attacker calls withdraw()

3

Callback

Attacker's fallback calls withdraw() again

4

Repeat

Loops until contract is drained

Prevention Strategies

  • Use the Checks-Effects-Interactions pattern
  • Implement OpenZeppelin's ReentrancyGuard
  • Use pull payments instead of push payments
  • Limit gas for external calls when possible

Scan Your Contract for Vulnerabilities

Use ChainLens to automatically detect these vulnerabilities and more in your smart contracts.

Try Free Vulnerability Scan