testing

Installation
SKILL.md

Smart Contract Testing

What You Probably Got Wrong

You test getters and trivial functions. Testing that name() returns the name is worthless. Test edge cases, failure modes, and economic invariants — the things that lose money when they break.

You don't fuzz. forge test finds the bugs you thought of. Fuzzing finds the ones you didn't. If your contract does math, fuzz it. If it handles user input, fuzz it. If it moves value, definitely fuzz it.

You don't fork-test. If your contract calls Uniswap, Aave, or any external protocol, test against their real deployed contracts on a fork. Mocking them hides integration bugs that only appear with real state.

You write tests that mirror the implementation. Testing that deposit(100) sets balance[user] = 100 is tautological — you're testing that Solidity assignments work. Test properties: "after deposit and withdraw, user gets their tokens back." Test invariants: "total deposits always equals contract balance."

You skip invariant testing for stateful protocols. If your contract has multiple interacting functions that change state over time (vaults, AMMs, lending), you need invariant tests. Unit tests check one path; invariant tests check that properties hold across thousands of random sequences.


Unit Testing with Foundry

Test File Structure

Related skills

More from austintgriffith/ethskills

Installs
33
GitHub Stars
214
First Seen
Feb 19, 2026