Files
proxmox/scripts/lib/promod_uniswap_v2_liquidity_program.py

204 lines
8.9 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
from pathlib import Path
import json
import time
ROOT = Path(__file__).resolve().parents[2]
POOL_MATRIX = ROOT / "cross-chain-pmm-lps" / "config" / "pool-matrix.json"
DEPLOYMENT_STATUS = ROOT / "cross-chain-pmm-lps" / "config" / "deployment-status.json"
POLICY = ROOT / "config" / "extraction" / "promod-uniswap-v2-liquidity-policy.json"
REPORT = ROOT / "reports" / "extraction" / "promod-uniswap-v2-liquidity-program-latest.json"
DOC = ROOT / "docs" / "03-deployment" / "PROMOD_UNISWAP_V2_LIQUIDITY_PROGRAM.md"
def load(path: Path):
return json.loads(path.read_text())
def write_json(path: Path, payload):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(payload, indent=2) + "\n")
def write_text(path: Path, text: str):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text.rstrip() + "\n")
def now():
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
def tier_for(chain_id: str, tiers: dict) -> str:
for tier_name, chain_ids in tiers.items():
if chain_id in chain_ids:
return tier_name
return "unassigned"
CORE_RAILS = {"cWUSDC", "cWUSDT", "cWAUSDT"}
def build_additional_gru_pairs(cw_symbols: list[str]) -> list[str]:
extras = [symbol for symbol in cw_symbols if symbol not in CORE_RAILS]
pairs: list[str] = []
for symbol in extras:
if "cWUSDC" in cw_symbols:
pairs.append(f"{symbol}/cWUSDC")
if "cWUSDT" in cw_symbols:
pairs.append(f"{symbol}/cWUSDT")
return pairs
def main():
matrix = load(POOL_MATRIX)
status = load(DEPLOYMENT_STATUS)
policy = load(POLICY)
entries = []
tier_counts = {}
for chain_id in sorted(matrix["chains"].keys(), key=lambda c: int(c)):
chain_matrix = matrix["chains"][chain_id]
chain_status = status["chains"].get(chain_id)
if not chain_status or not chain_status.get("bridgeAvailable"):
continue
cw_tokens = chain_status.get("cwTokens", {})
cw_symbols = sorted(cw_tokens.keys())
additional_gru_tokens = [symbol for symbol in cw_symbols if symbol not in CORE_RAILS]
hub = chain_matrix.get("hubStable")
pools_first = chain_matrix.get("poolsFirst", [])
existing_pairs = sorted(
{
f"{pool.get('base')}/{pool.get('quote')}"
for pool in (chain_status.get("pmmPools") or [])
if pool.get("base") and pool.get("quote")
}
)
wrapped_pairs = []
if "cWAUSDT" in cw_tokens and "cWUSDC" in cw_tokens:
wrapped_pairs.append("cWAUSDT/cWUSDC")
if "cWAUSDT" in cw_tokens and "cWUSDT" in cw_tokens:
wrapped_pairs.append("cWAUSDT/cWUSDT")
if "cWUSDT" in cw_tokens and "cWUSDC" in cw_tokens:
wrapped_pairs.append("cWUSDT/cWUSDC")
additional_wrapped_pairs = build_additional_gru_pairs(cw_symbols)
settlement_candidates = []
for symbol in ("cWUSDC", "cWUSDT", "cWAUSDT"):
pair = f"{symbol}/{hub}"
if symbol in cw_tokens and pair in pools_first:
settlement_candidates.append(pair)
blockers = [
"Uniswap V2 factory/router addresses are not documented in-repo for this chain; env-backed deployment or factory mapping is still required.",
"New Uniswap V2 pools must be added to token-aggregation indexing and MCP/API visibility before promotion."
]
if "cWAUSDT" not in cw_tokens:
blockers.append("cWAUSDT is not currently documented on this chain, so wrapped-depth phase is limited to cWUSDT/cWUSDC.")
if not settlement_candidates:
blockers.append("No canonical settlement candidate from the current pool-matrix matched the documented cW token set.")
tier = tier_for(chain_id, policy["priority_tiers"])
tier_counts[tier] = tier_counts.get(tier, 0) + 1
entries.append(
{
"chain_id": int(chain_id),
"network": chain_matrix.get("name"),
"tier": tier,
"hub_stable": hub,
"bridge_available": True,
"documented_cw_tokens": cw_symbols,
"additional_gru_v2_cw_tokens": additional_gru_tokens,
"wrapped_depth_phase_pairs": wrapped_pairs,
"additional_wrapped_depth_pairs": additional_wrapped_pairs,
"settlement_phase_pairs": settlement_candidates,
"existing_pmm_analogs": [
pair
for pair in existing_pairs
if pair in wrapped_pairs or pair in settlement_candidates or pair in additional_wrapped_pairs
],
"uniswap_v2_deployment_status": "planned",
"required_uniswap_v2_env_suffixes": policy["uniswap_v2_requirements"]["required_env_suffixes"],
"blockers": blockers
}
)
payload = {
"generated_at": now(),
"program_name": policy["program_name"],
"purpose": policy["purpose"],
"operator_rule": policy["operator_rule"],
"mainnet_funding_posture": policy["mainnet_funding_posture"],
"wrapped_depth_phase": policy["wrapped_depth_phase"],
"settlement_phase": policy["settlement_phase"],
"priority_tiers": policy["priority_tiers"],
"tier_counts": tier_counts,
"registry_sources": [
"cross-chain-pmm-lps/config/pool-matrix.json",
"cross-chain-pmm-lps/config/deployment-status.json",
"config/extraction/promod-uniswap-v2-liquidity-policy.json"
],
"entries": entries
}
write_json(REPORT, payload)
lines = [
"# Mr. Promod Uniswap V2 Liquidity Program",
"",
f"- Generated: `{payload['generated_at']}`",
f"- Program: {payload['program_name']}",
"- Strict note: this is a repo-native desired-state rollout package for Uniswap V2 or Uniswap-V2-compatible pools. It does not claim live deployment unless factory/router addresses and pool addresses are recorded.",
f"- Mainnet funding posture: `{payload['mainnet_funding_posture']['mode']}` via `{', '.join(payload['mainnet_funding_posture']['required_deployer_assets'])}`",
"",
"## Deployment Model",
"",
"- Phase 1: build wrapped-depth support first when canonical USDC or USDT is scarce.",
"- Phase 2: add or deepen canonical settlement rails once enough hub-stable inventory exists.",
"- Promotion gate: do not treat any Uniswap V2 rail as live until its factory/router env, pool address, and indexer visibility are all recorded.",
"",
"## Wrapped-Depth Policy",
"",
f"- Preferred wrapped pairs: `{', '.join(payload['wrapped_depth_phase']['preferred_pairs_in_order'])}`",
f"- Allocation split: flagship `{payload['wrapped_depth_phase']['allocation_share_pct']['flagship_pair']}%`, second `{payload['wrapped_depth_phase']['allocation_share_pct']['second_pair']}%`, third `{payload['wrapped_depth_phase']['allocation_share_pct']['third_pair']}%`",
"",
"## Operator Matrix",
"",
"| Chain | Network | Tier | Hub Stable | Core Wrapped Pairs | Additional GRU v2 cW* Tokens | Next Wrapped Expansion Pairs | Settlement Phase Pairs | Existing PMM Analogs |",
"|---|---|---|---|---|---|---|---|---|",
]
for entry in entries:
wrapped = ", ".join(f"`{pair}`" for pair in entry["wrapped_depth_phase_pairs"]) or ""
extra_tokens = ", ".join(f"`{token}`" for token in entry["additional_gru_v2_cw_tokens"]) or ""
extra_pairs = ", ".join(f"`{pair}`" for pair in entry["additional_wrapped_depth_pairs"][:8]) or ""
settlement = ", ".join(f"`{pair}`" for pair in entry["settlement_phase_pairs"]) or ""
analogs = ", ".join(f"`{pair}`" for pair in entry["existing_pmm_analogs"]) or ""
lines.append(
f"| `{entry['chain_id']}` | {entry['network']} | `{entry['tier']}` | `{entry['hub_stable']}` | {wrapped} | {extra_tokens} | {extra_pairs} | {settlement} | {analogs} |"
)
lines.extend(
[
"",
"## Readiness Rules",
"",
"- Use `cWAUSDT` as a wrapped-depth support asset, not as a full replacement for `USDC` or `USDT` settlement.",
"- Keep `cWUSDT/cWUSDC` available everywhere both core wrapped rails are documented.",
"- After the first rail is live, expand the other documented GRU v2 `cW*` assets against `cWUSDC` and `cWUSDT` before opening broad canonical settlement exits.",
"- Prefer `cWUSDC/USDC`, `cWUSDT/USDT`, or `cWAUSDT/USDC|USDT` only after canonical hub inventory is deep enough to matter.",
"- For every promoted chain, add the new pools to `deployment-status.json`, Uniswap V2 env config, and token-aggregation indexing.",
]
)
write_text(DOC, "\n".join(lines))
print(REPORT)
if __name__ == "__main__":
main()