Files
proxmox/scripts/verify/check-gas-public-pool-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

153 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Summarize gas-native c* / cW* rollout state from GRU transport config and deployment-status.json.
# Usage:
# bash scripts/verify/check-gas-public-pool-status.sh
# bash scripts/verify/check-gas-public-pool-status.sh --json
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
export PROJECT_ROOT
# shellcheck source=/dev/null
source "$PROJECT_ROOT/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
OUTPUT_JSON=0
for arg in "$@"; do
case "$arg" in
--json) OUTPUT_JSON=1 ;;
*)
echo "Unknown argument: $arg" >&2
exit 2
;;
esac
done
command -v node >/dev/null 2>&1 || {
echo "[FAIL] Missing required command: node" >&2
exit 1
}
OUTPUT_JSON="$OUTPUT_JSON" node <<'NODE'
const path = require('path');
const {
getActiveTransportPairs,
getGasAssetFamilies,
getGasProtocolExposureRecord,
loadDeploymentStatusJson,
loadGruTransportActiveJson,
} = require(path.join(process.env.PROJECT_ROOT, 'config/token-mapping-loader.cjs'));
const outputJson = process.env.OUTPUT_JSON === '1';
const deployment = loadDeploymentStatusJson() || {};
const chains = deployment.chains || {};
const gasFamilies = getGasAssetFamilies();
const pairs = getActiveTransportPairs().filter((pair) => pair.assetClass === 'gas_native');
const active = loadGruTransportActiveJson() || {};
const configuredGasPairs = Array.isArray(active.transportPairs)
? active.transportPairs.filter((pair) => pair && pair.assetClass === 'gas_native')
: [];
const deferredGasPairs = configuredGasPairs.filter((pair) => pair.active === false).length;
const rows = pairs
.map((pair) => {
const chain = chains[String(pair.destinationChainId)] || {};
const gasPools = Array.isArray(chain.gasPmmPools) ? chain.gasPmmPools.filter((pool) => pool.familyKey === pair.familyKey) : [];
const venues = Array.isArray(chain.gasReferenceVenues)
? chain.gasReferenceVenues.filter((venue) => venue.familyKey === pair.familyKey)
: [];
const wrappedNativePool = gasPools.find((pool) => pool.poolType === 'wrapped_native');
const stableQuotePool = gasPools.find((pool) => pool.poolType === 'stable_quote');
const protocolExposure = getGasProtocolExposureRecord(`${pair.destinationChainId}-${pair.familyKey}`);
const uniswap = venues.find((venue) => venue.protocol === 'uniswap_v3');
const balancer = venues.find((venue) => venue.protocol === 'balancer');
const curve = venues.find((venue) => venue.protocol === 'curve');
const oneInch = venues.find((venue) => venue.protocol === '1inch');
const missing = [];
if (!pair.mirroredAddress) missing.push('mirror:address');
if (!wrappedNativePool) missing.push('dodo:wrapped_native');
if (!stableQuotePool) missing.push('dodo:stable_quote');
if (!uniswap) missing.push('reference:uniswap_v3');
if (!pair.supplyInvariantSatisfied) missing.push('supplyInvariant');
if (!pair.runtimeReady) {
missing.push(...(pair.eligibilityBlockers || []).map((item) => `eligibility:${item}`));
missing.push(...(pair.runtimeMissingRequirements || []).map((item) => `runtime:${item}`));
}
return {
key: pair.key,
familyKey: pair.familyKey,
chainId: pair.destinationChainId,
chainName: pair.destinationChainName,
canonicalSymbol: pair.canonicalSymbol,
mirroredSymbol: pair.mirroredSymbol,
wrappedNativeQuoteSymbol: pair.wrappedNativeQuoteSymbol,
stableQuoteSymbol: pair.stableQuoteSymbol,
backingMode: pair.backingMode,
redeemPolicy: pair.redeemPolicy,
runtimeReady: pair.runtimeReady === true,
supplyInvariantSatisfied: pair.supplyInvariantSatisfied === true,
wrappedNativePoolLive: Boolean(wrappedNativePool?.publicRoutingEnabled),
stableQuotePoolLive: Boolean(stableQuotePool?.publicRoutingEnabled),
uniswapReferenceLive: Boolean(uniswap?.live),
balancerSupported: Boolean(balancer?.supported),
balancerLive: Boolean(balancer?.live),
curveSupported: Boolean(curve?.supported),
curveLive: Boolean(curve?.live),
oneInchRoutingVisible: Boolean(oneInch?.routingVisible),
protocolExposure,
missing,
};
})
.sort((a, b) => a.chainId - b.chainId || a.familyKey.localeCompare(b.familyKey));
const summary = {
gasFamiliesTracked: gasFamilies.length,
transportPairs: rows.length,
configuredTransportPairs: configuredGasPairs.length,
deferredTransportPairs: deferredGasPairs,
runtimeReadyPairs: rows.filter((row) => row.runtimeReady).length,
blockedPairs: rows.filter((row) => !row.runtimeReady).length,
strictEscrowPairs: rows.filter((row) => row.backingMode === 'strict_escrow').length,
hybridCapPairs: rows.filter((row) => row.backingMode === 'hybrid_cap').length,
chainsWithGasMirrors: new Set(rows.filter((row) => row.mirroredSymbol).map((row) => row.chainId)).size,
pairsWithWrappedNativePools: rows.filter((row) => row.wrappedNativePoolLive).length,
pairsWithStableQuotePools: rows.filter((row) => row.stableQuotePoolLive).length,
pairsWithUniswapReference: rows.filter((row) => row.uniswapReferenceLive).length,
pairsWithRoutingVisibleOneInch: rows.filter((row) => row.oneInchRoutingVisible).length,
supplyInvariantFailures: rows.filter((row) => !row.supplyInvariantSatisfied).length,
};
if (outputJson) {
console.log(JSON.stringify({ summary, rows }, null, 2));
process.exit(0);
}
console.log('=== Gas-Native c* / cW* Rollout Status ===');
console.log(`Gas families tracked: ${summary.gasFamiliesTracked}`);
console.log(`Active transport pairs: ${summary.transportPairs}`);
console.log(`Deferred transport pairs: ${summary.deferredTransportPairs}`);
console.log(`Runtime-ready pairs: ${summary.runtimeReadyPairs}`);
console.log(`Blocked pairs: ${summary.blockedPairs}`);
console.log(`Strict escrow pairs: ${summary.strictEscrowPairs}`);
console.log(`Hybrid-cap pairs: ${summary.hybridCapPairs}`);
console.log(`Pairs with wrapped-native DODO pool live: ${summary.pairsWithWrappedNativePools}`);
console.log(`Pairs with stable-quote DODO pool live: ${summary.pairsWithStableQuotePools}`);
console.log(`Pairs with Uniswap v3 reference live: ${summary.pairsWithUniswapReference}`);
console.log(`Pairs with 1inch routing visible: ${summary.pairsWithRoutingVisibleOneInch}`);
console.log(`Supply invariant failures: ${summary.supplyInvariantFailures}`);
for (const row of rows) {
const readiness = row.runtimeReady ? 'ready' : 'blocked';
const dodoState = `dodo=${row.wrappedNativePoolLive ? 'wrapped' : 'no-wrapped'}/${row.stableQuotePoolLive ? 'stable' : 'no-stable'}`;
const uniswapState = `uni=${row.uniswapReferenceLive ? 'live' : 'queued'}`;
const oneInchState = `1inch=${row.oneInchRoutingVisible ? 'visible' : 'off'}`;
const missing = row.missing.length > 0 ? ` missing=${row.missing.join(',')}` : '';
console.log(
`- ${row.chainId} ${row.chainName} ${row.familyKey} (${row.canonicalSymbol}->${row.mirroredSymbol}, ${row.backingMode}): ${readiness}, ${dodoState}, ${uniswapState}, ${oneInchState}${missing}`
);
}
NODE