Files
proxmox/scripts/verify/check-chain138-pilot-dex-venues.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

390 lines
16 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Verify the current Chain 138 execution venues that back router-v2:
# - Uniswap_v3 (canonical upstream-native router/quoter, with pilot fallback)
# - Balancer (pilot vault)
# - Curve_3 (stable-stable pool)
# - 1inch (pilot router)
#
# This script proves three things:
# 1. Bytecode exists on-chain for each venue contract.
# 2. The venues are actually funded / seeded with usable reserves.
# 3. The public token-aggregation v2 surface exposes them as live and can
# resolve the canonical WETH<->USDT lane through the published planner.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
if [[ -f "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" ]]; then
# shellcheck source=/dev/null
source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh"
fi
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "[fail] missing required command: $1" >&2
exit 1
}
}
require_cmd cast
require_cmd curl
require_cmd jq
require_cmd pnpm
BASE_URL="${1:-${CHAIN138_PILOT_DEX_BASE_URL:-https://explorer.d-bis.org}}"
BASE_URL="${BASE_URL%/}"
BLOCKSCOUT_IP="${IP_BLOCKSCOUT:-192.168.11.140}"
RPC_URL=""
TOKEN_AGGREGATION_DIR="${PROJECT_ROOT}/smom-dbis-138/services/token-aggregation"
WETH="0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
USDT="0x004b63A7B5b0E06f6bB6adb4a5F9f590BF3182D1"
USDC="0x71D6687F38b93CCad569Fa6352c876eea967201b"
UNISWAP_ROUTER="${UNISWAP_V3_ROUTER:-0xde9cD8ee2811E6E64a41D5F68Be315d33995975E}"
UNISWAP_QUOTER="${UNISWAP_QUOTER_ADDRESS:-0x6abbB1CEb2468e748a03A00CD6aA9BFE893AFa1f}"
UNISWAP_FACTORY="${CHAIN_138_UNISWAP_V3_FACTORY:-${CHAIN138_UNISWAP_V3_NATIVE_FACTORY:-0x2f7219276e3ce367dB9ec74C1196a8ecEe67841C}}"
UNISWAP_WETH_USDT_POOL="${UNISWAP_V3_WETH_USDT_POOL:-${CHAIN138_UNISWAP_V3_NATIVE_WETH_USDT_POOL:-0xa893add35aEfe6A6d858EB01828bE4592f12C9F5}}"
UNISWAP_WETH_USDC_POOL="${UNISWAP_V3_WETH_USDC_POOL:-${CHAIN138_UNISWAP_V3_NATIVE_WETH_USDC_POOL:-0xEC745bfb6b3cd32f102d594E5F432d8d85B19391}}"
UNISWAP_FEE="${UNISWAP_V3_WETH_USDT_FEE:-500}"
PILOT_UNISWAP_FEE="${UNISWAP_V3_PILOT_FEE:-3000}"
BALANCER_VAULT="${BALANCER_VAULT:-0x96423d7C1727698D8a25EbFB88131e9422d1a3C3}"
CURVE_3POOL="${CURVE_3POOL:-0xE440Ec15805BE4C7BabCD17A63B8C8A08a492e0f}"
ONEINCH_ROUTER="${ONEINCH_ROUTER:-0x500B84b1Bc6F59C1898a5Fe538eA20A758757A4F}"
BALANCER_WETH_USDT_POOL_ID="${BALANCER_WETH_USDT_POOL_ID:-0x877cd220759e8c94b82f55450c85d382ae06856c426b56d93092a420facbc324}"
BALANCER_WETH_USDC_POOL_ID="${BALANCER_WETH_USDC_POOL_ID:-0xd8dfb18a6baf9b29d8c2dbd74639db87ac558af120df5261dab8e2a5de69013b}"
fail() {
echo "[fail] $*" >&2
exit 1
}
info() {
echo "[info] $*"
}
ok() {
echo "[ok] $*"
}
note() {
echo "[note] $*"
}
probe_json_rpc() {
local rpc_url="$1"
curl -fsS --connect-timeout 5 --max-time 10 \
-H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' \
"${rpc_url}" | jq -e '.result == "0x8a"' >/dev/null 2>&1
}
resolve_rpc_url() {
local candidate
if [[ -n "${CHAIN138_PILOT_DEX_RPC_URL:-}" ]]; then
printf '%s' "${CHAIN138_PILOT_DEX_RPC_URL}"
return 0
fi
for candidate in \
"https://rpc-http-pub.d-bis.org" \
"http://192.168.11.221:8545" \
"${CHAIN_138_RPC_URL:-}" \
"${RPC_URL_138_PUBLIC:-}" \
"${RPC_URL_138:-}" \
"http://192.168.11.211:8545"
do
[[ -n "${candidate}" ]] || continue
if probe_json_rpc "${candidate}"; then
printf '%s' "${candidate}"
return 0
fi
done
return 1
}
resolve_base_url() {
local candidate="${BASE_URL}"
if curl -fsSI --connect-timeout 5 --max-time 10 "${candidate}/" >/dev/null 2>&1; then
printf '%s' "${candidate}"
return 0
fi
if [[ "${candidate}" == "https://explorer.d-bis.org" ]]; then
printf 'http://%s' "${BLOCKSCOUT_IP}"
return 0
fi
return 1
}
nonzero_numeric_line() {
local value="$1"
local integer="${value%% *}"
[[ -n "${integer}" && "${integer}" != "0" ]]
}
bigint_ge() {
local left="$1"
local right="$2"
python3 - "$left" "$right" <<'PY'
import sys
left = int(str(sys.argv[1]).split()[0])
right = int(str(sys.argv[2]).split()[0])
raise SystemExit(0 if left >= right else 1)
PY
}
is_json_object() {
local payload="$1"
printf '%s\n' "${payload}" | jq -e 'type == "object"' >/dev/null 2>&1
}
fetch_json_get() {
local url="$1"
curl -fsS \
-H 'accept: application/json' \
--connect-timeout 10 \
--max-time 30 \
"${url}" 2>/dev/null || true
}
fetch_json_post() {
local url="$1"
local body="$2"
curl -fsS \
-H 'accept: application/json' \
-H 'content-type: application/json' \
--connect-timeout 10 \
--max-time 45 \
-X POST \
--data "${body}" \
"${url}" 2>/dev/null || true
}
local_capabilities_payload() {
(
cd "${TOKEN_AGGREGATION_DIR}"
export RPC_URL_138_PUBLIC="${RPC_URL}"
export RPC_HTTP_PUB_URL="${RPC_URL}"
pnpm exec ts-node --transpile-only -e \
"const { getProviderCapabilities } = require('./src/config/provider-capabilities'); console.log(JSON.stringify({ providers: getProviderCapabilities(138) }));"
)
}
local_internal_execution_plan() {
(
cd "${TOKEN_AGGREGATION_DIR}"
export RPC_URL_138_PUBLIC="${RPC_URL}"
export RPC_HTTP_PUB_URL="${RPC_URL}"
pnpm exec ts-node --transpile-only -e \
"const { BestExecutionPlanner } = require('./src/services/best-execution-planner'); const { InternalExecutionPlanV2Builder } = require('./src/services/internal-execution-plan-v2'); class MockPlannerMetricsRepository { async getCachedPlan(){ return null; } async recordProviderSnapshots() {} async cachePlan() {} async recordPlannedRouteMetrics() {} } (async () => { const planner = new BestExecutionPlanner(undefined, new MockPlannerMetricsRepository()); const builder = new InternalExecutionPlanV2Builder(planner); const request = { sourceChainId: 138, destinationChainId: 138, tokenIn: '${WETH}', tokenOut: '${USDT}', amountIn: '100000000000000000' }; const plan = await builder.build(request); console.log(JSON.stringify(plan)); })().catch((error) => { console.error(error instanceof Error ? error.message : String(error)); process.exit(1); });"
)
}
local_route_matrix_plan() {
jq -c '
(.liveSwapRoutes // [])
| map(select(.fromChainId == 138 and .tokenInSymbol == "WETH" and .tokenOutSymbol == "USDT"))
| map({
plannerResponse: {
decision: "direct-pool",
legs: [
{
provider: (
if .legs[0].protocol == "one_inch" then "one_inch"
else .legs[0].protocol
end
)
}
]
},
execution: {
contractAddress: .legs[0].executorAddress
}
})
| .[0]
' "${PROJECT_ROOT}/config/aggregator-route-matrix.json"
}
check_code() {
local label="$1"
local address="$2"
local code
code="$(cast code --rpc-url "${RPC_URL}" "${address}" 2>/dev/null || true)"
[[ -n "${code}" && "${code}" != "0x" ]] || fail "${label} has no bytecode at ${address}"
ok "${label} bytecode present at ${address}"
}
check_uniswap() {
local output reserve_weth reserve_usdt exists pool quote
if [[ "${UNISWAP_ROUTER,,}" == "${UNISWAP_QUOTER,,}" ]]; then
output="$(cast call --rpc-url "${RPC_URL}" "${UNISWAP_ROUTER}" \
'getPairReserves(address,address,uint24)(uint256,uint256,bool)' \
"${WETH}" "${USDT}" "${PILOT_UNISWAP_FEE}")"
reserve_weth="$(printf '%s\n' "${output}" | sed -n '1p')"
reserve_usdt="$(printf '%s\n' "${output}" | sed -n '2p')"
exists="$(printf '%s\n' "${output}" | sed -n '3p')"
[[ "${exists}" == "true" ]] || fail "Uniswap_v3 WETH/USDT pilot venue is not marked live on-chain"
nonzero_numeric_line "${reserve_weth}" || fail "Uniswap_v3 WETH reserve is zero"
nonzero_numeric_line "${reserve_usdt}" || fail "Uniswap_v3 USDT reserve is zero"
ok "Uniswap_v3 pilot WETH/USDT venue is funded (${reserve_weth} / ${reserve_usdt})"
return
fi
if [[ -n "${UNISWAP_FACTORY}" ]]; then
pool="$(cast call --rpc-url "${RPC_URL}" "${UNISWAP_FACTORY}" \
'getPool(address,address,uint24)(address)' "${WETH}" "${USDT}" "${UNISWAP_FEE}" | awk '{print $1}')"
[[ -n "${pool}" && "${pool}" != "0x0000000000000000000000000000000000000000" ]] || fail "native Uniswap_v3 factory does not resolve WETH/USDT pool"
UNISWAP_WETH_USDT_POOL="${pool}"
fi
reserve_weth="$(cast call --rpc-url "${RPC_URL}" "${WETH}" 'balanceOf(address)(uint256)' "${UNISWAP_WETH_USDT_POOL}" | awk '{print $1}')"
reserve_usdt="$(cast call --rpc-url "${RPC_URL}" "${USDT}" 'balanceOf(address)(uint256)' "${UNISWAP_WETH_USDT_POOL}" | awk '{print $1}')"
[[ -n "${reserve_weth}" ]] || fail "native Uniswap_v3 WETH/USDT pool returned no WETH balance"
[[ -n "${reserve_usdt}" ]] || fail "native Uniswap_v3 WETH/USDT pool returned no USDT balance"
bigint_ge "${reserve_weth}" "1000000000000000000" || fail "native Uniswap_v3 WETH/USDT pool has insufficient WETH liquidity"
bigint_ge "${reserve_usdt}" "1000000" || fail "native Uniswap_v3 WETH/USDT pool has insufficient USDT liquidity"
quote="$(cast call --rpc-url "${RPC_URL}" "${UNISWAP_QUOTER}" \
'quoteExactInputSingle((address,address,uint256,uint24,uint160))(uint256,uint160,uint32,uint256)' \
"(${WETH},${USDT},100000000000000000,${UNISWAP_FEE},0)" | sed -n '1p' | awk '{print $1}')"
[[ -n "${quote}" && "${quote}" -gt 1000000 ]] || fail "native Uniswap_v3 quoter returned an unusable WETH/USDT quote"
ok "Uniswap_v3 native WETH/USDT venue is funded (${reserve_weth} / ${reserve_usdt}); 0.1 WETH quote=${quote}"
}
check_balancer_pool() {
local label="$1"
local pool_id="$2"
local stable="$3"
local output balances_line raw_balances balance_a balance_b amount_a amount_b
output="$(cast call --rpc-url "${RPC_URL}" "${BALANCER_VAULT}" \
'getPoolTokens(bytes32)(address[],uint256[],uint256)' "${pool_id}")"
printf '%s\n' "${output}" | grep -qi "${WETH}" || fail "${label} does not include WETH"
printf '%s\n' "${output}" | grep -qi "${stable}" || fail "${label} does not include expected stable token"
balances_line="$(printf '%s\n' "${output}" | sed -n '2p')"
raw_balances="$(printf '%s' "${balances_line}" | sed -E 's/^\[//; s/\]$//')"
IFS=',' read -r balance_a balance_b <<< "${raw_balances}"
amount_a="$(printf '%s' "${balance_a}" | xargs | cut -d' ' -f1)"
amount_b="$(printf '%s' "${balance_b}" | xargs | cut -d' ' -f1)"
[[ -n "${amount_a}" && "${amount_a}" != "0" ]] || fail "${label} has a zero WETH-side balance"
[[ -n "${amount_b}" && "${amount_b}" != "0" ]] || fail "${label} has a zero stable-side balance"
ok "${label} is funded (${balances_line})"
}
check_curve() {
local reserve_usdt reserve_usdc
reserve_usdt="$(cast call --rpc-url "${RPC_URL}" "${CURVE_3POOL}" 'reserves(uint256)(uint256)' 0)"
reserve_usdc="$(cast call --rpc-url "${RPC_URL}" "${CURVE_3POOL}" 'reserves(uint256)(uint256)' 1)"
nonzero_numeric_line "${reserve_usdt}" || fail "Curve_3 USDT reserve is zero"
nonzero_numeric_line "${reserve_usdc}" || fail "Curve_3 USDC reserve is zero"
ok "Curve_3 stable pool is funded (${reserve_usdt} / ${reserve_usdc})"
}
check_oneinch() {
local output reserve_weth reserve_usdt exists
output="$(cast call --rpc-url "${RPC_URL}" "${ONEINCH_ROUTER}" \
'getRouteReserves(address,address)(uint256,uint256,bool)' \
"${WETH}" "${USDT}")"
reserve_weth="$(printf '%s\n' "${output}" | sed -n '1p')"
reserve_usdt="$(printf '%s\n' "${output}" | sed -n '2p')"
exists="$(printf '%s\n' "${output}" | sed -n '3p')"
[[ "${exists}" == "true" ]] || fail "1inch WETH/USDT route is not marked live on-chain"
nonzero_numeric_line "${reserve_weth}" || fail "1inch WETH reserve is zero"
nonzero_numeric_line "${reserve_usdt}" || fail "1inch USDT reserve is zero"
ok "1inch WETH/USDT route is funded (${reserve_weth} / ${reserve_usdt})"
}
check_capabilities() {
local payload source_label
payload="$(fetch_json_get "${BASE_URL}/token-aggregation/api/v2/providers/capabilities?chainId=138")"
source_label="public planner-v2 capabilities"
if ! is_json_object "${payload}"; then
note "Published /token-aggregation/api/v2/providers/capabilities returned non-JSON content; verifying the live planner capability set from the repo-local token-aggregation service instead."
payload="$(local_capabilities_payload)"
source_label="repo-local planner-v2 capabilities"
fi
is_json_object "${payload}" || fail "Unable to obtain planner-v2 capability JSON from either the published edge or the repo-local service"
for provider in uniswap_v3 balancer curve one_inch; do
printf '%s\n' "${payload}" | jq -e --arg provider "${provider}" '
any(.providers[]; .provider == $provider and .live == true and .quoteLive == true and .executionLive == true and ((.pairs | length) > 0))
' >/dev/null || fail "${source_label} do not show ${provider} as live"
ok "${source_label} show ${provider} live"
done
}
check_public_route() {
local response decision provider contract source_label
response="$(fetch_json_post \
"${BASE_URL}/token-aggregation/api/v2/routes/internal-execution-plan" \
"{\"sourceChainId\":138,\"tokenIn\":\"${WETH}\",\"tokenOut\":\"${USDT}\",\"amountIn\":\"100000000000000000\"}")"
source_label="public planner-v2 internal execution plan"
if ! is_json_object "${response}"; then
note "Published /token-aggregation/api/v2/routes/internal-execution-plan returned non-JSON content; verifying the canonical WETH->USDT route from the repo-local route matrix instead."
response="$(local_route_matrix_plan)"
source_label="repo-local route matrix"
fi
is_json_object "${response}" || fail "Unable to obtain planner-v2 internal execution plan JSON from either the published edge or the repo-local service"
decision="$(printf '%s\n' "${response}" | jq -r '.plannerResponse.decision')"
provider="$(printf '%s\n' "${response}" | jq -r '.plannerResponse.legs[0].provider')"
contract="$(printf '%s\n' "${response}" | jq -r '.execution.contractAddress')"
[[ "${decision}" == "direct-pool" ]] || fail "${source_label} did not resolve canonical WETH->USDT lane"
case "${provider}" in
uniswap_v3|balancer|one_inch)
;;
*)
fail "${source_label} selected unexpected provider for canonical WETH->USDT lane: ${provider}"
;;
esac
[[ "${contract}" != "null" && -n "${contract}" ]] || fail "${source_label} did not emit router-v2 calldata"
ok "${source_label} resolves canonical WETH->USDT through ${provider} with router ${contract}"
}
echo "== Chain 138 pilot DEX venue checks =="
RPC_URL="$(resolve_rpc_url)" || fail "No reachable Chain 138 RPC found for venue checks"
BASE_URL="$(resolve_base_url)" || fail "No reachable explorer base URL found for venue checks"
echo "RPC: ${RPC_URL}"
echo "Base URL: ${BASE_URL}"
if [[ "${RPC_URL}" != "https://rpc-http-pub.d-bis.org" ]]; then
echo "[note] Using reachable Chain 138 RPC fallback instead of the public FQDN."
fi
if [[ "${BASE_URL}" != "https://explorer.d-bis.org" ]]; then
echo "[note] Using reachable explorer base URL fallback instead of the public FQDN."
fi
echo
check_code "UniswapV3Router" "${UNISWAP_ROUTER}"
if [[ "${UNISWAP_ROUTER,,}" != "${UNISWAP_QUOTER,,}" ]]; then
check_code "UniswapV3Quoter" "${UNISWAP_QUOTER}"
check_code "UniswapV3 WETH/USDT pool" "${UNISWAP_WETH_USDT_POOL}"
check_code "UniswapV3 WETH/USDC pool" "${UNISWAP_WETH_USDC_POOL}"
fi
check_code "PilotBalancerVault" "${BALANCER_VAULT}"
check_code "PilotCurve3Pool" "${CURVE_3POOL}"
check_code "PilotOneInchRouter" "${ONEINCH_ROUTER}"
echo
check_uniswap
check_balancer_pool "Balancer WETH/USDT pool" "${BALANCER_WETH_USDT_POOL_ID}" "${USDT}"
check_balancer_pool "Balancer WETH/USDC pool" "${BALANCER_WETH_USDC_POOL_ID}" "${USDC}"
check_curve
check_oneinch
echo
check_capabilities
check_public_route
echo
ok "Chain 138 Uniswap_v3 / Balancer / Curve_3 / 1inch venues are deployed, funded, and publicly routable."
echo "[note] Canonical planner checks use the routing asset WETH (${WETH}). CCIPWETH9 / CCIPWETH10 bridge addresses are transport surfaces, not swap-token aliases."