Compare commits

...

1 Commits

Author SHA1 Message Date
defiQUG
c840c0f777 Add GRU v2 full-mesh ops pack 2026-04-16 11:39:13 -07:00
23 changed files with 4105 additions and 3 deletions

View File

@@ -0,0 +1,133 @@
{
"statusDate": "2026-04-14",
"namespaces": {
"chain138": "c* V2",
"allMainnet651940": "cA*",
"publicConnectedNetworks": "cW*"
},
"executionPhases": [
{
"id": "P0",
"namespace": "c* V2",
"scope": "Chain 138 canonical hub and Wave 1"
},
{
"id": "P1",
"namespace": "c* V2",
"scope": "Chain 138 cross-links and gas-native hubs"
},
{
"id": "P2",
"namespace": "cA*",
"scope": "ALL Mainnet canonical hub and Wave 1"
},
{
"id": "P3",
"namespace": "cA*",
"scope": "ALL Mainnet cross-links and gas-native hubs"
},
{
"id": "P4",
"namespace": "cW*",
"scope": "Public cW stable hub, Wave 1, and gas-native mesh"
},
{
"id": "P5",
"namespace": "all",
"scope": "Spot venue protocol completion"
},
{
"id": "P6",
"namespace": "all",
"scope": "Aggregator, reserve, and market protocol completion"
},
{
"id": "P7",
"namespace": "all",
"scope": "MEV completion"
}
],
"protocolsRequired": [
"DODO",
"Uniswap v3",
"Uniswap v2",
"SushiSwap",
"Curve",
"Balancer",
"1Inch",
"Aave",
"GMX",
"dYdX"
],
"chain138CanonicalPools": [
"cUSDT V2 / cUSDC V2",
"cUSDT V2 / USDT",
"cUSDC V2 / USDC",
"cEURC V2 / cUSDC V2",
"cEURT V2 / cUSDC V2",
"cGBPC V2 / cUSDC V2",
"cGBPT V2 / cUSDC V2",
"cAUDC V2 / cUSDC V2",
"cJPYC V2 / cUSDC V2",
"cCHFC V2 / cUSDC V2",
"cCADC V2 / cUSDC V2",
"cXAUC V2 / cUSDC V2",
"cXAUT V2 / cUSDC V2",
"cEURC V2 / cEURT V2",
"cGBPC V2 / cGBPT V2",
"cXAUC V2 / cXAUT V2",
"cETH / WETH",
"cETH / cUSDC V2",
"cETHL2 / cUSDC V2",
"cBNB / cUSDC V2",
"cPOL / cUSDC V2",
"cAVAX / cUSDC V2",
"cCRO / cUSDC V2",
"cXDAI / cUSDC V2",
"cCELO / cUSDC V2",
"cWEMIX / cUSDC V2"
],
"allMainnetCanonicalPools": [
"cAUSDT / cAUSDC",
"cAUSDT / AUSDT",
"cAUSDC / USDC",
"cAEURC / cAUSDC",
"cAEURT / cAUSDC",
"cAGBPC / cAUSDC",
"cAGBPT / cAUSDC",
"cAAUDC / cAUSDC",
"cAJPYC / cAUSDC",
"cACHFC / cAUSDC",
"cACADC / cAUSDC",
"cAXAUC / cAUSDC",
"cAXAUT / cAUSDC",
"cAEURC / cAEURT",
"cAGBPC / cAGBPT",
"cAXAUC / cAXAUT",
"cAETH / WETH",
"cAETH / cAUSDC",
"cAWALL / WALL",
"cAWALL / cAUSDC"
],
"publicMeshTemplate": {
"stableHub": [
"cWUSDT / USDC",
"cWUSDC / USDC",
"cWUSDT / USDT",
"cWUSDC / USDT",
"cWUSDT / cWUSDC"
],
"wave1VsUsdc": [
"cWEURC / USDC",
"cWEURT / USDC",
"cWGBPC / USDC",
"cWGBPT / USDC",
"cWAUDC / USDC",
"cWJPYC / USDC",
"cWCHFC / USDC",
"cWCADC / USDC",
"cWXAUC / USDC",
"cWXAUT / USDC"
]
}
}

View File

