Skip to main content

Deployment Guide

This guide covers deploying Oak Network smart contracts to various networks and environments.

๐Ÿ“‹ Table of Contentsโ€‹

๐Ÿ”ง Prerequisitesโ€‹

Required Softwareโ€‹

  • Node.js 16+ and npm/yarn
  • Git for version control
  • Hardhat for smart contract development
  • Celo CLI for network interaction
  • MetaMask or compatible wallet

Required Accountsโ€‹

  • Deployer Account - Account with CELO for gas fees
  • Admin Account - Account for protocol administration
  • Treasury Account - Account for protocol fees

๐ŸŒ Environment Setupโ€‹

1. Clone Repositoryโ€‹

git clone https://github.com/oak-network/oaknetwork-contracts.git
cd oaknetwork-contracts

2. Install Dependenciesโ€‹

npm install

3. Environment Configurationโ€‹

Create environment files for different networks:

# Copy example environment file
cp .env.example .env

# Create network-specific files
cp .env.example .env.local
cp .env.example .env.testnet
cp .env.example .env.mainnet

4. Configure Environment Variablesโ€‹

# .env.local
NETWORK=localhost
RPC_URL=http://127.0.0.1:8545
PRIVATE_KEY=your_private_key_here
ADMIN_ADDRESS=your_admin_address_here
TREASURY_ADDRESS=your_treasury_address_here

# .env.testnet
NETWORK=alfajores
RPC_URL=https://alfajores-forno.celo-testnet.org
PRIVATE_KEY=your_private_key_here
ADMIN_ADDRESS=your_admin_address_here
TREASURY_ADDRESS=your_treasury_address_here
ETHERSCAN_API_KEY=your_etherscan_api_key

# .env.mainnet
NETWORK=celo
RPC_URL=https://forno.celo.org
PRIVATE_KEY=your_private_key_here
ADMIN_ADDRESS=your_admin_address_here
TREASURY_ADDRESS=your_treasury_address_here
ETHERSCAN_API_KEY=your_etherscan_api_key

๐Ÿ  Local Developmentโ€‹

1. Start Local Networkโ€‹

# Start Hardhat local network
npx hardhat node

# In another terminal, deploy contracts
npx hardhat run scripts/deploy.js --network localhost

2. Deploy Scriptโ€‹

// scripts/deploy.js
const { ethers } = require("hardhat");

async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with account:", deployer.address);
console.log("Account balance:", (await deployer.getBalance()).toString());

// Deploy GlobalParams
const GlobalParams = await ethers.getContractFactory("GlobalParams");
const globalParams = await GlobalParams.deploy();
await globalParams.deployed();
console.log("GlobalParams deployed to:", globalParams.address);

// Deploy TreasuryFactory
const TreasuryFactory = await ethers.getContractFactory("TreasuryFactory");
const treasuryFactory = await TreasuryFactory.deploy(globalParams.address);
await treasuryFactory.deployed();
console.log("TreasuryFactory deployed to:", treasuryFactory.address);

// Deploy CampaignInfoFactory
const CampaignInfoFactory = await ethers.getContractFactory("CampaignInfoFactory");
const campaignFactory = await CampaignInfoFactory.deploy(
globalParams.address,
treasuryFactory.address
);
await campaignFactory.deployed();
console.log("CampaignInfoFactory deployed to:", campaignFactory.address);

// Deploy Treasury Implementations
const AllOrNothing = await ethers.getContractFactory("AllOrNothing");
const allOrNothing = await AllOrNothing.deploy();
await allOrNothing.deployed();
console.log("AllOrNothing deployed to:", allOrNothing.address);

const KeepWhatsRaised = await ethers.getContractFactory("KeepWhatsRaised");
const keepWhatsRaised = await KeepWhatsRaised.deploy();
await keepWhatsRaised.deployed();
console.log("KeepWhatsRaised deployed to:", keepWhatsRaised.address);

// Set treasury implementations
await treasuryFactory.setTreasuryImplementation("AllOrNothing", allOrNothing.address);
await treasuryFactory.setTreasuryImplementation("KeepWhatsRaised", keepWhatsRaised.address);

console.log("Deployment completed!");
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

๐Ÿงช Testnet Deploymentโ€‹

1. Get Testnet CELOโ€‹

Visit the Celo Faucet to get testnet CELO.

2. Deploy to Alfajoresโ€‹

# Deploy to Alfajores testnet
npx hardhat run scripts/deploy.js --network alfajores

# Verify contracts
npx hardhat verify --network alfajores <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

3. Test Deploymentโ€‹

# Run integration tests
npx hardhat test --network alfajores

# Run specific test file
npx hardhat test test/integration/Deployment.t.js --network alfajores

๐ŸŒ Mainnet Deploymentโ€‹

1. Pre-deployment Checklistโ€‹

  • All tests passing
  • Security audit completed
  • Gas optimization reviewed
  • Contract addresses documented
  • Emergency procedures defined
  • Multi-sig wallet configured

