204 lines
8.9 KiB
Python
204 lines
8.9 KiB
Python
|
|
#!/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()
|