docs: update master documentation and push to Gitea (2026-03-06)
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- MASTER_INDEX: Last Updated 2026-03-06; status 59/59 contracts; add NEXT_STEPS_LIST, CONTRACT_NEXT_STEPS_LIST - docs/README, NEXT_STEPS_INDEX, 06-besu/MASTER_INDEX: Last Updated 2026-03-06 - Contract check script: 59 addresses (PMM, vault/reserve, CompliantFiatTokens); canonical CCIP/router - New docs: EXECUTION_CHECKLIST, NEXT_STEPS_LIST, DOTENV_AUDIT, ADDITIONAL_PATHS, deployer gas runbook, WEMIX_ACQUISITION_TABLED, etc. - Config: deployer-gas-routes, cro-wemix-swap-routes, routing-registry, token-mapping - Scripts: check-contracts-on-chain-138, check-pmm-pool-balances-chain138, deployer-gas-auto-route, acquire-cro-and-wemix-gas - Operator rule: operator-lan-access-check.mdc Made-with: Cursor
This commit is contained in:
69
scripts/deployment/acquire-cro-and-wemix-gas.sh
Executable file
69
scripts/deployment/acquire-cro-and-wemix-gas.sh
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env bash
|
||||
# Print all swap routes and instructions to acquire CRO (Cronos) and WEMIX (Wemix) native gas for the deployer.
|
||||
# Reads multiple routes from config/cro-wemix-swap-routes.json. No in-repo execution: use aggregator UIs.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/deployment/acquire-cro-and-wemix-gas.sh # full output from config
|
||||
# ./scripts/deployment/acquire-cro-and-wemix-gas.sh --json # emit config paths + deployer only
|
||||
# ./scripts/deployment/acquire-cro-and-wemix-gas.sh --list # one line per route (name, url)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
CONFIG="${PROJECT_ROOT}/config/cro-wemix-swap-routes.json"
|
||||
|
||||
OUTPUT_JSON=false
|
||||
OUTPUT_LIST=false
|
||||
for a in "$@"; do
|
||||
[[ "$a" == "--json" ]] && OUTPUT_JSON=true
|
||||
[[ "$a" == "--list" ]] && OUTPUT_LIST=true
|
||||
done
|
||||
|
||||
if [[ ! -f "$CONFIG" ]]; then
|
||||
echo "Error: Config not found: $CONFIG" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPLOYER="$(jq -r '.deployerAddress // "0x4A666F96fC8764181194447A7dFdb7d471b301C8"' "$CONFIG")"
|
||||
|
||||
if $OUTPUT_JSON; then
|
||||
jq -c '{ deployerAddress, configPath: $config, chains: .chains | keys }' --arg config "$CONFIG" "$CONFIG"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=============================================="
|
||||
echo " Swap routes: CRO and WEMIX deployer gas"
|
||||
echo " Deployer: $DEPLOYER"
|
||||
echo " Config: $CONFIG"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
for chain_key in 25 1111; do
|
||||
name=$(jq -r --arg k "$chain_key" '.chains[$k].name // empty' "$CONFIG")
|
||||
[[ -z "$name" ]] && continue
|
||||
native=$(jq -r --arg k "$chain_key" '.chains[$k].nativeSymbol // empty' "$CONFIG")
|
||||
required=$(jq -r --arg k "$chain_key" '.chains[$k].requiredNative // empty' "$CONFIG")
|
||||
unit=$(jq -r --arg k "$chain_key" '.chains[$k].requiredUnit // empty' "$CONFIG")
|
||||
recipient=$(jq -r --arg k "$chain_key" '.chains[$k].recipientNote // empty' "$CONFIG")
|
||||
|
||||
echo "--- $name (chain $chain_key) ---"
|
||||
echo " Required: ~$required $unit"
|
||||
echo " $recipient"
|
||||
echo " Deployer address: $DEPLOYER"
|
||||
echo ""
|
||||
|
||||
if $OUTPUT_LIST; then
|
||||
jq -r --arg k "$chain_key" '.chains[$k].swapRoutes[]? | " \(.name): \(.url)"' "$CONFIG" 2>/dev/null
|
||||
else
|
||||
echo " Swap routes (use any aggregator; send $unit to deployer when done):"
|
||||
jq -r --arg k "$chain_key" '.chains[$k].swapRoutes[]? | " [\(.name)] \(.description)\n \(.url)"' "$CONFIG" 2>/dev/null
|
||||
fi
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "After funding:"
|
||||
echo " Cronos: set CRONOS_RPC (or CRONOS_RPC_URL) in smom-dbis-138/.env, then run deploy-bridges-config-ready-chains.sh cronos and complete-config-ready-chains.sh."
|
||||
echo " Wemix: set WEMIX_RPC in smom-dbis-138/.env, then run deploy-bridges-config-ready-chains.sh wemix and complete-config-ready-chains.sh. See WEMIX_ACQUISITION_TABLED.md."
|
||||
echo ""
|
||||
89
scripts/deployment/chain138-tokens-to-gas.sh
Executable file
89
scripts/deployment/chain138-tokens-to-gas.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env bash
|
||||
# Chain 138 path for deployer gas auto-route: try token-aggregation quote for cUSDT/cUSDC → WETH.
|
||||
# If no c*→WETH pool exists (current state), output "use genesis/validator only".
|
||||
# Uses config/deployer-gas-routes.json for 138 entry (tokenAggregationBaseUrl, token addresses).
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/deployment/chain138-tokens-to-gas.sh [--dry-run] [--amount-raw WEI]
|
||||
# TOKEN_AGGREGATION_URL=https://dbis-api.d-bis.org/api/v1 ./scripts/deployment/chain138-tokens-to-gas.sh
|
||||
#
|
||||
# Requires: curl, jq. Optional: RPC_URL_138, PRIVATE_KEY for execute path (not implemented in v1).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
CONFIG="${PROJECT_ROOT}/config/deployer-gas-routes.json"
|
||||
|
||||
DRY_RUN=false
|
||||
AMOUNT_RAW="${AMOUNT_RAW:-1000000000}"
|
||||
# Default: 1000 USDT (6 decimals) in raw units
|
||||
|
||||
if [[ -f "$CONFIG" ]]; then
|
||||
BASE_URL="${TOKEN_AGGREGATION_URL:-$(jq -r '.chains[] | select(.chainId==138) | .tokenAggregationBaseUrl // empty' "$CONFIG")}"
|
||||
FALLBACK_URL="$(jq -r '.chains[] | select(.chainId==138) | .tokenAggregationFallbackUrl // empty' "$CONFIG")"
|
||||
CUSDT="$(jq -r '.chains[] | select(.chainId==138) | .cusdt // empty' "$CONFIG")"
|
||||
CUSDC="$(jq -r '.chains[] | select(.chainId==138) | .cusdc // empty' "$CONFIG")"
|
||||
WETH9="$(jq -r '.chains[] | select(.chainId==138) | .weth9 // empty' "$CONFIG")"
|
||||
fi
|
||||
BASE_URL="${BASE_URL:-https://dbis-api.d-bis.org/api/v1}"
|
||||
CUSDT="${CUSDT:-0x93E66202A11B1772E55407B32B44e5Cd8eda7f22}"
|
||||
CUSDC="${CUSDC:-0xf22258f57794CC8E06237084b353Ab30fFfa640b}"
|
||||
WETH9="${WETH9:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}"
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY_RUN=true ;;
|
||||
--amount-raw=*) AMOUNT_RAW="${arg#*=}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Try quote cUSDT -> WETH
|
||||
quote_cusdt_weth() {
|
||||
local url="${1:-$BASE_URL}"
|
||||
curl -sS --connect-timeout 5 "${url}/quote?chainId=138&tokenIn=${CUSDT}&tokenOut=${WETH9}&amountIn=${AMOUNT_RAW}" 2>/dev/null || echo '{"amountOut":null,"error":"request failed"}'
|
||||
}
|
||||
|
||||
# Try quote cUSDC -> WETH
|
||||
quote_cusdc_weth() {
|
||||
local url="${1:-$BASE_URL}"
|
||||
curl -sS --connect-timeout 5 "${url}/quote?chainId=138&tokenIn=${CUSDC}&tokenOut=${WETH9}&amountIn=${AMOUNT_RAW}" 2>/dev/null || echo '{"amountOut":null,"error":"request failed"}'
|
||||
}
|
||||
|
||||
echo "Chain 138 path: tokens → gas (WETH)"
|
||||
echo " Token-aggregation: $BASE_URL"
|
||||
echo " Amount (raw): $AMOUNT_RAW"
|
||||
echo ""
|
||||
|
||||
res_cusdt="$(quote_cusdt_weth)"
|
||||
res_cusdc="$(quote_cusdc_weth)"
|
||||
amount_out_cusdt="$(echo "$res_cusdt" | jq -r '.amountOut // empty' 2>/dev/null)"
|
||||
amount_out_cusdc="$(echo "$res_cusdc" | jq -r '.amountOut // empty' 2>/dev/null)"
|
||||
err_cusdt="$(echo "$res_cusdt" | jq -r '.error // empty' 2>/dev/null)"
|
||||
err_cusdc="$(echo "$res_cusdc" | jq -r '.error // empty' 2>/dev/null)"
|
||||
|
||||
if [[ -n "$amount_out_cusdt" && "$amount_out_cusdt" != "null" && "$amount_out_cusdt" -gt 0 ]] 2>/dev/null; then
|
||||
echo " cUSDT → WETH: quote available (amountOut=$amount_out_cusdt). Pool exists; use DODO PMM swap then optional unwrap."
|
||||
echo " Action: build DODO swap tx (swapCUSDTFor* to WETH pool) and optional WETH9.withdraw; see DEX_AND_AGGREGATORS_CHAIN138_EXPLAINER.md."
|
||||
exit 0
|
||||
fi
|
||||
if [[ -n "$amount_out_cusdc" && "$amount_out_cusdc" != "null" && "$amount_out_cusdc" -gt 0 ]] 2>/dev/null; then
|
||||
echo " cUSDC → WETH: quote available (amountOut=$amount_out_cusdc). Pool exists; use DODO PMM swap then optional unwrap."
|
||||
echo " Action: build DODO swap tx (swapCUSDCFor* to WETH pool) and optional WETH9.withdraw; see DEX_AND_AGGREGATORS_CHAIN138_EXPLAINER.md."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fallback URL if primary failed with network error
|
||||
if [[ -z "$amount_out_cusdt" && -z "$amount_out_cusdc" && -n "$FALLBACK_URL" ]]; then
|
||||
res_cusdt="$(quote_cusdt_weth "$FALLBACK_URL")"
|
||||
amount_out_cusdt="$(echo "$res_cusdt" | jq -r '.amountOut // empty' 2>/dev/null)"
|
||||
if [[ -n "$amount_out_cusdt" && "$amount_out_cusdt" != "null" && "$amount_out_cusdt" -gt 0 ]] 2>/dev/null; then
|
||||
echo " cUSDT → WETH: quote available (fallback URL). Pool exists."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo " No cUSDT/cUSDC → WETH pool found on Chain 138 (token-aggregation returned no quote)."
|
||||
echo " Chain 138 gas: use genesis alloc or validator transfer. See FUNDING_AND_DEPLOYMENT_CHECKLIST.md."
|
||||
echo " Output: method=genesis_or_validator"
|
||||
exit 0
|
||||
158
scripts/deployment/deployer-gas-auto-route.sh
Executable file
158
scripts/deployment/deployer-gas-auto-route.sh
Executable file
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deployer gas auto-route orchestrator: for each chain where deployer native balance is below
|
||||
# threshold, dispatch to internal (138), Protocolink (public), or manual (Wemix) path.
|
||||
# Uses config/deployer-gas-routes.json and smom-dbis-138/.env for RPC and deployer.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/deployment/deployer-gas-auto-route.sh [--dry-run] [--chain CHAIN_ID] [--no-execute]
|
||||
# # From repo root; load-project-env sources smom-dbis-138/.env
|
||||
#
|
||||
# Requires: jq, curl, cast (Foundry). Optional: Node for protocolink-swap-to-gas.js.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
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
|
||||
source "$PROJECT_ROOT/scripts/lib/load-project-env.sh"
|
||||
fi
|
||||
CONFIG="${PROJECT_ROOT}/config/deployer-gas-routes.json"
|
||||
|
||||
DRY_RUN=false
|
||||
NO_EXECUTE=false
|
||||
CHAIN_FILTER=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dry-run) DRY_RUN=true ;;
|
||||
--no-execute) NO_EXECUTE=true ;;
|
||||
--chain=*) CHAIN_FILTER="${arg#*=}" ;;
|
||||
--chain) CHAIN_FILTER="${2:-}"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -f "$CONFIG" ]]; then
|
||||
echo "ERROR: Config not found: $CONFIG" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPLOYER="${DEPLOYER_ADDRESS:-$(jq -r '.deployerAddress // empty' "$CONFIG")}"
|
||||
if [[ -z "$DEPLOYER" && -n "${PRIVATE_KEY:-}" ]] && command -v cast &>/dev/null; then
|
||||
DEPLOYER="$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || true)"
|
||||
fi
|
||||
DEPLOYER="${DEPLOYER:-0x4A666F96fC8764181194447A7dFdb7d471b301C8}"
|
||||
|
||||
# Map chainId to RPC env var name (from check-balances-gas-and-deploy.sh)
|
||||
get_rpc_for_chain() {
|
||||
local c="$1"
|
||||
case "$c" in
|
||||
1) echo "${ETHEREUM_MAINNET_RPC:-}" ;;
|
||||
56) echo "${BSC_RPC_URL:-${BSC_MAINNET_RPC:-}}" ;;
|
||||
137) echo "${POLYGON_MAINNET_RPC:-}" ;;
|
||||
138) echo "${RPC_URL_138:-}" ;;
|
||||
10) echo "${OPTIMISM_MAINNET_RPC:-}" ;;
|
||||
42161) echo "${ARBITRUM_MAINNET_RPC:-}" ;;
|
||||
8453) echo "${BASE_MAINNET_RPC:-}" ;;
|
||||
43114) echo "${AVALANCHE_RPC_URL:-${AVALANCHE_MAINNET_RPC:-}}" ;;
|
||||
100) echo "${GNOSIS_MAINNET_RPC:-${GNOSIS_RPC:-}}" ;;
|
||||
25) echo "${CRONOS_RPC_URL:-}" ;;
|
||||
42220) echo "${CELO_RPC_URL:-}" ;;
|
||||
1111) echo "${WEMIX_RPC_URL:-}" ;;
|
||||
651940) echo "${ALLTRA_MAINNET_RPC:-}" ;;
|
||||
*) echo "" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# thresholdEther is human number; convert to wei for ETH-like 18 decimals. For MATIC/BNB/etc same scale.
|
||||
threshold_to_wei() {
|
||||
local th="$1"
|
||||
echo "${th}" | awk 'BEGIN { OFMT="%.0f" } { gsub(/,/,""); printf "%.0f", $0 * 1e18 }'
|
||||
}
|
||||
|
||||
echo "=============================================="
|
||||
echo "Deployer gas auto-route"
|
||||
echo "Deployer: ${DEPLOYER:0:6}...${DEPLOYER: -6}"
|
||||
echo "Config: $CONFIG"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
needs_gas=()
|
||||
while read -r line; do
|
||||
chain_id="$(echo "$line" | jq -r '.chainId')"
|
||||
name="$(echo "$line" | jq -r '.name')"
|
||||
method="$(echo "$line" | jq -r '.method')"
|
||||
th_ether="$(echo "$line" | jq -r '.thresholdEther')"
|
||||
native_sym="$(echo "$line" | jq -r '.nativeSymbol // "native"')"
|
||||
[[ "$chain_id" == "null" || -z "$chain_id" ]] && continue
|
||||
[[ -n "$CHAIN_FILTER" && "$CHAIN_FILTER" != "$chain_id" ]] && continue
|
||||
|
||||
rpc="$(get_rpc_for_chain "$chain_id")"
|
||||
if [[ -z "$rpc" ]]; then
|
||||
echo "[$chain_id] $name — no RPC configured; skip"
|
||||
continue
|
||||
fi
|
||||
|
||||
balance_wei="$(cast balance "$DEPLOYER" --rpc-url "$rpc" 2>/dev/null || echo "0")"
|
||||
[[ -z "$balance_wei" || ! "$balance_wei" =~ ^[0-9]+$ ]] && balance_wei="0"
|
||||
th_wei="$(threshold_to_wei "$th_ether")"
|
||||
if [[ "$(echo "$balance_wei >= $th_wei" | bc 2>/dev/null)" -eq 1 ]]; then
|
||||
echo "[$chain_id] $name — balance OK (>= $th_ether $native_sym); skip"
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "[$chain_id] $name — below threshold ($th_ether); method=$method"
|
||||
needs_gas+=("$chain_id|$name|$method|$line")
|
||||
done < <(jq -c '.chains[]' "$CONFIG" 2>/dev/null)
|
||||
|
||||
echo ""
|
||||
if [[ ${#needs_gas[@]} -eq 0 ]]; then
|
||||
echo "No chains need gas. Done."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Chains needing gas: ${#needs_gas[@]}"
|
||||
echo ""
|
||||
|
||||
for entry in "${needs_gas[@]}"; do
|
||||
IFS='|' read -r chain_id name method line <<< "$entry"
|
||||
echo "--- $name (chain $chain_id) ---"
|
||||
case "$method" in
|
||||
internal)
|
||||
if [[ "$chain_id" == "138" ]]; then
|
||||
"$SCRIPT_DIR/chain138-tokens-to-gas.sh" ${DRY_RUN:+--dry-run} 2>&1 || true
|
||||
else
|
||||
echo " Internal path only for chain 138; skip."
|
||||
fi
|
||||
;;
|
||||
protocolink)
|
||||
if command -v node &>/dev/null; then
|
||||
node "$SCRIPT_DIR/protocolink-swap-to-gas.cjs" --chain-id "$chain_id" --no-execute 2>&1 || true
|
||||
else
|
||||
echo " Install Node to run protocolink-swap-to-gas.cjs for this chain."
|
||||
fi
|
||||
;;
|
||||
manual)
|
||||
manual_links="$(echo "$line" | jq -r '.manualLinks[]? // empty' 2>/dev/null)"
|
||||
manual_instr="$(echo "$line" | jq -r '.manualInstructions // empty' 2>/dev/null)"
|
||||
echo " $manual_instr"
|
||||
if [[ -n "$manual_links" ]]; then
|
||||
echo "$manual_links" | while read -r url; do [[ -n "$url" ]] && echo " $url"; done
|
||||
fi
|
||||
if [[ "$chain_id" == "25" || "$chain_id" == "1111" ]]; then
|
||||
echo " For all swap routes (multiple aggregators): ./scripts/deployment/acquire-cro-and-wemix-gas.sh"
|
||||
fi
|
||||
if [[ "$chain_id" == "1111" ]] && command -v node &>/dev/null; then
|
||||
node "$SCRIPT_DIR/wemix-acquire-via-lifi.js" --dry-run 2>&1 | head -20
|
||||
fi
|
||||
;;
|
||||
lifi|jumper)
|
||||
echo " LiFi/Jumper path not yet implemented; use manual links or wemix-acquire-via-lifi.js for Wemix."
|
||||
;;
|
||||
*)
|
||||
echo " Unknown method: $method"
|
||||
;;
|
||||
esac
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "Done. See docs/03-deployment/DEPLOYER_GAS_AUTO_ROUTE_RUNBOOK.md for full steps."
|
||||
175
scripts/deployment/protocolink-swap-to-gas.cjs
Normal file
175
scripts/deployment/protocolink-swap-to-gas.cjs
Normal file
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Protocolink path for deployer gas auto-route: get quote and build tx data for
|
||||
* swapping ERC-20 (USDT, USDC, LINK) to native gas (or WETH) on Protocolink-supported chains.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/deployment/protocolink-swap-to-gas.cjs --chain-id 1 [--token USDC] [--amount-raw 1000000] [--no-execute]
|
||||
* PROTOCOLINK_API_URL=https://api.protocolink.com node scripts/deployment/protocolink-swap-to-gas.cjs --chain-id 137
|
||||
*
|
||||
* Requires: Node 18+ (fetch), config/deployer-gas-routes.json for chain list.
|
||||
* Output: JSON with quote and tx building instructions; no private key or signing in script.
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const PROJECT_ROOT = path.resolve(__dirname, '../..');
|
||||
const CONFIG_PATH = path.join(PROJECT_ROOT, 'config/deployer-gas-routes.json');
|
||||
|
||||
const API_BASE = process.env.PROTOCOLINK_API_URL || 'https://api.protocolink.com';
|
||||
const PROTOCOL_ID = process.env.PROTOCOLINK_PROTOCOL || 'paraswap-v5';
|
||||
const LOGIC_ID = 'swap-token';
|
||||
const SLIPPAGE_BPS = parseInt(process.env.SLIPPAGE_BPS || '150', 10);
|
||||
|
||||
// Common token addresses per chain (mainnet; extend as needed)
|
||||
const NATIVE_OR_WETH = {
|
||||
1: { address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', decimals: 18, symbol: 'WETH' },
|
||||
56: { address: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c', decimals: 18, symbol: 'WBNB' },
|
||||
137: { address: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', decimals: 18, symbol: 'WMATIC' },
|
||||
100: { address: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', decimals: 18, symbol: 'WXDAI' },
|
||||
10: { address: '0x4200000000000000000000000000000000000006', decimals: 18, symbol: 'WETH' },
|
||||
42161: { address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBb1', decimals: 18, symbol: 'WETH' },
|
||||
8453: { address: '0x4200000000000000000000000000000000000006', decimals: 18, symbol: 'WETH' },
|
||||
43114: { address: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7', decimals: 18, symbol: 'WAVAX' },
|
||||
25: { address: '0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23', decimals: 18, symbol: 'WCRO' },
|
||||
};
|
||||
|
||||
const USDT = {
|
||||
1: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
||||
56: '0x55d398326f99059fF775485246999027B3197955',
|
||||
137: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
|
||||
100: '0x4ECaBa5870353805a9F068101A40E0f32ed605C6',
|
||||
10: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',
|
||||
42161: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
|
||||
8453: '0x0000000000000000000000000000000000000000', // TBD
|
||||
43114: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',
|
||||
25: '0x66e428c3f67a68878562e79A0234c1F83c208770',
|
||||
};
|
||||
|
||||
const USDC = {
|
||||
1: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
||||
56: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',
|
||||
137: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
|
||||
100: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
|
||||
10: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
|
||||
42161: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
|
||||
8453: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
||||
43114: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
|
||||
25: '0xc21223249CA28397B4B6541dfFaEcC539BfF0c59',
|
||||
};
|
||||
|
||||
const LINK = {
|
||||
1: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
|
||||
56: '0xF8A0BF9cF54Bb92F17374d9e9A321E6a111a51bD',
|
||||
137: '0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39',
|
||||
100: '0xE2e73A1c69ecF83F464CECE147577d37BCf26298',
|
||||
10: '0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6',
|
||||
42161: '0xf97f4df75117a78c1A5a0DBb814Af92458539FB4',
|
||||
8453: '0x0000000000000000000000000000000000000000', // TBD
|
||||
43114: '0x5947BB275c521040051D82396192181b413227A3',
|
||||
25: '0xE7d7D8374CF6a8e3F656c433F6B0f0C81F6d06F5',
|
||||
};
|
||||
|
||||
function getTokenIn(chainId, symbol) {
|
||||
const s = (symbol || 'USDC').toUpperCase();
|
||||
let addr;
|
||||
if (s === 'USDT') addr = USDT[chainId];
|
||||
else if (s === 'USDC') addr = USDC[chainId];
|
||||
else if (s === 'LINK') addr = LINK[chainId];
|
||||
else return null;
|
||||
if (!addr || addr === '0x0000000000000000000000000000000000000000') return null;
|
||||
const decimals = s === 'LINK' ? 18 : 6;
|
||||
return { chainId, address: addr, decimals, symbol: s, name: s };
|
||||
}
|
||||
|
||||
function getTokenOut(chainId) {
|
||||
const t = NATIVE_OR_WETH[chainId];
|
||||
if (!t) return null;
|
||||
return { chainId, address: t.address, decimals: t.decimals, symbol: t.symbol, name: t.symbol };
|
||||
}
|
||||
|
||||
function parseArgs() {
|
||||
const args = process.argv.slice(2);
|
||||
let chainId, tokenIn = 'USDC', amountRaw, noExecute = false;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
if (args[i] === '--chain-id' && args[i + 1]) chainId = parseInt(args[i + 1], 10);
|
||||
if (args[i] === '--token' && args[i + 1]) tokenIn = args[i + 1];
|
||||
if (args[i] === '--amount-raw' && args[i + 1]) amountRaw = args[i + 1];
|
||||
if (args[i] === '--no-execute') noExecute = true;
|
||||
}
|
||||
return { chainId, tokenIn, amountRaw: amountRaw || '1000000', noExecute };
|
||||
}
|
||||
|
||||
async function requestQuote(chainId, tokenInObj, tokenOutObj, amountRaw) {
|
||||
const url = `${API_BASE}/v1/protocols/${chainId}/${PROTOCOL_ID}/${LOGIC_ID}/quote`;
|
||||
const body = {
|
||||
input: {
|
||||
token: tokenInObj,
|
||||
amount: amountRaw,
|
||||
},
|
||||
tokenOut: tokenOutObj,
|
||||
slippage: SLIPPAGE_BPS,
|
||||
};
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
throw new Error(`Protocolink quote failed ${res.status}: ${text}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
function loadConfig() {
|
||||
if (!fs.existsSync(CONFIG_PATH)) return null;
|
||||
return JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { chainId, tokenIn: tokenSymbol, amountRaw, noExecute } = parseArgs();
|
||||
if (!chainId) {
|
||||
console.error('Usage: node protocolink-swap-to-gas.cjs --chain-id <chainId> [--token USDC|USDT|LINK] [--amount-raw <raw>] [--no-execute]');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const tokenInObj = getTokenIn(chainId, tokenSymbol);
|
||||
const tokenOutObj = getTokenOut(chainId);
|
||||
if (!tokenInObj || !tokenOutObj) {
|
||||
console.error(JSON.stringify({
|
||||
error: 'Unsupported chain or token',
|
||||
chainId,
|
||||
tokenIn: tokenSymbol,
|
||||
message: 'Add token addresses for this chain in protocolink-swap-to-gas.cjs or use a supported chain (1, 56, 137, 100, 10, 42161, 8453, 43114, 25).',
|
||||
}, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const quote = await requestQuote(chainId, tokenInObj, tokenOutObj, amountRaw);
|
||||
const output = {
|
||||
chainId,
|
||||
protocolId: PROTOCOL_ID,
|
||||
logicId: LOGIC_ID,
|
||||
quote,
|
||||
tokenIn: tokenInObj,
|
||||
tokenOut: tokenOutObj,
|
||||
amountInRaw: amountRaw,
|
||||
slippageBps: SLIPPAGE_BPS,
|
||||
nextStep: 'Use Protocolink API "build transaction" or SDK to build tx; sign with deployer key and submit. See https://docs.protocolink.com/protocolink-api/overview.',
|
||||
noExecute: true,
|
||||
};
|
||||
console.log(JSON.stringify(output, null, 2));
|
||||
} catch (err) {
|
||||
console.error(JSON.stringify({
|
||||
error: err.message,
|
||||
chainId,
|
||||
tokenIn: tokenSymbol,
|
||||
}, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Check that Chain 138 deployed contracts have bytecode on-chain.
|
||||
# Address list: 59 (core, CCIP, PMM, vault/reserve, CompliantFiatTokens). Source: CONTRACT_ADDRESSES_REFERENCE, ADDRESS_MATRIX.
|
||||
# Usage: ./scripts/verify/check-contracts-on-chain-138.sh [RPC_URL] [--dry-run]
|
||||
# Default RPC: from env RPC_URL_138 (Chain 138 Core standard) or config/ip-addresses.conf, else https://rpc-core.d-bis.org
|
||||
# Optional: SKIP_EXIT=1 to exit 0 even when some addresses MISS (e.g. when RPC unreachable from this host).
|
||||
@@ -81,7 +82,28 @@ else
|
||||
"0x6427F9739e6B6c3dDb4E94fEfeBcdF35549549d8" # MirrorRegistry
|
||||
"0x66FEBA2fC9a0B47F26DD4284DAd24F970436B8Dc" # AlltraAdapter
|
||||
"0x7131F887DBEEb2e44c1Ed267D2A68b5b83285afc" # TransactionMirror Chain 138 (deployed 2026-02-27; set TRANSACTION_MIRROR_ADDRESS in .env)
|
||||
"0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8" # DODO cUSDT-cUSDC pool (pending until CreateCUSDTCUSDCPool succeeds)
|
||||
"0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8" # DODO cUSDT-cUSDC pool
|
||||
"0x79cdbaFBaA0FdF9F55D26F360F54cddE5c743F7D" # DODOPMMIntegration
|
||||
"0x8EF6657D2a86c569F6ffc337EE6b4260Bd2e59d0" # DODOPMMProvider
|
||||
"0xa3Ee6091696B28e5497b6F491fA1e99047250c59" # DODO pool cUSDT/USDT
|
||||
"0x90bd9Bf18Daa26Af3e814ea224032d015db58Ea5" # DODO pool cUSDC/USDC
|
||||
"0x607e97cD626f209facfE48c1464815DDE15B5093" # ReserveSystem
|
||||
"0x34B73e6EDFd9f85a7c25EeD31dcB13aB6E969b96" # ReserveTokenIntegration
|
||||
"0xEA4C892D6c1253797c5D95a05BF3863363080b4B" # RegulatedEntityRegistry (vault)
|
||||
"0xB2Ac70f35A81481B005067ed6567a5043BA32336" # VaultFactory
|
||||
"0x67b3831dc64C14FB9352B2a45C6Dd69b3C86B7af" # Ledger (vault)
|
||||
"0x3aCdbCB749d6037a02F0ef6ea2E5Fb89D31fAB72" # Liquidation (vault)
|
||||
"0xf23E1eDa304082ab7a81531dFE6020E6105e77A8" # XAU Oracle (vault)
|
||||
"0x8085961F9cF02b4d800A3c6d386D31da4B34266a" # cEURC
|
||||
"0xdf4b71c61E5912712C1Bdd451416B9aC26949d72" # cEURT
|
||||
"0x003960f16D9d34F2e98d62723B6721Fb92074aD2" # cGBPC
|
||||
"0x350f54e4D23795f86A9c03988c7135357CCaD97c" # cGBPT
|
||||
"0xD51482e567c03899eecE3CAe8a058161FD56069D" # cAUDC
|
||||
"0xEe269e1226a334182aace90056EE4ee5Cc8A6770" # cJPYC
|
||||
"0x873990849DDa5117d7C644f0aF24370797C03885" # cCHFC
|
||||
"0x54dBd40cF05e15906A2C21f600937e96787f5679" # cCADC
|
||||
"0x290E52a8819A4fbD0714E517225429aA2B70EC6b" # cXAUC
|
||||
"0x94e408E26c6FD8F4ee00b54dF19082FDA07dC96E" # cXAUT
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
77
scripts/verify/check-pmm-pool-balances-chain138.sh
Executable file
77
scripts/verify/check-pmm-pool-balances-chain138.sh
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env bash
|
||||
# Check all Chain 138 DODO PMM pool token balances (base + quote).
|
||||
# Uses eth_call (curl) for compatibility with RPCs that reject some cast call formats.
|
||||
#
|
||||
# Usage: ./scripts/verify/check-pmm-pool-balances-chain138.sh [RPC_URL]
|
||||
# Default RPC: http://192.168.11.211:8545
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
RPC="${1:-${RPC_URL_138:-http://192.168.11.211:8545}}"
|
||||
|
||||
# Token addresses (Chain 138 canonical)
|
||||
cUSDT="0x93E66202A11B1772E55407B32B44e5Cd8eda7f22"
|
||||
cUSDC="0xf22258f57794CC8E06237084b353Ab30fFfa640b"
|
||||
OFFICIAL_USDT="0x15DF1D5BFDD8Aa4b380445D4e3E9B38d34283619"
|
||||
# Official USDC from integration or placeholder (no contract on 138)
|
||||
OFFICIAL_USDC="0x0000000000000000000000000000000000000000"
|
||||
|
||||
# Pool addresses
|
||||
POOL_CUSDTCUSDC="0x9fcB06Aa1FD5215DC0E91Fd098aeff4B62fEa5C8"
|
||||
POOL_CUSDTUSDT="0xa3Ee6091696B28e5497b6F491fA1e99047250c59"
|
||||
POOL_CUSDCUSDC="0x90bd9Bf18Daa26Af3e814ea224032d015db58Ea5"
|
||||
|
||||
pads() { local a; a=$(echo "$1" | sed 's/0x//'); printf '%064s' "$a" | tr ' ' '0'; }
|
||||
balance() {
|
||||
local tok="$1" acc="$2"
|
||||
local d="0x70a08231$(pads "$acc")"
|
||||
local res
|
||||
res=$(curl -s -X POST "$RPC" -H "Content-Type: application/json" \
|
||||
--data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[{\"to\":\"$tok\",\"data\":\"$d\"},\"latest\"],\"id\":1}" \
|
||||
| jq -r '.result // empty')
|
||||
echo "${res:-0x0000000000000000000000000000000000000000000000000000000000000000}"
|
||||
}
|
||||
hex2dec() { local h="$1"; [[ -z "$h" || "$h" == "0x" ]] && echo "0" && return; printf '%d' "$h"; }
|
||||
human6() { local r; r=$(hex2dec "$1"); echo "scale=6; $r / 1000000" | bc 2>/dev/null || echo "$r"; }
|
||||
|
||||
echo "=============================================="
|
||||
echo " Chain 138 — PMM pool balances"
|
||||
echo " RPC: $RPC"
|
||||
echo "=============================================="
|
||||
echo ""
|
||||
|
||||
# Pool 1: cUSDT / cUSDC (base / quote)
|
||||
echo "Pool 1: cUSDT / cUSDC"
|
||||
echo " Address: $POOL_CUSDTCUSDC"
|
||||
r1=$(balance "$cUSDT" "$POOL_CUSDTCUSDC")
|
||||
r2=$(balance "$cUSDC" "$POOL_CUSDTCUSDC")
|
||||
echo " cUSDT (base): raw=$r1 → $(human6 "$r1")"
|
||||
echo " cUSDC (quote): raw=$r2 → $(human6 "$r2")"
|
||||
echo ""
|
||||
|
||||
# Pool 2: cUSDT / USDT (official USDT has no code on 138)
|
||||
echo "Pool 2: cUSDT / USDT (official)"
|
||||
echo " Address: $POOL_CUSDTUSDT"
|
||||
r1=$(balance "$cUSDT" "$POOL_CUSDTUSDT")
|
||||
r2=$(balance "$OFFICIAL_USDT" "$POOL_CUSDTUSDT")
|
||||
echo " cUSDT (base): raw=${r1:-0x0} → $(human6 "$r1")"
|
||||
echo " USDT (quote): raw=${r2:-0x0} → $(human6 "$r2")"
|
||||
echo ""
|
||||
|
||||
# Pool 3: cUSDC / USDC (official USDC not deployed on 138)
|
||||
echo "Pool 3: cUSDC / USDC (official)"
|
||||
echo " Address: $POOL_CUSDCUSDC"
|
||||
r1=$(balance "$cUSDC" "$POOL_CUSDCUSDC")
|
||||
echo " cUSDC (base): raw=$r1 → $(human6 "$r1")"
|
||||
if [[ "$OFFICIAL_USDC" != "0x0000000000000000000000000000000000000000" ]]; then
|
||||
r2=$(balance "$OFFICIAL_USDC" "$POOL_CUSDCUSDC")
|
||||
echo " USDC (quote): raw=$r2 → $(human6 "$r2")"
|
||||
else
|
||||
echo " USDC (quote): N/A (no official USDC contract on 138)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Note: Pool 1 (cUSDT/cUSDC) is the only pool with liquidity on 138. Pools 2 and 3 use official USDT/USDC which have no contract on Chain 138."
|
||||
echo "Done."
|
||||
@@ -32,11 +32,11 @@ FEE_COLLECTOR=0xF78246eB94c6CB14018E507E60661314E5f4C53f
|
||||
DEBT_REGISTRY=0x95BC4A997c0670d5DAC64d55cDf3769B53B63C28
|
||||
POLICY_MANAGER=0x0C4FD27018130A00762a802f91a72D6a64a60F14
|
||||
TOKEN_IMPLEMENTATION=0x0059e237973179146237aB49f1322E8197c22b21
|
||||
CCIPWETH9_BRIDGE_CHAIN138=0x971cD9D156f193df8051E48043C476e53ECd4693
|
||||
CCIPWETH9_BRIDGE_CHAIN138=0x9cba0D04Ae5f6f16e3C599025aB97a05c4A593d5
|
||||
CCIPWETH10_BRIDGE_CHAIN138=0xe0E93247376aa097dB308B92e6Ba36bA015535D0
|
||||
LINK_TOKEN=0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03
|
||||
CCIP_FEE_TOKEN=0xb7721dD53A8c629d9f1Ba31a5819AFe250002b03
|
||||
CCIP_ROUTER=0x8078A09637e47Fa5Ed34F626046Ea2094a5CDE5e
|
||||
CCIP_ROUTER=0x89EC6574eeAC72Ed1b93DfCa4DB43547C8367FF0
|
||||
CCIP_SENDER=0x105F8A15b819948a89153505762444Ee9f324684
|
||||
UNIVERSAL_ASSET_REGISTRY=0xAEE4b7fBe82E1F8295951584CBc772b8BBD68575
|
||||
GOVERNANCE_CONTROLLER=0xA6891D5229f2181a34D4FF1B515c3Aa37dd90E0e
|
||||
|
||||
Reference in New Issue
Block a user