chore: sync submodule state (parent ref update)

Made-with: Cursor
This commit is contained in:
defiQUG
2026-03-02 12:14:09 -08:00
parent 50ab378da9
commit 5efe36b1e0
1100 changed files with 155024 additions and 8674 deletions

View File

@@ -0,0 +1,288 @@
#!/usr/bin/env bash
# Check deployer balances on all configured networks, estimate gas costs via gas API,
# ensure sufficient network token, then optionally deploy (Chain 138 phased core).
# Uses PRIVATE_KEY from .env (smom-dbis-138).
#
# Balance check: On EVM chains only the NATIVE token can be used for gas. We check that
# token for each network (cast balance = native currency). ERC-20 tokens (USDT, LINK, etc.)
# cannot be used for gas unless a meta-tx relayer is in use.
#
# Gas token per network (only these can be used for gas):
# Chain 138, Ethereum, Base, Optimism, Sepolia, Base Sepolia, Optimism Sepolia → ETH
# Polygon, Polygon Amoy → MATIC
# BSC → BNB
# Avalanche → AVAX
# Cronos → CRO
# Gnosis → xDAI
# Arbitrum → ETH
#
# Usage:
# ./scripts/deployment/check-balances-gas-and-deploy.sh # report only
# ./scripts/deployment/check-balances-gas-and-deploy.sh --deploy # deploy on Chain 138 (requires PRIVATE_KEY)
#
# Uses .env for RPCs and PRIVATE_KEY; --deploy is a tag (not .env).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
parse_deploy_tag "$@"
DO_DEPLOY="${DO_DEPLOY:-0}"
# Load .env (load_deployment_env already did; keep for any vars set after)
if [ -f .env ]; then
set -a
source .env
set +a
fi
# Infura: use Basic Auth URL when INFURA_PROJECT_SECRET is set (fixes "error sending request" from Infura)
SCRIPT_LIB="$SCRIPT_DIR/../lib"
[ -f "${SCRIPT_LIB}/infura.sh" ] && source "${SCRIPT_LIB}/infura.sh"
# Deployer address: use DEPLOYER_ADDRESS if set (matches MetaMask Portfolio), else derive from PRIVATE_KEY
if [ -n "${DEPLOYER_ADDRESS:-}" ]; then
DEPLOYER="${DEPLOYER_ADDRESS}"
[[ "$DEPLOYER" != 0x* ]] && DEPLOYER="0x$DEPLOYER"
else
if [ -z "${PRIVATE_KEY:-}" ]; then
echo "ERROR: Set PRIVATE_KEY in .env or set DEPLOYER_ADDRESS=0x4A666F96fC8764181194447A7dFdb7d471b301C8 for read-only balance check"
exit 1
fi
DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)
if [ -z "$DEPLOYER" ]; then
echo "ERROR: Could not derive deployer address from PRIVATE_KEY (is 'cast' available?)"
exit 1
fi
fi
# Gas estimate for "full" deploy per chain (conservative)
GAS_FULL_DEPLOY_138="${GAS_FULL_DEPLOY_138:-5000000}"
GAS_FULL_DEPLOY_MAINNET="${GAS_FULL_DEPLOY_MAINNET:-5000000}"
BUFFER_BPS=120 # 20% buffer
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Short form for matching MetaMask Portfolio (0x4A66...b301C8)
DEPLOYER_SHORT="${DEPLOYER:0:6}...${DEPLOYER: -6}"
echo -e "${BLUE}============================================${NC}"
echo -e "${BLUE}Deployer balance & gas check (all networks)${NC}"
echo -e "${BLUE}============================================${NC}"
echo "Deployer: $DEPLOYER_SHORT (full: $DEPLOYER)"
echo " (Matches MetaMask Portfolio when RPCs are reachable; use DEPLOYER_ADDRESS=0x... to check a specific wallet)"
echo ""
# Format wei to ether with 8 decimal places (avoids excessive decimals from cast)
format_wei_to_ether() {
local wei="${1:-0}"
local eth
eth=$(echo "scale=10; $wei / 1000000000000000000" | bc 2>/dev/null) || eth="0"
printf "%.8f" "${eth:-0}"
}
# Infura Gas API: supported chain IDs (EIP-1559 style; API returns suggestedMaxFeePerGas in gwei)
INFURA_GAS_API_CHAINS="1 137 10 8453 42161 11155111 84532 11155420 80002 43114 56 100 324 534352"
# Get gas price in wei from Infura Gas API for a given chain_id (optional).
# Returns wei or empty; caller should fallback to cast gas-price.
get_gas_price_wei_infura_api() {
local chain_id="${1:-1}"
local key=""
if [ -n "${INFURA_GAS_API:-}" ]; then
local url="$INFURA_GAS_API"
if [[ "$url" == *"/v3/"* ]]; then
key="${url#*v3/}"
key="${key%%/*}"
else
key="$url"
fi
elif [ -n "${INFURA_PROJECT_ID:-}" ]; then
key="${INFURA_PROJECT_ID}"
fi
if [ -z "$key" ] || ! command -v curl >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then
return 1
fi
local api_url="https://gas.api.infura.io/v3/${key}/networks/${chain_id}/suggestedGasFees"
local res
res=$(curl -sL --connect-timeout 5 "$api_url" 2>/dev/null || true)
if [ -z "$res" ] || echo "$res" | grep -qi "error\|required\|private key\|not found"; then
return 1
fi
local gwei
gwei=$(echo "$res" | jq -r '.medium.suggestedMaxFeePerGas // .standard.suggestedMaxFeePerGas // .standard.maxFeePerGas // .low.suggestedMaxFeePerGas // empty' 2>/dev/null)
if [ -z "$gwei" ] || [ "$gwei" = "null" ]; then
return 1
fi
local wei
wei=$(echo "scale=0; ($gwei) * 1000000000 / 1" | bc 2>/dev/null)
[ -n "$wei" ] && [ "$wei" != "0" ] && echo "$wei"
}
# Get mainnet gas price from Infura Gas API (preferred) or RPC fallback.
get_mainnet_gas_price_wei() {
local wei
wei=$(get_gas_price_wei_infura_api 1)
if [ -z "$wei" ] || [ "$wei" = "0" ]; then
[ -n "${ETHEREUM_MAINNET_RPC:-}" ] && command -v cast >/dev/null 2>&1 && wei=$(cast gas-price --rpc-url "$ETHEREUM_MAINNET_RPC" 2>/dev/null || true)
fi
[ -n "$wei" ] && [ "$wei" != "0" ] && echo "$wei" || echo "30000000000"
}
# Resolve gas price for a chain: try Infura Gas API first (if chain supported), else RPC, else default_wei.
# Usage: get_gas_price_for_chain chain_id rpc_url default_wei
# Output: wei (and sets GAS_SOURCE="Infura Gas API" or "RPC" or "default")
get_gas_price_for_chain() {
local chain_id="$1"
local rpc_url="$2"
local default_wei="${3:-30000000000}"
local wei=""
[ -n "$rpc_url" ] && type ensure_infura_rpc_url &>/dev/null && rpc_url=$(ensure_infura_rpc_url "$rpc_url")
if [[ " $INFURA_GAS_API_CHAINS " == *" $chain_id "* ]]; then
wei=$(get_gas_price_wei_infura_api "$chain_id")
[ -n "$wei" ] && GAS_SOURCE="Infura Gas API" && echo "$wei" && return
fi
if [ -n "$rpc_url" ] && command -v cast >/dev/null 2>&1; then
wei=$(cast gas-price --rpc-url "$rpc_url" 2>/dev/null || true)
[ -n "$wei" ] && [ "$wei" != "0" ] && GAS_SOURCE="RPC" && echo "$wei" && return
fi
GAS_SOURCE="default"
echo "$default_wei"
}
mainnet_gas_wei=$(get_mainnet_gas_price_wei)
mainnet_gas_gwei=$(printf "%.2f" $(echo "scale=4; $mainnet_gas_wei / 1000000000" | bc 2>/dev/null || echo "30"))
echo "Gas prices (verified via Infura Gas API where supported, else RPC or default):"
echo " Ethereum Mainnet (1): ${mainnet_gas_gwei} gwei (Infura Gas API)"
echo ""
# Check native (gas) token balance for one network. Only this token can be used for gas on EVM.
check_network() {
local name="$1"
local rpc="$2"
local chain_id="${3:-}"
local gas_token="${4:-ETH}"
local gas_limit="${5:-$GAS_FULL_DEPLOY_MAINNET}"
local gas_price_wei="${6:-$mainnet_gas_wei}"
if [ -z "$rpc" ]; then
echo -e " ${YELLOW}$name (chain $chain_id): no RPC — gas token = $gas_token (not checked)${NC}"
return 0
fi
type ensure_infura_rpc_url &>/dev/null && rpc=$(ensure_infura_rpc_url "$rpc")
local balance_wei
balance_wei=$(cast balance "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null) || balance_wei=""
local rpc_ok=1
if [ -z "$balance_wei" ] || ! [[ "$balance_wei" =~ ^[0-9]+$ ]]; then
rpc_ok=0
balance_wei="0"
fi
local balance_display
if [ "$rpc_ok" = "0" ]; then
balance_display="(unable to fetch — RPC unreachable?)"
else
balance_display=$(format_wei_to_ether "$balance_wei")
fi
local cost_wei
cost_wei=$(echo "$gas_limit * $gas_price_wei" | bc 2>/dev/null || echo "0")
local cost_with_buffer
cost_with_buffer=$(echo "$cost_wei * $BUFFER_BPS / 100" | bc 2>/dev/null || echo "$cost_wei")
local cost_display
cost_display=$(format_wei_to_ether "$cost_with_buffer")
local ok=0
[ "$rpc_ok" = "1" ] && [ "$(echo "$balance_wei >= $cost_with_buffer" | bc 2>/dev/null)" = "1" ] && ok=1
if [ "$ok" = "1" ]; then
echo -e " ${GREEN}$name (chain $chain_id): gas token $gas_token — balance ${balance_display}, required ~${cost_display} — OK for deploy${NC}"
elif [ "$rpc_ok" = "0" ]; then
echo -e " ${YELLOW}$name (chain $chain_id): gas token $gas_token — balance ${balance_display}, required ~${cost_display} — check RPC / run from network with access${NC}"
else
echo -e " ${RED}$name (chain $chain_id): gas token $gas_token — balance ${balance_display}, required ~${cost_display} — INSUFFICIENT for deploy${NC}"
fi
return $((1 - ok))
}
# All networks: order matches MetaMask Portfolio (Ethereum, BSC, Arbitrum, Optimism, Polygon, Cronos, …)
# Gas needed from Infura Gas API or RPC. Native gas token only (ETH, BNB, POL, CRO, etc.).
echo "Checking gas token balance (same order as MetaMask Portfolio where applicable):"
echo ""
any_insufficient=0
# --- Portfolio main networks (Ethereum, BSC, Arbitrum, Optimism, Polygon, Cronos) ---
check_network "Ethereum Mainnet" "${ETHEREUM_MAINNET_RPC:-}" "1" "ETH" "$GAS_FULL_DEPLOY_MAINNET" "$mainnet_gas_wei" || any_insufficient=1
check_network "BSC" "${BSC_RPC_URL:-${BSC_MAINNET_RPC:-https://bsc-dataseed.binance.org}}" "56" "BNB" "5000000" "$(get_gas_price_for_chain 56 "${BSC_RPC_URL:-${BSC_MAINNET_RPC:-}}" "5000000000")" || true
check_network "Arbitrum" "${ARBITRUM_MAINNET_RPC:-https://arbitrum-one.publicnode.com}" "42161" "ETH" "5000000" "$(get_gas_price_for_chain 42161 "${ARBITRUM_MAINNET_RPC:-}" "100000000")" || true
check_network "Optimism" "${OPTIMISM_MAINNET_RPC:-}" "10" "ETH" "5000000" "$(get_gas_price_for_chain 10 "${OPTIMISM_MAINNET_RPC:-}" "1000000")" || true
check_network "Polygon" "${POLYGON_MAINNET_RPC:-}" "137" "POL" "5000000" "$(get_gas_price_for_chain 137 "${POLYGON_MAINNET_RPC:-}" "50000000000")" || any_insufficient=1
check_network "Cronos" "${CRONOS_RPC_URL:-https://evm.cronos.org}" "25" "CRO" "5000000" "$(get_gas_price_for_chain 25 "${CRONOS_RPC_URL:-}" "1000000000")" || true
# --- Chain 138 (project chain) ---
check_network "Chain 138" "${RPC_URL_138:-}" "138" "ETH" "$GAS_FULL_DEPLOY_138" "$(cast gas-price --rpc-url "${RPC_URL_138:-http://192.168.11.211:8545}" 2>/dev/null || echo "1000000000")" || any_insufficient=1
# --- Other mainnets ---
check_network "Base" "${BASE_MAINNET_RPC:-}" "8453" "ETH" "5000000" "$(get_gas_price_for_chain 8453 "${BASE_MAINNET_RPC:-}" "100000000")" || true
check_network "Avalanche" "${AVALANCHE_RPC_URL:-${AVALANCHE_MAINNET_RPC:-https://avalanche-c-chain.publicnode.com}}" "43114" "AVAX" "5000000" "$(get_gas_price_for_chain 43114 "${AVALANCHE_RPC_URL:-${AVALANCHE_MAINNET_RPC:-}}" "25000000000")" || true
check_network "Gnosis" "${GNOSIS_MAINNET_RPC:-${GNOSIS_RPC:-https://rpc.gnosischain.com}}" "100" "xDAI" "5000000" "$(get_gas_price_for_chain 100 "${GNOSIS_MAINNET_RPC:-${GNOSIS_RPC:-}}" "1000000000")" || true
# --- Testnets ---
check_network "Ethereum Sepolia" "${ETHEREUM_SEPOLIA_RPC:-}" "11155111" "ETH" "5000000" "$(get_gas_price_for_chain 11155111 "${ETHEREUM_SEPOLIA_RPC:-}" "20000000000")" || true
check_network "Polygon Amoy" "${POLYGON_AMOY_RPC:-}" "80002" "MATIC" "5000000" "$(get_gas_price_for_chain 80002 "${POLYGON_AMOY_RPC:-}" "30000000000")" || true
check_network "Base Sepolia" "${BASE_SEPOLIA_RPC:-}" "84532" "ETH" "5000000" "$(get_gas_price_for_chain 84532 "${BASE_SEPOLIA_RPC:-}" "100000000")" || true
check_network "Optimism Sepolia" "${OPTIMISM_SEPOLIA_RPC:-}" "11155420" "ETH" "5000000" "$(get_gas_price_for_chain 11155420 "${OPTIMISM_SEPOLIA_RPC:-}" "1000000")" || true
echo ""
echo "Gas token summary: each chain uses only its native token for gas. ERC-20 (USDT, LINK, etc.) cannot pay gas."
echo "Gas needed above was computed from: Infura Gas API (chains 1, 10, 56, 100, 137, 42161, 43114, 8453, 84532, 80002, 11155111, 11155420) or RPC eth_gasPrice when API unavailable."
echo ""
if [ "${DO_DEPLOY:-0}" = "1" ]; then
if [ -n "${DEPLOYER_ADDRESS:-}" ]; then
echo -e "${RED}ERROR: --deploy requires PRIVATE_KEY in .env (unset DEPLOYER_ADDRESS to use key-derived deployer).${NC}"
exit 1
fi
if [ -z "${PRIVATE_KEY:-}" ]; then
echo -e "${RED}ERROR: PRIVATE_KEY required for --deploy.${NC}"
exit 1
fi
echo -e "${BLUE}Deploy phase (Chain 138 only; other chains need CCIP_* env)${NC}"
RPC_138="${RPC_URL_138:-http://192.168.11.211:8545}"
balance_138=$(cast balance "$DEPLOYER" --rpc-url "$RPC_138" 2>/dev/null || echo "0")
need_138=$(echo "5000000 * 1000000000 * $BUFFER_BPS / 100" | bc 2>/dev/null || echo "6000000000000000000")
if [ -n "$balance_138" ] && [ "$(echo "$balance_138 >= $need_138" | bc 2>/dev/null)" = "1" ]; then
echo "Deploying phased core (01_DeployCore, 02_DeployBridges) on Chain 138..."
export PRIVATE_KEY
out_01=$(mktemp)
trap "rm -f $out_01" EXIT
# Chain 138 often requires minimum gas price (e.g. 1 gwei)
GAS_PRICE_138="${GAS_PRICE_138:-1000000000}"
if forge script script/deploy/01_DeployCore.s.sol:DeployCore \
--rpc-url "$RPC_138" \
--private-key "$PRIVATE_KEY" \
--broadcast \
--with-gas-price "$GAS_PRICE_138" \
-vvv 2>&1 | tee "$out_01"; then
reg=$(grep "UNIVERSAL_ASSET_REGISTRY" "$out_01" | tail -1 | grep -oE "0x[a-fA-F0-9]{40}" | head -1)
if [ -n "$reg" ] && [ -n "${CCIP_ROUTER:-}" ]; then
export UNIVERSAL_ASSET_REGISTRY="$reg"
forge script script/deploy/02_DeployBridges.s.sol:DeployBridges \
--rpc-url "$RPC_138" \
--private-key "$PRIVATE_KEY" \
--broadcast \
--with-gas-price "$GAS_PRICE_138" \
-vvv 2>&1 || echo "02_DeployBridges failed or skipped."
fi
else
echo "01_DeployCore failed or skipped (may already be deployed)."
fi
echo -e "${GREEN}Chain 138 deploy phase finished.${NC}"
else
echo -e "${RED}Chain 138 balance insufficient for deploy (need more native ETH on 138). Fund deployer and re-run.${NC}"
exit 1
fi
else
echo "Run with --deploy to run deployment on Chain 138 (phased core)."
echo "Other chains: fund deployer with that chain's native token (MATIC, BNB, etc.) and set CCIP_* in .env for DeployAll."
fi

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Confirm Cronos deployments: test CRONOSCAN_API_KEY, verify contracts on-chain.
# See docs/04-configuration/CRONOS_EXPLORER_OPERATIONS.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}"
CONTRACTS=(
"0x99B3511A2d315A497C8112C1fdd8D508d4B1E506:WETH9"
"0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6:WETH10"
"0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e:CCIPWETH9Bridge"
"0x105F8A15b819948a89153505762444Ee9f324684:CCIPWETH10Bridge"
)
echo "=== Cronos (Chain 25) deployment confirmation ==="
echo ""
# 1. On-chain confirmation via RPC (eth_getCode)
echo "1. On-chain bytecode check (RPC: $RPC):"
ok=0 missing=0
for entry in "${CONTRACTS[@]}"; do
addr="${entry%%:*}"
name="${entry##*:}"
code=$(cast code "$addr" --rpc-url "$RPC" 2>/dev/null || echo "0x")
if [ "${#code}" -gt 10 ]; then
echo "$name ($addr)"
((ok++)) || true
else
echo "$name ($addr) — no bytecode"
((missing++)) || true
fi
done
echo " Summary: $ok confirmed, $missing missing"
echo ""
# 2. Explorer API (if key set)
if [ -n "${CRONOSCAN_API_KEY:-}" ]; then
echo "2. Cronos Explorer API (CRONOSCAN_API_KEY):"
BLOCK=$(curl -s "https://explorer-api.cronos.org/mainnet/api/v1/ethproxy/getBlockNumber?apikey=${CRONOSCAN_API_KEY}")
if echo "$BLOCK" | grep -q '"result"'; then
NUM=$(echo "$BLOCK" | jq -r '.result')
echo " ✓ Block number: $NUM (dec: $((NUM)))"
else
echo " ✗ API error: $BLOCK"
fi
echo ""
else
echo "2. Cronos Explorer API: SKIP (set CRONOSCAN_API_KEY for block/explorer data)"
echo ""
fi
# 3. Verification instructions
echo "3. Contract verification:"
echo " Manual: https://explorer.cronos.org/verifyContract"
echo " Per-address: https://explorer.cronos.org/address/<ADDR>"
echo ""
echo "Full reference: docs/04-configuration/CRONOS_EXPLORER_OPERATIONS.md"

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Check Cronos contract deployment and verification status.
# Verification status must be checked manually by visiting each explorer URL;
# this script confirms on-chain deployment and prints links.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}"
CONTRACTS=(
"0x99B3511A2d315A497C8112C1fdd8D508d4B1E506:WETH9"
"0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6:WETH10"
"0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e:CCIPWETH9Bridge"
"0x105F8A15b819948a89153505762444Ee9f324684:CCIPWETH10Bridge"
)
echo "=== Cronos (Chain 25) contract status ==="
echo ""
echo "On-chain deployment:"
for entry in "${CONTRACTS[@]}"; do
addr="${entry%%:*}"
name="${entry##*:}"
code=$(cast code "$addr" --rpc-url "$RPC" 2>/dev/null || echo "0x")
if [ "${#code}" -gt 10 ]; then
echo "$name — DEPLOYED"
else
echo "$name — MISSING"
fi
done
echo ""
echo "Verification status (check each link manually):"
echo " Verified contracts show 'Contract Source Code Verified' or display source."
echo ""
for entry in "${CONTRACTS[@]}"; do
addr="${entry%%:*}"
name="${entry##*:}"
echo " $name: https://explorer.cronos.org/address/$addr"
done
echo ""
echo "Run ./scripts/deployment/export-cronos-verification-sources.sh and follow"
echo "docs/deployment/CRONOS_VERIFICATION_RUNBOOK.md to verify unverified contracts."

View File

@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Check that .env has the VITE_* (and related) vars needed for frontend-dapp production build.
# Usage: ./scripts/deployment/check-dapp-env.sh [path-to-.env]
# Exit 0 if all required are set; exit 1 and list missing if not.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
ENV_FILE="${1:-$REPO_ROOT/.env}"
get_var() {
local name="$1"
if [[ ! -f "$ENV_FILE" ]]; then
echo ""
return
fi
local line
line="$(grep -E "^(export[[:space:]]+)?${name}=" "$ENV_FILE" 2>/dev/null | head -1)"
if [[ -n "$line" ]]; then
echo "$line" | sed -E 's/^(export[[:space:]]+)?[^=]+=//' | sed 's/^["'\'' ]//;s/["'\'' ]$//' | xargs
else
echo ""
fi
}
REQUIRED_FOR_BUILD=(
"VITE_RPC_URL_138"
)
OPTIONAL_BUT_RECOMMENDED=(
"VITE_LOCKBOX_138"
"VITE_INBOX_ETH_MAINNET"
"VITE_LIQUIDITY_POOL_ETH_MAINNET"
"VITE_DUAL_ROUTER_BRIDGE_SWAP_COORDINATOR"
"VITE_CHALLENGE_MANAGER_MAINNET"
"VITE_WALLETCONNECT_PROJECT_ID"
"VITE_THIRDWEB_CLIENT_ID"
)
missing=()
for v in "${REQUIRED_FOR_BUILD[@]}"; do
val="$(get_var "$v")"
if [[ -z "$val" || "$val" == "0x..." || "$val" == "your-"* ]]; then
missing+=("$v")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
echo "Missing or placeholder required for DApp build: ${missing[*]}"
echo "Set them in $ENV_FILE (or copy from .env.example and fill)."
exit 1
fi
echo "Required VITE_* for DApp build are set."
for v in "${OPTIONAL_BUT_RECOMMENDED[@]}"; do
val="$(get_var "$v")"
if [[ -z "$val" || "$val" == "0x..." || "$val" == "your-"* ]]; then
echo "Optional (recommended): $v"
fi
done
exit 0

View File

@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# Check smom-dbis-138/.env for required and optional variable names (no values printed).
# Usage: ./scripts/deployment/check-env-required.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
ENV_FILE="${PROJECT_ROOT}/.env"
echo "=== .env check (keys only, no values) ==="
echo ""
if [ ! -f "$ENV_FILE" ]; then
echo " .env: MISSING"
exit 1
fi
# Build list of key names (strip values; never print values)
keys_file=$(mktemp)
trap 'rm -f "$keys_file"' EXIT
grep -E '^[A-Za-z_][A-Za-z0-9_]*=' "$ENV_FILE" 2>/dev/null | sed 's/=.*//' > "$keys_file" || true
grep -E '^export [A-Za-z_][A-Za-z0-9_]*=' "$ENV_FILE" 2>/dev/null | sed 's/^export //; s/=.*//' >> "$keys_file" || true
sort -u "$keys_file" -o "$keys_file"
check() { grep -qx "$1" "$keys_file" 2>/dev/null; }
total=$(wc -l < "$keys_file")
echo " .env: EXISTS ($total keys)"
echo ""
# Required for deploy-contracts-unified.sh and most Chain 138 scripts
echo "--- Required (deploy / Chain 138) ---"
for k in PRIVATE_KEY RPC_URL RPC_URL_138; do
check "$k" && echo " OK $k" || echo " MISS $k"
done
# PRIVATE_KEY format: 64 hex chars (no value printed)
if check "PRIVATE_KEY"; then
len=$(awk -F= '/^PRIVATE_KEY=/ { v=$2; gsub(/^0x/,"",v); print length(v) }' "$ENV_FILE" 2>/dev/null || echo "0")
[ "$len" = "64" ] && echo " PRIVATE_KEY format: 64-char hex" || echo " PRIVATE_KEY format: WARN (length=$len, expected 64)"
fi
echo ""
# Optional for PMM pool script (create-all-dodo-pools-from-token-api.sh)
echo "--- Optional (PMM pools: DODO_PMM_INTEGRATION or DODO_PMM_INTEGRATION_ADDRESS, QUOTE_TOKEN or QUOTE_TOKEN_ADDRESS / WETH_ADDRESS_138) ---"
for k in DODO_PMM_INTEGRATION DODO_PMM_INTEGRATION_ADDRESS QUOTE_TOKEN QUOTE_TOKEN_ADDRESS WETH_ADDRESS_138; do
check "$k" && echo " OK $k" || echo " -- $k"
done
echo ""
# Optional for mainnet dry-run
echo "--- Optional (mainnet dry-run) ---"
for k in ETHEREUM_MAINNET_RPC; do
check "$k" && echo " OK $k" || echo " -- $k"
done
echo ""
# Common CCIP / bridge
echo "--- Optional (CCIP / bridge) ---"
for k in CCIP_ROUTER LINK_TOKEN CCIPWETH9_BRIDGE_CHAIN138 CCIPWETH10_BRIDGE_CHAIN138; do
check "$k" && echo " OK $k" || echo " -- $k"
done
echo ""
echo "Done. Fix any MISS above; -- means optional and can be set when needed."

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Check deployer LINK balance on Gnosis, Cronos, Celo (config-ready chains).
# Required before fund-ccip-bridges-with-link.sh: 20 LINK per chain (10 per bridge).
#
# Usage: ./scripts/deployment/check-link-balance-config-ready-chains.sh [gnosis|cronos|celo|all]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
[[ -f "$PROJECT_ROOT/.env" ]] && set -a && source "$PROJECT_ROOT/.env" && set +a
CHAIN="${1:-all}"
REQUIRED_LINK="20" # 10 per WETH9 bridge + 10 per WETH10 bridge
# LINK token addresses (from CCIP directory)
LINK_TOKEN_GNOSIS="${LINK_TOKEN_GNOSIS:-${CCIP_GNOSIS_LINK_TOKEN:-0xE2e73A1c69ecF83F464EFCE6A5be353a37cA09b2}}"
LINK_TOKEN_CRONOS="${LINK_TOKEN_CRONOS:-${CCIP_CRONOS_LINK_TOKEN:-0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85}}"
LINK_TOKEN_CELO="${LINK_TOKEN_CELO:-${CCIP_CELO_LINK_TOKEN:-0xd07294e6E917e07dfDcee882dd1e2565085C2ae0}}"
GNOSIS_RPC="${GNOSIS_RPC:-https://rpc.gnosischain.com}"
CRONOS_RPC="${CRONOS_RPC:-https://evm.cronos.org}"
CELO_RPC="${CELO_RPC:-https://forno.celo.org}"
if [[ -z "${PRIVATE_KEY:-}" ]]; then
echo "Error: Set PRIVATE_KEY in .env" >&2
exit 1
fi
DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)
[[ -z "$DEPLOYER" ]] && { echo "Error: Could not derive deployer from PRIVATE_KEY" >&2; exit 1; }
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
check_link() {
local name="$1" rpc="$2" link_token="$3"
[[ -z "$rpc" || -z "$link_token" ]] && return 1
local raw
raw=$(cast call "$link_token" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0")
local link_val
link_val=$(echo "scale=4; $raw / 1000000000000000000" | bc 2>/dev/null || echo "0")
if [[ -z "$link_val" || "$link_val" == "0" ]]; then
echo -e " ${RED}${NC} $name: 0 LINK (need $REQUIRED_LINK LINK)"
return 1
fi
if [[ "$(echo "$link_val >= $REQUIRED_LINK" | bc 2>/dev/null)" == "1" ]]; then
echo -e " ${GREEN}${NC} $name: $link_val LINK"
return 0
fi
echo -e " ${YELLOW}${NC} $name: $link_val LINK (need $REQUIRED_LINK LINK)"
return 1
}
echo "=== LINK Balance Check (Config-Ready Chains) ==="
echo "Deployer: ${DEPLOYER:0:10}...${DEPLOYER: -8}"
echo "Required: $REQUIRED_LINK LINK per chain (10 per WETH9 + 10 per WETH10 bridge)"
echo ""
failed=0
case "$CHAIN" in
gnosis) check_link "Gnosis" "$GNOSIS_RPC" "$LINK_TOKEN_GNOSIS" || failed=1 ;;
cronos) check_link "Cronos" "$CRONOS_RPC" "$LINK_TOKEN_CRONOS" || failed=1 ;;
celo) check_link "Celo" "$CELO_RPC" "$LINK_TOKEN_CELO" || failed=1 ;;
all)
check_link "Gnosis" "$GNOSIS_RPC" "$LINK_TOKEN_GNOSIS" || failed=1
check_link "Cronos" "$CRONOS_RPC" "$LINK_TOKEN_CRONOS" || failed=1
check_link "Celo" "$CELO_RPC" "$LINK_TOKEN_CELO" || failed=1
;;
*) echo "Usage: $0 [gnosis|cronos|celo|all]"; exit 1 ;;
esac
echo ""
if [[ $failed -eq 0 ]]; then
echo "LINK balance OK. Run: ./scripts/deployment/fund-ccip-bridges-with-link.sh"
exit 0
else
echo "Acquire LINK on each chain (bridge from mainnet or DEX), then re-run this check."
echo " Gnosis: $LINK_TOKEN_GNOSIS"
echo " Cronos: $LINK_TOKEN_CRONOS"
echo " Celo: $LINK_TOKEN_CELO"
exit 1
fi

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# Check bash syntax of deployment scripts and lib (bash -n). Run from anywhere.
# Usage: ./scripts/deployment/check-syntax.sh or bash scripts/deployment/check-syntax.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$REPO_ROOT"
FAIL=0
check() {
if bash -n "$1" 2>/dev/null; then
echo " OK $1"
else
echo " FAIL $1"
FAIL=1
fi
}
echo "Checking deployment scripts and lib..."
check scripts/lib/deployment/prompts.sh
check scripts/lib/deployment/dotenv.sh
check scripts/deployment/fund-mainnet-lp.sh
check scripts/deployment/run-all-four-gaps.sh
check scripts/deployment/deploy-pmm-all-l2s.sh
check scripts/deployment/deploy-trustless-l2s.sh
check scripts/deployment/fund-ccip-bridges-with-link.sh
check scripts/deployment/fix-nonce-and-retry.sh
check scripts/deployment/run-remaining-g2g3-with-nonce-fix.sh
check scripts/deployment/run-pmm-and-pools.sh
check scripts/deployment/check-balances-gas-and-deploy.sh
if [[ "$FAIL" -eq 0 ]]; then
echo "All passed."
else
echo "Some checks failed."
exit 1
fi

