Solidity Patterns

23+ vulnerability patterns covering $3.8B+ in historical smart contract exploits. Detect reentrancy, flash loan attacks, and DeFi-specific vulnerabilities.

High-Value Targets

Smart contract vulnerabilities can lead to immediate, irreversible financial loss. All patterns are based on real exploits that caused significant damage.

Overview

Bloodhound provides specialized analysis for Solidity smart contracts, covering DeFi protocols, NFT contracts, and EVM-compatible chains.

8
Critical
7
High
5
Medium
3
Low
$3.8B+ in exploits covered

Reentrancy Attacks

Critical

Single-Function Reentrancy

Real exploit: The DAO Hack - $60M stolen

External calls before state updates allow recursive calls to drain funds.

Vulnerable
Solidity
1// Vulnerable: State updated after external call
2function withdraw(uint256 amount) public {
3 require(balances[msg.sender] >= amount);
4 (bool success,) = msg.sender.call{value: amount}("");
5 require(success);
6 balances[msg.sender] -= amount; // Too late!
7}
Secure
Solidity
1// Secure: Checks-Effects-Interactions pattern
2function withdraw(uint256 amount) public {
3 require(balances[msg.sender] >= amount);
4 balances[msg.sender] -= amount; // Update first
5 (bool success,) = msg.sender.call{value: amount}("");
6 require(success);
7}
Critical

Cross-Function Reentrancy

Real exploit: Cream Finance - $130M

Reentering through a different function that shares state.

Vulnerable
Solidity
1// Vulnerable: transfer() can be called during withdraw()
2function transfer(address to, uint256 amount) public {
3 require(balances[msg.sender] >= amount);
4 balances[msg.sender] -= amount;
5 balances[to] += amount;
6}
Secure
Solidity
1// Secure: Use ReentrancyGuard
2import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
3
4function withdraw(uint256 amount) public nonReentrant {
5 // Protected from reentrancy
6}

Access Control

Critical

Missing Access Control

Real exploit: Parity Wallet - $280M frozen

Critical functions without access restrictions.

Vulnerable
Solidity
1// Vulnerable: Anyone can call
2function initialize(address _owner) public {
3 owner = _owner;
4}
Secure
Solidity
1// Secure: Add access control
2function initialize(address _owner) public {
3 require(owner == address(0), "Already initialized");
4 owner = _owner;
5}
High

tx.origin Authentication

Using tx.origin for auth allows phishing attacks via malicious contracts.

Vulnerable
Solidity
1// Vulnerable: tx.origin can be manipulated
2function transferOwnership(address newOwner) public {
3 require(tx.origin == owner); // Phishable!
4 owner = newOwner;
5}
Secure
Solidity
1// Secure: Use msg.sender
2function transferOwnership(address newOwner) public {
3 require(msg.sender == owner);
4 owner = newOwner;
5}

Arithmetic Issues

High

Integer Overflow/Underflow

Real exploit: Beauty Chain - Token exploit

Arithmetic operations without overflow checks in Solidity < 0.8.

Vulnerable
Solidity
1// Vulnerable (Solidity < 0.8): No overflow check
2function transfer(address to, uint256 amount) public {
3 balances[msg.sender] -= amount; // Can underflow!
4 balances[to] += amount;
5}
Secure
Solidity
1// Secure: Use Solidity 0.8+ or SafeMath
2pragma solidity ^0.8.0; // Built-in overflow checks
3
4// Or with SafeMath for older versions:
5using SafeMath for uint256;
6balances[msg.sender] = balances[msg.sender].sub(amount);
Medium

Precision Loss in Division

Division before multiplication causes rounding errors.

Vulnerable
Solidity
1// Vulnerable: Division first causes precision loss
2uint256 fee = amount / 100 * feePercent;
Secure
Solidity
1// Secure: Multiply first, then divide
2uint256 fee = amount * feePercent / 100;

Flash Loan Attacks

Critical

Flash Loan Price Manipulation

Real exploits: bZx - $8M, Harvest Finance - $34M

Using flash loans to manipulate prices in single-block transactions.

Vulnerable
Solidity
1// Vulnerable: Single source price oracle
2function getPrice() public view returns (uint256) {
3 return reserve0 / reserve1; // Manipulable with flash loan
4}
Secure
Solidity
1// Secure: Time-weighted average price (TWAP)
2function getPrice() public view returns (uint256) {
3 return oracle.consult(token, 1e18, TWAP_PERIOD);
4}

Oracle Manipulation

Critical

Oracle Manipulation

Real exploit: Mango Markets - $114M

Relying on easily manipulated on-chain price data.

Vulnerable
Solidity
1// Vulnerable: Spot price from DEX
2function getValue(uint256 amount) public view returns (uint256) {
3 uint256 price = uniswapPair.getReserves();
4 return amount * price; // Manipulable
5}
Secure
Solidity
1// Secure: Chainlink oracle with staleness check
2function getValue(uint256 amount) public view returns (uint256) {
3 (, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
4 require(block.timestamp - updatedAt < 3600, "Stale price");
5 return amount * uint256(price) / 1e8;
6}

Smart Contract Auditing

For comprehensive smart contract audits, use Apex mode which combines all 7 engines with extended analysis time for maximum coverage.