foundry-setup
Templates and automation for initializing and configuring Foundry projects. Use when setting up new Foundry projects or adding Foundry to existing codebases.
$ Installieren
git clone https://github.com/IvanTorresEdge/molcajete.ai /tmp/molcajete.ai && cp -r /tmp/molcajete.ai/tech-stacks/solidity/skills/foundry-setup ~/.claude/skills/molcajete-ai// tip: Run this command in your terminal to install the skill
name: foundry-setup description: Templates and automation for initializing and configuring Foundry projects. Use when setting up new Foundry projects or adding Foundry to existing codebases.
Foundry Setup Skill
This skill provides templates, scripts, and best practices for setting up Foundry-based Solidity projects.
When to Use
Use this skill when:
- Initializing a new Foundry project
- Adding Foundry to an existing Solidity codebase
- Configuring Foundry settings (optimization, tests, etc.)
- Setting up Foundry in a hybrid Hardhat/Foundry project
- Updating Foundry configuration
Prerequisites: Foundry must be installed (foundryup)
Integration with Framework Detection
Before using this skill, reference the framework-detection skill to:
- Check if Foundry is already configured
- Determine if this is a hybrid setup
- Avoid overwriting existing configuration
Quick Setup
Basic Initialization
# Initialize new Foundry project
forge init my-project
cd my-project
# Or initialize in existing directory
forge init --force
Project Structure
Foundry creates this structure:
project/
âââ foundry.toml # Configuration
âââ .env.example # Environment variables template
âââ lib/ # Dependencies (git submodules)
âââ src/ # Contract source files
â âââ interfaces # Interfaces
â â âââICounter # Example interface
â âââ Counter.sol # Example contract
âââ test/ # Test files
â âââ Counter.t.sol # Example test
âââ script/ # Deployment scripts
âââ Counter.s.sol # Example script
Configuration Templates
foundry.toml
See ./templates/foundry.toml for the complete configuration template.
Key Configuration Sections:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.30"
optimizer = true
optimizer_runs = 200
via_ir = false
# Testing
verbosity = 2
fuzz_runs = 256
# Gas reporting
gas_reports = ["*"]
# Formatting
line_length = 120
tab_width = 4
bracket_spacing = false
Environment Variables
See ./templates/.env.example for complete environment variable template.
Essential Variables:
# RPC URLs
MAINNET_RPC_URL=
SEPOLIA_RPC_URL=
ARBITRUM_RPC_URL=
# Private Keys (NEVER commit actual keys)
PRIVATE_KEY=
# Etherscan API Keys
ETHERSCAN_API_KEY=
ARBISCAN_API_KEY=
# Gas Price Settings
GAS_PRICE=
Common Configurations
1. High Optimization for Production
[profile.production]
optimizer = true
optimizer_runs = 10000
via_ir = true
2. Detailed Testing
[profile.test]
verbosity = 3
fuzz_runs = 1000
invariant_runs = 256
3. Gas Optimization Focus
[profile.gas-optimized]
optimizer = true
optimizer_runs = 1000000
via_ir = true
gas_reports = ["*"]
4. Mainnet Forking for Tests
[profile.default]
fork_url = "${MAINNET_RPC_URL}"
fork_block_number = 18000000
Dependencies Management
Adding Libraries
# Add OpenZeppelin contracts
forge install OpenZeppelin/openzeppelin-contracts
# Add Solmate
forge install transmissions11/solmate
# Add Forge Standard Library (included by default)
forge install foundry-rs/forge-std
Remappings
Foundry auto-generates remappings.txt, but you can customize:
@openzeppelin/=lib/openzeppelin-contracts/
@solmate/=lib/solmate/src/
forge-std/=lib/forge-std/src/
Or configure in foundry.toml:
remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/",
"@solmate/=lib/solmate/src/"
]
Initialization Script
See ./scripts/init-foundry.sh for automated setup.
Usage:
# Basic initialization
./scripts/init-foundry.sh
# With project name
./scripts/init-foundry.sh my-project
# In existing directory
./scripts/init-foundry.sh --force
What the script does:
- Checks if Foundry is installed
- Initializes Foundry project
- Copies configuration templates
- Sets up .gitignore
- Installs essential dependencies
- Creates initial directory structure
Hybrid Setup (Foundry + Hardhat)
When adding Foundry to an existing Hardhat project:
1. Initialize Foundry Without Overwriting
# Initialize but don't overwrite existing files
forge init --no-commit
2. Configure Separate Directories
# foundry.toml
[profile.default]
src = "contracts" # Use Hardhat's contracts dir
test = "test/foundry" # Separate Foundry tests
out = "out"
libs = ["node_modules", "lib"] # Include both package managers
3. Update .gitignore
# Foundry
out/
cache/
lib/
# Hardhat
artifacts/
cache/
node_modules/
4. Install Shared Dependencies
# Install via Foundry
forge install OpenZeppelin/openzeppelin-contracts
# Reference in Hardhat
# Add to hardhat.config.js:
# paths: { sources: "./contracts" }
Testing Setup
Basic Test Structure
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import "forge-std/Test.sol";
import "../src/MyContract.sol";
contract MyContractTest is Test {
MyContract public myContract;
function setUp() public {
myContract = new MyContract();
}
function testBasic() public {
// Test implementation
}
function testFuzz_Amount(uint256 amount) public {
// Fuzz test
}
}
Running Tests
# Run all tests
forge test
# Run specific test
forge test --match-test testBasic
# Run with verbosity
forge test -vvvv
# Run with gas reporting
forge test --gas-report
# Run with coverage
forge coverage
Security Best Practices for Private Keys
â ïž CRITICAL: Never store production private keys in .env files!
Recommended Approaches (in order of preference)
1. Hardware Wallets (Most Secure - Production)
# Deploy using Ledger
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--ledger \
--broadcast
# Deploy using Trezor
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--trezor \
--broadcast
2. Cast Wallet (Recommended - Development & Production)
Create a named keystore:
# Create a new wallet (prompts for password)
cast wallet new ~/.foundry/keystores/deployer
# Import existing private key into keystore
cast wallet import deployer --interactive
Use in deployment:
# Deploy using named account
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--account deployer \
--sender 0xYourAddress \
--broadcast
Update your script to use the account:
contract DeployScript is Script {
function run() external {
// No private key needed - uses --account flag
vm.startBroadcast();
MyContract myContract = new MyContract();
vm.stopBroadcast();
console.log("MyContract deployed to:", address(myContract));
}
}
3. Interactive Private Key (Development Only)
# Prompts for private key (not stored anywhere)
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--private-key-interactive \
--broadcast
4. .env Variables (Development/Testing ONLY)
â ïž Use ONLY for local development or testnet testing with non-production keys!
contract DeployScript is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
MyContract myContract = new MyContract();
vm.stopBroadcast();
console.log("MyContract deployed to:", address(myContract));
}
}
If using .env:
- â Only use accounts created specifically for development/testing
- â Never reuse production private keys
- â Keep test funds minimal
- â Add .env to .gitignore
- â Never commit .env to version control
- â Never use for mainnet deployments
Deployment Setup
Deploy Commands
# Dry run (simulation)
forge script script/Deploy.s.sol:DeployScript --rpc-url $RPC_URL
# Actual deployment with hardware wallet (RECOMMENDED for production)
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--ledger \
--broadcast \
--verify
# Actual deployment with cast wallet (RECOMMENDED for all deployments)
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--account deployer \
--sender 0xYourAddress \
--broadcast \
--verify
# Development only: with .env private key
forge script script/Deploy.s.sol:DeployScript \
--rpc-url $RPC_URL \
--broadcast \
--verify
Best Practices
- Secure private key management - Use hardware wallets or
cast walletfor all deployments; never store production keys in .env - Use profiles - Create different profiles for dev, test, production
- High optimizer runs for production - Use 10,000+ optimizer runs for deployed contracts
- Comprehensive .env.example - Document all required environment variables (but discourage private keys)
- Git submodules for deps - Let Foundry manage dependencies via git
- Separate test directories - Use
test/foundry/for Foundry tests in hybrid setups - Enable via-ir for optimization - Use
via_ir = truefor complex contracts - Version pin Solidity - Specify exact
solc_versionin foundry.toml
Troubleshooting
Issue: "forge: command not found"
# Install/update Foundry
curl -L https://foundry.paradigm.xyz | bash
foundryup
Issue: Dependency conflicts in hybrid setup
# Prioritize Foundry libs over node_modules
libs = ["lib", "node_modules"]
Issue: Compilation errors with remappings
# Regenerate remappings
forge remappings > remappings.txt
Issue: Tests not found
# Check test file naming (must end in .t.sol)
mv test/MyTest.sol test/MyTest.t.sol
Quick Reference
| Task | Command | Notes |
|---|---|---|
| Init project | forge init | Creates new project |
| Add dependency | forge install <repo> | Uses git submodules |
| Build | forge build | Compiles contracts |
| Test | forge test | Runs tests |
| Coverage | forge coverage | Test coverage |
| Gas report | forge test --gas-report | Gas usage |
| Format | forge fmt | Code formatting |
| Deploy | forge script | Run deployment |
| Verify | forge verify-contract | Verify on Etherscan |
Template Files
This skill provides the following templates:
./templates/foundry.toml- Complete Foundry configuration./templates/.env.example- Environment variables template
Scripts
This skill provides the following scripts:
./scripts/init-foundry.sh- Automated project initialization
Next Steps After Setup:
- Configure
foundry.tomlfor your specific needs - Copy
.env.exampleto.envand fill in values - Install required dependencies with
forge install - Write contracts in
src/ - Write tests in
test/ - Run
forge testto verify setup
Repository