View File

@@ -0,0 +1,136 @@
#!/usr/bin/env bash
# Complete CCIP bridge configuration for Config-Ready chains (Gnosis, Celo, Wemix).
# - Adds each chain as destination on Chain 138 bridges (138 → Gnosis/Celo/Wemix).
# - Adds Chain 138 as destination on each chain's bridges (Gnosis/Celo/Wemix → 138).
# Requires: bridge addresses and RPCs in .env; PRIVATE_KEY; CHAIN138_SELECTOR for step 2.
# Usage: ./scripts/deployment/complete-config-ready-chains.sh
# DRY_RUN=1 ./scripts/deployment/complete-config-ready-chains.sh # print commands only
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[[ -f "$SCRIPT_DIR/../lib/init.sh" ]] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
if [[ -f "$PROJECT_ROOT/.env" ]]; then
set -a
source "$PROJECT_ROOT/.env"
set +a
fi
# Chain selectors (decimal, for addDestination(uint64,address))
ETH_MAINNET_SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}"
GNOSIS_SELECTOR="${GNOSIS_SELECTOR:-465200170687744372}"
CRONOS_SELECTOR="${CRONOS_SELECTOR:-1456215246176062136}"
CELO_SELECTOR="${CELO_SELECTOR:-1346049177634351622}"
WEMIX_SELECTOR="${WEMIX_SELECTOR:-5142893604156789321}"
CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-}"
CHAIN138_RPC="${CHAIN138_RPC:-${RPC_URL:-https://rpc-core.d-bis.org}}"
GNOSIS_RPC="${GNOSIS_RPC:-https://rpc.gnosischain.com}"
CRONOS_RPC="${CRONOS_RPC:-https://evm.cronos.org}"
CELO_RPC="${CELO_RPC:-https://forno.celo.org}"
WEMIX_RPC="${WEMIX_RPC:-https://api.wemix.com}"
PRIVATE_KEY="${PRIVATE_KEY:-}"
if [[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]]; then
PRIVATE_KEY="0x$PRIVATE_KEY"
fi
# Chain 138 bridge addresses (required)
WETH9_138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CHAIN138:-}")
WETH10_138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CHAIN138:-}")
# Config-ready chain bridge addresses (optional; if set, we configure them)
WETH9_GNOSIS=$(grep "CCIPWETH9_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_GNOSIS:-}")
WETH10_GNOSIS=$(grep "CCIPWETH10_BRIDGE_GNOSIS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_GNOSIS:-}")
WETH9_CRONOS=$(grep "CCIPWETH9_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CRONOS:-}")
WETH10_CRONOS=$(grep "CCIPWETH10_BRIDGE_CRONOS=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CRONOS:-}")
WETH9_CELO=$(grep "CCIPWETH9_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_CELO:-}")
WETH10_CELO=$(grep "CCIPWETH10_BRIDGE_CELO=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_CELO:-}")
WETH9_WEMIX=$(grep "CCIPWETH9_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH9_BRIDGE_WEMIX:-}")
WETH10_WEMIX=$(grep "CCIPWETH10_BRIDGE_WEMIX=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "${CCIPWETH10_BRIDGE_WEMIX:-}")
DRY_RUN="${DRY_RUN:-0}"
log_info "=== Config-Ready Chains Completion (Gnosis, Cronos, Celo, Wemix) ==="
if [[ -z "$WETH9_138" || -z "$WETH10_138" ]]; then
echo "Error: Chain 138 bridge addresses not set. Set in .env: CCIPWETH9_BRIDGE_CHAIN138, CCIPWETH10_BRIDGE_CHAIN138" >&2
exit 1
fi
if [[ -z "$PRIVATE_KEY" ]]; then
echo "Error: PRIVATE_KEY not set in .env" >&2
exit 1
fi
run_or_echo() {
if [[ "$DRY_RUN" = "1" ]]; then
echo " [DRY RUN] $*"
else
if eval "$*" >/dev/null 2>&1; then
log_success " OK"
else
log_warn " Failed (non-fatal) - run manually to see error"
fi
fi
}
# ---- Step A: On Chain 138, add Gnosis/Cronos/Celo/Wemix as destinations ----
echo ""
echo "Step A: Chain 138 bridges → add Gnosis, Cronos, Celo, Wemix as destinations"
while IFS= read -r line; do
read -r label selector addr9 addr10 rpc <<< "$line"
if [[ -z "$addr9" && -z "$addr10" ]]; then
echo " Skip $label (no bridge addresses in .env)"
continue
fi
echo " Configuring Chain 138 → $label..."
if [[ -n "$addr9" ]]; then
run_or_echo "cast send $WETH9_138 \"addDestination(uint64,address)\" $selector $addr9 --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 200000"
fi
if [[ -n "$addr10" ]]; then
run_or_echo "cast send $WETH10_138 \"addDestination(uint64,address)\" $selector $addr10 --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy --gas-limit 200000"
fi
done << EOF
Gnosis $GNOSIS_SELECTOR $WETH9_GNOSIS $WETH10_GNOSIS $GNOSIS_RPC
Cronos $CRONOS_SELECTOR $WETH9_CRONOS $WETH10_CRONOS $CRONOS_RPC
Celo $CELO_SELECTOR $WETH9_CELO $WETH10_CELO $CELO_RPC
Wemix $WEMIX_SELECTOR $WETH9_WEMIX $WETH10_WEMIX $WEMIX_RPC
EOF
# ---- Step B: On Gnosis/Cronos/Celo/Wemix, add Chain 138 as destination ----
if [[ -z "$CHAIN138_SELECTOR" ]]; then
echo ""
echo "Step B: Skipped (CHAIN138_SELECTOR not set in .env). Set it to configure remote chains → Chain 138."
echo " Example: CHAIN138_SELECTOR=<decimal from CCIP Router getChainSelector()>"
else
echo ""
echo "Step B: Gnosis/Cronos/Celo/Wemix bridges → add Chain 138 as destination"
while IFS= read -r line; do
read -r label rpc addr9 addr10 <<< "$line"
if [[ -z "$addr9" && -z "$addr10" ]]; then
echo " Skip $label (no bridge addresses)"
continue
fi
echo " Configuring $label → Chain 138..."
if [[ -n "$addr9" ]]; then
run_or_echo "cast send $addr9 \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH9_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy"
fi
if [[ -n "$addr10" ]]; then
run_or_echo "cast send $addr10 \"addDestination(uint64,address)\" $CHAIN138_SELECTOR $WETH10_138 --rpc-url $rpc --private-key \$PRIVATE_KEY --legacy"
fi
done << EOF
Gnosis $GNOSIS_RPC $WETH9_GNOSIS $WETH10_GNOSIS
Cronos $CRONOS_RPC $WETH9_CRONOS $WETH10_CRONOS
Celo $CELO_RPC $WETH9_CELO $WETH10_CELO
Wemix $WEMIX_RPC $WETH9_WEMIX $WETH10_WEMIX
EOF
fi
echo ""
log_success "Config-ready chains script finished."
echo " Next: Fund each remote bridge with LINK (see docs/07-ccip/CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md)."

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env bash
# Configure CCIP bridge destinations for Avalanche, Arbitrum, Cronos ↔ Chain 138.
# Step A: On Chain 138, add Avalanche/Arbitrum/Cronos as destinations
# Step B: On Avalanche/Arbitrum/Cronos, add Chain 138 as destination
# Requires: bridge addresses and CHAIN138_SELECTOR in .env; PRIVATE_KEY; Chain 138 RPC reachable for Step A.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
if [[ -f .env ]]; then
set -a
source .env
set +a
fi
[[ -f "$SCRIPT_DIR/../lib/infura.sh" ]] && source "$SCRIPT_DIR/../lib/infura.sh"
# Chain selectors (decimal)
AVALANCHE_SELECTOR="${AVALANCHE_SELECTOR:-6433500567565415381}"
ARBITRUM_SELECTOR="${ARBITRUM_SELECTOR:-4949039107694359620}"
CRONOS_SELECTOR="${CRONOS_SELECTOR:-1456215246176062136}"
CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-138}"
CHAIN138_RPC="${RPC_URL_138:-${CHAIN138_RPC:-http://192.168.11.211:8545}}"
# Prefer explicit RPC; else Infura (INFURA_PROJECT_ID + optional INFURA_PROJECT_SECRET); else public
_avalanche_infura=$(build_infura_rpc "avalanche-mainnet" 2>/dev/null || true)
_arbitrum_infura=$(build_infura_rpc "arbitrum-mainnet" 2>/dev/null || true)
AVALANCHE_RPC="${AVALANCHE_RPC_URL:-${AVALANCHE_RPC:-${_avalanche_infura:-https://avalanche-c-chain.publicnode.com}}}"
ARBITRUM_RPC="${ARBITRUM_MAINNET_RPC:-${ARBITRUM_RPC:-${_arbitrum_infura:-https://arbitrum-one.publicnode.com}}}"
CRONOS_RPC="${CRONOS_RPC_URL:-${CRONOS_RPC:-https://evm.cronos.org}}"
WETH9_138="${CCIPWETH9_BRIDGE_CHAIN138:-}"
WETH10_138="${CCIPWETH10_BRIDGE_CHAIN138:-}"
WETH9_AVALANCHE="${CCIPWETH9_BRIDGE_AVALANCHE:-}"
WETH10_AVALANCHE="${CCIPWETH10_BRIDGE_AVALANCHE:-}"
WETH9_ARBITRUM="${CCIPWETH9_BRIDGE_ARBITRUM:-}"
WETH10_ARBITRUM="${CCIPWETH10_BRIDGE_ARBITRUM:-}"
WETH9_CRONOS="${CCIPWETH9_BRIDGE_CRONOS:-}"
WETH10_CRONOS="${CCIPWETH10_BRIDGE_CRONOS:-}"
PRIVATE_KEY="${PRIVATE_KEY:-}"
[[ -n "$PRIVATE_KEY" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY"
DRY_RUN="${DRY_RUN:-0}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
run_or_echo() {
if [[ "$DRY_RUN" = "1" ]]; then
echo " [DRY RUN] $*"
else
if eval "$*"; then
echo -e " ${GREEN}OK${NC}"
else
echo -e " ${RED}Failed${NC}"
return 1
fi
fi
}
echo -e "${GREEN}=== Avalanche/Arbitrum/Cronos ↔ Chain 138 Bridge Configuration ===${NC}"
echo ""
if [[ -z "$PRIVATE_KEY" ]]; then
echo -e "${RED}ERROR: PRIVATE_KEY not set${NC}"
exit 1
fi
if [[ -z "$WETH9_138" ]]; then
echo -e "${RED}ERROR: CCIPWETH9_BRIDGE_CHAIN138 must be set in .env${NC}"
exit 1
fi
if [[ -z "$WETH10_138" ]]; then
echo -e "${YELLOW}NOTE: CCIPWETH10_BRIDGE_CHAIN138 not set; skipping WETH10 bridge configuration${NC}"
fi
echo "Step A: Chain 138 → add Avalanche, Arbitrum, Cronos as destinations"
echo " (Requires Chain 138 RPC reachable: $CHAIN138_RPC)"
echo ""
# Step A: Chain 138 → Avalanche
if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then
echo " Chain 138 → Avalanche:"
[[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $AVALANCHE_SELECTOR $WETH9_AVALANCHE --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_AVALANCHE" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $AVALANCHE_SELECTOR $WETH10_AVALANCHE --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
# Step A: Chain 138 → Arbitrum
if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then
echo " Chain 138 → Arbitrum:"
[[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $ARBITRUM_SELECTOR $WETH9_ARBITRUM --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_ARBITRUM" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $ARBITRUM_SELECTOR $WETH10_ARBITRUM --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
# Step A: Chain 138 → Cronos
if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then
echo " Chain 138 → Cronos:"
[[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send $WETH9_138 'addDestination(uint64,address)' $CRONOS_SELECTOR $WETH9_CRONOS --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_CRONOS" ]] && run_or_echo "cast send $WETH10_138 'addDestination(uint64,address)' $CRONOS_SELECTOR $WETH10_CRONOS --rpc-url $CHAIN138_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
echo ""
echo "Step B: Avalanche/Arbitrum/Cronos → add Chain 138 as destination"
echo ""
# Step B: Avalanche → Chain 138
if [[ -n "$WETH9_AVALANCHE" || -n "$WETH10_AVALANCHE" ]]; then
echo " Avalanche → Chain 138:"
[[ -n "$WETH9_AVALANCHE" ]] && run_or_echo "cast send $WETH9_AVALANCHE 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_AVALANCHE" ]] && run_or_echo "cast send $WETH10_AVALANCHE 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $AVALANCHE_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
# Step B: Arbitrum → Chain 138
if [[ -n "$WETH9_ARBITRUM" || -n "$WETH10_ARBITRUM" ]]; then
echo " Arbitrum → Chain 138:"
[[ -n "$WETH9_ARBITRUM" ]] && run_or_echo "cast send $WETH9_ARBITRUM 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_ARBITRUM" ]] && run_or_echo "cast send $WETH10_ARBITRUM 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $ARBITRUM_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
# Step B: Cronos → Chain 138
if [[ -n "$WETH9_CRONOS" || -n "$WETH10_CRONOS" ]]; then
echo " Cronos → Chain 138:"
[[ -n "$WETH9_CRONOS" ]] && run_or_echo "cast send $WETH9_CRONOS 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH9_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY --legacy" || true
[[ -n "$WETH10_CRONOS" ]] && run_or_echo "cast send $WETH10_CRONOS 'addDestination(uint64,address)' $CHAIN138_SELECTOR $WETH10_138 --rpc-url $CRONOS_RPC --private-key \$PRIVATE_KEY --legacy" || true
fi
echo ""
echo -e "${GREEN}Bridge configuration complete.${NC}"
echo "Next: Fund each bridge with LINK for CCIP fees if not already done."

View File

@@ -1,57 +1,107 @@
#!/usr/bin/env bash
# Configure bridge destinations for cross-chain functionality
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Configure Bridge Destinations Script
# Configures ChainID 138 ↔ Mainnet bidirectional bridge destinations
set -e
log_info "=== Configuring Bridge Destinations ==="
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Load environment
if [ -f "$PROJECT_ROOT/.env" ]; then
source "$PROJECT_ROOT/.env"
fi
# Configuration
PRIVATE_KEY="${PRIVATE_KEY:-}"
RPC_URL_138="${RPC_URL_138:-http://192.168.11.175:8545}"
RPC_URL_MAINNET="${RPC_URL_MAINNET:-https://eth.llamarpc.com}"
MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}"
CHAIN138_RPC="${RPC_URL:-https://rpc.d-bis.org}"
PRIVATE_KEY="${PRIVATE_KEY}"
if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then
PRIVATE_KEY="0x$PRIVATE_KEY"
fi
# Chain Selectors
MAINNET_CHAIN_SELECTOR="5009297550715157269"
CHAIN138_CHAIN_SELECTOR="${CHAIN138_CHAIN_SELECTOR:-}" # To be determined
# Get deployed addresses
WETH9_BRIDGE_MAINNET=$(grep "CCIPWETH9_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "")
WETH10_BRIDGE_MAINNET=$(grep "CCIPWETH10_BRIDGE_MAINNET=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "")
WETH9_BRIDGE_CHAIN138=$(grep "CCIPWETH9_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "")
WETH10_BRIDGE_CHAIN138=$(grep "CCIPWETH10_BRIDGE_CHAIN138=" "$PROJECT_ROOT/.env" 2>/dev/null | cut -d'=' -f2 | tr -d ' "' || echo "")
# Contract Addresses (set these after deployment)
WETH9_BRIDGE_138="${WETH9_BRIDGE_138:-}"
WETH10_BRIDGE_138="${WETH10_BRIDGE_138:-}"
WETH9_MAINNET="${WETH9_MAINNET:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}"
WETH10_MAINNET="${WETH10_MAINNET:-0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f}"
# Chain selectors
ETH_SELECTOR="${ETH_MAINNET_SELECTOR:-0x500147}" # Ethereum Mainnet
CHAIN138_SELECTOR="${CHAIN138_SELECTOR:-0x000000000000008a}" # Chain-138
echo -e "${GREEN}=== Bridge Destination Configuration ===${NC}\n"
echo "Configuration:"
echo " Ethereum Mainnet Selector: $ETH_SELECTOR"
echo " Chain-138 Selector: $CHAIN138_SELECTOR"
if [ -z "$WETH9_BRIDGE_MAINNET" ] || [ -z "$WETH9_BRIDGE_CHAIN138" ]; then
log_warn "⚠️ Bridge addresses not found in .env"
echo "Please ensure bridges are deployed on both chains"
# Check prerequisites
if [ -z "$PRIVATE_KEY" ]; then
echo -e "${RED}ERROR: PRIVATE_KEY environment variable not set${NC}"
exit 1
fi
echo "Bridge Addresses:"
echo " WETH9 Mainnet: $WETH9_BRIDGE_MAINNET"
echo " WETH9 Chain-138: $WETH9_BRIDGE_CHAIN138"
echo " WETH10 Mainnet: $WETH10_BRIDGE_MAINNET"
echo " WETH10 Chain-138: $WETH10_BRIDGE_CHAIN138"
if [ -z "$WETH9_BRIDGE_138" ] || [ -z "$WETH10_BRIDGE_138" ]; then
echo -e "${YELLOW}WARNING: Bridge addresses not set. Please set WETH9_BRIDGE_138 and WETH10_BRIDGE_138${NC}"
exit 1
fi
log_info "Note: Bridge destination configuration requires:"
echo " 1. Calling addDestination() on each bridge contract"
echo " 2. Setting the corresponding bridge address on the destination chain"
echo " 3. Enabling the destination"
echo "This can be done via:"
echo " • cast send (for Foundry)"
echo " • Hardhat scripts"
echo " • Direct contract interaction"
log_warn "⚠️ Manual configuration required"
# Function to add destination
add_destination() {
local bridge_address=$1
local chain_selector=$2
local destination_token=$3
local rpc_url=$4
local network_name=$5
echo -e "${GREEN}Adding destination to $network_name bridge...${NC}"
cast send "$bridge_address" \
"addDestination(uint64,address,address)" \
"$chain_selector" \
"$destination_token" \
"0x0000000000000000000000000000000000000000" \
--rpc-url "$rpc_url" \
--private-key "$PRIVATE_KEY" \
--legacy
echo -e "${GREEN}✓ Destination added${NC}\n"
}
# Function to verify destinations
verify_destinations() {
local bridge_address=$1
local rpc_url=$2
local network_name=$3
echo -e "${GREEN}Verifying destinations on $network_name...${NC}"
local chains=$(cast call "$bridge_address" \
"getDestinationChains()(uint64[])" \
--rpc-url "$rpc_url")
echo -e "${GREEN}Destination chains: $chains${NC}\n"
}
# Configure ChainID 138 → Mainnet
echo -e "${YELLOW}=== Configuring ChainID 138 → Mainnet ===${NC}\n"
echo -e "${GREEN}1. Configuring WETH9 Bridge (ChainID 138 → Mainnet)${NC}"
add_destination "$WETH9_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH9_MAINNET" "$RPC_URL_138" "ChainID 138"
echo -e "${GREEN}2. Configuring WETH10 Bridge (ChainID 138 → Mainnet)${NC}"
add_destination "$WETH10_BRIDGE_138" "$MAINNET_CHAIN_SELECTOR" "$WETH10_MAINNET" "$RPC_URL_138" "ChainID 138"
# Verify ChainID 138 bridges
echo -e "${YELLOW}=== Verifying ChainID 138 Bridges ===${NC}\n"
verify_destinations "$WETH9_BRIDGE_138" "$RPC_URL_138" "WETH9 Bridge"
verify_destinations "$WETH10_BRIDGE_138" "$RPC_URL_138" "WETH10 Bridge"
# Note: Mainnet → ChainID 138 requires ChainID 138 selector
if [ -z "$CHAIN138_CHAIN_SELECTOR" ]; then
echo -e "${YELLOW}NOTE: ChainID 138 chain selector not set.${NC}"
echo -e "${YELLOW}To configure Mainnet → ChainID 138, first determine the ChainID 138 selector.${NC}"
echo -e "${YELLOW}You can find it using: cast call <CCIP_ROUTER> 'getChainSelector()(uint64)' --rpc-url $RPC_URL_138${NC}\n"
else
echo -e "${YELLOW}=== Configuring Mainnet → ChainID 138 ===${NC}\n"
echo -e "${YELLOW}NOTE: This requires deploying bridges on Mainnet first.${NC}\n"
fi
echo -e "${GREEN}=== Configuration Complete ===${NC}\n"
echo -e "Next Steps:"
echo -e " 1. Test bidirectional transfers"
echo -e " 2. Monitor bridge activity"
echo -e " 3. Verify LINK token balances for CCIP fees"

View File

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# Create a Uniswap V3 pool for cUSDT/cUSDC (or two token addresses) on a given chain.
# Requires: cast (foundry), RPC for the chain, PRIVATE_KEY with gas.
# Usage:
# CUSDT=0x... CUSDC=0x... RPC_URL=$POLYGON_MAINNET_RPC ./scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh
# Or: TOKEN_A=0x... TOKEN_B=0x... FEE=500 RPC_URL=... ./scripts/deployment/create-uniswap-v3-pool-cusdt-cusdc.sh
# Fee: 500 = 0.05% (typical for stables), 3000 = 0.3%, 10000 = 1%.
# Uniswap V3 factory (mainnet, Polygon, BSC, Base, Arbitrum, Optimism): 0x1F98431c8aD98523631AE4a59f267346ea31F984
# See docs/deployment/CUSDT_CUSDC_MULTICHAIN_LIQUIDITY_RUNBOOK.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DOTENV="$REPO_ROOT/.env"
if [[ -f "$DOTENV" ]]; then set -a; source "$DOTENV"; set +a; fi
UNISWAP_V3_FACTORY="${UNISWAP_V3_FACTORY:-0x1F98431c8aD98523631AE4a59f267346ea31F984}"
FEE="${FEE:-500}"
TOKEN_A="${TOKEN_A:-${CUSDT_ADDRESS:-}}"
TOKEN_B="${TOKEN_B:-${CUSDC_ADDRESS:-}}"
if [[ -z "$TOKEN_A" ]] && [[ -n "${CUSDT_ADDRESS_137:-}" ]]; then
TOKEN_A="${CUSDT_ADDRESS_137}"
TOKEN_B="${CUSDC_ADDRESS_137}"
fi
if [[ -z "$TOKEN_A" ]]; then
echo "Set TOKEN_A and TOKEN_B (or CUSDT_ADDRESS and CUSDC_ADDRESS, or CUSDT_ADDRESS_<chainId> and CUSDC_ADDRESS_<chainId>)"
exit 1
fi
if [[ -z "$TOKEN_B" ]]; then
echo "Set TOKEN_B (or CUSDC_ADDRESS)"
exit 1
fi
RPC_URL="${RPC_URL:-${POLYGON_MAINNET_RPC:-${ETHEREUM_MAINNET_RPC:-}}}"
if [[ -z "$RPC_URL" ]]; then
echo "Set RPC_URL (or POLYGON_MAINNET_RPC / ETHEREUM_MAINNET_RPC)"
exit 1
fi
echo "Creating Uniswap V3 pool: tokenA=$TOKEN_A tokenB=$TOKEN_B fee=$FEE"
echo "Factory=$UNISWAP_V3_FACTORY RPC=$RPC_URL"
POOL=$(cast call "$UNISWAP_V3_FACTORY" "getPool(address,address,uint24)(address)" "$TOKEN_A" "$TOKEN_B" "$FEE" --rpc-url "$RPC_URL" 2>/dev/null || true)
if [[ -n "$POOL" ]] && [[ "$POOL" != "0x0000000000000000000000000000000000000000" ]]; then
echo "Pool already exists: $POOL"
exit 0
fi
cast send "$UNISWAP_V3_FACTORY" "createPool(address,address,uint24)" "$TOKEN_A" "$TOKEN_B" "$FEE" \
--rpc-url "$RPC_URL" \
--private-key "${PRIVATE_KEY:?PRIVATE_KEY required}"
POOL=$(cast call "$UNISWAP_V3_FACTORY" "getPool(address,address,uint24)(address)" "$TOKEN_A" "$TOKEN_B" "$FEE" --rpc-url "$RPC_URL")
echo "Pool created: $POOL"
echo "Next: initialize the pool with sqrtPriceX96 and add liquidity via Uniswap UI or NonfungiblePositionManager."

View File

@@ -8,7 +8,8 @@ cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
RPC_URL="${RPC_URL:-http://localhost:8545}"
RPC_URL="${RPC_URL_138:-http://localhost:8545}"
GAS_PRICE="${GAS_PRICE:-1000000000}"
PRIVATE_KEY="${PRIVATE_KEY:-}"
if [ -z "$PRIVATE_KEY" ]; then
@@ -41,6 +42,7 @@ forge script script/DeployMulticall.s.sol:DeployMulticall \
--rpc-url "$RPC_URL" \
--broadcast \
--private-key "$PRIVATE_KEY" \
--with-gas-price "$GAS_PRICE" \
--legacy -vvv 2>&1 | tail -30
# Phase 3: Oracle Contracts
@@ -51,6 +53,7 @@ forge script script/DeployOracle.s.sol:DeployOracle \
--rpc-url "$RPC_URL" \
--broadcast \
--private-key "$PRIVATE_KEY" \
--with-gas-price "$GAS_PRICE" \
--legacy -vvv 2>&1 | tail -30
# Phase 4: Governance Contracts
@@ -61,6 +64,7 @@ forge script script/DeployMultiSig.s.sol:DeployMultiSig \
--rpc-url "$RPC_URL" \
--broadcast \
--private-key "$PRIVATE_KEY" \
--with-gas-price "$GAS_PRICE" \
--legacy -vvv 2>&1 | tail -30
echo ""

View File

@@ -31,11 +31,13 @@ else
fi
# Configuration
# Use public RPC for broadcasting (Infura doesn't support private key transactions)
MAINNET_RPC="${MAINNET_RPC_URL:-https://eth.llamarpc.com}"
if [[ "$ETHEREUM_MAINNET_RPC" == *"infura.io"* ]]; then
log_warn "Note: Infura RPC doesn't support private key transactions, using public RPC"
MAINNET_RPC="https://eth.llamarpc.com"
# Use ETHEREUM_MAINNET_RPC; when Infura + INFURA_PROJECT_SECRET set, use Basic Auth URL for private key transactions
MAINNET_RPC="${MAINNET_RPC_URL:-${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}}"
if [[ "$MAINNET_RPC" == *"infura.io"* ]] && [[ -n "${INFURA_PROJECT_SECRET:-}" ]] && [[ ! "${INFURA_PROJECT_SECRET}" =~ \$\{ ]]; then
# Build Infura URL with Basic Auth so cast/forge can send transactions
[[ -f "$SCRIPT_DIR/../lib/infura.sh" ]] && source "$SCRIPT_DIR/../lib/infura.sh"
_with_auth=$(build_infura_rpc "mainnet" 2>/dev/null || true)
[[ -n "$_with_auth" ]] && MAINNET_RPC="$_with_auth" && log_info "Using Infura Mainnet RPC with Basic Auth"
fi
MAINNET_PRIVATE_KEY="${PRIVATE_KEY}"
MAINNET_CCIP_ROUTER="${MAINNET_CCIP_ROUTER:-0x80226fc0Ee2b096224EeAc085Bb9a8cba1146f7D}" # Official Chainlink CCIP Router

View File

@@ -0,0 +1,157 @@
#!/usr/bin/env bash
# Deploy to all mainnets: CCIP Bridge, Trustless Bridge, Oracle, Mapper, PMM (anchored to ChainID 138).
# Run after check-balances-gas-and-deploy.sh. Requires .env with PRIVATE_KEY and per-chain RPC/CCIP vars.
# Usage: bash scripts/deployment/deploy-all-mainnets-with-mapper-oracle-pmm.sh [phase]
# phase: ccip | trustless | oracle | mapper | pmm | all (default: all)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
# Load .env without strict unset (avoid init.sh pipefail on .env)
set +u
[ -f .env ] && source .env
set -u
[ -f "$SCRIPT_DIR/../lib/infura.sh" ] && source "$SCRIPT_DIR/../lib/infura.sh"
PHASE="${1:-all}"
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
require_env() {
local var="$1"
if [ -z "${!var:-}" ]; then
echo -e "${RED}ERROR: $var not set in .env${NC}" >&2
return 1
fi
return 0
}
ensure_rpc() {
local rpc="$1"
type ensure_infura_rpc_url &>/dev/null && [ -n "$rpc" ] && rpc=$(ensure_infura_rpc_url "$rpc")
echo "$rpc"
}
# --- CCIP: DeployAll to BSC, Polygon, Base, Optimism, Gnosis ---
run_ccip_remaining_mainnets() {
echo -e "${YELLOW}=== CCIP Bridges (DeployAll) to BSC, Polygon, Base, Optimism, Gnosis ===${NC}"
require_env PRIVATE_KEY || return 1
local chains="BSC:56:BSC_RPC_URL POLYGON:137:POLYGON_MAINNET_RPC BASE:8453:BASE_MAINNET_RPC OPTIMISM:10:OPTIMISM_MAINNET_RPC GNOSIS:100:GNOSIS_MAINNET_RPC"
for entry in $chains; do
local name="${entry%%:*}"; entry="${entry#*:}"
local chain_id="${entry%%:*}"; entry="${entry#*:}"
local rpc_var="$entry"
local rpc="${!rpc_var:-}"
rpc=$(ensure_rpc "$rpc")
if [ -z "$rpc" ]; then
echo " Skip $name (no RPC)"
continue
fi
echo -e "${YELLOW}DeployAll to $name (chain $chain_id)...${NC}"
forge script script/DeployAll.s.sol:DeployAll \
--rpc-url "$rpc" --chain-id "$chain_id" --private-key "$PRIVATE_KEY" \
--broadcast --slow -vvv || echo -e "${RED}$name DeployAll failed${NC}"
echo ""
done
echo -e "${GREEN}CCIP phase done.${NC}"
}
# --- Trustless Bridge: Chain 138 (Lockbox) + Ethereum (BondManager, etc.) ---
run_trustless() {
echo -e "${YELLOW}=== Trustless Bridge (Chain 138 + Ethereum) ===${NC}"
require_env PRIVATE_KEY RPC_URL_138 || return 1
echo "Deploying Trustless (Lockbox) on Chain 138..."
forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
--rpc-url "$RPC_URL_138" --broadcast --via-ir --private-key "$PRIVATE_KEY" -vvv || true
require_env ETHEREUM_MAINNET_RPC || return 1
MAINNET_RPC=$(ensure_rpc "$ETHEREUM_MAINNET_RPC")
echo "Deploying Trustless (BondManager, ChallengeManager, LP, Inbox, SwapRouter, Coordinator) on Ethereum..."
forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
--rpc-url "$MAINNET_RPC" --broadcast --via-ir --private-key "$PRIVATE_KEY" \
${ETHERSCAN_API_KEY:+--verify --etherscan-api-key "$ETHERSCAN_API_KEY"} -vvv || true
echo -e "${GREEN}Trustless phase done.${NC}"
}
# --- Oracle: Chain 138 ---
run_oracle() {
echo -e "${YELLOW}=== Oracle (Chain 138) ===${NC}"
require_env PRIVATE_KEY RPC_URL_138 || return 1
forge script script/DeployOracle.s.sol:DeployOracle \
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
--with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
echo -e "${GREEN}Oracle phase done.${NC}"
}
# --- Mapper: Chain 138 (full) + others (empty) ---
run_mapper() {
echo -e "${YELLOW}=== Mapper (Chain 138 = AddressMapper; others = AddressMapperEmpty) ===${NC}"
require_env PRIVATE_KEY || return 1
if [ -n "${RPC_URL_138:-}" ]; then
echo "Deploying AddressMapper on Chain 138..."
forge script script/DeployAddressMapper.s.sol:DeployAddressMapper \
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
--with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
fi
local chains="ETHEREUM_MAINNET_RPC:1 BSC_RPC_URL:56 POLYGON_MAINNET_RPC:137 BASE_MAINNET_RPC:8453 ARBITRUM_MAINNET_RPC:42161 OPTIMISM_MAINNET_RPC:10 AVALANCHE_RPC_URL:43114 CRONOS_RPC_URL:25 GNOSIS_MAINNET_RPC:100"
for entry in $chains; do
local rpc_var="${entry%%:*}"; local chain_id="${entry#*:}"
local rpc="${!rpc_var:-}"
[ -z "$rpc" ] && continue
rpc=$(ensure_rpc "$rpc")
echo "Deploying AddressMapperEmpty on chain $chain_id..."
forge script script/DeployAddressMapperOtherChain.s.sol:DeployAddressMapperOtherChain \
--rpc-url "$rpc" --chain-id "$chain_id" --broadcast --private-key "$PRIVATE_KEY" -vvv || true
done
echo -e "${GREEN}Mapper phase done.${NC}"
}
# --- PMM (DODO) on Chain 138 ---
run_pmm() {
echo -e "${YELLOW}=== PMM Liquidity Pools (Chain 138) ===${NC}"
require_env PRIVATE_KEY RPC_URL_138 || return 1
if [ -z "${DODO_PMM_INTEGRATION:-}" ] && [ -n "${DODO_VENDING_MACHINE_ADDRESS:-}" ]; then
echo "Deploying DODOPMMIntegration on Chain 138..."
forge script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
--with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
else
echo " DODOPMMIntegration already set or DODO_VENDING_MACHINE_ADDRESS not set; skip deploy."
fi
if [ -n "${DODO_PMM_INTEGRATION:-}" ] && [ -n "${XAU_ADDRESS:-}" ]; then
echo "Creating XAU-anchored pools..."
forge script script/dex/DeployPrivatePoolRegistryAndPools.s.sol:DeployPrivatePoolRegistryAndPools \
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
--with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
fi
echo -e "${GREEN}PMM phase done.${NC}"
}
# --- Main ---
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}All Mainnets: CCIP, Trustless, Oracle, Mapper, PMM${NC}"
echo -e "${GREEN}========================================${NC}"
echo "Phase: $PHASE"
echo ""
case "$PHASE" in
ccip) run_ccip_remaining_mainnets ;;
trustless) run_trustless ;;
oracle) run_oracle ;;
mapper) run_mapper ;;
pmm) run_pmm ;;
all)
run_ccip_remaining_mainnets
run_trustless
run_oracle
run_mapper
run_pmm
;;
*) echo "Usage: $0 [ccip|trustless|oracle|mapper|pmm|all]"; exit 1 ;;
esac
echo ""
echo -e "${GREEN}Done. Update .env and config/smart-contracts-master.json with any new addresses.${NC}"

