CryptoHelper

ResearchGuidesReviews
Smart Contract Security Intermediate Level 12 min read

Smart Contract Auditing 101: Identifying Common EVM Vulnerabilities

A developer and investor guide to reviewing Solidity smart contracts, spotting reentrancy bugs, access control flaws, and oracle manipulation risks.

CH
Curated by CryptoHelper Research

Introduction: The Philosophy of Code as Law

On public blockchains, deployed bytecode is immutable. Flaws in logic or state updates cannot be patched through traditional hotfixes without pre-engineered proxy architectures. Conducting systematic static analysis and manual code review is mandatory prior to depositing capital into any DeFi protocol.


1. Reentrancy Vulnerabilities

Reentrancy occurs when an external contract call hands execution control back to an untrusted caller before state updates are finalized.

Vulnerable Pattern:

// VULNERABLE: State updated after external ether transfer
function withdraw(uint256 amount) public {
    require(balances[msg.sender] >= amount, "Insufficient funds");
    (bool success, ) = msg.sender.call{value: amount}("");
    require(success, "Transfer failed");
    balances[msg.sender] -= amount; // State modified too late!
}

Remediation: Checks-Effects-Interactions Pattern

// SECURE: Checks-Effects-Interactions & ReentrancyGuard
function withdraw(uint256 amount) public nonReentrant {
    require(balances[msg.sender] >= amount, "Insufficient funds");
    balances[msg.sender] -= amount; // 1. Effect
    (bool success, ) = msg.sender.call{value: amount}(""); // 2. Interaction
    require(success, "Transfer failed");
}

2. Oracle Manipulation & Spot Price Reliance

Protocols that query instantaneous spot prices from decentralized exchanges (like Uniswap v2 pair reserves) are vulnerable to flash loan manipulation within a single transaction block.

Oracle StrategyVulnerability LevelRecommended Implementation
DEX Spot ReservesCriticalNEVER use directly for lending collateralization
TWAP (Time-Weighted Average)ModerateRequires multiple blocks, costly to manipulate
Decentralized Oracles (Chainlink)LowMulti-source aggregation with heartbeat checks

3. Access Control & Initialization Flaws

Unprotected administrative initializers in upgradeable contracts (UUPS / Transparent Proxies) allow attackers to claim contract ownership:

  • Ensure all initialize() functions possess the initializer modifier.
  • Verify multi-signature governance (Gnosis Safe) controls privileged roles.
  • Implement timelocks with a minimum 48-hour delay for critical parameter modifications.

Audit Checklist for Protocol Due Diligence

  • Independent audit reports published by accredited security firms
  • Bug bounty program active on Immunefi
  • No unmitigated reentrancy vectors across all state-mutating functions
  • Decentralized oracle pricing resistant to single-block flash loan arbitrage
  • Multi-sig administrative access guarded by public timelock