Files
smom-dbis-138/docs/bridge/trustless/DEPLOYMENT_GUIDE.md
2026-03-02 12:14:09 -08:00

11 KiB

Trustless Bridge Deployment Guide

Complete guide for deploying the trustless bridge system with enhanced routing and integration contracts.

Table of Contents

  1. Prerequisites
  2. Environment Setup
  3. Deployment Order
  4. Step-by-Step Deployment
  5. Post-Deployment Configuration
  6. Verification
  7. Troubleshooting

Prerequisites

Required Accounts

  • Deployer Account: Private key with sufficient ETH for gas
  • Admin Account: For role management (can be same as deployer)
  • Liquidity Providers: Accounts to provide initial liquidity

Required Access

  • Ethereum Mainnet RPC endpoint
  • ChainID 138 RPC endpoint
  • Etherscan API key (for contract verification)

Required Funds

  • Deployment Gas: ~5-10 ETH (depending on gas prices)
  • Initial Liquidity: 100+ ETH recommended
  • Reserve Funding: Based on expected bridge volume

Environment Setup

1. Create .env File

# Deployment Account
PRIVATE_KEY=0x...  # Your deployer private key

# RPC Endpoints
ETHEREUM_MAINNET_RPC=https://eth.llamarpc.com
RPC_URL_138=http://chain138.example.com:8545

# Etherscan Verification
ETHERSCAN_API_KEY=your_etherscan_api_key

# Bridge Configuration (optional, defaults provided)
BOND_MULTIPLIER_BPS=11000  # 110%
MIN_BOND=1000000000000000000  # 1 ETH
CHALLENGE_WINDOW_SECONDS=1800  # 30 minutes
LP_FEE_BPS=5  # 0.05%
MIN_LIQUIDITY_RATIO_BPS=11000  # 110%

# Reserve System (if deploying)
RESERVE_SYSTEM=0x...  # ReserveSystem address
XAU_ADDRESS=0x...  # XAU token address (if tokenized)

# Peg Configuration
USD_PEG_THRESHOLD_BPS=50  # 0.5%
ETH_PEG_THRESHOLD_BPS=10  # 0.1%
COMMODITY_PEG_THRESHOLD_BPS=100  # 1%
MIN_RESERVE_RATIO_BPS=11000  # 110%

2. Source Environment

source .env

Deployment Order

The deployment must follow this order due to dependencies:

  1. ReserveSystem (ChainID 138) - If not already deployed
  2. Core Bridge Contracts (ChainID 138 + Ethereum)
  3. EnhancedSwapRouter (Ethereum)
  4. Integration Contracts (Ethereum)
  5. System Initialization (Ethereum)
  6. Backend Services
  7. Frontend Applications

Step-by-Step Deployment

Step 1: Deploy ReserveSystem (ChainID 138)

Skip if already deployed

cd /home/intlc/projects/proxmox/smom-dbis-138

forge script script/reserve/DeployReserveSystem.s.sol:DeployReserveSystem \
  --rpc-url $RPC_URL_138 \
  --broadcast \
  --via-ir

# Save the deployed address
export RESERVE_SYSTEM=0x...

Step 2: Deploy Core Bridge Contracts

2.1 Deploy on ChainID 138

forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
  --rpc-url $RPC_URL_138 \
  --broadcast \
  --via-ir

# Save the deployed address
export LOCKBOX_138=0x...

2.2 Deploy on Ethereum Mainnet

forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --broadcast \
  --via-ir \
  --verify \
  --etherscan-api-key $ETHERSCAN_API_KEY

# Save deployed addresses
export BOND_MANAGER=0x...
export CHALLENGE_MANAGER=0x...
export LIQUIDITY_POOL=0x...
export INBOX_ETH=0x...
export SWAP_ROUTER=0x...  # Basic SwapRouter
export BRIDGE_SWAP_COORDINATOR=0x...

Step 3: Deploy EnhancedSwapRouter

forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --broadcast \
  --via-ir \
  --verify \
  --etherscan-api-key $ETHERSCAN_API_KEY

# Save the deployed address
export ENHANCED_SWAP_ROUTER=0x...

