npx skills add smithery/towns-protocol --skill foundry-testing
sablier-labs/evm-monorepo · Archived
foundry-testing
Write Foundry-based tests and scripts. Trigger phrases - foundry testing, write test, fuzz test, fork test, invariant test, deploy script, gas benchmark, coverage, or when working in tests/ or scripts/ directories.
Installation
npx skills add sablier-labs/evm-monorepo --skill foundry-testing
Stronger alternatives
This repository is archived — consider an actively maintained alternative.
Write production-quality Solidity contracts. Trigger phrases - write contract, implement functi…
1 installsVerify smart contracts on Etherscan, Routescan, and Blockscout block explorers. This skill shou…
1 installsBuild, deploy, evaluate, optimize, fine-tune, and manage Microsoft Foundry agents, models, and …
576.5K installsExpert knowledge for Microsoft Foundry (aka Azure AI Foundry) development including troubleshoo…
187 installsSimilar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, includ…
810.4K installsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe …
568.9K installsPre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure…
567.7K installsConfigure Azure API Management as an AI Gateway for AI models, MCP tools, and agents. WHEN: sem…
566.3K installsAzure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compar…
510K installsPostgres best practices maintained by Supabase, for Postgres running anywhere. Load this skill …
391.6K installsAlso in this package
Other skills from sablier-labs/evm-monorepo.
npx skills add sablier-labs/evm-monorepo
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
Repository health
main
Skill metadata
Parsed from SKILL.md frontmatter.
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md8,168 B -
docs
SUMMARY.md237 B
History
- First seen on skills.sh
- First recorded snapshot · 1 installs
SKILL.md
Foundry Testing & Script Skill
Rules and patterns for Foundry tests. Find examples in the actual codebase.
Bundled References
| Reference | Content | When to Read |
|---|---|---|
.claude/skills/foundry-testing/references/test-infrastructure.md |
Constants, defaults, mocks | When setting up tests |
.claude/skills/foundry-testing/references/cheat-codes.md |
Common cheatcode patterns | When using vm cheatcodes |
.claude/skills/foundry-testing/references/invariant-patterns.md |
Handlers, stores, invariants | When writing invariant tests |
.claude/skills/foundry-testing/references/formal-verification.md |
Halmos, Certora, symbolic exec | When proving correctness |
.claude/skills/foundry-testing/references/deployment-scripts.md |
Script patterns, verification | When writing deploy scripts |
.claude/skills/foundry-testing/references/deployment-checklist.md |
Pre-mainnet deployment steps | Before deploying to production |
.claude/skills/foundry-testing/references/gas-benchmarking.md |
Snapshot, profiling, CI | When measuring gas performance |
.claude/skills/foundry-testing/references/sablier-conventions.md |
Sablier-specific patterns | When working in Sablier repos |
Test Types
| Type | Directory | Naming | Purpose |
|---|---|---|---|
| Integration | tests/integration/concrete/ |
*.t.sol |
BTT-based concrete tests |
| Fuzz | tests/integration/fuzz/ |
*.t.sol |
Property-based testing |
| Fork | tests/fork/ |
*.t.sol |
Mainnet state testing |
| Invariant | tests/invariant/ |
Invariant*.t.sol |
Stateful protocol properties |
| Scripts | scripts/solidity/ |
*.s.sol |
Deployment/initialization |
1. Integration Tests (Concrete)
Naming Convention
| Pattern | Usage |
|---|---|
testRevertWhen{Condition} |
Revert on input |
testRevertGiven{State} |
Revert on state |
testWhen{Condition} |
Success path |
Rules
- Stack modifiers to document BTT path (modifiers are often empty - just document the path)
- Expect events BEFORE action -
vm.expectEmit()then call function - Assert state AFTER action - Check state changes after function executes
- Use revert helpers for common patterns (
expectRevertDelegateCall,expectRevertNull) - Named parameters in assertions -
assertEq(actual, expected, "description")
Mock Rules
- Place all mocks in
tests/mocks/ - One mock per scenario (not one mega-mock)
- Naming:
Good,Reverting,InvalidSelector,Reentrant
2. Fuzz Tests
Naming Convention
testFuzz{FunctionName}{Scenario}
Rules
- Bound before assume -
_bound()is more efficient thanvm.assume() - Bound in dependency order - Independent params first, then dependent
- Never hardcode params with validation constraints
- Document fuzzed scenarios in NatSpec
Bounding Pattern
// 1. Bound independent params first
cliffDuration = boundUint40(cliffDuration, 0, MAX - 1);
// 2. Bound dependent params based on constraints
totalDuration = boundUint40(totalDuration, cliffDuration + 1, MAX);
3. Fork Tests
Rules
- Create fork with
vm.createSelectFork("ethereum") - Use
deal()to give tokens to test users - Use
assumeNoBlacklisted()for USDC/USDT - Use
forceApprove()for non-standard tokens (USDT)
Token Quirks
| Token | Issue | Solution |
|---|---|---|
| USDC/USDT | Blacklist | assumeNoBlacklisted() |
| USDT | Non-standard | forceApprove() |
| Fee-on-transfer | Balance diff | Check actual received amount |
4. Invariant Tests
Architecture
tests/invariant/
├── handlers/ # State manipulation (call functions with bounded params)
├── stores/ # State tracking (record totals, IDs)
└── Invariant.t.sol
Rules
- Target handlers only -
targetContract(address(handler)) - Exclude protocol contracts -
excludeSender(address(vault)) - Use stores to track totals for invariant assertions
- Early return in handlers if preconditions not met
5. Solidity Scripts
Rules
- Inherit from
BaseScriptwithbroadcastmodifier - Use env vars:
ETH_FROM,MNEMONIC - Simulation first, then broadcast
Commands
# Simulation
forge script scripts/Deploy.s.sol --sig "run(...)" ARGS --rpc-url $RPC
# Broadcast
forge script scripts/Deploy.s.sol --sig "run(...)" ARGS --rpc-url $RPC --broadcast --verify
Running Tests
# By type
forge test --match-path "tests/integration/concrete/**"
forge test --match-path "tests/fork/**"
forge test --match-contract Invariant_Test
# Specific test
forge test --match-test test_WhenCallerRecipient -vvvv
# Fuzz with more runs
forge test --match-test testFuzz_ --fuzz-runs 1000
# Coverage
forge coverage --report lcov
Debugging
Verbosity Levels
| Flag | Shows |
|---|---|
-v |
Logs for failing tests |
-vv |
Logs for all tests |
-vvv |
Stack traces for failures |
-vvvv |
Stack traces + setup traces |
-vvvvv |
Full execution traces |
Console Logging
import { console2 } from "forge-std/console2.sol";
console2.log("value:", someValue);
console2.log("address:", someAddress);
console2.logBytes32(someBytes32);
Debugging Commands
# Trace specific failing test
forge test --match-test test_MyTest -vvvv
# Gas report for a test
forge test --match-test test_MyTest --gas-report
# Debug in interactive debugger
forge debug --debug tests/MyTest.t.sol --sig "test_MyTest()"
# Inspect storage layout
forge inspect MyContract storage-layout
Debugging Tips
- Label addresses -
vm.label(addr, "Recipient")for readable traces - Check state with logs - Add
console2.logbefore reverts - Isolate failures - Run single test with
--match-test - Compare gas - Use
--gas-reportto spot unexpected costs - Snapshot comparisons - Use
vm.snapshot()/vm.revertTo()to isolate state changes
Best Practices Summary
- Use constants from
Defaults/Constants- never hardcode - Specialized mocks - one per scenario, all in
tests/mocks/ - Modifiers in
Modifiers.sol- centralize BTT path modifiers - Label addresses with
vm.label()for traces - Events before actions -
vm.expectEmit()then call - Bound before assume - more efficient
External References
Example Invocations
Test this skill with these prompts:
- Integration test: "Write a concrete test for
withdrawthat expectsErrors.Flow_Overdrawwhen amount exceeds
balance"
- Fuzz test: "Create a fuzz test for
depositthat bounds amount between 1 and type(uint128).max" - Fork test: "Write a fork test for USDC deposits on mainnet with blacklist handling"
- Invariant test: "Create an invariant handler for the
depositandwithdrawfunctions" - Deploy script: "Write a deployment script for SablierFlow with verification"