โ† All cheat sheets

BLOCKCHAIN-SECURITY

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

Security vulnerabilities, audit tools, and attack vectors
for blockchain applications and smart contracts.

COMMON SOLIDITY VULNERABILITIES#

1. REENTRANCY
   Description: External call allows callee to re-enter the calling
   function before state is updated.

   Vulnerable code:
     function withdraw(uint amount) public {
         require(balances[msg.sender] >= amount);
         (bool success, ) = msg.sender.call{value: amount}("");
         require(success);
         balances[msg.sender] -= amount;  // state updated AFTER call
     }

   Attack:
     // Attacker contract
     fallback() external payable {
         if (address(target).balance >= amount) {
             target.withdraw(amount);  // re-enter before balance updated
         }
     }

   Fix (Checks-Effects-Interactions pattern):
     function withdraw(uint amount) public {
         require(balances[msg.sender] >= amount);
         balances[msg.sender] -= amount;  // update state FIRST
         (bool success, ) = msg.sender.call{value: amount}("");
         require(success);
     }

   Additional mitigations:
     - Use ReentrancyGuard (OpenZeppelin nonReentrant modifier)
     - Use pull payment pattern instead of push
     - Limit gas forwarded in external calls

2. INTEGER OVERFLOW / UNDERFLOW
   Description: Arithmetic operations exceed type bounds.
   Note: Solidity 0.8.0+ has built-in overflow checks.

   Vulnerable (Solidity < 0.8.0):
     uint8 balance = 255;
     balance += 1;  // overflows to 0

     uint8 balance = 0;
     balance -= 1;  // underflows to 255

   Fix:
     - Use Solidity >= 0.8.0 (automatic checks)
     - For < 0.8.0: use SafeMath library
     - Use unchecked{} blocks only when overflow is intentional

3. ACCESS CONTROL
   Description: Missing or improper authorization checks.

   Vulnerable:
     function setOwner(address newOwner) public {
         owner = newOwner;  // anyone can call!
     }

   Fix:
     function setOwner(address newOwner) public onlyOwner {
         owner = newOwner;
     }

     modifier onlyOwner() {
         require(msg.sender == owner, "Not owner");
         _;
     }

   Best practices:
     - Use OpenZeppelin Ownable or AccessControl
     - Role-based access with AccessControl
     - Multi-sig for critical operations
     - TimeLock for governance changes

4. UNCHECKED EXTERNAL CALLS
   Description: Not checking return value of external calls.

   Vulnerable:
     payable(addr).send(amount);       // returns bool, not checked
     payable(addr).transfer(amount);   // reverts but limited to 2300 gas

   Fix:
     (bool success, ) = payable(addr).call{value: amount}("");
     require(success, "Transfer failed");

5. FRONT-RUNNING (MEV)
   Description: Attacker sees pending transaction and submits
   their own with higher gas price to execute first.

   Common targets:
     - DEX trades (sandwich attacks)
     - Token approvals
     - Auction bids
     - Oracle updates

   Mitigations:
     - Commit-reveal schemes
     - Use private mempools (Flashbots Protect)
     - Slippage protection on DEX trades
     - Batch auctions
     - Submarine sends

6. DENIAL OF SERVICE
   Description: Making contract functions unusable.

   Patterns:
     - Unexpected revert in loop (one failure blocks all)
     - Block gas limit reached (unbounded loops)
     - External call failure blocking critical functions
     - Self-destruct sending ETH to contract without receive()

   Fix:
     - Use pull over push patterns
     - Limit loop iterations
     - Handle external call failures gracefully
     - Set gas limits on external calls

7. ORACLE MANIPULATION
   Description: Manipulating price feeds or external data sources.

   Attack:
     1. Flash loan large amount of token A
     2. Swap to manipulate price on DEX (AMM)
     3. Interact with victim contract using manipulated price
     4. Profit from price difference
     5. Repay flash loan

   Fix:
     - Use time-weighted average prices (TWAP)
     - Use decentralized oracle networks (Chainlink)
     - Use multiple oracle sources
     - Implement circuit breakers for extreme price movements
     - Add price deviation checks

8. DELEGATECALL INJECTION
   Description: delegatecall executes code in the context of the
   calling contract, allowing storage manipulation.

   Vulnerable:
     function execute(address target, bytes calldata data) public {
         target.delegatecall(data);  // target can modify our storage
     }

   Fix:
     - Restrict delegatecall targets to trusted contracts
     - Use proxy patterns carefully (UUPS, Transparent)
     - Audit storage layout compatibility

9. SIGNATURE REPLAY
   Description: Valid signature reused on different chain or context.

   Fix:
     - Include chain ID in signed data (EIP-155)
     - Include nonce to prevent replay
     - Include contract address in signed message
     - Use EIP-712 for typed structured data signing
     - Implement deadline/expiration

