Files
proxmox/scripts/verify/plan-mainnet-cwusdc-usdc-repeg.py
defiQUG dd02f4b59b
All checks were successful
Deploy to Phoenix / validate (push) Successful in 1m11s
Deploy to Phoenix / deploy (push) Successful in 43s
Deploy to Phoenix / deploy-atomic-swap-dapp (push) Successful in 1m32s
phoenix-deploy Deployed to cloudflare-sync
Deploy to Phoenix / cloudflare (push) Successful in 38s
Enhance .env configuration with Infura support and add new RPC endpoints for various networks. Update package.json with new deployment scripts for Engine X. Improve public LP compliance documentation in runbooks and scripts, including guidance for public pair repairs and funding strategies.
2026-05-07 18:19:37 -07:00

480 lines
22 KiB
Python

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import os
import re
import subprocess
import sys
from datetime import datetime, timezone
from decimal import Decimal, ROUND_CEILING, getcontext
from pathlib import Path
getcontext().prec = 42
ROOT = Path(__file__).resolve().parents[2]
LATEST_SNAPSHOT = ROOT / "reports" / "status" / "mainnet-cwusdc-usdc-preflight-latest.json"
POLICY_PATH = ROOT / "config" / "extraction" / "mainnet-cwusdc-usdc-support-policy.json"
ROOT_ENV_PATH = ROOT / ".env"
SMOM_ENV_PATH = ROOT / "smom-dbis-138" / ".env"
ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
DEFAULT_CWUSDC = "0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a"
DEFAULT_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
SIX_DECIMALS = Decimal(10) ** 6
ADDRESS_RE = re.compile(r"0x[a-fA-F0-9]{40}")
UINT_RE = re.compile(r"\b\d+\b")
def load_json(path: Path) -> dict:
return json.loads(path.read_text())
def load_env_file(path: Path) -> dict[str, str]:
values: dict[str, str] = {}
if not path.exists():
return values
for raw_line in path.read_text().splitlines():
line = raw_line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
values[key.strip()] = value.strip().strip('"').strip("'")
return values
def merged_env_values() -> dict[str, str]:
values: dict[str, str] = {}
values.update(load_env_file(ROOT_ENV_PATH))
values.update(load_env_file(SMOM_ENV_PATH))
return values
def resolve_env_value(key: str, env_values: dict[str, str], seen: set[str] | None = None) -> str:
if seen is None:
seen = set()
if key in seen:
return env_values.get(key, "")
seen.add(key)
value = os.environ.get(key) or env_values.get(key, "")
if value.startswith("${") and value.endswith("}"):
inner = value[2:-1]
target = inner.split(":-", 1)[0]
fallback = inner.split(":-", 1)[1] if ":-" in inner else ""
resolved = resolve_env_value(target, env_values, seen)
return resolved or fallback
return value.rstrip("\r\n")
def normalize_units(raw: int, decimals: int = 6) -> Decimal:
return Decimal(raw) / (Decimal(10) ** decimals)
def units_to_raw(units: Decimal, decimals: int = 6) -> int:
scale = Decimal(10) ** decimals
return int((units * scale).to_integral_value(rounding=ROUND_CEILING))
def decimal_max(a: Decimal, b: Decimal) -> Decimal:
return a if a >= b else b
def parse_uint(value: str) -> int:
matches = UINT_RE.findall(value)
if not matches:
raise ValueError(f"could not parse integer from {value!r}")
return int(matches[0])
def parse_address(value: str) -> str:
match = ADDRESS_RE.search(value)
if not match:
raise ValueError(f"could not parse address from {value!r}")
return match.group(0)
def cast_call(rpc_url: str, target: str, signature: str, *args: str) -> str:
cmd = ["cast", "call", target, signature, *args, "--rpc-url", rpc_url]
return subprocess.check_output(cmd, text=True).strip()
def query_balance(rpc_url: str, token: str, holder: str) -> int:
return parse_uint(cast_call(rpc_url, token, "balanceOf(address)(uint256)", holder))
def derive_holder_from_private_key(env_values: dict[str, str]) -> str:
private_key = resolve_env_value("PRIVATE_KEY", env_values) or resolve_env_value("KEEPER_PRIVATE_KEY", env_values)
if not private_key or "${" in private_key:
return ""
output = subprocess.check_output(["cast", "wallet", "address", "--private-key", private_key], text=True).strip()
return parse_address(output)
def shell_quote(value: str) -> str:
return "'" + value.replace("'", "'\"'\"'") + "'"
def command_block(lines: list[str]) -> str:
return "\n".join(lines)
def funding_status(required_raw: int, available_raw: int, decimals: int = 6) -> dict:
shortfall_raw = max(required_raw - available_raw, 0)
return {
"requiredRaw": str(required_raw),
"requiredUnits": str(normalize_units(required_raw, decimals)),
"availableRaw": str(available_raw),
"availableUnits": str(normalize_units(available_raw, decimals)),
"shortfallRaw": str(shortfall_raw),
"shortfallUnits": str(normalize_units(shortfall_raw, decimals)),
"covered": shortfall_raw == 0,
}
def public_reseed_status(
base_shortfall_raw: int,
quote_shortfall_raw: int,
base_funding: dict,
quote_funding: dict,
) -> str:
if base_shortfall_raw == 0 and quote_shortfall_raw == 0:
return "ready"
if quote_shortfall_raw > 0 and not quote_funding["covered"]:
return "needs_usdc"
if base_shortfall_raw > 0 and not base_funding["covered"]:
return "needs_cwusdc"
if quote_shortfall_raw > 0:
return "needs_quote_side_repair"
return "needs_base_side_reseed"
def build_plan(snapshot: dict, policy: dict, env_values: dict[str, str], holder_override: str) -> dict:
rpc_url = resolve_env_value("ETHEREUM_MAINNET_RPC", env_values)
if not rpc_url:
raise RuntimeError("missing ETHEREUM_MAINNET_RPC")
summary = snapshot["summary"]
public_health = snapshot["health"]["publicPairHealth"]
defended_health = snapshot["health"]["defendedVenueHealth"]
treasury = snapshot.get("treasuryManager") or {}
base_reserve_raw = int(summary["defendedBaseReserveRaw"])
quote_reserve_raw = int(summary["defendedQuoteReserveRaw"])
target_reserve_raw = max(base_reserve_raw, quote_reserve_raw)
add_quote_raw = max(base_reserve_raw - quote_reserve_raw, 0)
add_base_raw = max(quote_reserve_raw - base_reserve_raw, 0)
min_base_units = Decimal(str(policy["thresholds"]["minBaseReserveUnits"]))
min_quote_units = Decimal(str(policy["thresholds"]["minQuoteReserveUnits"]))
public_base_units = Decimal(str(summary["publicPairBaseReserveUnits"]))
public_quote_units = Decimal(str(summary["publicPairQuoteReserveUnits"]))
public_base_shortfall_units = decimal_max(min_base_units - public_base_units, Decimal(0))
public_quote_shortfall_units = decimal_max(min_quote_units - public_quote_units, Decimal(0))
public_base_shortfall_raw = units_to_raw(public_base_shortfall_units)
public_quote_shortfall_raw = units_to_raw(public_quote_shortfall_units)
max_automated_raw = int(policy["managedCycle"]["maxAutomatedFlashQuoteAmountRaw"])
manager_available_raw = int(treasury.get("availableQuoteRaw") or 0)
holder = holder_override or derive_holder_from_private_key(env_values)
cwusdc = resolve_env_value("CWUSDC_MAINNET", env_values) or DEFAULT_CWUSDC
usdc = resolve_env_value("USDC_MAINNET", env_values) or DEFAULT_USDC
manager = snapshot["resolvedAddresses"].get("treasuryManager") or ""
receiver = snapshot["resolvedAddresses"].get("receiver") or ""
defended_pool = snapshot["health"]["defendedVenue"]["poolAddress"]
public_pair = snapshot["health"]["publicPair"]["poolAddress"]
integration = resolve_env_value("DODO_PMM_INTEGRATION_MAINNET", env_values)
router = resolve_env_value("CHAIN_1_UNISWAP_V2_ROUTER", env_values)
holder_state = None
holder_usdc_raw = 0
holder_cwusdc_raw = 0
holder_blockers: list[str] = []
if holder and holder.lower() != ZERO_ADDRESS:
try:
holder_cwusdc_raw = query_balance(rpc_url, cwusdc, holder)
holder_usdc_raw = query_balance(rpc_url, usdc, holder)
holder_state = {
"address": holder,
"cwusdcBalanceRaw": str(holder_cwusdc_raw),
"cwusdcBalanceUnits": str(normalize_units(holder_cwusdc_raw)),
"usdcBalanceRaw": str(holder_usdc_raw),
"usdcBalanceUnits": str(normalize_units(holder_usdc_raw)),
}
except Exception as exc:
holder_blockers.append(f"holder balance query failed: {exc}")
manager_funding = funding_status(max_automated_raw, manager_available_raw)
defended_quote_funding = funding_status(add_quote_raw, holder_usdc_raw)
public_base_funding = funding_status(public_base_shortfall_raw, holder_cwusdc_raw)
public_quote_funding = funding_status(public_quote_shortfall_raw, holder_usdc_raw)
blockers: list[str] = []
warnings = snapshot.get("warnings") or []
if add_base_raw > 0:
blockers.append("defended pool needs base-side top-up logic; current plan only supports quote-side top-up for this rail")
if add_quote_raw > 0 and holder_state and not defended_quote_funding["covered"]:
blockers.append(
"operator wallet does not hold enough USDC to restore defended pool reserve parity; external funding is required"
)
if public_base_shortfall_raw > 0 and holder_state and not public_base_funding["covered"]:
blockers.append(
"operator wallet does not hold enough cWUSDC to reseed the public pair to policy floor; external mint/bridge is required"
)
if public_quote_shortfall_raw > 0 and holder_state and not public_quote_funding["covered"]:
blockers.append(
"operator wallet does not hold enough USDC to reseed the public pair to policy floor"
)
if manager_funding["covered"] is False and holder_state and holder_usdc_raw < max_automated_raw:
blockers.append("operator wallet cannot fully fund even one max-sized automated defense cycle from current USDC balance")
if not integration:
blockers.append("missing DODO_PMM_INTEGRATION_MAINNET")
if not router:
blockers.append("missing CHAIN_1_UNISWAP_V2_ROUTER")
if any("defended quote query failed" in warning for warning in warnings):
blockers.append("defended pool quote preview reverted; set MIN_BASE_OUT_RAW manually before any quote-in trade")
public_deviation_bps = Decimal(str(summary["publicPairDeviationBps"]))
public_price_distorted = public_deviation_bps >= Decimal(str(policy["thresholds"]["warnDeviationBps"]))
if public_price_distorted:
warnings.append("public pair is materially asymmetric; plain addLiquidity follows the current reserve ratio and will not repair price")
operator_commands = {
"rerunPreflight": "bash scripts/verify/snapshot-mainnet-cwusdc-usdc-preflight.sh",
"rerunPlan": "bash scripts/verify/plan-mainnet-cwusdc-usdc-repeg.sh",
}
if manager and manager.lower() != ZERO_ADDRESS:
operator_commands["fundManagerUsdc"] = command_block(
[
"source smom-dbis-138/scripts/load-env.sh >/dev/null",
f"export USDC={usdc}",
f"export MANAGER={manager}",
f"export AMOUNT_RAW={max_automated_raw}",
'cast send "$USDC" \'transfer(address,uint256)(bool)\' "$MANAGER" "$AMOUNT_RAW" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
]
)
if integration and add_quote_raw > 0:
operator_commands["tradeDefendedPoolQuoteIn"] = command_block(
[
"source smom-dbis-138/scripts/load-env.sh >/dev/null",
f"export CWUSDC={cwusdc}",
f"export USDC={usdc}",
f"export INTEGRATION={integration}",
f"export POOL={defended_pool}",
f"export QUOTE_IN_RAW={add_quote_raw}",
"export MIN_BASE_OUT_RAW=REPLACE_AFTER_DRY_RUN",
'cast send "$USDC" \'approve(address,uint256)(bool)\' "$INTEGRATION" "$QUOTE_IN_RAW" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
'cast send "$INTEGRATION" \'swapExactIn(address,address,uint256,uint256)\' "$POOL" "$USDC" "$QUOTE_IN_RAW" "$MIN_BASE_OUT_RAW" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
]
)
if router and public_base_shortfall_raw > 0 and public_quote_shortfall_raw > 0:
operator_commands["reseedPublicPair"] = command_block(
[
"source smom-dbis-138/scripts/load-env.sh >/dev/null",
f"export ROUTER={router}",
f"export CWUSDC={cwusdc}",
f"export USDC={usdc}",
f"export BASE_AMOUNT_RAW={public_base_shortfall_raw}",
f"export QUOTE_AMOUNT_RAW={public_quote_shortfall_raw}",
'export DEADLINE="$(( $(date +%s) + 3600 ))"',
'export SIGNER="$(cast wallet address --private-key "$PRIVATE_KEY")"',
'cast send "$CWUSDC" \'approve(address,uint256)(bool)\' "$ROUTER" "$BASE_AMOUNT_RAW" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
'cast send "$USDC" \'approve(address,uint256)(bool)\' "$ROUTER" "$QUOTE_AMOUNT_RAW" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
'cast send "$ROUTER" \'addLiquidity(address,address,uint256,uint256,uint256,uint256,address,uint256)\' \\',
' "$CWUSDC" "$USDC" "$BASE_AMOUNT_RAW" "$QUOTE_AMOUNT_RAW" "$BASE_AMOUNT_RAW" "$QUOTE_AMOUNT_RAW" "$SIGNER" "$DEADLINE" \\',
' --private-key "$PRIVATE_KEY" --rpc-url "$ETHEREUM_MAINNET_RPC"',
]
)
if (
public_base_shortfall_raw > 0
or public_quote_shortfall_raw > 0
or public_price_distorted
):
operator_commands["publicPairRepairGuidance"] = command_block(
[
"# Public cWUSDC/USDC is one-sided or price-distorted.",
"# Do not use addLiquidity by itself as a price repair when only one reserve side is short.",
"# Use official Mainnet USDC for a quote-side repair swap first, then add balanced",
"# liquidity only after the reserve-implied price is back inside policy gates.",
"bash scripts/verify/snapshot-mainnet-cwusdc-usdc-preflight.sh",
"bash scripts/verify/plan-mainnet-cwusdc-usdc-repeg.sh",
]
)
public_action_status = public_reseed_status(
public_base_shortfall_raw,
public_quote_shortfall_raw,
public_base_funding,
public_quote_funding,
)
needs_external_funding = (
not defended_quote_funding["covered"]
or not public_base_funding["covered"]
or not public_quote_funding["covered"]
)
recommended_next_action = "execute_verified_repair"
if public_quote_shortfall_raw > 0 and not public_quote_funding["covered"]:
recommended_next_action = "acquire_official_mainnet_usdc"
elif public_quote_shortfall_raw > 0 or public_price_distorted:
recommended_next_action = "run_quote_side_public_pair_repair_before_balanced_liquidity"
elif add_quote_raw > 0 and not defended_quote_funding["covered"]:
recommended_next_action = "acquire_official_mainnet_usdc_for_defended_parity"
recommended_actions = [
{
"step": "fund_manager_for_one_max_cycle",
"quoteAmountRaw": str(max_automated_raw),
"quoteAmountUnits": str(normalize_units(max_automated_raw)),
"status": "ready" if manager_funding["covered"] else "needs_usdc",
},
{
"step": "sell_usdc_into_defended_pool_toward_simple_1_to_1_reserve_parity",
"baseAmountRaw": str(add_base_raw),
"quoteAmountRaw": str(add_quote_raw),
"quoteAmountUnits": str(normalize_units(add_quote_raw)),
"status": "ready" if add_quote_raw == 0 or defended_quote_funding["covered"] else "needs_usdc",
},
{
"step": "reseed_public_pair_to_policy_floor",
"baseAmountRaw": str(public_base_shortfall_raw),
"baseAmountUnits": str(normalize_units(public_base_shortfall_raw)),
"quoteAmountRaw": str(public_quote_shortfall_raw),
"quoteAmountUnits": str(normalize_units(public_quote_shortfall_raw)),
"status": public_action_status,
"guidance": (
"Use quote-side repair before balanced liquidity; plain addLiquidity cannot repair an asymmetric public pair."
if public_quote_shortfall_raw > 0 or public_price_distorted
else "Use addLiquidity only after price and reserve gates pass."
),
},
]
return {
"generatedAt": datetime.now(timezone.utc).isoformat(),
"mode": "read_only_repeg_plan",
"summary": {
"publicPairBaseReserveUnits": str(public_base_units),
"publicPairQuoteReserveUnits": str(public_quote_units),
"publicPairDeviationBps": str(summary["publicPairDeviationBps"]),
"publicPolicyFloorBaseShortfallUnits": str(normalize_units(public_base_shortfall_raw)),
"publicPolicyFloorQuoteShortfallUnits": str(normalize_units(public_quote_shortfall_raw)),
"publicPairRepairRequiresQuoteSideAction": public_quote_shortfall_raw > 0 or public_price_distorted,
"publicIndexedLpComplianceStatus": (
"blocked_missing_quote_side_public_lp_evidence"
if public_quote_shortfall_raw > 0 or public_price_distorted
else "ready_for_evidence_review"
),
"defendedAddQuoteUnits": str(normalize_units(add_quote_raw)),
"managerFundingShortfallUnits": manager_funding["shortfallUnits"],
"needsExternalFunding": needs_external_funding,
"recommendedNextAction": recommended_next_action,
},
"snapshotPath": str(LATEST_SNAPSHOT),
"policyPath": str(POLICY_PATH),
"inferenceNotes": [
"Defended-pool 1:1 sizing is inferred from equal 6-decimal matched-rail tokens and reserve-balance parity.",
"DODO PMM mid-price can still differ from reserve ratio; rerun preflight after each funding action.",
"Public-pair reseed target uses the current policy reserve floors, not a smaller cosmetic liquidity target.",
],
"resolvedAddresses": {
"holder": holder or None,
"cwusdc": cwusdc,
"usdc": usdc,
"publicPair": public_pair,
"defendedPool": defended_pool,
"treasuryManager": manager or None,
"receiver": receiver or None,
"dodoIntegration": integration or None,
"uniswapV2Router": router or None,
},
"defendedVenue": {
"midPrice": summary["defendedMidPrice"],
"deviationBps": summary["defendedDeviationBps"],
"baseReserveRaw": str(base_reserve_raw),
"baseReserveUnits": str(normalize_units(base_reserve_raw)),
"quoteReserveRaw": str(quote_reserve_raw),
"quoteReserveUnits": str(normalize_units(quote_reserve_raw)),
"simpleReserveParity": {
"targetReservePerSideRaw": str(target_reserve_raw),
"targetReservePerSideUnits": str(normalize_units(target_reserve_raw)),
"addBaseRaw": str(add_base_raw),
"addBaseUnits": str(normalize_units(add_base_raw)),
"addQuoteRaw": str(add_quote_raw),
"addQuoteUnits": str(normalize_units(add_quote_raw)),
},
},
"publicLane": {
"pairAddress": public_pair,
"priceQuotePerBase": public_health["priceQuotePerBase"],
"deviationBps": summary["publicPairDeviationBps"],
"baseReserveUnits": str(public_base_units),
"quoteReserveUnits": str(public_quote_units),
"policyFloorBaseUnits": str(min_base_units),
"policyFloorQuoteUnits": str(min_quote_units),
"policyFloorBaseShortfallRaw": str(public_base_shortfall_raw),
"policyFloorBaseShortfallUnits": str(normalize_units(public_base_shortfall_raw)),
"policyFloorQuoteShortfallRaw": str(public_quote_shortfall_raw),
"policyFloorQuoteShortfallUnits": str(normalize_units(public_quote_shortfall_raw)),
},
"automation": {
"managerAvailableQuoteRaw": str(manager_available_raw),
"managerAvailableQuoteUnits": str(normalize_units(manager_available_raw)),
"maxAutomatedFlashQuoteAmountRaw": str(max_automated_raw),
"maxAutomatedFlashQuoteAmountUnits": str(normalize_units(max_automated_raw)),
"managerFundingForOneMaxCycle": manager_funding,
},
"holderState": holder_state,
"holderFundingChecks": {
"defendedQuoteTopUp": defended_quote_funding,
"publicPairBaseTopUp": public_base_funding,
"publicPairQuoteTopUp": public_quote_funding,
},
"recommendedActions": recommended_actions,
"operatorCommands": operator_commands,
"warnings": warnings,
"blockers": holder_blockers + blockers,
"status": {
"canFullyReachSimple1To1WithCurrentHolder": len(holder_blockers + blockers) == 0,
"needsExternalFunding": needs_external_funding,
"canFundManagerFromCurrentHolder": holder_usdc_raw >= max_automated_raw if holder_state else None,
},
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--snapshot", default=str(LATEST_SNAPSHOT), help="Path to a preflight snapshot JSON.")
parser.add_argument("--holder", default="", help="Optional holder address to inventory-check instead of deriving from PRIVATE_KEY.")
parser.add_argument("--out", help="Write the plan JSON to this file.")
args = parser.parse_args()
snapshot_path = Path(args.snapshot)
if not snapshot_path.exists():
raise RuntimeError(f"missing snapshot file: {snapshot_path}")
snapshot = load_json(snapshot_path)
policy = load_json(POLICY_PATH)
env_values = merged_env_values()
plan = build_plan(snapshot, policy, env_values, args.holder.strip())
output = json.dumps(plan, indent=2)
if args.out:
out_path = Path(args.out)
out_path.parent.mkdir(parents=True, exist_ok=True)
out_path.write_text(output + "\n")
print(output)
return 0
if __name__ == "__main__":
sys.exit(main())