evm-testing

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

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

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 invariant tests that never find bugs — leading to false confidence in contract security. This Skill provides correct, battle-tested testing patterns for Foundry and Hardhat so tests actually catch vulnerabilities. ## Core Features & Use Cases - Foundry Testing Patterns: Unit tests with correct vm.prank/vm.expectRevert/vm.expectEmit usage, custom error assertions, and event ordering checks. - Fuzz & Invariant Testing: Input bounding with bound() vs vm.assume(), handler contracts with ghost variables, and solvency/accounting invariants for DeFi protocols. - Fork Testing: Pinned-block mainnet forks, whale impersonation, multi-fork L1/L2 setups, and tests against deployed Uniswap and Aave contracts. - Hardhat Testing: Mocha/Chai patterns with loadFixture, revert and event matchers, time manipulation, and balance change assertions. - Use Case: When auditing a lending pool, use the invariant handler pattern to fuzz random deposit/borrow/repay sequences and assert that total borrows never exceed total deposits. ## Quick Start Ask the agent to write a Foundry invariant test with a handler contract and ghost variables for your ERC-4626 vault.

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, while invariant tests call random sequences of functions across contracts and assert properties that must always hold. Invariant tests use handler contracts with ghost variables to track cumulative state.

vm.prank vs vm.startPrank in Foundry tests?

vm.prank(addr) only affects the next external call, while vm.startPrank(addr) applies to all calls until vm.stopPrank(). Using prank when multiple calls need the same sender is the most common cause of tests passing when they should not.

Why is my Foundry fork test flaky or failing with RPC errors?

Fork tests pull live mainnet state, so whale balances and contract storage change over time. Pin a block number in vm.createSelectFork, use a paid RPC provider to avoid rate limits, and enable RPC storage caching in foundry.toml.

Does Hardhat use Jest or Mocha for testing?

Hardhat uses Mocha for test structure with describe/it blocks and Chai for assertions via @nomicfoundation/hardhat-chai-matchers. Jest matchers like toBe and toEqual do not exist; use expect().to.equal and revertedWithCustomError 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 verify targetContract is set in setUp().