Files
proxmox/scripts/verify/check-gru-v2-deployer-funding-status.sh
defiQUG dbd517b279 Sync workspace: config, docs, scripts, CI, operator rules, and submodule pointers.
- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains
- Omit embedded publish git dirs and empty placeholders from index

Made-with: Cursor
2026-04-12 06:12:20 -07:00

289 lines
10 KiB
Bash

#!/usr/bin/env bash
# Check deployer wallet funding posture for the remaining GRU v2 public rollout.
#
# Usage:
# bash scripts/verify/check-gru-v2-deployer-funding-status.sh
# bash scripts/verify/check-gru-v2-deployer-funding-status.sh --json
#
# This is an operator-planning surface. It does not broadcast transactions.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SMOM_ROOT="$PROJECT_ROOT/smom-dbis-138"
OUTPUT_JSON=0
for arg in "$@"; do
case "$arg" in
--json) OUTPUT_JSON=1 ;;
*)
echo "Unknown argument: $arg" >&2
exit 2
;;
esac
done
need_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "[FAIL] Missing required command: $1" >&2
exit 1
}
}
need_cmd bash
need_cmd cast
need_cmd jq
need_cmd python3
# shellcheck disable=SC1091
source "$PROJECT_ROOT/scripts/lib/load-project-env.sh"
if [[ -z "${PRIVATE_KEY:-}" && -f "$SMOM_ROOT/scripts/lib/deployment/dotenv.sh" ]]; then
# shellcheck disable=SC1091
source "$SMOM_ROOT/scripts/lib/deployment/dotenv.sh"
load_deployment_env --repo-root "$SMOM_ROOT"
fi
if [[ -z "${PRIVATE_KEY:-}" && -n "${DEPLOYER_PRIVATE_KEY:-}" ]]; then
export PRIVATE_KEY="$DEPLOYER_PRIVATE_KEY"
fi
DEPLOYER="${DEPLOYER_ADDRESS:-}"
if [[ -z "$DEPLOYER" && -n "${PRIVATE_KEY:-}" ]]; then
DEPLOYER="$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)"
fi
DEPLOYER="${DEPLOYER:-0x4A666F96fC8764181194447A7dFdb7d471b301C8}"
MAINNET_RPC="${ETHEREUM_MAINNET_RPC:-${ETH_MAINNET_RPC_URL:-}}"
CRONOS_RPC="${CRONOS_RPC_URL:-${CRONOS_RPC:-}}"
ARBITRUM_RPC="${ARBITRUM_MAINNET_RPC:-${ARBITRUM_MAINNET_RPC_URL:-${ARBITRUM_RPC_URL:-}}}"
WETH_138="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
WETH10_138="0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f"
LINK_138="0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03"
CUSDT_138="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
CUSDC_138="0xf22258f57794CC8E06237084b353Ab30fFfa640b"
# Default ~0.44 ETH at 35 gwei for a medium Arbitrum deploy batch. Override or disable via env:
# GRU_FUNDING_ARBITRUM_THRESHOLD_WEI=0 → skip Arbitrum balance blocker
# GRU_FUNDING_ARBITRUM_THRESHOLD_WEI=100000000000000000 → custom threshold (wei)
ARBITRUM_DEPLOY_THRESHOLD_WEI="${GRU_FUNDING_ARBITRUM_THRESHOLD_WEI:-440872740000000000}"
probe_chain_id() {
local rpc="$1"
[[ -z "$rpc" ]] && return 1
if command -v timeout >/dev/null 2>&1; then
timeout 5s cast chain-id --rpc-url "$rpc" 2>/dev/null | awk '{print $1; exit}'
else
cast chain-id --rpc-url "$rpc" 2>/dev/null | awk '{print $1; exit}'
fi
}
get_nonce() {
local rpc="$1"
[[ -z "$rpc" ]] && { echo "?"; return; }
cast nonce "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null | awk '{print $1; exit}' || echo "?"
}
get_native_balance() {
local rpc="$1"
[[ -z "$rpc" ]] && { echo "?"; return; }
cast balance "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null | awk '{print $1; exit}' || echo "?"
}
get_erc20_balance() {
local token="$1"
local rpc="$2"
[[ -z "$rpc" ]] && { echo "?"; return; }
cast call "$token" "balanceOf(address)(uint256)" "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null | awk '{print $1; exit}' || echo "?"
}
fmt_units() {
local raw="$1"
local decimals="$2"
local precision="${3:-6}"
if [[ "$raw" == "?" ]]; then
echo "?"
return
fi
python3 - "$raw" "$decimals" "$precision" <<'PY'
import sys
raw = int(sys.argv[1])
decimals = int(sys.argv[2])
precision = int(sys.argv[3])
value = raw / (10 ** decimals)
fmt = f"{{:.{precision}f}}"
print(fmt.format(value))
PY
}
pick_chain138_rpc() {
local candidates=(
"${RPC_URL_138_PUBLIC:-}"
"https://rpc-http-pub.d-bis.org"
"${RPC_URL_138:-}"
"https://rpc.public-0138.defi-oracle.io"
)
local seen="|"
local candidate=""
local chain_id=""
for candidate in "${candidates[@]}"; do
[[ -z "$candidate" ]] && continue
[[ "$seen" == *"|$candidate|"* ]] && continue
seen="${seen}${candidate}|"
chain_id="$(probe_chain_id "$candidate" || true)"
if [[ "$chain_id" == "138" ]]; then
printf '%s\n' "$candidate"
return 0
fi
done
printf '%s\n' "${RPC_URL_138_PUBLIC:-${RPC_URL_138:-https://rpc-http-pub.d-bis.org}}"
}
CHAIN138_RPC="$(pick_chain138_rpc)"
MAINNET_NONCE="$(get_nonce "$MAINNET_RPC")"
MAINNET_BALANCE="$(get_native_balance "$MAINNET_RPC")"
CRONOS_NONCE="$(get_nonce "$CRONOS_RPC")"
CRONOS_BALANCE="$(get_native_balance "$CRONOS_RPC")"
ARBITRUM_NONCE="$(get_nonce "$ARBITRUM_RPC")"
ARBITRUM_BALANCE="$(get_native_balance "$ARBITRUM_RPC")"
CHAIN138_NATIVE="$(get_native_balance "$CHAIN138_RPC")"
CHAIN138_WETH="$(get_erc20_balance "$WETH_138" "$CHAIN138_RPC")"
CHAIN138_WETH10="$(get_erc20_balance "$WETH10_138" "$CHAIN138_RPC")"
CHAIN138_LINK="$(get_erc20_balance "$LINK_138" "$CHAIN138_RPC")"
CHAIN138_CUSDT="$(get_erc20_balance "$CUSDT_138" "$CHAIN138_RPC")"
CHAIN138_CUSDC="$(get_erc20_balance "$CUSDC_138" "$CHAIN138_RPC")"
BLOCKERS=()
WARNINGS=()
if [[ "$CHAIN138_LINK" == "0" ]]; then
WARNINGS+=("Chain 138 deployer holds 0 LINK, so LINK-funded relay or CCIP fee operations are unfunded from this wallet.")
fi
if [[ "${ARBITRUM_DEPLOY_THRESHOLD_WEI:-0}" != "0" ]] && [[ "$ARBITRUM_BALANCE" != "?" ]] && [[ "$ARBITRUM_BALANCE" -lt "$ARBITRUM_DEPLOY_THRESHOLD_WEI" ]]; then
BLOCKERS+=("Arbitrum deployer balance is below the repo deploy threshold (${ARBITRUM_DEPLOY_THRESHOLD_WEI} wei; set GRU_FUNDING_ARBITRUM_THRESHOLD_WEI=0 to skip this gate).")
fi
if [[ "$MAINNET_BALANCE" != "?" ]] && [[ "$MAINNET_BALANCE" -lt "1000000000000000" ]]; then
WARNINGS+=("Mainnet deployer balance is below 0.001 ETH and is likely too low for additional pool/protocol deployment work.")
fi
REPORT="$(jq -n \
--arg generatedAt "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
--arg deployer "$DEPLOYER" \
--arg mainnetRpc "${MAINNET_RPC:-}" \
--arg cronosRpc "${CRONOS_RPC:-}" \
--arg arbitrumRpc "${ARBITRUM_RPC:-}" \
--arg chain138Rpc "${CHAIN138_RPC:-}" \
--arg mainnetNonce "$MAINNET_NONCE" \
--arg mainnetBalance "$MAINNET_BALANCE" \
--arg mainnetBalanceEth "$(fmt_units "$MAINNET_BALANCE" 18 9)" \
--arg cronosNonce "$CRONOS_NONCE" \
--arg cronosBalance "$CRONOS_BALANCE" \
--arg cronosBalanceNative "$(fmt_units "$CRONOS_BALANCE" 18 9)" \
--arg arbitrumNonce "$ARBITRUM_NONCE" \
--arg arbitrumBalance "$ARBITRUM_BALANCE" \
--arg arbitrumBalanceEth "$(fmt_units "$ARBITRUM_BALANCE" 18 9)" \
--arg chain138Native "$CHAIN138_NATIVE" \
--arg chain138NativeEth "$(fmt_units "$CHAIN138_NATIVE" 18 9)" \
--arg chain138Weth "$CHAIN138_WETH" \
--arg chain138WethUnits "$(fmt_units "$CHAIN138_WETH" 18 9)" \
--arg chain138Weth10 "$CHAIN138_WETH10" \
--arg chain138Weth10Units "$(fmt_units "$CHAIN138_WETH10" 18 9)" \
--arg chain138Link "$CHAIN138_LINK" \
--arg chain138LinkUnits "$(fmt_units "$CHAIN138_LINK" 18 9)" \
--arg chain138Cusdt "$CHAIN138_CUSDT" \
--arg chain138CusdtUnits "$(fmt_units "$CHAIN138_CUSDT" 6 2)" \
--arg chain138Cusdc "$CHAIN138_CUSDC" \
--arg chain138CusdcUnits "$(fmt_units "$CHAIN138_CUSDC" 6 2)" \
--argjson blockers "$(printf '%s\n' "${BLOCKERS[@]:-}" | sed '/^$/d' | jq -R . | jq -s .)" \
--argjson warnings "$(printf '%s\n' "${WARNINGS[@]:-}" | sed '/^$/d' | jq -R . | jq -s .)" \
'{
generatedAt: $generatedAt,
deployer: $deployer,
networks: {
mainnet: {
rpc: $mainnetRpc,
nonce: ($mainnetNonce | if . == "?" then . else tonumber end),
balanceWei: ($mainnetBalance | if . == "?" then . else tonumber end),
balanceEth: ($mainnetBalanceEth | if . == "?" then . else tonumber end)
},
cronos: {
rpc: $cronosRpc,
nonce: ($cronosNonce | if . == "?" then . else tonumber end),
balanceWei: ($cronosBalance | if . == "?" then . else tonumber end),
balanceNative: ($cronosBalanceNative | if . == "?" then . else tonumber end)
},
arbitrum: {
rpc: $arbitrumRpc,
nonce: ($arbitrumNonce | if . == "?" then . else tonumber end),
balanceWei: ($arbitrumBalance | if . == "?" then . else tonumber end),
balanceEth: ($arbitrumBalanceEth | if . == "?" then . else tonumber end)
},
chain138: {
rpc: $chain138Rpc,
nativeWei: ($chain138Native | if . == "?" then . else tonumber end),
nativeEth: ($chain138NativeEth | if . == "?" then . else tonumber end),
weth: {
raw: ($chain138Weth | if . == "?" then . else tonumber end),
units: ($chain138WethUnits | if . == "?" then . else tonumber end)
},
weth10: {
raw: ($chain138Weth10 | if . == "?" then . else tonumber end),
units: ($chain138Weth10Units | if . == "?" then . else tonumber end)
},
link: {
raw: ($chain138Link | if . == "?" then . else tonumber end),
units: ($chain138LinkUnits | if . == "?" then . else tonumber end)
},
cUSDT: {
raw: ($chain138Cusdt | if . == "?" then . else tonumber end),
units: ($chain138CusdtUnits | if . == "?" then . else tonumber end)
},
cUSDC: {
raw: ($chain138Cusdc | if . == "?" then . else tonumber end),
units: ($chain138CusdcUnits | if . == "?" then . else tonumber end)
}
}
},
blockers: $blockers,
warnings: $warnings
}')"
if (( OUTPUT_JSON == 1 )); then
printf '%s\n' "$REPORT"
exit 0
fi
printf '=== GRU V2 Deployer Funding Status ===\n'
printf 'Deployer: %s\n\n' "$DEPLOYER"
printf 'Mainnet: nonce=%s balance=%s wei (~%s ETH)\n' "$MAINNET_NONCE" "$MAINNET_BALANCE" "$(fmt_units "$MAINNET_BALANCE" 18 9)"
printf 'Cronos: nonce=%s balance=%s wei (~%s native)\n' "$CRONOS_NONCE" "$CRONOS_BALANCE" "$(fmt_units "$CRONOS_BALANCE" 18 9)"
printf 'Arbitrum: nonce=%s balance=%s wei (~%s ETH)\n' "$ARBITRUM_NONCE" "$ARBITRUM_BALANCE" "$(fmt_units "$ARBITRUM_BALANCE" 18 9)"
printf '\n'
printf 'Chain 138 native: %s wei (~%s ETH)\n' "$CHAIN138_NATIVE" "$(fmt_units "$CHAIN138_NATIVE" 18 9)"
printf 'Chain 138 WETH: %s raw (~%s)\n' "$CHAIN138_WETH" "$(fmt_units "$CHAIN138_WETH" 18 9)"
printf 'Chain 138 WETH10: %s raw (~%s)\n' "$CHAIN138_WETH10" "$(fmt_units "$CHAIN138_WETH10" 18 9)"
printf 'Chain 138 LINK: %s raw (~%s)\n' "$CHAIN138_LINK" "$(fmt_units "$CHAIN138_LINK" 18 9)"
printf 'Chain 138 cUSDT: %s raw (~%s)\n' "$CHAIN138_CUSDT" "$(fmt_units "$CHAIN138_CUSDT" 6 2)"
printf 'Chain 138 cUSDC: %s raw (~%s)\n' "$CHAIN138_CUSDC" "$(fmt_units "$CHAIN138_CUSDC" 6 2)"
if ((${#BLOCKERS[@]} > 0)); then
printf '\nActive funding blockers:\n'
for item in "${BLOCKERS[@]}"; do
printf -- '- %s\n' "$item"
done
fi
if ((${#WARNINGS[@]} > 0)); then
printf '\nWarnings:\n'
for item in "${WARNINGS[@]}"; do
printf -- '- %s\n' "$item"
done
fi