10. FLASH LOAN ATTACKS
    Description: Borrow large amounts without collateral in single
    transaction to exploit price-dependent logic.

    Common pattern:
      1. Flash loan millions in tokens
      2. Manipulate AMM price
      3. Exploit lending protocol using wrong price
      4. Repay flash loan with profit

    Mitigations:
      - Use Chainlink oracles (not AMM spot price)
      - Implement TWAP oracles
      - Add transaction-level access controls
      - Rate limiting / cooldown periods

SECURITY ANALYSIS TOOLS#

Slither (Trail of Bits):
  pip install slither-analyzer

  # Basic analysis
  slither contract.sol
  slither . --solc-remaps "@openzeppelin=node_modules/@openzeppelin"

  # Specific detectors
  slither contract.sol --detect reentrancy-eth
  slither contract.sol --detect arbitrary-send-eth
  slither contract.sol --detect unchecked-transfer

  # Print useful information
  slither contract.sol --print contract-summary
  slither contract.sol --print function-summary
  slither contract.sol --print inheritance-graph

  Key detectors:
    reentrancy-eth          High: reentrancy with ETH transfer
    reentrancy-no-eth       Medium: reentrancy without ETH
    arbitrary-send-eth      High: unprotected ETH send
    suicidal                High: unprotected selfdestruct
    unprotected-upgrade     High: unprotected proxy upgrade
    unchecked-transfer      Medium: unchecked ERC20 transfer
    tx-origin               Medium: use of tx.origin for auth
    locked-ether            Medium: contract can receive but not send ETH

Mythril (ConsenSys):
  pip install mythril

  # Analyze contract
  myth analyze contract.sol
  myth analyze contract.sol --solc-json mythril.config.json

  # Analyze on-chain contract
  myth analyze -a <contract_address> --rpc <rpc_url>

  # Specific checks
  myth analyze contract.sol --execution-timeout 300

  Detection capabilities:
    - Integer overflow/underflow
    - Reentrancy
    - Unprotected selfdestruct
    - Delegatecall to untrusted contract
    - Ether transfer to arbitrary address
    - Unchecked return values

Echidna (Trail of Bits):
  # Property-based fuzzer for Solidity
  pip install echidna

  # Write test properties
  contract TestContract is TargetContract {
      function echidna_balance_positive() public view returns (bool) {
          return address(this).balance >= 0;
      }
      function echidna_no_overflow() public view returns (bool) {
          return totalSupply <= MAX_SUPPLY;
      }
  }

  # Run fuzzer
  echidna contract.sol --contract TestContract --config echidna.yaml

  # Configuration (echidna.yaml)
  testMode: assertion     # or property
  testLimit: 50000
  shrinkLimit: 5000
  seqLen: 100

Foundry (for security testing):
  # Fuzz testing
  function testFuzz_Withdraw(uint256 amount) public {
      vm.assume(amount > 0 && amount <= address(this).balance);
      // ... test withdraw logic
  }

  # Invariant testing
  function invariant_totalSupply() public {
      assertEq(token.totalSupply(), expectedSupply);
  }

  # Fork testing (test against mainnet state)
  forge test --fork-url https://eth-mainnet.alchemyapi.io/v2/<KEY>

Additional tools:
  Aderyn:          Rust-based static analyzer (fast)
  Certora Prover:  Formal verification (commercial)
  Manticore:       Symbolic execution (Trail of Bits)
  Securify2:       Automated security scanner (ETH Zurich)
  4naly3er:        Static analysis report generator

DEFI ATTACK VECTORS#

Flash Loan Attacks:
  Platforms: Aave, dYdX, Uniswap V3 (flash swaps)
  Pattern: borrow -> manipulate -> exploit -> profit -> repay
  Notable: bZx ($8M), Harvest Finance ($34M), Cream Finance ($130M)

Oracle Manipulation:
  Attack: Manipulate spot price on AMM, exploit price-dependent protocol
  Targets: Lending protocols using AMM as oracle
  Defense: Chainlink, TWAP, multiple oracles

Sandwich Attacks (MEV):
  Attack: Front-run + back-run victim's swap
  1. See victim's pending swap (buy token X)
  2. Buy token X first (front-run, price goes up)
  3. Victim's swap executes at worse price
  4. Sell token X (back-run, profit from price difference)
  Defense: MEV protection (Flashbots), slippage limits

Governance Attacks:
  Attack: Acquire enough tokens to pass malicious proposal
  Flash loan governance tokens, vote, execute in same block
  Defense: Time-locked proposals, vote escrow, snapshot voting

Rug Pulls:
  Types:
    - Liquidity removal (pull LP tokens)
    - Minting unlimited tokens
    - Hidden backdoor functions
    - Proxy upgrade to malicious implementation
  Red flags:
    - Unverified contract source
    - Owner can mint unlimited tokens
    - No timelock on admin functions
    - Low liquidity locked amount
    - Anonymous team

