Files
proxmox/scripts/deployment/replace-mainnet-public-dodo-cw-pool.sh
defiQUG fb1d90c3d2
All checks were successful
Deploy to Phoenix / deploy (push) Successful in 10s
Fix 256-bit allowance checks in mainnet PMM scripts
2026-04-14 18:22:53 -07:00

263 lines
8.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Replace a legacy Mainnet public DODO cW/USD pool in the integration mapping,
# create a canonical factory-backed replacement, and seed it with matched liquidity.
#
# Example:
# bash scripts/deployment/replace-mainnet-public-dodo-cw-pool.sh \
# --pair=cwusdc-usdc \
# --initial-price=1000000000000000000 \
# --base-amount=100000000 \
# --quote-amount=100000000 \
# --dry-run
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
source "${PROJECT_ROOT}/smom-dbis-138/scripts/load-env.sh" >/dev/null 2>&1
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "[fail] missing required command: $1" >&2
exit 1
}
}
uint_lt() {
python3 - "$1" "$2" <<'PY'
import sys
print("1" if int(sys.argv[1]) < int(sys.argv[2]) else "0")
PY
}
require_cmd cast
PAIR=""
INITIAL_PRICE=""
BASE_AMOUNT=""
QUOTE_AMOUNT=""
FEE_BPS="3"
K_VALUE="0"
OPEN_TWAP="false"
DRY_RUN=0
for arg in "$@"; do
case "$arg" in
--pair=*) PAIR="${arg#*=}" ;;
--initial-price=*) INITIAL_PRICE="${arg#*=}" ;;
--base-amount=*) BASE_AMOUNT="${arg#*=}" ;;
--quote-amount=*) QUOTE_AMOUNT="${arg#*=}" ;;
--fee-bps=*) FEE_BPS="${arg#*=}" ;;
--k=*) K_VALUE="${arg#*=}" ;;
--open-twap=*) OPEN_TWAP="${arg#*=}" ;;
--dry-run) DRY_RUN=1 ;;
*)
echo "[fail] unknown arg: $arg" >&2
exit 2
;;
esac
done
if [[ -z "$PAIR" || -z "$INITIAL_PRICE" || -z "$BASE_AMOUNT" || -z "$QUOTE_AMOUNT" ]]; then
echo "[fail] required args: --pair, --initial-price, --base-amount, --quote-amount" >&2
exit 1
fi
RPC_URL="${ETHEREUM_MAINNET_RPC:-}"
PRIVATE_KEY="${PRIVATE_KEY:-}"
INTEGRATION="${DODO_PMM_INTEGRATION_MAINNET:-}"
USDC_MAINNET="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
USDT_MAINNET="0xdAC17F958D2ee523a2206206994597C13D831ec7"
if [[ -z "$RPC_URL" || -z "$PRIVATE_KEY" || -z "$INTEGRATION" ]]; then
echo "[fail] ETHEREUM_MAINNET_RPC, PRIVATE_KEY, and DODO_PMM_INTEGRATION_MAINNET are required" >&2
exit 1
fi
DEPLOYER="$(cast wallet address --private-key "$PRIVATE_KEY")"
BASE_TOKEN=""
QUOTE_TOKEN=""
LEGACY_POOL=""
PAIR_LABEL=""
ENV_KEY=""
case "$PAIR" in
cwusdc-usdc)
BASE_TOKEN="${CWUSDC_MAINNET:-0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a}"
QUOTE_TOKEN="$USDC_MAINNET"
LEGACY_POOL="${POOL_CWUSDC_USDC_MAINNET:-0xB227dDA4e89E2EA63A1345509C9AC02644e8d526}"
PAIR_LABEL="cWUSDC/USDC"
ENV_KEY="POOL_CWUSDC_USDC_MAINNET"
;;
cwusdt-usdc)
BASE_TOKEN="${CWUSDT_MAINNET:-0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE}"
QUOTE_TOKEN="$USDC_MAINNET"
LEGACY_POOL="${POOL_CWUSDT_USDC_MAINNET:-0x27f3aE7EE71Be3d77bAf17d4435cF8B895DD25D2}"
PAIR_LABEL="cWUSDT/USDC"
ENV_KEY="POOL_CWUSDT_USDC_MAINNET"
;;
cwusdt-usdt)
BASE_TOKEN="${CWUSDT_MAINNET:-0xaF5017d0163ecb99D9B5D94e3b4D7b09Af44D8AE}"
QUOTE_TOKEN="$USDT_MAINNET"
LEGACY_POOL="${POOL_CWUSDT_USDT_MAINNET:-0x79156F6B7bf71a1B72D78189B540A89A6C13F6FC}"
PAIR_LABEL="cWUSDT/USDT"
ENV_KEY="POOL_CWUSDT_USDT_MAINNET"
;;
cwusdc-usdt)
BASE_TOKEN="${CWUSDC_MAINNET:-0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a}"
QUOTE_TOKEN="$USDT_MAINNET"
LEGACY_POOL="${POOL_CWUSDC_USDT_MAINNET:-0xCC0fd27A40775c9AfcD2BBd3f7c902b0192c247A}"
PAIR_LABEL="cWUSDC/USDT"
ENV_KEY="POOL_CWUSDC_USDT_MAINNET"
;;
*)
echo "[fail] unsupported pair: $PAIR" >&2
exit 2
;;
esac
bool_to_cli() {
if [[ "$1" == "true" ]]; then
printf 'true'
else
printf 'false'
fi
}
parse_tx_hash() {
local output="$1"
local tx_hash
tx_hash="$(printf '%s\n' "$output" | grep -E '^0x[0-9a-fA-F]{64}$' | tail -n1 || true)"
if [[ -z "$tx_hash" ]]; then
tx_hash="$(printf '%s\n' "$output" | grep -E '^transactionHash[[:space:]]+0x[0-9a-fA-F]{64}$' | awk '{print $2}' | tail -n1 || true)"
fi
if [[ -z "$tx_hash" ]]; then
return 1
fi
printf '%s\n' "$tx_hash"
}
mapped_pool_before="$(cast call "$INTEGRATION" 'pools(address,address)(address)' "$BASE_TOKEN" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" | awk '{print $1}')"
base_balance_before="$(cast call "$BASE_TOKEN" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
quote_balance_before="$(cast call "$QUOTE_TOKEN" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
base_allowance_before="$(cast call "$BASE_TOKEN" 'allowance(address,address)(uint256)' "$DEPLOYER" "$INTEGRATION" --rpc-url "$RPC_URL" | awk '{print $1}')"
quote_allowance_before="$(cast call "$QUOTE_TOKEN" 'allowance(address,address)(uint256)' "$DEPLOYER" "$INTEGRATION" --rpc-url "$RPC_URL" | awk '{print $1}')"
base_approval_required="$(uint_lt "$base_allowance_before" "$BASE_AMOUNT")"
quote_approval_required="$(uint_lt "$quote_allowance_before" "$QUOTE_AMOUNT")"
if (( base_balance_before < BASE_AMOUNT )); then
echo "[fail] insufficient base balance: have=$base_balance_before need=$BASE_AMOUNT" >&2
exit 1
fi
if (( quote_balance_before < QUOTE_AMOUNT )); then
echo "[fail] insufficient quote balance: have=$quote_balance_before need=$QUOTE_AMOUNT" >&2
exit 1
fi
remove_gas="$(cast estimate --from "$DEPLOYER" "$INTEGRATION" 'removePool(address)' "$LEGACY_POOL" --rpc-url "$RPC_URL")"
create_gas="post-remove estimate not available while current mapping exists"
if (( DRY_RUN == 1 )); then
echo "pair=$PAIR_LABEL"
echo "envKey=$ENV_KEY"
echo "legacyPool=$LEGACY_POOL"
echo "mappedPoolBefore=$mapped_pool_before"
echo "baseToken=$BASE_TOKEN"
echo "quoteToken=$QUOTE_TOKEN"
echo "initialPrice=$INITIAL_PRICE"
echo "feeBps=$FEE_BPS"
echo "k=$K_VALUE"
echo "openTwap=$OPEN_TWAP"
echo "baseAmount=$BASE_AMOUNT"
echo "quoteAmount=$QUOTE_AMOUNT"
echo "removeGas=$remove_gas"
echo "createGas=$create_gas"
echo "baseBalanceBefore=$base_balance_before"
echo "quoteBalanceBefore=$quote_balance_before"
echo "baseAllowanceBefore=$base_allowance_before"
echo "quoteAllowanceBefore=$quote_allowance_before"
exit 0
fi
remove_output="$(
cast send "$INTEGRATION" \
'removePool(address)' \
"$LEGACY_POOL" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY"
)"
remove_tx="$(parse_tx_hash "$remove_output")"
create_output="$(
cast send "$INTEGRATION" \
'createPool(address,address,uint256,uint256,uint256,bool)(address)' \
"$BASE_TOKEN" "$QUOTE_TOKEN" "$FEE_BPS" "$INITIAL_PRICE" "$K_VALUE" "$(bool_to_cli "$OPEN_TWAP")" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY"
)"
create_tx="$(parse_tx_hash "$create_output")"
new_pool="$(cast call "$INTEGRATION" 'pools(address,address)(address)' "$BASE_TOKEN" "$QUOTE_TOKEN" --rpc-url "$RPC_URL" | awk '{print $1}')"
if [[ "$new_pool" == "0x0000000000000000000000000000000000000000" ]]; then
echo "[fail] replacement pool mapping is empty after createPool" >&2
exit 1
fi
approve_base_tx=""
approve_quote_tx=""
if [[ "$base_approval_required" == "1" ]]; then
approve_base_output="$(
cast send "$BASE_TOKEN" \
'approve(address,uint256)(bool)' \
"$INTEGRATION" "$BASE_AMOUNT" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY"
)"
approve_base_tx="$(parse_tx_hash "$approve_base_output")"
fi
if [[ "$quote_approval_required" == "1" ]]; then
approve_quote_output="$(
cast send "$QUOTE_TOKEN" \
'approve(address,uint256)(bool)' \
"$INTEGRATION" "$QUOTE_AMOUNT" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY"
)"
approve_quote_tx="$(parse_tx_hash "$approve_quote_output")"
fi
add_output="$(
cast send "$INTEGRATION" \
'addLiquidity(address,uint256,uint256)(uint256,uint256,uint256)' \
"$new_pool" "$BASE_AMOUNT" "$QUOTE_AMOUNT" \
--rpc-url "$RPC_URL" \
--private-key "$PRIVATE_KEY"
)"
add_liquidity_tx="$(parse_tx_hash "$add_output")"
reserves_after="$(cast call "$new_pool" 'getVaultReserve()(uint256,uint256)' --rpc-url "$RPC_URL")"
base_reserve_after="$(printf '%s\n' "$reserves_after" | sed -n '1p' | awk '{print $1}')"
quote_reserve_after="$(printf '%s\n' "$reserves_after" | sed -n '2p' | awk '{print $1}')"
base_balance_after="$(cast call "$BASE_TOKEN" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
quote_balance_after="$(cast call "$QUOTE_TOKEN" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
echo "pair=$PAIR_LABEL"
echo "envKey=$ENV_KEY"
echo "legacyPool=$LEGACY_POOL"
echo "newPool=$new_pool"
echo "removeTx=$remove_tx"
echo "createTx=$create_tx"
echo "approveBaseTx=${approve_base_tx:-none}"
echo "approveQuoteTx=${approve_quote_tx:-none}"
echo "addLiquidityTx=$add_liquidity_tx"
echo "baseReserveAfter=$base_reserve_after"
echo "quoteReserveAfter=$quote_reserve_after"
echo "baseBalanceBefore=$base_balance_before"
echo "baseBalanceAfter=$base_balance_after"
echo "quoteBalanceBefore=$quote_balance_before"
echo "quoteBalanceAfter=$quote_balance_after"