#!/usr/bin/env bash 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 DRY_RUN=0 STATUS_ONLY=0 JSON_OUTPUT=0 RUN_STATUS=1 RUN_MAINNET_LINK=1 RUN_MAINNET_LP=1 RUN_MAINNET_RELAY=1 RUN_BSC_LINK=1 RUN_BSC_RELAY=1 RUN_FINAL_CHECK=1 MAINNET_GAS_TARGET_WEI="$(eth_to_wei "0.05")" BSC_GAS_TARGET_WEI="$(eth_to_wei "0.06")" MAINNET_LINK_WEI="10000000000000000000" BSC_LINK_WEI="10000000000000000000" MAINNET_LP_ETH_TARGET_WEI="$(eth_to_wei "1")" MAINNET_LP_WETH_TARGET_WEI="$(eth_to_wei "0.5")" MAINNET_RELAY_WETH_TARGET_WEI="$(eth_to_wei "0.01")" BSC_RELAY_WETH_TARGET_WEI="$(eth_to_wei "0.01")" MAINNET_ETH_WEI="$(eth_to_wei "0.985")" MAINNET_WETH_WEI="$(eth_to_wei "0.499")" MAINNET_RELAY_WETH_WEI="$(eth_to_wei "0.007365719417988711")" BSC_RELAY_WETH_WEI="$(eth_to_wei "0.01")" usage() { cat <<'EOF' Run the final Mainnet/BSC unblock funding sequence from one place. Usage: ./scripts/deployment/run-final-unblock-checklist.sh ./scripts/deployment/run-final-unblock-checklist.sh --dry-run ./scripts/deployment/run-final-unblock-checklist.sh --only mainnet-link mainnet-lp check ./scripts/deployment/run-final-unblock-checklist.sh --skip bsc-link bsc-relay ./scripts/deployment/run-final-unblock-checklist.sh --mainnet-link 5 --bsc-link 5 ./scripts/deployment/run-final-unblock-checklist.sh --mainnet-eth 1 --mainnet-weth 0.5 ./scripts/deployment/run-final-unblock-checklist.sh --status-only ./scripts/deployment/run-final-unblock-checklist.sh --status-only --json Steps: status Print the exact checklist path and current target amounts mainnet-link Fund both Mainnet CCIP bridges with LINK mainnet-lp Fund LiquidityPoolETH on Mainnet mainnet-relay Fund the Mainnet relay bridge with WETH bsc-link Fund both BSC CCIP bridges with LINK bsc-relay Fund the BSC relay bridge with WETH check Run the trustless bridge readiness check Amount tags: --mainnet-link LINK per Mainnet bridge (default 10) --bsc-link LINK per BSC bridge (default 10) --mainnet-eth ETH to add to LiquidityPoolETH (default 0.985) --mainnet-weth WETH to add to LiquidityPoolETH (default 0.499) --mainnet-relay-weth WETH for Mainnet relay bridge (default 0.007365719417988711) --bsc-relay-weth WETH for BSC relay bridge (default 0.01) --status-only Print live balances and deficits, then exit --json Emit the status block as JSON --dry-run Print commands without broadcasting EOF } normalize_step_name() { case "${1,,}" in status) echo "status" ;; mainnet-link|mainnet_link) echo "mainnet-link" ;; mainnet-lp|mainnet_lp) echo "mainnet-lp" ;; mainnet-relay|mainnet_relay) echo "mainnet-relay" ;; bsc-link|bsc_link) echo "bsc-link" ;; bsc-relay|bsc_relay) echo "bsc-relay" ;; check|final-check|final_check) echo "check" ;; *) echo "" ;; esac } enable_only_steps() { RUN_STATUS=0 RUN_MAINNET_LINK=0 RUN_MAINNET_LP=0 RUN_MAINNET_RELAY=0 RUN_BSC_LINK=0 RUN_BSC_RELAY=0 RUN_FINAL_CHECK=0 while [[ $# -gt 0 ]]; do local step step="$(normalize_step_name "$1")" [[ -z "$step" ]] && break case "$step" in status) RUN_STATUS=1 ;; mainnet-link) RUN_MAINNET_LINK=1 ;; mainnet-lp) RUN_MAINNET_LP=1 ;; mainnet-relay) RUN_MAINNET_RELAY=1 ;; bsc-link) RUN_BSC_LINK=1 ;; bsc-relay) RUN_BSC_RELAY=1 ;; check) RUN_FINAL_CHECK=1 ;; esac shift done ONLY_REMAINING=("$@") } skip_steps() { while [[ $# -gt 0 ]]; do local step step="$(normalize_step_name "$1")" [[ -z "$step" ]] && break case "$step" in status) RUN_STATUS=0 ;; mainnet-link) RUN_MAINNET_LINK=0 ;; mainnet-lp) RUN_MAINNET_LP=0 ;; mainnet-relay) RUN_MAINNET_RELAY=0 ;; bsc-link) RUN_BSC_LINK=0 ;; bsc-relay) RUN_BSC_RELAY=0 ;; check) RUN_FINAL_CHECK=0 ;; esac shift done SKIP_REMAINING=("$@") } fmt_eth() { cast from-wei "${1:-0}" ether 2>/dev/null || echo "${1:-0}" } wei_max_zero_sub() { python3 - "$1" "$2" <<'PY' import sys target = int(sys.argv[1] or "0") current = int(sys.argv[2] or "0") print(max(target - current, 0)) PY } fetch_native_balance() { local rpc="$1" local addr="$2" [[ -z "$rpc" || -z "$addr" ]] && { echo "0"; return 0; } cast balance "$addr" --rpc-url "$rpc" 2>/dev/null || echo "0" } sanitize_uint_output() { local raw="${1:-0}" raw="${raw%% *}" if [[ "$raw" =~ ^0x[0-9a-fA-F]+$ ]]; then cast --to-dec "$raw" 2>/dev/null || echo "0" elif [[ "$raw" =~ ^[0-9]+$ ]]; then echo "$raw" else echo "0" fi } fetch_token_balance() { local token="$1" local holder="$2" local rpc="$3" [[ -z "$token" || -z "$holder" || -z "$rpc" ]] && { echo "0"; return 0; } sanitize_uint_output "$(cast call "$token" "balanceOf(address)(uint256)" "$holder" --rpc-url "$rpc" 2>/dev/null || echo "0")" } fetch_lp_available() { local pool="$1" local index="$2" local rpc="$3" [[ -z "$pool" || -z "$rpc" ]] && { echo "0"; return 0; } sanitize_uint_output "$(cast call "$pool" "getAvailableLiquidity(uint8)(uint256)" "$index" --rpc-url "$rpc" 2>/dev/null || echo "0")" } print_balance_line() { local label="$1" local current="$2" local target="$3" local unit="${4:-ETH}" local deficit deficit="$(wei_max_zero_sub "$target" "$current")" printf ' %-30s current=%s %s | target=%s %s | deficit=%s %s\n' \ "$label" "$(fmt_eth "$current")" "$unit" "$(fmt_eth "$target")" "$unit" "$(fmt_eth "$deficit")" "$unit" } status_from_deficit() { local deficit="${1:-0}" if [[ "$deficit" == "0" ]]; then echo "ok" else echo "needs_topup" fi } ensure_private_key() { if [[ -z "${PRIVATE_KEY:-}" ]]; then echo "Set PRIVATE_KEY in .env before running the final unblock wrapper." >&2 exit 1 fi } run_or_echo_array() { local -n cmd_ref=$1 local -n dry_ref=$2 if [[ "$DRY_RUN" == "1" ]]; then printf ' [DRY RUN] ' printf '%q ' "${dry_ref[@]}" printf '\n' else "${cmd_ref[@]}" fi } fund_ccip_bridge_link() { local label="$1" local rpc="$2" local link_token="$3" local bridge9="$4" local bridge10="$5" local amount_wei="$6" if [[ -z "$rpc" || -z "$link_token" ]]; then echo "Skipping $label LINK funding: missing RPC or LINK token address." return 0 fi echo "" echo "--- $label CCIP bridge LINK funding ---" echo " LINK token: $link_token" echo " Amount per bridge: $(fmt_eth "$amount_wei") LINK" if [[ -n "$bridge9" ]]; then local cmd=(cast send "$link_token" "transfer(address,uint256)" "$bridge9" "$amount_wei" --rpc-url "$rpc" --private-key "$PRIVATE_KEY" --legacy) local dry=(cast send "$link_token" "transfer(address,uint256)" "$bridge9" "$amount_wei" --rpc-url "$rpc" --private-key "" --legacy) run_or_echo_array cmd dry fi if [[ -n "$bridge10" ]]; then local cmd=(cast send "$link_token" "transfer(address,uint256)" "$bridge10" "$amount_wei" --rpc-url "$rpc" --private-key "$PRIVATE_KEY" --legacy) local dry=(cast send "$link_token" "transfer(address,uint256)" "$bridge10" "$amount_wei" --rpc-url "$rpc" --private-key "" --legacy) run_or_echo_array cmd dry fi } echo_status() { local deployer mainnet_eth bsc_bnb local mainnet_bridge9_link mainnet_bridge10_link bsc_bridge9_link bsc_bridge10_link local lp_eth_available lp_weth_available local mainnet_relay_weth bsc_relay_weth deployer="$(cast wallet address --private-key "$PRIVATE_KEY")" mainnet_eth="$(fetch_native_balance "$MAINNET_RPC" "$deployer")" bsc_bnb="$(fetch_native_balance "$BSC_RPC" "$deployer")" mainnet_bridge9_link="$(fetch_token_balance "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE9" "$MAINNET_RPC")" mainnet_bridge10_link="$(fetch_token_balance "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE10" "$MAINNET_RPC")" bsc_bridge9_link="$(fetch_token_balance "$BSC_LINK_TOKEN" "$BSC_BRIDGE9" "$BSC_RPC")" bsc_bridge10_link="$(fetch_token_balance "$BSC_LINK_TOKEN" "$BSC_BRIDGE10" "$BSC_RPC")" lp_eth_available="$(fetch_lp_available "${LIQUIDITY_POOL_ETH_MAINNET:-${LIQUIDITY_POOL:-}}" 0 "$MAINNET_RPC")" lp_weth_available="$(fetch_lp_available "${LIQUIDITY_POOL_ETH_MAINNET:-${LIQUIDITY_POOL:-}}" 1 "$MAINNET_RPC")" mainnet_relay_weth="$(fetch_token_balance "${WETH9_MAINNET:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}" "${CCIP_RELAY_BRIDGE_MAINNET:-${RELAY_BRIDGE_MAINNET:-${CW_BRIDGE_MAINNET:-}}}" "$MAINNET_RPC")" bsc_relay_weth="$(fetch_token_balance "${DEST_WETH9_ADDRESS:-0x2170Ed0880ac9A755fd29B2688956BD959F933F8}" "${DEST_RELAY_BRIDGE:-}" "$BSC_RPC")" mainnet_gas_deficit="$(wei_max_zero_sub "$MAINNET_GAS_TARGET_WEI" "$mainnet_eth")" mainnet_bridge9_link_deficit="$(wei_max_zero_sub "$MAINNET_LINK_WEI" "$mainnet_bridge9_link")" mainnet_bridge10_link_deficit="$(wei_max_zero_sub "$MAINNET_LINK_WEI" "$mainnet_bridge10_link")" mainnet_lp_eth_deficit="$(wei_max_zero_sub "$MAINNET_LP_ETH_TARGET_WEI" "$lp_eth_available")" mainnet_lp_weth_deficit="$(wei_max_zero_sub "$MAINNET_LP_WETH_TARGET_WEI" "$lp_weth_available")" mainnet_relay_weth_deficit="$(wei_max_zero_sub "$MAINNET_RELAY_WETH_TARGET_WEI" "$mainnet_relay_weth")" mainnet_gas_status="$(status_from_deficit "$mainnet_gas_deficit")" mainnet_bridge9_link_status="$(status_from_deficit "$mainnet_bridge9_link_deficit")" mainnet_bridge10_link_status="$(status_from_deficit "$mainnet_bridge10_link_deficit")" mainnet_lp_eth_status="$(status_from_deficit "$mainnet_lp_eth_deficit")" mainnet_lp_weth_status="$(status_from_deficit "$mainnet_lp_weth_deficit")" mainnet_relay_weth_status="$(status_from_deficit "$mainnet_relay_weth_deficit")" bsc_gas_deficit="$(wei_max_zero_sub "$BSC_GAS_TARGET_WEI" "$bsc_bnb")" bsc_bridge9_link_deficit="$(wei_max_zero_sub "$BSC_LINK_WEI" "$bsc_bridge9_link")" bsc_bridge10_link_deficit="$(wei_max_zero_sub "$BSC_LINK_WEI" "$bsc_bridge10_link")" bsc_relay_weth_deficit="$(wei_max_zero_sub "$BSC_RELAY_WETH_TARGET_WEI" "$bsc_relay_weth")" bsc_gas_status="$(status_from_deficit "$bsc_gas_deficit")" bsc_bridge9_link_status="$(status_from_deficit "$bsc_bridge9_link_deficit")" bsc_bridge10_link_status="$(status_from_deficit "$bsc_bridge10_link_deficit")" bsc_relay_weth_status="$(status_from_deficit "$bsc_relay_weth_deficit")" if [[ "$JSON_OUTPUT" == "1" ]]; then python3 - <&2 usage >&2 exit 1 ;; esac done ensure_private_key MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-${RPC_URL_MAINNET:-}}" BSC_RPC="${BSC_RPC_URL:-${BSC_MAINNET_RPC:-${DEST_RPC_URL:-}}}" MAINNET_LINK_TOKEN="${MAINNET_LINK_TOKEN:-${CCIP_ETH_LINK_TOKEN:-}}" BSC_LINK_TOKEN="${CCIP_BSC_LINK_TOKEN:-${LINK_TOKEN_BSC:-}}" MAINNET_BRIDGE9="${MAINNET_CCIP_WETH9_BRIDGE:-}" MAINNET_BRIDGE10="${MAINNET_CCIP_WETH10_BRIDGE:-}" BSC_BRIDGE9="${CCIPWETH9_BRIDGE_BSC:-}" BSC_BRIDGE10="${CCIPWETH10_BRIDGE_BSC:-}" mainnet_gas_deficit="" mainnet_bridge9_link_deficit="" mainnet_bridge10_link_deficit="" mainnet_lp_eth_deficit="" mainnet_lp_weth_deficit="" mainnet_relay_weth_deficit="" mainnet_gas_status="" mainnet_bridge9_link_status="" mainnet_bridge10_link_status="" mainnet_lp_eth_status="" mainnet_lp_weth_status="" mainnet_relay_weth_status="" bsc_gas_deficit="" bsc_bridge9_link_deficit="" bsc_bridge10_link_deficit="" bsc_relay_weth_deficit="" bsc_gas_status="" bsc_bridge9_link_status="" bsc_bridge10_link_status="" bsc_relay_weth_status="" if [[ "$JSON_OUTPUT" != "1" ]]; then echo "==============================================" echo "Running final unblock checklist" echo "==============================================" fi if [[ "$RUN_STATUS" == "1" ]]; then echo_status fi if [[ "$STATUS_ONLY" == "1" ]]; then exit 0 fi if [[ "$RUN_MAINNET_LINK" == "1" ]]; then fund_ccip_bridge_link "Mainnet" "$MAINNET_RPC" "$MAINNET_LINK_TOKEN" "$MAINNET_BRIDGE9" "$MAINNET_BRIDGE10" "$MAINNET_LINK_WEI" fi if [[ "$RUN_MAINNET_LP" == "1" ]]; then echo "" echo "--- Mainnet LP funding ---" LP_ARGS=(--eth-wei "$MAINNET_ETH_WEI" --weth-wei "$MAINNET_WETH_WEI") [[ "$DRY_RUN" == "1" ]] && LP_ARGS+=(--dry-run) ./scripts/deployment/fund-mainnet-lp.sh "${LP_ARGS[@]}" fi if [[ "$RUN_MAINNET_RELAY" == "1" ]]; then echo "" echo "--- Mainnet relay bridge funding ---" RELAY_ARGS=("$MAINNET_RELAY_WETH_WEI") [[ "$DRY_RUN" == "1" ]] && RELAY_ARGS+=(--dry-run) ./scripts/bridge/fund-mainnet-relay-bridge.sh "${RELAY_ARGS[@]}" fi if [[ "$RUN_BSC_LINK" == "1" ]]; then fund_ccip_bridge_link "BSC" "$BSC_RPC" "$BSC_LINK_TOKEN" "$BSC_BRIDGE9" "$BSC_BRIDGE10" "$BSC_LINK_WEI" fi if [[ "$RUN_BSC_RELAY" == "1" ]]; then echo "" echo "--- BSC relay bridge funding ---" RELAY_ARGS=("$BSC_RELAY_WETH_WEI") [[ "$DRY_RUN" == "1" ]] && RELAY_ARGS+=(--dry-run) ./scripts/bridge/fund-bsc-relay-bridge.sh "${RELAY_ARGS[@]}" fi if [[ "$RUN_FINAL_CHECK" == "1" ]]; then echo "" echo "--- Final readiness check ---" ./scripts/deployment/live-test-trustless-bridge.sh --check fi echo "" echo "Done. Reconcile any remaining top-up gaps against:" echo " /home/intlc/projects/proxmox/docs/03-deployment/FINAL_UNBLOCK_CHECKLIST_MAINNET_BSC.md"