Add ALL Mainnet completion planning evidence

This commit is contained in:
defiQUG
2026-04-29 23:52:52 -07:00
parent d5af3a2077
commit 33601f51b5
5 changed files with 581 additions and 40 deletions

View File

@@ -37,6 +37,24 @@
"Tiny live canary swap executed on ALL Mainnet Uniswap V2 WALL/AUSDC."
]
},
{
"poolId": "651940-dodo_pmm-wall-ausdt",
"generatedAt": "2026-04-30T06:58:00Z",
"canaryTransactions": [
{
"direction": "base_to_quote",
"txHash": "0x6b74c3b6816eb67409268a6e3b108fd631d278baf0fd57524a63c60c995bded3",
"fundingTransferTxHash": "0x2e1540c484abac9049e383a16fc35a5b6b81a33bd70183b80b20f94533dbe141",
"amountInRaw": "1000000",
"tokenIn": "WALL",
"tokenOut": "AUSDT",
"executor": "DODO_DVM.transfer_then_sellBase"
}
],
"notes": [
"Tiny live canary swap executed on ALL Mainnet DODO PMM WALL/AUSDT."
]
},
{
"poolId": "137-dodo_pmm-cwusdc-usdc",
"generatedAt": "2026-04-29T04:41:13.993Z",

View File

@@ -1,6 +1,6 @@
{
"version": "1.0.0",
"generatedAt": "2026-04-29T06:18:00Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"description": "Canonical pool-creation matrix for ALL Mainnet public spend readiness. Pools must exist here before funding.",
"lifecycle": [
"planned",
@@ -23,9 +23,9 @@
],
"statusCounts": {
"planned": 83,
"canary_passed": 5,
"canary_passed": 6,
"created": 17,
"live_read": 8
"live_read": 7
},
"protocolCounts": {
"dodo_pmm": 49,
@@ -292,7 +292,7 @@
"verification": "DODOPMMIntegration pools(base,quote) resolves to pool address; DVM clone has bytecode; initial reserves are zero until funding."
},
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-dodo_pmm-wall-ausdc",
"baseBalanceRaw": "1000000000001000000",
"quoteBalanceRaw": "999999999998000001",
@@ -444,10 +444,27 @@
"k": null,
"singleSided": false,
"publicRoutingEnabled": true,
"reserveSource": "all-mainnet-canonical-ausdt-correction",
"status": "live_read",
"reserveSource": "all-mainnet-required-pool-balance-check",
"status": "canary_passed",
"requiredForSpend": true,
"canaryEvidence": null,
"canaryEvidence": {
"generatedAt": "2026-04-30T06:58:00Z",
"sourceFile": "config/all-mainnet-canary-evidence.json",
"canaryTransactions": [
{
"direction": "base_to_quote",
"txHash": "0x6b74c3b6816eb67409268a6e3b108fd631d278baf0fd57524a63c60c995bded3",
"fundingTransferTxHash": "0x2e1540c484abac9049e383a16fc35a5b6b81a33bd70183b80b20f94533dbe141",
"amountInRaw": "1000000",
"tokenIn": "WALL",
"tokenOut": "AUSDT",
"executor": "DODO_DVM.transfer_then_sellBase"
}
],
"notes": [
"Tiny live canary swap executed on ALL Mainnet DODO PMM WALL/AUSDT."
]
},
"fundingTiersUsd": {
"seed": 10,
"smoke": 100,
@@ -464,7 +481,9 @@
"Canonical WALL/AUSDT DODO V2 DVM-backed pool created after quote asset correction from USDT to AUSDT.",
"Vault assignments applied from explicit All Mainnet vault assignment map.",
"Seeded with 1 WALL and 1 AUSDT from deployer wallet.",
"EnhancedSwapRouterV2 DODO route registered and quoteable."
"EnhancedSwapRouterV2 DODO route registered and quoteable.",
"Live reserve read recorded from required-pool balance checker.",
"Canary evidence recorded from explicit All Mainnet canary evidence file."
],
"infrastructure": {
"dvmFactory": "0x8a3403aef8d40c0F4AfaF6Dc2000A537EbC863c2",
@@ -477,16 +496,12 @@
"verification": "DODOPMMIntegration pools(WALL,AUSDT) resolves to pool address; DVM clone has bytecode."
},
"reserveEvidence": {
"generatedAt": "2026-04-29T05:48:00Z",
"baseBalanceRaw": "1000000000000000000",
"quoteBalanceRaw": "1000000000000000000",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-dodo_pmm-wall-ausdt",
"baseBalanceRaw": "1000000000001000000",
"quoteBalanceRaw": "999999999998000001",
"poolHasCode": true,
"liveReadStatus": "nonzero_base_and_quote",
"fundingTransactions": [
"0x2aa8835e2506e1d8802f9d14c570abdad7e14e9dfe0d0261f7e19da019215f25",
"0xc3a6a7edb6d9e9422a78fafae53bab9b96746a6fff83ca607edff7793286f294",
"0xf9344211547bccadc1b433cf31f6f953f15b915b7d031c03411a114e180cf399"
]
"liveReadStatus": "nonzero_base_and_quote"
},
"routerRouteEvidence": {
"routerAddress": "0xb905fEfA56b028221E2Bc248Bbcd41141dc7aeD3",
@@ -815,10 +830,10 @@
"Canary evidence recorded from explicit All Mainnet canary evidence file."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-uniswap_v2-wall-ausdc",
"baseBalanceRaw": "222025888680628319105322384",
"quoteBalanceRaw": "130598623255778071651280",
"baseBalanceRaw": "224445209871270534969174163",
"quoteBalanceRaw": "129194376317333448505973",
"poolHasCode": true,
"liveReadStatus": "nonzero_base_and_quote"
}
@@ -895,10 +910,10 @@
"Vault assignments applied from explicit All Mainnet vault assignment map."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-uniswap_v2-wall-usdt",
"baseBalanceRaw": "119579763278558287348114878",
"quoteBalanceRaw": "96183323535791914791099",
"baseBalanceRaw": "116762468938410673082689864",
"quoteBalanceRaw": "98510599724849461923660",
"poolHasCode": true,
"liveReadStatus": "nonzero_base_and_quote"
}
@@ -975,10 +990,10 @@
"Vault assignments applied from explicit All Mainnet vault assignment map."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-uniswap_v2-usdt-ausdc",
"baseBalanceRaw": "128823453150848278870209",
"quoteBalanceRaw": "77642915975212836473965",
"baseBalanceRaw": "126950810303091320030551",
"quoteBalanceRaw": "78791103453769787415423",
"poolHasCode": true,
"liveReadStatus": "nonzero_base_and_quote"
}
@@ -1205,7 +1220,7 @@
"Vault assignments applied from explicit All Mainnet vault assignment map."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#1-dodo_pmm-cwusdc-usdc",
"baseBalanceRaw": "818811480",
"quoteBalanceRaw": "233144600",
@@ -1285,7 +1300,7 @@
"Vault assignments applied from explicit All Mainnet vault assignment map."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#1-dodo_pmm-cwusdt-usdt",
"baseBalanceRaw": "9845664",
"quoteBalanceRaw": "2160199",
@@ -2583,7 +2598,7 @@
"Canary evidence recorded from explicit All Mainnet canary evidence file."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#137-dodo_pmm-cwusdc-usdc",
"baseBalanceRaw": "39885",
"quoteBalanceRaw": "39883",
@@ -2681,7 +2696,7 @@
"Canary evidence recorded from explicit All Mainnet canary evidence file."
],
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#137-dodo_pmm-cwusdt-usdt",
"baseBalanceRaw": "2605",
"quoteBalanceRaw": "2603",
@@ -3291,7 +3306,7 @@
"transactionHash": "0x6a63466a12d2ee71201be232db0af6d5f40f8d829dbe453c9f00abbe6df6fbb9"
},
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#8453-dodo_pmm-cwusdc-usdc",
"baseBalanceRaw": "1000000",
"quoteBalanceRaw": "1000000",
@@ -3977,7 +3992,7 @@
"transactionHash": "0x4385161e41e88a560cc5107020d6099c540428c4e39f2415e238a37de16f4d31"
},
"reserveEvidence": {
"generatedAt": "2026-04-29T04:41:20.353Z",
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#42161-dodo_pmm-cwusdc-usdc",
"baseBalanceRaw": "100000",
"quoteBalanceRaw": "100000",
@@ -8677,7 +8692,7 @@
"k": null,
"singleSided": false,
"publicRoutingEnabled": true,
"reserveSource": "uniswap_v3_position_manager_seed",
"reserveSource": "all-mainnet-required-pool-balance-check",
"status": "canary_passed",
"requiredForSpend": true,
"canaryEvidence": {
@@ -8712,7 +8727,8 @@
"notes": [
"ALL Mainnet official Uniswap V3 pool stack deployed from upstream Uniswap V3 artifacts.",
"AUSDT/WALL 0.30% pool initialized at 1:1 sqrtPriceX96 and seeded through NonfungiblePositionManager.",
"Standalone SwapRouter and Quoter are live and tested; EnhancedSwapRouterV2 V3 provider remains disabled until adapter quote compatibility is fixed."
"Standalone SwapRouter and Quoter are live and tested; EnhancedSwapRouterV2 V3 provider remains disabled until adapter quote compatibility is fixed.",
"Live reserve read recorded from required-pool balance checker."
],
"infrastructure": {
"nftDescriptorLibrary": "0xb53E8A0A19fB381537c6f28D37b7C2f7DC29EF02",
@@ -8731,12 +8747,12 @@
"verification": "UniswapV3Factory.getPool(AUSDT,WALL,3000) resolves to pool address; pool has code and liquidity."
},
"reserveEvidence": {
"generatedAt": "2026-04-29T06:14:00Z",
"liquidityRaw": "1000000000000000000",
"sqrtPriceX96": "79228162514264337593543950336",
"tick": 0,
"mintTxHash": "0x64660f089eac210ff94a1a01ffcdc1e3d9dc82739589b781d9ef18d8247a4754",
"liveReadStatus": "nonzero_liquidity"
"generatedAt": "2026-04-30T06:51:46.495Z",
"evidenceRef": "reports/status/all-mainnet-required-pool-balances-latest.json#651940-uniswap_v3-wall-ausdt",
"baseBalanceRaw": "1000000000001000000",
"quoteBalanceRaw": "999999999999003001",
"poolHasCode": true,
"liveReadStatus": "nonzero_base_and_quote"
},
"routerRouteEvidence": {
"routerAddress": "0xb905fEfA56b028221E2Bc248Bbcd41141dc7aeD3",

View File

@@ -0,0 +1,188 @@
# ALL Mainnet Protocol Completion Runbook
**Status:** Operator runbook
**Scope:** ALL Mainnet `651940` pool inventory, auto-rebalancing, and protocol support gates.
**Canonical inputs:** `config/all-mainnet-pool-creation-matrix.json`, `config/allmainnet-non-dodo-protocol-surface.json`
## Current State
The pool matrix already contains the intended inventory surface. Treat it as the source of truth for what must be created, funded, canaried, and eventually promoted.
As of the current matrix:
| Protocol | Rows | Required for spend | Main blocker |
|---|---:|---:|---|
| `dodo_pmm` | 49 | 24 | Remaining planned pools and non-production rows |
| `single_sided_pmm` | 3 | 3 | Pool creation and funding |
| `uniswap_v2` | 5 | 3 | One planned pool plus promotion evidence |
| `uniswap_v3` | 1 | 1 | Canary passed; keep adapter compatibility gated |
| `balancer_weighted` | 11 | 0 | Optional protocol inventory not deployed/imported |
| `curve_stable` | 11 | 0 | Optional protocol inventory not deployed/imported |
| `sushiswap_v2` | 11 | 0 | Optional protocol inventory not deployed/imported |
| `oneinch_aggregator` | 11 | 0 | Optional aggregator routes depend on live native liquidity first |
| `aave_backstop` | 11 | 0 | Optional backstop market not deployed/imported |
`config/allmainnet-non-dodo-protocol-surface.json` currently publishes partial same-chain inventory and keeps only DODO enabled through `EnhancedSwapRouterV2`. Do not enable optional providers until their pool rows have real addresses, reserve reads, canary evidence, and route quotes.
## Phase 1: Close Required Inventory
Work required rows first. Optional protocols should not distract from getting the spend mesh healthy.
1. Generate the live worklist:
```bash
node scripts/status/generate-all-mainnet-readiness.mjs
```
Read:
- `reports/status/all-mainnet-deployment-readiness-worklist-latest.json`
- `reports/status/all-mainnet-production-gate-latest.json`
- `reports/status/all-mainnet-spend-readiness-latest.json`
2. For every required row with `status: planned`, create or import the pool address.
Required blockers are usually one of:
- `pool_not_created`
- `missing_base_address:*`
- `missing_quote_address:*`
- `missing_pool_address`
For DODO rows, use the committed DODO infrastructure from the row:
- `infrastructure.dvmFactory`
- `infrastructure.dvmFactoryAdapter`
- `infrastructure.dodoPmmIntegration`
For Uniswap V2/V3 rows, use the committed factory/router/quoter or import the canonical address from verified on-chain deployment evidence. Do not invent placeholder pool addresses.
3. After creating or importing pools, run reserve reads:
```bash
node scripts/status/check-all-mainnet-required-pool-balances.mjs
node scripts/status/check-all-mainnet-required-pool-balances.mjs --update-matrix
```
Only use `--update-matrix` after reviewing the report. It promotes rows with live code and non-zero base/quote balances to `live_read`; it does not create, fund, or canary pools.
## Phase 2: Fund and Canary
Funding should move in tiers, not straight to production.
Use each row's `fundingTiersUsd`:
- `seed`: proves transferability and reserve reads
- `smoke`: proves route quoteability and tiny swaps
- `productionMinimum`: minimum operating reserve before promotion
After funding, run:
```bash
node scripts/status/check-all-mainnet-required-pool-balances.mjs
node scripts/status/preflight-all-mainnet-canaries.mjs
```
Record successful canaries with:
```bash
node scripts/status/record-all-mainnet-canary-evidence.mjs
```
Promotion rule:
- `planned` -> create/import pool
- `created` -> fund both sides
- `live_read` -> canary both directions where applicable
- `canary_passed` -> operator review
- `production` -> public route eligible
## Phase 3: Auto-Rebalancing
Auto-rebalancing should be conservative and evidence driven. It should not be allowed to create new exposure on rows that have not passed the production gate.
Minimum policy per row:
```json
{
"maxPriceImpactBps": 100,
"minReserveUsd": 1000,
"refillTriggerBps": 200,
"pauseOnReserveReadFailure": true
}
```
Implementation shape:
1. Watch only rows with `requiredForSpend: true` and status `live_read`, `canary_passed`, or `production`.
2. Read live base/quote balances using `check-all-mainnet-required-pool-balances.mjs`.
3. Convert reserves to oracle ISO value using the same ISO peg rules used by `scripts/verify/build-cw-public-price-table.py`.
4. If either side is below `minReserveUsd` or outside `refillTriggerBps`, generate a rebalance intent.
5. Execute only after dry-run quote checks pass and `maxPriceImpactBps` is respected.
6. Record every action back into a report before changing matrix status.
Recommended first automation artifact:
```text
scripts/status/plan-all-mainnet-rebalance.mjs
```
It should be read-only by default and write:
```text
reports/status/all-mainnet-rebalance-plan-latest.json
```
The read-only planner is available now:
```bash
node scripts/status/plan-all-mainnet-rebalance.mjs
```
Only after that report is stable should an execution wrapper be added, for example:
```text
scripts/deployment/execute-all-mainnet-rebalance.mjs
```
The execution wrapper must require an explicit `--execute` flag.
## Phase 4: Enable All Protocols
Protocol enablement must follow native-liquidity order. Aggregators come last.
1. **DODO PMM:** Finish required DODO and single-sided PMM rows first. Keep DODO as the default router provider until other providers pass canaries.
2. **Uniswap V2:** Promote committed V2 rows with live reserve reads and canaries. Add the remaining planned V2 pool address or mark it explicitly deferred.
3. **Uniswap V3:** Keep the standalone V3 route recorded, but do not enable the enhanced-router V3 provider until the adapter quote incompatibility is fixed and canary evidence exists through the enhanced router path.
4. **Balancer / Curve / Sushi:** Import or deploy canonical factories, routers/vaults, pools, and pool IDs. Add addresses to the pool matrix before funding. No route generation from config-only rows.
5. **1inch:** Enable only after DODO plus at least one native venue for the same pair is live. 1inch rows are aggregator-only and must not be the first source of liquidity truth.
6. **Aave backstop:** Treat as a reserve/backstop surface, not a swap venue. Enable after token markets, oracle config, caps, and pause controls are committed.
After each protocol wave:
```bash
bash scripts/verify/check-allmainnet-protocol-surface.sh
node scripts/status/generate-all-mainnet-readiness.mjs
bash scripts/validation/validate-config-files.sh
```
## Production Gate
A row can become public-route eligible only when all of these are true:
- Real token addresses
- Real pool address with bytecode
- Required vault assignments complete
- Non-zero base and quote reserves
- Canary evidence recorded
- Route quote check passes
- Protocol surface has the provider enabled
- Status is `production`
The whole ALL Mainnet same-chain surface is production-ready only when:
```bash
jq -e '.status == "production_ready"' reports/status/all-mainnet-production-gate-latest.json
```
Until then, keep public routing constrained to canary-passed rows and explicitly disabled historical rows out of route generation.

View File

@@ -0,0 +1,164 @@
#!/usr/bin/env node
/**
* Build the strict deployment/funding packet for ALL Mainnet completion.
*
* This is intentionally read-only. It converts the matrix, reserve report,
* canary preflight, and rebalance plan into an operator packet that separates
* executable work from rows that are blocked by missing addresses/evidence.
*/
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
const repoRoot = resolve(new URL("../..", import.meta.url).pathname);
const matrixPath = resolve(repoRoot, "config/all-mainnet-pool-creation-matrix.json");
const readinessPath = resolve(repoRoot, "reports/status/all-mainnet-deployment-readiness-worklist-latest.json");
const reservePath = resolve(repoRoot, "reports/status/all-mainnet-required-pool-balances-latest.json");
const canaryPath = resolve(repoRoot, "reports/status/all-mainnet-canary-preflight-latest.json");
const rebalancePath = resolve(repoRoot, "reports/status/all-mainnet-rebalance-plan-latest.json");
const jsonOut = resolve(repoRoot, "reports/status/all-mainnet-full-deployment-funding-packet-latest.json");
const mdOut = resolve(repoRoot, "reports/status/all-mainnet-full-deployment-funding-packet-latest.md");
function readJson(path, fallback = null) {
return existsSync(path) ? JSON.parse(readFileSync(path, "utf8")) : fallback;
}
function table(headers, rows) {
return [
`| ${headers.join(" | ")} |`,
`| ${headers.map(() => "---").join(" | ")} |`,
...rows.map((row) => `| ${row.map((cell) => String(cell ?? "").replace(/\|/g, "\\|")).join(" | ")} |`),
].join("\n");
}
function tokenPair(row) {
return `${row.baseToken?.symbol || "?"}/${row.quoteToken?.symbol || "?"}`;
}
function poolBlockers(row) {
const blockers = [];
if (!row.baseToken?.address) blockers.push(`missing_base_address:${row.baseToken?.symbol || "unknown"}`);
if (!row.quoteToken?.address) blockers.push(`missing_quote_address:${row.quoteToken?.symbol || "unknown"}`);
if (!row.poolAddress) blockers.push("missing_pool_address");
if ((row.missingRequiredVaultRoles || []).length) blockers.push("missing_required_vault_assignments");
return blockers;
}
const matrix = readJson(matrixPath);
const readiness = readJson(readinessPath, { blockers: [] });
const reserve = readJson(reservePath, { results: [] });
const canary = readJson(canaryPath, { results: [] });
const rebalance = readJson(rebalancePath, { intents: [] });
const generatedAt = new Date().toISOString();
const reserveByPoolId = new Map(reserve.results.map((row) => [row.poolId, row]));
const canaryByPoolId = new Map(canary.results.map((row) => [row.poolId, row]));
const rebalanceByPoolId = new Map(rebalance.intents.map((row) => [row.poolId, row]));
const requiredRows = matrix.rows.filter((row) => row.requiredForSpend === true);
const rows = requiredRows.map((row) => {
const reserveRow = reserveByPoolId.get(row.poolId);
const canaryRow = canaryByPoolId.get(row.poolId);
const rebalanceRow = rebalanceByPoolId.get(row.poolId);
const blockers = new Set(poolBlockers(row));
const productionBlockers = new Set();
const actions = [];
if (row.status === "planned") {
actions.push(row.protocol === "dodo_pmm" ? "create_or_import_dodo_pool" : "create_or_import_pool");
}
if (reserveRow?.liveReadStatus === "zero_balances") actions.push("fund_base_and_quote");
if (reserveRow?.liveReadStatus === "partial_balance") actions.push("fund_low_side");
if (["live_read"].includes(row.status)) actions.push("run_canary");
if (canaryRow?.canaryPreflight === "ready") actions.push("execute_canary_swap");
if (rebalanceRow?.executionStatus === "operator_review_required") actions.push(...(rebalanceRow.actions || []));
for (const blocker of canaryRow?.blockers || []) blockers.add(blocker);
if (["live_read", "canary_passed", "production"].includes(row.status)) {
for (const blocker of rebalanceRow?.blockers || []) blockers.add(blocker);
}
if (row.status !== "production") productionBlockers.add("not_production_status");
return {
poolId: row.poolId,
chainId: row.chainId,
network: row.network,
protocol: row.protocol,
pair: tokenPair(row),
status: row.status,
poolAddress: row.poolAddress,
publicRoutingEnabled: Boolean(row.publicRoutingEnabled),
reserveStatus: reserveRow?.liveReadStatus || "not_checked",
canaryPreflight: canaryRow?.canaryPreflight || "not_checked",
rebalanceStatus: rebalanceRow?.executionStatus || "not_planned",
actions: [...new Set(actions)],
blockers: [...blockers],
productionBlockers: [...productionBlockers],
};
});
const blocked = rows.filter((row) => row.blockers.length > 0);
const executable = rows.filter((row) => row.blockers.length === 0 && row.actions.length > 0);
const readyNoop = rows.filter((row) => row.blockers.length === 0 && row.actions.length === 0);
const hardConfigBlockers = rows.filter((row) =>
row.blockers.some((blocker) => blocker.startsWith("missing_") || blocker === "missing_pool_address"),
);
const packet = {
generatedAt,
mode: "read_only_operator_packet",
summary: {
requiredRows: rows.length,
executableRows: executable.length,
blockedRows: blocked.length,
readyNoopRows: readyNoop.length,
hardConfigBlockers: hardConfigBlockers.length,
},
operatorOrder: [
"resolve_hard_config_blockers",
"create_or_import_missing_pools",
"fund_zero_balance_pools",
"run_reserve_reads",
"execute_canary_swaps_for_ready_rows",
"record_canary_evidence",
"promote_reviewed_rows_to_production",
"enable_optional_protocol_providers_after_native_pool_canaries",
],
rows,
};
const md = [
"# ALL Mainnet Full Deployment + Funding Packet",
"",
`- Generated: \`${generatedAt}\``,
"- Mode: read-only operator packet; no transactions were executed.",
"",
table(
["Metric", "Count"],
Object.entries(packet.summary).map(([key, value]) => [key, value]),
),
"",
"## Executable Rows",
"",
executable.length
? table(["Pool", "Chain", "Protocol", "Pair", "Status", "Actions"], executable.map((row) => [row.poolId, row.chainId, row.protocol, row.pair, row.status, row.actions.join(", ")]))
: "_No rows are fully executable without first clearing blockers._",
"",
"## Hard Config Blockers",
"",
hardConfigBlockers.length
? table(["Pool", "Chain", "Protocol", "Pair", "Status", "Blockers"], hardConfigBlockers.map((row) => [row.poolId, row.chainId, row.protocol, row.pair, row.status, row.blockers.join(", ")]))
: "_No hard config blockers._",
"",
"## Blocked Rows",
"",
blocked.length
? table(["Pool", "Chain", "Protocol", "Pair", "Status", "Reserve", "Canary", "Blockers"], blocked.map((row) => [row.poolId, row.chainId, row.protocol, row.pair, row.status, row.reserveStatus, row.canaryPreflight, row.blockers.join(", ")]))
: "_No blocked rows._",
"",
].join("\n");
mkdirSync(resolve(repoRoot, "reports/status"), { recursive: true });
writeFileSync(jsonOut, `${JSON.stringify(packet, null, 2)}\n`);
writeFileSync(mdOut, `${md}\n`);
console.log(`[OK] ALL Mainnet deployment/funding packet written: ${jsonOut}`);

View File

@@ -0,0 +1,155 @@
#!/usr/bin/env node
/**
* Build a read-only ALL Mainnet rebalance plan.
*
* This intentionally does not execute transfers or swaps. It consumes the
* canonical pool matrix plus the latest reserve-read report, then emits
* operator-reviewable intents for rows that are eligible for rebalancing.
*/
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
const repoRoot = resolve(new URL("../..", import.meta.url).pathname);
const matrixPath = resolve(repoRoot, "config/all-mainnet-pool-creation-matrix.json");
const reserveReportPath = resolve(repoRoot, "reports/status/all-mainnet-required-pool-balances-latest.json");
const outPath = resolve(repoRoot, "reports/status/all-mainnet-rebalance-plan-latest.json");
const eligibleStatuses = new Set(["live_read", "canary_passed", "production"]);
const productionStatuses = new Set(["canary_passed", "production"]);
function readJson(path) {
return JSON.parse(readFileSync(path, "utf8"));
}
function asBigInt(value) {
try {
return BigInt(value || "0");
} catch {
return 0n;
}
}
function ratioBps(a, b) {
if (a === 0n && b === 0n) return null;
const high = a > b ? a : b;
const low = a > b ? b : a;
if (high === 0n) return null;
return Number(((high - low) * 10_000n) / high);
}
function reserveEvidenceFor(row, reserveByPoolId) {
const live = reserveByPoolId.get(row.poolId);
if (live) {
return {
source: "latest_reserve_report",
liveReadStatus: live.liveReadStatus,
baseBalanceRaw: live.baseBalanceRaw,
quoteBalanceRaw: live.quoteBalanceRaw,
poolHasCode: live.poolHasCode,
errors: live.errors || [],
};
}
if (row.reserveEvidence) {
return {
source: "matrix_reserve_evidence",
liveReadStatus: row.reserveEvidence.liveReadStatus,
baseBalanceRaw: row.reserveEvidence.baseBalanceRaw,
quoteBalanceRaw: row.reserveEvidence.quoteBalanceRaw,
poolHasCode: row.reserveEvidence.poolHasCode,
errors: [],
};
}
return null;
}
function planForRow(row, evidence) {
const policy = row.policy || {};
const blockers = [];
const actions = [];
if (!row.requiredForSpend) blockers.push("not_required_for_spend");
if (!eligibleStatuses.has(row.status)) blockers.push(`status_not_rebalance_eligible:${row.status}`);
if (!row.poolAddress) blockers.push("missing_pool_address");
if (!row.baseToken?.address) blockers.push(`missing_base_address:${row.baseToken?.symbol || "unknown"}`);
if (!row.quoteToken?.address) blockers.push(`missing_quote_address:${row.quoteToken?.symbol || "unknown"}`);
if (!evidence) blockers.push("missing_reserve_evidence");
const base = asBigInt(evidence?.baseBalanceRaw);
const quote = asBigInt(evidence?.quoteBalanceRaw);
const imbalanceBps = ratioBps(base, quote);
if (evidence) {
if (evidence.poolHasCode !== true) blockers.push("pool_code_not_confirmed");
if (evidence.errors?.length) blockers.push("reserve_read_errors");
if (evidence.liveReadStatus === "partial_balance") actions.push("refill_empty_or_low_side");
if (evidence.liveReadStatus === "zero_balances") actions.push("fund_both_sides_before_rebalance");
if (evidence.liveReadStatus === "missing_pool_address") blockers.push("reserve_report_missing_pool_address");
if (evidence.liveReadStatus === "missing_token_address") blockers.push("reserve_report_missing_token_address");
}
if (base === 0n && quote > 0n) actions.push("fund_base_side");
if (quote === 0n && base > 0n) actions.push("fund_quote_side");
if (base > 0n && quote > 0n && imbalanceBps !== null && imbalanceBps >= (policy.refillTriggerBps || 200)) {
actions.push("quote_and_rebalance_to_target_inventory");
}
if (actions.length === 0 && blockers.length === 0) actions.push("monitor_no_rebalance_required");
return {
poolId: row.poolId,
chainId: row.chainId,
network: row.network,
protocol: row.protocol,
status: row.status,
productionRouteEligible: productionStatuses.has(row.status) && blockers.length === 0,
baseToken: row.baseToken,
quoteToken: row.quoteToken,
poolAddress: row.poolAddress,
policy: {
maxPriceImpactBps: policy.maxPriceImpactBps ?? 100,
minReserveUsd: policy.minReserveUsd ?? 1000,
refillTriggerBps: policy.refillTriggerBps ?? 200,
pauseOnReserveReadFailure: policy.pauseOnReserveReadFailure ?? true,
},
reserveEvidence: evidence,
imbalanceBps,
actions: [...new Set(actions)],
blockers: [...new Set(blockers)],
executionStatus: blockers.length ? "blocked" : actions.includes("monitor_no_rebalance_required") ? "no_action" : "operator_review_required",
};
}
const matrix = readJson(matrixPath);
const reserveReport = existsSync(reserveReportPath) ? readJson(reserveReportPath) : null;
const reserveByPoolId = new Map((reserveReport?.results || []).map((row) => [row.poolId, row]));
const generatedAt = new Date().toISOString();
const rows = matrix.rows.filter((row) => row.requiredForSpend === true);
const intents = rows.map((row) => planForRow(row, reserveEvidenceFor(row, reserveByPoolId)));
const actionable = intents.filter((intent) => intent.executionStatus === "operator_review_required");
const blocked = intents.filter((intent) => intent.executionStatus === "blocked");
const noAction = intents.filter((intent) => intent.executionStatus === "no_action");
const payload = {
generatedAt,
sourceMatrix: "config/all-mainnet-pool-creation-matrix.json",
sourceReserveReport: existsSync(reserveReportPath) ? "reports/status/all-mainnet-required-pool-balances-latest.json" : null,
mode: "read_only_plan",
executionGuardrails: [
"This report never executes swaps or transfers.",
"An execution wrapper must require an explicit --execute flag.",
"Rows with reserve read errors or missing code must pause, not rebalance.",
"Optional protocol rows are excluded until they become requiredForSpend or production-route eligible.",
],
summary: {
requiredRows: rows.length,
actionableRows: actionable.length,
blockedRows: blocked.length,
noActionRows: noAction.length,
},
intents,
};
mkdirSync(resolve(repoRoot, "reports/status"), { recursive: true });
writeFileSync(outPath, `${JSON.stringify(payload, null, 2)}\n`);
console.log(`[OK] ALL Mainnet rebalance plan written: ${outPath}`);