Note: After deployment, configure Balancer pool IDs:

# Example: Configure WETH-USDT pool
cast send $ENHANCED_SWAP_ROUTER \
  "setBalancerPoolId(address,address,bytes32)" \
  0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
  0xdAC17F958D2ee523a2206206994597C13D831ec7 \
  0x... \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

Step 4: Deploy Integration Contracts

# Ensure RESERVE_SYSTEM and BRIDGE_SWAP_COORDINATOR are set
forge script script/bridge/trustless/DeployIntegrationContracts.s.sol:DeployIntegrationContracts \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --broadcast \
  --via-ir \
  --verify \
  --etherscan-api-key $ETHERSCAN_API_KEY

# Save deployed addresses
export STABLECOIN_PEG_MANAGER=0x...
export COMMODITY_PEG_MANAGER=0x...
export ISO_CURRENCY_MANAGER=0x...
export BRIDGE_RESERVE_COORDINATOR=0x...

Step 5: Initialize System

forge script script/bridge/trustless/InitializeBridgeSystem.s.sol:InitializeBridgeSystem \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --broadcast \
  --via-ir

Step 6: Provide Initial Liquidity

# Provide liquidity to LiquidityPoolETH
cast send $LIQUIDITY_POOL \
  "provideLiquidity(uint8)" \
  0 \
  --value 100ether \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

Step 7: Fund ReserveSystem

# Deposit reserves (example with USDT)
cast send $USDT \
  "approve(address,uint256)" \
  $RESERVE_SYSTEM \
  100000000000000000000000 \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

cast send $RESERVE_SYSTEM \
  "depositReserve(address,uint256)" \
  $USDT \
  100000000000000000000000 \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

Post-Deployment Configuration

1. Configure Access Control Roles

# Grant COORDINATOR_ROLE to BridgeSwapCoordinator
cast send $ENHANCED_SWAP_ROUTER \
  "grantRole(bytes32,address)" \
  $(cast keccak "COORDINATOR_ROLE") \
  $BRIDGE_SWAP_COORDINATOR \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

2. Configure Routing Logic

The EnhancedSwapRouter is pre-configured with default routing, but you can customize:

# Example: Update small swap routing
cast send $ENHANCED_SWAP_ROUTER \
  "setRoutingConfig(uint256,uint8[])" \
  0 \
  "[0,2]" \
  --rpc-url $ETHEREUM_MAINNET_RPC \
  --private-key $PRIVATE_KEY

3. Update BridgeSwapCoordinator

If using EnhancedSwapRouter, update the coordinator to use it:

# This may require redeployment or upgrade
# Check BridgeSwapCoordinator implementation for update method

Verification

1. Verify Contracts on Etherscan

All contracts should be automatically verified if using --verify flag. Manual verification:

forge verify-contract <CONTRACT_ADDRESS> \
  <CONTRACT_NAME> \
  --chain-id 1 \
  --etherscan-api-key $ETHERSCAN_API_KEY \
  --constructor-args $(cast abi-encode "constructor(...)" <args>)

2. Test End-to-End Flow

# 1. Deposit on ChainID 138
cast send $LOCKBOX_138 \
  "depositNative(address,bytes32)" \
  <recipient> \
  $(cast keccak "test") \
  --value 1ether \
  --rpc-url $RPC_URL_138 \
  --private-key $PRIVATE_KEY

# 2. Submit claim on Ethereum
# (Use relayer service or manual call)

# 3. Wait for challenge window

# 4. Finalize claim

# 5. Verify swap executed

3. Check System Status

# Check liquidity pool balance
cast call $LIQUIDITY_POOL "totalLiquidity()" --rpc-url $ETHEREUM_MAINNET_RPC

# Check reserve status
cast call $BRIDGE_RESERVE_COORDINATOR \
  "getReserveStatus(address,uint256)" \
  $USDT \
  1000000000000000000 \
  --rpc-url $ETHEREUM_MAINNET_RPC

# Check peg status
cast call $STABLECOIN_PEG_MANAGER \
  "checkUSDpeg(address)" \
  $USDT \
  --rpc-url $ETHEREUM_MAINNET_RPC