View File

@@ -1,135 +1,115 @@
#!/bin/bash
#!/usr/bin/env bash
# Phased deployment for Chain 138: run each phase in order.
# Break-up of "deploy all" into discrete steps; skip phases that are already deployed (env set).
#
# Usage:
# ./scripts/deployment/deploy-all-phases.sh # run all phases (skip when env indicates done)
# ./scripts/deployment/deploy-all-phases.sh --all # run every phase (no skip)
# ./scripts/deployment/deploy-all-phases.sh --phase 5 # run only phase 5
# ./scripts/deployment/deploy-all-phases.sh --dry-run # print what would run
#
# Requires: .env with PRIVATE_KEY, RPC_URL_138 (Chain 138 Core). Uses --with-gas-price 1000000000 for Chain 138.
# Deploy All Phases
# This script orchestrates the complete deployment process
set -e
echo "=========================================="
echo " Trustless Bridge Complete Deployment"
echo "=========================================="
echo ""
# Load environment variables
if [ -f .env ]; then
export $(cat .env | grep -v '^#' | grep -v '^$' | xargs)
else
echo "Error: .env file not found"
echo "Please run phase1-env-setup.sh first"
exit 1
fi
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
echo "This will deploy all phases of the trustless bridge system."
echo ""
read -p "Continue? (y/N) " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Deployment cancelled"
exit 1
if [ -f .env ]; then
set -a
source .env
set +a
fi
echo ""
echo "Starting deployment..."
echo ""
RPC="${RPC_URL_138:-http://192.168.11.211:8545}"
GAS_PRICE="${GAS_PRICE_138:-1000000000}"
DRY_RUN=""
RUN_ALL="" # if set, do not skip any phase
PHASE_ONLY="" # if set, run only this phase number (e.g. 5)
# Phase 1: Environment Setup
echo ">>> Phase 1: Environment Setup"
"$SCRIPT_DIR/phase1-env-setup.sh" || exit 1
echo ""
while [ $# -gt 0 ]; do
case "$1" in
--dry-run) DRY_RUN=1 ;;
--all) RUN_ALL=1 ;;
--phase)
shift
[ $# -gt 0 ] && PHASE_ONLY="$1"
;;
esac
shift
done
# Phase 2: Deploy Core Contracts
echo ">>> Phase 2: Deploy Core Bridge Contracts"
read -p "Deploy core contracts? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase2-deploy-core.sh" || exit 1
echo ""
read -p "Press Enter after updating .env with contract addresses..."
if [ -z "${PRIVATE_KEY:-}" ]; then
echo "ERROR: PRIVATE_KEY not set in .env"
exit 1
fi
run_phase() {
local num="$1"
local name="$2"
local skip_var="$3" # optional: if set in env, skip (unless --all)
local cmd="$4"
if [ -n "$PHASE_ONLY" ] && [ "$PHASE_ONLY" != "$num" ]; then
return 0
fi
if [ -n "$skip_var" ] && [ -z "$RUN_ALL" ]; then
local val=""
eval "val=\"\${${skip_var}:-}\""
if [ -n "$val" ]; then
echo "[Phase $num] $name — SKIP (${skip_var} already set)"
return 0
fi
fi
echo "[Phase $num] $name — RUNNING"
if [ -n "$DRY_RUN" ]; then
echo " would run: $(echo "$cmd" | sed 's/--private-key "[^"]*"/--private-key ***REDACTED***/g')"
return 0
fi
eval "$cmd" || { echo "Phase $num failed."; exit 1; }
echo "[Phase $num] $name — DONE"
}
echo "============================================"
echo "Chain 138 — Phased deployment"
echo "RPC: $RPC"
echo "Gas price: $GAS_PRICE wei"
echo "============================================"
echo ""
# Phase 3: Deploy Enhanced Router
echo ">>> Phase 3: Deploy EnhancedSwapRouter"
read -p "Deploy EnhancedSwapRouter? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase3-deploy-router.sh" || exit 1
echo ""
read -p "Press Enter after updating .env with ENHANCED_SWAP_ROUTER address..."
fi
echo ""
# Phase 1: Phased core (registry + governance)
run_phase 1 "Phased core (01_DeployCore)" "UNIVERSAL_ASSET_REGISTRY" \
"forge script script/deploy/01_DeployCore.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 4: Deploy Integration Contracts
echo ">>> Phase 4: Deploy Integration Contracts"
read -p "Deploy integration contracts? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase4-deploy-integration.sh" || exit 1
echo ""
read -p "Press Enter after updating .env with integration contract addresses..."
fi
echo ""
# Phase 2: Phased bridges (CCIP bridge + orchestrator)
run_phase 2 "Phased bridges (02_DeployBridges)" "UNIVERSAL_CCIP_BRIDGE" \
"forge script script/deploy/02_DeployBridges.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 5: Initialize System
echo ">>> Phase 5: Initialize System"
read -p "Initialize system? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase5-initialize.sh" || exit 1
fi
echo ""
# Phase 3: Channel managers
run_phase 3 "PaymentChannelManager" "PAYMENT_CHANNEL_MANAGER" \
"forge script script/DeployPaymentChannelManager.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 6: Provide Liquidity
echo ">>> Phase 6: Provide Initial Liquidity"
read -p "Provide initial liquidity? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase6-provide-liquidity.sh" || exit 1
fi
echo ""
run_phase 3 "GenericStateChannelManager" "GENERIC_STATE_CHANNEL_MANAGER" \
"forge script script/DeployGenericStateChannelManager.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 7: Configure
echo ">>> Phase 7: Configure Access Control and Routing"
read -p "Configure access control and routing? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase7-configure.sh" || exit 1
fi
echo ""
# Phase 4: Deterministic core (CREATE2)
run_phase 4 "Deterministic core (DeployDeterministicCore)" "CREATE2_FACTORY" \
"forge script script/deploy/DeployDeterministicCore.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 8: Deploy Services
echo ">>> Phase 8: Deploy Backend Services"
read -p "Deploy backend services? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase8-deploy-services.sh" || exit 1
fi
echo ""
# Phase 5: Vault system
run_phase 5 "Vault system (DeployVaultSystem)" "VAULT_FACTORY" \
"forge script script/deploy/vault/DeployVaultSystem.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 9: Deploy Frontend
echo ">>> Phase 9: Deploy Frontend Applications"
read -p "Build frontend applications? (y/N) " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/phase9-deploy-frontend.sh" || exit 1
fi
echo ""
# Phase 6: Reserve system (requires TOKEN_FACTORY in .env)
run_phase 6 "Reserve system (DeployReserveSystem)" "RESERVE_SYSTEM" \
"forge script script/reserve/DeployReserveSystem.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 10: Verify
echo ">>> Phase 10: Verification"
"$SCRIPT_DIR/phase10-verify.sh" || exit 1
# Phase 7: Trustless bridge (Lockbox138 on Chain 138)
run_phase 7 "Trustless bridge (Lockbox138)" "LOCKBOX_138" \
"forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
echo ""
echo "=========================================="
echo " Deployment Complete!"
echo "=========================================="
echo ""
echo "Next steps:"
echo "1. Review deployment status"
echo "2. Set up monitoring dashboards"
echo "3. Configure alerts"
echo "4. Train operations team"
echo "5. Begin bridge operations"
echo ""
echo "============================================"
echo "Phased deployment finished."
echo "Update .env with any new addresses and run setCCIPRouter on deterministic bridge if Phase 4 ran."
echo "============================================"

View File

@@ -0,0 +1,104 @@
#!/usr/bin/env bash
# Deploy CCIP WETH9/WETH10 bridges on Gnosis, Cronos, Celo, Wemix (config-ready chains).
# Requires: PRIVATE_KEY in .env; per-chain RPC and gas (xDAI, CRO, CELO, WEMIX).
# Set CCIP_ROUTER_<CHAIN>, LINK_TOKEN_<CHAIN>; set WETH9_<CHAIN> and WETH10_<CHAIN> (native wrapped token on each chain, or deployment will fail).
# See docs/deployment/ENV_CONFIG_READY_CHAINS.example and docs/07-ccip/CONFIG_READY_CHAINS_COMPLETION_RUNBOOK.md.
#
# Usage: cd smom-dbis-138 && ./scripts/deployment/deploy-bridges-config-ready-chains.sh [gnosis|cronos|celo|wemix|all]
# PREFLIGHT=1 ... # run preflight first (default: 1)
# DRY_RUN=1 ... # print forge commands only, no deploy
# SIMULATE=1 ... # run forge without --broadcast (test script, no on-chain tx)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
[[ -f "$PROJECT_ROOT/.env" ]] && set -a && source "$PROJECT_ROOT/.env" && set +a
DRY_RUN="${DRY_RUN:-0}"
SIMULATE="${SIMULATE:-0}"
PREFLIGHT="${PREFLIGHT:-1}"
CHAIN="${1:-all}"
# Per-chain env for DeployWETHBridges: RPC_URL, CCIP_ROUTER_ADDRESS, LINK_TOKEN_ADDRESS, WETH9_ADDRESS, WETH10_ADDRESS (0x0 to skip)
run_deploy() {
local chain_name="$1"
local rpc_var="$2"
local router_var="$3"
local link_var="$4"
local weth9_var="$5"
local weth10_var="$6"
local rpc="${!rpc_var:-}"
local router="${!router_var:-}"
local link="${!link_var:-}"
local weth9="${!weth9_var:-}"
local weth10="${!weth10_var:-}"
if [[ -z "$rpc" || -z "$router" ]]; then
echo " Skip $chain_name: set ${rpc_var} and ${router_var} in .env"
return 0
fi
if [[ -z "${PRIVATE_KEY:-}" ]]; then
echo " Skip $chain_name: PRIVATE_KEY not set"
return 0
fi
if [[ -z "$weth9" || -z "$weth10" ]]; then
echo " Skip $chain_name: set ${weth9_var} and ${weth10_var} in .env (native wrapped token addresses from chain)"
return 0
fi
export RPC_URL="$rpc"
export CCIP_ROUTER_ADDRESS="$router"
export LINK_TOKEN_ADDRESS="${link:-0x0000000000000000000000000000000000000000}"
export WETH9_ADDRESS="$weth9"
export WETH10_ADDRESS="$weth10"
local broadcast="--broadcast"
[[ "$SIMULATE" == "1" ]] && broadcast=""
local cmd="forge script script/deploy/bridge/DeployWETHBridges.s.sol:DeployWETHBridges --rpc-url \"$RPC_URL\" $broadcast --legacy -vvvv"
if [[ "$DRY_RUN" == "1" ]]; then
echo " [DRY RUN] $chain_name: $cmd"
return 0
fi
if [[ "$SIMULATE" == "1" ]]; then
echo " Simulating deploy on $chain_name (no broadcast)..."
else
echo " Deploying bridges on $chain_name..."
fi
eval "$cmd" || { echo " Failed (non-fatal)"; return 0; }
echo " Set CCIPWETH9_BRIDGE_${chain_name^^} and CCIPWETH10_BRIDGE_${chain_name^^} in .env from script output."
}
# Preflight (RPC + gas balance check)
if [[ "$PREFLIGHT" == "1" && "$DRY_RUN" != "1" ]]; then
if ! "$SCRIPT_DIR/preflight-config-ready-chains.sh" "$CHAIN" 2>/dev/null; then
echo ""
echo "Preflight failed. Fix RPCs and gas balances, or run with PREFLIGHT=0 to skip."
exit 1
fi
echo ""
fi
echo "=== Deploy CCIP bridges (Gnosis, Cronos, Celo, Wemix) ==="
echo " DRY_RUN=$DRY_RUN SIMULATE=$SIMULATE PREFLIGHT=$PREFLIGHT CHAIN=$CHAIN"
echo " Gas tokens: Gnosis=xDAI, Cronos=CRO, Celo=CELO, Wemix=WEMIX"
echo ""
case "$CHAIN" in
gnosis) run_deploy "GNOSIS" "GNOSIS_RPC" "CCIP_ROUTER_GNOSIS" "LINK_TOKEN_GNOSIS" "WETH9_GNOSIS" "WETH10_GNOSIS" ;;
cronos) run_deploy "CRONOS" "CRONOS_RPC" "CCIP_ROUTER_CRONOS" "LINK_TOKEN_CRONOS" "WETH9_CRONOS" "WETH10_CRONOS" ;;
celo) run_deploy "CELO" "CELO_RPC" "CCIP_ROUTER_CELO" "LINK_TOKEN_CELO" "WETH9_CELO" "WETH10_CELO" ;;
wemix) run_deploy "WEMIX" "WEMIX_RPC" "CCIP_ROUTER_WEMIX" "LINK_TOKEN_WEMIX" "WETH9_WEMIX" "WETH10_WEMIX" ;;
all)
run_deploy "GNOSIS" "GNOSIS_RPC" "CCIP_ROUTER_GNOSIS" "LINK_TOKEN_GNOSIS" "WETH9_GNOSIS" "WETH10_GNOSIS"
run_deploy "CRONOS" "CRONOS_RPC" "CCIP_ROUTER_CRONOS" "LINK_TOKEN_CRONOS" "WETH9_CRONOS" "WETH10_CRONOS"
run_deploy "CELO" "CELO_RPC" "CCIP_ROUTER_CELO" "LINK_TOKEN_CELO" "WETH9_CELO" "WETH10_CELO"
run_deploy "WEMIX" "WEMIX_RPC" "CCIP_ROUTER_WEMIX" "LINK_TOKEN_WEMIX" "WETH9_WEMIX" "WETH10_WEMIX"
;;
*) echo "Usage: $0 [gnosis|cronos|celo|wemix|all]"; exit 1 ;;
esac
echo ""
echo "Next: Add deployed bridge addresses to .env (CCIPWETH9_BRIDGE_*, CCIPWETH10_BRIDGE_*), then run complete-config-ready-chains.sh"

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Deploy CCIPLogger to all configured chains (mainnet, BSC, Polygon, Gnosis, Cronos) via Hardhat.
# Requires: from smom-dbis-138 run `pnpm install` or `npm install` so Hardhat resolves locally; .env with PRIVATE_KEY and per-chain RPC.
# Usage: cd smom-dbis-138 && ./scripts/deployment/deploy-ccip-logger-all-chains.sh
# CHAINS="mainnet bsc" ./scripts/deployment/deploy-ccip-logger-all-chains.sh # only mainnet and bsc
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
if [[ -f .env ]]; then
set -a
source .env
set +a
fi
CHAINS="${CHAINS:-mainnet bsc polygon gnosis cronos}"
if ! command -v npx &>/dev/null; then
echo "npx not found. Install Node/npm and run: npm install" >&2
exit 1
fi
echo "Deploying CCIPLogger to: $CHAINS"
for net in $CHAINS; do
echo ""
echo "=== $net ==="
case "$net" in
mainnet) npm run deploy:logger:mainnet 2>&1 || echo " Failed (non-fatal)" ;;
bsc) NETWORK=bsc npx hardhat run scripts/ccip-deployment/deploy-ccip-logger-multichain.js --network bsc 2>&1 || echo " Failed (non-fatal)" ;;
polygon) npm run deploy:logger:polygon 2>&1 || echo " Failed (non-fatal)" ;;
gnosis) npm run deploy:logger:gnosis 2>&1 || echo " Failed (non-fatal)" ;;
cronos) npm run deploy:logger:cronos 2>&1 || echo " Failed (non-fatal)" ;;
*) echo " Unknown network: $net" ;;
esac
done
echo ""
echo "Done. Update .env with CCIP_LOGGER_* addresses per chain if deployed."

View File

@@ -87,8 +87,8 @@ fi
# Verify RPC endpoint
log_info "Verifying RPC endpoint..."
if ! curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' > /dev/null 2>&1; then
log_error "Error: RPC endpoint is not accessible"
if ! curl -s -m 10 -X POST "$RPC_URL" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' > /dev/null 2>&1; then
log_error "Error: RPC endpoint is not accessible at $RPC_URL"
exit 1
fi

View File

@@ -0,0 +1,84 @@
#!/usr/bin/env bash
# Deploy CompliantUSDT and CompliantUSDC to each target chain (Ethereum, BSC, Polygon, Base, etc.).
# Uses smom-dbis-138/.env. Requires per-chain RPC and PRIVATE_KEY with gas on each chain.
# Output: suggested .env lines for CUSDT_ADDRESS_<chainId> and CUSDC_ADDRESS_<chainId>.
# See docs/deployment/CUSDT_CUSDC_MULTICHAIN_LIQUIDITY_RUNBOOK.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DOTENV="$REPO_ROOT/.env"
cd "$REPO_ROOT"
if [[ -f "$DOTENV" ]]; then set -a; source "$DOTENV"; set +a; fi
# Chain name : chain_id : RPC env var name
CHAINS=(
"ETHEREUM:1:ETHEREUM_MAINNET_RPC"
"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"
"CELO:42220:CELO_MAINNET_RPC"
"WEMIX:1111:WEMIX_MAINNET_RPC"
)
FILTER="${DEPLOY_CUSDT_CUSDC_FILTER:-}"
DRY_RUN="${DEPLOY_CUSDT_CUSDC_DRY_RUN:-}"
for entry in "${CHAINS[@]}"; do
IFS=: read -r name chain_id rpc_var <<< "$entry"
if [[ -n "$FILTER" ]] && [[ " $FILTER " != *" $name "* ]]; then continue; fi
rpc="${!rpc_var:-}"
if [[ -z "$rpc" ]]; then
echo "Skip $name (chain $chain_id): $rpc_var not set"
continue
fi
echo "=== $name (chain $chain_id) ==="
if [[ -n "$DRY_RUN" ]]; then
echo "[DRY RUN] Would deploy CompliantUSDT and CompliantUSDC on $name via $rpc_var"
continue
fi
CUSDT=""
CUSDC=""
log_usdt="/tmp/cusdt-deploy-$chain_id.log"
log_usdc="/tmp/cusdc-deploy-$chain_id.log"
if forge script script/DeployCompliantUSDT.s.sol:DeployCompliantUSDT \
--rpc-url "$rpc" \
--chain-id "$chain_id" \
--broadcast \
--private-key "${PRIVATE_KEY:?PRIVATE_KEY required}" \
-vv 2>&1 | tee "$log_usdt"; then
CUSDT=$(grep -oE "CompliantUSDT deployed at: 0x[a-fA-F0-9]{40}" "$log_usdt" | tail -1 | awk '{print $NF}')
fi
if [[ -z "$CUSDT" ]]; then
echo "Warning: CompliantUSDT deploy failed or address not found on $name"
else
echo "CUSDT_ADDRESS_${chain_id}=$CUSDT"
fi
if forge script script/DeployCompliantUSDC.s.sol:DeployCompliantUSDC \
--rpc-url "$rpc" \
--chain-id "$chain_id" \
--broadcast \
--private-key "${PRIVATE_KEY:?PRIVATE_KEY required}" \
-vv 2>&1 | tee "$log_usdc"; then
CUSDC=$(grep -oE "CompliantUSDC deployed at: 0x[a-fA-F0-9]{40}" "$log_usdc" | tail -1 | awk '{print $NF}')
fi
if [[ -z "$CUSDC" ]]; then
echo "Warning: CompliantUSDC deploy failed or address not found on $name"
else
echo "CUSDC_ADDRESS_${chain_id}=$CUSDC"
fi
echo ""
done
echo "Done. Add the printed CUSDT_ADDRESS_<id> and CUSDC_ADDRESS_<id> lines to .env."
echo "See docs/deployment/CUSDT_CUSDC_MULTICHAIN_LIQUIDITY_RUNBOOK.md for next steps (PMM, Uniswap, Balancer, Curve)."

View File

