- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
513 lines
12 KiB
Markdown
513 lines
12 KiB
Markdown
# Multichain Deployment Runbook
|
|
|
|
**Last Updated**: 2025-01-27
|
|
**Purpose**: Comprehensive guide for deploying smart contracts to multiple chains using Foundry
|
|
|
|
## Overview
|
|
|
|
This runbook covers deployment of the complete contract suite to:
|
|
- **Ethereum Mainnet** (chainId 1): Only CCIPLogger (other contracts already deployed)
|
|
- **Cronos** (chainId 25): All contracts
|
|
- **BSC** (chainId 56): All contracts
|
|
- **Polygon PoS** (chainId 137): All contracts
|
|
- **Gnosis Chain** (chainId 100): All contracts
|
|
|
|
## Prerequisites
|
|
|
|
### 1. Environment Setup
|
|
|
|
1. **Copy environment template**:
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
2. **Fill in all required variables** in `.env`:
|
|
- `PRIVATE_KEY`: Your deployer private key
|
|
- RPC URLs for all chains
|
|
- Explorer API keys for verification
|
|
- CCIP router addresses per chain
|
|
- LINK token addresses per chain
|
|
|
|
3. **Verify Foundry installation**:
|
|
```bash
|
|
forge --version
|
|
# Should be >= 0.2.0
|
|
```
|
|
|
|
4. **Install dependencies** (if using Hardhat for CCIPLogger):
|
|
```bash
|
|
npm install
|
|
npm install @openzeppelin/contracts@5.0.2
|
|
npm install @chainlink/contracts-ccip
|
|
```
|
|
|
|
### 2. Verify Configuration
|
|
|
|
Check that all environment variables are set:
|
|
```bash
|
|
# Check mainnet config
|
|
echo $ETH_MAINNET_RPC_URL
|
|
echo $CCIP_ETH_ROUTER
|
|
echo $CCIP_ETH_LINK_TOKEN
|
|
|
|
# Check other chains
|
|
echo $CRONOS_RPC_URL
|
|
echo $BSC_RPC_URL
|
|
echo $POLYGON_RPC_URL
|
|
echo $GNOSIS_RPC_URL
|
|
```
|
|
|
|
### 3. Get Real-Time Gas Prices
|
|
|
|
Before checking balances, fetch real-time gas prices:
|
|
|
|
```bash
|
|
# Fetch real-time gas prices for all chains
|
|
./scripts/deployment/get-multichain-gas-prices.sh
|
|
|
|
# Update documentation with real-time prices
|
|
./scripts/deployment/update-gas-estimates.sh
|
|
```
|
|
|
|
This will:
|
|
- Fetch current gas prices from configured APIs
|
|
- Calculate deployment costs for all chains
|
|
- Update documentation with real-time estimates
|
|
- Show you exactly how much you need
|
|
|
|
### 4. Verify Wallet Balance
|
|
|
|
Ensure your deployer wallet has sufficient native tokens for gas:
|
|
```bash
|
|
# Check balances (adjust RPC URLs as needed)
|
|
cast balance $DEPLOYER_ADDRESS --rpc-url $ETH_MAINNET_RPC_URL
|
|
cast balance $DEPLOYER_ADDRESS --rpc-url $CRONOS_RPC_URL
|
|
cast balance $DEPLOYER_ADDRESS --rpc-url $BSC_RPC_URL
|
|
cast balance $DEPLOYER_ADDRESS --rpc-url $POLYGON_RPC_URL
|
|
cast balance $DEPLOYER_ADDRESS --rpc-url $GNOSIS_RPC_URL
|
|
```
|
|
|
|
**Recommended minimum balances** (see [Gas and Token Requirements](./GAS_AND_TOKEN_REQUIREMENTS.md) for details):
|
|
- Ethereum Mainnet: **0.20 ETH** (for CCIPLogger deployment)
|
|
- Cronos: **15 CRO** (for all 5 contracts)
|
|
- BSC: **0.06 BNB** (for all 5 contracts)
|
|
- Polygon: **1.0 MATIC** (for all 5 contracts)
|
|
- Gnosis: **0.05 xDAI** (for all 5 contracts)
|
|
|
|
**Total Estimated Cost**: ~$520 USD (with buffers)
|
|
|
|
---
|
|
|
|
## Deployment Commands
|
|
|
|
### Ethereum Mainnet - CCIPLogger Only
|
|
|
|
**Status**: WETH9, WETH10, CCIPWETH9Bridge, CCIPWETH10Bridge are already deployed.
|
|
|
|
**Deploy CCIPLogger**:
|
|
|
|
```bash
|
|
# Option 1: Using Foundry (if CCIPLogger is compatible)
|
|
forge script script/DeployCCIPLoggerOnly.s.sol:DeployCCIPLoggerOnly \
|
|
--rpc-url mainnet \
|
|
--chain-id 1 \
|
|
--private-key $PRIVATE_KEY \
|
|
--broadcast \
|
|
--verify \
|
|
-vvvv
|
|
|
|
# Option 2: Using Hardhat (recommended for CCIPLogger)
|
|
npm install @openzeppelin/contracts@5.0.2
|
|
npx hardhat run scripts/ccip-deployment/deploy-ccip-logger.js --network mainnet
|
|
```
|
|
|
|
**Verify CCIPLogger**:
|
|
```bash
|
|
# If deployed via Foundry, verification is automatic with --verify flag
|
|
# If deployed via Hardhat:
|
|
npx hardhat verify --network mainnet \
|
|
<CCIPLOGGER_ADDRESS> \
|
|
"$CCIP_ETH_ROUTER" \
|
|
"$AUTHORIZED_SIGNER" \
|
|
"$CHAIN138_SELECTOR"
|
|
```
|
|
|
|
---
|
|
|
|
### Cronos (Chain ID 25)
|
|
|
|
**Deploy all contracts**:
|
|
|
|
```bash
|
|
forge script script/DeployAll.s.sol:DeployAll \
|
|
--rpc-url cronos \
|
|
--chain-id 25 \
|
|
--private-key $PRIVATE_KEY \
|
|
--broadcast \
|
|
--verify \
|
|
-vvvv
|
|
```
|
|
|
|
**Verify contracts** (if automatic verification fails):
|
|
```bash
|
|
# WETH9
|
|
forge verify-contract \
|
|
--chain-id 25 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<WETH9_ADDRESS> \
|
|
contracts/tokens/WETH.sol:WETH \
|
|
$CRONOSCAN_API_KEY
|
|
|
|
# WETH10
|
|
forge verify-contract \
|
|
--chain-id 25 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<WETH10_ADDRESS> \
|
|
contracts/tokens/WETH10.sol:WETH10 \
|
|
$CRONOSCAN_API_KEY
|
|
|
|
# CCIPWETH9Bridge
|
|
forge verify-contract \
|
|
--chain-id 25 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<BRIDGE_ADDRESS> \
|
|
contracts/ccip/CCIPWETH9Bridge.sol:CCIPWETH9Bridge \
|
|
$CRONOSCAN_API_KEY \
|
|
--constructor-args $(cast abi-encode "constructor(address,address,address)" $CCIP_CRONOS_ROUTER $WETH9_ADDRESS $CCIP_CRONOS_LINK_TOKEN)
|
|
|
|
# CCIPWETH10Bridge
|
|
forge verify-contract \
|
|
--chain-id 25 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<BRIDGE_ADDRESS> \
|
|
contracts/ccip/CCIPWETH10Bridge.sol:CCIPWETH10Bridge \
|
|
$CRONOSCAN_API_KEY \
|
|
--constructor-args $(cast abi-encode "constructor(address,address,address)" $CCIP_CRONOS_ROUTER $WETH10_ADDRESS $CCIP_CRONOS_LINK_TOKEN)
|
|
```
|
|
|
|
---
|
|
|
|
### BSC (Chain ID 56)
|
|
|
|
**Deploy all contracts**:
|
|
|
|
```bash
|
|
forge script script/DeployAll.s.sol:DeployAll \
|
|
--rpc-url bsc \
|
|
--chain-id 56 \
|
|
--private-key $PRIVATE_KEY \
|
|
--broadcast \
|
|
--verify \
|
|
-vvvv
|
|
```
|
|
|
|
**Verify contracts** (if automatic verification fails):
|
|
```bash
|
|
# Similar to Cronos, but use BSCSCAN_API_KEY
|
|
forge verify-contract \
|
|
--chain-id 56 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<CONTRACT_ADDRESS> \
|
|
<CONTRACT_PATH>:<CONTRACT_NAME> \
|
|
$BSCSCAN_API_KEY \
|
|
--constructor-args <ENCODED_ARGS>
|
|
```
|
|
|
|
---
|
|
|
|
### Polygon PoS (Chain ID 137)
|
|
|
|
**Deploy all contracts**:
|
|
|
|
```bash
|
|
forge script script/DeployAll.s.sol:DeployAll \
|
|
--rpc-url polygon \
|
|
--chain-id 137 \
|
|
--private-key $PRIVATE_KEY \
|
|
--broadcast \
|
|
--verify \
|
|
-vvvv
|
|
```
|
|
|
|
**Verify contracts** (if automatic verification fails):
|
|
```bash
|
|
# Use POLYGONSCAN_API_KEY
|
|
forge verify-contract \
|
|
--chain-id 137 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<CONTRACT_ADDRESS> \
|
|
<CONTRACT_PATH>:<CONTRACT_NAME> \
|
|
$POLYGONSCAN_API_KEY \
|
|
--constructor-args <ENCODED_ARGS>
|
|
```
|
|
|
|
**Note**: Polygon CCIP Router is available at `0x3C3D92629A02a8D95D5CB9650fe49C3544f69B43`
|
|
|
|
---
|
|
|
|
### Gnosis Chain (Chain ID 100)
|
|
|
|
**Deploy all contracts**:
|
|
|
|
```bash
|
|
forge script script/DeployAll.s.sol:DeployAll \
|
|
--rpc-url gnosis \
|
|
--chain-id 100 \
|
|
--private-key $PRIVATE_KEY \
|
|
--broadcast \
|
|
--verify \
|
|
-vvvv
|
|
```
|
|
|
|
**Verify contracts** (if automatic verification fails):
|
|
```bash
|
|
# Use GNOSISSCAN_API_KEY
|
|
forge verify-contract \
|
|
--chain-id 100 \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<CONTRACT_ADDRESS> \
|
|
<CONTRACT_PATH>:<CONTRACT_NAME> \
|
|
$GNOSISSCAN_API_KEY \
|
|
--constructor-args <ENCODED_ARGS>
|
|
```
|
|
|
|
---
|
|
|
|
## Post-Deployment Steps
|
|
|
|
### 1. Save Deployment Addresses
|
|
|
|
After each deployment, save the addresses to your `.env` file:
|
|
|
|
```bash
|
|
# Example for Cronos
|
|
echo "WETH9_CRONOS=<deployed_address>" >> .env
|
|
echo "WETH10_CRONOS=<deployed_address>" >> .env
|
|
echo "CCIPWETH9BRIDGE_CRONOS=<deployed_address>" >> .env
|
|
echo "CCIPWETH10BRIDGE_CRONOS=<deployed_address>" >> .env
|
|
echo "CCIPLOGGER_CRONOS=<deployed_address>" >> .env
|
|
```
|
|
|
|
### 2. Verify All Contracts
|
|
|
|
Verify all contracts on their respective explorers:
|
|
- [Etherscan](https://etherscan.io) (Mainnet)
|
|
- [Cronoscan](https://cronoscan.com) (Cronos)
|
|
- [BscScan](https://bscscan.com) (BSC)
|
|
- [Polygonscan](https://polygonscan.com) (Polygon)
|
|
- [Gnosisscan](https://gnosisscan.io) (Gnosis)
|
|
|
|
### 3. Configure Bridge Destinations
|
|
|
|
For each bridge contract, configure destination chains:
|
|
|
|
```bash
|
|
# Example: Configure WETH9 Bridge on Cronos to send to Mainnet
|
|
cast send <CCIPWETH9BRIDGE_CRONOS> \
|
|
"addDestination(uint64,address)" \
|
|
$ETH_MAINNET_SELECTOR \
|
|
$CCIPWETH9BRIDGE_MAINNET \
|
|
--rpc-url cronos \
|
|
--private-key $PRIVATE_KEY
|
|
```
|
|
|
|
### 4. Test Cross-Chain Transfers
|
|
|
|
Test a small cross-chain transfer to verify everything works:
|
|
|
|
```bash
|
|
# Example: Send WETH9 from Cronos to Mainnet
|
|
cast send <WETH9_CRONOS> \
|
|
"approve(address,uint256)" \
|
|
<CCIPWETH9BRIDGE_CRONOS> \
|
|
1000000000000000000 \
|
|
--rpc-url cronos \
|
|
--private-key $PRIVATE_KEY
|
|
|
|
cast send <CCIPWETH9BRIDGE_CRONOS> \
|
|
"sendCrossChain(uint64,address,uint256)" \
|
|
$ETH_MAINNET_SELECTOR \
|
|
<RECIPIENT_ADDRESS> \
|
|
1000000000000000000 \
|
|
--rpc-url cronos \
|
|
--private-key $PRIVATE_KEY
|
|
```
|
|
|
|
---
|
|
|
|
## Gas and Token Requirements
|
|
|
|
**📊 For detailed gas cost breakdowns and token requirements, see**: [Gas and Token Requirements](./GAS_AND_TOKEN_REQUIREMENTS.md)
|
|
|
|
### Quick Reference: Minimum Balances
|
|
|
|
| Chain | Token | Minimum | Recommended |
|
|
|-------|-------|---------|-------------|
|
|
| **Mainnet** | ETH | 0.15 ETH | **0.20 ETH** |
|
|
| **Cronos** | CRO | 8.76 CRO | **15 CRO** |
|
|
| **BSC** | BNB | 0.044 BNB | **0.06 BNB** |
|
|
| **Polygon** | MATIC | 0.44 MATIC | **1.0 MATIC** |
|
|
| **Gnosis** | xDAI | 0.0175 xDAI | **0.05 xDAI** |
|
|
|
|
### Total Gas Requirements
|
|
|
|
- **Ethereum Mainnet**: 3,000,000 gas (CCIPLogger only)
|
|
- **Other Chains**: 8,760,000 gas (all 5 contracts: WETH9, WETH10, 2 Bridges, CCIPLogger)
|
|
|
|
---
|
|
|
|
## Gas Price Strategies
|
|
|
|
### Ethereum Mainnet
|
|
- **Strategy**: Use EIP-1559 (automatic)
|
|
- **Max Fee**: Check current gas prices
|
|
- **Priority Fee**: 2-5 gwei
|
|
|
|
### Cronos
|
|
- **Strategy**: Fixed gas price
|
|
- **Gas Price**: ~500 gwei (very low)
|
|
- **Note**: Cronos uses CRO for gas
|
|
|
|
### BSC
|
|
- **Strategy**: Fixed gas price
|
|
- **Gas Price**: ~3-5 gwei
|
|
- **Note**: BSC uses BNB for gas
|
|
|
|
### Polygon
|
|
- **Strategy**: Fixed gas price
|
|
- **Gas Price**: ~30-100 gwei
|
|
- **Note**: Polygon uses MATIC for gas
|
|
|
|
### Gnosis
|
|
- **Strategy**: Fixed gas price
|
|
- **Gas Price**: ~1 gwei
|
|
- **Note**: Gnosis uses xDAI for gas
|
|
|
|
---
|
|
|
|
## Network-Specific Caveats
|
|
|
|
### Cronos
|
|
- **Finality**: ~6 seconds
|
|
- **CCIP Support**: Verify CCIP router availability
|
|
- **RPC**: May have rate limits
|
|
|
|
### BSC
|
|
- **Finality**: ~3 seconds
|
|
- **CCIP Support**: Verify CCIP router availability
|
|
- **Gas**: Very cheap, but watch for congestion
|
|
|
|
### Polygon
|
|
- **Finality**: ~2 seconds
|
|
- **CCIP Support**: ✅ Available
|
|
- **Router**: `0x3C3D92629A02a8D95D5CB9650fe49C3544f69B43`
|
|
- **LINK Token**: `0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39`
|
|
|
|
### Gnosis
|
|
- **Finality**: ~5 seconds
|
|
- **CCIP Support**: Verify CCIP router availability
|
|
- **Gas**: Very cheap
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### RPC Connection Issues
|
|
|
|
```bash
|
|
# Test RPC connectivity
|
|
cast block-number --rpc-url $ETH_MAINNET_RPC_URL
|
|
cast block-number --rpc-url $CRONOS_RPC_URL
|
|
cast block-number --rpc-url $BSC_RPC_URL
|
|
cast block-number --rpc-url $POLYGON_RPC_URL
|
|
cast block-number --rpc-url $GNOSIS_RPC_URL
|
|
```
|
|
|
|
### Contract Verification Fails
|
|
|
|
1. **Check compiler settings match**:
|
|
```bash
|
|
# Verify optimizer settings
|
|
grep optimizer foundry.toml
|
|
grep optimizer_runs foundry.toml
|
|
```
|
|
|
|
2. **Verify constructor arguments**:
|
|
```bash
|
|
# Encode constructor args manually
|
|
cast abi-encode "constructor(address,address,address)" \
|
|
$ROUTER $WETH $LINK
|
|
```
|
|
|
|
3. **Use explicit verification**:
|
|
```bash
|
|
forge verify-contract \
|
|
--chain-id <CHAIN_ID> \
|
|
--num-of-optimizations 200 \
|
|
--watch \
|
|
<ADDRESS> \
|
|
<CONTRACT_PATH>:<CONTRACT_NAME> \
|
|
<API_KEY> \
|
|
--constructor-args <ENCODED_ARGS>
|
|
```
|
|
|
|
### CCIPLogger Deployment Issues
|
|
|
|
If CCIPLogger fails to deploy via Foundry:
|
|
1. Use Hardhat script instead: `npm run deploy:logger:mainnet`
|
|
2. Ensure OpenZeppelin v5.0.2+ is installed
|
|
3. Check that CCIP contracts are available
|
|
|
|
---
|
|
|
|
## Deployment Checklist
|
|
|
|
### Pre-Deployment
|
|
- [ ] Environment variables configured
|
|
- [ ] Wallet balances sufficient
|
|
- [ ] RPC endpoints tested
|
|
- [ ] Contracts compile successfully
|
|
- [ ] Tests pass
|
|
|
|
### Deployment
|
|
- [ ] Ethereum Mainnet: CCIPLogger deployed
|
|
- [ ] Cronos: All contracts deployed
|
|
- [ ] BSC: All contracts deployed
|
|
- [ ] Polygon: All contracts deployed
|
|
- [ ] Gnosis: All contracts deployed
|
|
|
|
### Post-Deployment
|
|
- [ ] All contracts verified on explorers
|
|
- [ ] Deployment addresses saved to `.env`
|
|
- [ ] Bridge destinations configured
|
|
- [ ] Cross-chain transfers tested
|
|
- [ ] Monitoring set up
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
For issues or questions:
|
|
- Check deployment logs
|
|
- Review contract documentation
|
|
- Verify configuration
|
|
- Check troubleshooting section above
|
|
|
|
---
|
|
|
|
## References
|
|
|
|
- [Foundry Documentation](https://book.getfoundry.sh/)
|
|
- [Chainlink CCIP Documentation](https://docs.chain.link/ccip)
|
|
- [Etherscan API](https://docs.etherscan.io/)
|
|
- [Multichain Deployment Script](../script/DeployAll.s.sol)
|
|
- [CCIPLogger Deployment Script](../script/DeployCCIPLoggerOnly.s.sol)
|
|
|