evm-testing

Write unit, fuzz, invariant, and fork tests for EVM smart contracts with Foundry and Hardhat.

6|20|Updated Mar 14, 2026
One-click install
npx skills add https://github.com/andresdefi/cryptoskills --skill evm-testing-andresdefi
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: evm-testing
Source: https://github.com/andresdefi/cryptoskills/tree/main/skills/evm-testing
Command: npx skills add https://github.com/andresdefi/cryptoskills --skill evm-testing-andresdefi

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Smart contract developers often write tests with subtle mistakes — misused cheatcodes, flaky fork tests, ineffective fuzz ranges, or invariants that never trigger — leading to false confidence in contract security. This Skill provides correct, battle-tested testing patterns for Foundry and Hardhat so tests actually catch bugs. ## Core Features & Use Cases - Foundry Testing Patterns: Unit tests with correct vm.prank/expectRevert/expectEmit usage, custom error assertions, and event ordering checks. - Fuzz & Invariant Testing: Property-based fuzz tests using bound() vs vm.assume(), plus stateful invariant tests with handler contracts and ghost variables. - Fork & Hardhat Testing: Pinned-block fork tests against live mainnet state (Uniswap, Aave), multi-fork setups, and Hardhat Mocha/Chai patterns with loadFixture and time manipulation. - Use Case: You are building a lending protocol and need to verify solvency under random user behavior. Use this Skill to write an invariant test with a handler contract that tracks ghost variables for deposits, borrows, and repayments, then asserts the pool always remains solvent. ## Quick Start Ask the AI to write a Foundry invariant test with a handler contract for your ERC4626 vault, including ghost variables and solvency assertions.

Frequently Asked Questions about evm-testing

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I write fuzz tests in Foundry?

Add parameters to your test function and Foundry generates random inputs automatically. Use bound() to constrain values into valid ranges instead of vm.assume(), which discards runs and can fail the campaign after too many rejections.

What is the difference between fuzz testing and invariant testing in Foundry?

Fuzz tests run one function with random inputs in isolation. Invariant tests are stateful: Foundry calls random sequences of functions across handler contracts, then checks that asserted properties still hold after every sequence.

vm.prank vs vm.startPrank in Foundry tests?

vm.prank(addr) only impersonates the address for the next single external call. Use vm.startPrank(addr) followed by vm.stopPrank() when your test makes multiple calls as the same address.

Why is my Foundry fork test flaky or failing?

Fork tests pull live mainnet state, so whale balances, oracle prices, and contract upgrades change over time. Pin a block number in vm.createSelectFork and enable RPC caching in foundry.toml to make runs deterministic.

Does Hardhat use Jest or Mocha for testing?

Hardhat uses Mocha for test structure (describe/it) and Chai for assertions via @nomicfoundation/hardhat-chai-matchers. Jest matchers like toBe and toEqual do not exist; use equal, revertedWithCustomError, and emit instead.

Why does my invariant test never find the bug?

Common causes are handler functions not covering all entry points, depth set too low, ghost variables not updated after calls, or bound() ranges too narrow. Increase invariant depth and runs in foundry.toml and widen input ranges.