@@ -0,0 +1,182 @@
#!/usr/bin/env bash
# Create LXC 5801 (dapp-smom): frontend-dapp build served by nginx.
# Usage: ./scripts/deployment/deploy-dapp-lxc.sh [--dry-run] [--skip-create]
# --dry-run Print commands only.
# --skip-create Use existing container 5801 (only install/build/serve).
# Env: PROXMOX_HOST (optional; if unset, run pct on current host), NODE (optional; pct --node),
# VMID, HOSTNAME, IP_DAPP_LXC, TEMPLATE, STORAGE, NETWORK, MEMORY_MB, CORES, DISK_GB,
# REPO_URL (git URL to clone) or REPO_PATH (local path to copy; no git in container),
# ENV_FILE (path to .env for VITE_*).
# See: docs/03-deployment/DAPP_LXC_DEPLOYMENT.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SMOM_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Robust ip-addresses.conf path: override, or proxmox repo layout, or smom-dbis-138-only layout
IP_CONFIG_PATH="${IP_CONFIG_PATH:-}"
if [[ -n "$IP_CONFIG_PATH" && -f "$IP_CONFIG_PATH" ]]; then
source "$IP_CONFIG_PATH" 2>/dev/null || true
elif [[ -f "${SMOM_ROOT}/../../config/ip-addresses.conf" ]]; then
source "${SMOM_ROOT}/../../config/ip-addresses.conf" 2>/dev/null || true
elif [[ -f "${SCRIPT_DIR}/../../../config/ip-addresses.conf" ]]; then
source "${SCRIPT_DIR}/../../../config/ip-addresses.conf" 2>/dev/null || true
fi
VMID="${VMID:-5801}"
HOSTNAME="${HOSTNAME:-dapp-smom}"
IP="${IP_DAPP_LXC:-192.168.11.58}"
GATEWAY="${NETWORK_GATEWAY:-192.168.11.1}"
NETWORK="${NETWORK:-vmbr0}"
STORAGE="${STORAGE:-local-lvm}"
TEMPLATE="${TEMPLATE:-local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst}"
MEMORY_MB="${MEMORY_MB:-6144}"
CORES="${CORES:-4}"
DISK_GB="${DISK_GB:-40}"
REPO_URL="${REPO_URL:-}"
REPO_PATH="${REPO_PATH:-}"
ENV_FILE="${ENV_FILE:-}"
PROXMOX_HOST="${PROXMOX_HOST:-}"
NODE="${NODE:-}"
SSH_OPTS="-o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
DRY_RUN=false
SKIP_CREATE=false
for a in "$@"; do
[[ "$a" == "--dry-run" ]] && DRY_RUN=true
[[ "$a" == "--skip-create" ]] && SKIP_CREATE=true
done
run_cmd() {
if [[ -n "$PROXMOX_HOST" ]]; then
ssh $SSH_OPTS root@"$PROXMOX_HOST" "$@"
else
bash -c "$*"
fi
}
run_pct() {
local node_opt=""
[[ -n "$NODE" && -z "$PROXMOX_HOST" ]] && node_opt="--node $NODE"
if [[ -n "$PROXMOX_HOST" ]]; then
ssh $SSH_OPTS root@"$PROXMOX_HOST" "pct $node_opt $*"
else
pct $node_opt "$@"
fi
}
pct_exec() {
run_pct "exec $VMID -- $*"
}
echo "=== DApp LXC ($VMID) — $HOSTNAME ==="
echo "IP: $IP | Memory: ${MEMORY_MB}MB | Cores: $CORES | Disk: ${DISK_GB}G"
echo ""
if ! $SKIP_CREATE; then
if $DRY_RUN; then
echo "[DRY-RUN] Would create LXC $VMID on ${PROXMOX_HOST:-local} with hostname=$HOSTNAME, ip=$IP/24"
exit 0
fi
if run_pct list 2>/dev/null | grep -q " $VMID "; then
echo "Container $VMID already exists. Use --skip-create to only install/build/serve."
exit 0
fi
echo "Creating CT $VMID ($HOSTNAME)..."
# When PROXMOX_HOST is set we SSH to that host; do not pass --node (pct runs on that node).
node_opt=""
[[ -n "$NODE" && -z "$PROXMOX_HOST" ]] && node_opt="--node $NODE"
run_cmd "pct create $VMID $TEMPLATE \
--hostname $HOSTNAME \
--memory $MEMORY_MB \
--cores $CORES \
--rootfs $STORAGE:${DISK_GB} \
--net0 name=eth0,bridge=$NETWORK,ip=$IP/24,gw=$GATEWAY \
--nameserver ${DNS_PRIMARY:-1.1.1.1} \
--description 'DApp (frontend-dapp) for Chain 138 bridge. See docs/03-deployment/DAPP_LXC_DEPLOYMENT.md' \
--start 1 \
--onboot 1 \
--unprivileged 0 \
--features nesting=1 \
$node_opt"
echo "Waiting for container to boot..."
sleep 20
fi
if $DRY_RUN; then
echo "[DRY-RUN] Would install Node, nginx, clone repo, build, configure nginx."
exit 0
fi
echo "Installing Node 20, nginx, git, curl..."
pct_exec "bash -c 'export DEBIAN_FRONTEND=noninteractive && apt-get update -qq && apt-get install -y -qq curl git ca-certificates'"
pct_exec "bash -c 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y -qq nodejs'"
pct_exec "apt-get install -y -qq nginx"
if [[ -z "$REPO_URL" && -z "$REPO_PATH" ]]; then
echo "Neither REPO_URL nor REPO_PATH set. Skipping clone/copy and build."
echo "Example: REPO_URL=https://github.com/your-org/smom-dbis-138.git ... or REPO_PATH=/path/to/smom-dbis-138 ... ./scripts/deployment/deploy-dapp-lxc.sh --skip-create"
exit 0
fi
APP_DIR="/srv/smom-dbis-138"
pct_exec "mkdir -p $APP_DIR"
if [[ -n "$REPO_PATH" && -d "$REPO_PATH" ]]; then
echo "Copying repo from host ($REPO_PATH)..."
PARENT="$(cd "$(dirname "$REPO_PATH")" && pwd)"
BARE="$(basename "$REPO_PATH")"
TARNAME="smom-dbis-138-deploy.tar.gz"
TARBALL="/tmp/$TARNAME"
(cd "$PARENT" && tar czf "$TARBALL" --exclude="$BARE/node_modules" --exclude="$BARE/.git" --exclude="$BARE/frontend-dapp/node_modules" --exclude="$BARE/frontend-dapp/dist" "$BARE") || { echo "Failed to create tarball"; exit 1; }
if [[ -n "$PROXMOX_HOST" ]]; then
scp $SSH_OPTS "$TARBALL" root@"$PROXMOX_HOST":/tmp/
run_cmd "pct push $VMID /tmp/$TARNAME /tmp/$TARNAME"
pct_exec "bash -c 'rm -rf $APP_DIR && mkdir -p /srv && tar xzf /tmp/$TARNAME -C /srv && rm /tmp/$TARNAME'"
run_cmd "rm -f /tmp/$TARNAME"
else
run_pct push "$VMID" "$TARBALL" "/tmp/$TARNAME"
pct_exec "bash -c 'rm -rf $APP_DIR && mkdir -p /srv && tar xzf /tmp/$TARNAME -C /srv && rm /tmp/$TARNAME'"
fi
rm -f "$TARBALL"
elif [[ -n "$REPO_URL" ]]; then
echo "Cloning repo..."
pct_exec "bash -c 'if [ -d $APP_DIR/.git ]; then (cd $APP_DIR && git fetch && git reset --hard origin/HEAD); else git clone --depth 1 $REPO_URL $APP_DIR; fi'"
fi
if [[ -n "$ENV_FILE" && -f "$ENV_FILE" ]]; then
if [[ -n "$PROXMOX_HOST" ]]; then
REMOTE_ENV="/tmp/dapp-deploy-$$.env"
echo "Copying .env to Proxmox host and pushing into container..."
scp $SSH_OPTS "$ENV_FILE" root@"$PROXMOX_HOST":"$REMOTE_ENV" && \
run_pct push "$VMID" "$REMOTE_ENV" "$APP_DIR/.env" 2>/dev/null || true
run_cmd "rm -f $REMOTE_ENV" 2>/dev/null || true
else
run_pct push "$VMID" "$ENV_FILE" "$APP_DIR/.env" 2>/dev/null || true
fi
fi
echo "Building frontend-dapp..."
pct_exec "bash -c 'cd $APP_DIR/frontend-dapp && (test -f package-lock.json && npm ci || npm install) && npm run build'"
echo "Configuring nginx to serve dist..."
pct_exec "bash -c 'cat > /etc/nginx/sites-available/dapp <<\"NGINXEOF\"
server {
listen 80 default_server;
listen [::]:80 default_server;
root /srv/smom-dbis-138/frontend-dapp/dist;
index index.html;
server_name _;
include /srv/smom-dbis-138/frontend-dapp/nginx-dapp-snippet.conf;
location / {
try_files \$uri \$uri/ /index.html;
}
}
NGINXEOF
rm -f /etc/nginx/sites-enabled/default && ln -sf /etc/nginx/sites-available/dapp /etc/nginx/sites-enabled/dapp && nginx -t && systemctl reload nginx'"
echo "Done. DApp LXC $VMID ($HOSTNAME) is serving at http://$IP"
echo "Add NPMplus proxy host (e.g. dapp.d-bis.org) pointing to $IP:80. See docs/03-deployment/DAPP_LXC_DEPLOYMENT.md"

View File

@@ -0,0 +1,110 @@
#!/usr/bin/env bash
# Full parity: Mapper + Oracle on ALL bridge networks.
# Extends deploy-all-mainnets-with-mapper-oracle-pmm.sh with Celo, Wemix, and Oracle-on-all-chains.
# Usage: bash scripts/deployment/deploy-full-parity-all-chains.sh [phase] [--dry-run]
# phase: mapper | oracle | bridges | all (default: all)
# --dry-run Print commands only
# Requires: .env with PRIVATE_KEY and per-chain RPC vars (GNOSIS_RPC, CELO_RPC, WEMIX_RPC, etc.)
# See: docs/07-ccip/FULL_PARITY_RUNBOOK.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
set +u
[ -f .env ] && source .env
set -u
[ -f "$SCRIPT_DIR/../lib/infura.sh" ] && source "$SCRIPT_DIR/../lib/infura.sh"
PHASE="${1:-all}"
DRY_RUN=false
for a in "$@"; do [[ "$a" == "--dry-run" ]] && DRY_RUN=true; done
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
ensure_rpc() {
local rpc="$1"
type ensure_infura_rpc_url &>/dev/null && [ -n "$rpc" ] && rpc=$(ensure_infura_rpc_url "$rpc")
echo "$rpc"
}
run_or_echo() {
if $DRY_RUN; then
echo " [DRY RUN] $*"
else
eval "$@" || echo -e "${RED} Failed${NC}"
fi
}
# --- Mapper: all chains including Celo, Wemix ---
run_mapper() {
echo -e "${YELLOW}=== Full Parity: Mapper (AddressMapperEmpty) on ALL bridge chains ===${NC}"
[ -z "${PRIVATE_KEY:-}" ] && { echo -e "${RED}PRIVATE_KEY not set${NC}"; return 1; }
# RPC_VAR:CHAIN_ID — include Celo, Wemix
local chains="ETHEREUM_MAINNET_RPC:1 BSC_RPC_URL:56 POLYGON_MAINNET_RPC:137 BASE_MAINNET_RPC:8453 ARBITRUM_MAINNET_RPC:42161 OPTIMISM_MAINNET_RPC:10 AVALANCHE_RPC_URL:43114 CRONOS_RPC_URL:25 GNOSIS_RPC:100 CELO_RPC:42220 WEMIX_RPC:1111"
for entry in $chains; do
local rpc_var="${entry%%:*}"; local chain_id="${entry#*:}"
local rpc="${!rpc_var:-}"
[ -z "$rpc" ] && echo " Skip chain $chain_id ($rpc_var not set)" && continue
rpc=$(ensure_rpc "$rpc")
echo " Deploying AddressMapperEmpty on chain $chain_id ($rpc_var)..."
local gas_opts=""
[ "$chain_id" = "138" ] && gas_opts="--with-gas-price ${GAS_PRICE_138:-1000000000} --legacy"
run_or_echo "forge script script/DeployAddressMapperOtherChain.s.sol:DeployAddressMapperOtherChain --rpc-url \"$rpc\" --chain-id \"$chain_id\" --broadcast --private-key \"\$PRIVATE_KEY\" $gas_opts -vvv"
done
echo -e "${GREEN}Mapper phase done. Record addresses in config.${NC}"
}
# --- Oracle: all chains ---
run_oracle() {
echo -e "${YELLOW}=== Full Parity: Oracle (Aggregator+Proxy) on ALL bridge chains ===${NC}"
[ -z "${PRIVATE_KEY:-}" ] && { echo -e "${RED}PRIVATE_KEY not set${NC}"; return 1; }
local chains="RPC_URL_138:138 ETHEREUM_MAINNET_RPC:1 BSC_RPC_URL:56 POLYGON_MAINNET_RPC:137 BASE_MAINNET_RPC:8453 ARBITRUM_MAINNET_RPC:42161 OPTIMISM_MAINNET_RPC:10 AVALANCHE_RPC_URL:43114 CRONOS_RPC_URL:25 GNOSIS_RPC:100 CELO_RPC:42220 WEMIX_RPC:1111"
for entry in $chains; do
local rpc_var="${entry%%:*}"; local chain_id="${entry#*:}"
local rpc="${!rpc_var:-}"
[ -z "$rpc" ] && echo " Skip chain $chain_id ($rpc_var not set)" && continue
rpc=$(ensure_rpc "$rpc")
echo " Deploying Oracle on chain $chain_id ($rpc_var)..."
local gas_opts=""
[ "$chain_id" = "138" ] && gas_opts="--with-gas-price ${GAS_PRICE_138:-1000000000} --legacy"
run_or_echo "forge script script/DeployOracle.s.sol:DeployOracle --rpc-url \"$rpc\" --broadcast --private-key \"\$PRIVATE_KEY\" $gas_opts -vvv"
done
echo -e "${GREEN}Oracle phase done. Record Aggregator+Proxy addresses in config.${NC}"
}
# --- Bridges: Celo, Wemix (when funded) ---
run_bridges() {
echo -e "${YELLOW}=== Full Parity: CCIP Bridges on Celo, Wemix ===${NC}"
[ -z "${PRIVATE_KEY:-}" ] && { echo -e "${RED}PRIVATE_KEY not set${NC}"; return 1; }
run_or_echo "bash scripts/deployment/deploy-bridges-config-ready-chains.sh celo"
run_or_echo "bash scripts/deployment/deploy-bridges-config-ready-chains.sh wemix"
echo " Run complete-config-ready-chains.sh after recording bridge addresses in .env"
echo -e "${GREEN}Bridges phase done.${NC}"
}
# --- Main ---
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Full Parity: Mapper, Oracle, AMB on All Bridge Networks${NC}"
echo -e "${GREEN}========================================${NC}"
echo "Phase: $PHASE Dry-run: $DRY_RUN"
echo ""
case "$PHASE" in
mapper) run_mapper ;;
oracle) run_oracle ;;
bridges) run_bridges ;;
all)
run_bridges
run_mapper
run_oracle
;;
*) echo "Usage: $0 [mapper|oracle|bridges|all] [--dry-run]"; exit 1 ;;
esac
echo ""
echo -e "${GREEN}Done. Update .env and config with new addresses. See docs/07-ccip/FULL_PARITY_RUNBOOK.md${NC}"

View File

@@ -49,7 +49,7 @@ if ! cast block-number --rpc-url "$ETHEREUM_MAINNET_RPC" >/dev/null 2>&1; then
echo ""
echo "Please fix the Infura RPC configuration:"
echo " 1. Go to https://infura.io/"
echo " 2. Project ID: 43b945b33d58463a9246cf5ca8aa6286"
echo " 2. Project ID: (set in .env as INFURA_PROJECT_ID; use INFURA_PROJECT_SECRET for Basic Auth)"
echo " 3. Settings → Disable 'Private Key Only'"
echo " 4. Save and run this script again"
echo ""

View File

@@ -0,0 +1,84 @@
#!/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
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DODO_DIR="$PROJECT_ROOT/lib/dodo-contractV2"
cd "$PROJECT_ROOT"
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}"
# 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) || true
echo "=== Running Truffle migration 9 (DVM stack) on Chain 138 ==="
(cd "$DODO_DIR" && npx truffle migrate -f 9 --to 9 --network chain138)
# 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=<dvm_factory_address> 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_ADDRESS=$(grep -o '"contractAddress":"0x[^"]*"' "$PROJECT_ROOT/broadcast/DeployDVMFactoryAdapter.s.sol/138/"*run-latest.json 2>/dev/null | tail -1 | sed 's/.*"0x/0x/;s/".*//') || 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."

View File

