Hashtag Web3 Logo

Using Foundry and Slither

8 min
advanced

The Auditor's Toolkit

Code review and executable tests answer different questions. Read the implementation, then test the behaviors and assumptions that could cause a failure.

Slither checks for patterns in source code. Foundry runs tests and local simulations. Both produce results that need interpretation.

1. Static Analysis: Slither

Slither can be run early in a review to identify areas that deserve closer inspection.

Slither is an open-source static analysis framework written in Python. "Static analysis" means it reads your code without actually executing it on a blockchain. It looks for known patterns of bad code.

What Slither catches in seconds:

  • Reentrancy vulnerabilities.
  • Uninitialized state variables.
  • public functions that should probably be internal.
  • Using outdated or dangerous Solidity keywords (like tx.origin for authorization).

Review each finding against the implementation. Some findings are false positives, and a clean run does not establish that the protocol's accounting or economic assumptions are correct.

2. The Testing Framework: Foundry

Foundry supports tests written in Solidity. JavaScript and TypeScript toolchains such as Hardhat are another option; use suitable integer types and libraries when handling EVM values in those languages.

Solidity tests

Solidity tests can call the same interfaces and use the same types as the contracts under review. Foundry also provides controls for accounts, time, balances, and other test conditions.

Fuzz Testing with Foundry

Fuzz testing runs a test with generated inputs instead of only a fixed set of examples.

When writing a standard unit test, a developer might write: "If user deposits 100 tokens, balance should equal 100."

But what if the user deposits 0 tokens? What if they deposit 115,792,089,237,316,195,423,570,985,008,687,907,853,269 tokens?

Fuzz testing automates this. You define the rules (the invariants), and Foundry automatically generates tens of thousands of random inputs and fires them at your smart contract. If even one random input breaks the contract, Foundry stops and tells you exactly which input caused the failure.

Fuzzer Generates 10,000 random inputs Smart Contract Function executes Invariant Did it break?

Mainnet Forking

If a hacker is executing a flash loan attack, they are interacting with live, deployed protocols like Uniswap and Aave. How do you test your defense against this?

Foundry can fork a network at a chosen block, fetching the state it needs through an RPC provider. Tests then run locally against that state. Pin the block for reproducible results; a fork does not reproduce every aspect of live transaction ordering or future market conditions.

How to get started in Security

To practice contract auditing:

  1. Learn Solidity's storage, call, and access-control behavior.
  2. Write unit, fuzz, and invariant tests with a tool such as Foundry.
  3. Read past audit reports. Firms like Consensys Diligence publish their findings publicly.
  4. Compete on platforms like Code4rena or Sherlock, where protocols post bounties for developers to find bugs in their code.

A practice exercise

Choose a small open-source contract. Run its tests, inspect Slither's findings, and write one additional test for an accounting invariant. Record what you tested and what remains outside the review.

Quiz: Using Foundry and Slither

1 / 5

What is Foundry?