agentleFS
kaynetikkaynetik/skills/web3-testing/SKILL.md

web3-testing

Skill1 starsChanged 8 months agoMITView on GitHub

Production-grade smart contract testing with Foundry (primary) and Hardhat 3. Covers unit tests, parameterized fuzzing, stateful invariants with handlers and actor patterns, mainnet forking and impersonation, static analysis (Slither, Aderyn), property testing (Echidna, Medusa), symbolic execution (Halmos, Kontrol), gas snapshots, coverage, mutation testing, storage-layout upgrade safety, ERC-4337 testing, and CI integration. Use when writing or reviewing Solidity tests, designing test suites, chasing flaky tests, adding invariants, setting up Foundry or Hardhat, wiring CI for contracts, or when the user mentions forge, foundry, hardhat, cheatcodes, vm.prank, vm.expectRevert, invariant testing, fuzz testing, fork testing, Slither, Echidna, Medusa, Halmos, Kontrol, forge coverage, or forge snapshot.

6 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

5 rules. 0 are common, 3 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read these before doing anything else.

    line 12
  2. Distinctive:

    Read at most 2 reference files per turn: Use the routing table to pick.

    line 15
  3. Very specific:

    Fuzz everything that takes user input: Every public function with numeric, address, or byte inputs gets at least one fuzz test with …

    line 44
  4. Very specific:

    Test access control exhaustively: Every onlyRole/onlyOwner path needs a negative test proving unauthorized callers revert.

    line 48
  5. Distinctive:

    If the user explicitly chose another stack, do not argue.

    line 65

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Web3 Testing (Foundry primary, Hardhat 3 supported)

Routing-first skill. The body is intentionally thin; depth lives in reference/. Open only the files you actually need.

Token economy rules for the agent

Read these before doing anything else. They cut answer cost without losing quality.

  1. Do not paste the user's contract back at them. Reference function names and line ranges; write only the test harness or the diff.
  2. Read at most 2 reference files per turn. Use the routing table to pick.
  3. Never reproduce forge-std internals. Reference them by name (Test, StdInvariant, StdCheats) and assume the user has forge-std installed.
  4. Default to Foundry in examples. Only show Hardhat when the user says Hardhat or already has a Hardhat project.
  5. Prefer tables over prose for cheatcode catalogs, option matrices, or revert-parsing rules.
  6. Verify version-specific APIs via Context7 for Foundry, Hardhat, OpenZeppelin, Slither, Echidna, Halmos, and ethers/viem. Foundry and Hardhat both moved fast through 2024-2026; treat any pre-2026 snippet in your training as suspect -- especially testFail*, ethers v5, Goerli, and Hardhat 2 ESM assumptions.

Routing table

TaskFile
foundry.toml, profiles, remappings, forge init hygienereference/setup-foundry.md
Hardhat 3 with viem, Node test runner, legacy Hardhat 2 escape hatchreference/setup-hardhat.md
describe/it style vs Foundry tests, expectRevert, expectEmit, cheatcodesreference/unit-testing.md
Parameterized fuzzing, vm.assume, bound, typed generatorsreference/fuzzing.md
Stateful invariants, handlers, targetContract, actor-based patternsreference/invariants.md
Mainnet fork, block pinning, vm.createSelectFork, impersonationreference/forking.md
Slither, Aderyn, Echidna, Medusa integrationreference/static-and-property.md
forge snapshot, forge coverage, LCOV, mutation testing (necessist)reference/gas-and-coverage.md
GitHub Actions for Foundry/Hardhat, caching, slither gate, matrixreference/ci.md
Symbolic execution (Halmos, Kontrol), upgrade safety, ERC-4337 testsreference/advanced.md
Footguns: flaky tests, testFail, timestamp coupling, hardcoded blocksreference/anti-patterns.md

Golden rules (non-negotiable)

These prevent the failures that actually matter in production.

  1. Test against custom errors, not strings. vm.expectRevert(MyErr.selector) and revertedWithCustomError for Hardhat. revertedWith("...") is brittle and breaks under Solidity optimizer changes.
  2. Never use Foundry's testFail* prefix. It masks unrelated reverts. Always use vm.expectRevert with an explicit reason or selector.
  3. Pin the fork block. Unpinned forks are the #1 source of "passes locally, fails in CI" flakiness.
  4. Fuzz everything that takes user input. Every public function with numeric, address, or byte inputs gets at least one fuzz test with bound(...) to constrain to the domain.
  5. Invariants for protocols, not unit tests. Any system with accumulating state (lending, vaults, AMMs, staking, governance) needs a StdInvariant-based harness with handlers. Pure unit tests cannot find state-space bugs.
  6. Run forge snapshot in CI and fail on regressions. Silent gas bloat is a deployment-blocking problem you can only catch mechanically.
  7. Pair tests with at least one static analyzer (Slither or Aderyn). Tests find behavioral bugs; static analysis finds class-of-bug issues (reentrancy, tx.origin, unchecked-low-level-call) in patterns tests cannot exhaustively cover.
  8. Test access control exhaustively. Every onlyRole/onlyOwner path needs a negative test proving unauthorized callers revert.
  9. Never vm.skip() or disable a test without a tracked issue. Skipped tests are permanent dead code.
  10. Coverage is a floor, not a ceiling. Aim for >90% line AND branch, but stop measuring coverage once a suite has solid invariants and fuzz tests -- they find bugs coverage metrics never will.

Default stack (one choice, one escape hatch)

ConcernDefaultEscape hatch
Unit + fuzz + invariant frameworkFoundry (forge test)Hardhat 3 when the user already uses TypeScript-heavy tooling or off-chain integration is primary
Static analysisSlitherAderyn (Rust, faster) as a second opinion; run both in CI when budget allows
Property testingEchidnaMedusa (Go, faster on complex state)
Symbolic executionHalmos (Foundry-compatible)Kontrol for K-framework-grade rigor
Mainnet forkFoundry --fork-url with pinned --fork-block-numberHardhat network fork for TS-heavy suites
Gas reportingforge snapshot committed to repohardhat-gas-reporter
Coverageforge coverage --report lcovhardhat-coverage via solidity-coverage
Mutation testingnecessistSlither's slither-mutate

If the user explicitly chose another stack, do not argue; help them with what they have.

Decision matrix: what kind of test does this bug need?

Bug classTest type
Known revert path with fixed inputsUnit test with vm.expectRevert
Arithmetic edge cases across input domainParameterized fuzz test with bound
State-space bugs (accounting drift, double-spend)Stateful invariant with handler
Attack against specific mainnet stateBlock-pinned fork test
Protocol-level safety property ("no user can withdraw more than deposited")Invariant + Echidna/Medusa property
Class-of-bug (reentrancy, delegatecall misuse)Slither/Aderyn + unit test for the specific pattern
Algorithmic proof (upper bounds, absence of overflow)Halmos / Kontrol symbolic execution
Storage layout breakage after upgradeforge inspect storageLayout diff + OZ upgrades validator

When NOT to apply this skill

  • Writing the contracts themselves or architecting new protocols -> use ultimate-web3.
  • Solidity patterns, secure fixes, and audit preparation -> use solidity-security.
  • A codebase audit, pen test, or findings report -> use security-audit.
  • dApp frontend testing (component, E2E) -> that is frontend testing, not contract testing.

Companion skills

  • solidity-security -- vulnerability patterns and secure coding
  • ultimate-web3 -- protocol architecture
  • security-audit -- coverage-led codebase audit and findings report
  • web3-frontend -- dApp frontend patterns (wagmi, viem, Next.js)
  • gh -- CI authoring, GitHub Actions hygiene

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.