@@ -0,0 +1,141 @@
#!/usr/bin/env bash
# Deployments — Chain 138 and multichain (nothing optional nor future; these are planned deployments).
# Usage:
# ./scripts/deployment/deploy-optional-future-all.sh # run all phases
# ./scripts/deployment/deploy-optional-future-all.sh --dry-run # print only
# ./scripts/deployment/deploy-optional-future-all.sh --phases 1,3,5 # run phases 1,3,5
#
# Requires: .env with PRIVATE_KEY, RPC_URL_138. Chain 138: --with-gas-price (default 2 gwei).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
if [ -f .env ]; then
set -a
source .env
set +a
fi
RPC="${RPC_URL_138:-http://192.168.11.211:8545}"
# Default 2 gwei to reduce "Replacement transaction underpriced"; override with GAS_PRICE_138.
GAS_PRICE="${GAS_PRICE_138:-2000000000}"
DRY_RUN=""
PHASES="" # comma-separated, e.g. 1,3,5
while [ $# -gt 0 ]; do
case "$1" in
--dry-run) DRY_RUN=1 ;;
--phases)
shift
[ $# -gt 0 ] && PHASES="$1"
;;
esac
shift
done
if [ -z "${PRIVATE_KEY:-}" ]; then
echo "ERROR: PRIVATE_KEY not set in .env"
exit 1
fi
# run_phase num name skip_var cmd [required_var]
# If required_var is set and skip_var is not set, requires that required_var is non-empty in env; else skips with message.
run_phase() {
local num="$1"
local name="$2"
local skip_var="$3"
local cmd="$4"
local required_var="${5:-}"
if [ -n "$PHASES" ]; then
if ! echo ",$PHASES," | grep -q ",$num,"; then
return 0
fi
fi
if [ -n "$skip_var" ]; then
local val=""
eval "val=\"\${${skip_var}:-}\""
if [ -n "$val" ]; then
echo "[Phase $num] $name — SKIP (${skip_var} already set)"
return 0
fi
fi
if [ -n "$required_var" ]; then
local req_val=""
eval "req_val=\"\${${required_var}:-}\""
if [ -z "$req_val" ]; then
echo "[Phase $num] $name — SKIP (set ${required_var} in .env to run; or set ${skip_var} to skip)"
return 0
fi
fi
echo "[Phase $num] $name — RUNNING"
if [ -n "$DRY_RUN" ]; then
echo " would run: $(echo "$cmd" | sed 's/--private-key "[^"]*"/--private-key ***REDACTED***/g')"
return 0
fi
eval "$cmd" || { echo "Phase $num failed."; exit 1; }
echo "[Phase $num] $name — DONE"
}
echo "============================================"
echo "Deployments — Chain 138 and multichain"
echo "RPC: $RPC"
echo "Gas price: $GAS_PRICE wei"
echo "============================================"
echo ""
# Phase 1: CREATE2 / Deterministic core
run_phase 1 "Deterministic core (DeployDeterministicCore)" "CREATE2_FACTORY" \
"forge script script/deploy/DeployDeterministicCore.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 2: Vault system
run_phase 2 "Vault system (DeployVaultSystem)" "VAULT_FACTORY" \
"forge script script/deploy/vault/DeployVaultSystem.s.sol:DeployVaultSystem --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 3: Reserve system (requires TOKEN_FACTORY)
run_phase 3 "Reserve system (DeployReserveSystem)" "RESERVE_SYSTEM" \
"forge script script/reserve/DeployReserveSystem.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 4: Reserve Keeper (requires ORACLE_PRICE_FEED unless RESERVE_KEEPER already set)
run_phase 4 "Reserve Keeper (DeployKeeper)" "RESERVE_KEEPER" \
"forge script script/reserve/DeployKeeper.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\"" \
"ORACLE_PRICE_FEED"
# Phase 5: PaymentChannelManager + GenericStateChannelManager
run_phase 5a "PaymentChannelManager" "PAYMENT_CHANNEL_MANAGER" \
"forge script script/DeployPaymentChannelManager.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
run_phase 5b "GenericStateChannelManager" "GENERIC_STATE_CHANNEL_MANAGER" \
"forge script script/DeployGenericStateChannelManager.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 6: Trustless bridge (Lockbox138 on Chain 138)
run_phase 6 "Trustless bridge (Lockbox138)" "LOCKBOX_138" \
"forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 7: DODO / Swap (requires DODO_VENDING_MACHINE_ADDRESS, COMPLIANT_USDT_ADDRESS, COMPLIANT_USDC_ADDRESS)
run_phase 7 "DODO PMM Integration" "DODOPMM_INTEGRATION_ADDRESS" \
"forge script script/dex/DeployDODOPMMIntegration.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\"" \
"DODO_VENDING_MACHINE_ADDRESS"
# Phase 8: eMoney (Chain 138)
run_phase 8 "eMoney (DeployChain138)" "TOKEN_FACTORY_138" \
"forge script script/emoney/DeployChain138.s.sol:DeployChain138 --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
# Phase 9: Smart accounts (informational — actual deploy from ERC-4337 impl)
run_phase 9 "Smart accounts kit (informational)" "" \
"forge script script/smart-accounts/DeploySmartAccountsKit.s.sol --rpc-url \"$RPC\" --broadcast --private-key \"$PRIVATE_KEY\" --with-gas-price \"$GAS_PRICE\""
echo ""
echo "============================================"
echo "Deployments finished."
echo "Update .env with new addresses."
echo "DeployAll (mainnet/multichain): run script/DeployAll.s.sol per chain."
echo "Trustless bridge Mainnet: run DeployTrustlessBridge with MAINNET_RPC."
echo "See docs/03-deployment/OPTIONAL_FUTURE_DEPLOYMENTS_RUNBOOK.md"
echo "============================================"

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
# Deploy DODOPMMIntegration on each L2 (BSC, Polygon, Base, Optimism, Arbitrum, Avalanche, Cronos, Gnosis).
# Uses .env for RPC and token addresses. Chains via tag: --chain bsc polygon ... (or DEPLOY_PMM_L2S_FILTER in .env).
# Usage: ./scripts/deployment/deploy-pmm-all-l2s.sh [--chain bsc polygon base]
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"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
parse_chain_filter "$@"
if [[ ${#CHAIN_FILTER[@]} -eq 0 && -n "${DEPLOY_PMM_L2S_FILTER:-}" ]]; then
CHAIN_FILTER=()
for n in $DEPLOY_PMM_L2S_FILTER; do n="$(normalize_chain_name "$n")"; [[ -n "$n" ]] && CHAIN_FILTER+=("$n"); done
fi
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"
)
for entry in "${CHAINS[@]}"; do
IFS=: read -r name chain_id rpc_var <<< "$entry"
if [[ ${#CHAIN_FILTER[@]} -gt 0 ]] && [[ ! " ${CHAIN_FILTER[*]} " =~ " $name " ]]; then continue; fi
rpc="${!rpc_var:-}"
if [[ -z "$rpc" ]]; then
echo "Skip $name (chain $chain_id): $rpc_var not set"
continue
fi
# Prefer chain-prefixed DVM and tokens; fallback to global
dvm_var="${name}_DODO_VENDING_MACHINE_ADDRESS"
usdt_var="${name}_OFFICIAL_USDT_ADDRESS"
usdc_var="${name}_OFFICIAL_USDC_ADDRESS"
cusdt_var="${name}_COMPLIANT_USDT_ADDRESS"
cusdc_var="${name}_COMPLIANT_USDC_ADDRESS"
# Per-chain cUSDT/cUSDC (optional): CUSDT_ADDRESS_<chainId> / CUSDC_ADDRESS_<chainId> or POLYGON_COMPLIANT_USDT_ADDRESS etc.
cusdt_chain="CUSDT_ADDRESS_${chain_id}"
cusdc_chain="CUSDC_ADDRESS_${chain_id}"
dvm="${!dvm_var:-$DODO_VENDING_MACHINE_ADDRESS}"
usdt="${!usdt_var:-$OFFICIAL_USDT_ADDRESS}"
usdc="${!usdc_var:-$OFFICIAL_USDC_ADDRESS}"
compliant_usdt="${!cusdt_var:-${!cusdt_chain:-$usdt}}"
compliant_usdc="${!cusdc_var:-${!cusdc_chain:-$usdc}}"
if [[ -z "$dvm" ]] || [[ -z "$usdt" ]] || [[ -z "$usdc" ]]; then
echo "Skip $name: set ${dvm_var} (or DODO_VENDING_MACHINE_ADDRESS), ${usdt_var}, ${usdc_var} (or OFFICIAL_USDT/USDC_ADDRESS)"
continue
fi
echo "=== Deploying DODOPMMIntegration on $name (chain $chain_id) ==="
DODO_VENDING_MACHINE_ADDRESS="$dvm" \
OFFICIAL_USDT_ADDRESS="$usdt" \
OFFICIAL_USDC_ADDRESS="$usdc" \
COMPLIANT_USDT_ADDRESS="$compliant_usdt" \
COMPLIANT_USDC_ADDRESS="$compliant_usdc" \
forge script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \
--rpc-url "$rpc" \
--chain-id "$chain_id" \
--broadcast \
--private-key "$PRIVATE_KEY" \
-vvv || true
echo ""
done
echo "Done. Update .env with any new DODOPMM_INTEGRATION_<CHAIN> addresses."

View File

@@ -0,0 +1,85 @@
#!/usr/bin/env bash
# Deploy to chains with sufficient native token balance (Avalanche, Arbitrum, Cronos).
# Run check-balances-gas-and-deploy.sh first to confirm balances.
# Chain 138 phased core is deployed separately (check-balances-gas-and-deploy.sh --deploy).
#
# Requires: PRIVATE_KEY, CCIP_*_ROUTER, CCIP_*_LINK_TOKEN, *_SELECTOR, *_RPC_URL per chain.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
# Load .env
if [ -f .env ]; then
set -a
source .env
set +a
fi
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
if [ -z "${PRIVATE_KEY:-}" ]; then
echo -e "${RED}ERROR: PRIVATE_KEY not set in .env${NC}"
exit 1
fi
# Chains with sufficient balance (from last balance check): Avalanche, Arbitrum, Cronos
# Prefer INFURA_PROJECT_ID (+ optional INFURA_PROJECT_SECRET) when set; else public RPCs
[[ -f "$SCRIPT_DIR/../lib/infura.sh" ]] && source "$SCRIPT_DIR/../lib/infura.sh"
_av_rpc=$(build_infura_rpc "avalanche-mainnet" 2>/dev/null || true)
_ar_rpc=$(build_infura_rpc "arbitrum-mainnet" 2>/dev/null || true)
AVALANCHE_RPC="${AVALANCHE_RPC_URL:-${AVALANCHE_RPC:-${_av_rpc:-https://avalanche-c-chain.publicnode.com}}}"
ARBITRUM_RPC="${ARBITRUM_MAINNET_RPC:-${ARBITRUM_RPC:-${_ar_rpc:-https://arbitrum-one.publicnode.com}}}"
CRONOS_RPC="${CRONOS_RPC_URL:-${CRONOS_RPC:-https://evm.cronos.org}}"
deploy_chain() {
local name="$1"
local rpc="$2"
local chain_id="$3"
echo -e "${YELLOW}Deploying to ${name} (chain ${chain_id})...${NC}"
forge script script/DeployAll.s.sol:DeployAll \
--rpc-url "$rpc" \
--chain-id "$chain_id" \
--private-key "$PRIVATE_KEY" \
--broadcast \
--slow \
-vvvv || {
echo -e "${RED}${name} deployment failed${NC}"
return 1
}
echo -e "${GREEN}${name} deployment complete${NC}"
echo ""
}
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Deploy to chains with sufficient balance${NC}"
echo -e "${BLUE}========================================${NC}"
echo "Chains: Avalanche, Arbitrum, Cronos"
echo ""
# Verify required CCIP env vars
for chain in AVALANCHE ARBITRUM CRONOS; do
router="CCIP_${chain}_ROUTER"
link="CCIP_${chain}_LINK_TOKEN"
selector="${chain}_SELECTOR"
if [ -z "${!router:-}" ] || [ -z "${!link:-}" ] || [ -z "${!selector:-}" ]; then
echo -e "${RED}ERROR: Missing ${router}, ${link}, or ${selector} in .env${NC}"
exit 1
fi
done
# Deploy (skip --verify to avoid needing chain-specific explorer API keys)
deploy_chain "Avalanche" "$AVALANCHE_RPC" "43114"
deploy_chain "Arbitrum" "$ARBITRUM_RPC" "42161"
deploy_chain "Cronos" "$CRONOS_RPC" "25"
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}Deployments complete${NC}"
echo -e "${GREEN}========================================${NC}"
echo "Next: update .env with deployed addresses; run verify manually if needed."

View File

@@ -0,0 +1,340 @@
#!/usr/bin/env bash
# Deploy WETH9/WETH10 + CCIP bridges (and optionally Cronos D-WIN W) to all blockchains
# unless a canonical/pre-existing deployment is already present in .env.
#
# Deploys:
# - WETH9, WETH10, CCIPWETH9Bridge, CCIPWETH10Bridge (via DeployAll.s.sol) on each chain
# where WETH9_<CHAIN> and WETH10_<CHAIN> are not both set.
# - On Cronos (25): optionally ISO-4217 W system (USDW, EURW, ...) if not already deployed.
# - With --deploy-c: cUSDT/cUSDC (and optional c*) on each chain where CUSDT_<CHAIN>/CUSDC_<CHAIN> unset (via DeployCompliantFiatTokensForChain.s.sol).
# - With --deploy-cw: cWUSDT/cWUSDC on each chain where CWUSDT_<CHAIN> unset (via DeployCWTokens.s.sol; set CW_BRIDGE_ADDRESS or CW_BRIDGE_<CHAIN>).
# - Chain 651940 (ALL Mainnet): env validation only (check AUSDT_ADDRESS_651940 set); no token deploy from this repo.
#
# Skips:
# - Ethereum Mainnet (1): uses canonical WETH from .env (WETH9_MAINNET, WETH10_MAINNET).
# - Any chain where both WETH9_* and WETH10_* are already set in .env.
# - Chain 138: not in DeployAll; compliant tokens (c*) are deployed separately on 138.
#
# Usage:
# cd smom-dbis-138 && ./scripts/deployment/deploy-tokens-and-weth-all-chains-skip-canonical.sh [OPTIONS]
#
# Options:
# --dry-run Print commands only; do not broadcast.
# --chain 25 56 137 Deploy only to these chain IDs (default: all supported).
# --no-iso4217 Do not deploy ISO-4217 W system on Cronos even if missing.
# --iso4217-only Only run Cronos ISO-4217 W deploy (skip DeployAll).
# --deploy-c Deploy cUSDT/cUSDC (and optional c*) on chains where CUSDT_<CHAIN>/CUSDC_<CHAIN> unset (skip 138, 1).
# --deploy-cw Deploy cWUSDT/cWUSDC on chains where CWUSDT_<CHAIN> unset; requires CW_BRIDGE_ADDRESS or CW_BRIDGE_<CHAIN> in .env.
#
# Requires: .env with PRIVATE_KEY; per-chain RPC and CCIP vars for chains you deploy to.
# See: docs/11-references/TOKENS_DEPLOYER_DEPLOYED_ON_OTHER_CHAINS.md
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
[ -f .env ] && set -a && source .env && set +a
DRY_RUN=false
CHAINS_FILTER=""
NO_ISO4217=false
ISO4217_ONLY=false
DEPLOY_C=false
DEPLOY_CW=false
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true; shift ;;
--no-iso4217) NO_ISO4217=true; shift ;;
--iso4217-only) ISO4217_ONLY=true; shift ;;
--deploy-c) DEPLOY_C=true; shift ;;
--deploy-cw) DEPLOY_CW=true; shift ;;
--chain)
shift
CHAINS_FILTER="$*"
break
;;
*) shift ;;
esac
done
# Chain ID : Name : RPC env var (primary)
# DeployAll.s.sol supports: 1, 25, 56, 137, 100, 43114, 8453, 42161, 10. 651940 = env validation only.
ALL_CHAINS="1:Mainnet:ETH_MAINNET_RPC_URL 25:Cronos:CRONOS_RPC_URL 56:BSC:BSC_RPC_URL 137:Polygon:POLYGON_RPC_URL 100:Gnosis:GNOSIS_RPC_URL 43114:Avalanche:AVALANCHE_RPC_URL 8453:Base:BASE_RPC_URL 42161:Arbitrum:ARBITRUM_RPC_URL 10:Optimism:OPTIMISM_RPC_URL 651940:ALL:CHAIN_651940_RPC"
# Fallback RPC env names (some scripts use different names)
fallback_rpc() {
local chain_id="$1"
local rpc_var="$2"
local rpc="${!rpc_var:-}"
if [[ -z "$rpc" ]]; then
case "$chain_id" in
1) rpc="${ETHEREUM_MAINNET_RPC:-${ETH_MAINNET_RPC_URL:-}}";;
25) rpc="${CRONOS_RPC:-}";;
56) rpc="${BSC_RPC_URL:-}";;
137) rpc="${POLYGON_MAINNET_RPC:-}";;
100) rpc="${GNOSIS_RPC:-}";;
43114) rpc="${AVALANCHE_RPC_URL:-}";;
8453) rpc="${BASE_MAINNET_RPC:-}";;
42161) rpc="${ARBITRUM_MAINNET_RPC:-}";;
10) rpc="${OPTIMISM_MAINNET_RPC:-}";;
651940) rpc="${CHAIN_651940_RPC:-${ALL_MAINNET_RPC:-}}";;
esac
fi
echo "$rpc"
}
is_canonical_present() {
local weth9_var="$1"
local weth10_var="$2"
local w9="${!weth9_var:-}"
local w10="${!weth10_var:-}"
w9="${w9//0x/}"
w10="${w10//0x/}"
[[ -n "$w9" && "${#w9}" -ge 40 && "$w9" != "0000000000000000000000000000000000000000" ]] && \
[[ -n "$w10" && "${#w10}" -ge 40 && "$w10" != "0000000000000000000000000000000000000000" ]] && return 0
return 1
}
run_cmd() {
if $DRY_RUN; then
echo " [DRY-RUN] $*"
else
eval "$@" || return 1
fi
}
# ---------- DeployAll (WETH9, WETH10, CCIP bridges) per chain ----------
run_deploy_all() {
local chain_id="$1"
local name="$2"
local rpc_var="$3"
if [[ "$chain_id" == "651940" ]]; then
echo " Skip $name (chain 651940): DeployAll not supported; env validation only."
return 0
fi
local rpc
rpc=$(fallback_rpc "$chain_id" "$rpc_var")
if [[ -z "$rpc" ]]; then
echo " Skip $name (chain $chain_id): RPC not set ($rpc_var)."
return 0
fi
local weth9_var="WETH9_MAINNET" weth10_var="WETH10_MAINNET"
case "$chain_id" in
1) weth9_var="WETH9_MAINNET"; weth10_var="WETH10_MAINNET" ;;
25) weth9_var="WETH9_CRONOS"; weth10_var="WETH10_CRONOS" ;;
56) weth9_var="WETH9_BSC"; weth10_var="WETH10_BSC" ;;
137) weth9_var="WETH9_POLYGON"; weth10_var="WETH10_POLYGON" ;;
100) weth9_var="WETH9_GNOSIS"; weth10_var="WETH10_GNOSIS" ;;
43114) weth9_var="WETH9_AVALANCHE"; weth10_var="WETH10_AVALANCHE" ;;
8453) weth9_var="WETH9_BASE"; weth10_var="WETH10_BASE" ;;
42161) weth9_var="WETH9_ARBITRUM"; weth10_var="WETH10_ARBITRUM" ;;
10) weth9_var="WETH9_OPTIMISM"; weth10_var="WETH10_OPTIMISM" ;;
*) echo " Unsupported chain ID $chain_id"; return 1 ;;
esac
# Mainnet: use canonical WETH from .env; DeployAll only deploys CCIPLogger (placeholder). Skip to avoid requiring env.
if [[ "$chain_id" == "1" ]]; then
if is_canonical_present "$weth9_var" "$weth10_var"; then
echo " Skip $name (chain $chain_id): canonical WETH9/WETH10 already set."
return 0
fi
echo " Skip $name (chain $chain_id): set WETH9_MAINNET and WETH10_MAINNET in .env for canonical WETH; DeployAll on Mainnet does not deploy tokens."
return 0
fi
if is_canonical_present "$weth9_var" "$weth10_var"; then
echo " Skip $name (chain $chain_id): WETH9/WETH10 already set in .env."
return 0
fi
echo " Deploying WETH9, WETH10, CCIP bridges on $name (chain $chain_id)..."
local gas_opts="--legacy"
run_cmd "forge script script/DeployAll.s.sol:DeployAll --rpc-url \"$rpc\" --chain-id \"$chain_id\" --broadcast --private-key \"\$PRIVATE_KEY\" $gas_opts -vvv" || true
echo " → Set WETH9_${name^^}, WETH10_${name^^}, CCIPWETH9_BRIDGE_${name^^}, CCIPWETH10_BRIDGE_${name^^} in .env from script output."
}
# ---------- ISO-4217 W (Cronos): deploy only if USDW not already deployed ----------
run_iso4217_cronos() {
if $NO_ISO4217; then
echo " Skip Cronos ISO-4217 W (--no-iso4217)."
return 0
fi
local rpc
rpc=$(fallback_rpc 25 "CRONOS_RPC_URL")
[[ -z "$rpc" ]] && rpc="${CRONOS_RPC:-}"
if [[ -z "$rpc" ]]; then
echo " Skip Cronos ISO-4217 W: CRONOS_RPC_URL / CRONOS_RPC not set."
return 0
fi
local usdw_addr="0x948690147D2e50ffe50C5d38C14125aD6a9FA036"
local code_len
code_len=$(cast code "$usdw_addr" --rpc-url "$rpc" 2>/dev/null | wc -c)
if [[ -n "$code_len" && "$code_len" -gt 10 ]]; then
echo " Skip Cronos ISO-4217 W: USDW already deployed at $usdw_addr."
return 0
fi
echo " Deploying ISO-4217 W system on Cronos (25)..."
run_cmd "forge script script/deploy/iso4217w/DeployISO4217WSystem.s.sol:DeployISO4217WSystem --rpc-url \"$rpc\" --chain-id 25 --broadcast --private-key \"\$PRIVATE_KEY\" --legacy -vvv" || true
echo " → Record MintController, TokenRegistry, USDW, EURW, ... addresses from output; add to .env / docs."
}
# ---------- c* (cUSDT, cUSDC) on other chains: DeployCompliantFiatTokensForChain ----------
run_deploy_c() {
local chain_id="$1"
local name="$2"
local rpc_var="$3"
[[ "$chain_id" == "138" || "$chain_id" == "1" ]] && return 0
local rpc
rpc=$(fallback_rpc "$chain_id" "$rpc_var")
if [[ -z "$rpc" ]]; then return 0; fi
local cusdt_var="CUSDT_${name^^}" cusdc_var="CUSDC_${name^^}"
local cusdt_val="${!cusdt_var:-}" cusdc_val="${!cusdc_var:-}"
cusdt_val="${cusdt_val//0x/}"; cusdc_val="${cusdc_val//0x/}"
if [[ -n "$cusdt_val" && "${#cusdt_val}" -ge 40 ]] && [[ -n "$cusdc_val" && "${#cusdc_val}" -ge 40 ]]; then
echo " Skip c* on $name (chain $chain_id): CUSDT_${name^^} and CUSDC_${name^^} already set."
return 0
fi
echo " Deploying cUSDT/cUSDC on $name (chain $chain_id)..."
run_cmd "forge script script/deploy/DeployCompliantFiatTokensForChain.s.sol:DeployCompliantFiatTokensForChain --rpc-url \"$rpc\" --chain-id \"$chain_id\" --broadcast --private-key \"\$PRIVATE_KEY\" --legacy -vvv" || true
echo " → Set CUSDT_${name^^}, CUSDC_${name^^} in .env from script output."
}
# ---------- cW* (all 12: cWUSDT, cWUSDC, cWEURC, cWEURT, cWGBPC, cWGBPT, cWAUDC, cWJPYC, cWCHFC, cWCADC, cWXAUC, cWXAUT): DeployCWTokens ----------
run_deploy_cw() {
local chain_id="$1"
local name="$2"
local rpc_var="$3"
local rpc
rpc=$(fallback_rpc "$chain_id" "$rpc_var")
if [[ -z "$rpc" ]]; then return 0; fi
local bridge_var="CW_BRIDGE_${name^^}"
local bridge="${!bridge_var:-${CW_BRIDGE_ADDRESS:-}}"
if [[ -z "$bridge" || "$bridge" == "0x"*"0000000000000000000000000000000000000000" ]]; then
echo " Skip cW* on $name (chain $chain_id): set CW_BRIDGE_ADDRESS or CW_BRIDGE_${name^^} in .env."
return 0
fi
local cw_var="CWUSDT_${name^^}"
local cw_val="${!cw_var:-}"
cw_val="${cw_val//0x/}"
local deploy_opts=""
if [[ -n "$cw_val" && "${#cw_val}" -ge 40 ]]; then
echo " Deploying remaining cW* (cWEURC..cWXAUT) on $name (chain $chain_id) (bridge $bridge)..."
deploy_opts="DEPLOY_CWUSDT=0 DEPLOY_CWUSDC=0"
else
echo " Deploying all cW* (12 tokens) on $name (chain $chain_id) (bridge $bridge)..."
fi
local gas_opt=""
[[ "$chain_id" == "42161" && -n "${ARBITRUM_GAS_PRICE:-}" ]] && gas_opt="--with-gas-price ${ARBITRUM_GAS_PRICE}"
run_cmd "${deploy_opts:+$deploy_opts }CW_BRIDGE_ADDRESS=$bridge forge script script/deploy/DeployCWTokens.s.sol:DeployCWTokens --rpc-url \"$rpc\" --chain-id \"$chain_id\" --broadcast --private-key \"\$PRIVATE_KEY\" --legacy ${gas_opt} -vvv" || true
echo " → Set CWUSDT_*, CWUSDC_*, CWEURC_*, CWEURT_*, CWGBPC_*, CWGBPT_*, CWAUDC_*, CWJPYC_*, CWCHFC_*, CWCADC_*, CWXAUC_*, CWXAUT_* in .env from script output."
}
# ---------- 651940 (ALL Mainnet): env validation only ----------
run_651940_validate() {
local rpc
rpc=$(fallback_rpc 651940 "CHAIN_651940_RPC")
if [[ -z "$rpc" ]]; then
echo " Skip ALL (651940): CHAIN_651940_RPC not set."
return 0
fi
local ausdt_var="AUSDT_ADDRESS_651940"
local ausdt_val="${!ausdt_var:-}"
if [[ -z "$ausdt_val" || "$ausdt_val" == "0x0000000000000000000000000000000000000000" ]]; then
echo " ALL (651940): Set AUSDT_ADDRESS_651940 in .env (ecosystem token; not deployed by this script)."
else
echo " ALL (651940): AUSDT_ADDRESS_651940 set."
fi
}
# ---------- Main ----------
echo "=============================================="
echo "Deploy tokens/WETH to all chains (skip canonical)"
echo "=============================================="
echo " Dry-run: $DRY_RUN"
echo " Chain filter: ${CHAINS_FILTER:-all}"
echo " ISO-4217 on Cronos: $(! $NO_ISO4217 && ! $ISO4217_ONLY || $ISO4217_ONLY)"
echo " Deploy c* (cUSDT/cUSDC): $DEPLOY_C"
echo " Deploy cW* (cWUSDT/cWUSDC): $DEPLOY_CW"
echo ""
if [[ -z "${PRIVATE_KEY:-}" ]]; then
echo "ERROR: PRIVATE_KEY not set in .env." >&2
exit 1
fi
if ! $ISO4217_ONLY; then
echo "--- DeployAll (WETH9, WETH10, CCIP bridges) per chain ---"
for entry in $ALL_CHAINS; do
chain_id="${entry%%:*}"; rest="${entry#*:}"
name="${rest%%:*}"; rpc_var="${rest#*:}"
if [[ -n "$CHAINS_FILTER" ]]; then
echo "$CHAINS_FILTER" | grep -q "\b$chain_id\b" || continue
fi
run_deploy_all "$chain_id" "$name" "$rpc_var"
done
echo ""
fi
if ! $ISO4217_ONLY; then
if [[ -z "$CHAINS_FILTER" ]] || echo "$CHAINS_FILTER" | grep -q "\b25\b"; then
echo "--- Cronos: ISO-4217 W (USDW, EURW, ...) ---"
run_iso4217_cronos
echo ""
fi
else
echo "--- Cronos: ISO-4217 W only ---"
run_iso4217_cronos
echo ""
fi
if $DEPLOY_C; then
echo "--- Deploy c* (cUSDT/cUSDC) per chain (skip 138, 1) ---"
for entry in $ALL_CHAINS; do
chain_id="${entry%%:*}"; rest="${entry#*:}"
name="${rest%%:*}"; rpc_var="${rest#*:}"
if [[ "$chain_id" == "651940" ]]; then continue; fi
if [[ -n "$CHAINS_FILTER" ]]; then
echo "$CHAINS_FILTER" | grep -q "\b$chain_id\b" || continue
fi
run_deploy_c "$chain_id" "$name" "$rpc_var"
done
echo ""
fi
if $DEPLOY_CW; then
echo "--- Deploy cW* (cWUSDT/cWUSDC) per chain ---"
for entry in $ALL_CHAINS; do
chain_id="${entry%%:*}"; rest="${entry#*:}"
name="${rest%%:*}"; rpc_var="${rest#*:}"
if [[ "$chain_id" == "651940" ]]; then continue; fi
if [[ -n "$CHAINS_FILTER" ]]; then
echo "$CHAINS_FILTER" | grep -q "\b$chain_id\b" || continue
fi
run_deploy_cw "$chain_id" "$name" "$rpc_var"
done
echo ""
fi
echo "--- Chain 651940 (ALL Mainnet) env validation ---"
for entry in $ALL_CHAINS; do
chain_id="${entry%%:*}"; rest="${entry#*:}"
name="${rest%%:*}"; rpc_var="${rest#*:}"
if [[ "$chain_id" != "651940" ]]; then continue; fi
if [[ -n "$CHAINS_FILTER" ]]; then
echo "$CHAINS_FILTER" | grep -q "\b651940\b" || continue
fi
run_651940_validate
break
done
echo ""
echo "=============================================="
echo "Done. Update .env with deployed addresses; see TOKENS_DEPLOYER_DEPLOYED_ON_OTHER_CHAINS.md."
echo "=============================================="

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Deploy Trustless Bridge stack (BondManager, ChallengeManager, LiquidityPool, Inbox, optional Lockbox) on each L2.
# Uses .env for RPC and PRIVATE_KEY. Chains via --chain bsc polygon ...; Lockbox via --lockbox / --no-lockbox (not .env).
#
# Usage:
# ./scripts/deployment/deploy-trustless-l2s.sh
# ./scripts/deployment/deploy-trustless-l2s.sh --chain bsc polygon --lockbox
# ./scripts/deployment/deploy-trustless-l2s.sh --no-lockbox
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DOTENV="$REPO_ROOT/.env"
cd "$REPO_ROOT"
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
parse_lockbox_tag "$@"
set -- "${PARSE_LOCKBOX_REMAINING[@]}"
parse_chain_filter "$@"
# Backward compat: single positional chain (e.g. deploy-trustless-l2s.sh BSC)
if [[ ${#CHAIN_FILTER[@]} -eq 0 && ${#PARSE_CHAIN_FILTER_REMAINING[@]} -eq 1 ]]; then
n="$(normalize_chain_name "${PARSE_CHAIN_FILTER_REMAINING[0]}")"
[[ -n "$n" ]] && CHAIN_FILTER=("$n")
fi
get_rpc() { local n="$1"; case "$n" in BSC) echo "${BSC_RPC_URL:-}";; POLYGON) echo "${POLYGON_MAINNET_RPC:-}";; BASE) echo "${BASE_MAINNET_RPC:-}";; OPTIMISM) echo "${OPTIMISM_MAINNET_RPC:-}";; ARBITRUM) echo "${ARBITRUM_MAINNET_RPC:-}";; AVALANCHE) echo "${AVALANCHE_RPC_URL:-}";; CRONOS) echo "${CRONOS_RPC_URL:-}";; GNOSIS) echo "${GNOSIS_MAINNET_RPC:-}";; *) echo "";; esac; }
get_weth() { local n="$1"; local v="${n}_WETH_ADDRESS"; if [[ -n "${!v:-}" ]]; then echo "${!v}"; return; fi; case "$n" in BSC) echo "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";; POLYGON) echo "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270";; BASE) echo "0x4200000000000000000000000000000000000006";; OPTIMISM) echo "0x4200000000000000000000000000000000000006";; ARBITRUM) echo "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";; AVALANCHE) echo "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7";; CRONOS) echo "0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23";; GNOSIS) echo "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d";; *) echo "";; esac; }
get_chain_id() { case "$1" in BSC) echo 56;; POLYGON) echo 137;; BASE) echo 8453;; OPTIMISM) echo 10;; ARBITRUM) echo 42161;; AVALANCHE) echo 43114;; CRONOS) echo 25;; GNOSIS) echo 100;; *) echo 0;; esac; }
for name in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS; do
if [[ ${#CHAIN_FILTER[@]} -gt 0 ]] && [[ ! " ${CHAIN_FILTER[*]} " =~ " $name " ]]; then continue; fi
rpc="$(get_rpc "$name")"
if [[ -z "$rpc" ]]; then echo "Skip $name: RPC not set"; continue; fi
weth="$(get_weth "$name")"
chain_id="$(get_chain_id "$name")"
echo "=== Deploying Trustless stack on $name (chain $chain_id) ==="
TRUSTLESS_WETH_ADDRESS="$weth" TRUSTLESS_DEPLOY_LOCKBOX="${TRUSTLESS_DEPLOY_LOCKBOX:-0}" \
forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
--rpc-url "$rpc" --chain-id "$chain_id" --broadcast --private-key "$PRIVATE_KEY" --slow -vvv || true
echo ""
done
echo "Done. Update .env with BondManager, ChallengeManager, LiquidityPool, Inbox (and Lockbox) per chain."

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Deploy Vault System, then ac* / vdc* / sdc* vaults (DeployAcVdcSdcVaults).
# Run from a host that can reach Chain 138 RPC (e.g. on same LAN as 192.168.11.211).
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
RPC_URL="${RPC_URL_138:-http://192.168.11.211:8545}"
GAS_PRICE="${GAS_PRICE:-1000000000}"
CHAIN_ID="${CHAIN_ID:-138}"
if [ -z "$PRIVATE_KEY" ]; then
echo "Error: PRIVATE_KEY not set (e.g. in smom-dbis-138/.env)"
exit 1
fi
if [[ ! "$PRIVATE_KEY" =~ ^0x ]]; then
export PRIVATE_KEY="0x$PRIVATE_KEY"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "1. Deploy Vault System (DeployVaultSystem.s.sol)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "RPC: $RPC_URL Chain: $CHAIN_ID Gas: $GAS_PRICE"
echo ""
forge script script/deploy/vault/DeployVaultSystem.s.sol:DeployVaultSystem \
--rpc-url "$RPC_URL" \
--broadcast \
--with-gas-price "$GAS_PRICE"
# Resolve VaultFactory address from broadcast (last contract creation)
RUN_JSON=""
for candidate in \
"broadcast/DeployVaultSystem.s.sol/$CHAIN_ID/run-latest.json" \
"broadcast/vault/DeployVaultSystem.s.sol/$CHAIN_ID/run-latest.json" \
"broadcast/script/deploy/vault/DeployVaultSystem.s.sol/$CHAIN_ID/run-latest.json"; do
if [ -f "$candidate" ]; then
RUN_JSON="$candidate"
break
fi
done
if [ -z "$RUN_JSON" ] || [ ! -f "$RUN_JSON" ]; then
echo "Could not find broadcast file. Set VAULT_FACTORY_ADDRESS manually and run:"
echo " VAULT_FACTORY_ADDRESS=0x... forge script script/deploy/vault/DeployAcVdcSdcVaults.s.sol:DeployAcVdcSdcVaults --rpc-url \$RPC_URL_138 --broadcast --with-gas-price 1000000000"
exit 1
fi
VAULT_FACTORY_ADDRESS=$(jq -r '[.transactions[] | select(.contractAddress != null) | .contractAddress] | last' "$RUN_JSON")
if [ -z "$VAULT_FACTORY_ADDRESS" ] || [ "$VAULT_FACTORY_ADDRESS" = "null" ]; then
echo "Could not parse Vault Factory address from $RUN_JSON. Set VAULT_FACTORY_ADDRESS and run DeployAcVdcSdcVaults manually."
exit 1
fi
export VAULT_FACTORY_ADDRESS
echo ""
echo "Vault Factory address: $VAULT_FACTORY_ADDRESS"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "2. Deploy ac* / vdc* / sdc* (DeployAcVdcSdcVaults.s.sol)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Optional: set CUSDC_ADDRESS_138, CUSDT_ADDRESS_138 (or COMPLIANT_USDC_ADDRESS, COMPLIANT_USDT_ADDRESS) to create vaults for those tokens."
echo ""
forge script script/deploy/vault/DeployAcVdcSdcVaults.s.sol:DeployAcVdcSdcVaults \
--rpc-url "$RPC_URL" \
--broadcast \
--with-gas-price "$GAS_PRICE"
echo ""
echo "Done. Record Vault Factory and any new vault/deposit/debt token addresses in .env and config/smart-contracts-master.json if needed."

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
# Ensure prerequisites for: LINK funding, PMM (Chain 138), CCIPLogger deploy.
# Run from repo root (proxmox) or smom-dbis-138. Fixes what can be automated and reports the rest.
# Usage: ./scripts/deployment/ensure-prerequisites.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# PROJECT_ROOT = smom-dbis-138
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ok() { echo -e "${GREEN}${NC} $1"; }
warn() { echo -e "${YELLOW}${NC} $1"; }
fail() { echo -e "${RED}${NC} $1"; }
echo "=== Prerequisites (LINK funding, PMM, CCIPLogger) ==="
echo ""
# 1) .env
if [[ ! -f "$PROJECT_ROOT/.env" ]]; then
fail ".env not found in $PROJECT_ROOT"
exit 1
fi
ok ".env exists"
set -a
source "$PROJECT_ROOT/.env" 2>/dev/null || true
set +a
[[ -z "${PRIVATE_KEY:-}" ]] && fail "PRIVATE_KEY not set in .env" || ok "PRIVATE_KEY set"
[[ -z "${RPC_URL_138:-}" ]] && warn "RPC_URL_138 not set" || ok "RPC_URL_138 set"
# 2) npm install in smom-dbis-138 (for Hardhat / CCIPLogger)
echo ""
echo "--- Dependencies (CCIPLogger / Hardhat) ---"
if [[ -f "$PROJECT_ROOT/package.json" ]]; then
if [[ ! -d "$PROJECT_ROOT/node_modules/hardhat" ]]; then
warn "Hardhat not found in node_modules. Running: npm install --legacy-peer-deps"
npm install --legacy-peer-deps 2>/dev/null || true
fi
if [[ -d "$PROJECT_ROOT/node_modules/hardhat" ]]; then
ok "Hardhat available (node_modules)"
else
warn "Hardhat still missing; run from $PROJECT_ROOT: npm install --legacy-peer-deps"
fi
else
warn "No package.json in $PROJECT_ROOT"
fi
# 3) LINK funding prereqs
echo ""
echo "--- LINK funding ---"
[[ -z "${LINK_TOKEN_CHAIN138:-${LINK_TOKEN:-}}" ]] && warn "LINK_TOKEN_CHAIN138/LINK_TOKEN not set" || ok "Chain 138 LINK token set"
[[ -z "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && warn "CCIPWETH9_BRIDGE_CHAIN138 not set" || ok "CCIPWETH9_BRIDGE_CHAIN138 set"
[[ -z "${MAINNET_CCIP_WETH9_BRIDGE:-}" ]] && warn "MAINNET_CCIP_WETH9_BRIDGE not set" || ok "Mainnet bridge vars set"
echo " Deployer must have LINK on each chain. Run: scripts/deployment/fund-ccip-bridges-with-link.sh (use DRY_RUN=1 first)."
# 4) PMM prereqs
echo ""
echo "--- PMM (Chain 138) ---"
if [[ -z "${DODO_VENDING_MACHINE_ADDRESS:-}" || "${DODO_VENDING_MACHINE_ADDRESS}" =~ ^0x?0*$ ]]; then
warn "DODO_VENDING_MACHINE_ADDRESS not set. Set to DODO DVM factory on Chain 138 to run PMM (see docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md)."
else
ok "DODO_VENDING_MACHINE_ADDRESS set"
fi
[[ -z "${COMPLIANT_USDT_ADDRESS:-}" ]] && warn "COMPLIANT_USDT_ADDRESS not set" || ok "COMPLIANT_USDT_ADDRESS set"
[[ -z "${COMPLIANT_USDC_ADDRESS:-}" ]] && warn "COMPLIANT_USDC_ADDRESS not set" || ok "COMPLIANT_USDC_ADDRESS set"
[[ -z "${OFFICIAL_USDT_ADDRESS:-}" ]] && warn "OFFICIAL_USDT_ADDRESS not set" || ok "OFFICIAL_USDT_ADDRESS set"
[[ -z "${OFFICIAL_USDC_ADDRESS:-}" ]] && warn "OFFICIAL_USDC_ADDRESS not set" || ok "OFFICIAL_USDC_ADDRESS set"
echo " Then run: scripts/deployment/run-pmm-and-pools.sh"
# 5) CCIPLogger
echo ""
echo "--- CCIPLogger ---"
echo " Optional. From $PROJECT_ROOT run: scripts/deployment/deploy-ccip-logger-all-chains.sh"
echo " If Hardhat compile fails (e.g. missing @emoney/interfaces), fix deps or skip CCIPLogger."
echo ""
echo "=== Done. Address any ⚠ items above, then run the task scripts. ==="

View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Export flattened Solidity source for Cronos manual verification.
# Paste each file at https://explorer.cronos.org/verifyContract
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
OUT_DIR="$PROJECT_ROOT/.cronos-verify"
cd "$PROJECT_ROOT"
mkdir -p "$OUT_DIR"
CONTRACTS=(
"contracts/tokens/WETH.sol:WETH"
"contracts/tokens/WETH10.sol:WETH10"
"contracts/ccip/CCIPWETH9Bridge.sol:CCIPWETH9Bridge"
"contracts/ccip/CCIPWETH10Bridge.sol:CCIPWETH10Bridge"
)
ADDRESSES=(
"0x99B3511A2d315A497C8112C1fdd8D508d4B1E506"
"0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6"
"0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e"
"0x105F8A15b819948a89153505762444Ee9f324684"
)
echo "Exporting flattened source for Cronos manual verification..."
echo ""
for i in "${!CONTRACTS[@]}"; do
entry="${CONTRACTS[$i]}"
addr="${ADDRESSES[$i]}"
path="${entry%%:*}"
name="${entry##*:}"
base=$(basename "$path" .sol)
out="$OUT_DIR/${base}_flattened.sol"
forge flatten "$path" > "$out" 2>/dev/null
echo "$name -> $out"
done
# Export Standard JSON Input (required — includes viaIR:true)
echo "Exporting Standard JSON Input (includes viaIR — required for bytecode match)..."
forge verify-contract "${ADDRESSES[0]}" "${CONTRACTS[0]}" --chain cronos --show-standard-json-input 2>/dev/null | jq -c . > "$OUT_DIR/WETH_standard_input.json"
forge verify-contract "${ADDRESSES[1]}" "${CONTRACTS[1]}" --chain cronos --show-standard-json-input 2>/dev/null | jq -c . > "$OUT_DIR/WETH10_standard_input.json"
forge verify-contract "${ADDRESSES[2]}" "${CONTRACTS[2]}" --chain cronos --constructor-args "$(cast abi-encode 'constructor(address,address,address)' 0xE26B0A098D861d5C7d9434aD471c0572Ca6EAa67 0x99B3511A2d315A497C8112C1fdd8D508d4B1E506 0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85)" --show-standard-json-input 2>/dev/null | jq -c . > "$OUT_DIR/CCIPWETH9Bridge_standard_input.json"
forge verify-contract "${ADDRESSES[3]}" "${CONTRACTS[3]}" --chain cronos --constructor-args "$(cast abi-encode 'constructor(address,address,address)' 0xE26B0A098D861d5C7d9434aD471c0572Ca6EAa67 0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6 0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85)" --show-standard-json-input 2>/dev/null | jq -c . > "$OUT_DIR/CCIPWETH10Bridge_standard_input.json"
echo " ✓ Standard JSON files written to $OUT_DIR/*_standard_input.json"
echo ""
echo "IMPORTANT: Use Standard-Json-Input (not flattened source). Contracts were deployed with via_ir=true."
echo " Flattened source produces different bytecode → Unmatched."
echo ""
echo "Next: https://explorer.cronos.org/verifyContract"
echo " 1. Select 'Solidity (Standard-Json-Input)'"
echo " 2. Upload the *_standard_input.json file for each contract"
echo " 3. See docs/deployment/CRONOS_VERIFICATION_RUNBOOK.md"
echo ""
echo "Sources: $OUT_DIR/"

View File

@@ -0,0 +1,57 @@
#!/usr/bin/env bash
# Fix nonce mismatch by clearing broadcast/cache so Forge uses fresh on-chain nonce.
# Usage: ./scripts/deployment/fix-nonce-and-retry.sh [--chain cronos] [--script <path>]
# ./scripts/deployment/fix-nonce-and-retry.sh cronos # positional still supported
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
load_deployment_env
CHAIN=""
SCRIPT=""
while [[ $# -gt 0 ]]; do
case "$1" in
--chain) CHAIN="${2:-cronos}"; shift 2 ;;
--script) SCRIPT="${2:-script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge}"; shift 2 ;;
*) if [[ -z "$CHAIN" ]]; then CHAIN="$1"; elif [[ -z "$SCRIPT" ]]; then SCRIPT="$1"; fi; shift ;;
esac
done
CHAIN="${CHAIN:-cronos}"
SCRIPT="${SCRIPT:-script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge}"
case "$(echo "$CHAIN" | tr '[:upper:]' '[:lower:]')" in
cronos) RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}"; CHAIN_ID=25 ;;
chain138) RPC="${RPC_URL_138:-${CHAIN_138_RPC_URL:-}}"; CHAIN_ID=138 ;;
bsc) RPC="${BSC_RPC_URL:-}"; CHAIN_ID=56 ;;
polygon) RPC="${POLYGON_MAINNET_RPC:-}"; CHAIN_ID=137 ;;
base) RPC="${BASE_MAINNET_RPC:-}"; CHAIN_ID=8453 ;;
optimism) RPC="${OPTIMISM_MAINNET_RPC:-}"; CHAIN_ID=10 ;;
arbitrum) RPC="${ARBITRUM_MAINNET_RPC:-}"; CHAIN_ID=42161 ;;
avalanche) RPC="${AVALANCHE_RPC_URL:-}"; CHAIN_ID=43114 ;;
gnosis) RPC="${GNOSIS_MAINNET_RPC:-}"; CHAIN_ID=100 ;;
*) echo "Unknown chain: $CHAIN (use: cronos, chain138, bsc, polygon, base, optimism, arbitrum, avalanche, gnosis)"; exit 1 ;;
esac
if [[ -z "$RPC" ]]; then echo "RPC not set for $CHAIN"; exit 1; fi
DEPLOYER=$(cast wallet address --private-key "$PRIVATE_KEY" 2>/dev/null || true)
NONCE=$(cast nonce "$DEPLOYER" --rpc-url "$RPC" 2>/dev/null || echo "0")
echo "Deployer: $DEPLOYER"
echo "Current on-chain nonce: $NONCE"
echo "RPC: $RPC"
echo ""
# Clear broadcast cache so Forge fetches fresh nonce
CACHE_DIR="$PROJECT_ROOT/cache"
BROADCAST_DIR="$PROJECT_ROOT/broadcast"
SCRIPT_PATH="${SCRIPT%%:*}"
rm -rf "$CACHE_DIR/$SCRIPT_PATH/$CHAIN_ID" 2>/dev/null || true
rm -rf "$BROADCAST_DIR/$SCRIPT_PATH/$CHAIN_ID" 2>/dev/null || true
echo "Cleared cache for $SCRIPT_PATH on chain $CHAIN_ID"
echo ""
echo "Run deployment (use --slow to avoid nonce gaps):"
echo " forge script $SCRIPT --rpc-url \"$RPC\" --chain-id $CHAIN_ID --broadcast --private-key \"\$PRIVATE_KEY\" --slow"
echo ""

