#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" PROJECT_ROOT="$(cd "$SMOM_ROOT/.." && pwd)" PROJECT_ENV_LOADER="$PROJECT_ROOT/scripts/lib/load-project-env.sh" ENV_FILE="$SMOM_ROOT/.env" ENV_SOURCE="" RUN_FORGE_DRY_RUN=0 RUN_TIMEOUT_SECONDS="${RUN_TIMEOUT_SECONDS:-90}" VERBOSITY="${VERBOSITY:--vv}" while [[ $# -gt 0 ]]; do case "$1" in --run) RUN_FORGE_DRY_RUN=1 shift ;; --timeout-seconds) RUN_TIMEOUT_SECONDS="${2:?missing value for --timeout-seconds}" shift 2 ;; --verbosity) VERBOSITY="${2:?missing value for --verbosity}" shift 2 ;; *) echo "Unknown argument: $1" >&2 echo "Usage: $0 [--run] [--timeout-seconds ] [--verbosity <-v|-vv|-vvv|...>]" >&2 exit 1 ;; esac done CHAIN138_WETH_DEFAULT="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" CHAIN138_USDT_DEFAULT="0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1" CHAIN138_USDC_DEFAULT="0x71D6687F38b93CCad569Fa6352c876eea967201b" DAI_PLACEHOLDER_DEFAULT="0x6B175474E89094C44Da98b954EedeAC495271d0F" if [[ -f "$PROJECT_ENV_LOADER" ]]; then export PROJECT_ROOT # shellcheck disable=SC1090 source "$PROJECT_ENV_LOADER" ENV_SOURCE="$PROJECT_ENV_LOADER" elif [[ -f "$ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a ENV_SOURCE="$ENV_FILE" fi source "$SMOM_ROOT/scripts/lib/forge-scope.sh" RPC_URL_138="${RPC_URL_138:-http://192.168.11.211:8545}" WETH="${WETH:-$CHAIN138_WETH_DEFAULT}" OFFICIAL_USDT_ADDRESS="${OFFICIAL_USDT_ADDRESS:-$CHAIN138_USDT_DEFAULT}" OFFICIAL_USDC_ADDRESS="${OFFICIAL_USDC_ADDRESS:-$CHAIN138_USDC_DEFAULT}" DAI="${DAI:-$DAI_PLACEHOLDER_DEFAULT}" missing=() [[ -n "${PRIVATE_KEY:-}" ]] || missing+=("PRIVATE_KEY") [[ -n "${RPC_URL_138:-}" ]] || missing+=("RPC_URL_138") show_var() { local name="$1" value="$2" note="${3:-}" printf ' %-28s %s' "$name" "$value" [[ -n "$note" ]] && printf ' (%s)' "$note" printf '\n' } probe_bool() { local label="$1" token_in="$2" token_out="$3" provider="$4" local calldata payload response result calldata="$(cast calldata "supportsTokenPair(address,address)" "$token_in" "$token_out" 2>/dev/null || true)" [[ -n "$calldata" ]] || { echo " UNKNOWN: $label (failed to encode calldata)" return 2 } payload=$(printf '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"%s","data":"%s"},"latest"],"id":1}' "$provider" "$calldata") response="$(curl -s -X POST "$RPC_URL_138" -H 'Content-Type: application/json' --data "$payload" 2>/dev/null || true)" result="$(printf '%s' "$response" | sed -n 's/.*"result":"\([^"]*\)".*/\1/p')" case "$result" in "true"|"0x0000000000000000000000000000000000000000000000000000000000000001") echo " OK: $label" return 0 ;; "false"|"0x0000000000000000000000000000000000000000000000000000000000000000") echo " MISSING: $label" return 1 ;; *) echo " UNKNOWN: $label (provider call failed)" return 2 ;; esac } run_forge_dry_run() { local forge_cmd=( forge script script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --skip test --non-interactive --rpc-url "$RPC_URL_138" --private-key "$PRIVATE_KEY" "$VERBOSITY" ) local exit_code=0 set +e ( cd "$SMOM_ROOT" || exit 1 echo "Running targeted build warm-up" forge build contracts/bridge/trustless/EnhancedSwapRouter.sol script/bridge/trustless/DeployEnhancedSwapRouter.s.sol echo "" echo "Running sourced non-broadcast forge script" echo "Working directory: $SMOM_ROOT" echo "Timeout: ${RUN_TIMEOUT_SECONDS}s" echo "Verbosity: $VERBOSITY" echo "" if command -v timeout >/dev/null 2>&1; then timeout "${RUN_TIMEOUT_SECONDS}s" "${forge_cmd[@]}" else "${forge_cmd[@]}" fi ) exit_code=$? set -e if (( exit_code == 124 )); then echo "" echo "Forge dry-run timed out after ${RUN_TIMEOUT_SECONDS}s." echo "Likely causes:" echo " - large project compilation still dominates the preflight" echo " - RPC simulation is slow on the current Chain 138 endpoint" echo " - the script needs more visibility to pinpoint the slow phase" echo "Next diagnostic step:" echo " bash scripts/deployment/dry-run-enhanced-swap-router-chain138.sh --run --timeout-seconds 180 --verbosity -vvv" return 124 fi if (( exit_code != 0 )); then echo "" echo "Forge dry-run failed with exit code ${exit_code}." return "$exit_code" fi } echo "=== EnhancedSwapRouter Chain 138 Dry Run ===" echo "Project root: $SMOM_ROOT" echo "Repository root: $PROJECT_ROOT" echo "Project env loader: $PROJECT_ENV_LOADER" echo "Env file: $ENV_FILE" echo "Env source: $ENV_SOURCE" echo "" if (( ${#missing[@]} > 0 )); then echo "Missing required env:" for item in "${missing[@]}"; do echo " - $item" done echo "" echo "Set them in $ENV_FILE, the repo root env loaded by $PROJECT_ENV_LOADER, or export them in your shell, then rerun." exit 1 fi echo "Required env" show_var "RPC_URL_138" "$RPC_URL_138" "Core RPC only" show_var "PRIVATE_KEY" "" "value loaded; not printed" echo "" echo "Chain 138 token env used by the deploy script" show_var "WETH" "$WETH" "defaults to Chain 138 canonical WETH" show_var "OFFICIAL_USDT_ADDRESS" "$OFFICIAL_USDT_ADDRESS" "defaults to Chain 138 mirror USDT" show_var "OFFICIAL_USDC_ADDRESS" "$OFFICIAL_USDC_ADDRESS" "defaults to Chain 138 mirror USDC" show_var "DAI" "$DAI" "placeholder unless a real Chain 138 DAI exists" echo "" echo "Optional provider env" show_var "DODOEX_ROUTER" "${DODOEX_ROUTER:-}" "unset => Dodoex provider disabled after deploy" show_var "DODO_PMM_PROVIDER_ADDRESS" "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" "set => Chain 138 uses deployed PMM provider backend" show_var "UNISWAP_V3_ROUTER" "${UNISWAP_V3_ROUTER:-}" "unset => Uniswap provider disabled after deploy" show_var "CURVE_3POOL" "${CURVE_3POOL:-}" "unset => Curve provider disabled after deploy" show_var "BALANCER_VAULT" "${BALANCER_VAULT:-}" "unset => Balancer provider disabled after deploy" show_var "ONEINCH_ROUTER" "${ONEINCH_ROUTER:-}" "unset => 1inch provider disabled after deploy" echo "" echo "Live execution readiness" if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]]; then echo " OK: DODO PMM provider is set, so Chain 138 can use the deployed PMM integration/provider backend." elif [[ -z "${DODOEX_ROUTER:-}" ]]; then echo " BLOCKER: neither DODOEX_ROUTER nor DODO_PMM_PROVIDER_ADDRESS is set." echo " BLOCKER: live Chain 138 DODO pool mappings would be registered, but no DODO execution path would remain enabled." else echo " OK: DODOEX_ROUTER is set, so external Dodoex token-to-token execution can stay enabled." fi if [[ -z "${UNISWAP_V3_ROUTER:-}" && -z "${BALANCER_VAULT:-}" && -z "${CURVE_3POOL:-}" && -z "${ONEINCH_ROUTER:-}" ]]; then echo " NOTE: no secondary providers are configured yet; that is acceptable for DODO-only bring-up." fi echo " GAP: swapToStablecoin() still needs real WETH -> stable routes before it is operational on Chain 138." echo "" if [[ -n "${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER:-}}" ]] && command -v cast >/dev/null 2>&1; then DODO_PROVIDER_TO_PROBE="${DODO_PMM_PROVIDER_ADDRESS:-${DODO_PMM_PROVIDER}}" live_pair_missing=0 echo "Live PMM provider route probe" probe_bool "WETH -> OFFICIAL_USDT_ADDRESS" "$WETH" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true probe_bool "WETH -> OFFICIAL_USDC_ADDRESS" "$WETH" "$OFFICIAL_USDC_ADDRESS" "$DODO_PROVIDER_TO_PROBE" || true probe_bool "WETH -> DAI" "$WETH" "$DAI" "$DODO_PROVIDER_TO_PROBE" || true echo "Registered live-pair probe" probe_bool "cUSDT -> cUSDC" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "0xf22258f57794CC8E06237084b353Ab30fFfa640b" "$DODO_PROVIDER_TO_PROBE" || true if ! probe_bool "cUSDT -> OFFICIAL_USDT_ADDRESS" "0x93E66202A11B1772E55407B32B44e5Cd8eda7f22" "$OFFICIAL_USDT_ADDRESS" "$DODO_PROVIDER_TO_PROBE"; then live_pair_missing=1 fi if (( live_pair_missing == 1 )); then echo " BLOCKER: the deployed DODOPMMProvider is missing at least one documented live pair registration." echo " FIX: rerun RegisterDODOPools.s.sol with the corrected 2026-03-26 public pool map." fi echo " NOTE: current bridge-and-swap via swapToStablecoin() needs at least one WETH -> stable route above." echo "" fi echo "Live DODO pairs preloaded by the deploy script" echo " - cUSDT <-> cUSDC" echo " - cUSDT <-> USDT" echo " - cUSDC <-> USDC" echo " - cUSDT <-> cXAUC" echo " - cUSDC <-> cXAUC" echo " - cEURT <-> cXAUC" echo "" echo "Exact dry-run command" if [[ -f "$PROJECT_ENV_LOADER" ]]; then echo "cd \"$PROJECT_ROOT\" && source scripts/lib/load-project-env.sh && cd smom-dbis-138 && bash scripts/forge/scope.sh script bridge/trustless script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --rpc-url \"$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\"" else echo "cd \"$SMOM_ROOT\" && source .env && bash scripts/forge/scope.sh script bridge/trustless script/bridge/trustless/DeployEnhancedSwapRouter.s.sol:DeployEnhancedSwapRouter --rpc-url \"$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\"" fi echo "" echo "Example minimal exports before dry-run" cat <stable routes to be useful on Chain 138." if (( RUN_FORGE_DRY_RUN == 1 )); then echo "" run_forge_dry_run fi