Price Manipulation via AMMs:
  Attack: Large swap to skew price, exploit dependent protocol
  Vulnerable: Any protocol reading AMM spot price as oracle
  Defense: TWAP, Chainlink, EMA oracles

WALLET SECURITY#

Hot wallet security:
  - Use hardware wallet for large amounts
  - Enable all available 2FA
  - Use dedicated device for crypto operations
  - Verify transaction details on hardware wallet screen
  - Be cautious of approval transactions (check spender and amount)

Private key management:
  - Never store private keys in plaintext
  - Use hardware wallets (Ledger, Trezor)
  - Multi-signature wallets for team/treasury (Safe/Gnosis)
  - Seed phrase: offline, metal backup, split storage
  - Never share seed phrase or private key

Common wallet attacks:
  - Phishing (fake dApp sites, wallet connect scams)
  - Approval exploits (infinite approve to malicious contract)
  - Address poisoning (dust transactions with similar addresses)
  - Clipboard malware (replaces copied addresses)
  - Fake airdrops (interaction triggers token approval)
  - Social engineering (fake support, fake giveaways)

Token approval safety:
  # Check approvals
  # Use: revoke.cash, etherscan token approval checker

  # Revoke approvals
  # Set approval to 0 for unused contracts
  token.approve(spenderAddress, 0);

  # Best practice: approve exact amount needed
  token.approve(spenderAddress, exactAmount);

AUDIT METHODOLOGY#

Pre-audit:
  1. Gather documentation (specs, architecture, threat model)
  2. Understand the protocol's intended behavior
  3. Review similar protocols and past audits
  4. Set up development environment
  5. Compile and run existing tests

Automated analysis:
  1. Run Slither (static analysis)
  2. Run Mythril (symbolic execution)
  3. Run Echidna (fuzzing) with custom properties
  4. Run Aderyn (fast static checks)
  5. Review automated findings, filter false positives

Manual review checklist:
  [ ] Access control: who can call each function?
  [ ] Reentrancy: external calls before state changes?
  [ ] Integer arithmetic: overflow/underflow possible?
  [ ] Oracle usage: is price data manipulation-resistant?
  [ ] Flash loan resistance: can logic be exploited in single tx?
  [ ] Front-running: are transactions MEV-susceptible?
  [ ] Upgrade safety: proxy storage layout compatible?
  [ ] Token handling: ERC20 return values checked? Fee-on-transfer?
  [ ] Gas optimization: unbounded loops? DoS potential?
  [ ] Input validation: all parameters validated?
  [ ] Event emissions: state changes properly logged?
  [ ] Centralization risks: admin key single point of failure?
  [ ] Economic model: game theory sound? Incentive alignment?
  [ ] Edge cases: zero values, max values, empty arrays?

Reporting:
  Severity levels:
    Critical:  Direct loss of funds, protocol takeover
    High:      Indirect loss of funds, significant impact
    Medium:    Limited impact, conditional exploit
    Low:       Best practice violations, minor issues
    Informational: Gas optimization, code quality

  Finding format:
    - Title
    - Severity
    - Description
    - Impact
    - Proof of Concept (test code)
    - Recommendation

COMMON SECURITY PATTERNS#

Checks-Effects-Interactions:
  function withdraw(uint amount) external {
      require(balances[msg.sender] >= amount);  // CHECK
      balances[msg.sender] -= amount;            // EFFECT
      (bool ok,) = msg.sender.call{value: amount}(""); // INTERACTION
      require(ok);
  }

Pull over Push:
  // Instead of sending to many, let each claim
  mapping(address => uint) public pendingWithdrawals;
  function withdraw() external {
      uint amount = pendingWithdrawals[msg.sender];
      pendingWithdrawals[msg.sender] = 0;
      payable(msg.sender).transfer(amount);
  }

Emergency stop:
  bool public paused;
  modifier whenNotPaused() { require(!paused); _; }
  function pause() external onlyOwner { paused = true; }

Timelock:
  // Delay between proposal and execution
  // Gives users time to exit if they disagree

Rate limiting:
  mapping(address => uint) public lastAction;
  modifier rateLimit(uint delay) {
      require(block.timestamp >= lastAction[msg.sender] + delay);
      lastAction[msg.sender] = block.timestamp;
      _;
  }

REFERENCES#

- SWC Registry: https://swcregistry.io/ (Smart Contract Weakness Classification)
- Slither: https://github.com/crytic/slither
- Mythril: https://github.com/Consensys/mythril
- Echidna: https://github.com/crytic/echidna
- OpenZeppelin Contracts: https://github.com/OpenZeppelin/openzeppelin-contracts
- Rekt News: https://rekt.news/ (DeFi exploit database)
- DeFi Llama Hacks: https://defillama.com/hacks
- Solidity by Example: https://solidity-by-example.org/