View File

@@ -0,0 +1,91 @@
#!/usr/bin/env bash
# Fund all CCIP WETH9/WETH10 bridge contracts with LINK on each chain.
# Amount via tag (not .env): --link <amount> (default 10 LINK), --dry-run to print commands only.
# Usage: ./scripts/deployment/fund-ccip-bridges-with-link.sh [--link 10] [--dry-run]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
parse_link_tags "$@"
[[ -f "$SCRIPT_DIR/../lib/infura.sh" ]] && source "$SCRIPT_DIR/../lib/infura.sh" 2>/dev/null || true
[[ -n "${PRIVATE_KEY:-}" && ! "$PRIVATE_KEY" =~ ^0x ]] && PRIVATE_KEY="0x$PRIVATE_KEY"
run_or_echo() {
if [[ "${DRY_RUN:-0}" = "1" ]]; then
echo " [DRY RUN] $*"
else
if eval "$*"; then
echo " OK"
else
echo " Failed (non-fatal)"
fi
fi
}
ensure_rpc() { local rpc="$1"; type ensure_infura_rpc_url &>/dev/null && [[ -n "$rpc" ]] && rpc=$(ensure_infura_rpc_url "$rpc"); echo "$rpc"; }
if [[ -z "$PRIVATE_KEY" ]]; then
echo "ERROR: PRIVATE_KEY not set" >&2
exit 1
fi
echo "Funding CCIP bridges with LINK (amount per bridge: $LINK_AMOUNT_WEI wei)"
echo ""
# Chain 138
if [[ -n "${RPC_URL_138:-}" && -n "${LINK_TOKEN_CHAIN138:-${LINK_TOKEN:-}}" ]]; then
link="${LINK_TOKEN_CHAIN138:-$LINK_TOKEN}"
rpc=$(ensure_rpc "$RPC_URL_138")
echo "Chain 138 (RPC: ${rpc%%\?*}...)"
[[ -n "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $CCIPWETH9_BRIDGE_CHAIN138 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
[[ -n "${CCIPWETH10_BRIDGE_CHAIN138:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $CCIPWETH10_BRIDGE_CHAIN138 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
echo ""
fi
# Ethereum
if [[ -n "${ETHEREUM_MAINNET_RPC:-}" && -n "${MAINNET_LINK_TOKEN:-${CCIP_ETH_LINK_TOKEN:-}}" ]]; then
link="${MAINNET_LINK_TOKEN:-$CCIP_ETH_LINK_TOKEN}"
rpc=$(ensure_rpc "$ETHEREUM_MAINNET_RPC")
echo "Ethereum Mainnet"
[[ -n "${MAINNET_CCIP_WETH9_BRIDGE:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH9_BRIDGE $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
[[ -n "${MAINNET_CCIP_WETH10_BRIDGE:-}" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $MAINNET_CCIP_WETH10_BRIDGE $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
echo ""
fi
# BSC, Polygon, Base, Optimism, Arbitrum, Avalanche, Cronos, Gnosis, Celo
for label in BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO; do
case "$label" in
BSC) rpc_var="BSC_RPC_URL"; link_var="CCIP_BSC_LINK_TOKEN"; ;;
POLYGON) rpc_var="POLYGON_MAINNET_RPC"; link_var="CCIP_POLYGON_LINK_TOKEN"; ;;
BASE) rpc_var="BASE_MAINNET_RPC"; link_var="CCIP_BASE_LINK_TOKEN"; ;;
OPTIMISM) rpc_var="OPTIMISM_MAINNET_RPC"; link_var="CCIP_OPTIMISM_LINK_TOKEN"; ;;
ARBITRUM) rpc_var="ARBITRUM_MAINNET_RPC"; link_var="CCIP_ARBITRUM_LINK_TOKEN"; ;;
AVALANCHE) rpc_var="AVALANCHE_RPC_URL"; link_var="CCIP_AVALANCHE_LINK_TOKEN"; ;;
CRONOS) rpc_var="CRONOS_RPC_URL"; link_var="CCIP_CRONOS_LINK_TOKEN"; rpc_fb="CRONOS_RPC"; link_fb="LINK_TOKEN_CRONOS"; ;;
GNOSIS) rpc_var="GNOSIS_MAINNET_RPC"; link_var="CCIP_GNOSIS_LINK_TOKEN"; rpc_fb="GNOSIS_RPC"; link_fb="LINK_TOKEN_GNOSIS"; ;;
CELO) rpc_var="CELO_MAINNET_RPC"; link_var="CCIP_CELO_LINK_TOKEN"; rpc_fb="CELO_RPC"; link_fb="LINK_TOKEN_CELO"; ;;
esac
rpc="${!rpc_var:-${!rpc_fb:-}}"
link="${!link_var:-${!link_fb:-}}"
rpc=$(ensure_rpc "$rpc")
[[ -z "$rpc" || -z "$link" ]] && continue
bridge9_var="CCIPWETH9_BRIDGE_${label}"
bridge10_var="CCIPWETH10_BRIDGE_${label}"
addr9="${!bridge9_var:-}"
addr10="${!bridge10_var:-}"
[[ -z "$addr9" && -z "$addr10" ]] && continue
echo "$label"
[[ -n "$addr9" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $addr9 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
[[ -n "$addr10" ]] && run_or_echo "cast send $link \"transfer(address,uint256)\" $addr10 $LINK_AMOUNT_WEI --rpc-url \"$rpc\" --private-key \"\$PRIVATE_KEY\" --legacy"
echo ""
done
echo "Done. Use --link <amount> and --dry-run to adjust."

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Fund the mainnet LiquidityPoolETH with ETH and/or WETH (G4).
# Uses .env for PRIVATE_KEY, LIQUIDITY_POOL_ETH_MAINNET (or LIQUIDITY_POOL), ETHEREUM_MAINNET_RPC.
# Amounts via tags (not .env): --eth <amount>, --weth <amount> (in ETH), or --eth-wei / --weth-wei.
# If no amounts given and stdin is a TTY, prompts interactively.
#
# Usage:
# ./scripts/deployment/fund-mainnet-lp.sh --eth 1.5 --weth 0.5
# ./scripts/deployment/fund-mainnet-lp.sh --eth 1
# ./scripts/deployment/fund-mainnet-lp.sh # interactive prompt
# ./scripts/deployment/fund-mainnet-lp.sh --dry-run # no tx, show what would be sent
#
# Callable from other scripts: pass same tags; or source and call run_fund_mainnet_lp "${args[@]}"
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$REPO_ROOT"
# Load deployment env and tag parsing
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
# Parse tags; remaining args left in PARSE_FUND_TAGS_REMAINING
parse_fund_tags "$@"
# Interactive if no amounts and TTY
prompt_fund_amounts
if [[ "${FUND_ETH_AMOUNT_WEI:-0}" == "0" && "${FUND_WETH_AMOUNT_WEI:-0}" == "0" ]]; then
echo "No amounts set. Use --eth <amount> and/or --weth <amount>, or run interactively."
echo "Example: $0 --eth 1.5 --weth 0.5"
exit 0
fi
require_fund_lp_env || exit 1
if [[ "${DRY_RUN:-0}" == "1" ]]; then
echo "Dry run: would fund LP with ETH wei=$FUND_ETH_AMOUNT_WEI, WETH wei=$FUND_WETH_AMOUNT_WEI"
exit 0
fi
echo "Funding mainnet LP at $LIQUIDITY_POOL_ETH_MAINNET (ETH wei=$FUND_ETH_AMOUNT_WEI, WETH wei=$FUND_WETH_AMOUNT_WEI)"
FUND_ETH_AMOUNT_WEI="$FUND_ETH_AMOUNT_WEI" FUND_WETH_AMOUNT_WEI="$FUND_WETH_AMOUNT_WEI" \
forge script script/bridge/trustless/FundMainnetLP.s.sol:FundMainnetLP \
--rpc-url "$ETHEREUM_MAINNET_RPC" \
--broadcast \
--private-key "$PRIVATE_KEY" \
-vvv

View File

@@ -0,0 +1,140 @@
#!/bin/bash
# Generate all chain adapters and deployment configurations
# This script creates the complete multi-chain integration package
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
CONTRACTS_DIR="$PROJECT_ROOT/contracts/bridge/adapters"
SCRIPTS_DIR="$PROJECT_ROOT/script/deploy/chains"
CONFIG_DIR="$PROJECT_ROOT/config/chains"
echo "🚀 Generating comprehensive multi-chain adapter deployment package..."
# Create directory structure
mkdir -p "$CONTRACTS_DIR"/{evm,non-evm,hyperledger}
mkdir -p "$SCRIPTS_DIR"/{evm,non-evm,hyperledger}
mkdir -p "$CONFIG_DIR"/{evm,non-evm,hyperledger}
mkdir -p "$PROJECT_ROOT/services"/{firefly-bridge,cacti-bridge,fabric-bridge,indy-verifier}
mkdir -p "$PROJECT_ROOT/docs/chains"/{evm,non-evm,hyperledger}
echo "✅ Directory structure created"
# Generate chain configuration files
cat > "$CONFIG_DIR/SUPPORTED_CHAINS.md" << 'EOF'
# Supported Chains - Complete List
## EVM Chains
| Chain | Chain ID | Status | Adapter | Explorer |
|-------|----------|--------|---------|----------|
| ChainID 138 | 138 | ✅ Live | UniversalCCIPBridge | https://explorer.d-bis.org |
| Ethereum Mainnet | 1 | ⚠️ Deploy | EVMAdapter | https://etherscan.io |
| Polygon | 137 | ⚠️ Deploy | EVMAdapter | https://polygonscan.com |
| Arbitrum | 42161 | ⚠️ Deploy | EVMAdapter | https://arbiscan.io |
| Optimism | 10 | ⚠️ Deploy | EVMAdapter | https://optimistic.etherscan.io |
| Base | 8453 | ⚠️ Deploy | EVMAdapter | https://basescan.org |
| Avalanche | 43114 | ⚠️ Deploy | EVMAdapter | https://snowtrace.io |
| BSC | 56 | ⚠️ Deploy | EVMAdapter | https://bscscan.com |
| XDC Network | 50 | ⚠️ Deploy | XDCAdapter | https://explorer.xdc.network |
| ALL Mainnet | 651940 | ⚠️ Deploy | AlltraAdapter | https://alltra.global |
## Non-EVM Chains
| Chain | Type | Status | Adapter | Explorer |
|-------|------|--------|---------|----------|
| XRP Ledger | XRPL | ⚠️ Deploy | XRPLAdapter | https://xrpscan.com |
| Stellar | Stellar | 🔨 Plan | StellarAdapter | https://stellarchain.io |
| Algorand | Algorand | 🔨 Plan | AlgorandAdapter | https://algoexplorer.io |
| Hedera | Hashgraph | 🔨 Plan | HederaAdapter | https://hashscan.io |
| Tron | Tron | 🔨 Plan | TronAdapter | https://tronscan.org |
| TON | TON | 🔨 Plan | TONAdapter | https://tonscan.org |
| Cosmos Hub | Cosmos | 🔨 Plan | CosmosAdapter | https://mintscan.io |
| Solana | Solana | 🔨 Plan | SolanaAdapter | https://solscan.io |
## Hyperledger Enterprise
| Framework | Type | Status | Adapter | Nodes |
|-----------|------|--------|---------|-------|
| Firefly | Orchestration | ✅ Deployed | FireflyAdapter | VMID 6202, 6203 |
| Cacti | Interoperability | ✅ Deployed | CactiAdapter | VMID 5201 |
| Fabric | Permissioned | 🔨 Plan | FabricAdapter | TBD |
| Indy | Identity | 🔨 Plan | IndyVerifier | TBD |
## Legend
- ✅ Live: Fully deployed and operational
- ⚠️ Deploy: Code ready, needs deployment
- 🔨 Plan: Design phase, implementation needed
EOF
echo "✅ Chain configuration documentation created"
# Create deployment orchestrator script
cat > "$PROJECT_ROOT/scripts/deployment/deploy-all-chains.sh" << 'EOF'
#!/bin/bash
# Deploy Universal Bridge to all supported chains
# This script orchestrates deployment across all chains
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
source "$PROJECT_ROOT/.env" 2>/dev/null || true
# Chain configurations
declare -A EVM_CHAINS=(
["1"]="Ethereum Mainnet"
["137"]="Polygon"
["42161"]="Arbitrum"
["10"]="Optimism"
["8453"]="Base"
["43114"]="Avalanche"
["56"]="BSC"
["50"]="XDC Network"
)
# Deployment function
deploy_chain() {
local chain_id=$1
local chain_name=$2
echo "📦 Deploying to $chain_name (Chain ID: $chain_id)..."
# Run deployment script for this chain
if [ -f "$PROJECT_ROOT/script/deploy/chains/evm/deploy-chain-$chain_id.s.sol" ]; then
forge script "script/deploy/chains/evm/deploy-chain-$chain_id.s.sol:DeployChain" \
--rpc-url "${RPC_URLS[$chain_id]}" \
--broadcast \
--private-key "$PRIVATE_KEY" \
--verify || echo "⚠️ Deployment failed for $chain_name"
else
echo "⚠️ Deployment script not found for $chain_name"
fi
}
# Main deployment loop
echo "🚀 Starting multi-chain deployment..."
echo ""
for chain_id in "${!EVM_CHAINS[@]}"; do
deploy_chain "$chain_id" "${EVM_CHAINS[$chain_id]}"
echo ""
done
echo "✅ Multi-chain deployment complete!"
EOF
chmod +x "$PROJECT_ROOT/scripts/deployment/deploy-all-chains.sh"
echo "✅ Deployment orchestrator script created"
echo ""
echo "🎉 Multi-chain adapter generation complete!"
echo ""
echo "Next steps:"
echo "1. Review generated adapters in: $CONTRACTS_DIR"
echo "2. Configure chain RPC endpoints in: $CONFIG_DIR"
echo "3. Run deployment: ./scripts/deployment/deploy-all-chains.sh"
echo "4. Configure admin dashboard with new chains"

View File

@@ -0,0 +1,236 @@
#!/usr/bin/env bash
# List all tokens in the deployer wallet across all networks.
# Token categories (see docs/11-references/TOKEN_CATEGORIES_CANONICAL.md):
# 1. Canonical 138 Compliant: Native ETH, WETH, WETH10, LINK, cUSDT, cUSDC, cEURT, cEURC, cGBPT, cGBPC, cAUDT, cAUDC, cJPYT, cJPYC, cCHFT, cCHFC, cCADT, cCADC, cAUSDT
# 2. ALL Mainnet (Alltra): Native, AUSDT, USDT, USDC, WETH, WALL
# 3. Compliant Wrapped (cW*): cWUSDT, cWUSDC, cWEURT, cWEURC, ... (per public chain)
# 4. D-WIN W Tokens: USDW, EURW, GBPW, AUDW, JPYW, CHFW, CADW (Cronos §4)
# This script lists (1) Chain 138, (2) ALL Mainnet, (4) Cronos D-WIN W, plus Ethereum/Polygon/Base/Optimism/BSC/Avalanche/Arbitrum.
# Uses PRIVATE_KEY or DEPLOYER_ADDRESS; falls back to public RPCs when env RPC vars unset.
#
# Usage: ./scripts/deployment/list-deployer-tokens-all-networks.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
if [ -f .env ]; then
set -a
source .env
set +a
fi
# Deployer: derive from PRIVATE_KEY or use DEPLOYER_ADDRESS if set (read-only mode)
if [ -n "${DEPLOYER_ADDRESS:-}" ]; then
DEPLOYER="${DEPLOYER_ADDRESS}"
[[ "$DEPLOYER" != 0x* ]] && DEPLOYER="0x$DEPLOYER"
else
if [ -z "${PRIVATE_KEY:-}" ]; then
echo "ERROR: Set PRIVATE_KEY in .env or DEPLOYER_ADDRESS=0x4A666F96fC8764181194447A7dFdb7d471b301C8 for read-only"
exit 1
fi
DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)
if [ -z "$DEPLOYER" ]; then
echo "ERROR: Could not derive deployer address (is 'cast' available?)"
exit 1
fi
fi
# Format raw balance with decimals (divide by 10^decimals). Uses cast when decimals=18.
format_balance() {
local raw="$1"
local decimals="${2:-18}"
if [ -z "$raw" ] || [ "$raw" = "0" ]; then
echo "0"
return
fi
if [ "$decimals" = "18" ]; then
cast --to-unit "$raw" ether 2>/dev/null || echo "$raw"
return
fi
# bc: 10^decimals (e.g. 10^6 for USDC)
echo "scale=12; $raw / 10^$decimals" | bc 2>/dev/null | sed 's/^\./0./;s/0*$//;s/\.$//' || echo "$raw"
}
# Fetch ERC-20 balance and decimals, print " SYMBOL: balance"
token_balance_line() {
local rpc="$1"
local token_addr="$2"
local symbol="$3"
local decimals_override="${4:-}"
local bal_hex
bal_hex=$(cast call "$token_addr" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0x0")
local bal_raw
bal_raw=$(cast --to-dec "$bal_hex" 2>/dev/null || echo "0")
if [ -z "$decimals_override" ]; then
decimals_override=$(cast call "$token_addr" "decimals()(uint8)" --rpc-url "$rpc" 2>/dev/null | cast --to-dec 2>/dev/null || echo "18")
fi
local disp
disp=$(format_balance "$bal_raw" "$decimals_override")
printf " %-8s %s\n" "$symbol:" "$disp"
}
# Report one network: native + optional ERC-20 list (name, rpc, chain_id, native_symbol, "addr:symbol:decimals ...")
report_network() {
local name="$1"
local rpc="$2"
local chain_id="$3"
local native_sym="$4"
local token_list="$5"
echo ""
echo "=== $name (chain $chain_id) ==="
if [ -z "$rpc" ]; then
echo " (no RPC configured)"
return
fi
local native_wei
native_wei=$(cast balance "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0")
local native_disp
native_disp=$(cast --to-unit "$native_wei" ether 2>/dev/null || echo "0")
echo " Native ($native_sym): $native_disp"
local entry addr rest sym dec
for entry in $token_list; do
entry=$(echo "$entry" | tr -d '[:space:]')
[ -z "$entry" ] && continue
addr="${entry%%:*}"
rest="${entry#*:}"
sym="${rest%%:*}"
dec="${rest#*:}"
[ "$dec" = "$rest" ] && dec=""
token_balance_line "$rpc" "$addr" "$sym" "$dec"
done
}
echo "============================================"
echo "Deployer wallet tokens (all networks)"
echo "Deployer: $DEPLOYER"
echo "============================================"
# Fallback public RPCs when env not set (so token lists are always shown)
RPC_138="${RPC_URL_138:-https://rpc-core.d-bis.org}"
RPC_1="${ETHEREUM_MAINNET_RPC:-https://eth.llamarpc.com}"
RPC_651940="${CHAIN_651940_RPC:-${ALLTRA_MAINNET_RPC:-https://mainnet-rpc.alltra.global}}"
RPC_25="${CRONOS_RPC:-${CRONOS_MAINNET_RPC:-https://evm.cronos.org}}"
RPC_137="${POLYGON_MAINNET_RPC:-https://polygon-rpc.com}"
RPC_8453="${BASE_MAINNET_RPC:-https://mainnet.base.org}"
RPC_10="${OPTIMISM_MAINNET_RPC:-https://mainnet.optimism.io}"
RPC_56="${BSC_RPC_URL:-${BSC_MAINNET_RPC:-https://bsc-dataseed.binance.org}}"
RPC_43114="${AVALANCHE_RPC_URL:-${AVALANCHE_MAINNET_RPC:-https://api.avax.network/ext/bc/C/rpc}}"
RPC_42161="${ARBITRUM_MAINNET_RPC:-https://arb1.arbitrum.io/rpc}"
# Chain 138 tokens (from CHAIN138_TOKEN_ADDRESSES)
CHAIN138_TOKENS="
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2:WETH:18
0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f:WETH10:18
0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03:LINK:18
0x93E66202A11B1772E55407B32B44e5Cd8eda7f22:cUSDT:6
0xf22258f57794CC8E06237084b353Ab30fFfa640b:cUSDC:6
0x15DF1D5BFDD8Aa4b380445D4e3E9B38d34283619:USDT:6
"
report_network "Chain 138" "$RPC_138" "138" "ETH" "$CHAIN138_TOKENS"
# Ethereum Mainnet
MAINNET_TOKENS="
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2:WETH:18
0xdAC17F958D2ee523a2206206994597C13D831ec7:USDT:6
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48:USDC:6
0x514910771AF9Ca656af840dff83E8264EcF986CA:LINK:18
0x6B175474E89094C44Da98b954EedeAC495271d0F:DAI:18
"
report_network "Ethereum Mainnet" "$RPC_1" "1" "ETH" "$MAINNET_TOKENS"
# ALL Mainnet (651940)
ALLMAINNET_TOKENS="
0x015B1897Ed5279930bC2Be46F661894d219292A6:AUSDT:18
0x66D8Efa0AF63B0e84eb1Dd72bf00f00cd1e2234e:USDT:18
0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881:USDC:18
0x798F6762BB40d6801A593459d08F890603D3979C:WETH:18
0x2da2b8f961F161ab6320acB3377e2e844a3C3ce4:WALL:18
"
report_network "ALL Mainnet (Alltra)" "$RPC_651940" "651940" "ETH" "$ALLMAINNET_TOKENS"
# Cronos (25)
CRONOS_TOKENS="
0x99B3511A2d315A497C8112C1fdd8D508d4B1E506:WETH9:18
0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6:WETH10:18
0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85:LINK:18
0x948690147D2e50ffe50C5d38C14125aD6a9FA036:USDW:2
0x58a8D8F78F1B65c06dAd7542eC46b299629A60dd:EURW:2
0xFb4B6Cc81211F7d886950158294A44C312abCA29:GBPW:2
0xf9f5D0ACD71C76F9476F10B3F3d3E201F0883C68:AUDW:2
0xeE17bB0322383fecCA2784fbE2d4CD7d02b1905B:JPYW:2
0xc9750828124D4c10e7a6f4B655cA8487bD3842EB:CHFW:2
0x328Cd365Bb35524297E68ED28c6fF2C9557d1363:CADW:2
"
report_network "Cronos" "$RPC_25" "25" "CRO" "$CRONOS_TOKENS"
# Polygon
POLYGON_TOKENS="
0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619:WETH:18
0xc2132D05D31c914a87C6611C10748AEb04B58e8F:USDT:6
0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174:USDC:6
0xb0897686c545045aFc77CF20eA7Ee945E98F291e:LINK:18
"
report_network "Polygon" "$RPC_137" "137" "MATIC" "$POLYGON_TOKENS"
# Base
BASE_TOKENS="
0x4200000000000000000000000000000000000006:WETH:18
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913:USDC:6
0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb:DAI:18
"
report_network "Base" "$RPC_8453" "8453" "ETH" "$BASE_TOKENS"
# Optimism
OPTIMISM_TOKENS="
0x4200000000000000000000000000000000000006:WETH:18
0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85:USDC:6
0x94b008aA00579c1307B0EF2c499aD98a8ce58e58:USDT:6
"
report_network "Optimism" "$RPC_10" "10" "ETH" "$OPTIMISM_TOKENS"
# BSC (56)
BSC_TOKENS="
0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173c095c:WBNB:18
0x55d398326f99059fF775485246999027B3197955:USDT:18
0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d:USDC:18
0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c:BTCB:18
"
report_network "BSC (BNB Chain)" "$RPC_56" "56" "BNB" "$BSC_TOKENS"
# Avalanche C-Chain
AVAX_TOKENS="
0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7:WAVAX:18
0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7:USDT:6
0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E:USDC:6
"
report_network "Avalanche C-Chain" "$RPC_43114" "43114" "AVAX" "$AVAX_TOKENS"
# Arbitrum One
ARBITRUM_TOKENS="
0x82aF49447D8a07e3bd95BD0d56f35241523fBab1:WETH:18
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9:USDT:6
0xaf88d065e77c8cC2239327C5EDb3A432268e5831:USDC:6
"
report_network "Arbitrum One" "$RPC_42161" "42161" "ETH" "$ARBITRUM_TOKENS"
# Sepolia (optional; no token list)
report_network "Ethereum Sepolia" "${ETHEREUM_SEPOLIA_RPC:-}" "11155111" "ETH" ""
# Polygon Amoy
report_network "Polygon Amoy" "${POLYGON_AMOY_RPC:-}" "80002" "MATIC" ""
# Base Sepolia
report_network "Base Sepolia" "${BASE_SEPOLIA_RPC:-}" "84532" "ETH" ""
# Optimism Sepolia
report_network "Optimism Sepolia" "${OPTIMISM_SEPOLIA_RPC:-}" "11155420" "ETH" ""
echo ""
echo "============================================"
echo "Done. Override RPCs via .env: RPC_URL_138, ETHEREUM_MAINNET_RPC, CHAIN_651940_RPC, CRONOS_RPC, etc."
echo "============================================"

View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
# Print cast commands for live trustless bridge test (138 -> mainnet) and optionally check LP/BondManager state.
# Does NOT send the lock tx; you run that and capture depositId from the Deposit event.
# Usage: ./scripts/deployment/live-test-trustless-bridge.sh [--check]
# --check Print LP getPoolStats(0) and BondManager totalEthHeld() for mainnet.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$REPO_ROOT"
[[ -f .env ]] && set -a && source .env && set +a
BOND_MANAGER="${BOND_MANAGER_MAINNET:-${BOND_MANAGER:-}}"
CHALLENGE_MANAGER="${CHALLENGE_MANAGER_MAINNET:-${CHALLENGE_MANAGER:-}}"
LIQUIDITY_POOL="${LIQUIDITY_POOL_ETH_MAINNET:-${LIQUIDITY_POOL:-}}"
INBOX_ETH="${INBOX_ETH_MAINNET:-${INBOX_ETH:-}}"
RPC_138="${RPC_URL_138:-${CHAIN_138_RPC_URL:-}}"
RPC_MAINNET="${ETHEREUM_MAINNET_RPC:-}"
if [[ "${1:-}" == "--check" ]]; then
echo "--- Mainnet LP ETH pool stats (AssetType 0) ---"
cast call "$LIQUIDITY_POOL" "getPoolStats(uint8)(uint256,uint256,uint256)" 0 --rpc-url "$RPC_MAINNET" 2>/dev/null || echo " (set LIQUIDITY_POOL and ETHEREUM_MAINNET_RPC)"
echo "--- BondManager totalEthHeld ---"
cast call "$BOND_MANAGER" "totalEthHeld()(uint256)" --rpc-url "$RPC_MAINNET" 2>/dev/null || echo " (set BOND_MANAGER and ETHEREUM_MAINNET_RPC)"
echo ""
fi
echo "=== Live test commands (138 -> mainnet) ==="
echo "Set: RECIPIENT (mainnet address), DEPOSIT_ID (from Lockbox Deposit event depositId — NOT the amount), AMOUNT_WEI (e.g. 1000000000000000 for 0.001 ether)"
echo ""
echo "Get DEPOSIT_ID after lock: ./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH> # or cast logs <TX> \"Deposit(...)\" --rpc-url \$RPC_URL_138"
echo ""
echo "1) Lock on Chain 138 (run this; then get DEPOSIT_ID from Deposit event):"
echo " cast send \$LOCKBOX_138 \"depositNative(address,bytes32)\" \$RECIPIENT \$(cast keccak \"live-test-\$(date +%s)\") --value 0.01ether --rpc-url \$RPC_URL_138 --private-key \$PRIVATE_KEY --legacy --gas-price \${GAS_PRICE_138:-1000000000}"
echo ""
echo "2) Bond for claim (run and set BOND=...):"
echo " BOND=\$(cast call \$BOND_MANAGER \"getRequiredBond(uint256)\" \$AMOUNT_WEI --rpc-url \$ETHEREUM_MAINNET_RPC)"
echo ""
echo "3) Submit claim on mainnet:"
echo " cast send \$INBOX_ETH \"submitClaim(uint256,address,uint256,address,bytes)\" \$DEPOSIT_ID 0x0000000000000000000000000000000000000000 \$AMOUNT_WEI \$RECIPIENT 0x --value \$BOND --rpc-url \$ETHEREUM_MAINNET_RPC --private-key \$PRIVATE_KEY"
echo ""
echo "4) After challenge window (e.g. 30 min), finalize:"
echo " cast send \$CHALLENGE_MANAGER \"finalizeClaim(uint256)\" \$DEPOSIT_ID --rpc-url \$ETHEREUM_MAINNET_RPC --private-key \$PRIVATE_KEY # CHALLENGE_MANAGER in .env"
echo ""
echo "5) Release bond:"
echo " cast send \$BOND_MANAGER \"releaseBond(uint256)\" \$DEPOSIT_ID --rpc-url \$ETHEREUM_MAINNET_RPC --private-key \$PRIVATE_KEY"
echo ""
echo "Full runbook: docs/bridge/trustless/DEPLOYMENT_GUIDE.md (Deploy, Configure, and Live Test section)"

View File

@@ -0,0 +1,145 @@
#!/usr/bin/env bash
# Preflight check for Config-Ready Chains (Gnosis, Cronos, Celo, Wemix) CCIP bridge deployment.
# Verifies: RPC connectivity, deployer address, native gas balance on each chain.
# Run before deploy-bridges-config-ready-chains.sh.
#
# Usage: ./scripts/deployment/preflight-config-ready-chains.sh [gnosis|cronos|celo|wemix|all]
# SKIP_BALANCE=1 ... # skip balance checks (RPC-only)
# DEPLOYER_ADDRESS=0x... # use specific address instead of deriving from PRIVATE_KEY
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
[[ -f "$PROJECT_ROOT/.env" ]] && set -a && source "$PROJECT_ROOT/.env" && set +a
SKIP_BALANCE="${SKIP_BALANCE:-0}"
CHAIN="${1:-all}"
# Chain config: name | chain_id | RPC_var | gas_token | min_recommended (human)
get_chain_config() {
case "$1" in
gnosis) echo "Gnosis|100|GNOSIS_RPC|xDAI|0.1" ;;
cronos) echo "Cronos|25|CRONOS_RPC|CRO|1" ;;
celo) echo "Celo|42220|CELO_RPC|CELO|0.1" ;;
wemix) echo "Wemix|1111|WEMIX_RPC|WEMIX|0.4" ;;
*) echo "" ;;
esac
}
# Default RPCs (from env or public)
GNOSIS_RPC="${GNOSIS_RPC:-https://rpc.gnosischain.com}"
CRONOS_RPC="${CRONOS_RPC:-https://evm.cronos.org}"
CELO_RPC="${CELO_RPC:-https://forno.celo.org}"
WEMIX_RPC="${WEMIX_RPC:-https://api.wemix.com}"
# Deployer
if [[ -n "${DEPLOYER_ADDRESS:-}" ]]; then
DEPLOYER="${DEPLOYER_ADDRESS}"
[[ "$DEPLOYER" != 0x* ]] && DEPLOYER="0x$DEPLOYER"
else
if [[ -z "${PRIVATE_KEY:-}" ]]; then
echo "Error: Set PRIVATE_KEY in .env or DEPLOYER_ADDRESS for read-only check" >&2
exit 1
fi
DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)
if [[ -z "$DEPLOYER" ]]; then
echo "Error: Could not derive deployer from PRIVATE_KEY (is 'cast' available?)" >&2
exit 1
fi
fi
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
check_chain() {
local key="$1"
local config
config=$(get_chain_config "$key")
[[ -z "$config" ]] && return 1
local name chain_id rpc_var gas_token min_rec
IFS='|' read -r name chain_id rpc_var gas_token min_rec <<< "$config"
local rpc="${!rpc_var:-}"
if [[ -z "$rpc" ]]; then
echo -e " ${RED}${NC} $name: $rpc_var not set in .env"
return 1
fi
# RPC connectivity
local res
res=$(curl -s -m 10 -X POST "$rpc" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' 2>/dev/null || true)
if [[ -z "$res" ]] || ! echo "$res" | grep -q '"result"'; then
echo -e " ${RED}${NC} $name: RPC unreachable ($rpc)"
return 1
fi
echo -e " ${GREEN}${NC} $name: RPC OK (chain $chain_id)"
if [[ "$SKIP_BALANCE" == "1" ]]; then
return 0
fi
# Balance check
local balance_wei
balance_wei=$(cast balance "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0")
local balance_eth
balance_eth=$(echo "scale=6; $balance_wei / 1000000000000000000" | bc 2>/dev/null || echo "0")
if [[ -z "$balance_wei" || "$balance_wei" == "0" ]]; then
echo -e " ${RED}${NC} Balance: 0 $gas_token (need $min_rec $gas_token)"
return 1
fi
# Compare: balance_eth >= min_rec (use bc for decimals)
if ! command -v bc >/dev/null 2>&1; then
echo -e " ${YELLOW}?${NC} Balance: $balance_eth $gas_token (bc not found, cannot compare)"
return 0
fi
if [[ "$(echo "$balance_eth >= $min_rec" | bc 2>/dev/null)" != "1" ]]; then
echo -e " ${YELLOW}${NC} Balance: $balance_eth $gas_token (recommended: $min_rec $gas_token)"
return 1
fi
echo -e " ${GREEN}${NC} Balance: $balance_eth $gas_token"
return 0
}
run_checks() {
local keys
case "$CHAIN" in
gnosis) keys="gnosis" ;;
cronos) keys="cronos" ;;
celo) keys="celo" ;;
wemix) keys="wemix" ;;
all) keys="gnosis cronos celo wemix" ;;
*) echo "Usage: $0 [gnosis|cronos|celo|wemix|all]"; exit 1 ;;
esac
local failed=0
for k in $keys; do
if ! check_chain "$k"; then
failed=1
fi
done
return $failed
}
echo "=== Preflight: Config-Ready Chains (Gnosis, Cronos, Celo, Wemix) ==="
echo "Deployer: ${DEPLOYER:0:10}...${DEPLOYER: -8}"
echo "SKIP_BALANCE=$SKIP_BALANCE CHAIN=$CHAIN"
echo ""
if run_checks; then
echo ""
echo "Preflight OK. Run: ./scripts/deployment/deploy-bridges-config-ready-chains.sh $CHAIN"
exit 0
else
echo ""
echo "Preflight failed. Fix RPCs and gas balances before deploy."
echo " Gas tokens: Gnosis=xDAI, Cronos=CRO, Celo=CELO, Wemix=WEMIX"
echo " Recommended: Gnosis 0.1, Cronos 1, Celo 0.1, Wemix 0.4"
exit 1
fi

