Expert usage of Foundry (Forge, Cast, Anvil, Chisel) for smart contract development, testing, and deployment. Includes fuzzing, gas reporting, local development, and deployment scripting capabilities.
Provides expert Foundry toolkit usage for Ethereum smart contract development, testing, and deployment.
npx claudepluginhub a5c-ai/babysitterThis skill is limited to using the following tools:
README.mdExpert-level usage of Foundry, the blazing fast, portable, and modular toolkit for Ethereum application development.
# Install Foundry
curl -L https://foundry.paradigm.xyz | bash
# Update to latest
foundryup
# Verify installation
forge --version
cast --version
anvil --version
chisel --version
# New project
forge init my_project
cd my_project
# Add dependencies
forge install OpenZeppelin/openzeppelin-contracts
forge install foundry-rs/forge-std
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.20"
optimizer = true
optimizer_runs = 200
via_ir = false
[profile.default.fuzz]
runs = 256
max_test_rejects = 65536
seed = "0x1234"
[profile.default.invariant]
runs = 256
depth = 15
fail_on_revert = false
[profile.ci]
fuzz = { runs = 10000 }
invariant = { runs = 1000, depth = 50 }
[rpc_endpoints]
mainnet = "${MAINNET_RPC_URL}"
sepolia = "${SEPOLIA_RPC_URL}"
arbitrum = "${ARBITRUM_RPC_URL}"
[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
sepolia = { key = "${ETHERSCAN_API_KEY}" }
// test/Counter.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/Counter.sol";
contract CounterTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
counter.setNumber(0);
}
function test_Increment() public {
counter.increment();
assertEq(counter.number(), 1);
}
function testFail_Underflow() public {
counter.decrement();
}
}
contract FuzzTest is Test {
function testFuzz_SetNumber(uint256 x) public {
counter.setNumber(x);
assertEq(counter.number(), x);
}
function testFuzz_BoundedInput(uint256 x) public {
x = bound(x, 1, 100);
// x is now between 1 and 100
}
}
contract InvariantTest is Test {
Counter public counter;
function setUp() public {
counter = new Counter();
targetContract(address(counter));
}
function invariant_NumberNeverNegative() public {
assertTrue(counter.number() >= 0);
}
function invariant_NumberUnderMax() public {
assertTrue(counter.number() < type(uint256).max);
}
}
contract ForkTest is Test {
function setUp() public {
// Fork mainnet at specific block
vm.createSelectFork("mainnet", 18000000);
}
function test_MainnetState() public {
// Interact with mainnet contracts
IERC20 dai = IERC20(0x6B175474E89094C44Da98b954EescdeCB5c811d7);
uint256 balance = dai.balanceOf(address(this));
}
}
# Build project
forge build
# Run tests
forge test
# Run tests with verbosity
forge test -vvvv
# Run specific test
forge test --match-test testFuzz_SetNumber
# Run tests with gas report
forge test --gas-report
# Generate gas snapshot
forge snapshot
# Compare gas snapshots
forge snapshot --diff
# Coverage
forge coverage
# Format code
forge fmt
# Get ETH balance
cast balance 0x... --rpc-url $RPC
# Read contract storage
cast storage 0x... 0 --rpc-url $RPC
# Call view function
cast call 0x... "balanceOf(address)" 0x... --rpc-url $RPC
# Decode calldata
cast calldata-decode "transfer(address,uint256)" 0x...
# Send ETH
cast send 0x... --value 1ether --rpc-url $RPC --private-key $KEY
# Call contract function
cast send 0x... "transfer(address,uint256)" 0x... 1000 --rpc-url $RPC --private-key $KEY
# Convert units
cast to-wei 1 ether
cast from-wei 1000000000000000000
# Compute function selector
cast sig "transfer(address,uint256)"
# Get ABI
cast abi-encode "transfer(address,uint256)" 0x... 100
# Decode ABI
cast abi-decode "balanceOf(address)(uint256)" 0x...
# Start local node
anvil
# Start with specific chain ID
anvil --chain-id 31337
# Fork mainnet
anvil --fork-url $MAINNET_RPC
# Fork at specific block
anvil --fork-url $MAINNET_RPC --fork-block-number 18000000
# Preload accounts
anvil --accounts 20 --balance 10000
# Impersonate account
cast rpc anvil_impersonateAccount 0x... --rpc-url http://localhost:8545
# Set balance
cast rpc anvil_setBalance 0x... 0x1000000000000000000 --rpc-url http://localhost:8545
# Mine blocks
cast rpc anvil_mine 10 --rpc-url http://localhost:8545
# Set block timestamp
cast rpc evm_setNextBlockTimestamp 1700000000 --rpc-url http://localhost:8545
// script/Deploy.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Script.sol";
import "../src/Counter.sol";
contract DeployScript is Script {
function setUp() public {}
function run() public {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
Counter counter = new Counter();
counter.setNumber(42);
vm.stopBroadcast();
console.log("Counter deployed at:", address(counter));
}
}
# Simulate deployment
forge script script/Deploy.s.sol --rpc-url $RPC
# Deploy to network
forge script script/Deploy.s.sol --rpc-url $RPC --broadcast
# Verify on Etherscan
forge script script/Deploy.s.sol --rpc-url $RPC --broadcast --verify
# Start Chisel
chisel
# In REPL
> uint256 x = 100
> x * 2
200
> address(this)
0x...
| Process | Purpose |
|---|---|
smart-contract-development-lifecycle.js | Full development |
smart-contract-fuzzing.js | Fuzzing and invariant testing |
invariant-testing.js | Property-based testing |
gas-optimization.js | Gas profiling |
| All DeFi processes | Testing and deployment |
forge fmt before committingskills/hardhat-framework/SKILL.md - Alternative frameworkskills/echidna-fuzzer/SKILL.md - Advanced fuzzingskills/gas-optimization/SKILL.md - Gas optimizationActivates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.