Files
proxmox/scripts/deployment/plan-mainnet-cwusdc-flash-quote-push-rebalance.sh
2026-04-13 21:38:57 -07:00

117 lines
5.7 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Plan rebalancing Mainnet cWUSDC/USDC when the operator wallet has **no USDC**.
#
# Direct addLiquidity (add-mainnet-public-dodo-cw-liquidity.sh) cannot run with zero
# wallet USDC: DODOPMMIntegration.addLiquidity requires baseAmount>0 AND quoteAmount>0.
#
# The repo-supported path without wallet USDC is the **flash quote-push** loop
# (Aave flashLoan USDC → PMM swap USDC→cWUSDC → external unwind cWUSDC→USDC
# → repay Aave + premium). Each successful round **raises PMM quote reserves** and
# **draws base** from the pool, moving base-heavy / quote-thin books toward peg.
# Retained quote surplus stays on the receiver until swept by the owner and can
# then be recycled into wallet-funded pool growth.
#
# This script is read-only + local modeling:
# - reads live pool reserves (cast)
# - prints copy/paste node commands for pmm-flash-push-break-even.mjs
# - points to on-chain execution (deploy + call receiver), not implemented here
#
# References:
# docs/03-deployment/MAINNET_CWUSD_HYBRID_FLASH_LOOP_CALCULATION_WHITEPAPER.md
# smom-dbis-138/contracts/flash/AaveQuotePushFlashReceiver.sol
# smom-dbis-138/script/deploy/DeployAaveQuotePushFlashReceiver.s.sol
# scripts/verify/run-mainnet-cwusdc-usdc-ladder-steps-1-3.sh (preflight + dry-run ladder)
# scripts/deployment/run-mainnet-cwusdc-flash-quote-push-model-sweep.sh (multi-size dry-run loop)
#
# Usage:
# source scripts/lib/load-project-env.sh
# bash scripts/deployment/plan-mainnet-cwusdc-flash-quote-push-rebalance.sh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROXMOX_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
# shellcheck disable=SC1091
source "${PROXMOX_ROOT}/scripts/lib/load-project-env.sh" 2>/dev/null || true
# shellcheck disable=SC1091
source "${PROXMOX_ROOT}/smom-dbis-138/scripts/load-env.sh" >/dev/null 2>&1 || true
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "[fail] missing required command: $1" >&2
exit 1
}
}
require_cmd cast
RPC_URL="${ETHEREUM_MAINNET_RPC:-}"
CWUSDC="${CWUSDC_MAINNET:-0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a}"
USDC="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
INTEGRATION="${DODO_PMM_INTEGRATION_MAINNET:-}"
POOL="${POOL_CWUSDC_USDC_MAINNET:-0x69776fc607e9edA8042e320e7e43f54d06c68f0E}"
if [[ -z "$RPC_URL" ]]; then
echo "[fail] ETHEREUM_MAINNET_RPC is required" >&2
exit 1
fi
if [[ -n "$INTEGRATION" ]]; then
mapped_pool="$(cast call "$INTEGRATION" 'pools(address,address)(address)' "$CWUSDC" "$USDC" --rpc-url "$RPC_URL" 2>/dev/null | awk '{print $1}' || true)"
if [[ -n "$mapped_pool" && "$mapped_pool" != "0x0000000000000000000000000000000000000000" && "${mapped_pool,,}" != "${POOL,,}" ]]; then
POOL="$mapped_pool"
fi
fi
out="$(cast call "$POOL" 'getVaultReserve()(uint256,uint256)' --rpc-url "$RPC_URL")"
B="$(printf '%s\n' "$out" | sed -n '1p' | awk '{print $1}')"
Q="$(printf '%s\n' "$out" | sed -n '2p' | awk '{print $1}')"
PMM_JS="${PROXMOX_ROOT}/scripts/analytics/pmm-flash-push-break-even.mjs"
DEFAULT_EXIT_CMD="printf 1.02"
EXIT_CMD="${PMM_FLASH_EXIT_PRICE_CMD:-$DEFAULT_EXIT_CMD}"
echo "=== Mainnet cWUSDC/USDC rebalance without wallet USDC (flash quote-push plan) ==="
echo "pool=$POOL"
echo "live_base_reserve_raw=$B live_quote_reserve_raw=$Q"
echo
echo "Why addLiquidity is not enough: integration requires both tokens from the wallet."
echo "Flash quote-push borrows USDC for the PMM leg; wallet only needs ETH for gas + a deployed receiver."
echo
echo "1) Model one or more flash sizes (read-only; tune -x or use model sweep script):"
echo "node \"${PMM_JS}\" \\"
echo " -B \"$B\" -Q \"$Q\" \\"
echo " --full-loop-dry-run --loop-strategy quote-push \\"
echo " -x 10000000 \\"
echo " --base-asset cWUSDC --base-decimals 6 --quote-asset USDC --quote-decimals 6 \\"
echo " --external-exit-price-cmd \"$EXIT_CMD\" \\"
echo " --flash-fee-bps 5 --lp-fee-bps 3 \\"
echo " --flash-provider-cap 1000000000000 --flash-provider-name 'Aave mainnet (cap placeholder)' \\"
echo " --gas-tx-count 3 --gas-per-tx 250000 --max-fee-gwei 40 --native-token-price 3200 \\"
echo " --max-post-trade-deviation-bps 500"
echo
echo "2) Multi-size modeling loop (still no chain writes):"
echo " FLASH_MODEL_SCAN_SIZES=5000000,10000000,25000000 \\"
echo " bash scripts/deployment/run-mainnet-cwusdc-flash-quote-push-model-sweep.sh"
echo
echo "3) On-chain stack (forge, from repo root):"
echo " bash scripts/deployment/deploy-mainnet-aave-quote-push-stack.sh --dry-run # then --apply"
echo " bash scripts/deployment/run-mainnet-aave-cwusdc-quote-push-once.sh --dry-run"
echo " FLASH_LOOP_COUNT=3 bash scripts/deployment/run-mainnet-aave-cwusdc-quote-push-loop.sh --apply"
echo " Route ladder on a local fork: bash scripts/verify/benchmark-mainnet-aave-quote-push-routes.sh"
echo " Solidity: smom-dbis-138/script/flash/RunMainnetAaveCwusdcUsdcQuotePushOnce.s.sol"
echo " Fork proofs: cd smom-dbis-138 && forge test --match-contract AaveQuotePushFlashReceiverMainnetForkTest"
echo
echo "4) Reserve peg monitor after any live work:"
echo " bash scripts/verify/check-mainnet-cwusdc-usdc-reserve-peg.sh"
echo
echo "5) Receiver surplus accounting and recycle path:"
echo " bash scripts/verify/report-mainnet-aave-quote-push-surplus-accounting.sh"
echo " bash scripts/deployment/sweep-mainnet-aave-quote-push-receiver-surplus.sh --dry-run"
echo " bash scripts/deployment/recycle-mainnet-aave-quote-push-surplus.sh --dry-run"
echo
echo "6) Pick a valid Uniswap V3 unwind (no guessing fee tiers):"
echo " bash scripts/verify/probe-uniswap-v3-cwusdc-usdc-mainnet.sh"
echo " If no pool: UNWIND_MODE=2 — build path: bash scripts/verify/build-uniswap-v3-exact-input-path-hex.sh ... (VERIFY_POOLS=1 optional)"
echo " Calculations report (dry-run snapshots): reports/status/mainnet_cwusdc_usdc_quote_push_calculations_2026-04-12.md"