View File

@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script, console} from "forge-std/Script.sol";
import {ChainRegistry} from "../../contracts/registry/ChainRegistry.sol";
/**
* @title RegisterAllMainnet
* @notice Register ALL Mainnet (651940) in ChainRegistry
* @dev Run this after deploying AlltraAdapter
*/
contract RegisterAllMainnet is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
address deployer = vm.addr(deployerPrivateKey);
// Load environment variables
address registryAddress = vm.envOr("CHAIN_REGISTRY_ADDRESS", address(0));
address alltraAdapterAddress = vm.envOr("ALLTRA_ADAPTER_ADDRESS", address(0));
require(registryAddress != address(0), "CHAIN_REGISTRY_ADDRESS not set");
require(alltraAdapterAddress != address(0), "ALLTRA_ADAPTER_ADDRESS not set");
console.log("Registering ALL Mainnet (651940) in ChainRegistry");
console.log("Registry:", vm.toString(registryAddress));
console.log("Adapter:", vm.toString(alltraAdapterAddress));
vm.startBroadcast(deployerPrivateKey);
ChainRegistry registry = ChainRegistry(registryAddress);
// Register ALL Mainnet as EVM chain
// Parameters:
// - chainId: 651940
// - adapter: AlltraAdapter address
// - explorerUrl: https://alltra.global
// - minConfirmations: 12 (standard EVM)
// - avgBlockTime: 2 seconds (TBD - verify actual block time)
// - additionalData: empty (can include CCIP selector if available later)
registry.registerEVMChain(
651940, // chainId
alltraAdapterAddress, // adapter
"https://alltra.global", // explorerUrl
12, // minConfirmations
2, // avgBlockTime (seconds) - TODO: Verify actual block time
"" // additionalData
);
vm.stopBroadcast();
console.log("\n=== Registration Summary ===");
console.log("Chain ID: 651940");
console.log("Chain Name: ALL Mainnet");
console.log("Adapter:", vm.toString(alltraAdapterAddress));
console.log("Explorer: https://alltra.global");
console.log("Min Confirmations: 12");
console.log("Avg Block Time: 2 seconds");
console.log("\n✅ ALL Mainnet registered successfully!");
console.log("\nNext Steps:");
console.log("1. Verify chain registration: cast call <REGISTRY> 'evmChains(uint256)(uint256,string,uint8,address,bool,uint256,uint256,bool,string,string,bytes)' 651940 --rpc-url <RPC>");
console.log("2. Test adapter: Verify AlltraAdapter.getChainIdentifier() returns (651940, 'ALL-Mainnet')");
console.log("3. Update routing services to use AlltraAdapter for chain 651940");
}
}

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
# Run all deployment tasks in parallel where possible.
# Respects dependency order. Requires .env with PRIVATE_KEY, RPC URLs.
# Usage: ./scripts/deployment/run-all-deployments-parallel.sh [chain]
# chain: chain138 (default), cronos, mainnet
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
CHAIN="${1:-chain138}"
case "$CHAIN" in
chain138) RPC="${RPC_URL_138:-$CHAIN138_RPC_URL}"; CHAIN_ID=138 ;;
cronos) RPC="${CRONOS_RPC_URL:-https://evm.cronos.org}"; CHAIN_ID=25 ;;
mainnet) RPC="${ETHEREUM_MAINNET_RPC}"; CHAIN_ID=1 ;;
*) echo "Unknown chain: $CHAIN"; exit 1 ;;
esac
echo "=== Parallel Deployment: $CHAIN (chain $CHAIN_ID) ==="
echo "RPC: $RPC"
echo ""
# Phase 1: Independent deployments (run in parallel)
echo "Phase 1: Core (parallel)..."
(
forge script script/DeployMulticall.s.sol:DeployMulticall --rpc-url "$RPC" --broadcast &
forge script script/DeployOracle.s.sol:DeployOracle --rpc-url "$RPC" --broadcast &
wait
) 2>&1 | tee /tmp/deploy-phase1.log || true
# Phase 2: Depends on Phase 1 (CREATE2 if needed for deterministic)
echo ""
echo "Phase 2: CREATE2Factory (if not exists)..."
if [ -z "${CREATE2_FACTORY:-}" ] || [ "$CREATE2_FACTORY" = "0x0000000000000000000000000000000000000000" ]; then
forge script script/Deploy.s.sol:Deploy --rpc-url "$RPC" --broadcast 2>&1 || true
fi
# Phase 3: Token/Reserve (require TOKEN_FACTORY etc.)
echo ""
echo "Phase 3: Token systems (require existing deps)..."
# DeployChain138, DeployISO4217WSystem, etc. — run if deps present
echo ""
echo "Deployment batch complete. Check logs for any failures."
echo "Note: Chain 138 may show 'Replacement transaction underpriced' if mempool has stuck tx."

View File

@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Run liquidity-gap tasks (G1G4) using .env. Phase and G4 amounts via tags (not .env).
#
# Usage:
# ./scripts/deployment/run-all-four-gaps.sh # run all phases (G4 interactive if no amounts)
# ./scripts/deployment/run-all-four-gaps.sh g1 g4 # run only G1 and G4
# ./scripts/deployment/run-all-four-gaps.sh g4 --eth 1 --weth 0.5 # G4 with amounts (no prompt)
# ./scripts/deployment/run-all-four-gaps.sh g4 # G4 with interactive prompt
#
# Phases: g1 (PMM on L2s), g2g3 (Trustless + Lockbox on L2s), g4 (fund mainnet LP).
# G4 amounts: use --eth, --weth, --eth-wei, --weth-wei (see fund-mainnet-lp.sh).
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
DOTENV="${ENV_FILE:-$PROJECT_ROOT/.env}"
if [[ ! -f "$DOTENV" ]]; then
echo "No .env at $DOTENV. Create from .env.example and set PRIVATE_KEY, RPCs, token addresses. Or set ENV_FILE."
exit 1
fi
# Parse phase tags (g1, g2g3, g4); remaining args may include G2G3 tags (--lockbox, --chain) and G4 tags (--eth, --weth)
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
parse_phase_tags "$@"
REMAINING=("${PARSE_PHASE_TAGS_REMAINING[@]}")
parse_lockbox_tag "${REMAINING[@]}"
parse_chain_filter "${PARSE_LOCKBOX_REMAINING[@]}"
G4_ARGS=("${PARSE_CHAIN_FILTER_REMAINING[@]}")
G2G3_ARGS=()
[[ "${TRUSTLESS_DEPLOY_LOCKBOX:-1}" == "1" ]] && G2G3_ARGS+=(--lockbox) || G2G3_ARGS+=(--no-lockbox)
[[ ${#CHAIN_FILTER[@]} -gt 0 ]] && G2G3_ARGS+=(--chain "${CHAIN_FILTER[@]}")
echo "=============================================="
echo "Running liquidity gaps (secrets from .env)"
echo "=============================================="
if [[ "$RUN_G1" == "1" ]]; then
echo ""
echo "--- G1: Deploy PMM on L2s ---"
./scripts/deployment/deploy-pmm-all-l2s.sh || true
fi
if [[ "$RUN_G2G3" == "1" ]]; then
echo ""
echo "--- G2/G3: Deploy Trustless (+ Lockbox) on L2s ---"
./scripts/deployment/deploy-trustless-l2s.sh "${G2G3_ARGS[@]}" || true
fi
if [[ "$RUN_G4" == "1" ]]; then
echo ""
echo "--- G4: Fund mainnet LP ---"
./scripts/deployment/fund-mainnet-lp.sh "${G4_ARGS[@]}" || true
fi
echo ""
echo "Done. Update .env with any new contract addresses printed above."

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env bash
# E2E live test: lock on 138 -> submit claim on mainnet -> (after 30 min) finalize -> release bond.
# Run from a host that can reach RPC_URL_138. Requires .env in smom-dbis-138 repo root.
# Best: cd /path/to/smom-dbis-138 then ./scripts/deployment/run-e2e-trustless-live-test.sh
#
# Usage:
# ./scripts/deployment/run-e2e-trustless-live-test.sh # run step 1 (lock), then print steps 23
# ./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH> # print DEPOSIT_ID from lock tx
# DEPOSIT_ID=0x... AMOUNT_WEI=1000000000000000 ./scripts/deployment/run-e2e-trustless-live-test.sh claim # run step 2 only
# DEPOSIT_ID=0x... ./scripts/deployment/run-e2e-trustless-live-test.sh finalize # run step 3 only
set -euo pipefail
# Resolve repo root from script path so this works from any cwd (use full path to script when invoking)
SCRIPT_PATH="${BASH_SOURCE[0]}"
[[ -z "$SCRIPT_PATH" ]] && SCRIPT_PATH="$0"
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
if [[ ! -d "$REPO_ROOT" ]]; then
echo "Error: REPO_ROOT not found: $REPO_ROOT. Run from smom-dbis-138 repo, e.g. cd /path/to/smom-dbis-138 && ./scripts/deployment/run-e2e-trustless-live-test.sh"
exit 1
fi
cd "$REPO_ROOT" || { echo "Error: cannot cd to $REPO_ROOT"; exit 1; }
[[ -f .env ]] && set -a && source .env && set +a
# Use _MAINNET variants if unsuffixed not set (for .env that only has _MAINNET)
export BOND_MANAGER="${BOND_MANAGER:-${BOND_MANAGER_MAINNET:-}}"
export CHALLENGE_MANAGER="${CHALLENGE_MANAGER:-${CHALLENGE_MANAGER_MAINNET:-}}"
export INBOX_ETH="${INBOX_ETH:-${INBOX_ETH_MAINNET:-}}"
export LOCKBOX_138="${LOCKBOX_138:-}"
export RPC_URL_138="${RPC_URL_138:-${CHAIN_138_RPC_URL:-}}"
export ETHEREUM_MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-}"
# Require key and RPCs so we fail with a clear message instead of "Invalid params"
[[ -n "${PRIVATE_KEY:-}" ]] || { echo "PRIVATE_KEY not set in .env"; exit 1; }
RECIPIENT=$(cast wallet address "$PRIVATE_KEY")
NONCE=$(cast keccak "e2e-$(date +%s)" | tr -d '\n\r')
# 0.001 ether in wei
AMOUNT_WEI="${AMOUNT_WEI:-1000000000000000}"
case "${1:-}" in
get-deposit-id)
[[ -n "${RPC_URL_138:-}" ]] || { echo "RPC_URL_138 not set"; exit 1; }
LOCK_TX="${2:-}"
[[ -n "$LOCK_TX" ]] || { echo "Usage: $0 get-deposit-id <LOCK_TX_HASH>"; exit 1; }
# Deposit event: first indexed param is depositId (topics[1])
DEPOSIT_ID_HEX=$(cast receipt "$LOCK_TX" --rpc-url "$RPC_URL_138" -j 2>/dev/null | jq -r '.logs[0].topics[1] // empty')
if [[ -z "$DEPOSIT_ID_HEX" ]]; then
echo "No Deposit log in tx or jq failed. Try: cast logs $LOCK_TX \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138"
exit 1
fi
# cast expects uint256 as decimal or 0x; topics are 32-byte hex (0x + 64 chars)
echo "$DEPOSIT_ID_HEX"
exit 0
;;
claim)
[[ -n "${ETHEREUM_MAINNET_RPC:-}" ]] || { echo "ETHEREUM_MAINNET_RPC not set"; exit 1; }
[[ -n "${INBOX_ETH:-}" && -n "${BOND_MANAGER:-}" ]] || { echo "INBOX_ETH and BOND_MANAGER must be set for claim"; exit 1; }
if [[ -z "${DEPOSIT_ID:-}" ]]; then
echo "Set DEPOSIT_ID (from step 1 lock tx Deposit event). Example: DEPOSIT_ID=0x... $0 claim"
echo "To get DEPOSIT_ID from lock tx: cast logs <LOCK_TX_HASH> \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138"
echo " Use the first decoded arg (depositId) as DEPOSIT_ID. Do NOT use AMOUNT_WEI as DEPOSIT_ID."
exit 1
fi
# Avoid common mistake: DEPOSIT_ID must be the event's depositId (large/hash), not the amount
if [[ "${DEPOSIT_ID:-}" == "1000000000000000" ]] || [[ "${DEPOSIT_ID:-}" == "$AMOUNT_WEI" ]]; then
echo "Error: DEPOSIT_ID looks like AMOUNT_WEI (0.001 ether). Set DEPOSIT_ID to the depositId from the Deposit event, not the amount."
exit 1
fi
BOND=$(cast call "$BOND_MANAGER" "getRequiredBond(uint256)(uint256)" "$AMOUNT_WEI" --rpc-url "$ETHEREUM_MAINNET_RPC")
# cast may append " [1e18]" etc.; use only the numeric part for --value
BOND="${BOND%% *}"
echo "BOND (required for claim): $BOND wei"
cast send "$INBOX_ETH" "submitClaim(uint256,address,uint256,address,bytes)" \
"$DEPOSIT_ID" 0x0000000000000000000000000000000000000000 "$AMOUNT_WEI" "$RECIPIENT" 0x \
--value "$BOND" --rpc-url "$ETHEREUM_MAINNET_RPC" --private-key "$PRIVATE_KEY"
echo "Claim submitted. Wait ~30 min then run: DEPOSIT_ID=$DEPOSIT_ID $0 finalize"
exit 0
;;
finalize)
[[ -n "${ETHEREUM_MAINNET_RPC:-}" ]] || { echo "ETHEREUM_MAINNET_RPC not set"; exit 1; }
[[ -n "${CHALLENGE_MANAGER:-}" && -n "${BOND_MANAGER:-}" ]] || { echo "CHALLENGE_MANAGER and BOND_MANAGER must be set for finalize"; exit 1; }
if [[ -z "${DEPOSIT_ID:-}" ]]; then
echo "Set DEPOSIT_ID. Example: DEPOSIT_ID=0x... $0 finalize"
exit 1
fi
cast send "$CHALLENGE_MANAGER" "finalizeClaim(uint256)" "$DEPOSIT_ID" \
--rpc-url "$ETHEREUM_MAINNET_RPC" --private-key "$PRIVATE_KEY"
cast send "$BOND_MANAGER" "releaseBond(uint256)" "$DEPOSIT_ID" \
--rpc-url "$ETHEREUM_MAINNET_RPC" --private-key "$PRIVATE_KEY"
echo "Finalized and bond released."
exit 0
;;
esac
# Step 1: Lock on 138
[[ -n "${RPC_URL_138:-}" ]] || { echo "RPC_URL_138 not set (required for lock on 138)"; exit 1; }
[[ -n "${LOCKBOX_138:-}" ]] || { echo "LOCKBOX_138 not set in .env"; exit 1; }
# Fail fast if RPC is not Chain 138 (avoids -32602 Invalid params from wrong chain)
CHAIN_ID=$(curl -s -m 5 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' "$RPC_URL_138" 2>/dev/null | sed -n 's/.*"result":"\([^"]*\)".*/\1/p')
if [[ "$CHAIN_ID" != "0x8a" && "$CHAIN_ID" != "0x8A" ]]; then
echo "Error: RPC_URL_138 ($RPC_URL_138) returned chainId=$CHAIN_ID; expected 0x8a (138). Fix .env and retry."
exit 1
fi
echo "Step 1: Lock 0.001 ether on Chain 138 (LOCKBOX_138=$LOCKBOX_138)"
echo "RECIPIENT=$RECIPIENT NONCE=$NONCE"
# Use explicit --gas-limit to avoid eth_estimateGas -32602 Invalid params on some Chain 138 (Besu) nodes
cast send "$LOCKBOX_138" "depositNative(address,bytes32)" "$RECIPIENT" "$NONCE" \
--value 0.001ether --rpc-url "$RPC_URL_138" --private-key "$PRIVATE_KEY" \
--legacy --gas-price "${GAS_PRICE_138:-1000000000}" --gas-limit "${GAS_LIMIT_138:-200000}"
echo ""
echo "Get DEPOSIT_ID from the lock tx (run with the tx hash from above):"
echo " export DEPOSIT_ID=\$(./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH>)"
echo " AMOUNT_WEI=$AMOUNT_WEI $0 claim"
echo "Or manually: cast logs <LOCK_TX_HASH> \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138 (use first decoded arg)"
echo "Note: DEPOSIT_ID is the event's depositId, NOT the amount. Required bond for 0.001 ether is 1 ETH (min bond)."

View File

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
# Run PMM phase (DeployDODOPMMIntegration) and optionally DeployPrivatePoolRegistryAndPools.
# Requires: .env with DODO_VENDING_MACHINE_ADDRESS, COMPLIANT_USDT_ADDRESS, COMPLIANT_USDC_ADDRESS,
# OFFICIAL_USDT_ADDRESS, OFFICIAL_USDC_ADDRESS (see docs/integration/DODO_PMM_INTEGRATION.md).
# For XAU pools: set DODOPMM_INTEGRATION_ADDRESS and XAU_ADDRESS_138 after the first run.
# Usage: ./scripts/deployment/run-pmm-and-pools.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
load_deployment_env
# Reject unset, empty, or zero address (0x0 or 0x000...)
if [[ -z "${DODO_VENDING_MACHINE_ADDRESS:-}" ]]; then
echo "DODO_VENDING_MACHINE_ADDRESS not set. Set it to the DODO DVM factory on Chain 138 (see docs/deployment/ALL_MAINNETS_DEPLOYMENT_RUNBOOK.md)."
exit 1
fi
# Reject 0x0 or 0x000...000 (zero address)
if [[ "$(echo "${DODO_VENDING_MACHINE_ADDRESS}" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')" =~ ^0x0+$ ]]; then
echo "DODO_VENDING_MACHINE_ADDRESS is zero. Set it to the DVM factory on Chain 138."
exit 1
fi
echo "=== Deploy DODOPMMIntegration (Chain 138) ==="
bash "$SCRIPT_DIR/deploy-all-mainnets-with-mapper-oracle-pmm.sh" pmm
if [[ -n "${DODO_PMM_INTEGRATION:-}" || -n "${DODOPMM_INTEGRATION_ADDRESS:-}" ]]; then
addr="${DODO_PMM_INTEGRATION:-$DODOPMM_INTEGRATION_ADDRESS}"
echo ""
echo "DODOPMMIntegration at $addr. Create cUSDT/USDT and cUSDC/USDC pools via createCUSDTUSDTPool/createCUSDCUSDCPool (see docs/integration/DODO_PMM_INTEGRATION.md)."
if [[ -n "${XAU_ADDRESS_138:-}" ]]; then
echo "=== Deploy PrivatePoolRegistry and XAU-anchored pools ==="
forge script script/dex/DeployPrivatePoolRegistryAndPools.s.sol:DeployPrivatePoolRegistryAndPools \
--rpc-url "$RPC_URL_138" --broadcast --private-key "$PRIVATE_KEY" \
--with-gas-price "${GAS_PRICE_138:-1000000000}" --legacy -vvv || true
else
echo "Set XAU_ADDRESS_138 and DODOPMM_INTEGRATION_ADDRESS in .env to deploy XAU-anchored pools (DeployPrivatePoolRegistryAndPools)."
fi
else
echo "Set DODO_PMM_INTEGRATION or DODOPMM_INTEGRATION_ADDRESS in .env after deploy, then re-run for pool creation."
fi

View File

@@ -0,0 +1,143 @@
#!/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
# Ensure .env is loaded (for PRIVATE_KEY, RPCs, etc.)
[[ -f ".env" ]] && set -a && source ".env" && set +a
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:-0x79cdbaFBaA0FdF9F55D26F360F54cddE5c743F7D}}"
POOL_CUSDTCUSDC="${POOL_CUSDTCUSDC:-0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8}"
POOL_CUSDTUSDT="${POOL_CUSDTUSDT:-0xa3Ee6091696B28e5497b6F491fA1e99047250c59}"
POOL_CUSDCUSDC="${POOL_CUSDCUSDC:-0x90bd9Bf18Daa26Af3e814ea224032d015db58Ea5}"
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 in parallel (if not already created — scripts will fail if pool exists)
log "Creating PMM pools (parallel)..."
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 ) &
PID1=$!
( 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 ) &
PID2=$!
( 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 ) &
PID3=$!
wait $PID1 2>/dev/null || true
wait $PID2 2>/dev/null || true
wait $PID3 2>/dev/null || 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."

