skills/cli-forge/SKILL.md
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.
npx skillsauth add sablier-labs/agent-skills cli-forgeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Rules and patterns for Foundry tests. Find examples in the actual codebase.
| Reference | Content | When to Read |
| -------------------------------------- | ------------------------------ | ------------------------------ |
| ./references/test-infrastructure.md | Constants, defaults, mocks | When setting up tests |
| ./references/cheat-codes.md | Common cheatcode patterns | When using vm cheatcodes |
| ./references/invariant-patterns.md | Handlers, stores, invariants | When writing invariant tests |
| ./references/formal-verification.md | Halmos, Certora, symbolic exec | When proving correctness |
| ./references/deployment-scripts.md | Script patterns, verification | When writing deploy scripts |
| ./references/deployment-checklist.md | Pre-mainnet deployment steps | Before deploying to production |
| ./references/gas-benchmarking.md | Snapshot, profiling, CI | When measuring gas performance |
| ./references/sablier-conventions.md | Sablier-specific patterns | When working in Sablier repos |
| 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 |
| Pattern | Usage |
| ----------------------------- | --------------- |
| test_RevertWhen_{Condition} | Revert on input |
| test_RevertGiven_{State} | Revert on state |
| test_When_{Condition} | Success path |
vm.expectEmit() then call functionexpectRevert_DelegateCall, expectRevert_Null)assertEq(actual, expected, "description")tests/mocks/*Good, *Reverting, *InvalidSelector, *ReentranttestFuzz_{FunctionName}_{Scenario}
_bound() is more efficient than vm.assume()// 1. Bound independent params first
cliffDuration = boundUint40(cliffDuration, 0, MAX - 1);
// 2. Bound dependent params based on constraints
totalDuration = boundUint40(totalDuration, cliffDuration + 1, MAX);
vm.createSelectFork("ethereum")deal() to give tokens to test usersassumeNoBlacklisted() for USDC/USDTforceApprove() for non-standard tokens (USDT)| Token | Issue | Solution |
| --------------- | ------------ | ---------------------------- |
| USDC/USDT | Blacklist | assumeNoBlacklisted() |
| USDT | Non-standard | forceApprove() |
| Fee-on-transfer | Balance diff | Check actual received amount |
tests/invariant/
├── handlers/ # State manipulation (call functions with bounded params)
├── stores/ # State tracking (record totals, IDs)
└── Invariant.t.sol
targetContract(address(handler))excludeSender(address(vault))BaseScript with broadcast modifierETH_FROM, MNEMONIC# 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
# 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
| 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 |
import { console2 } from "forge-std/console2.sol";
console2.log("value:", someValue);
console2.log("address:", someAddress);
console2.logBytes32(someBytes32);
# 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
vm.label(addr, "Recipient") for readable tracesconsole2.log before reverts--match-test--gas-report to spot unexpected costsvm.snapshot() / vm.revertTo() to isolate state changesDefaults/Constants - never hardcodetests/mocks/Modifiers.sol - centralize BTT path modifiersvm.label() for tracesvm.expectEmit() then callTest this skill with these prompts:
withdraw that expects Errors.Flow_Overdraw when amount exceeds
balance"deposit that bounds amount between 1 and type(uint128).max"deposit and withdraw functions"development
This skill should be used when the user asks to "create a state machine", "add xState", "use xState with React", "implement actor-based state", "manage complex state with state machines", "use xState with Effect", "integrate Effect-ts with xState", mentions xState hooks (useMachine, useActor, useSelector), or discusses finite state machines in React applications.
tools
This skill should be used when the user asks about "viem", "viem client", "viem actions", "TypeScript Ethereum", "createPublicClient", "createWalletClient", "parseEther", "formatEther", "readContract", "writeContract", or mentions using viem for blockchain interactions.
development
This skill should be used when the user asks about "Tailwind CSS", "tailwind-variants", "tv() function", "CSS-first configuration", "Tailwind breaking changes", mentions styling with Tailwind utilities, gradient syntax, or component variants with TypeScript.
development
This skill should be used when the user asks to "analyze a screenshot", "generate implementation spec", "create SPEC.md from screenshot", "extract design specs", "spec from image", or provides website screenshots and wants detailed implementation guidance.