2. Deploy to Mainnetโ€‹

# Deploy to Celo mainnet
npx hardhat run scripts/deploy.js --network celo

# Verify contracts
npx hardhat verify --network celo <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

3. Post-deployment Setupโ€‹

# Set protocol parameters
npx hardhat run scripts/setup.js --network celo

# Transfer admin roles to multi-sig
npx hardhat run scripts/transfer-admin.js --network celo

โœ… Verificationโ€‹

1. Contract Verificationโ€‹

# Verify single contract
npx hardhat verify --network celo <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

# Verify all contracts
npx hardhat run scripts/verify.js --network celo

2. Verification Scriptโ€‹

// scripts/verify.js
const { run } = require("hardhat");

async function main() {
const contracts = [
{
address: "0x...", // GlobalParams
constructorArgs: []
},
{
address: "0x...", // TreasuryFactory
constructorArgs: ["0x..."] // GlobalParams address
},
{
address: "0x...", // CampaignInfoFactory
constructorArgs: ["0x...", "0x..."] // GlobalParams, TreasuryFactory
}
];

for (const contract of contracts) {
try {
await run("verify:verify", {
address: contract.address,
constructorArguments: contract.constructorArgs,
});
console.log(`โœ… Verified ${contract.address}`);
} catch (error) {
console.log(`โŒ Failed to verify ${contract.address}:`, error.message);
}
}
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

โš™๏ธ Configurationโ€‹

1. Protocol Parametersโ€‹

// scripts/setup.js
const { ethers } = require("hardhat");

async function main() {
const globalParams = await ethers.getContractAt("GlobalParams", GLOBAL_PARAMS_ADDRESS);

// Set protocol fee (1% = 100 basis points)
await globalParams.setProtocolFee(100);

// Set minimum campaign duration (1 day)
await globalParams.setMinCampaignDuration(86400);

// Set maximum campaign duration (1 year)
await globalParams.setMaxCampaignDuration(31536000);

console.log("Protocol parameters configured");
}

2. Access Control Setupโ€‹

// scripts/setup-roles.js
const { ethers } = require("hardhat");

async function main() {
const campaignFactory = await ethers.getContractAt("CampaignInfoFactory", CAMPAIGN_FACTORY_ADDRESS);

// Grant campaign creator role
const CAMPAIGN_CREATOR_ROLE = await campaignFactory.CAMPAIGN_CREATOR_ROLE();
await campaignFactory.grantRole(CAMPAIGN_CREATOR_ROLE, CAMPAIGN_CREATOR_ADDRESS);

// Grant pauser role
const PAUSER_ROLE = await campaignFactory.PAUSER_ROLE();
await campaignFactory.grantRole(PAUSER_ROLE, PAUSER_ADDRESS);

console.log("Access control configured");
}

๐Ÿ”ง Troubleshootingโ€‹

Common Issuesโ€‹

1. Insufficient Gasโ€‹

# Increase gas limit
npx hardhat run scripts/deploy.js --network celo --gas-limit 8000000

2. Transaction Revertedโ€‹

# Check transaction details
npx hardhat run scripts/debug.js --network celo

3. Verification Failedโ€‹

# Check constructor arguments
npx hardhat verify --network celo <CONTRACT_ADDRESS> --show-stack-traces

Debug Scriptโ€‹

// scripts/debug.js
const { ethers } = require("hardhat");

async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deployer address:", deployer.address);
console.log("Deployer balance:", ethers.utils.formatEther(await deployer.getBalance()));

// Check network
const network = await ethers.provider.getNetwork();
console.log("Network:", network.name, network.chainId);

// Check gas price
const gasPrice = await ethers.provider.getGasPrice();
console.log("Gas price:", ethers.utils.formatUnits(gasPrice, "gwei"), "gwei");
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

๐Ÿ“Š Deployment Checklistโ€‹

Pre-deploymentโ€‹

  • Environment variables configured
  • Private keys secured
  • Gas estimates calculated
  • Constructor arguments prepared
  • Testnet deployment successful

During Deploymentโ€‹

  • Monitor gas usage
  • Record contract addresses
  • Verify constructor arguments
  • Check transaction confirmations

Post-deploymentโ€‹

  • Verify contracts on block explorer
  • Configure protocol parameters
  • Set up access control
  • Test contract functionality
  • Update documentation
  • Notify community

๐Ÿ”’ Security Considerationsโ€‹

Private Key Managementโ€‹

  • Use hardware wallets for mainnet deployments
  • Never commit private keys to version control
  • Use environment variables for sensitive data
  • Consider multi-sig wallets for admin functions

Contract Securityโ€‹

  • Verify all contracts on block explorer
  • Use proxy patterns for upgradeable contracts
  • Implement proper access control
  • Test emergency procedures

Network Securityโ€‹

  • Use official RPC endpoints
  • Verify network parameters
  • Monitor for suspicious activity
  • Keep deployment scripts secure

Need help? Check our Smart Contract Reference or join our Discord community.