Troubleshooting

Common Issues

  1. Insufficient Gas: Increase gas limit or gas price
  2. Contract Verification Fails: Check constructor arguments
  3. Role Grant Fails: Ensure deployer has admin role
  4. Liquidity Pool Empty: Provide initial liquidity
  5. Reserve Insufficient: Fund ReserveSystem

Live-test cast errors (lock / claim / finalize)

  • -32602: Invalid params — Wrong RPC for the tx (e.g. mainnet RPC for a 138 lock), or missing/corrupt env (PRIVATE_KEY, RPC_URL_138, ETHEREUM_MAINNET_RPC). Ensure lock uses --rpc-url $RPC_URL_138 and claim/finalize use --rpc-url $ETHEREUM_MAINNET_RPC. Check .env has no typos (e.g. PRIVATE_KEYIT_ID).
  • invalid string length (e.g. for 1000000000000000) — You passed the amount (AMOUNT_WEI) where an address or depositId is expected. DEPOSIT_ID must be the depositId from the Lockbox Deposit event (a large uint256 from the event), not the amount. Get it with:
    cast logs <LOCK_TX_HASH> "Deposit(uint256,address,uint256,address,bytes32,address,uint256)" --rpc-url $RPC_URL_138
    
    Use the first decoded argument as DEPOSIT_ID.
  • encode length mismatch: expected 1 types, got 0DEPOSIT_ID is empty or unset for claim or finalize. Set it from the lock tx event as above.

Quick DEPOSIT_ID from lock tx:
export DEPOSIT_ID=$(./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH>)
Then run AMOUNT_WEI=1000000000000000 ./scripts/deployment/run-e2e-trustless-live-test.sh claim.

Emergency Procedures

  1. Pause System: Use pause functions if available
  2. Withdraw Liquidity: Emergency withdrawal procedures
  3. Update Configuration: Use admin functions to update parameters

Next Steps

After deployment:

  1. Deploy backend services
  2. Deploy frontend applications
  3. Set up monitoring
  4. Configure alerting
  5. Train operators
  6. Begin operations

See OPERATIONS_GUIDE.md for operational procedures.


Deploy, Configure, and Live Test (single flow)

Deploy: Run trustless phase: ./scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh trustless (from smom-dbis-138). Set LOCKBOX_138, BOND_MANAGER, LIQUIDITY_POOL, INBOX_ETH, CHALLENGE_MANAGER in .env.

Configure: (1) Verify Inbox is authorized on LP: cast call $LIQUIDITY_POOL "authorizedRelease(address)(bool)" $INBOX_ETH --rpc-url $ETHEREUM_MAINNET_RPC. (2) Initialize if using router: forge script script/bridge/trustless/InitializeBridgeSystem.s.sol:InitializeBridgeSystem --rpc-url $ETHEREUM_MAINNET_RPC --broadcast --via-ir. (3) Fund LP: ./scripts/deployment/fund-mainnet-lp.sh --eth 2 --weth 1.

Verify: ./scripts/deployment/verify-trustless-deployments.sh.

Live test with actual tokens (138 to mainnet): (1) Lock: cast send $LOCKBOX_138 "depositNative(address,bytes32)" RECIPIENT NONCE --value 0.01ether --rpc-url $RPC_URL_138 --private-key $PRIVATE_KEY --legacy. (2) Get depositId from Deposit event. (3) Submit claim: cast send $INBOX_ETH "submitClaim(uint256,address,uint256,address,bytes)" DEPOSIT_ID 0x0 AMOUNT_WEI RECIPIENT 0x --value BOND --rpc-url $ETHEREUM_MAINNET_RPC --private-key $PRIVATE_KEY (BOND = getRequiredBond(amount)). (4) Wait challenge window. (5) Finalize: cast send $CHALLENGE_MANAGER "finalizeClaim(uint256)" DEPOSIT_ID .... (6) Release bond: cast send $BOND_MANAGER "releaseBond(uint256)" DEPOSIT_ID .... See runbook: scripts/deployment/live-test-trustless-bridge.sh (prints commands and optional checks).