@@ -0,0 +1,82 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://d-bis.org/schemas/gru-v2-full-mesh-pool-tracker.json",
"title": "GRU v2 Full Mesh Pool Tracker",
"type": "object",
"required": [
"statusDate",
"defaultFields",
"chain138",
"allMainnet651940",
"publicMesh"
],
"properties": {
"statusDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"defaultFields": {
"type": "object",
"required": ["status", "deployed", "seeded", "validated", "live", "mevReady"],
"properties": {
"status": {
"type": "string",
"enum": ["todo", "in_progress", "blocked", "done"]
},
"deployed": { "type": "boolean" },
"seeded": { "type": "boolean" },
"validated": { "type": "boolean" },
"live": { "type": "boolean" },
"mevReady": { "type": "boolean" }
},
"additionalProperties": false
},
"chain138": { "$ref": "#/$defs/namedBucket" },
"allMainnet651940": { "$ref": "#/$defs/namedBucket" },
"publicMesh": {
"type": "object",
"minProperties": 1,
"additionalProperties": { "$ref": "#/$defs/meshBucket" }
}
},
"$defs": {
"pairEntry": {
"type": "object",
"required": ["pair"],
"properties": {
"pair": { "type": "string", "minLength": 3 },
"priority": { "type": "string", "minLength": 2 }
},
"additionalProperties": false
},
"namedBucket": {
"type": "object",
"required": ["namespace", "entries"],
"properties": {
"namespace": { "type": "string", "minLength": 2 },
"entries": {
"type": "array",
"items": { "$ref": "#/$defs/pairEntry" }
}
},
"additionalProperties": false
},
"meshBucket": {
"type": "object",
"required": ["namespace", "entries"],
"properties": {
"namespace": { "type": "string", "minLength": 2 },
"entries": {
"type": "array",
"items": { "type": "string", "minLength": 3 }
},
"statusOverride": {
"type": "string",
"enum": ["planned", "todo", "in_progress", "blocked", "done"]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}

View File

@@ -10,9 +10,26 @@ The full plan is only partially deployable today.
- Chain `138` canonical non-gas DODO PMM mesh: `script-backed` and live
- Chain `138` pilot `Uniswap v3`, `Balancer`, `Curve`, and `1Inch` venues: `script-backed` and live
- Chain `138` native `Uniswap v2` and `SushiSwap`: `script-backed`, deployed, seeded, and verified
- Chain `138` deployed smart-contract publication now has a repo-backed orchestration lane:
- targeted Blockscout submission wrappers for native `Uniswap v2` / `SushiSwap`
- targeted Blockscout submission wrappers for the route execution stack and pilot venues
- a generated publication report at [CHAIN138_DEPLOYED_SMART_CONTRACT_VERIFICATION_STATUS.md](/home/intlc/projects/proxmox/docs/04-configuration/CHAIN138_DEPLOYED_SMART_CONTRACT_VERIFICATION_STATUS.md:1)
- current live publication status is explicit rather than implied:
- `D3Oracle`, `D3Vault`, `DODOApprove`, and `DODOApproveProxy` are Blockscout-verified
- `D3MMFactory` and `D3Proxy` still show bytecode-only metadata
- the flash trio, native `Uniswap v2` / `SushiSwap`, and the route execution stack now have Blockscout verification submissions accepted, but the explorer API still exposes them as bytecode-only as of the latest report
- repeated internal Blockscout polling after submission did not materialize source metadata yet, so the remaining work is now explorer-side verification materialization or manual explorer intervention rather than missing repo automation
- Chain `138` supported spot / routing protocol publication is now live end to end:
- token-aggregation planner capabilities expose `DODO`, `Uniswap v3`, `Uniswap v2`, `SushiSwap`, `Balancer`, `Curve`, and `1Inch`
- MEV venue coverage exposes native `curve`, `dodo_d3mm`, `dodo_pmm`, `sushiswap`, `uniswap_v2`, and `uniswap_v3`
- token-aggregation persistence for Chain `138` V2/Sushi pools is wired to the DBIS primary and writing into `liquidity_pools`
- Chain `138` `Aave`: repo-backed deployment surface plus imported upstream native source now exist, but rollout remains blocked on real Chain `138` market deployment and canonical live addresses
- Chain `138` `GMX`: imported upstream native source now exists, but rollout remains blocked on Chain `138` deployment/configuration work and canonical live addresses
- Chain `138` `dYdX`: canonical inventory surface exists, but it remains blocked on a native protocol stack and live Chain `138` addresses
- public `cW*` token and partial PMM rollout: `script-backed` in parts
- ALL Mainnet `651940` full `cA*` mesh: `inventory-backed`, not fully deployer-backed
- full protocol completion across `DODO`, `Uniswap v2`, `Uniswap v3`, `SushiSwap`, `Curve`, `Balancer`, `1Inch`, `Aave`, `GMX`, and `dYdX`: not fully deployer-backed
- full protocol completion across `DODO`, `Uniswap v2`, `Uniswap v3`, `SushiSwap`, `Curve`, `Balancer`, `1Inch`, `Aave`, `GMX`, and `dYdX`: Chain `138` supported spot/routing set is complete; `Aave` and `GMX` now have imported upstream native source, while `dYdX` still remains an external native-stack gap
## Script-backed now
@@ -22,6 +39,25 @@ The full plan is only partially deployable today.
| Chain `138` rollout wrapper | [scripts/deployment/run-all-next-steps-chain138.sh](/home/intlc/projects/proxmox/scripts/deployment/run-all-next-steps-chain138.sh:1) |
| Chain `138` readiness validation | [scripts/verify/check-gru-v2-chain138-readiness.sh](/home/intlc/projects/proxmox/scripts/verify/check-gru-v2-chain138-readiness.sh:1) |
| Chain `138` protocol venue deployer | [scripts/deployment/deploy-chain138-pilot-protocol-venues.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-pilot-protocol-venues.sh:1) |
| Chain `138` native `Uniswap v2` deployer | [scripts/deployment/deploy-chain138-uniswap-v2-native.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-uniswap-v2-native.sh:1) |
| Chain `138` native `SushiSwap` deployer | [scripts/deployment/deploy-chain138-sushiswap-native.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-sushiswap-native.sh:1) |
| Chain `138` native V2 venue verification | [scripts/verify/check-chain138-native-v2-venues.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-native-v2-venues.sh:1) |
| Chain `138` native V2 Blockscout publication | [scripts/verify/verify-chain138-native-v2-blockscout.sh](/home/intlc/projects/proxmox/scripts/verify/verify-chain138-native-v2-blockscout.sh:1) |
| Chain `138` route execution stack Blockscout publication | [scripts/verify/verify-chain138-route-execution-stack-blockscout.sh](/home/intlc/projects/proxmox/scripts/verify/verify-chain138-route-execution-stack-blockscout.sh:1) |
| Chain `138` deployed-contract publication report | [scripts/verify/check-chain138-deployed-contract-publication.py](/home/intlc/projects/proxmox/scripts/verify/check-chain138-deployed-contract-publication.py:1) |
| Chain `138` publication orchestrator | [scripts/deployment/publish-chain138-deployed-smart-contracts.sh](/home/intlc/projects/proxmox/scripts/deployment/publish-chain138-deployed-smart-contracts.sh:1) |
| Chain `138` Aave execution stack deployer | [scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh:1) |
| Chain `138` Aave quote-push receiver deployer | [scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh:1) |
| Chain `138` remaining protocol env verifier | [scripts/verify/check-chain138-remaining-protocol-env.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-remaining-protocol-env.sh:1) |
| Chain `138` Aave rollout readiness verifier | [scripts/verify/check-chain138-aave-rollout-readiness.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-aave-rollout-readiness.sh:1) |
| Chain `138` Aave runtime publication helper | [scripts/deployment/publish-chain138-aave-runtime-from-artifacts.sh](/home/intlc/projects/proxmox/scripts/deployment/publish-chain138-aave-runtime-from-artifacts.sh:1) |
| Chain `138` Aave blocker-removal worksheet | [CHAIN138_AAVE_BLOCKER_REMOVAL_WORKSHEET.md](/home/intlc/projects/proxmox/docs/04-configuration/CHAIN138_AAVE_BLOCKER_REMOVAL_WORKSHEET.md:1) |
| Chain `138` Aave rollout manifest template | [chain138-aave-rollout-manifest.example.json](/home/intlc/projects/proxmox/config/chain138-aave-rollout-manifest.example.json:1) |
| Chain `138` Aave manifest apply helper | [scripts/deployment/apply-chain138-aave-manifest.sh](/home/intlc/projects/proxmox/scripts/deployment/apply-chain138-aave-manifest.sh:1) |
| Imported upstream native Aave source | [vendor/chain138-protocols/aave-v3-origin](</home/intlc/projects/proxmox/vendor/chain138-protocols/aave-v3-origin>) |
| Imported upstream native GMX source | [vendor/chain138-protocols/gmx-synthetics](</home/intlc/projects/proxmox/vendor/chain138-protocols/gmx-synthetics>) |
| Chain `138` native Aave V3 Origin scaffold | [deploy-chain138-aave-v3-origin-market.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-aave-v3-origin-market.sh:1) |
| Chain `138` native GMX synthetics scaffold | [deploy-chain138-gmx-synthetics-core.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-chain138-gmx-synthetics-core.sh:1) |
| Chain `138` canonical PMM pool seeding | [smom-dbis-138/scripts/deployment/seed-chain138-canonical-pmm-pools.sh](/home/intlc/projects/proxmox/smom-dbis-138/scripts/deployment/seed-chain138-canonical-pmm-pools.sh:1) |
| GRU mesh planning and live reconciliation | [scripts/verify/reconcile-gru-v2-full-mesh-status.py](/home/intlc/projects/proxmox/scripts/verify/reconcile-gru-v2-full-mesh-status.py:1) |
| ALL Mainnet `cA*` token deployment wrapper | [scripts/deployment/deploy-allmainnet-ca-tokens.sh](/home/intlc/projects/proxmox/scripts/deployment/deploy-allmainnet-ca-tokens.sh:1) |
@@ -33,6 +69,9 @@ The full plan is only partially deployable today.
|---|---|---|
| ALL Mainnet token inventory | [docs/11-references/ALL_MAINNET_TOKEN_ADDRESSES.md](/home/intlc/projects/proxmox/docs/11-references/ALL_MAINNET_TOKEN_ADDRESSES.md:1) | still needs final deployed `cA*` addresses to complete live inventory |
| `651940` planned full mesh | [config/gru-v2-full-mesh-pool-tracker.json](/home/intlc/projects/proxmox/config/gru-v2-full-mesh-pool-tracker.json:1) | still needs final live pool addresses and liquidity |
| Chain `138` remaining native protocol inventory | [config/chain138-remaining-protocol-surface.json](/home/intlc/projects/proxmox/config/chain138-remaining-protocol-surface.json:1) | `Aave` and `GMX` are now source-backed, but still need live Chain `138` deployment outputs and canonical addresses; `dYdX` still needs both source and live addresses |
| Chain `138` remaining protocol discovery evidence | [CHAIN138_REMAINING_PROTOCOL_DISCOVERY_REPORT.md](/home/intlc/projects/proxmox/docs/04-configuration/CHAIN138_REMAINING_PROTOCOL_DISCOVERY_REPORT.md:1) | evidence pass found no discoverable canonical live addresses for Aave / GMX / dYdX on Chain `138` |
| Chain `138` native protocol stack gap report | [CHAIN138_NATIVE_PROTOCOL_STACK_GAP_REPORT.md](/home/intlc/projects/proxmox/docs/04-configuration/CHAIN138_NATIVE_PROTOCOL_STACK_GAP_REPORT.md:1) | confirms the repo does not include full native Aave / GMX / dYdX deployment stacks |
| public/non-public protocol target state | [docs/04-configuration/GRU_V2_PROTOCOL_COMPLETION_MATRIX.md](/home/intlc/projects/proxmox/docs/04-configuration/GRU_V2_PROTOCOL_COMPLETION_MATRIX.md:1) | no end-to-end deployer coverage for all protocol cells |
## External blockers
@@ -42,6 +81,7 @@ The full plan is only partially deployable today.
| Missing live `651940` venue addresses and integrations for the non-DODO protocol set | canonical env surface now exists, but the live addresses still need to be supplied |
| Live liquidity and partner venue dependencies | even with scripts, final pool rows cannot be marked `live` without real seeding and venue support |
| Chain `138` gas-native runtime verifier / vault wiring | the gas family rows remain blocked until real `CW_GAS_*_CHAIN138` addresses are supplied from deployed contracts |
| Native `Aave`, `GMX`, and `dYdX` protocol programs on Chain `138` | `Aave` now has repo-backed deployment wrappers plus imported upstream source but still needs real Chain `138` market deployment outputs; `GMX` now has imported upstream source but still needs a Chain `138` deployment program and live addresses; `dYdX` still needs both a native stack and canonical live addresses |
## New operator entrypoints
@@ -51,3 +91,5 @@ The full plan is only partially deployable today.
| [scripts/verify/check-gru-v2-full-deployment-implementation.py](/home/intlc/projects/proxmox/scripts/verify/check-gru-v2-full-deployment-implementation.py:1) | verify which plan segments are actually implemented in-repo |
| [scripts/verify/check-gru-v2-core-protocol-blockers.sh](/home/intlc/projects/proxmox/scripts/verify/check-gru-v2-core-protocol-blockers.sh:1) | verify the repo-side blockers are closed and isolate only the remaining external dependencies |
| [scripts/verify/check-allmainnet-protocol-env.sh](/home/intlc/projects/proxmox/scripts/verify/check-allmainnet-protocol-env.sh:1) | inventory the remaining ALL Mainnet protocol env gaps so missing venue coverage is explicit |
| [scripts/verify/check-chain138-remaining-protocol-env.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-remaining-protocol-env.sh:1) | inventory the remaining Chain `138` Aave / GMX / dYdX protocol env gaps and verify bytecode when addresses are supplied |
| [scripts/verify/check-chain138-native-protocol-stack-source.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-native-protocol-stack-source.sh:1) | prove whether the repo actually contains the native source families needed to deploy Aave / GMX / dYdX on Chain `138` |

View File

@@ -0,0 +1,106 @@
# GRU v2 Full Mesh Execution Checklist
This checklist turns the master matrix into execution order.
Status values:
- `todo`
- `in_progress`
- `blocked`
- `done`
Execution classes:
- `script-backed`
- `inventory-backed`
- `external-blocked`
Current truth:
- `138` DODO PMM work is `script-backed`
- `651940` full `cA*` deployment is currently `inventory-backed` and `external-blocked`
- protocol-complete rollout across both namespaces is not fully deployer-backed in this repo yet
## 1. Chain 138 Canonical Pools
| Status | Namespace | Pair / Venue | Priority | Notes |
|---|---|---|---|---|
| `todo` | `c* V2` | `cUSDT V2 / cUSDC V2` | `P0` | canonical USD hub |
| `todo` | `c* V2` | `cUSDT V2 / USDT` | `P0` | native bridge rail |
| `todo` | `c* V2` | `cUSDC V2 / USDC` | `P0` | native bridge rail |
| `todo` | `c* V2` | `cEURC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cEURT V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cGBPC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cGBPT V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cAUDC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cJPYC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cCHFC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cCADC V2 / cUSDC V2` | `P0` | Wave 1 |
| `todo` | `c* V2` | `cXAUC V2 / cUSDC V2` | `P0` | commodity |
| `todo` | `c* V2` | `cXAUT V2 / cUSDC V2` | `P0` | commodity |
| `todo` | `c* V2` | `cEURC V2 / cEURT V2` | `P1` | cross-link |
| `todo` | `c* V2` | `cGBPC V2 / cGBPT V2` | `P1` | cross-link |
| `todo` | `c* V2` | `cXAUC V2 / cXAUT V2` | `P1` | cross-link |
## 2. ALL Mainnet Canonical Pools
| Status | Namespace | Pair / Venue | Priority | Notes |
|---|---|---|---|---|
| `todo` | `cA*` | `cAUSDT / cAUSDC` | `P0` | canonical ALL USD hub |
| `todo` | `cA*` | `cAUSDT / AUSDT` | `P0` | native ALL rail |
| `todo` | `cA*` | `cAUSDC / USDC` | `P0` | native ALL rail |
| `todo` | `cA*` | `cAEURC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAEURT / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAGBPC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAGBPT / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAAUDC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAJPYC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cACHFC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cACADC / cAUSDC` | `P0` | Wave 1 |
| `todo` | `cA*` | `cAXAUC / cAUSDC` | `P0` | commodity |
| `todo` | `cA*` | `cAXAUT / cAUSDC` | `P0` | commodity |
| `todo` | `cA*` | `cAEURC / cAEURT` | `P1` | cross-link |
| `todo` | `cA*` | `cAGBPC / cAGBPT` | `P1` | cross-link |
| `todo` | `cA*` | `cAXAUC / cAXAUT` | `P1` | cross-link |
## 3. Public cW Mesh
| Status | Chain | Required work | Priority | Notes |
|---|---|---|---|---|
| `todo` | `1` | full stable hub + Wave 1 + gas-native lanes | `P2` | first public reference mesh |
| `todo` | `10` | full stable hub + Wave 1 + gas-native lanes | `P3` | ETH L2 |
| `todo` | `8453` | full stable hub + Wave 1 + gas-native lanes | `P3` | ETH L2 |
| `todo` | `42161` | full stable hub + Wave 1 + gas-native lanes | `P3` | ETH L2 |
| `todo` | `137` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `56` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `100` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `43114` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `42220` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `25` | full stable hub + Wave 1 + gas-native lanes | `P4` | major public chain |
| `todo` | `1111` | publish mirrors, then deploy full mesh | `P5` | token family still incomplete |
## 4. Protocol Completion
| Status | Protocol | Namespace scope | Completion requirement |
|---|---|---|---|
| `todo` | `DODO` | all namespaces | primary PMM mesh complete |
| `todo` | `Uniswap v3` | all namespaces | live reference and execution lanes |
| `todo` | `Uniswap v2` | all namespaces | fallback spot lanes where applicable |
| `todo` | `SushiSwap` | all namespaces | secondary AMM lanes |
| `todo` | `Curve` | all namespaces | stable and basket lanes |
| `todo` | `Balancer` | all namespaces | weighted and stable basket lanes |
| `todo` | `1Inch` | all namespaces | routing/execution integration |
| `todo` | `Aave` | all namespaces | reserve + flash-liquidity integration |
| `todo` | `GMX` | all namespaces | market integration or unsupported-by-protocol closure |
| `todo` | `dYdX` | all namespaces | market integration or unsupported-by-protocol closure |
## 5. MEV Completion
| Status | Requirement | Exit condition |
|---|---|---|
| `todo` | discovery | pools/venues visible in canonical MEV inventory |
| `todo` | quoting | exact protocol quote path works |
| `todo` | simulation | route simulation matches execution semantics |
| `todo` | execution | execution adapter succeeds |
| `todo` | settlement | settlement and attribution persist cleanly |
| `todo` | observability | health / infra / freshness / coverage surfaces green |

View File

@@ -40,7 +40,7 @@ Implementation vocabulary:
| Namespace | DODO | Uni v3 | Uni v2 | Sushi | Curve | Balancer | 1Inch | Aave | GMX | dYdX |
|---|---|---|---|---|---|---|---|---|---|---|
| `138 c* V2` | `done`, `script-backed` | `done`, `script-backed` | `todo`, `external-blocked` | `todo`, `external-blocked` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` |
| `138 c* V2` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `done`, `script-backed` | `blocked`, `script-backed` | `blocked`, `inventory-backed` | `blocked`, `inventory-backed` |
| `651940 cA*` | `todo`, `inventory-backed` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` |
| public `cW*` | `in_progress`, `script-backed` | `in_progress`, `inventory-backed` | `in_progress`, `inventory-backed` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` | `in_progress`, `inventory-backed` | `todo`, `external-blocked` | `todo`, `external-blocked` | `todo`, `external-blocked` |
@@ -54,4 +54,16 @@ For a protocol cell to move to `done`, all of the following should be true:
4. `live`
5. `MEV-ready` where the protocol participates in MEV routing/execution
For `Aave`, `GMX`, and `dYdX`, if the protocol does not support the family or chain natively, the cell should be closed as `unsupported_by_protocol` rather than left ambiguous.
For `Aave`, `GMX`, and `dYdX`, close a cell as `unsupported_by_protocol` only when the namespace is intentionally out of scope. If the protocol remains a target but lacks live contracts or addresses, keep it `blocked`.
## 4. Chain 138 closure evidence
These `138 c* V2` cells are closed with explicit evidence rather than left as open `todo` rows:
| Protocol | Closed status | Evidence |
|---|---|---|
| `Uniswap v2` | `done`, `script-backed` | native Chain `138` factory `0x0C30F6e67Ab3667fCc2f5CEA8e274ef1FB920279`, router `0x3019A7fDc76ba7F64F18d78e66842760037ee638`, and seeded pairs (`WETH/USDT`, `WETH/USDC`, `cUSDT/cUSDC`) are now published in `config/smart-contracts-master.json`, `.env.master.example`, and verified by [check-chain138-native-v2-venues.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-native-v2-venues.sh:1) |
| `SushiSwap` | `done`, `script-backed` | native Chain `138` factory `0x2871207ff0d56089D70c0134d33f1291B6Fce0BE`, router `0xB37b93D38559f53b62ab020A14919f2630a1aE34`, and seeded pairs (`WETH/USDT`, `WETH/USDC`, `cUSDT/cUSDC`) are now published in `config/smart-contracts-master.json`, `.env.master.example`, and verified by [check-chain138-native-v2-venues.sh](/home/intlc/projects/proxmox/scripts/verify/check-chain138-native-v2-venues.sh:1) |
| `Aave` | `blocked`, `source-backed`, `external-blocked` | the repo now contains a Chain `138` native surface inventory, a hard env/bytecode checker, a Chain `138` wrapper for the Aave-backed MEV execution stack, a Chain `138` quote-push receiver deployer, and imported upstream source from `aave-dao/aave-v3-origin`, but no canonical Chain `138` Aave pool/provider/data-provider addresses or native market rollout are published yet |
| `GMX` | `blocked`, `source-backed`, `external-blocked` | a canonical Chain `138` inventory surface now exists and the official upstream source from `gmx-io/gmx-synthetics` is now imported, but no Chain `138` GMX deployment outputs, live addresses, registry wiring, planner capabilities, or MEV venue coverage are published yet |
| `dYdX` | `blocked`, `inventory-backed`, `external-blocked` | a canonical Chain `138` inventory surface now exists, but no Chain `138` dYdX market / data-provider / exchange addresses or vendored native deployment stack exist in canonical env, registry, planner capabilities, or MEV venue coverage |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,234 @@
namespace,chain,pair,priority,status
c* V2,138,cUSDT V2 / cUSDC V2,P0,todo
c* V2,138,cUSDT V2 / USDT,P0,todo
c* V2,138,cUSDC V2 / USDC,P0,todo
c* V2,138,cEURC V2 / cUSDC V2,P0,todo
c* V2,138,cEURT V2 / cUSDC V2,P0,todo
c* V2,138,cGBPC V2 / cUSDC V2,P0,todo
c* V2,138,cGBPT V2 / cUSDC V2,P0,todo
c* V2,138,cAUDC V2 / cUSDC V2,P0,todo
c* V2,138,cJPYC V2 / cUSDC V2,P0,todo
c* V2,138,cCHFC V2 / cUSDC V2,P0,todo
c* V2,138,cCADC V2 / cUSDC V2,P0,todo
c* V2,138,cXAUC V2 / cUSDC V2,P0,todo
c* V2,138,cXAUT V2 / cUSDC V2,P0,todo
c* V2,138,cEURC V2 / cEURT V2,P1,todo
c* V2,138,cGBPC V2 / cGBPT V2,P1,todo
c* V2,138,cXAUC V2 / cXAUT V2,P1,todo
c* V2,138,cETH / WETH,P1,todo
c* V2,138,cETH / cUSDC V2,P1,todo
c* V2,138,cETHL2 / cUSDC V2,P2,todo
c* V2,138,cBNB / cUSDC V2,P2,todo
c* V2,138,cPOL / cUSDC V2,P2,todo
c* V2,138,cAVAX / cUSDC V2,P2,todo
c* V2,138,cCRO / cUSDC V2,P2,todo
c* V2,138,cXDAI / cUSDC V2,P2,todo
c* V2,138,cCELO / cUSDC V2,P2,todo
c* V2,138,cWEMIX / cUSDC V2,P2,todo
cA*,651940,cAUSDT / cAUSDC,P0,todo
cA*,651940,cAUSDT / AUSDT,P0,todo
cA*,651940,cAUSDC / USDC,P0,todo
cA*,651940,cAEURC / cAUSDC,P0,todo
cA*,651940,cAEURT / cAUSDC,P0,todo
cA*,651940,cAGBPC / cAUSDC,P0,todo
cA*,651940,cAGBPT / cAUSDC,P0,todo
cA*,651940,cAAUDC / cAUSDC,P0,todo
cA*,651940,cAJPYC / cAUSDC,P0,todo
cA*,651940,cACHFC / cAUSDC,P0,todo
cA*,651940,cACADC / cAUSDC,P0,todo
cA*,651940,cAXAUC / cAUSDC,P0,todo
cA*,651940,cAXAUT / cAUSDC,P0,todo
cA*,651940,cAEURC / cAEURT,P1,todo
cA*,651940,cAGBPC / cAGBPT,P1,todo
cA*,651940,cAXAUC / cAXAUT,P1,todo
cA*,651940,cAETH / WETH,P1,todo
cA*,651940,cAETH / cAUSDC,P1,todo
cA*,651940,cAWALL / WALL,P1,todo
cA*,651940,cAWALL / cAUSDC,P1,todo
cW*,1,cWUSDT / USDC,,todo
cW*,1,cWUSDC / USDC,,todo
cW*,1,cWUSDT / USDT,,todo
cW*,1,cWUSDC / USDT,,todo
cW*,1,cWUSDT / cWUSDC,,todo
cW*,1,cWEURC / USDC,,todo
cW*,1,cWEURT / USDC,,todo
cW*,1,cWGBPC / USDC,,todo
cW*,1,cWGBPT / USDC,,todo
cW*,1,cWAUDC / USDC,,todo
cW*,1,cWJPYC / USDC,,todo
cW*,1,cWCHFC / USDC,,todo
cW*,1,cWCADC / USDC,,todo
cW*,1,cWXAUC / USDC,,todo
cW*,1,cWXAUT / USDC,,todo
cW*,1,cWETH / WETH,,todo
cW*,1,cWETH / USDC,,todo
cW*,10,cWUSDT / USDC,,todo
cW*,10,cWUSDC / USDC,,todo
cW*,10,cWUSDT / USDT,,todo
cW*,10,cWUSDC / USDT,,todo
cW*,10,cWUSDT / cWUSDC,,todo
cW*,10,cWEURC / USDC,,todo
cW*,10,cWEURT / USDC,,todo
cW*,10,cWGBPC / USDC,,todo
cW*,10,cWGBPT / USDC,,todo
cW*,10,cWAUDC / USDC,,todo
cW*,10,cWJPYC / USDC,,todo
cW*,10,cWCHFC / USDC,,todo
cW*,10,cWCADC / USDC,,todo
cW*,10,cWXAUC / USDC,,todo
cW*,10,cWXAUT / USDC,,todo
cW*,10,cWETHL2 / WETH,,todo
cW*,10,cWETHL2 / USDC,,todo
cW*,25,cWUSDT / USDC,,todo
cW*,25,cWUSDC / USDC,,todo
cW*,25,cWUSDT / USDT,,todo
cW*,25,cWUSDC / USDT,,todo
cW*,25,cWUSDT / cWUSDC,,todo
cW*,25,cWEURC / USDC,,todo
cW*,25,cWEURT / USDC,,todo
cW*,25,cWGBPC / USDC,,todo
cW*,25,cWGBPT / USDC,,todo
cW*,25,cWAUDC / USDC,,todo
cW*,25,cWJPYC / USDC,,todo
cW*,25,cWCHFC / USDC,,todo
cW*,25,cWCADC / USDC,,todo
cW*,25,cWXAUC / USDC,,todo
cW*,25,cWXAUT / USDC,,todo
cW*,25,cWCRO / WCRO,,todo
cW*,25,cWCRO / USDT,,todo
cW*,56,cWUSDT / USDC,,todo
cW*,56,cWUSDC / USDC,,todo
cW*,56,cWUSDT / USDT,,todo
cW*,56,cWUSDC / USDT,,todo
cW*,56,cWUSDT / cWUSDC,,todo
cW*,56,cWEURC / USDC,,todo
cW*,56,cWEURT / USDC,,todo
cW*,56,cWGBPC / USDC,,todo
cW*,56,cWGBPT / USDC,,todo
cW*,56,cWAUDC / USDC,,todo
cW*,56,cWJPYC / USDC,,todo
cW*,56,cWCHFC / USDC,,todo
cW*,56,cWCADC / USDC,,todo
cW*,56,cWXAUC / USDC,,todo
cW*,56,cWXAUT / USDC,,todo
cW*,56,cWBNB / WBNB,,todo
cW*,56,cWBNB / USDT,,todo
cW*,100,cWUSDT / USDC,,todo
cW*,100,cWUSDC / USDC,,todo
cW*,100,cWUSDT / USDT,,todo
cW*,100,cWUSDC / USDT,,todo
cW*,100,cWUSDT / cWUSDC,,todo
cW*,100,cWEURC / USDC,,todo
cW*,100,cWEURT / USDC,,todo
cW*,100,cWGBPC / USDC,,todo
cW*,100,cWGBPT / USDC,,todo
cW*,100,cWAUDC / USDC,,todo
cW*,100,cWJPYC / USDC,,todo
cW*,100,cWCHFC / USDC,,todo
cW*,100,cWCADC / USDC,,todo
cW*,100,cWXAUC / USDC,,todo
cW*,100,cWXAUT / USDC,,todo
cW*,100,cWXDAI / WXDAI,,todo
cW*,100,cWXDAI / USDC,,todo
cW*,137,cWUSDT / USDC,,todo
cW*,137,cWUSDC / USDC,,todo
cW*,137,cWUSDT / USDT,,todo
cW*,137,cWUSDC / USDT,,todo
cW*,137,cWUSDT / cWUSDC,,todo
cW*,137,cWEURC / USDC,,todo
cW*,137,cWEURT / USDC,,todo
cW*,137,cWGBPC / USDC,,todo
cW*,137,cWGBPT / USDC,,todo
cW*,137,cWAUDC / USDC,,todo
cW*,137,cWJPYC / USDC,,todo
cW*,137,cWCHFC / USDC,,todo
cW*,137,cWCADC / USDC,,todo
cW*,137,cWXAUC / USDC,,todo
cW*,137,cWXAUT / USDC,,todo
cW*,137,cWPOL / WPOL,,todo
cW*,137,cWPOL / USDC,,todo
cW*,8453,cWUSDT / USDC,,todo
cW*,8453,cWUSDC / USDC,,todo
cW*,8453,cWUSDT / USDT,,todo
cW*,8453,cWUSDC / USDT,,todo
cW*,8453,cWUSDT / cWUSDC,,todo
cW*,8453,cWEURC / USDC,,todo
cW*,8453,cWEURT / USDC,,todo
cW*,8453,cWGBPC / USDC,,todo
cW*,8453,cWGBPT / USDC,,todo
cW*,8453,cWAUDC / USDC,,todo
cW*,8453,cWJPYC / USDC,,todo
cW*,8453,cWCHFC / USDC,,todo
cW*,8453,cWCADC / USDC,,todo
cW*,8453,cWXAUC / USDC,,todo
cW*,8453,cWXAUT / USDC,,todo
cW*,8453,cWETHL2 / WETH,,todo
cW*,8453,cWETHL2 / USDC,,todo
cW*,42161,cWUSDT / USDC,,todo
cW*,42161,cWUSDC / USDC,,todo
cW*,42161,cWUSDT / USDT,,todo
cW*,42161,cWUSDC / USDT,,todo
cW*,42161,cWUSDT / cWUSDC,,todo
cW*,42161,cWEURC / USDC,,todo
cW*,42161,cWEURT / USDC,,todo
cW*,42161,cWGBPC / USDC,,todo
cW*,42161,cWGBPT / USDC,,todo
cW*,42161,cWAUDC / USDC,,todo
cW*,42161,cWJPYC / USDC,,todo
cW*,42161,cWCHFC / USDC,,todo
cW*,42161,cWCADC / USDC,,todo
cW*,42161,cWXAUC / USDC,,todo
cW*,42161,cWXAUT / USDC,,todo
cW*,42161,cWETHL2 / WETH,,todo
cW*,42161,cWETHL2 / USDC,,todo
cW*,42220,cWUSDT / USDC,,todo
cW*,42220,cWUSDC / USDC,,todo
cW*,42220,cWUSDT / USDT,,todo
cW*,42220,cWUSDC / USDT,,todo
cW*,42220,cWUSDT / cWUSDC,,todo
cW*,42220,cWEURC / USDC,,todo
cW*,42220,cWEURT / USDC,,todo
cW*,42220,cWGBPC / USDC,,todo
cW*,42220,cWGBPT / USDC,,todo
cW*,42220,cWAUDC / USDC,,todo
cW*,42220,cWJPYC / USDC,,todo
cW*,42220,cWCHFC / USDC,,todo
cW*,42220,cWCADC / USDC,,todo
cW*,42220,cWXAUC / USDC,,todo
cW*,42220,cWXAUT / USDC,,todo
cW*,42220,cWCELO / WCELO,,todo
cW*,42220,cWCELO / USDC,,todo
cW*,43114,cWUSDT / USDC,,todo
cW*,43114,cWUSDC / USDC,,todo
cW*,43114,cWUSDT / USDT,,todo
cW*,43114,cWUSDC / USDT,,todo
cW*,43114,cWUSDT / cWUSDC,,todo
cW*,43114,cWEURC / USDC,,todo
cW*,43114,cWEURT / USDC,,todo
cW*,43114,cWGBPC / USDC,,todo
cW*,43114,cWGBPT / USDC,,todo
cW*,43114,cWAUDC / USDC,,todo
cW*,43114,cWJPYC / USDC,,todo
cW*,43114,cWCHFC / USDC,,todo
cW*,43114,cWCADC / USDC,,todo
cW*,43114,cWXAUC / USDC,,todo
cW*,43114,cWXAUT / USDC,,todo
cW*,43114,cWAVAX / WAVAX,,todo
cW*,43114,cWAVAX / USDC,,todo
cW*,1111,cWUSDT / USDC,,planned
cW*,1111,cWUSDC / USDC,,planned
cW*,1111,cWUSDT / USDT,,planned
cW*,1111,cWUSDC / USDT,,planned
cW*,1111,cWUSDT / cWUSDC,,planned
cW*,1111,cWEURC / USDC,,planned
cW*,1111,cWEURT / USDC,,planned
cW*,1111,cWGBPC / USDC,,planned
cW*,1111,cWGBPT / USDC,,planned
cW*,1111,cWAUDC / USDC,,planned
cW*,1111,cWJPYC / USDC,,planned
cW*,1111,cWCHFC / USDC,,planned
cW*,1111,cWCADC / USDC,,planned
cW*,1111,cWXAUC / USDC,,planned
cW*,1111,cWXAUT / USDC,,planned
cW*,1111,cWWEMIX / WWEMIX,,planned
cW*,1111,cWWEMIX / USDC,,planned
1 namespace chain pair priority status
2 c* V2 138 cUSDT V2 / cUSDC V2 P0 todo
3 c* V2 138 cUSDT V2 / USDT P0 todo
4 c* V2 138 cUSDC V2 / USDC P0 todo
5 c* V2 138 cEURC V2 / cUSDC V2 P0 todo
6 c* V2 138 cEURT V2 / cUSDC V2 P0 todo
7 c* V2 138 cGBPC V2 / cUSDC V2 P0 todo
8 c* V2 138 cGBPT V2 / cUSDC V2 P0 todo
9 c* V2 138 cAUDC V2 / cUSDC V2 P0 todo
10 c* V2 138 cJPYC V2 / cUSDC V2 P0 todo
11 c* V2 138 cCHFC V2 / cUSDC V2 P0 todo
12 c* V2 138 cCADC V2 / cUSDC V2 P0 todo
13 c* V2 138 cXAUC V2 / cUSDC V2 P0 todo
14 c* V2 138 cXAUT V2 / cUSDC V2 P0 todo
15 c* V2 138 cEURC V2 / cEURT V2 P1 todo
16 c* V2 138 cGBPC V2 / cGBPT V2 P1 todo
17 c* V2 138 cXAUC V2 / cXAUT V2 P1 todo
18 c* V2 138 cETH / WETH P1 todo
19 c* V2 138 cETH / cUSDC V2 P1 todo
20 c* V2 138 cETHL2 / cUSDC V2 P2 todo
21 c* V2 138 cBNB / cUSDC V2 P2 todo
22 c* V2 138 cPOL / cUSDC V2 P2 todo
23 c* V2 138 cAVAX / cUSDC V2 P2 todo
24 c* V2 138 cCRO / cUSDC V2 P2 todo
25 c* V2 138 cXDAI / cUSDC V2 P2 todo
26 c* V2 138 cCELO / cUSDC V2 P2 todo
27 c* V2 138 cWEMIX / cUSDC V2 P2 todo
28 cA* 651940 cAUSDT / cAUSDC P0 todo
29 cA* 651940 cAUSDT / AUSDT P0 todo
30 cA* 651940 cAUSDC / USDC P0 todo
31 cA* 651940 cAEURC / cAUSDC P0 todo
32 cA* 651940 cAEURT / cAUSDC P0 todo
33 cA* 651940 cAGBPC / cAUSDC P0 todo
34 cA* 651940 cAGBPT / cAUSDC P0 todo
35 cA* 651940 cAAUDC / cAUSDC P0 todo
36 cA* 651940 cAJPYC / cAUSDC P0 todo
37 cA* 651940 cACHFC / cAUSDC P0 todo
38 cA* 651940 cACADC / cAUSDC P0 todo
39 cA* 651940 cAXAUC / cAUSDC P0 todo
40 cA* 651940 cAXAUT / cAUSDC P0 todo
41 cA* 651940 cAEURC / cAEURT P1 todo
42 cA* 651940 cAGBPC / cAGBPT P1 todo
43 cA* 651940 cAXAUC / cAXAUT P1 todo
44 cA* 651940 cAETH / WETH P1 todo
45 cA* 651940 cAETH / cAUSDC P1 todo
46 cA* 651940 cAWALL / WALL P1 todo
47 cA* 651940 cAWALL / cAUSDC P1 todo
48 cW* 1 cWUSDT / USDC todo
49 cW* 1 cWUSDC / USDC todo
50 cW* 1 cWUSDT / USDT todo
51 cW* 1 cWUSDC / USDT todo
52 cW* 1 cWUSDT / cWUSDC todo
53 cW* 1 cWEURC / USDC todo
54 cW* 1 cWEURT / USDC todo
55 cW* 1 cWGBPC / USDC todo
56 cW* 1 cWGBPT / USDC todo
57 cW* 1 cWAUDC / USDC todo
58 cW* 1 cWJPYC / USDC todo
59 cW* 1 cWCHFC / USDC todo
60 cW* 1 cWCADC / USDC todo
61 cW* 1 cWXAUC / USDC todo
62 cW* 1 cWXAUT / USDC todo
63 cW* 1 cWETH / WETH todo
64 cW* 1 cWETH / USDC todo
65 cW* 10 cWUSDT / USDC todo
66 cW* 10 cWUSDC / USDC todo
67 cW* 10 cWUSDT / USDT todo
68 cW* 10 cWUSDC / USDT todo
69 cW* 10 cWUSDT / cWUSDC todo
70 cW* 10 cWEURC / USDC todo
71 cW* 10 cWEURT / USDC todo
72 cW* 10 cWGBPC / USDC todo
73 cW* 10 cWGBPT / USDC todo
74 cW* 10 cWAUDC / USDC todo
75 cW* 10 cWJPYC / USDC todo
76 cW* 10 cWCHFC / USDC todo
77 cW* 10 cWCADC / USDC todo
78 cW* 10 cWXAUC / USDC todo
79 cW* 10 cWXAUT / USDC todo
80 cW* 10 cWETHL2 / WETH todo
81 cW* 10 cWETHL2 / USDC todo
82 cW* 25 cWUSDT / USDC todo
83 cW* 25 cWUSDC / USDC todo
84 cW* 25 cWUSDT / USDT todo
85 cW* 25 cWUSDC / USDT todo
86 cW* 25 cWUSDT / cWUSDC todo
87 cW* 25 cWEURC / USDC todo
88 cW* 25 cWEURT / USDC todo
89 cW* 25 cWGBPC / USDC todo
90 cW* 25 cWGBPT / USDC todo
91 cW* 25 cWAUDC / USDC todo
92 cW* 25 cWJPYC / USDC todo
93 cW* 25 cWCHFC / USDC todo
94 cW* 25 cWCADC / USDC todo
95 cW* 25 cWXAUC / USDC todo
96 cW* 25 cWXAUT / USDC todo
97 cW* 25 cWCRO / WCRO todo
98 cW* 25 cWCRO / USDT todo
99 cW* 56 cWUSDT / USDC todo
100 cW* 56 cWUSDC / USDC todo
101 cW* 56 cWUSDT / USDT todo
102 cW* 56 cWUSDC / USDT todo
103 cW* 56 cWUSDT / cWUSDC todo
104 cW* 56 cWEURC / USDC todo
105 cW* 56 cWEURT / USDC todo
106 cW* 56 cWGBPC / USDC todo
107 cW* 56 cWGBPT / USDC todo
108 cW* 56 cWAUDC / USDC todo
109 cW* 56 cWJPYC / USDC todo
110 cW* 56 cWCHFC / USDC todo
111 cW* 56 cWCADC / USDC todo
112 cW* 56 cWXAUC / USDC todo
113 cW* 56 cWXAUT / USDC todo
114 cW* 56 cWBNB / WBNB todo
115 cW* 56 cWBNB / USDT todo
116 cW* 100 cWUSDT / USDC todo
117 cW* 100 cWUSDC / USDC todo
118 cW* 100 cWUSDT / USDT todo
119 cW* 100 cWUSDC / USDT todo
120 cW* 100 cWUSDT / cWUSDC todo
121 cW* 100 cWEURC / USDC todo
122 cW* 100 cWEURT / USDC todo
123 cW* 100 cWGBPC / USDC todo
124 cW* 100 cWGBPT / USDC todo
125 cW* 100 cWAUDC / USDC todo
126 cW* 100 cWJPYC / USDC todo
127 cW* 100 cWCHFC / USDC todo
128 cW* 100 cWCADC / USDC todo
129 cW* 100 cWXAUC / USDC todo
130 cW* 100 cWXAUT / USDC todo
131 cW* 100 cWXDAI / WXDAI todo
132 cW* 100 cWXDAI / USDC todo
133 cW* 137 cWUSDT / USDC todo
134 cW* 137 cWUSDC / USDC todo
135 cW* 137 cWUSDT / USDT todo
136 cW* 137 cWUSDC / USDT todo
137 cW* 137 cWUSDT / cWUSDC todo
138 cW* 137 cWEURC / USDC todo
139 cW* 137 cWEURT / USDC todo
140 cW* 137 cWGBPC / USDC todo
141 cW* 137 cWGBPT / USDC todo
142 cW* 137 cWAUDC / USDC todo
143 cW* 137 cWJPYC / USDC todo
144 cW* 137 cWCHFC / USDC todo
145 cW* 137 cWCADC / USDC todo
146 cW* 137 cWXAUC / USDC todo
147 cW* 137 cWXAUT / USDC todo
148 cW* 137 cWPOL / WPOL todo
149 cW* 137 cWPOL / USDC todo
150 cW* 8453 cWUSDT / USDC todo
151 cW* 8453 cWUSDC / USDC todo
152 cW* 8453 cWUSDT / USDT todo
153 cW* 8453 cWUSDC / USDT todo
154 cW* 8453 cWUSDT / cWUSDC todo
155 cW* 8453 cWEURC / USDC todo
156 cW* 8453 cWEURT / USDC todo
157 cW* 8453 cWGBPC / USDC todo
158 cW* 8453 cWGBPT / USDC todo
159 cW* 8453 cWAUDC / USDC todo
160 cW* 8453 cWJPYC / USDC todo
161 cW* 8453 cWCHFC / USDC todo
162 cW* 8453 cWCADC / USDC todo
163 cW* 8453 cWXAUC / USDC todo
164 cW* 8453 cWXAUT / USDC todo
165 cW* 8453 cWETHL2 / WETH todo
166 cW* 8453 cWETHL2 / USDC todo
167 cW* 42161 cWUSDT / USDC todo
168 cW* 42161 cWUSDC / USDC todo
169 cW* 42161 cWUSDT / USDT todo
170 cW* 42161 cWUSDC / USDT todo
171 cW* 42161 cWUSDT / cWUSDC todo
172 cW* 42161 cWEURC / USDC todo
173 cW* 42161 cWEURT / USDC todo
174 cW* 42161 cWGBPC / USDC todo
175 cW* 42161 cWGBPT / USDC todo
176 cW* 42161 cWAUDC / USDC todo
177 cW* 42161 cWJPYC / USDC todo
178 cW* 42161 cWCHFC / USDC todo
179 cW* 42161 cWCADC / USDC todo
180 cW* 42161 cWXAUC / USDC todo
181 cW* 42161 cWXAUT / USDC todo
182 cW* 42161 cWETHL2 / WETH todo
183 cW* 42161 cWETHL2 / USDC todo
184 cW* 42220 cWUSDT / USDC todo
185 cW* 42220 cWUSDC / USDC todo
186 cW* 42220 cWUSDT / USDT todo
187 cW* 42220 cWUSDC / USDT todo
188 cW* 42220 cWUSDT / cWUSDC todo
189 cW* 42220 cWEURC / USDC todo
190 cW* 42220 cWEURT / USDC todo
191 cW* 42220 cWGBPC / USDC todo
192 cW* 42220 cWGBPT / USDC todo
193 cW* 42220 cWAUDC / USDC todo
194 cW* 42220 cWJPYC / USDC todo
195 cW* 42220 cWCHFC / USDC todo
196 cW* 42220 cWCADC / USDC todo
197 cW* 42220 cWXAUC / USDC todo
198 cW* 42220 cWXAUT / USDC todo
199 cW* 42220 cWCELO / WCELO todo
200 cW* 42220 cWCELO / USDC todo
201 cW* 43114 cWUSDT / USDC todo
202 cW* 43114 cWUSDC / USDC todo
203 cW* 43114 cWUSDT / USDT todo
204 cW* 43114 cWUSDC / USDT todo
205 cW* 43114 cWUSDT / cWUSDC todo
206 cW* 43114 cWEURC / USDC todo
207 cW* 43114 cWEURT / USDC todo
208 cW* 43114 cWGBPC / USDC todo
209 cW* 43114 cWGBPT / USDC todo
210 cW* 43114 cWAUDC / USDC todo
211 cW* 43114 cWJPYC / USDC todo
212 cW* 43114 cWCHFC / USDC todo
213 cW* 43114 cWCADC / USDC todo
214 cW* 43114 cWXAUC / USDC todo
215 cW* 43114 cWXAUT / USDC todo
216 cW* 43114 cWAVAX / WAVAX todo
217 cW* 43114 cWAVAX / USDC todo
218 cW* 1111 cWUSDT / USDC planned
219 cW* 1111 cWUSDC / USDC planned
220 cW* 1111 cWUSDT / USDT planned
221 cW* 1111 cWUSDC / USDT planned
222 cW* 1111 cWUSDT / cWUSDC planned
223 cW* 1111 cWEURC / USDC planned
224 cW* 1111 cWEURT / USDC planned
225 cW* 1111 cWGBPC / USDC planned
226 cW* 1111 cWGBPT / USDC planned
227 cW* 1111 cWAUDC / USDC planned
228 cW* 1111 cWJPYC / USDC planned
229 cW* 1111 cWCHFC / USDC planned
230 cW* 1111 cWCADC / USDC planned
231 cW* 1111 cWXAUC / USDC planned
232 cW* 1111 cWXAUT / USDC planned
233 cW* 1111 cWWEMIX / WWEMIX planned
234 cW* 1111 cWWEMIX / USDC planned

View File

@@ -0,0 +1,128 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
source "${PROJECT_ROOT}/smom-dbis-138/scripts/load-env.sh" >/dev/null 2>&1 || true
need_cmd() {
command -v "$1" >/dev/null 2>&1 || { echo "[fail] missing required command: $1" >&2; exit 1; }
}
need_cmd cast
L1_BRIDGE="${CW_MULTITOKEN_BRIDGE_L1_138:-${CW_L1_BRIDGE_CHAIN138:-${CHAIN138_L1_BRIDGE:-0x152ed3e9912161b76bdfd368d0c84b7c31c10de7}}}"
L2_BRIDGE="${CW_MULTITOKEN_BRIDGE_L2_MAINNET:-${CW_BRIDGE_MAINNET:-0x2bF74583206A49Be07E0E8A94197C12987AbD7B5}}"
SELECTOR="${ETH_MAINNET_SELECTOR:-5009297550715157269}"
RPC138="${RPC_URL_138:-}"
RPC1="${ETHEREUM_MAINNET_RPC:-${ETH_MAINNET_RPC_URL:-}}"
CUSDT_V2="${COMPLIANT_USDT_V2:-0x9FBfab33882Efe0038DAa608185718b772EE5660}"
CUSDC_V2="${COMPLIANT_USDC_V2:-0x219522c60e83dEe01FC5b0329d6fA8fD84b9D13d}"
CWUSDT="${CWUSDT_V2_MAINNET:-${CWUSDT_MAINNET:-0x7E8FF0DcC974F290a29968e9350800a6df674447}}"
CWUSDC="${CWUSDC_V2_MAINNET:-${CWUSDC_MAINNET:-0x3398ff0Bc56Fe3597E12BE6b191Cc92f10Eae53c}}"
ASSET="ALL"
EXECUTE=0
usage() {
cat <<'EOF'
Usage:
bash scripts/deployment/configure-gru-v2-mainnet-bridge-parity.sh [--asset cUSDT_V2|cUSDC_V2] [--execute]
Dry-run by default. With --execute, broadcasts:
1. L2 configureDestination(138, L1_BRIDGE, true)
2. L2 configureTokenPair(V2 canonical, cW mirrored)
3. L1 configureDestination(V2 canonical, MAINNET_SELECTOR, L2_BRIDGE, true)
4. L1 configureSupportedCanonicalToken(V2 canonical, true) only when the deployed L1 bridge supports it
EOF
}
for arg in "$@"; do
case "$arg" in
--asset) shift ;;
esac
done
while [[ $# -gt 0 ]]; do
case "$1" in
--asset) ASSET="${2:-}"; shift 2 ;;
--execute) EXECUTE=1; shift ;;
--help|-h) usage; exit 0 ;;
*) echo "[fail] unknown arg: $1" >&2; usage >&2; exit 2 ;;
esac
done
[[ -n "$RPC138" && -n "$RPC1" ]] || { echo "[fail] RPC_URL_138 and ETHEREUM_MAINNET_RPC are required" >&2; exit 1; }
if (( EXECUTE == 1 )); then
[[ -n "${PRIVATE_KEY:-}" ]] || { echo "[fail] PRIVATE_KEY is required for --execute" >&2; exit 1; }
fi
send_cast() {
local rpc="$1" to="$2" sig="$3"
shift 3
if (( EXECUTE == 1 )); then
cast send "$to" "$sig" "$@" --rpc-url "$rpc" --private-key "$PRIVATE_KEY" --legacy
else
printf 'cast send %q %q' "$to" "$sig"
for part in "$@"; do
printf ' %q' "$part"
done
printf ' --rpc-url %q --private-key "$PRIVATE_KEY" --legacy\n' "$rpc"
fi
}
print_state() {
local label="$1" canonical="$2"
echo "=== $label ==="
echo "canonical=$canonical"
echo "l1_destination=$(cast call "$L1_BRIDGE" 'destinations(address,uint64)((address,bool))' "$canonical" "$SELECTOR" --rpc-url "$RPC138" 2>/dev/null | tr '\n' ' ' || true)"
echo "l1_supported=$(cast call "$L1_BRIDGE" 'supportedCanonicalToken(address)(bool)' "$canonical" --rpc-url "$RPC138" 2>/dev/null | awk '{print $1}' || true)"
echo "l2_pair=$(cast call "$L2_BRIDGE" 'canonicalToMirrored(address)(address)' "$canonical" --rpc-url "$RPC1" 2>/dev/null | awk '{print $1}' || true)"
echo "l2_destination=$(cast call "$L2_BRIDGE" 'destinations(uint64)((address,bool))' 138 --rpc-url "$RPC1" 2>/dev/null | tr '\n' ' ' || true)"
}
l1_supports_supported_canonical_fn() {
local canonical="$1"
cast call "$L1_BRIDGE" 'supportedCanonicalToken(address)(bool)' "$canonical" --rpc-url "$RPC138" >/dev/null 2>&1
}
run_asset() {
local label="$1" canonical="$2" mirrored="$3"
print_state "$label" "$canonical"
echo "plan_l2_destination:"
send_cast "$RPC1" "$L2_BRIDGE" "configureDestination(uint64,address,bool)" 138 "$L1_BRIDGE" true
echo "plan_l2_pair:"
send_cast "$RPC1" "$L2_BRIDGE" "configureTokenPair(address,address)" "$canonical" "$mirrored"
echo "plan_l1_destination:"
send_cast "$RPC138" "$L1_BRIDGE" "configureDestination(address,uint64,address,bool)" "$canonical" "$SELECTOR" "$L2_BRIDGE" true
if l1_supports_supported_canonical_fn "$canonical"; then
echo "plan_l1_supported:"
send_cast "$RPC138" "$L1_BRIDGE" "configureSupportedCanonicalToken(address,bool)" "$canonical" true
else
echo "plan_l1_supported: skipped (deployed L1 bridge does not expose supportedCanonicalToken(address)(bool); destination + fee-quote path is authoritative)"
fi
echo
}
case "$ASSET" in
ALL)
run_asset "cUSDT_V2" "$CUSDT_V2" "$CWUSDT"
run_asset "cUSDC_V2" "$CUSDC_V2" "$CWUSDC"
;;
cUSDT_V2)
run_asset "cUSDT_V2" "$CUSDT_V2" "$CWUSDT"
;;
cUSDC_V2)
run_asset "cUSDC_V2" "$CUSDC_V2" "$CWUSDC"
;;
*)
echo "[fail] unsupported asset: $ASSET" >&2
exit 2
;;
esac
if (( EXECUTE == 0 )); then
echo "Dry-run only. Re-run with --execute to broadcast."
fi

View File

@@ -0,0 +1,335 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
OUTPUT_PATH="${ROOT_DIR}/reports/extraction/gru-v2-wave1-public-deploy-plan-latest.json"
POLICY_PATH="${ROOT_DIR}/config/extraction/gru-v2-wave1-public-seed-policy.json"
GAP_REPORT_PATH="${ROOT_DIR}/reports/extraction/gru-v2-wave1-public-gap-report-latest.json"
source "${ROOT_DIR}/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
if [[ -f "${ROOT_DIR}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" ]]; then
# shellcheck disable=SC1090
source "${ROOT_DIR}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" >/dev/null 2>&1 || true
load_deployment_env --repo-root "${ROOT_DIR}/smom-dbis-138" >/dev/null 2>&1 || true
export PROJECT_ROOT="${ROOT_DIR}"
fi
mkdir -p "$(dirname "$OUTPUT_PATH")"
python3 - <<'PY' "$ROOT_DIR" "$OUTPUT_PATH" "$POLICY_PATH" "$GAP_REPORT_PATH"
import json
import os
import subprocess
import sys
from collections import Counter
from datetime import datetime, timezone
from pathlib import Path
project_root = Path(sys.argv[1])
output_path = Path(sys.argv[2])
policy_path = Path(sys.argv[3])
gap_report_path = Path(sys.argv[4])
if not gap_report_path.exists():
subprocess.check_call(
["bash", "scripts/verify/build-gru-v2-wave1-public-gap-report.sh"],
cwd=project_root,
)
deployment_status = json.loads((project_root / "cross-chain-pmm-lps/config/deployment-status.json").read_text())
policy = json.loads(policy_path.read_text())
gap_report = json.loads(gap_report_path.read_text())
chain_suffix = {
1: "MAINNET",
10: "OPTIMISM",
25: "CRONOS",
56: "BSC",
100: "GNOSIS",
137: "POLYGON",
1111: "WEMIX",
8453: "BASE",
42161: "ARBITRUM",
42220: "CELO",
43114: "AVALANCHE",
}
rpc_env_key = {
1: "ETHEREUM_MAINNET_RPC",
10: "OPTIMISM_RPC_URL",
25: "CRONOS_RPC_URL",
56: "BSC_RPC_URL",
100: "GNOSIS_MAINNET_RPC",
137: "POLYGON_RPC_URL",
1111: "WEMIX_RPC",
8453: "BASE_RPC_URL",
42161: "ARBITRUM_RPC_URL",
42220: "CELO_RPC_URL",
43114: "AVALANCHE_RPC_URL",
}
integration_env_key = {
1: "DODO_PMM_INTEGRATION_MAINNET",
10: "DODO_PMM_INTEGRATION_OPTIMISM",
25: "DODO_PMM_INTEGRATION_CRONOS",
56: "DODO_PMM_INTEGRATION_BSC",
100: "DODO_PMM_INTEGRATION_GNOSIS",
137: "DODO_PMM_INTEGRATION_POLYGON",
1111: "DODO_PMM_INTEGRATION_WEMIX",
8453: "DODO_PMM_INTEGRATION_BASE",
42161: "DODO_PMM_INTEGRATION_ARBITRUM",
42220: "DODO_PMM_INTEGRATION_CELO",
43114: "DODO_PMM_INTEGRATION_AVALANCHE",
}
private_key = os.environ.get("PRIVATE_KEY", "")
live_checks = os.environ.get("GRU_WAVE1_PLAN_LIVE_CHECKS", "").strip().lower() in {"1", "true", "yes", "on"}
include_allowances = os.environ.get("GRU_WAVE1_PLAN_INCLUDE_ALLOWANCES", "").strip().lower() in {"1", "true", "yes", "on"}
call_timeout = max(1, int(os.environ.get("GRU_WAVE1_CALL_TIMEOUT_SEC", "2")))
estimate_timeout = max(1, int(os.environ.get("GRU_WAVE1_ESTIMATE_TIMEOUT_SEC", "2")))
deployer = ""
if private_key and live_checks:
try:
deployer = subprocess.check_output(
["cast", "wallet", "address", "--private-key", private_key],
text=True,
timeout=call_timeout,
).strip()
except Exception:
deployer = ""
defaults = policy.get("defaults", {})
symbol_defaults = policy.get("symbol_defaults", {})
pair_overrides = policy.get("pair_overrides", {})
rows = []
def merge_policy(base_symbol: str, pair_key: str):
merged = dict(defaults)
merged.update(symbol_defaults.get(base_symbol, {}))
merged.update(pair_overrides.get(pair_key, {}))
return merged
def compute_quote_amount(base_raw: str, price_e18: str):
if not base_raw or not price_e18:
return None
return str((int(base_raw) * int(price_e18)) // 10**18)
def call_single(rpc_url: str, to: str, sig: str, *args):
try:
out = subprocess.check_output(
["cast", "call", to, sig, *args, "--rpc-url", rpc_url],
text=True,
stderr=subprocess.DEVNULL,
timeout=call_timeout,
).strip()
return out.split()[0] if out else ""
except Exception:
return ""
def estimate_single(rpc_url: str, to: str, sig: str, *args):
try:
out = subprocess.check_output(
["cast", "estimate", to, sig, *args, "--rpc-url", rpc_url],
text=True,
stderr=subprocess.DEVNULL,
timeout=estimate_timeout,
).strip()
return out.split()[0] if out else ""
except Exception:
return ""
for missing in gap_report["missing_first_tier_wave1_pools"]:
chain_id = missing["chain_id"]
network = missing["network"]
pair = missing["pair"]
base_symbol, quote_symbol = [part.strip() for part in pair.split("/")]
suffix = chain_suffix.get(chain_id, "")
rpc_key = rpc_env_key.get(chain_id, "")
integration_key = integration_env_key.get(chain_id, "")
base_env_key = f"{base_symbol.upper()}_{suffix}" if suffix else ""
pair_key = pair.lower().replace("/", "-").replace(" ", "")
chain_state = deployment_status["chains"].get(str(chain_id), {})
quote_address = (chain_state.get("anchorAddresses") or {}).get(quote_symbol, "")
rpc_url = os.environ.get(rpc_key, "")
integration = os.environ.get(integration_key, "")
base_address = os.environ.get(base_env_key, "")
cfg = merge_policy(base_symbol, pair_key)
initial_price = cfg.get("initial_price_e18")
base_amount = str(cfg.get("base_amount_raw")) if cfg.get("base_amount_raw") is not None else None
quote_amount = str(cfg.get("quote_amount_raw")) if cfg.get("quote_amount_raw") is not None else None
if quote_amount is None and base_amount and initial_price:
quote_amount = compute_quote_amount(base_amount, initial_price)
mint_amount = str(cfg.get("mint_base_amount_raw")) if cfg.get("mint_base_amount_raw") is not None else None
fee_bps = str(cfg.get("fee_bps", 3))
k_value = str(cfg.get("k", "500000000000000000"))
open_twap = bool(cfg.get("open_twap", False))
price_mode = cfg.get("price_mode", "unspecified")
blockers = []
if not rpc_url:
blockers.append(f"missing_rpc_env:{rpc_key}")
if not integration:
blockers.append(f"missing_integration_env:{integration_key}")
if not base_address:
blockers.append(f"missing_base_token_env:{base_env_key}")
if not quote_address:
blockers.append(f"missing_quote_anchor:{quote_symbol}")
if not initial_price:
blockers.append("missing_initial_price_e18")
if not base_amount:
blockers.append("missing_base_amount_raw")
if not quote_amount:
blockers.append("missing_quote_amount_raw")
if price_mode == "bootstrap_reference":
blockers.append("bootstrap_price_requires_operator_review")
if not private_key:
blockers.append("missing_private_key")
existing_pool = ""
base_balance = ""
quote_balance = ""
base_allowance = ""
quote_allowance = ""
mintable_base = False
base_supply_mode = "unknown"
if live_checks and rpc_url and integration and base_address and quote_address:
existing_pool = call_single(rpc_url, integration, "pools(address,address)(address)", base_address, quote_address)
if deployer:
base_balance = call_single(rpc_url, base_address, "balanceOf(address)(uint256)", deployer)
quote_balance = call_single(rpc_url, quote_address, "balanceOf(address)(uint256)", deployer)
if include_allowances:
base_allowance = call_single(rpc_url, base_address, "allowance(address,address)(uint256)", deployer, integration)
quote_allowance = call_single(rpc_url, quote_address, "allowance(address,address)(uint256)", deployer, integration)
live_missing = existing_pool in ("", "0x0000000000000000000000000000000000000000")
if not live_missing:
blockers = [b for b in blockers if b not in {"missing_base_amount_raw", "missing_quote_amount_raw"}]
has_seed_amounts = bool(base_amount and quote_amount)
create_ready = all(
token not in blockers
for token in [
f"missing_rpc_env:{rpc_key}",
f"missing_integration_env:{integration_key}",
f"missing_base_token_env:{base_env_key}",
f"missing_quote_anchor:{quote_symbol}",
"missing_initial_price_e18",
"missing_private_key",
]
) and live_missing
create_ready_with_bootstrap_price = create_ready
create_ready = create_ready and price_mode != "bootstrap_reference"
seed_ready = create_ready_with_bootstrap_price and has_seed_amounts
if base_balance and base_amount:
if int(base_balance) >= int(base_amount):
base_supply_mode = "wallet_balance"
else:
gap = int(base_amount) - int(base_balance)
if live_checks and deployer:
mintable_base = bool(estimate_single(rpc_url, base_address, "mint(address,uint256)", deployer, str(max(gap, 1))))
if mintable_base and mint_amount and int(base_balance) + int(mint_amount) >= int(base_amount):
base_supply_mode = "mintable_gap"
else:
base_supply_mode = "insufficient"
blockers.append("insufficient_base_balance")
if quote_balance and quote_amount and int(quote_balance) < int(quote_amount):
blockers.append("insufficient_quote_balance")
create_cmd = (
f"cast send {integration} "
f"'createPool(address,address,uint256,uint256,uint256,bool)(address)' "
f"{base_address} {quote_address} {fee_bps} {initial_price or '<initial_price_e18>'} {k_value} "
f"{str(open_twap).lower()} --rpc-url {rpc_url} --private-key $PRIVATE_KEY"
if integration and base_address and quote_address and rpc_url else ""
)
seed_cmd = (
f"cast send {integration} "
f"'addLiquidity(address,uint256,uint256)(uint256,uint256,uint256)' "
f"<pool_address> {base_amount or '<base_amount_raw>'} {quote_amount or '<quote_amount_raw>'} "
f"--rpc-url {rpc_url} --private-key $PRIVATE_KEY"
if integration and rpc_url else ""
)
rows.append({
"chain_id": chain_id,
"network": network,
"pair": pair,
"base_symbol": base_symbol,
"quote_symbol": quote_symbol,
"hub_stable": missing["hub_stable"],
"rpc_env_key": rpc_key,
"integration_env_key": integration_key,
"base_env_key": base_env_key,
"quote_anchor_source": "deployment-status.json",
"rpc_url_present": bool(rpc_url),
"integration_present": bool(integration),
"base_token_present": bool(base_address),
"quote_anchor_present": bool(quote_address),
"base_address": base_address or None,
"quote_address": quote_address or None,
"integration_address": integration or None,
"deployer": deployer or None,
"live_checks_enabled": live_checks,
"existing_pool_address": existing_pool or None,
"initial_price_e18": initial_price,
"price_mode": price_mode,
"fee_bps": fee_bps,
"k": k_value,
"open_twap": open_twap,
"base_amount_raw": base_amount,
"quote_amount_raw": quote_amount,
"mint_base_amount_raw": mint_amount,
"wallet_base_balance_raw": base_balance or None,
"wallet_quote_balance_raw": quote_balance or None,
"wallet_base_allowance_raw": base_allowance or None,
"wallet_quote_allowance_raw": quote_allowance or None,
"mintable_base": mintable_base,
"base_supply_mode": base_supply_mode,
"ready_to_create": create_ready,
"ready_to_create_with_bootstrap_price": create_ready_with_bootstrap_price,
"ready_to_seed": seed_ready and "insufficient_base_balance" not in blockers and "insufficient_quote_balance" not in blockers,
"blockers": sorted(set(blockers)),
"create_command": create_cmd,
"seed_command": seed_cmd,
"next_step": (
"deploy_or_seed_now" if seed_ready and "insufficient_base_balance" not in blockers and "insufficient_quote_balance" not in blockers
else "operator_review_bootstrap_price" if create_ready_with_bootstrap_price
else "resolve_blockers"
),
})
summary = {
"planned_missing_rows": len(rows),
"ready_to_create_strict": sum(1 for row in rows if row["ready_to_create"]),
"ready_to_create_with_bootstrap_price": sum(1 for row in rows if row["ready_to_create_with_bootstrap_price"]),
"ready_to_seed": sum(1 for row in rows if row["ready_to_seed"]),
"existing_pool_rows_found_onchain": sum(1 for row in rows if row["existing_pool_address"] and row["existing_pool_address"] != "0x0000000000000000000000000000000000000000"),
"counts_by_network": dict(sorted(Counter(row["network"] for row in rows).items())),
"top_blockers": dict(sorted(Counter(blocker for row in rows for blocker in row["blockers"]).items(), key=lambda item: (-item[1], item[0]))[:20]),
}
result = {
"generated_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"description": "Universal GRU v2 Wave 1 public pool deployment plan derived from the missing-pool gap report, env, deployment-status, and seed policy.",
"sources": [
"reports/extraction/gru-v2-wave1-public-gap-report-latest.json",
"cross-chain-pmm-lps/config/deployment-status.json",
"config/extraction/gru-v2-wave1-public-seed-policy.json",
"repo env via scripts/lib/load-project-env.sh",
"optional live RPC checks via GRU_WAVE1_PLAN_LIVE_CHECKS=1",
],
"summary": summary,
"rows": sorted(rows, key=lambda item: (item["chain_id"], item["pair"])),
}
output_path.write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps(summary, indent=2))
PY
echo "Wrote ${OUTPUT_PATH}"

View File

@@ -0,0 +1,152 @@
#!/usr/bin/env bash
#
# Orchestrate the repo-backed portions of the GRU v2 full deployment plan.
# This script is intentionally honest about scope:
# - Chain 138 has real PMM desired-state sync and verification paths.
# - ALL Mainnet 651940 full cA* mesh is not fully deployable from this repo today.
# - Multi-protocol completion on 138/651940 is still partially inventory-only.
#
# Usage:
# bash scripts/deployment/run-gru-v2-full-deployment.sh [--dry-run] [--apply-chain138]
#
# Exit codes:
# 0 = all repo-backed steps passed and no known implementation blockers remain
# 1 = one or more repo-backed steps failed
# 2 = repo-backed steps passed but external/not-yet-implemented blockers remain
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
DRY_RUN=1
APPLY_CHAIN138=0
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
--apply-chain138) DRY_RUN=0; APPLY_CHAIN138=1 ;;
*)
echo "Unknown argument: $arg" >&2
exit 1
;;
esac
done
run_cmd() {
if (( DRY_RUN )); then
echo "[DRY-RUN] $*"
else
"$@"
fi
}
say() {
printf '\n== %s ==\n' "$1"
}
BLOCKERS=0
FAILURES=0
say "GRU v2 full deployment"
echo "projectRoot=$PROJECT_ROOT"
echo "dryRun=$DRY_RUN"
echo "applyChain138=$APPLY_CHAIN138"
say "Validate planning artifacts"
if ! run_cmd python3 "$PROJECT_ROOT/scripts/validation/validate-gru-v2-full-mesh-artifacts.py"; then
echo "validation failed: GRU mesh artifacts" >&2
FAILURES=1
fi
say "Reconcile current live status"
if ! run_cmd python3 "$PROJECT_ROOT/scripts/verify/reconcile-gru-v2-full-mesh-status.py"; then
echo "reconcile failed: GRU mesh live status" >&2
FAILURES=1
fi
say "Chain 138 repo-backed deployment path"
if (( APPLY_CHAIN138 )); then
if ! run_cmd bash "$PROJECT_ROOT/scripts/deployment/run-all-next-steps-chain138.sh" --mesh-only --skip-register-gru; then
echo "chain 138 deployment path failed" >&2
FAILURES=1
fi
if ! run_cmd bash "$PROJECT_ROOT/scripts/deployment/deploy-chain138-pilot-protocol-venues.sh" --apply; then
echo "chain 138 protocol venue deployment path failed" >&2
FAILURES=1
fi
else
run_cmd bash "$PROJECT_ROOT/scripts/deployment/run-all-next-steps-chain138.sh" --dry-run --mesh-only --skip-register-gru
run_cmd bash "$PROJECT_ROOT/scripts/deployment/deploy-chain138-pilot-protocol-venues.sh" --dry-run
fi
say "Chain 138 readiness"
if ! run_cmd bash "$PROJECT_ROOT/scripts/verify/check-gru-v2-chain138-readiness.sh"; then
echo "chain 138 readiness failed" >&2
FAILURES=1
fi
say "Chain 138 remaining protocol surface"
if [[ -x "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh" ]]; then
run_cmd bash "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh" --dry-run || BLOCKERS=1
else
echo "No Chain 138 Aave execution deployer was found."
BLOCKERS=1
fi
if [[ -x "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh" ]]; then
run_cmd bash "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh" --dry-run || BLOCKERS=1
else
echo "No Chain 138 Aave quote-push receiver deployer was found."
BLOCKERS=1
fi
run_cmd bash "$PROJECT_ROOT/scripts/verify/check-chain138-remaining-protocol-env.sh" || BLOCKERS=1
say "ALL Mainnet 651940 implementation gate"
if [[ -x "$PROJECT_ROOT/scripts/deployment/deploy-allmainnet-ca-tokens.sh" ]]; then
run_cmd bash "$PROJECT_ROOT/scripts/deployment/deploy-allmainnet-ca-tokens.sh" --dry-run
else
echo "No repo-backed full cA* contract deployer was found for 651940."
BLOCKERS=1
fi
if [[ -x "$PROJECT_ROOT/scripts/deployment/sync-allmainnet-pmm-pools-from-json.sh" ]]; then
run_cmd bash "$PROJECT_ROOT/scripts/deployment/sync-allmainnet-pmm-pools-from-json.sh"
else
echo "No repo-backed full 651940 PMM mesh deployer was found."
BLOCKERS=1
fi
echo "651940 still requires live cA* addresses, DODO integration/provider addresses, and routeable liquidity to finish."
BLOCKERS=1
say "Protocol completion gate"
echo "DODO on Chain 138 is script-backed."
echo "Full Uniswap v2/v3, SushiSwap, Curve, Balancer, 1Inch, Aave, GMX, and dYdX completion on 138/651940 is not fully deployer-backed in this repo."
echo "Marking protocol completion as externally blocked until venue-specific deploy/integration scripts exist."
BLOCKERS=1
if ! run_cmd bash "$PROJECT_ROOT/scripts/verify/check-gru-v2-core-protocol-blockers.sh"; then
BLOCKERS=1
fi
run_cmd bash "$PROJECT_ROOT/scripts/verify/check-allmainnet-protocol-env.sh" || BLOCKERS=1
say "Implementation verifier"
if ! run_cmd python3 "$PROJECT_ROOT/scripts/verify/check-gru-v2-full-deployment-implementation.py"; then
BLOCKERS=1
fi
say "Summary"
if (( FAILURES )); then
echo "result=failed"
exit 1
fi
if (( BLOCKERS )); then
echo "result=partial"
echo "note=repo-backed deployment steps completed, but external/not-yet-implemented blockers remain"
exit 2
fi
echo "result=complete"

View File

@@ -0,0 +1,105 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
source "${REPO_ROOT}/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
source "${REPO_ROOT}/smom-dbis-138/scripts/load-env.sh" >/dev/null 2>&1 || true
TARGET_USD="${TARGET_USD:-100000}"
EXECUTE=0
usage() {
cat <<'EOF'
Usage:
bash scripts/deployment/run-gru-v2-mainnet-funding.sh [--target-usd=100000] [--execute]
Stages:
1. Ensure reports are current
2. Print / optionally apply GRU V2 Mainnet bridge parity
3. Mint required cUSDT_V2 / cUSDC_V2 on Chain 138
4. Bridge the required amounts to Mainnet cW mirrors
5. Apply full-target funding to cwusdt-usdt and cwusdc-usdc
EOF
}
for arg in "$@"; do
case "$arg" in
--target-usd=*) TARGET_USD="${arg#*=}" ;;
--execute) EXECUTE=1 ;;
--help|-h) usage; exit 0 ;;
*) echo "[fail] unknown arg: $arg" >&2; usage >&2; exit 2 ;;
esac
done
command -v python3 >/dev/null 2>&1 || { echo "[fail] missing required command: python3" >&2; exit 1; }
command -v cast >/dev/null 2>&1 || { echo "[fail] missing required command: cast" >&2; exit 1; }
bash "${REPO_ROOT}/scripts/verify/build-gru-v2-mainnet-bridge-parity.sh" >/dev/null
bash "${REPO_ROOT}/scripts/verify/build-mainnet-direct-exit-funding-plan.sh" >/dev/null
bash "${REPO_ROOT}/scripts/verify/build-gru-v2-mainnet-funding-plan.sh" >/dev/null
TARGET_USD="$TARGET_USD" REPO_ROOT="$REPO_ROOT" python3 - <<'PY'
import json, os
from pathlib import Path
root = Path(os.environ["REPO_ROOT"])
target_usd = int(os.environ["TARGET_USD"])
report = json.loads((root / "reports/extraction/gru-v2-mainnet-funding-plan-latest.json").read_text())
lane = report.get("parity_state", {}).get("lane_policy", {})
print("lanePolicy.v2CutoverActive="+str(lane.get("v2_cutover_active")))
print("lanePolicy.v1DisplacedAssets="+",".join(lane.get("v1_displaced_assets", [])))
for row in report["assets"]:
print("asset="+row["symbol"])
print("targetUsd="+str(row["target_exit_usd"]))
print("mintNeededRaw="+row["mint_needed_raw"])
print("bridgeRaw="+row["bridge_amount_raw"])
print("pair="+row["funding_pair"])
print("quoteSideReadyNow="+str(row.get("wallet_can_fund_quote_side_now")))
print("fundPairCommand="+row["fund_pool_command"])
print("---")
PY
run_stage() {
local cmd="$1"
echo "$cmd"
if (( EXECUTE == 1 )); then
bash -lc "$cmd"
fi
}
run_stage "bash ${REPO_ROOT}/scripts/deployment/configure-gru-v2-mainnet-bridge-parity.sh $([[ $EXECUTE -eq 1 ]] && echo --execute)"
readarray -t ASSET_LINES < <(
TARGET_USD="$TARGET_USD" REPO_ROOT="$REPO_ROOT" python3 - <<'PY'
import json, os
from pathlib import Path
root = Path(os.environ["REPO_ROOT"])
target_usd = int(os.environ["TARGET_USD"])
report = json.loads((root / "reports/extraction/gru-v2-mainnet-funding-plan-latest.json").read_text())
for row in report["assets"]:
print("|".join([
row["symbol"],
row["canonical_token"],
row["mirrored_token"],
row["mint_needed_raw"],
row["bridge_amount_raw"],
row["funding_pair"],
]))
PY
)
for entry in "${ASSET_LINES[@]}"; do
IFS='|' read -r SYMBOL TOKEN MIRRORED MINT_NEEDED BRIDGE_RAW FUND_PAIR <<<"$entry"
if [[ "$MINT_NEEDED" != "0" ]]; then
run_stage "cast send ${TOKEN} 'mint(address,uint256)' ${CANONICAL_WALLET:-0x4A666F96fC8764181194447A7dFdb7d471b301C8} ${MINT_NEEDED} --rpc-url \"\$RPC_URL_138\" --private-key \"\$PRIVATE_KEY\" --legacy"
fi
if [[ "$BRIDGE_RAW" != "0" ]]; then
run_stage "bash ${REPO_ROOT}/scripts/bridge/bridge-canonical-token-to-mainnet-cw.sh --label ${SYMBOL} --canonical-token ${TOKEN} --mirrored-token ${MIRRORED} --raw-amount ${BRIDGE_RAW} --recipient ${CANONICAL_WALLET:-0x4A666F96fC8764181194447A7dFdb7d471b301C8} --approve $([[ $EXECUTE -eq 1 ]] && echo --execute)"
fi
run_stage "bash ${REPO_ROOT}/scripts/deployment/apply-mainnet-direct-exit-funding.sh --pair=${FUND_PAIR} --mode=full-target --target-usd=${TARGET_USD} $([[ $EXECUTE -eq 1 ]] && echo --execute)"
done
if (( EXECUTE == 0 )); then
echo "Dry-run only. Re-run with --execute to broadcast."
echo "Note: if quoteSideReadyNow=false in the printed plan, the pool-funding stage is still capital-blocked even though the V2 bridge lane is ready."
fi

View File

@@ -0,0 +1,360 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
PLAN_PATH="${ROOT_DIR}/reports/extraction/gru-v2-wave1-public-deploy-plan-latest.json"
OUTPUT_PATH="${ROOT_DIR}/reports/extraction/gru-v2-wave1-public-deploy-run-latest.json"
source "${ROOT_DIR}/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
if [[ -f "${ROOT_DIR}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" ]]; then
# shellcheck disable=SC1090
source "${ROOT_DIR}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" >/dev/null 2>&1 || true
load_deployment_env --repo-root "${ROOT_DIR}/smom-dbis-138" >/dev/null 2>&1 || true
export PROJECT_ROOT="${ROOT_DIR}"
fi
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "[fail] missing required command: $1" >&2
exit 1
}
}
parse_tx_hash() {
local output="$1"
local tx_hash
tx_hash="$(printf '%s\n' "$output" | grep -E '^0x[0-9a-fA-F]{64}$' | tail -n1 || true)"
if [[ -z "$tx_hash" ]]; then
tx_hash="$(printf '%s\n' "$output" | grep -E '^transactionHash[[:space:]]+0x[0-9a-fA-F]{64}$' | awk '{print $2}' | tail -n1 || true)"
fi
printf '%s\n' "$tx_hash"
}
require_cmd python3
CHAIN_ID_FILTER=""
PAIR_FILTER=""
MAX_POOLS=0
EXECUTE=0
ONLY_READY=0
SKIP_SEED=0
ALLOW_BOOTSTRAP_PRICES=0
BASE_AMOUNT_OVERRIDE=""
QUOTE_AMOUNT_OVERRIDE=""
MINT_BASE_AMOUNT_OVERRIDE=""
for arg in "$@"; do
case "$arg" in
--chain-id=*) CHAIN_ID_FILTER="${arg#*=}" ;;
--pair=*) PAIR_FILTER="${arg#*=}" ;;
--max-pools=*) MAX_POOLS="${arg#*=}" ;;
--execute) EXECUTE=1 ;;
--only-ready) ONLY_READY=1 ;;
--skip-seed) SKIP_SEED=1 ;;
--allow-bootstrap-prices) ALLOW_BOOTSTRAP_PRICES=1 ;;
--base-amount=*) BASE_AMOUNT_OVERRIDE="${arg#*=}" ;;
--quote-amount=*) QUOTE_AMOUNT_OVERRIDE="${arg#*=}" ;;
--mint-base-amount=*) MINT_BASE_AMOUNT_OVERRIDE="${arg#*=}" ;;
*)
echo "[fail] unknown arg: $arg" >&2
exit 2
;;
esac
done
if (( EXECUTE == 1 )); then
export GRU_WAVE1_PLAN_LIVE_CHECKS="${GRU_WAVE1_PLAN_LIVE_CHECKS:-1}"
fi
bash "${ROOT_DIR}/scripts/deployment/plan-gru-v2-wave1-public-pools.sh" >/dev/null
mkdir -p "$(dirname "$OUTPUT_PATH")"
python3 - <<'PY' "$PLAN_PATH" "$OUTPUT_PATH" "$CHAIN_ID_FILTER" "$PAIR_FILTER" "$MAX_POOLS" "$EXECUTE" "$ONLY_READY" "$SKIP_SEED" "$ALLOW_BOOTSTRAP_PRICES"
import json
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path
plan_path = Path(sys.argv[1])
output_path = Path(sys.argv[2])
chain_filter = sys.argv[3]
pair_filter = sys.argv[4].lower()
max_pools = int(sys.argv[5])
execute = sys.argv[6] == "1"
only_ready = sys.argv[7] == "1"
skip_seed = sys.argv[8] == "1"
allow_bootstrap_prices = sys.argv[9] == "1"
plan = json.loads(plan_path.read_text())
rows = plan["rows"]
selected = []
for row in rows:
if chain_filter and str(row["chain_id"]) != chain_filter:
continue
if pair_filter and row["pair"].lower() != pair_filter:
continue
if only_ready and not row["ready_to_create_with_bootstrap_price"]:
continue
selected.append(row)
if max_pools and len(selected) >= max_pools:
break
result_rows = []
for row in selected:
out = {
"chain_id": row["chain_id"],
"network": row["network"],
"pair": row["pair"],
"mode": "execute" if execute else "dry_run",
"create_planned": row["ready_to_create_with_bootstrap_price"],
"seed_planned": row["ready_to_seed"] and not skip_seed,
"price_mode": row["price_mode"],
"blockers": list(row["blockers"]),
"base_supply_mode": row.get("base_supply_mode"),
"mintable_base": row.get("mintable_base"),
"wallet_base_balance_raw": row.get("wallet_base_balance_raw"),
"wallet_quote_balance_raw": row.get("wallet_quote_balance_raw"),
"create_tx": None,
"seed_tx": None,
"pool_address_before": row["existing_pool_address"],
"pool_address_after": row["existing_pool_address"],
"status": "planned",
}
if row["price_mode"] == "bootstrap_reference" and not allow_bootstrap_prices:
out["status"] = "blocked_bootstrap_price_guard"
result_rows.append(out)
continue
if not execute:
result_rows.append(out)
continue
out["status"] = "execute_requires_shell_runner"
result_rows.append(out)
result = {
"generated_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"description": "Universal GRU v2 Wave 1 pool operator run record. Execute mode is implemented in the surrounding shell runner.",
"selected_count": len(selected),
"rows": result_rows,
}
output_path.write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps({"selected_count": len(selected)}, indent=2))
PY
if (( EXECUTE == 0 )); then
echo "Wrote ${OUTPUT_PATH}"
exit 0
fi
require_cmd cast
mapfile -t RUN_ROWS < <(
python3 - <<'PY' "$PLAN_PATH" "$CHAIN_ID_FILTER" "$PAIR_FILTER" "$MAX_POOLS" "$ONLY_READY" "$ALLOW_BOOTSTRAP_PRICES" "$BASE_AMOUNT_OVERRIDE" "$QUOTE_AMOUNT_OVERRIDE" "$MINT_BASE_AMOUNT_OVERRIDE"
import base64, json, os, sys
from pathlib import Path
plan = json.loads(Path(sys.argv[1]).read_text())
chain_filter = sys.argv[2]
pair_filter = sys.argv[3].lower()
max_pools = int(sys.argv[4])
only_ready = sys.argv[5] == "1"
allow_bootstrap_prices = sys.argv[6] == "1"
base_override = sys.argv[7]
quote_override = sys.argv[8]
mint_override = sys.argv[9]
rows = []
for row in plan["rows"]:
if chain_filter and str(row["chain_id"]) != chain_filter:
continue
if pair_filter and row["pair"].lower() != pair_filter:
continue
if only_ready and not row["ready_to_create_with_bootstrap_price"]:
continue
if row["price_mode"] == "bootstrap_reference" and not allow_bootstrap_prices:
continue
rows.append(row)
if max_pools and len(rows) >= max_pools:
break
for row in rows:
payload = {
"chain_id": row["chain_id"],
"network": row["network"],
"pair": row["pair"],
"integration": row["integration_address"] or "",
"base_addr": row["base_address"] or "",
"quote_addr": row["quote_address"] or "",
"existing_pool": row["existing_pool_address"] or "",
"initial_price": row["initial_price_e18"] or "",
"fee_bps": row["fee_bps"] or "",
"k_value": row["k"] or "",
"open_twap": "true" if row["open_twap"] else "false",
"base_amount": base_override or row["base_amount_raw"] or "",
"quote_amount": quote_override or row["quote_amount_raw"] or "",
"mint_amount": mint_override or row["mint_base_amount_raw"] or "",
"rpc_env_key": row["rpc_env_key"] or "",
"rpc_url": os.environ.get(row["rpc_env_key"] or "", "") if row.get("rpc_url_present") else "",
"ready_to_seed": "true" if row.get("ready_to_seed") else "false",
"base_supply_mode": row.get("base_supply_mode") or "",
"mintable_base": "true" if row.get("mintable_base") else "false",
"wallet_base_balance_raw": row.get("wallet_base_balance_raw") or "",
"wallet_quote_balance_raw": row.get("wallet_quote_balance_raw") or "",
"blockers_json": json.dumps(row.get("blockers", []), separators=(",", ":")),
}
print(base64.b64encode(json.dumps(payload).encode()).decode())
PY
)
DEPLOYER="$(cast wallet address --private-key "${PRIVATE_KEY:-}")"
RESULT_JSON="$(
python3 - <<'PY'
import json
print(json.dumps({"generated_at": None, "description": "Universal GRU v2 Wave 1 pool operator live run record.", "rows": []}))
PY
)"
for encoded in "${RUN_ROWS[@]}"; do
eval "$(
python3 - <<'PY' "$encoded"
import base64, json, shlex, sys
row = json.loads(base64.b64decode(sys.argv[1]).decode())
for key, value in row.items():
print(f"{key.upper()}={shlex.quote(str(value))}")
PY
)"
STATUS="executed"
CREATE_TX=""
SEED_TX=""
POOL_ADDRESS="$EXISTING_POOL"
NOTES=()
SEED_READY=0
MINTABLE_BASE_READY=0
HAS_INSUFFICIENT_BASE=0
HAS_INSUFFICIENT_QUOTE=0
if [[ "${READY_TO_SEED:-false}" == "true" ]]; then
SEED_READY=1
fi
if [[ "${MINTABLE_BASE:-false}" == "true" ]]; then
MINTABLE_BASE_READY=1
fi
if [[ "${BLOCKERS_JSON:-[]}" == *'"insufficient_base_balance"'* ]]; then
HAS_INSUFFICIENT_BASE=1
fi
if [[ "${BLOCKERS_JSON:-[]}" == *'"insufficient_quote_balance"'* ]]; then
HAS_INSUFFICIENT_QUOTE=1
fi
if [[ -z "$RPC_URL" || -z "$INTEGRATION" || -z "$BASE_ADDR" || -z "$QUOTE_ADDR" ]]; then
STATUS="blocked_missing_runtime_inputs"
else
if [[ -z "$POOL_ADDRESS" || "$POOL_ADDRESS" == "0x0000000000000000000000000000000000000000" ]]; then
create_output="$(
cast send "$INTEGRATION" \
'createPool(address,address,uint256,uint256,uint256,bool)(address)' \
"$BASE_ADDR" "$QUOTE_ADDR" "$FEE_BPS" "$INITIAL_PRICE" "$K_VALUE" "$OPEN_TWAP" \
--rpc-url "$RPC_URL" \
--private-key "${PRIVATE_KEY:-}"
)"
CREATE_TX="$(parse_tx_hash "$create_output")"
POOL_ADDRESS="$(cast call "$INTEGRATION" 'pools(address,address)(address)' "$BASE_ADDR" "$QUOTE_ADDR" --rpc-url "$RPC_URL" | awk '{print $1}')"
fi
if (( SKIP_SEED == 0 )) && [[ -n "$POOL_ADDRESS" && "$POOL_ADDRESS" != "0x0000000000000000000000000000000000000000" && -n "$BASE_AMOUNT" && -n "$QUOTE_AMOUNT" ]]; then
if (( HAS_INSUFFICIENT_BASE == 1 )); then
STATUS="blocked_seed_base_supply"
NOTES+=("seed_skipped_insufficient_base_supply")
elif (( HAS_INSUFFICIENT_QUOTE == 1 )); then
STATUS="blocked_seed_quote_supply"
NOTES+=("seed_skipped_insufficient_quote_supply")
elif (( SEED_READY == 0 )); then
STATUS="blocked_seed_readiness"
NOTES+=("seed_skipped_not_ready")
else
BASE_BAL="${WALLET_BASE_BALANCE_RAW:-}"
QUOTE_BAL="${WALLET_QUOTE_BALANCE_RAW:-}"
if [[ -z "$BASE_BAL" ]]; then
BASE_BAL="$(cast call "$BASE_ADDR" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
fi
if [[ -z "$QUOTE_BAL" ]]; then
QUOTE_BAL="$(cast call "$QUOTE_ADDR" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
fi
if (( BASE_BAL < BASE_AMOUNT )); then
if (( MINTABLE_BASE_READY == 1 )) && [[ -n "$MINT_AMOUNT" && "$MINT_AMOUNT" != "0" ]]; then
cast send "$BASE_ADDR" 'mint(address,uint256)' "$DEPLOYER" "$MINT_AMOUNT" --rpc-url "$RPC_URL" --private-key "${PRIVATE_KEY:-}" >/dev/null
NOTES+=("minted_base")
BASE_BAL="$(cast call "$BASE_ADDR" 'balanceOf(address)(uint256)' "$DEPLOYER" --rpc-url "$RPC_URL" | awk '{print $1}')"
fi
fi
if (( BASE_BAL < BASE_AMOUNT )); then
STATUS="blocked_seed_base_supply"
NOTES+=("seed_skipped_postcheck_base_short")
elif (( QUOTE_BAL < QUOTE_AMOUNT )); then
STATUS="blocked_seed_quote_supply"
NOTES+=("seed_skipped_postcheck_quote_short")
else
cast send "$BASE_ADDR" 'approve(address,uint256)(bool)' "$INTEGRATION" "$BASE_AMOUNT" --rpc-url "$RPC_URL" --private-key "${PRIVATE_KEY:-}" >/dev/null
cast send "$QUOTE_ADDR" 'approve(address,uint256)(bool)' "$INTEGRATION" "$QUOTE_AMOUNT" --rpc-url "$RPC_URL" --private-key "${PRIVATE_KEY:-}" >/dev/null
seed_output="$(
cast send "$INTEGRATION" \
'addLiquidity(address,uint256,uint256)(uint256,uint256,uint256)' \
"$POOL_ADDRESS" "$BASE_AMOUNT" "$QUOTE_AMOUNT" \
--rpc-url "$RPC_URL" \
--private-key "${PRIVATE_KEY:-}"
)"
SEED_TX="$(parse_tx_hash "$seed_output")"
if [[ -n "$CREATE_TX" ]]; then
STATUS="executed_create_and_seed"
else
STATUS="executed_seed_only"
fi
fi
fi
elif [[ -n "$CREATE_TX" ]]; then
STATUS="executed_create_only"
fi
fi
RESULT_JSON="$(
python3 - <<'PY' "$RESULT_JSON" "$CHAIN_ID" "$NETWORK" "$PAIR" "$STATUS" "$CREATE_TX" "$SEED_TX" "$POOL_ADDRESS" "$EXISTING_POOL" "$(printf '%s\n' "${NOTES[*]}")" "${BASE_SUPPLY_MODE:-}" "${MINTABLE_BASE:-false}" "${WALLET_BASE_BALANCE_RAW:-}" "${WALLET_QUOTE_BALANCE_RAW:-}" "${BLOCKERS_JSON:-[]}"
import json, sys
doc = json.loads(sys.argv[1])
doc["rows"].append({
"chain_id": int(sys.argv[2]),
"network": sys.argv[3],
"pair": sys.argv[4],
"status": sys.argv[5],
"create_tx": sys.argv[6] or None,
"seed_tx": sys.argv[7] or None,
"pool_address_before": sys.argv[9] or None,
"pool_address_after": sys.argv[8] or None,
"notes": [x for x in sys.argv[10].split() if x],
"base_supply_mode": sys.argv[11] or None,
"mintable_base": sys.argv[12] == "true",
"wallet_base_balance_raw": sys.argv[13] or None,
"wallet_quote_balance_raw": sys.argv[14] or None,
"blockers": json.loads(sys.argv[15] or "[]"),
})
print(json.dumps(doc))
PY
)"
done
python3 - <<'PY' "$RESULT_JSON" "$OUTPUT_PATH"
import json, sys
from datetime import datetime, timezone
doc = json.loads(sys.argv[1])
doc["generated_at"] = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
with open(sys.argv[2], "w") as fh:
json.dump(doc, fh, indent=2)
fh.write("\n")
print(json.dumps({"executed_rows": len(doc["rows"])}, indent=2))
PY
echo "Wrote ${OUTPUT_PATH}"

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env python3
import json
import pathlib
import re
import sys
ROOT = pathlib.Path(__file__).resolve().parents[2]
TRACKER = ROOT / "config/gru-v2-full-mesh-pool-tracker.json"
SCHEMA = ROOT / "config/gru-v2-full-mesh-pool-tracker.schema.json"
MASTER = ROOT / "config/gru-v2-full-mesh-master-matrix.json"
MASTER_DOC = ROOT / "docs/04-configuration/GRU_V2_FULL_MESH_MASTER_MATRIX.md"
CHECKLIST = ROOT / "docs/04-configuration/GRU_V2_FULL_MESH_EXECUTION_CHECKLIST.md"
PROTOCOL = ROOT / "docs/04-configuration/GRU_V2_PROTOCOL_COMPLETION_MATRIX.md"
def fail(msg: str) -> None:
print(f"ERROR: {msg}", file=sys.stderr)
sys.exit(1)
def load_json(path: pathlib.Path):
try:
return json.loads(path.read_text())
except Exception as exc:
fail(f"failed to parse {path}: {exc}")
def require(cond: bool, msg: str) -> None:
if not cond:
fail(msg)
def validate_tracker(tracker: dict) -> None:
require(re.fullmatch(r"\d{4}-\d{2}-\d{2}", tracker.get("statusDate", "")) is not None, "tracker statusDate must be YYYY-MM-DD")
default_fields = tracker.get("defaultFields", {})
for key in ["status", "deployed", "seeded", "validated", "live", "mevReady"]:
require(key in default_fields, f"defaultFields missing {key}")
require(default_fields["status"] in {"todo", "in_progress", "blocked", "done"}, "defaultFields.status invalid")
chain138_pairs = [row["pair"] for row in tracker["chain138"]["entries"]]
allmain_pairs = [row["pair"] for row in tracker["allMainnet651940"]["entries"]]
require("cUSDT V2 / cUSDC V2" in chain138_pairs, "chain138 tracker missing canonical USD hub pair")
require("cAUSDT / cAUSDC" in allmain_pairs, "allMainnet tracker missing canonical USD hub pair")
public_mesh = tracker["publicMesh"]
for chain in ["1", "10", "25", "56", "100", "137", "1111", "8453", "42161", "42220", "43114"]:
require(chain in public_mesh, f"publicMesh missing connected chain {chain}")
entries = public_mesh[chain]["entries"]
require("cWUSDT / USDC" in entries, f"publicMesh {chain} missing cWUSDT / USDC")
require("cWUSDC / USDC" in entries, f"publicMesh {chain} missing cWUSDC / USDC")
def validate_master(master: dict) -> None:
phases = {row["id"] for row in master.get("executionPhases", [])}
require(phases == {"P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7"}, "executionPhases must contain P0..P7")
protocols = set(master.get("protocolsRequired", []))
for protocol in ["DODO", "Uniswap v3", "Uniswap v2", "SushiSwap", "Curve", "Balancer", "1Inch", "Aave", "GMX", "dYdX"]:
require(protocol in protocols, f"master matrix missing protocol {protocol}")
def validate_docs() -> None:
for path in [MASTER_DOC, CHECKLIST, PROTOCOL]:
require(path.exists(), f"missing doc {path}")
text = path.read_text()
require("Chain 138" in text or "138" in text, f"{path.name} does not mention Chain 138")
require("651940" in text or "ALL Mainnet" in text, f"{path.name} does not mention ALL Mainnet")
def main() -> None:
for path in [TRACKER, SCHEMA, MASTER, MASTER_DOC, CHECKLIST, PROTOCOL]:
require(path.exists(), f"required artifact missing: {path}")
tracker = load_json(TRACKER)
_schema = load_json(SCHEMA)
master = load_json(MASTER)
validate_tracker(tracker)
validate_master(master)
validate_docs()
print("GRU_V2_FULL_MESH_ARTIFACTS_OK")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$ROOT/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
python3 "$ROOT/scripts/lib/immediate_liquidity_expansion.py" parity

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "$ROOT/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
python3 "$ROOT/scripts/lib/immediate_liquidity_expansion.py" v2-funding

View File

@@ -0,0 +1,298 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
REPO_ROOT="$PROJECT_ROOT"
OUTPUT_PATH="${PROJECT_ROOT}/reports/extraction/gru-v2-wave1-funding-authority-report-latest.json"
PLAN_PATH="${PROJECT_ROOT}/reports/extraction/gru-v2-wave1-public-deploy-plan-latest.json"
GAP_REPORT_PATH="${PROJECT_ROOT}/reports/extraction/gru-v2-wave1-public-gap-report-latest.json"
VERIFY_MATRIX_PATH="${PROJECT_ROOT}/reports/status/contract_verification_publish_matrix.json"
source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" >/dev/null 2>&1 || true
if [[ -f "${PROJECT_ROOT}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" ]]; then
# shellcheck disable=SC1090
source "${PROJECT_ROOT}/smom-dbis-138/scripts/lib/deployment/dotenv.sh" >/dev/null 2>&1 || true
load_deployment_env --repo-root "${PROJECT_ROOT}/smom-dbis-138" >/dev/null 2>&1 || true
PROJECT_ROOT="$REPO_ROOT"
export PROJECT_ROOT
fi
mkdir -p "$(dirname "$OUTPUT_PATH")"
NEEDS_PLAN_REFRESH="$(
python3 - <<'PY' "$PLAN_PATH" "$GAP_REPORT_PATH"
import json, sys
from pathlib import Path
plan_path = Path(sys.argv[1])
gap_report_path = Path(sys.argv[2])
if not plan_path.exists() or not gap_report_path.exists():
print("1")
raise SystemExit
plan = json.loads(plan_path.read_text())
gap = json.loads(gap_report_path.read_text())
rows = plan.get("rows", [])
expected = gap.get("summary", {}).get("first_tier_wave1_pools_missing")
live_rows = [row for row in rows if row.get("live_checks_enabled")]
if expected is None or len(rows) != expected or len(live_rows) != len(rows):
print("1")
else:
print("0")
PY
)"
if [[ "$NEEDS_PLAN_REFRESH" == "1" ]]; then
export GRU_WAVE1_PLAN_LIVE_CHECKS="${GRU_WAVE1_PLAN_LIVE_CHECKS:-1}"
bash "${PROJECT_ROOT}/scripts/deployment/plan-gru-v2-wave1-public-pools.sh" >/dev/null
fi
python3 - <<'PY' "$PLAN_PATH" "$GAP_REPORT_PATH" "$VERIFY_MATRIX_PATH" "$OUTPUT_PATH"
import json
import sys
from collections import Counter, defaultdict
from datetime import datetime, timezone
from pathlib import Path
plan_path = Path(sys.argv[1])
gap_report_path = Path(sys.argv[2])
verify_matrix_path = Path(sys.argv[3])
output_path = Path(sys.argv[4])
plan = json.loads(plan_path.read_text())
gap_report = json.loads(gap_report_path.read_text())
verify_matrix = json.loads(verify_matrix_path.read_text()) if verify_matrix_path.exists() else {"entries": []}
plan_rows = {
(int(row["chain_id"]), row["pair"]): row
for row in plan.get("rows", [])
}
by_label = {}
by_address = {}
for entry in verify_matrix.get("entries", []):
chain_id = str(entry.get("chainId", ""))
label = entry.get("label", "")
address = (entry.get("address") or "").lower()
if chain_id and label:
by_label[(chain_id, label)] = entry
if chain_id and address:
by_address[(chain_id, address)] = entry
def verification_entry(chain_id: int, label: str = "", address: str = ""):
chain_key = str(chain_id)
if label and (chain_key, label) in by_label:
return by_label[(chain_key, label)]
address = (address or "").lower()
if address and (chain_key, address) in by_address:
return by_address[(chain_key, address)]
return None
def verification_state_for(chain_id: int, label: str = "", address: str = "", exists_expected: bool = True):
if not exists_expected:
return {
"tracked": False,
"verification_status": "not_deployed",
"publication_status": "not_deployed",
"publish_surface": "",
"explorer": "",
"notes": "Pool or contract not yet deployed",
}
entry = verification_entry(chain_id, label=label, address=address)
if not entry:
return {
"tracked": False,
"verification_status": "untracked",
"publication_status": "untracked",
"publish_surface": "",
"explorer": "",
"notes": "No matching verification/publication matrix row found",
}
return {
"tracked": True,
"verification_status": entry.get("verificationStatus", "unknown"),
"publication_status": entry.get("publicationStatus", "unknown"),
"publish_surface": entry.get("publishSurface", ""),
"explorer": entry.get("explorer", ""),
"notes": entry.get("publishNotes", ""),
}
def is_complete(status_block: dict) -> bool:
return (
status_block.get("tracked") is True
and status_block.get("verification_status") == "complete"
and status_block.get("publication_status") == "complete"
)
rows = []
chain_summary = defaultdict(lambda: {
"missing_pair_count": 0,
"rows_missing_quote_side_stable": 0,
"rows_missing_base_side_balance": 0,
"rows_missing_base_side_mintability": 0,
"rows_missing_integration": 0,
"rows_missing_verification_publication": 0,
})
for gap_row in gap_report.get("missing_first_tier_wave1_pools", []):
key = (int(gap_row["chain_id"]), gap_row["pair"])
plan_row = plan_rows.get(key)
if not plan_row:
continue
chain_id = int(plan_row["chain_id"])
network = plan_row["network"]
pair = plan_row["pair"]
base_symbol = plan_row["base_symbol"]
quote_symbol = plan_row["quote_symbol"]
existing_pool = plan_row.get("existing_pool_address") or ""
pool_exists = existing_pool not in ("", "0x0000000000000000000000000000000000000000", None)
quote_balance_raw = plan_row.get("wallet_quote_balance_raw")
quote_amount_raw = plan_row.get("quote_amount_raw")
base_balance_raw = plan_row.get("wallet_base_balance_raw")
base_amount_raw = plan_row.get("base_amount_raw")
quote_has_balance = bool(quote_balance_raw) and bool(quote_amount_raw) and int(quote_balance_raw) >= int(quote_amount_raw)
base_has_balance = bool(base_balance_raw) and bool(base_amount_raw) and int(base_balance_raw) >= int(base_amount_raw)
base_mintable = bool(plan_row.get("mintable_base"))
integration_present = bool(plan_row.get("integration_present"))
base_ver = verification_state_for(chain_id, label=base_symbol, address=plan_row.get("base_address") or "", exists_expected=bool(plan_row.get("base_address")))
quote_ver = verification_state_for(chain_id, label=quote_symbol, address=plan_row.get("quote_address") or "", exists_expected=bool(plan_row.get("quote_address")))
pool_ver = verification_state_for(chain_id, label=pair, address=existing_pool, exists_expected=pool_exists)
integration_ver = verification_state_for(chain_id, address=plan_row.get("integration_address") or "", exists_expected=integration_present)
verification_publication_complete = all(
is_complete(block) for block in [base_ver, quote_ver]
) and (
is_complete(pool_ver) if pool_exists else False
) and (
is_complete(integration_ver) if integration_present else False
)
missing = {
"quote_side_stable": not quote_has_balance,
"base_side_balance": not base_has_balance,
"base_side_mintability": not base_mintable,
"integration": not integration_present,
"verification_publication_status": not verification_publication_complete,
}
missing_reasons = []
if missing["quote_side_stable"]:
missing_reasons.append("quote_side_stable")
if missing["base_side_balance"]:
missing_reasons.append("base_side_balance")
if missing["base_side_mintability"]:
missing_reasons.append("base_side_mintability")
if missing["integration"]:
missing_reasons.append("integration")
if missing["verification_publication_status"]:
missing_reasons.append("verification_publication_status")
verification_publication = {
"overall_complete": verification_publication_complete,
"base_token": base_ver,
"quote_token": quote_ver,
"integration_contract": integration_ver,
"pool_contract": pool_ver,
}
row = {
"chain_id": chain_id,
"network": network,
"pair": pair,
"hub_stable": gap_row.get("hub_stable"),
"missing": missing,
"missing_reasons": missing_reasons,
"quote_side_stable": {
"quote_symbol": quote_symbol,
"quote_address": plan_row.get("quote_address"),
"required_raw": quote_amount_raw,
"wallet_balance_raw": quote_balance_raw,
"sufficient": quote_has_balance,
},
"base_side_balance": {
"base_symbol": base_symbol,
"base_address": plan_row.get("base_address"),
"required_raw": base_amount_raw,
"wallet_balance_raw": base_balance_raw,
"sufficient": base_has_balance,
"base_supply_mode": plan_row.get("base_supply_mode"),
},
"base_side_mintability": {
"mintable_base": base_mintable,
"mint_base_amount_raw": plan_row.get("mint_base_amount_raw"),
},
"integration": {
"env_key": plan_row.get("integration_env_key"),
"address": plan_row.get("integration_address"),
"present": integration_present,
},
"verification_publication_status": verification_publication,
"existing_pool_address": existing_pool or None,
"ready_to_create": plan_row.get("ready_to_create"),
"ready_to_create_with_bootstrap_price": plan_row.get("ready_to_create_with_bootstrap_price"),
"ready_to_seed_live": plan_row.get("ready_to_seed"),
"blockers": plan_row.get("blockers", []),
"next_step": plan_row.get("next_step"),
}
rows.append(row)
chain_entry = chain_summary[(chain_id, network)]
chain_entry["missing_pair_count"] += 1
chain_entry["rows_missing_quote_side_stable"] += int(missing["quote_side_stable"])
chain_entry["rows_missing_base_side_balance"] += int(missing["base_side_balance"])
chain_entry["rows_missing_base_side_mintability"] += int(missing["base_side_mintability"])
chain_entry["rows_missing_integration"] += int(missing["integration"])
chain_entry["rows_missing_verification_publication"] += int(missing["verification_publication_status"])
summary = {
"remaining_missing_pairs": len(rows),
"rows_missing_quote_side_stable": sum(int(row["missing"]["quote_side_stable"]) for row in rows),
"rows_missing_base_side_balance": sum(int(row["missing"]["base_side_balance"]) for row in rows),
"rows_missing_base_side_mintability": sum(int(row["missing"]["base_side_mintability"]) for row in rows),
"rows_missing_integration": sum(int(row["missing"]["integration"]) for row in rows),
"rows_missing_verification_publication": sum(int(row["missing"]["verification_publication_status"]) for row in rows),
"top_missing_reasons": dict(
sorted(
Counter(reason for row in rows for reason in row["missing_reasons"]).items(),
key=lambda item: (-item[1], item[0]),
)
),
}
chains = []
for (chain_id, network), item in sorted(chain_summary.items()):
chains.append({
"chain_id": chain_id,
"network": network,
**item,
})
result = {
"generated_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"description": "Chain-by-chain GRU v2 Wave 1 funding and authority report for the remaining missing public pools.",
"sources": [
str(plan_path.relative_to(output_path.parents[2])),
str(gap_report_path.relative_to(output_path.parents[2])),
str(verify_matrix_path.relative_to(output_path.parents[2])) if verify_matrix_path.exists() else "reports/status/contract_verification_publish_matrix.json (missing)",
],
"summary": summary,
"chains": chains,
"rows": sorted(rows, key=lambda item: (item["chain_id"], item["pair"])),
}
output_path.write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps(summary, indent=2))
PY
echo "Wrote ${OUTPUT_PATH}"

View File

@@ -0,0 +1,185 @@
#!/usr/bin/env bash
# Build a machine-readable GRU v2 public Wave 1 gap report.
# Captures missing first-tier pools and missing token suites by network.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
OUTPUT_PATH="${PROJECT_ROOT}/reports/extraction/gru-v2-wave1-public-gap-report-latest.json"
mkdir -p "$(dirname "$OUTPUT_PATH")"
python3 - <<'PY' "$PROJECT_ROOT" "$OUTPUT_PATH"
import json
from collections import Counter
from datetime import datetime, timezone
from pathlib import Path
import sys
project_root = Path(sys.argv[1])
output_path = Path(sys.argv[2])
deployment_status = json.loads((project_root / "cross-chain-pmm-lps/config/deployment-status.json").read_text())
queue_json = json.loads(
__import__("subprocess").check_output(
["bash", "scripts/verify/check-gru-v2-deployment-queue.sh", "--json"],
cwd=project_root,
text=True,
)
)
loaded_full_mesh_tokens = {
"cWUSDT",
"cWUSDC",
"cWEURC",
"cWEURT",
"cWGBPC",
"cWGBPT",
"cWAUDC",
"cWJPYC",
"cWCHFC",
"cWCADC",
"cWXAUC",
"cWXAUT",
}
gas_native_required = {
1: ["cWETH"],
10: ["cWETHL2"],
25: ["cWCRO"],
56: ["cWBNB"],
100: ["cWXDAI"],
137: ["cWPOL"],
1111: ["cWWEMIX"],
8453: ["cWETHL2"],
42161: ["cWETHL2"],
42220: ["cWCELO"],
43114: ["cWAVAX"],
}
network_names = {
1: "Ethereum Mainnet",
10: "Optimism",
25: "Cronos",
56: "BSC",
100: "Gnosis",
137: "Polygon",
1111: "Wemix",
8453: "Base",
42161: "Arbitrum One",
42220: "Celo",
43114: "Avalanche C-Chain",
}
def normalize_pair(pair: str) -> str:
return " / ".join(part.strip() for part in pair.split("/"))
chains = []
missing_pool_rows = []
missing_tokens_rows = []
live_pool_rows = []
for row in queue_json["chainQueue"]:
chain_id = row["chainId"]
network = row["name"]
planned = set(row["plannedWave1Pairs"])
recorded = set(row["recordedWave1Pairs"])
missing = sorted(planned - recorded)
live = sorted(recorded)
chain_status = deployment_status["chains"].get(str(chain_id), {})
actual_tokens = set((chain_status.get("cwTokens") or {}).keys())
missing_tokens = sorted(token for token in loaded_full_mesh_tokens if token not in actual_tokens)
missing_gas = [token for token in gas_native_required.get(chain_id, []) if token not in set((chain_status.get("gasMirrors") or {}).keys())]
chain_entry = {
"chain_id": chain_id,
"network": network,
"hub_stable": row["hubStable"],
"bridge_available": row["bridgeAvailable"],
"cw_token_count": row["cwTokenCount"],
"planned_wave1_pair_count": len(planned),
"recorded_live_pair_count": len(recorded),
"missing_wave1_pair_count": len(missing),
"live_wave1_pairs": live,
"missing_wave1_pairs": missing,
"missing_wrapped_tokens": missing_tokens,
"missing_gas_native_tokens": missing_gas,
"next_step": row["nextStep"],
}
chains.append(chain_entry)
for pair in missing:
missing_pool_rows.append(
{
"chain_id": chain_id,
"network": network,
"pair": pair,
"hub_stable": row["hubStable"],
"next_step": row["nextStep"],
}
)
for pair in live:
live_pool_rows.append(
{
"chain_id": chain_id,
"network": network,
"pair": pair,
"hub_stable": row["hubStable"],
}
)
for token in missing_tokens:
missing_tokens_rows.append(
{
"chain_id": chain_id,
"network": network,
"token": token,
"token_type": "wrapped_wave1",
}
)
for token in missing_gas:
missing_tokens_rows.append(
{
"chain_id": chain_id,
"network": network,
"token": token,
"token_type": "gas_native_public_mirror",
}
)
summary = {
"desired_public_evm_targets": queue_json["summary"]["desiredPublicEvmTargets"],
"chains_with_loaded_cw_suites": queue_json["summary"]["chainsWithLoadedCwSuites"],
"chains_missing_cw_suites": queue_json["summary"]["chainsMissingCwSuites"],
"first_tier_wave1_pools_planned": queue_json["summary"]["firstTierWave1PoolsPlanned"],
"first_tier_wave1_pools_recorded_live": queue_json["summary"]["firstTierWave1PoolsRecordedLive"],
"first_tier_wave1_pools_missing": queue_json["summary"]["firstTierWave1PoolsPlanned"] - queue_json["summary"]["firstTierWave1PoolsRecordedLive"],
"wave1_transport_pending_assets": queue_json["summary"]["wave1TransportPending"],
"missing_token_rows": len(missing_tokens_rows),
"networks_with_missing_tokens": len({row["network"] for row in missing_tokens_rows}),
}
result = {
"generated_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"description": "Canonical machine-readable GRU v2 public Wave 1 rollout gap report.",
"sources": [
"scripts/verify/check-gru-v2-deployment-queue.sh --json",
"cross-chain-pmm-lps/config/deployment-status.json",
"config/gru-v2-d3mm-network-expansion-plan.json",
"cross-chain-pmm-lps/config/pool-matrix.json",
],
"summary": summary,
"chains": sorted(chains, key=lambda item: item["chain_id"]),
"missing_first_tier_wave1_pools": sorted(missing_pool_rows, key=lambda item: (item["chain_id"], item["pair"])),
"live_first_tier_wave1_pools": sorted(live_pool_rows, key=lambda item: (item["chain_id"], item["pair"])),
"missing_tokens": sorted(missing_tokens_rows, key=lambda item: (item["chain_id"], item["token_type"], item["token"])),
}
output_path.write_text(json.dumps(result, indent=2) + "\n")
print(json.dumps(summary, indent=2))
PY
echo "Wrote ${OUTPUT_PATH}"

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
failures=0
check_file() {
local label="$1" path="$2"
if [[ -f "$path" ]]; then
echo "OK $label -> $path"
else
echo "MISS $label -> $path"
failures=1
fi
}
echo "=== GRU v2 core protocol blocker check ==="
check_file "138 DODO PMM mesh sync" "$PROJECT_ROOT/scripts/create-pmm-full-mesh-chain138.sh"
check_file "138 pilot protocol venue deployer" "$PROJECT_ROOT/scripts/deployment/deploy-chain138-pilot-protocol-venues.sh"
check_file "138 Aave execution stack deployer" "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh"
check_file "138 Aave quote-push receiver deployer" "$PROJECT_ROOT/scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh"
check_file "138 remaining protocol surface" "$PROJECT_ROOT/config/chain138-remaining-protocol-surface.json"
check_file "138 remaining protocol env verifier" "$PROJECT_ROOT/scripts/verify/check-chain138-remaining-protocol-env.sh"
check_file "651940 cA* token deployer" "$PROJECT_ROOT/scripts/deployment/deploy-allmainnet-ca-tokens.sh"
check_file "651940 PMM desired-state sync" "$PROJECT_ROOT/scripts/deployment/sync-allmainnet-pmm-pools-from-json.sh"
check_file "651940 cA* token catalog" "$PROJECT_ROOT/config/allmainnet-ca-token-catalog.json"
check_file "651940 PMM desired-state config" "$PROJECT_ROOT/config/allmainnet-pmm-pools.json"
check_file "GRU deployment implementation status doc" "$PROJECT_ROOT/docs/04-configuration/GRU_V2_FULL_DEPLOYMENT_IMPLEMENTATION_STATUS.md"
echo "--- remaining external blockers ---"
echo "INFO Chain 138 Aave still requires real CHAIN_138_AAVE_POOL / provider / data-provider addresses before the new deploy wrappers can be applied."
echo "INFO Chain 138 GMX and dYdX still require canonical live addresses and native protocol stacks."
echo "INFO Full venue completion for 651940 across Uniswap v2/v3, SushiSwap, Curve, Balancer, 1Inch, Aave, GMX, and dYdX still depends on live venue addresses, chain support, and liquidity."
echo "INFO 651940 PMM sync also requires live DODO integration/provider addresses and final deployed cA* token addresses."
exit "$failures"

View File

@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""Verify which parts of the GRU v2 full deployment plan are actually implemented in-repo."""
from __future__ import annotations
import json
from pathlib import Path
import sys
ROOT = Path(__file__).resolve().parents[2]
def exists(rel: str) -> bool:
return (ROOT / rel).exists()
def main() -> int:
checks = {
"chain138_mesh_sync": exists("scripts/create-pmm-full-mesh-chain138.sh"),
"chain138_next_steps_runner": exists("scripts/deployment/run-all-next-steps-chain138.sh"),
"chain138_readiness_check": exists("scripts/verify/check-gru-v2-chain138-readiness.sh"),
"gru_master_matrix": exists("docs/04-configuration/GRU_V2_FULL_MESH_MASTER_MATRIX.md"),
"gru_live_status_report": exists("docs/04-configuration/GRU_V2_FULL_MESH_LIVE_STATUS_REPORT.md"),
"gru_protocol_matrix": exists("docs/04-configuration/GRU_V2_PROTOCOL_COMPLETION_MATRIX.md"),
"gru_pool_tracker": exists("config/gru-v2-full-mesh-pool-tracker.json"),
"all_mainnet_token_inventory": exists("docs/11-references/ALL_MAINNET_TOKEN_ADDRESSES.md"),
"all_mainnet_full_cA_deployer": exists("scripts/deployment/deploy-allmainnet-ca-tokens.sh"),
"all_mainnet_full_mesh_deployer": exists("scripts/deployment/sync-allmainnet-pmm-pools-from-json.sh"),
"chain138_uniswap_curve_balancer_full_deployer": exists("scripts/deployment/deploy-chain138-pilot-protocol-venues.sh"),
"chain138_aave_execution_deployer": exists("scripts/deployment/deploy-chain138-aave-v3-execution-stack.sh"),
"chain138_aave_receiver_deployer": exists("scripts/deployment/deploy-chain138-aave-quote-push-receiver.sh"),
"chain138_remaining_protocol_inventory": exists("config/chain138-remaining-protocol-surface.json"),
"chain138_remaining_protocol_checker": exists("scripts/verify/check-chain138-remaining-protocol-env.sh"),
"all_mainnet_uniswap_curve_balancer_full_deployer": False,
}
missing_repo_backed = [
"all_mainnet_uniswap_curve_balancer_full_deployer",
]
report = {
"implemented": {k: v for k, v in checks.items() if v},
"missing_or_external_blocked": {k: checks[k] for k in missing_repo_backed if not checks[k]},
}
print(json.dumps(report, indent=2, sort_keys=True))
return 1 if any(not checks[k] for k in missing_repo_backed) else 0
if __name__ == "__main__":
sys.exit(main())

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python3
import csv
import json
import pathlib
import sys
ROOT = pathlib.Path("/home/intlc/projects/proxmox")
TRACKER = ROOT / "config/gru-v2-full-mesh-pool-tracker.json"
def main() -> None:
data = json.loads(TRACKER.read_text())
out = csv.writer(sys.stdout)
out.writerow(["namespace", "chain", "pair", "priority", "status"])
for row in data["chain138"]["entries"]:
out.writerow(["c* V2", "138", row["pair"], row.get("priority", ""), data["defaultFields"]["status"]])
for row in data["allMainnet651940"]["entries"]:
out.writerow(["cA*", "651940", row["pair"], row.get("priority", ""), data["defaultFields"]["status"]])
for chain, bucket in data["publicMesh"].items():
status = bucket.get("statusOverride", data["defaultFields"]["status"])
for pair in bucket["entries"]:
out.writerow(["cW*", chain, pair, "", status])
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,133 @@
{
"statusDate": "2026-04-14",
"namespaces": {
"chain138": "c* V2",
"allMainnet651940": "cA*",
"publicConnectedNetworks": "cW*"
},
"executionPhases": [
{
"id": "P0",
"namespace": "c* V2",
"scope": "Chain 138 canonical hub and Wave 1"
},
{
"id": "P1",
"namespace": "c* V2",
"scope": "Chain 138 cross-links and gas-native hubs"
},
{
"id": "P2",
"namespace": "cA*",
"scope": "ALL Mainnet canonical hub and Wave 1"
},
{
"id": "P3",
"namespace": "cA*",
"scope": "ALL Mainnet cross-links and gas-native hubs"
},
{
"id": "P4",
"namespace": "cW*",
"scope": "Public cW stable hub, Wave 1, and gas-native mesh"
},
{
"id": "P5",
"namespace": "all",
"scope": "Spot venue protocol completion"
},
{
"id": "P6",
"namespace": "all",
"scope": "Aggregator, reserve, and market protocol completion"
},
{
"id": "P7",
"namespace": "all",
"scope": "MEV completion"
}
],
"protocolsRequired": [
"DODO",
"Uniswap v3",
"Uniswap v2",
"SushiSwap",
"Curve",
"Balancer",
"1Inch",
"Aave",
"GMX",
"dYdX"
],
"chain138CanonicalPools": [
"cUSDT V2 / cUSDC V2",
"cUSDT V2 / USDT",
"cUSDC V2 / USDC",
"cEURC V2 / cUSDC V2",
"cEURT V2 / cUSDC V2",
"cGBPC V2 / cUSDC V2",
"cGBPT V2 / cUSDC V2",
"cAUDC V2 / cUSDC V2",
"cJPYC V2 / cUSDC V2",
"cCHFC V2 / cUSDC V2",
"cCADC V2 / cUSDC V2",
"cXAUC V2 / cUSDC V2",
"cXAUT V2 / cUSDC V2",
"cEURC V2 / cEURT V2",
"cGBPC V2 / cGBPT V2",
"cXAUC V2 / cXAUT V2",
"cETH / WETH",
"cETH / cUSDC V2",
"cETHL2 / cUSDC V2",
"cBNB / cUSDC V2",
"cPOL / cUSDC V2",
"cAVAX / cUSDC V2",
"cCRO / cUSDC V2",
"cXDAI / cUSDC V2",
"cCELO / cUSDC V2",
"cWEMIX / cUSDC V2"
],
"allMainnetCanonicalPools": [
"cAUSDT / cAUSDC",
"cAUSDT / AUSDT",
"cAUSDC / USDC",
"cAEURC / cAUSDC",
"cAEURT / cAUSDC",
"cAGBPC / cAUSDC",
"cAGBPT / cAUSDC",
"cAAUDC / cAUSDC",
"cAJPYC / cAUSDC",
"cACHFC / cAUSDC",
"cACADC / cAUSDC",
"cAXAUC / cAUSDC",
"cAXAUT / cAUSDC",
"cAEURC / cAEURT",
"cAGBPC / cAGBPT",
"cAXAUC / cAXAUT",
"cAETH / WETH",
"cAETH / cAUSDC",
"cAWALL / WALL",
"cAWALL / cAUSDC"
],
"publicMeshTemplate": {
"stableHub": [
"cWUSDT / USDC",
"cWUSDC / USDC",
"cWUSDT / USDT",
"cWUSDC / USDT",
"cWUSDT / cWUSDC"
],
"wave1VsUsdc": [
"cWEURC / USDC",
"cWEURT / USDC",
"cWGBPC / USDC",
"cWGBPT / USDC",
"cWAUDC / USDC",
"cWJPYC / USDC",
"cWCHFC / USDC",
"cWCADC / USDC",
"cWXAUC / USDC",
"cWXAUT / USDC"
]
}
}

View File

@@ -0,0 +1,169 @@
{
"statusDate": "2026-04-15",
"defaultFields": {
"status": "todo",
"deployed": false,
"seeded": false,
"validated": false,
"live": false,
"mevReady": false
},
"chain138": {
"namespace": "c* V2",
"entries": [
{ "pair": "cUSDT V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cUSDT V2 / USDT", "priority": "P0" },
{ "pair": "cUSDC V2 / USDC", "priority": "P0" },
{ "pair": "cEURC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cEURT V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cGBPC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cGBPT V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cAUDC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cJPYC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cCHFC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cCADC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cXAUC V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cXAUT V2 / cUSDC V2", "priority": "P0" },
{ "pair": "cEURC V2 / cEURT V2", "priority": "P1" },
{ "pair": "cGBPC V2 / cGBPT V2", "priority": "P1" },
{ "pair": "cXAUC V2 / cXAUT V2", "priority": "P1" },
{ "pair": "cETH / WETH", "priority": "P1" },
{ "pair": "cETH / cUSDC V2", "priority": "P1" },
{ "pair": "cETHL2 / cUSDC V2", "priority": "P2" },
{ "pair": "cBNB / cUSDC V2", "priority": "P2" },
{ "pair": "cPOL / cUSDC V2", "priority": "P2" },
{ "pair": "cAVAX / cUSDC V2", "priority": "P2" },
{ "pair": "cCRO / cUSDC V2", "priority": "P2" },
{ "pair": "cXDAI / cUSDC V2", "priority": "P2" },
{ "pair": "cCELO / cUSDC V2", "priority": "P2" },
{ "pair": "cWEMIX / cUSDC V2", "priority": "P2" }
]
},
"allMainnet651940": {
"namespace": "cA*",
"entries": [
{ "pair": "cAUSDT / cAUSDC", "priority": "P0" },
{ "pair": "cAUSDT / AUSDT", "priority": "P0" },
{ "pair": "cAUSDC / USDC", "priority": "P0" },
{ "pair": "cAEURC / cAUSDC", "priority": "P0" },
{ "pair": "cAEURT / cAUSDC", "priority": "P0" },
{ "pair": "cAGBPC / cAUSDC", "priority": "P0" },
{ "pair": "cAGBPT / cAUSDC", "priority": "P0" },
{ "pair": "cAAUDC / cAUSDC", "priority": "P0" },
{ "pair": "cAJPYC / cAUSDC", "priority": "P0" },
{ "pair": "cACHFC / cAUSDC", "priority": "P0" },
{ "pair": "cACADC / cAUSDC", "priority": "P0" },
{ "pair": "cAXAUC / cAUSDC", "priority": "P0" },
{ "pair": "cAXAUT / cAUSDC", "priority": "P0" },
{ "pair": "cAEURC / cAEURT", "priority": "P1" },
{ "pair": "cAGBPC / cAGBPT", "priority": "P1" },
{ "pair": "cAXAUC / cAXAUT", "priority": "P1" },
{ "pair": "cAETH / WETH", "priority": "P1" },
{ "pair": "cAETH / cAUSDC", "priority": "P1" },
{ "pair": "cAWALL / WALL", "priority": "P1" },
{ "pair": "cAWALL / cAUSDC", "priority": "P1" }
]
},
"publicMesh": {
"1": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWETH / WETH","cWETH / USDC"
]
},
"10": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWETHL2 / WETH","cWETHL2 / USDC"
]
},
"25": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWCRO / WCRO","cWCRO / USDT"
]
},
"56": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWBNB / WBNB","cWBNB / USDT"
]
},
"100": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWXDAI / WXDAI","cWXDAI / USDC"
]
},
"137": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWPOL / WPOL","cWPOL / USDC"
]
},
"8453": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWETHL2 / WETH","cWETHL2 / USDC"
]
},
"42161": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWETHL2 / WETH","cWETHL2 / USDC"
]
},
"42220": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWCELO / WCELO","cWCELO / USDC"
]
},
"43114": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWAVAX / WAVAX","cWAVAX / USDC"
]
},
"1111": {
"namespace": "cW*",
"entries": [
"cWUSDT / USDC","cWUSDC / USDC","cWUSDT / USDT","cWUSDC / USDT","cWUSDT / cWUSDC",
"cWEURC / USDC","cWEURT / USDC","cWGBPC / USDC","cWGBPT / USDC","cWAUDC / USDC",
"cWJPYC / USDC","cWCHFC / USDC","cWCADC / USDC","cWXAUC / USDC","cWXAUT / USDC",
"cWWEMIX / WWEMIX","cWWEMIX / USDC"
],
"statusOverride": "planned"
}
}
}

View File

@@ -0,0 +1,82 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://d-bis.org/schemas/gru-v2-full-mesh-pool-tracker.json",
"title": "GRU v2 Full Mesh Pool Tracker",
"type": "object",
"required": [
"statusDate",
"defaultFields",
"chain138",
"allMainnet651940",
"publicMesh"
],
"properties": {
"statusDate": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
},
"defaultFields": {
"type": "object",
"required": ["status", "deployed", "seeded", "validated", "live", "mevReady"],
"properties": {
"status": {
"type": "string",
"enum": ["todo", "in_progress", "blocked", "done"]
},
"deployed": { "type": "boolean" },
"seeded": { "type": "boolean" },
"validated": { "type": "boolean" },
"live": { "type": "boolean" },
"mevReady": { "type": "boolean" }
},
"additionalProperties": false
},
"chain138": { "$ref": "#/$defs/namedBucket" },
"allMainnet651940": { "$ref": "#/$defs/namedBucket" },
"publicMesh": {
"type": "object",
"minProperties": 1,
"additionalProperties": { "$ref": "#/$defs/meshBucket" }
}
},
"$defs": {
"pairEntry": {
"type": "object",
"required": ["pair"],
"properties": {
"pair": { "type": "string", "minLength": 3 },
"priority": { "type": "string", "minLength": 2 }
},
"additionalProperties": false
},
"namedBucket": {
"type": "object",
"required": ["namespace", "entries"],
"properties": {
"namespace": { "type": "string", "minLength": 2 },
"entries": {
"type": "array",
"items": { "$ref": "#/$defs/pairEntry" }
}
},
"additionalProperties": false
},
"meshBucket": {
"type": "object",
"required": ["namespace", "entries"],
"properties": {
"namespace": { "type": "string", "minLength": 2 },
"entries": {
"type": "array",
"items": { "type": "string", "minLength": 3 }
},
"statusOverride": {
"type": "string",
"enum": ["planned", "todo", "in_progress", "blocked", "done"]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}