Skip to content

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:

  1. Roles Contract - Three-tier access control system (Admin → Manager → Distributor)
  2. Whitelist Contract - Merkle tree-based whitelist system with UUPS upgradeable pattern
  3. IFIFFactory Contract - Factory for deploying IFIF projects with DEX integration
  4. 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 deployment

Step-by-Step Deployment

1. Deploy Roles Contract

# Deploy Roles contract first
pnpm contracts:script script/Roles.s.sol --rpc-url $RPC_URL --broadcast --verify

Output: 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 --verify

Output: 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 V2

5. Deploy IFIFFactory and Implementations

# Deploy complete factory system
pnpm contracts:script script/IFIFFactory.s.sol --rpc-url $RPC_URL --broadcast --verify

Output: 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 --verify

Polygon

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 --verify

Arbitrum

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 --verify

Local Development (Anvil)

# Start local node
anvil
 
# Deploy to local network (mock DEX router address is acceptable for testing)
forge script script/DeployAll.s.sol:DeployAllScript

Post-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_KEY

Grant 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_KEY

Whitelist 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_KEY

Factory 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_KEY

Configure 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
Deployment Fee Payment Methods:
  • 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 --broadcast

Deployment 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
Token Payment:
# 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
Frontend Integration:
  • 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_KEY

Post-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_URL

Security Considerations

Private Key Management

  • Use --interactives 1 for 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 --verify

Environment 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 instead

Script 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:

  1. Assign Roles - Grant manager and distributor roles to appropriate addresses
  2. Configure Whitelist - Set initial merkle roots for whitelist sections
  3. Configure Factory - Set base URI and verify implementation contracts
  4. Test Integration - Verify all contracts work together correctly
  5. Create Test Project - Deploy a test IFIF project using the factory
  6. Set Up Monitoring - Monitor contract events and role changes
  7. Plan Upgrades - Establish governance for future upgrades