View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Run G2/G3 (Trustless + Lockbox) on the chains that previously failed: BSC, POLYGON, BASE, OPTIMISM, CRONOS.
# Fixes nonce for Cronos by clearing broadcast cache first; uses --slow and delay between chains to avoid 429/nonce issues.
# Tags: --delay <sec>, --lockbox / --no-lockbox.
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"
source "$SCRIPT_DIR/../lib/deployment/prompts.sh"
load_deployment_env
parse_delay_tag "$@"
parse_lockbox_tag "${PARSE_DELAY_REMAINING[@]}"
TRUSTLESS_SCRIPT="script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge"
DELAY_BETWEEN_CHAINS="${DELAY_BETWEEN_CHAINS:-45}"
echo "=============================================="
echo "G2/G3 remaining: BSC, POLYGON, BASE, OPTIMISM, CRONOS (nonce fix for Cronos)"
echo "=============================================="
# Cronos: clear nonce cache then deploy
echo ""
echo "--- Fix nonce for Cronos (clear cache) ---"
./scripts/deployment/fix-nonce-and-retry.sh --chain cronos --script "$TRUSTLESS_SCRIPT" || true
echo ""
echo "--- Deploy Trustless + Lockbox on CRONOS (chain 25) ---"
rpc="${CRONOS_RPC_URL:-https://evm.cronos.org}"
weth="0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23"
TRUSTLESS_WETH_ADDRESS="$weth" TRUSTLESS_DEPLOY_LOCKBOX="${TRUSTLESS_DEPLOY_LOCKBOX:-1}" \
forge script script/bridge/trustless/DeployTrustlessBridge.s.sol:DeployTrustlessBridge \
--rpc-url "$rpc" --chain-id 25 --broadcast --private-key "$PRIVATE_KEY" --slow -vvv || true
sleep "$DELAY_BETWEEN_CHAINS"
# BSC, Polygon, Base, Optimism with delay between each
for name in BSC POLYGON BASE OPTIMISM; do
echo ""
echo "--- Deploy Trustless + Lockbox on $name ---"
if [[ "${TRUSTLESS_DEPLOY_LOCKBOX:-1}" == "1" ]]; then
./scripts/deployment/deploy-trustless-l2s.sh --chain "$name" --lockbox || true
else
./scripts/deployment/deploy-trustless-l2s.sh --chain "$name" --no-lockbox || true
fi
sleep "$DELAY_BETWEEN_CHAINS"
done
echo ""
echo "Done. Update .env with BondManager, ChallengeManager, LiquidityPool, Inbox, Lockbox per chain."

View File

@@ -36,21 +36,23 @@ update_var() {
fi
}
# Update the provided variables
# Update the provided variables (use placeholders; set real values in .env and never commit).
if [ ! -z "$1" ] && [ "$1" == "update" ]; then
update_var "ETHEREUM_MAINNET_RPC" "https://mainnet.infura.io/v3/43b945b33d58463a9246cf5ca8aa6286"
update_var "RPC_URL_138" "http://192.168.11.250"
update_var "ETHERSCAN_API_KEY" "89HVZNN68DWKWVZHQRGQJ1B74FGKWBJV1W"
update_var "ETHEREUM_MAINNET_RPC" "https://mainnet.infura.io/v3/<INFURA_PROJECT_ID>"
update_var "RPC_URL_138" "http://192.168.11.211:8545"
update_var "ETHERSCAN_API_KEY" "<YOUR_ETHERSCAN_API_KEY>"
update_var "INFURA_PROJECT_ID" "<YOUR_INFURA_PROJECT_ID>"
update_var "INFURA_PROJECT_SECRET" "<YOUR_INFURA_PROJECT_SECRET>"
echo ""
echo "✓ Environment variables updated"
echo "✓ Environment variables updated with placeholders"
echo " Set real values in .env (INFURA_PROJECT_ID, INFURA_PROJECT_SECRET, ETHERSCAN_API_KEY); never commit secrets."
echo ""
echo "Run: ./scripts/deployment/check-env-requirements.sh to verify"
else
echo "Usage: $0 update"
echo ""
echo "This will update:"
echo " - ETHEREUM_MAINNET_RPC"
echo " - RPC_URL_138"
echo " - ETHERSCAN_API_KEY"
echo "This will set placeholders for:"
echo " - ETHEREUM_MAINNET_RPC (Infura), RPC_URL_138, ETHERSCAN_API_KEY"
echo " - INFURA_PROJECT_ID, INFURA_PROJECT_SECRET (for Infura RPC + Basic Auth)"
fi

View File

@@ -1,41 +1,48 @@
#!/bin/bash
# Verify All RPC Endpoints
# This script tests connectivity to all configured RPC endpoints
#!/usr/bin/env bash
# Verify All RPC Endpoints — tests connectivity to Mainnet, Chain 138, and all configured chain RPCs.
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
echo "=== RPC Endpoint Verification ==="
echo ""
# Load environment variables
if [ -f .env ]; then
export $(cat .env | grep -v '^#' | grep -v '^$' | xargs)
set -a
source .env
set +a
fi
# Use Infura with Basic Auth when INFURA_PROJECT_SECRET is set (fixes "error sending request" from Infura)
[ -f "${PROJECT_ROOT}/scripts/lib/infura.sh" ] && source "${PROJECT_ROOT}/scripts/lib/infura.sh"
if ! command -v cast &> /dev/null; then
echo "Error: cast command not found. Install foundry to verify RPC endpoints."
exit 1
fi
# Function to test RPC
# Function to test RPC (uses Infura Basic Auth URL when INFURA_PROJECT_SECRET is set)
test_rpc() {
local name=$1
local url=$2
[ -n "$url" ] && type ensure_infura_rpc_url &>/dev/null && url=$(ensure_infura_rpc_url "$url")
if [ -z "$url" ] || [ "$url" == "http://chain138.example.com:8545" ] || [[ "$url" == *"YOUR_PROJECT_ID"* ]]; then
if [ -z "$url" ] || [ "$url" == "http://chain138.example.com:8545" ] || [[ "$url" == *"YOUR_PROJECT_ID"* ]] || [[ "$url" == *"<"* ]]; then
echo "$name: Not configured"
return
fi
echo -n "Testing $name... "
BLOCK=$(cast block-number --rpc-url "$url" 2>&1)
if [ $? -eq 0 ] && [[ "$BLOCK" =~ ^[0-9]+$ ]]; then
BLOCK=$(cast block-number --rpc-url "$url" 2>&1) || true
if [[ "$BLOCK" =~ ^[0-9]+$ ]]; then
echo "✓ Connected (block: $BLOCK)"
else
echo "✗ Failed: $BLOCK"
echo "✗ Failed (${BLOCK:0:80})"
fi
return 0
}
echo "--- Required RPC Endpoints ---"
@@ -43,7 +50,7 @@ test_rpc "Ethereum Mainnet" "$ETHEREUM_MAINNET_RPC"
test_rpc "ChainID 138" "$RPC_URL_138"
echo ""
echo "--- Additional Network RPC Endpoints ---"
echo "--- Additional Network RPC Endpoints (Infura when set) ---"
test_rpc "Ethereum Sepolia" "$ETHEREUM_SEPOLIA_RPC"
test_rpc "Polygon Mainnet" "$POLYGON_MAINNET_RPC"
test_rpc "Polygon Amoy" "$POLYGON_AMOY_RPC"
@@ -51,6 +58,19 @@ test_rpc "Base Mainnet" "$BASE_MAINNET_RPC"
test_rpc "Base Sepolia" "$BASE_SEPOLIA_RPC"
test_rpc "Optimism Mainnet" "$OPTIMISM_MAINNET_RPC"
test_rpc "Optimism Sepolia" "$OPTIMISM_SEPOLIA_RPC"
test_rpc "Arbitrum Mainnet" "$ARBITRUM_MAINNET_RPC"
test_rpc "Arbitrum Sepolia" "$ARBITRUM_SEPOLIA_RPC"
test_rpc "Avalanche Mainnet" "$AVALANCHE_MAINNET_RPC"
test_rpc "Avalanche Fuji" "$AVALANCHE_FUJI_RPC"
test_rpc "BSC Mainnet" "$BSC_MAINNET_RPC"
test_rpc "Celo Mainnet" "$CELO_MAINNET_RPC"
test_rpc "Linea Mainnet" "$LINEA_MAINNET_RPC"
echo ""
echo "--- Other chain RPCs (aliases / public fallbacks) ---"
test_rpc "AVALANCHE_RPC_URL" "${AVALANCHE_RPC_URL:-}"
test_rpc "ARBITRUM_RPC" "${ARBITRUM_MAINNET_RPC:-$ARBITRUM_RPC}"
test_rpc "Cronos" "$CRONOS_RPC_URL"
echo ""
echo "=== Verification Complete ==="

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env bash
# Verify CCIPLogger on Etherscan-V2-supported chains (BSC, Polygon, Gnosis, Optimism, Base, Arbitrum, Avalanche).
# Prerequisite: Deploy CCIPLogger per chain (deploy-ccip-logger-all-chains.sh) and set in .env:
# CCIP_LOGGER_BSC, CCIP_BSC_ROUTER (and same for polygon, gnosis, optimism, base, arbitrum, avalanche).
# Mainnet: already verified (see COMPLETION_RUN_WITH_KEYS_20260223.md). Cronos: not Etherscan V2; use Cronoscan.
# Usage: cd smom-dbis-138 && ./scripts/deployment/verify-ccip-logger-other-chains.sh
# Requires: ETHERSCAN_API_KEY and PRIVATE_KEY in .env; npm/hardhat.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
if [[ -f .env ]]; then
set -a
source .env
set +a
fi
AUTH_SIGNER="${AUTHORIZED_SIGNER:-0x0000000000000000000000000000000000000000}"
SOURCE_CHAIN_SELECTOR="${CHAIN138_SELECTOR:-138}"
# Network -> env suffix (logger address, router). mainnet skipped (already verified); cronos skipped (no V2).
declare -A LOGGER_VAR=(
[bsc]=CCIP_LOGGER_BSC
[polygon]=CCIP_LOGGER_POLYGON
[gnosis]=CCIP_LOGGER_GNOSIS
[optimism]=CCIP_LOGGER_OPTIMISM
[base]=CCIP_LOGGER_BASE
[arbitrum]=CCIP_LOGGER_ARBITRUM
[avalanche]=CCIP_LOGGER_AVALANCHE
)
declare -A ROUTER_VAR=(
[bsc]=CCIP_BSC_ROUTER
[polygon]=CCIP_POLYGON_ROUTER
[gnosis]=CCIP_GNOSIS_ROUTER
[optimism]=CCIP_OPTIMISM_ROUTER
[base]=CCIP_BASE_ROUTER
[arbitrum]=CCIP_ARBITRUM_ROUTER
[avalanche]=CCIP_AVALANCHE_ROUTER
)
if [[ -z "${ETHERSCAN_API_KEY:-}" ]]; then
echo "ETHERSCAN_API_KEY not set. Add to .env and re-run." >&2
exit 1
fi
VERIFIED=0
SKIPPED=0
FAILED=0
for net in bsc polygon gnosis optimism base arbitrum avalanche; do
addr_var="${LOGGER_VAR[$net]}"
router_var="${ROUTER_VAR[$net]}"
addr="${!addr_var:-}"
router="${!router_var:-}"
if [[ -z "$addr" || "$addr" = "0x0000000000000000000000000000000000000000" ]]; then
echo "[$net] Skip (no $addr_var in .env)"
SKIPPED=$((SKIPPED + 1))
continue
fi
if [[ -z "$router" || "$router" = "0x0000000000000000000000000000000000000000" ]]; then
echo "[$net] Skip ($addr_var set but $router_var missing)"
SKIPPED=$((SKIPPED + 1))
continue
fi
echo "[$net] Verifying CCIPLogger $addr ..."
if npx hardhat verify --network "$net" "$addr" "$router" "$AUTH_SIGNER" "$SOURCE_CHAIN_SELECTOR" 2>&1; then
echo "[$net] Verified."
VERIFIED=$((VERIFIED + 1))
else
echo "[$net] Verify failed (may already be verified)."
FAILED=$((FAILED + 1))
fi
done
echo ""
echo "Summary: $VERIFIED verified, $SKIPPED skipped (no address/router), $FAILED failed."
echo "To deploy first: ./scripts/deployment/deploy-ccip-logger-all-chains.sh then set CCIP_LOGGER_* and CCIP_*_ROUTER in .env."

View File

@@ -3,9 +3,19 @@
set -e
cd "$(dirname "$0")/../.."
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR/../.."
[ -f "$SCRIPT_DIR/../lib/init.sh" ] && source "$SCRIPT_DIR/../lib/init.sh" 2>/dev/null || true
# Color codes
# Color codes (fallbacks if init.sh not loaded)
: "${GREEN:=\033[0;32m}"
: "${RED:=\033[0;31m}"
: "${YELLOW:=\033[1;33m}"
: "${NC:=\033[0m}"
log_info() { echo "$@"; }
log_success() { echo "$@"; }
log_warn() { echo "$@"; }
log_error() { echo "$@" >&2; }
echo "==================================================================="
echo " CHAIN-138 FULL DEPLOYMENT VERIFICATION"
@@ -13,9 +23,17 @@ echo "==================================================================="
# Load environment variables
if [ -f .env ]; then
set +u
source .env 2>/dev/null || true
set -u 2>/dev/null || true
fi
# Optional vars (allow unset for graceful checks)
CHAIN138_CCIP_REPORTER="${CHAIN138_CCIP_REPORTER:-}"
CCIP_CHAIN138_ROUTER="${CCIP_CHAIN138_ROUTER:-$CCIP_ROUTER}"
CHAIN138_CCIP_WETH9_BRIDGE="${CHAIN138_CCIP_WETH9_BRIDGE:-$CCIPWETH9_BRIDGE_CHAIN138}"
CHAIN138_CCIP_WETH10_BRIDGE="${CHAIN138_CCIP_WETH10_BRIDGE:-$CCIPWETH10_BRIDGE_CHAIN138}"
ERRORS=0
WARNINGS=0
SUCCESS=0
@@ -133,7 +151,7 @@ if [ -n "$CHAIN138_CCIP_REPORTER" ] && [ "$CHAIN138_CCIP_REPORTER" != "" ]; then
check_status "CCIPTxReporter" "warning" "$CHAIN138_CCIP_REPORTER (address in .env, cannot verify on-chain)"
fi
else
check_status "CCIPTxReporter" "error" "Not deployed (no address in .env)"
check_status "CCIPTxReporter" "warning" "Not deployed (optional; set CHAIN138_CCIP_REPORTER when deployed)"
fi
# CCIP Router on Chain-138
@@ -236,7 +254,7 @@ if [ -f "genesis.json" ]; then
check_status "WETH10 in Genesis" "warning" "Not found in genesis.json"
fi
else
check_status "Genesis File" "error" "genesis.json not found"
check_status "Genesis File" "warning" "genesis.json not found (optional for RPC-only Chain 138)"
fi
# Check .env configuration

View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Verify all four Cronos contracts via Etherscan-style API.
# Uses explorer-api.cronos.org (module/action, solidity-standard-json-input).
# Run from smom-dbis-138/
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
if [ -z "${CRONOSCAN_API_KEY:-}" ]; then
echo "ERROR: CRONOSCAN_API_KEY not set. Set in .env (from explorer.cronos.org/register)."
exit 1
fi
export CRONOSCAN_API_KEY
echo "Cronos verification (Etherscan-style API)"
echo " API: https://explorer-api.cronos.org/mainnet/api"
echo " Chain: cronos (from foundry.toml)"
echo ""
verify() {
local addr="$1"
local contract="$2"
local extra_args="${3:-}"
echo "Verifying $contract at $addr..."
# shellcheck disable=SC2086
if forge verify-contract \
"$addr" "$contract" \
--chain cronos \
--etherscan-api-key "$CRONOSCAN_API_KEY" \
--skip-is-verified-check \
$extra_args \
--watch 2>&1; then
echo "$contract verified"
else
echo "$contract verification failed"
return 1
fi
}
FAIL=0
# WETH9 - no constructor args
verify "0x99B3511A2d315A497C8112C1fdd8D508d4B1E506" "contracts/tokens/WETH.sol:WETH" || FAIL=$((FAIL+1))
# WETH10 - no constructor args
verify "0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6" "contracts/tokens/WETH10.sol:WETH10" || FAIL=$((FAIL+1))
# CCIPWETH9Bridge - constructor(router, weth9, linkToken)
verify "0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e" "contracts/ccip/CCIPWETH9Bridge.sol:CCIPWETH9Bridge" \
"--constructor-args $(cast abi-encode 'constructor(address,address,address)' 0xE26B0A098D861d5C7d9434aD471c0572Ca6EAa67 0x99B3511A2d315A497C8112C1fdd8D508d4B1E506 0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85)" || FAIL=$((FAIL+1))
# CCIPWETH10Bridge - constructor(router, weth10, linkToken)
verify "0x105F8A15b819948a89153505762444Ee9f324684" "contracts/ccip/CCIPWETH10Bridge.sol:CCIPWETH10Bridge" \
"--constructor-args $(cast abi-encode 'constructor(address,address,address)' 0xE26B0A098D861d5C7d9434aD471c0572Ca6EAa67 0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6 0x8c80A01F461f297Df7F9DA3A4f740D7297C8Ac85)" || FAIL=$((FAIL+1))
echo ""
if [ "$FAIL" -eq 0 ]; then
echo "All four Cronos contracts verified."
exit 0
else
echo "$FAIL contract(s) failed."
echo ""
echo "Manual verification (recommended):"
echo " 1. ./scripts/deployment/export-cronos-verification-sources.sh"
echo " 2. Open https://explorer.cronos.org/verifyContract"
echo " 3. Follow docs/deployment/CRONOS_VERIFICATION_RUNBOOK.md"
echo ""
exit 1
fi

View File

@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# Verify deployed contracts on Avalanche, Arbitrum, Cronos.
# Requires ETHERSCAN_API_KEY (or SNOWTRACE_API_KEY, ARBISCAN_API_KEY, CRONOSCAN_API_KEY per chain).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
source .env 2>/dev/null || true
if [ -z "${ETHERSCAN_API_KEY:-}" ]; then
echo "ERROR: ETHERSCAN_API_KEY not set. Set in .env or export."
exit 1
fi
export SNOWTRACE_API_KEY="${SNOWTRACE_API_KEY:-$ETHERSCAN_API_KEY}"
export ARBISCAN_API_KEY="${ARBISCAN_API_KEY:-$ETHERSCAN_API_KEY}"
# Cronos not in Etherscan V2; needs separate CRONOSCAN_API_KEY from cronoscan.com (no fallback)
verify_one() {
local addr="$1"
local contract="$2"
local chain_arg="$3"
local chain_name="$4"
echo "Verifying $contract at $addr on $chain_name..."
# shellcheck disable=SC2086
forge verify-contract "$addr" "$contract" $chain_arg \
--etherscan-api-key "${ETHERSCAN_API_KEY}" \
--watch 2>/dev/null || echo " (may already be verified or need chain-specific API key)"
}
# Avalanche 43114
for addr in 0xa4B9DD039565AeD9641D45b57061f99d9cA6Df08 0x89dd12025bfCD38A168455A44B400e913ED33BE2 0xe0E93247376aa097dB308B92e6Ba36bA015535D0 0xAb57BF30F1354CA0590af22D8974c7f24DB2DbD7; do
case "$addr" in
0xa4B9DD039565AeD9641D45b57061f99d9cA6Df08) c="contracts/tokens/WETH.sol:WETH" ;;
0x89dd12025bfCD38A168455A44B400e913ED33BE2) c="contracts/tokens/WETH10.sol:WETH10" ;;
0xe0E93247376aa097dB308B92e6Ba36bA015535D0) c="contracts/ccip/CCIPWETH9Bridge.sol:CCIPWETH9Bridge" ;;
0xAb57BF30F1354CA0590af22D8974c7f24DB2DbD7) c="contracts/ccip/CCIPWETH10Bridge.sol:CCIPWETH10Bridge" ;;
esac
verify_one "$addr" "$c" "--chain avalanche" "Avalanche"
done
# Arbitrum 42161
for addr in 0x89dd12025bfCD38A168455A44B400e913ED33BE2 0xe0E93247376aa097dB308B92e6Ba36bA015535D0 0xAb57BF30F1354CA0590af22D8974c7f24DB2DbD7 0xa780ef19A041745d353c9432f2a7f5A241335ffE; do
case "$addr" in
0x89dd12025bfCD38A168455A44B400e913ED33BE2) c="contracts/tokens/WETH.sol:WETH" ;;
0xe0E93247376aa097dB308B92e6Ba36bA015535D0) c="contracts/tokens/WETH10.sol:WETH10" ;;
0xAb57BF30F1354CA0590af22D8974c7f24DB2DbD7) c="contracts/ccip/CCIPWETH9Bridge.sol:CCIPWETH9Bridge" ;;
0xa780ef19A041745d353c9432f2a7f5A241335ffE) c="contracts/ccip/CCIPWETH10Bridge.sol:CCIPWETH10Bridge" ;;
esac
verify_one "$addr" "$c" "--chain arbitrum" "Arbitrum"
done
# Cronos 25 — API: explorer-api.cronos.org/mainnet. Forge Blockscout verifier incompatible.
# Try: ./scripts/deployment/verify-cronos-contracts.sh (may fail; use manual fallback)
# See docs/04-configuration/CRONOS_EXPLORER_OPERATIONS.md
if [ -n "${CRONOSCAN_API_KEY:-}" ]; then
echo ""
echo "Cronos contracts: run ./scripts/deployment/verify-cronos-contracts.sh"
echo "If that fails, manual verification: export-cronos-verification-sources.sh then CRONOS_VERIFICATION_RUNBOOK.md"
echo " WETH9: 0x99B3511A2d315A497C8112C1fdd8D508d4B1E506"
echo " WETH10: 0x3304b747E565a97ec8AC220b0B6A1f6ffDB837e6"
echo " CCIPWETH9: 0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e"
echo " CCIPWETH10: 0x105F8A15b819948a89153505762444Ee9f324684"
echo ""
else
echo "Skipping Cronos: set CRONOSCAN_API_KEY (from explorer.cronos.org) for manual verification."
fi
echo "Verification complete."

View File

@@ -0,0 +1,121 @@
#!/usr/bin/env bash
# Verify deployed Trustless Bridge contracts (BondManager, LiquidityPool, Inbox, Lockbox) on each chain.
# Uses dotenv at smom-dbis-138/.env. Requires: cast (Foundry).
# Exit 0 if all checked addresses have code; non-zero if any missing.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DOTENV="$REPO_ROOT/.env"
cd "$REPO_ROOT"
[[ -f "$DOTENV" ]] && set -a && source "$DOTENV" && set +a
PASS=0
FAIL=0
FAILED_CHAINS=""
check_addr() {
local label="$1"
local addr="$2"
local rpc="$3"
if [[ -z "$addr" || "$addr" == "0x"*"..." ]]; then return; fi
local code
code=$(cast code "$addr" --rpc-url "$rpc" 2>/dev/null || true)
if [[ -n "$code" && "${#code}" -gt 2 ]]; then
echo " OK $label $addr"
PASS=$((PASS+1))
return 0
else
echo " FAIL $label $addr (no code or RPC error)"
FAIL=$((FAIL+1))
return 1
fi
}
verify_chain() {
local name="$1"
local rpc="$2"
shift 2
if [[ -z "$rpc" ]]; then echo "Skip $name (no RPC)"; return; fi
echo "--- $name ---"
local any_fail=0
while [[ $# -ge 2 ]]; do
check_addr "$1" "$2" "$rpc" || any_fail=1
shift 2
done
if [[ $any_fail -ne 0 ]]; then FAILED_CHAINS="$FAILED_CHAINS $name"; fi
echo ""
}
# Mainnet (Ethereum)
verify_chain "Ethereum Mainnet" "${ETHEREUM_MAINNET_RPC:-}" \
"BOND_MANAGER" "${BOND_MANAGER_MAINNET:-}" \
"LIQUIDITY_POOL" "${LIQUIDITY_POOL_ETH_MAINNET:-}" \
"INBOX" "${INBOX_ETH_MAINNET:-}"
# Chain 138
verify_chain "Chain 138" "${RPC_URL_138:-${CHAIN_138_RPC_URL:-}}" \
"LOCKBOX_138" "${LOCKBOX_138:-}"
# BSC
verify_chain "BSC" "${BSC_RPC_URL:-}" \
"BOND_MANAGER" "${BSC_BOND_MANAGER:-}" \
"LIQUIDITY_POOL" "${BSC_LIQUIDITY_POOL_ETH:-}" \
"INBOX" "${BSC_INBOX_ETH:-}" \
"LOCKBOX" "${BSC_LOCKBOX:-}"
# Polygon
verify_chain "Polygon" "${POLYGON_MAINNET_RPC:-}" \
"BOND_MANAGER" "${POLYGON_BOND_MANAGER:-}" \
"LIQUIDITY_POOL" "${POLYGON_LIQUIDITY_POOL_ETH:-}" \
"INBOX" "${POLYGON_INBOX_ETH:-}" \
"LOCKBOX" "${POLYGON_LOCKBOX:-}"
# Base
verify_chain "Base" "${BASE_MAINNET_RPC:-}" \
"BOND_MANAGER" "${BASE_BOND_MANAGER:-}" \
"LIQUIDITY_POOL" "${BASE_LIQUIDITY_POOL_ETH:-}" \
"INBOX" "${BASE_INBOX_ETH:-}" \
"LOCKBOX" "${BASE_LOCKBOX:-}"
# Optimism
verify_chain "Optimism" "${OPTIMISM_MAINNET_RPC:-}" \
"BOND_MANAGER" "${OPTIMISM_BOND_MANAGER:-}" \
"LIQUIDITY_POOL" "${OPTIMISM_LIQUIDITY_POOL_ETH:-}" \
"INBOX" "${OPTIMISM_INBOX_ETH:-}" \
"LOCKBOX" "${OPTIMISM_LOCKBOX:-}"
# Cronos
verify_chain "Cronos" "${CRONOS_RPC_URL:-}" \
"BOND_MANAGER" "${CRONOS_BOND_MANAGER:-}" \
"LIQUIDITY_POOL" "${CRONOS_LIQUIDITY_POOL_ETH:-}" \
"INBOX" "${CRONOS_INBOX_ETH:-}" \
"LOCKBOX" "${CRONOS_LOCKBOX:-}"
# Arbitrum (addresses from deployment run; may not be in .env)
verify_chain "Arbitrum" "${ARBITRUM_MAINNET_RPC:-}" \
"BOND_MANAGER" "${ARBITRUM_BOND_MANAGER:-0x26Eb0AC01BAb5756c73945d48e2B8e28D6b32287}" \
"LIQUIDITY_POOL" "${ARBITRUM_LIQUIDITY_POOL_ETH:-0x866aCe8664FF40E0a8842705E0D140E614eCc67B}" \
"INBOX" "${ARBITRUM_INBOX_ETH:-0xb1061A71412E18F66FF8D043e3F0682532ECdaf7}" \
"LOCKBOX" "${ARBITRUM_LOCKBOX:-0x57f8b4DB2d92CAB6093405b53158ab3224D37D24}"
# Avalanche
verify_chain "Avalanche" "${AVALANCHE_RPC_URL:-${AVALANCHE_MAINNET_RPC:-}}" \
"BOND_MANAGER" "${AVALANCHE_BOND_MANAGER:-0xD1695ed8F7683EE5d1BF55ed34585B22F474a7ef}" \
"LIQUIDITY_POOL" "${AVALANCHE_LIQUIDITY_POOL_ETH:-0xb6D2f38b9015F32ccE8818509c712264E7fceeD3}" \
"INBOX" "${AVALANCHE_INBOX_ETH:-0x866aCe8664FF40E0a8842705E0D140E614eCc67B}" \
"LOCKBOX" "${AVALANCHE_LOCKBOX:-0x7e6fB8D80f81430e560F8232b2A4fd06249d74ce}"
# Gnosis
verify_chain "Gnosis" "${GNOSIS_MAINNET_RPC:-}" \
"BOND_MANAGER" "${GNOSIS_BOND_MANAGER:-0x73376eB92c16977B126dB9112936A20Fa0De3442}" \
"LIQUIDITY_POOL" "${GNOSIS_LIQUIDITY_POOL_ETH:-0xb689c1C69DAa08DEb5D8feA2aBF0F64bFD409727}" \
"INBOX" "${GNOSIS_INBOX_ETH:-0x4C38F9A5ed68A04cd28a72E8c68C459Ec34576f3}" \
"LOCKBOX" "${GNOSIS_LOCKBOX:-0x0CA60e6f8589c540200daC9D9Cb27BC2e48eE66A}"
echo "=============================================="
echo "Summary: $PASS passed, $FAIL failed"
if [[ -n "$FAILED_CHAINS" ]]; then
echo "Chains with failures:$FAILED_CHAINS"
exit 1
fi
exit 0