一键导入
foundry
// 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.
// 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.
This skill should be used when the user asks about Effect-TS patterns, services, layers, error handling, service composition, or writing/refactoring code that imports from 'effect'. Also covers Effect + Next.js integration with @prb/effect-next.
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.
This skill should be used when the user asks to "create a Zustand store", "add Zustand", "manage global state with Zustand", "use Zustand with TypeScript", "add state management", or mentions Zustand stores, selectors, or middleware. Provides TypeScript-first state management guidance for Next.js projects.
This skill should be used when writing content for Sablier, including "write a blog post", "create a case study", "draft a tweet", "write X/Twitter posts", "write an announcement", "create educational content", or any marketing content task for Sablier's brand.
Write bulloak tree specifications (.tree files) for smart contract integration tests. Trigger phrases - write a tree, create test tree, BTT spec, bulloak tree, Branching Tree Technique, or when writing integration tests for contract functions.
This skill should be used when the user asks to "write tests", "add tests", "test coverage", "run tests", "debug failing tests", "mock functions", or mentions Vitest, unit tests, component tests, test-driven development, or testing utilities. Provides comprehensive Vitest v4 guidance for TypeScript React/Next.js projects.
| name | foundry |
| description | 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. |
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"