Contract Deployment Guide
This guide provides comprehensive instructions for deploying the ifif protocol smart contracts to any Ethereum-compatible network.
Overview
The ifif protocol consists of core smart contracts that work together to provide a complete crowdfunding ecosystem:
- Roles Contract - Three-tier access control system (Admin → Manager → Distributor)
- Whitelist Contract - Merkle tree-based whitelist system with UUPS upgradeable pattern
- IFIFFactory Contract - Factory for deploying IFIF projects with DEX integration
- Implementation Contracts - IFIF and IFIFToken implementations for project deployments
Quick Start
Prerequisites
- Node.js and pnpm installed
- Foundry toolkit installed
- RPC endpoint for target network
- Private key for deployment account (with sufficient ETH for gas)
- DEX router address for the target network (required for factory deployment)
One-Command Deployment
# Deploy complete protocol to any network (requires DEX router configuration)
pnpm contracts:script script/DeployAll.s.sol --rpc-url $RPC_URL --broadcast --verify
# The script will prompt for your private key securely
# Note: Update DEX_ROUTER_ADDRESS in DeployAll.s.sol before deploymentStep-by-Step Deployment
1. Deploy Roles Contract
# Deploy Roles contract first
pnpm contracts:script script/Roles.s.sol --rpc-url $RPC_URL --broadcast --verifyOutput: You'll get the Roles contract address - save this for the next step.
2. Configure Whitelist Deployment
Edit contracts/script/Whitelist.s.sol and update the Roles address:
// Replace address(0) with your deployed Roles contract address
address public constant ROLES_ADDRESS = 0x742d35Cc6Ff7D966fD4c3f5AdB8d9aE6CE1E5E40;3. Deploy Whitelist Contract
# Deploy Whitelist with UUPS proxy
pnpm contracts:script script/Whitelist.s.sol --rpc-url $RPC_URL --broadcast --verifyOutput: You'll get the Whitelist proxy and implementation addresses.
4. Configure IFIFFactory Deployment
Edit contracts/script/IFIFFactory.s.sol and update the required addresses:
// Update with deployed contract addresses
address public constant ROLES_ADDRESS = 0x742d35Cc6Ff7D966fD4c3f5AdB8d9aE6CE1E5E40;
address public constant WHITELIST_ADDRESS = 0x8ba1f109551BD432803012645Hac136c22C6cC2a;
address public constant DEX_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; // Uniswap V25. Deploy IFIFFactory and Implementations
# Deploy complete factory system
pnpm contracts:script script/IFIFFactory.s.sol --rpc-url $RPC_URL --broadcast --verifyOutput: You'll get the factory address and implementation contract addresses.
Network Examples
Ethereum Mainnet
export RPC_URL="https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY"
# Update DEX_ROUTER_ADDRESS in DeployAll.s.sol with Uniswap V2: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
pnpm contracts:script script/DeployAll.s.sol --rpc-url $RPC_URL --broadcast --verifyPolygon
export RPC_URL="https://polygon-rpc.com"
# Update DEX_ROUTER_ADDRESS in DeployAll.s.sol with QuickSwap or SushiSwap router
pnpm contracts:script script/DeployAll.s.sol --rpc-url $RPC_URL --broadcast --verifyArbitrum
export RPC_URL="https://arb1.arbitrum.io/rpc"
# Update DEX_ROUTER_ADDRESS in DeployAll.s.sol with Uniswap V3 or SushiSwap router
pnpm contracts:script script/DeployAll.s.sol --rpc-url $RPC_URL --broadcast --verifyLocal Development (Anvil)
# Start local node
anvil
# Deploy to local network (mock DEX router address is acceptable for testing)
forge script script/DeployAll.s.sol:DeployAllScriptPost-Deployment Setup
Role Assignment
After deployment, the deployer has admin role. Assign operational roles:
Grant Manager Role
# Using cast (replace addresses with actual values)
cast send $ROLES_ADDRESS "grantRole(bytes32,address)" \
0x241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08 \
$MANAGER_ADDRESS \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEYGrant Distributor Role (by Manager)
# Manager grants distributor role
cast send $ROLES_ADDRESS "grantRole(bytes32,address)" \
0xfbd454f36a7e1a388bd6fc3ab10d434aa4578f811acbbcf33afb1c697486313c \
$DISTRIBUTOR_ADDRESS \
--rpc-url $RPC_URL \
--private-key $MANAGER_PRIVATE_KEYWhitelist Configuration
Set Initial Merkle Root
# Manager sets merkle root for section 0
cast send $WHITELIST_ADDRESS "updateRoot(uint8,bytes32)" \
0 \
$MERKLE_ROOT \
--rpc-url $RPC_URL \
--private-key $MANAGER_PRIVATE_KEYFactory Configuration
Update Factory Settings (Admin Only)
# Update base URI for NFT metadata
cast send $FACTORY_ADDRESS "updateBaseURI(string)" \
"https://api.ifif.xyz/metadata/" \
--rpc-url $RPC_URL \
--private-key $ADMIN_PRIVATE_KEY
# Update implementations
cast send $FACTORY_ADDRESS "updateImplementation(address)" \
$NEW_IFIF_IMPLEMENTATION \
--rpc-url $RPC_URL \
--private-key $ADMIN_PRIVATE_KEYConfigure Deployment Fees (Admin Only)
The factory supports deployment fees in ETH or ERC20 tokens to cover operational costs:
# Set ETH deployment fee (0.01 ETH example)
cast send $FACTORY_ADDRESS "updateDeploymentFee(address,uint256)" \
0x0000000000000000000000000000000000000000 \
10000000000000000 \
--rpc-url $RPC_URL \
--private-key $ADMIN_PRIVATE_KEY
# Set ERC20 token deployment fee (1000 USDC example - 6 decimals)
cast send $FACTORY_ADDRESS "updateDeploymentFee(address,uint256)" \
$USDC_TOKEN_ADDRESS \
1000000000 \
--rpc-url $RPC_URL \
--private-key $ADMIN_PRIVATE_KEY
# Disable deployment fee for a token (set amount to 0)
cast send $FACTORY_ADDRESS "updateDeploymentFee(address,uint256)" \
$TOKEN_ADDRESS \
0 \
--rpc-url $RPC_URL \
--private-key $ADMIN_PRIVATE_KEY- ETH Payment: Users send ETH value with the deployment transaction
- Token Payment: Users approve tokens first, then the factory transfers during deployment
- Multiple Methods: Configure multiple payment options for user flexibility
Project Creation
Create New IFIF Project
Projects can be deployed through the factory contract with automatic deployment fee handling:
# Create project using the factory (requires EIP-712 signature)
# Note: Use IFIFFactory.s.sol script for proper signature generation
pnpm contracts:script script/IFIFFactory.s.sol --sig "deployExampleProject()" --rpc-url $RPC_URL --broadcastDeployment Fee Payment
When deployment fees are configured, users have flexible payment options:
ETH Payment:# Deploy project with ETH fee (0.01 ETH example)
cast send $FACTORY_ADDRESS "deploy(tuple,tuple,bytes,bytes,string,string,address)" \
$CONFIG_TUPLE \
$NEXT_CONFIG_TUPLE \
$CONFIG_SIGNATURE \
$NEXT_CONFIG_SIGNATURE \
"ProjectName" \
"SYMBOL" \
0x0000000000000000000000000000000000000000 \
--value 10000000000000000 \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY# First approve tokens for the factory
cast send $TOKEN_ADDRESS "approve(address,uint256)" \
$FACTORY_ADDRESS \
$FEE_AMOUNT \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
# Then deploy project with token payment
cast send $FACTORY_ADDRESS "deploy(tuple,tuple,bytes,bytes,string,string,address)" \
$CONFIG_TUPLE \
$NEXT_CONFIG_TUPLE \
$CONFIG_SIGNATURE \
$NEXT_CONFIG_SIGNATURE \
"ProjectName" \
"SYMBOL" \
$TOKEN_ADDRESS \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY- The web interface automatically handles payment method selection
- Users can choose from available ETH or token payment options
- Token approvals are handled automatically via two-transaction flow
- Insufficient balance and allowance checks prevent failed transactions
Verification
Contract Verification
Scripts automatically verify contracts on Etherscan-compatible explorers. For manual verification:
# Verify Roles contract
forge verify-contract $ROLES_ADDRESS src/core/Roles.sol:Roles \
--chain-id $CHAIN_ID \
--etherscan-api-key $ETHERSCAN_API_KEY
# Verify Whitelist implementation
forge verify-contract $WHITELIST_IMPL_ADDRESS src/core/Whitelist.sol:Whitelist \
--chain-id $CHAIN_ID \
--etherscan-api-key $ETHERSCAN_API_KEY
# Verify IFIFFactory
forge verify-contract $FACTORY_ADDRESS src/utils/IFIFFactory.sol:IFIFFactory \
--constructor-args $(cast abi-encode "constructor(address,address,address)" $WHITELIST_ADDRESS $DEX_ROUTER_ADDRESS $ROLES_ADDRESS) \
--chain-id $CHAIN_ID \
--etherscan-api-key $ETHERSCAN_API_KEYPost-Deployment Checks
# Check deployer has admin role
cast call $ROLES_ADDRESS "hasRole(bytes32,address)(bool)" \
0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775 \
$DEPLOYER_ADDRESS \
--rpc-url $RPC_URL
# Check whitelist is initialized
cast call $WHITELIST_ADDRESS "getRoleHelper()(address)" --rpc-url $RPC_URL
# Check factory configuration
cast call $FACTORY_ADDRESS "whitelist()(address)" --rpc-url $RPC_URL
cast call $FACTORY_ADDRESS "dexRouter()(address)" --rpc-url $RPC_URL
cast call $FACTORY_ADDRESS "getRoleHelper()(address)" --rpc-url $RPC_URLSecurity Considerations
Private Key Management
- Use
--interactives 1for secure private key input - Never commit private keys to version control
- Use hardware wallets for mainnet deployments
- Consider multi-sig wallets for admin roles
Role Security
- Admin Role: Should be a secure multi-sig or hardware wallet
- Manager Role: Trusted addresses for whitelist management
- Distributor Role: Operational addresses for routine tasks
Upgrade Security
- Whitelist uses UUPS pattern - only admin can upgrade
- Always test upgrades on testnet first
- Consider timelock contracts for upgrade governance
Troubleshooting
Common Issues
"DEX_ROUTER_ADDRESS must be set"
Update DEX_ROUTER_ADDRESS in deployment scripts with a valid DEX router address for your target network.
"ROLES_ADDRESS must be set"
Update ROLES_ADDRESS in Whitelist.s.sol or IFIFFactory.s.sol with deployed Roles contract address.
"Invalid contract address"
Ensure the provided addresses are valid deployed contracts that implement the required interfaces.
Gas estimation failed
Check your account has sufficient ETH for deployment gas costs. Factory deployment requires more gas than basic contracts.
Verification failed
Ensure you're using the correct Etherscan API key and the contract is deployed.
Getting Help
- Check deployment logs for specific error messages
- Verify network configuration and RPC endpoints
- Ensure sufficient gas and proper private key setup
- Review contract requirements and dependencies
Advanced Configuration
Custom Network Configuration
# Add custom network to foundry.toml
[rpc_endpoints]
custom = "https://your-custom-rpc.com"
# Deploy to custom network
pnpm contracts:script script/DeployAll.s.sol --rpc-url custom --broadcast --verifyEnvironment Variables
# Optional environment variables
export ETHERSCAN_API_KEY="your_etherscan_api_key"
export RPC_URL="https://your-rpc-endpoint.com"
export PRIVATE_KEY="your_private_key" # Not recommended, use --interactives 1 insteadScript Customization
For custom deployment needs, modify the constants in deployment scripts:
// In deployment scripts
address public constant DEPLOYER_ADDRESS = 0x...;
address public constant DEX_ROUTER_ADDRESS = 0x...; // Required for factory deployment
string public constant BASE_URI = "https://api.ifif.xyz/metadata/";Production Deployment Checklist
- Test deployment on testnet first
- Verify all contract addresses and configurations
- Set correct DEX router address for target network
- Ensure sufficient ETH for gas costs (factory deployment requires more gas)
- Have Etherscan API key ready for verification
- Plan role assignment strategy
- Prepare merkle roots for initial whitelist setup
- Plan initial factory configuration (base URI, implementations)
- Set up monitoring and alerting
- Document all deployed addresses securely
- Plan upgrade procedures and governance
- Test factory project creation functionality
- Conduct security review of deployment plan
Contract Addresses
After deployment, save these addresses securely:
ROLES_ADDRESS=0x...
WHITELIST_IMPLEMENTATION=0x...
WHITELIST_PROXY=0x...
IFIF_FACTORY_ADDRESS=0x...
IFIF_IMPLEMENTATION=0x...
IFIF_TOKEN_IMPLEMENTATION=0x...
DEX_ROUTER_ADDRESS=0x...
DEPLOYER_ADDRESS=0x...Next Steps
After successful deployment:
- Assign Roles - Grant manager and distributor roles to appropriate addresses
- Configure Whitelist - Set initial merkle roots for whitelist sections
- Configure Factory - Set base URI and verify implementation contracts
- Test Integration - Verify all contracts work together correctly
- Create Test Project - Deploy a test IFIF project using the factory
- Set Up Monitoring - Monitor contract events and role changes
- Plan Upgrades - Establish governance for future upgrades