#!/usr/bin/env bash # Deploy official DODO DVM (DVMFactory + deps) to Chain 138 via DODOEX/contractV2 Truffle, # then deploy DVMFactoryAdapter (createDVM -> createDODOVendingMachine) via Forge and update .env. # Requires: smom-dbis-138/.env with PRIVATE_KEY, RPC_URL_138 # # Notes: # - The vendored DODO V2 tree contains both Solidity 0.6.9 and 0.8.x sources. # Truffle uses a single configured compiler, so this script temporarily hides the # unrelated 0.8.x contracts during compile/migrate, then restores them on exit. # - Use --compile-only to verify the official DVM stack compiles cleanly before broadcast. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" DODO_DIR="$PROJECT_ROOT/lib/dodo-contractV2" COMPILE_ONLY=false TRUFFLE_RESET=false HIDDEN_ROOT="$DODO_DIR/.chain138-dvm-solc-excludes" declare -a HIDDEN_SOL_FILES=() usage() { cat <<'EOF' Usage: deploy-official-dvm-chain138.sh [--compile-only] [--reset] Options: --compile-only Compile the official DODO V2 DVM stack in DVM-only mode, then exit. --reset Pass --reset to truffle migrate. EOF } while [[ $# -gt 0 ]]; do case "$1" in --compile-only) COMPILE_ONLY=true shift ;; --reset) TRUFFLE_RESET=true shift ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 1 ;; esac done prepare_dvm_only_sources() { local rel_path rm -rf "$HIDDEN_ROOT" mkdir -p "$HIDDEN_ROOT" while IFS= read -r rel_path; do [[ -z "$rel_path" ]] && continue mkdir -p "$HIDDEN_ROOT/$(dirname "$rel_path")" mv "$DODO_DIR/$rel_path" "$HIDDEN_ROOT/$rel_path" HIDDEN_SOL_FILES+=("$rel_path") done < <( cd "$DODO_DIR" && find contracts -type f -name '*.sol' -print0 | xargs -0 grep -El 'pragma solidity (\^?0\.8|>=0\.8)' | sort ) if [[ ${#HIDDEN_SOL_FILES[@]} -gt 0 ]]; then echo "Temporarily hiding ${#HIDDEN_SOL_FILES[@]} Solidity 0.8.x sources for Chain 138 DVM-only compile..." fi } restore_hidden_sources() { local rel_path if [[ -d "$HIDDEN_ROOT" ]]; then while IFS= read -r rel_path; do [[ -z "$rel_path" ]] && continue mkdir -p "$DODO_DIR/$(dirname "$rel_path")" mv "$HIDDEN_ROOT/$rel_path" "$DODO_DIR/$rel_path" done < <(cd "$HIDDEN_ROOT" && find contracts -type f -name '*.sol' | sort) rm -rf "$HIDDEN_ROOT" fi } trap restore_hidden_sources EXIT cd "$PROJECT_ROOT" # Load .env via dotenv (RPC CR/LF trim). Fallback: raw source. if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then # shellcheck disable=SC1090 source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}" elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then set -a # shellcheck disable=SC1090 source "$PROJECT_ROOT/.env" set +a elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then set -a # shellcheck disable=SC1090 source "$REPO_ROOT/.env" set +a fi if [[ ! -f .env ]]; then echo "ERROR: .env not found" >&2 exit 1 fi set -a source .env set +a if [[ -z "${PRIVATE_KEY:-}" ]]; then echo "ERROR: PRIVATE_KEY not set" >&2 exit 1 fi if [[ -z "${RPC_URL_138:-}" ]]; then echo "ERROR: RPC_URL_138 not set" >&2 exit 1 fi # Ensure DODO submodule has deps and compiles if [[ ! -d "$DODO_DIR/node_modules" ]]; then echo "Installing DODO contractV2 dependencies..." (cd "$DODO_DIR" && npm install) fi # Export for Truffle (privKey without 0x for HDWalletProvider if needed) export privKey="${PRIVATE_KEY#0x}" export RPC_URL_138 export GAS_PRICE_138="${GAS_PRICE_138:-1000000000}" prepare_dvm_only_sources echo "=== Compiling official DODO V2 DVM-only subset for Chain 138 ===" (cd "$DODO_DIR" && rm -rf build/contracts && npx truffle compile) if [[ "$COMPILE_ONLY" == "true" ]]; then echo "DODO V2 DVM-only compile completed successfully." exit 0 fi TRUFFLE_RESET_ARGS=() if [[ "$TRUFFLE_RESET" == "true" ]]; then TRUFFLE_RESET_ARGS+=(--reset) fi # Deploy Migrations (required for Truffle), then DVM stack only echo "=== Running Truffle migration 1 (Migrations) on Chain 138 ===" (cd "$DODO_DIR" && npx truffle migrate -f 1 --to 1 --network chain138 "${TRUFFLE_RESET_ARGS[@]}") || true echo "=== Running Truffle migration 9 (DVM stack) on Chain 138 ===" (cd "$DODO_DIR" && npx truffle migrate -f 9 --to 9 --network chain138 "${TRUFFLE_RESET_ARGS[@]}") # Parse DVMFactory address from Truffle build (network id 138 as string or number) DVM_FACTORY_ADDRESS=$(cd "$DODO_DIR" && node -e " const fs = require('fs'); const path = require('path'); const buildPath = path.join(__dirname, 'build', 'contracts', 'DVMFactory.json'); if (!fs.existsSync(buildPath)) process.exit(1); const j = JSON.parse(fs.readFileSync(buildPath, 'utf8')); const n = j.networks || {}; const addr = n['138']?.address || n[138]?.address; if (!addr) process.exit(1); console.log(addr); " 2>/dev/null) || true if [[ -z "$DVM_FACTORY_ADDRESS" ]]; then echo "Could not read DVMFactory from build. If you already deployed, set DODO_DVM_FACTORY and run:" >&2 echo " DODO_DVM_FACTORY= forge script script/dex/DeployDVMFactoryAdapter.s.sol:DeployDVMFactoryAdapter --rpc-url \$RPC_URL_138 --broadcast --private-key \$PRIVATE_KEY --legacy" >&2 exit 1 fi echo "DVMFactory deployed at: $DVM_FACTORY_ADDRESS" echo "=== Deploying DVMFactoryAdapter (createDVM wrapper) via Forge ===" export DODO_DVM_FACTORY="$DVM_FACTORY_ADDRESS" forge script script/dex/DeployDVMFactoryAdapter.s.sol:DeployDVMFactoryAdapter \ --rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" --legacy # Extract adapter address from broadcast (or script output) ADAPTER_BROADCAST="$PROJECT_ROOT/broadcast/DeployDVMFactoryAdapter.s.sol/138/run-latest.json" ADAPTER_ADDRESS=$( node -e " const fs = require('fs'); const path = process.argv[1]; if (!fs.existsSync(path)) process.exit(1); const j = JSON.parse(fs.readFileSync(path, 'utf8')); const tx = (j.transactions || []).find((entry) => entry.contractName === 'DVMFactoryAdapter' && entry.contractAddress); if (!tx) process.exit(1); console.log(tx.contractAddress); " "$ADAPTER_BROADCAST" 2>/dev/null ) || true if [[ -z "$ADAPTER_ADDRESS" ]]; then echo "Set DODO_VENDING_MACHINE_ADDRESS to the DVMFactoryAdapter address printed above." exit 0 fi echo "DVMFactoryAdapter at: $ADAPTER_ADDRESS" echo "Updating .env DODO_VENDING_MACHINE_ADDRESS=$ADAPTER_ADDRESS" if grep -q '^DODO_VENDING_MACHINE_ADDRESS=' .env; then sed -i "s|^DODO_VENDING_MACHINE_ADDRESS=.*|DODO_VENDING_MACHINE_ADDRESS=$ADAPTER_ADDRESS|" .env else echo "DODO_VENDING_MACHINE_ADDRESS=$ADAPTER_ADDRESS" >> .env fi echo "Done. Run scripts/deployment/run-pmm-and-pools.sh to deploy DODOPMMIntegration with the official DVM."