#!/usr/bin/env bash # Run PMM full parity: Phase 1 (Chain 138) and Phase 2 (L2s) in full parallel where possible. # Usage: # ./scripts/deployment/run-pmm-full-parity-all-phases.sh # run all phases # RUN_PHASE1=0 ./scripts/deployment/run-pmm-full-parity-all-phases.sh # skip Phase 1 # RUN_PHASE2=0 ./scripts/deployment/run-pmm-full-parity-all-phases.sh # skip Phase 2 # DRY_RUN=1 ./scripts/deployment/run-pmm-full-parity-all-phases.sh # print only # ADD_LIQUIDITY_BASE_AMOUNT=1000000e6 ADD_LIQUIDITY_QUOTE_AMOUNT=1000000e6 ... # liquidity amounts (6 decimals) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" cd "$REPO_ROOT" source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env RUN_PHASE1="${RUN_PHASE1:-1}" RUN_PHASE2="${RUN_PHASE2:-1}" DRY_RUN="${DRY_RUN:-}" RPC_138="${RPC_URL_138:-${RPC_URL:-http://192.168.11.211:8545}}" GAS_PRICE="${GAS_PRICE_138:-${GAS_PRICE:-1000000000}}" INTEGRATION="${DODO_PMM_INTEGRATION_ADDRESS:-${DODO_PMM_INTEGRATION:-0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895}}" POOL_CUSDTCUSDC="${POOL_CUSDTCUSDC:-0x9e89bAe009adf128782E19e8341996c596ac40dC}" POOL_CUSDTUSDT="${POOL_CUSDTUSDT:-0x866Cb44b59303d8dc5f4F9E3E7A8e8b0bf238d66}" POOL_CUSDCUSDC="${POOL_CUSDCUSDC:-0xc39B7D0F40838cbFb54649d327f49a6DAC964062}" export DODO_LP_FEE_BPS="${DODO_LP_FEE_BPS:-10}" export DODO_INITIAL_PRICE_1E18="${DODO_INITIAL_PRICE_1E18:-1000000000000000000}" export DODO_K_FACTOR_1E18="${DODO_K_FACTOR_1E18:-0}" export DODO_ENABLE_TWAP="${DODO_ENABLE_TWAP:-false}" export RPC_URL_138="$RPC_138" export DODO_PMM_INTEGRATION_ADDRESS="$INTEGRATION" export POOL_CUSDTCUSDC POOL_CUSDTUSDT POOL_CUSDCUSDC log() { echo "[$(date +%H:%M:%S)] $*"; } run_or_dry() { if [[ -n "$DRY_RUN" ]]; then log "[DRY RUN] $*" return 0 fi "$@" } # ---------- Phase 1: Chain 138 ---------- phase1() { log "=== Phase 1: Chain 138 (verify pools, register, add liquidity) ===" if [[ -z "${PRIVATE_KEY:-}" ]]; then log "Skip Phase 1: PRIVATE_KEY not set" return 0 fi # 1a) Create all 3 pools sequentially (single deployer nonce lane; canonical stable params are i=1e18, k=0) log "Creating PMM pools (sequential)..." if [[ -z "$DRY_RUN" ]]; then forge script script/dex/CreateCUSDTCUSDCPool.s.sol:CreateCUSDTCUSDCPool \ --rpc-url "$RPC_138" --broadcast --private-key "$PRIVATE_KEY" --with-gas-price "$GAS_PRICE" -vv 2>&1 | tee /tmp/pmm-create-cusdt-cusdc.log || true forge script script/dex/CreateCUSDTUSDTPool.s.sol:CreateCUSDTUSDTPool \ --rpc-url "$RPC_138" --broadcast --private-key "$PRIVATE_KEY" --with-gas-price "$GAS_PRICE" -vv 2>&1 | tee /tmp/pmm-create-cusdt-usdt.log || true forge script script/dex/CreateCUSDCUSDCPool.s.sol:CreateCUSDCUSDCPool \ --rpc-url "$RPC_138" --broadcast --private-key "$PRIVATE_KEY" --with-gas-price "$GAS_PRICE" -vv 2>&1 | tee /tmp/pmm-create-cusdc-usdc.log || true else log "[DRY RUN] forge script CreateCUSDTCUSDCPool ..." log "[DRY RUN] forge script CreateCUSDTUSDTPool ..." log "[DRY RUN] forge script CreateCUSDCUSDCPool ..." fi # 1b) Register pools with DODOPMMProvider (requires DODO_PMM_PROVIDER_ADDRESS) if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-}" ]]; then log "Registering pools with DODOPMMProvider..." run_or_dry forge script script/liquidity/RegisterDODOPools.s.sol:RegisterDODOPools \ --rpc-url "$RPC_138" --broadcast --private-key "$PRIVATE_KEY" --with-gas-price "$GAS_PRICE" -vv else log "Skip register: DODO_PMM_PROVIDER_ADDRESS not set" fi # 1c) Add liquidity (optional: set ADD_LIQUIDITY_BASE_AMOUNT and ADD_LIQUIDITY_QUOTE_AMOUNT) if [[ -n "${ADD_LIQUIDITY_BASE_AMOUNT:-}" && -n "${ADD_LIQUIDITY_QUOTE_AMOUNT:-}" ]]; then log "Adding liquidity to PMM pools..." run_or_dry forge script script/dex/AddLiquidityPMMPoolsChain138.s.sol:AddLiquidityPMMPoolsChain138 \ --rpc-url "$RPC_138" --broadcast --private-key "$PRIVATE_KEY" --with-gas-price "$GAS_PRICE" -vv else log "Skip add liquidity: set ADD_LIQUIDITY_BASE_AMOUNT and ADD_LIQUIDITY_QUOTE_AMOUNT (e.g. 1000000e6)" fi log "Phase 1 done." } # ---------- Phase 2: One chain (deploy cUSDT/cUSDC + DODOPMMIntegration) ---------- phase2_chain() { local name="$1" chain_id="$2" rpc_var="$3" local rpc="${!rpc_var:-}" [[ -z "$rpc" ]] && return 0 log "[$name] Deploy cUSDT/cUSDC + DODOPMMIntegration (chain $chain_id)" if [[ -n "$DRY_RUN" ]]; then log "[DRY RUN] $name: deploy tokens + integration" return 0 fi local name_lower name_lower=$(echo "$name" | tr '[:upper:]' '[:lower:]') ( export DEPLOY_CUSDT_CUSDC_FILTER="$name" export DEPLOY_PMM_L2S_FILTER="$name_lower" cd "$REPO_ROOT" source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env ./scripts/deployment/deploy-cusdt-cusdc-all-chains.sh 2>&1 | tee "/tmp/pmm-phase2-$name-tokens.log" || true ./scripts/deployment/deploy-pmm-all-l2s.sh --chain "$name_lower" 2>&1 | tee "/tmp/pmm-phase2-$name-pmm.log" || true ) log "[$name] done." } # ---------- Phase 2: All L2s in parallel ---------- phase2() { log "=== Phase 2: L2s (deploy cUSDT/cUSDC + DODOPMMIntegration per chain, parallel) ===" CHAINS=( "BSC:56:BSC_RPC_URL" "POLYGON:137:POLYGON_MAINNET_RPC" "BASE:8453:BASE_MAINNET_RPC" "OPTIMISM:10:OPTIMISM_MAINNET_RPC" "ARBITRUM:42161:ARBITRUM_MAINNET_RPC" "AVALANCHE:43114:AVALANCHE_RPC_URL" "CRONOS:25:CRONOS_RPC_URL" "GNOSIS:100:GNOSIS_MAINNET_RPC" ) PIDS=() for entry in "${CHAINS[@]}"; do IFS=: read -r name chain_id rpc_var <<< "$entry" phase2_chain "$name" "$chain_id" "$rpc_var" & PIDS+=($!) done for p in "${PIDS[@]}"; do wait "$p" 2>/dev/null || true; done log "Phase 2 done." } # ---------- Main ---------- log "PMM full parity — Phase1=$RUN_PHASE1 Phase2=$RUN_PHASE2 DRY_RUN=$DRY_RUN" [[ "$RUN_PHASE1" = "1" ]] && phase1 [[ "$RUN_PHASE2" = "1" ]] && phase2 log "All requested phases finished."