16 Commits

Author SHA1 Message Date
defiQUG
dcf33187ea chore: refresh deployment-status.json
All checks were successful
Validate capital efficiency / validate (push) Successful in 37s
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-10 12:56:30 -07:00
defiQUG
f8593b905f chore(config): deployment-status + Solana pool matrix refresh
All checks were successful
Validate capital efficiency / validate (push) Successful in 51s
Made-with: Cursor
2026-04-28 04:23:53 -07:00
defiQUG
858353ffff ci(gitea): validate capital-efficiency gate on push/PR
All checks were successful
Validate capital efficiency / validate (push) Successful in 44s
Made-with: Cursor
2026-04-28 01:24:25 -07:00
defiQUG
656ce38a0b docs: proxmox origin/gitea parity required before audit submission
Made-with: Cursor
2026-04-28 01:18:39 -07:00
defiQUG
88d45e9978 docs(capital-efficiency): intake ready; submission tables + policy auditIntakeSubmission
Register blocker shift to submission/engagement pending; add signedEngagement placeholders.

Made-with: Cursor
2026-04-27 23:12:57 -07:00
defiQUG
365fcf8e94 Record audit intake path 2026-04-27 21:57:56 -07:00
defiQUG
fb4d86ae38 Clear local capital efficiency simulation gates 2026-04-27 15:58:17 -07:00
defiQUG
818e864d2b Add capital efficiency risk simulation 2026-04-27 11:26:55 -07:00
defiQUG
1cf845cb3a chore: refresh deployment status for live gas pools 2026-04-24 12:52:49 -07:00
defiQUG
68647ff4d4 chore: update deployment-status and validate-deployment-status
Made-with: Cursor
2026-04-21 22:00:54 -07:00
defiQUG
5aa162e6b3 chore: refresh deployment status and solana policies 2026-04-18 12:05:17 -07:00
defiQUG
0b089f1181 Enforce native protocol inventory rules 2026-04-14 07:13:17 -07:00
defiQUG
24119f8a6e chore(policy): peg-bands gruPolicyIntegration + GRU reference primacy cross-links
- Add gruPolicyIntegration block (referencePrimacyDoc, meshExecutionRole) to peg-bands.json
- Document parent-repo policy and CI verifier in README, bot policy, and oracles doc

Made-with: Cursor
2026-04-13 03:12:45 -07:00
defiQUG
198da72977 chore(sim): update deployment status with new pool configuration and date
- Updated the 'updated' field to reflect the new date.
- Added a new public routing pool configuration for cWUSDT/cWUSDC.

Made-with: Cursor
2026-04-10 12:52:33 -07:00
defiQUG
168dba25d9 chore(sim): refresh deployment status, pool matrix, schemas, and scenario scripts
- deployment-status and pool-matrix snapshots aligned with validate-deployment-status.cjs.
- Micro-trade / scorecard docs and run-scenario wiring.

Made-with: Cursor
2026-04-07 22:56:16 -07:00
defiQUG
f7f3e3b020 chore(sim): gas-budgeted micro-trade scenario and support doc
Made-with: Cursor
2026-04-07 22:45:56 -07:00
34 changed files with 5651 additions and 266 deletions

View File

@@ -0,0 +1,22 @@
# Simulation/docs repo — no dedicated hosting VM; CI validates policy + scenarios.
name: Validate capital efficiency
on:
push:
branches: [main]
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Run capital-efficiency validation gate
run: node scripts/validate-capital-efficiency.cjs

View File

@@ -8,17 +8,21 @@ Implementation-grade blueprint for the **home-minted M1 suite on ChainID 138**,
- **Pool topology**: Single-sided PMM edge pools per chain (`cW* / HUB` or multi-quote).
- **Bot-driven mesh**: Deviation watcher, inventory re-centering, cross-pool routing, bridge-aware throttling; peg bands; oracles; mesh reflexivity controls.
**GRU policy integration (reference primacy):** this mesh is an **execution and capacity layer** for agreed peg bands and oracles — not an independent FX discovery layer for GRU/XDR. Parent canonical: [docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md](../docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md).
## Quick start
1. See [docs/01-token-map.md](docs/01-token-map.md) for canonical and cW* token mapping.
2. See [docs/02-pool-topology.md](docs/02-pool-topology.md) for edge pool design.
3. See [docs/06-deployment-recipe.md](docs/06-deployment-recipe.md) for step-by-step deployment.
4. Config: [config/token-map.json](config/token-map.json), [config/pool-matrix.json](config/pool-matrix.json), [config/peg-bands.json](config/peg-bands.json), [config/chains.json](config/chains.json).
5. **Simulation:** Two-layer model (design vs deployed graph), routing supergraph, PMM edge function, and scenario-based sim: [docs/08-simulation-model.md](docs/08-simulation-model.md). First-pass params: [config/simulation-params.json](config/simulation-params.json), [docs/09-simulation-params-sheet.md](docs/09-simulation-params-sheet.md). Deployment-realistic sim: fill [config/deployment-status.json](config/deployment-status.json).
5. **Simulation:** Two-layer model (design vs deployed graph), routing supergraph, PMM edge function, and scenario-based sim: [docs/08-simulation-model.md](docs/08-simulation-model.md). First-pass params: [config/simulation-params.json](config/simulation-params.json), [docs/09-simulation-params-sheet.md](docs/09-simulation-params-sheet.md). Deployment-realistic sim: fill [config/deployment-status.json](config/deployment-status.json). **Hub stable pools** (`cW*/USDC`, `cW*/USDT`) live in `pmmPools[]`. **Volatile cWUSD\* vs TRUU** (mainnet) use `anchorAddresses.TRUU` plus `pmmPoolsVolatile[]` (runbook `docs/03-deployment/MAINNET_PMM_TRUU_CWUSD_PEG_AND_BOT_RUNBOOK.md` §11; parent scripts `deploy-mainnet-pmm-cw-truu-pool.sh`, `add-mainnet-truu-pmm-topup.sh`).
6. **Behavioral stability:** What to simulate first, three metrics in economic terms, where it can break: [docs/10-behavioral-stability-analysis.md](docs/10-behavioral-stability-analysis.md). **Safe inventory sizing** (closed-form I_T^* per chain): [docs/11-safe-inventory-sizing.md](docs/11-safe-inventory-sizing.md).
7. **Tools:** [scripts/size-inventory.cjs](scripts/size-inventory.cjs) — regenerate I_T^*, D_0 from params (single command, deterministic; see [scripts/README.md](scripts/README.md)). [scripts/validate-deployment-status.cjs](scripts/validate-deployment-status.cjs) — CI validation for deployment-status (phase 1 tokens when bridge=true; pool role/fee/k/tokens).
8. **Sim scorecard:** Simulator output contract and pass/fail gates: [docs/12-sim-scorecard.md](docs/12-sim-scorecard.md), [config/scorecard-schema.json](config/scorecard-schema.json). Bridge edge with optional **latency risk** ρ(Δt): [docs/08-simulation-model.md](docs/08-simulation-model.md) §2.
9. **Scenario contract:** Formal scenario input schema and three Phase 0 scenarios: [config/scenario-schema.json](config/scenario-schema.json), [config/scenarios/](config/scenarios/). **Routing exposure controls:** [config/routing-controls.json](config/routing-controls.json) (maxTradeSize, cooldown, minImprovementBps, publicRoutingEnabled). **Real sim (PR#1):** `node scripts/run-scenario.cjs hub_only_11` — graph from configs, PMM state, path enumeration + waterfilling, real scorecard (drain half-life, path concentration, capture, churn); see [spec/13-minimal-router-sim.md](spec/13-minimal-router-sim.md).
10. **USD-wrapper support lane:** Gas-budgeted micro-trade policy for `cWUSDC` / `cWUSDT` and a runnable scenario: [docs/15-gas-budgeted-micro-trade-support.md](docs/15-gas-budgeted-micro-trade-support.md), [config/scenarios/micro_support_usd_wrappers_1_56_137.json](config/scenarios/micro_support_usd_wrappers_1_56_137.json).
11. **Capital efficiency risk simulation:** Simulation-only Monte Carlo overlay for treasury allocation, leverage, peg pressure, volatility throttles, liquidation probability, and parameter optimization: [docs/16-capital-efficiency-risk-simulation.md](docs/16-capital-efficiency-risk-simulation.md), [docs/17-capital-efficiency-contract-blueprint-gate.md](docs/17-capital-efficiency-contract-blueprint-gate.md), [docs/18-capital-efficiency-risk-dashboard-and-runbook.md](docs/18-capital-efficiency-risk-dashboard-and-runbook.md), [docs/19-capital-efficiency-external-approval-evidence.md](docs/19-capital-efficiency-external-approval-evidence.md), [config/capital-efficiency-policy.json](config/capital-efficiency-policy.json), [config/treasury-liquidity-commitments.json](config/treasury-liquidity-commitments.json), stress scenarios under [config/scenarios/](config/scenarios/), and CI-style validation via `node scripts/validate-capital-efficiency.cjs`.
## Parent repo

View File

@@ -0,0 +1,107 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Simulation-only capital efficiency policy for Chain 138/cW PMM treasury risk modeling. This is not a live leverage or mint/redemption contract configuration.",
"version": "1.0.0",
"updated": "2026-04-28",
"defaults": {
"paths": 1000,
"epochs": 365,
"seed": 138001,
"initialCapital": 1000000,
"alpha": 0.7,
"leverage": 2,
"spreadBps": 35,
"volumeEfficiency": 2,
"pmmK": 0.1,
"liquidityTargetUnits": 1000000
},
"parameterBands": {
"alphaBalanced": [0.65, 0.75],
"alphaYieldDominant": [0.75, 0.9],
"leverageSafe": [1, 1],
"leverageStressDeployable": [1, 1.5],
"leverageTarget": [2, 3],
"leverageUnstableAbove": 4,
"spreadCompetitiveBps": 10,
"spreadTargetBps": [30, 50],
"spreadVolumeRiskCeilingBps": 100,
"volumeEfficiencyPassive": 1,
"volumeEfficiencyActive": [2, 4],
"volumeEfficiencyHighlyOptimizedAbove": 5
},
"treasury": {
"yieldRatePerEpoch": 0.00035,
"volatilityDragLambda": 0.35,
"marketMakingScale": 0.04
},
"volatilityProcess": {
"sigma0": 0.03,
"sigmaBar": 0.03,
"kappa": 0.08,
"eta": 0.01
},
"pegDynamics": {
"p0": 1,
"beta": 0.25,
"imbalanceStd": 0.01,
"arbLiquidityCoefficient": 0.65
},
"risk": {
"minExternalLiquidityPct": 0.2,
"maxLtvBps": 6500,
"hardMaxLtvBps": 7500,
"liquidationLtvBps": 8000,
"hardMaxLeverage": 4,
"liquidationLossFraction": 0.08,
"sigmaCrit": 0.08,
"throttleLeverageMultiplier": 0.7,
"throttleAlphaMultiplier": 0.9,
"throttleSpreadBps": 50,
"maxSpreadBps": 100,
"circuitBreakerSpreadBps": 100,
"pegCircuitBreakerBps": 200,
"collateralVolatilityHaircut": 0.5,
"bankRunRedemptionFeeBps": 100
},
"gates": {
"maxDeployableLeverage": 1.5,
"maxLiquidationProbability": 0.02,
"maxDrawdownP95": 0.25,
"maxPegDeviationFrequency": 0.05,
"maxExternalLiquidityFloorViolations": 0
},
"optimizer": {
"paths": 250,
"maxCandidates": 250,
"topN": 10
},
"liveExecutionGuard": {
"status": "simulation_only",
"requiresBeforeContractWork": [
"smart_contract_audit_engagement",
"governance_approval",
"risk_dashboard",
"operator_runbook",
"treasury_liquidity_commitments"
],
"auditEngagementEvidence": null,
"auditIntakeUrl": "https://cybersecur.d-bis.org/intake.html",
"auditIntakeSubmission": {
"submittedAt": null,
"receiptOrReference": null,
"contactEmail": null,
"auditFirm": null,
"evidenceDoc": "docs/19-capital-efficiency-external-approval-evidence.md"
},
"signedEngagement": {
"firm": null,
"engagementReference": null,
"signedAt": null,
"finalScopeSummary": null
},
"governanceApprovalEvidence": null,
"riskDashboardEvidence": "docs/18-capital-efficiency-risk-dashboard-and-runbook.md",
"operatorRunbookEvidence": "docs/18-capital-efficiency-risk-dashboard-and-runbook.md",
"treasuryLiquidityCommitmentEvidence": "config/treasury-liquidity-commitments.json"
}
}

View File

@@ -1,8 +1,20 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Public chain IDs and hub stable per chain for cW* edge pools.",
"version": "1.0.0",
"updated": "2026-02-26",
"description": "Public chain IDs and hub stable per chain for cW* edge pools (EVM). Non-EVM networks used for interoperability are listed under nonEvm (no EIP-155 id) with their own execution/oracle topology references.",
"version": "1.2.0",
"updated": "2026-04-17",
"nonEvm": [
{
"identifier": "Solana",
"vmKind": "SVM",
"caip2": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"hubStableNote": "Primary Solana hubs are SPL USDC then SPL USDT; deep liquidity and single-sided edge pools are defined in the dedicated Solana configs rather than the EVM DODO PMM matrix.",
"adapter": "SolanaAdapter",
"liquidityMode": "non_evm_deep_plus_single_sided_edge",
"oraclePolicy": "cross-chain-pmm-lps/config/solana-oracle-policy.json",
"poolMatrix": "cross-chain-pmm-lps/config/solana-pool-matrix.json"
}
],
"chains": [
{ "chainId": 1, "name": "Ethereum Mainnet", "hubStable": "USDC" },
{ "chainId": 10, "name": "Optimism", "hubStable": "USDC" },

File diff suppressed because it is too large Load Diff

View File

@@ -23,5 +23,10 @@
"eurUsesEurUsdFeed": true,
"stalenessWidenBands": true,
"stalenessPauseTrades": true
},
"gruPolicyIntegration": {
"referencePrimacyDoc": "docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md",
"meshExecutionRole": "public_pmm_corridor_implementation",
"summary": "Peg bands and oracle settings bound bot behavior against external references; they do not define GRU/XDR/XAU policy. Parent-repo CI verifies this block via scripts/verify/check-gru-reference-primacy-integration.sh."
}
}

View File

@@ -1 +1,317 @@
{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Per-chain pool matrix: which cW* / stable pools to deploy. Single-sided on cW* side.","version":"1.0.0","updated":"2026-02-27","cwTokens":["cWUSDT","cWUSDC","cWAUSDT","cWEURC","cWEURT","cWUSDW"],"strategy":"hub_first","chains":{"1":{"name":"Ethereum Mainnet","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC","cWAUSDT/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDT/DAI","cWUSDC/USDT","cWUSDC/DAI"]},"56":{"name":"BSC","hubStable":"USDT","poolsFirst":["cWUSDT/USDT","cWUSDC/USDT","cWAUSDT/USDT","cWEURC/USDT","cWEURT/USDT","cWUSDW/USDT"],"poolsOptional":["cWUSDT/USDC","cWUSDT/BUSD","cWUSDC/USDC","cWUSDC/BUSD"]},"137":{"name":"Polygon","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"10":{"name":"Optimism","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"100":{"name":"Gnosis","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDT/mUSD","cWUSDC/mUSD"]},"25":{"name":"Cronos","hubStable":"USDT","poolsFirst":["cWUSDT/USDT","cWUSDC/USDT","cWAUSDT/USDT","cWEURC/USDT","cWEURT/USDT","cWUSDW/USDT"],"poolsOptional":["cWUSDT/USDC","cWUSDT/BUSD","cWUSDC/USDC","cWUSDC/BUSD"]},"42220":{"name":"Celo","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"43114":{"name":"Avalanche C-Chain","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"42161":{"name":"Arbitrum One","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"8453":{"name":"Base","hubStable":"USDC","poolsFirst":["cWUSDT/USDC","cWUSDC/USDC","cWAUSDT/USDC","cWEURC/USDC","cWEURT/USDC","cWUSDW/USDC"],"poolsOptional":["cWUSDT/USDT","cWUSDC/USDT","cWUSDT/DAI","cWUSDC/DAI"]},"1111":{"name":"Wemix","hubStable":"USDT","poolsFirst":["cWUSDT/USDT","cWUSDC/USDT","cWAUSDT/USDT","cWEURC/USDT","cWEURT/USDT","cWUSDW/USDT"],"poolsOptional":["cWUSDT/USDC","cWUSDT/BUSD","cWUSDC/USDC","cWUSDC/BUSD"]}},"liquiditySizingTargets":{}}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Per-chain pool matrix: which cW* / stable pools to deploy. Single-sided on cW* side.",
"version": "1.1.0",
"updated": "2026-04-03",
"cwTokens": [
"cWUSDT",
"cWUSDC",
"cWAUSDT",
"cWEURC",
"cWEURT",
"cWUSDW",
"cWGBPC",
"cWGBPT",
"cWAUDC",
"cWJPYC",
"cWCHFC",
"cWCADC",
"cWXAUC",
"cWXAUT"
],
"strategy": "hub_first",
"notes": [
"The first-tier public cW matrix now covers the full GRU Wave 1 wrapped set in addition to the older USD/AUSDT/USDW lanes.",
"This file is a deployment plan, not proof of live liquidity. Live pool addresses still belong in cross-chain-pmm-lps/config/deployment-status.json."
],
"chains": {
"1": {
"name": "Ethereum Mainnet",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDT/DAI",
"cWUSDC/USDT",
"cWUSDC/DAI"
]
},
"56": {
"name": "BSC",
"hubStable": "USDT",
"poolsFirst": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWEURC/USDT",
"cWEURT/USDT",
"cWGBPC/USDT",
"cWGBPT/USDT",
"cWAUDC/USDT",
"cWJPYC/USDT",
"cWCHFC/USDT",
"cWCADC/USDT",
"cWXAUC/USDT",
"cWXAUT/USDT",
"cWUSDW/USDT",
"cWAUSDT/USDT"
],
"poolsOptional": [
"cWUSDT/USDC",
"cWUSDT/BUSD",
"cWUSDC/USDC",
"cWUSDC/BUSD"
]
},
"137": {
"name": "Polygon",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"10": {
"name": "Optimism",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"100": {
"name": "Gnosis",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDT/mUSD",
"cWUSDC/mUSD"
]
},
"25": {
"name": "Cronos",
"hubStable": "USDT",
"poolsFirst": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWEURC/USDT",
"cWEURT/USDT",
"cWGBPC/USDT",
"cWGBPT/USDT",
"cWAUDC/USDT",
"cWJPYC/USDT",
"cWCHFC/USDT",
"cWCADC/USDT",
"cWXAUC/USDT",
"cWXAUT/USDT",
"cWUSDW/USDT",
"cWAUSDT/USDT"
],
"poolsOptional": [
"cWUSDT/USDC",
"cWUSDT/BUSD",
"cWUSDC/USDC",
"cWUSDC/BUSD"
]
},
"42220": {
"name": "Celo",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"43114": {
"name": "Avalanche C-Chain",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"42161": {
"name": "Arbitrum One",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"8453": {
"name": "Base",
"hubStable": "USDC",
"poolsFirst": [
"cWUSDT/USDC",
"cWUSDC/USDC",
"cWEURC/USDC",
"cWEURT/USDC",
"cWGBPC/USDC",
"cWGBPT/USDC",
"cWAUDC/USDC",
"cWJPYC/USDC",
"cWCHFC/USDC",
"cWCADC/USDC",
"cWXAUC/USDC",
"cWXAUT/USDC",
"cWUSDW/USDC",
"cWAUSDT/USDC"
],
"poolsOptional": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWUSDT/DAI",
"cWUSDC/DAI"
]
},
"1111": {
"name": "Wemix",
"hubStable": "USDT",
"poolsFirst": [
"cWUSDT/USDT",
"cWUSDC/USDT",
"cWEURC/USDT",
"cWEURT/USDT",
"cWGBPC/USDT",
"cWGBPT/USDT",
"cWAUDC/USDT",
"cWJPYC/USDT",
"cWCHFC/USDT",
"cWCADC/USDT",
"cWXAUC/USDT",
"cWXAUT/USDT",
"cWUSDW/USDT",
"cWAUSDT/USDT"
],
"poolsOptional": [
"cWUSDT/USDC",
"cWUSDT/BUSD",
"cWUSDC/USDC",
"cWUSDC/BUSD"
]
}
},
"liquiditySizingTargets": {}
}

View File

@@ -135,9 +135,147 @@
}
}
},
"microTradePolicy": {
"type": "object",
"description": "Optional gas-budgeted support trades for selected cW wrappers. Use to model tiny corrective or turnover-seeding trades without turning the PMM into a venue.",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"tokens": {
"type": "array",
"items": {
"type": "string"
},
"description": "Base cW tokens to support, e.g. [\"cWUSDT\", \"cWUSDC\"]"
},
"quoteTokens": {
"type": "array",
"items": {
"type": "string"
},
"description": "Allowed quote stables for the support lane, e.g. [\"USDT\", \"USDC\"]"
},
"preferMatchedQuote": {
"type": "boolean",
"default": true,
"description": "Prefer cWUSDT/USDT and cWUSDC/USDC when those rails exist; otherwise fall back to another allowed quote."
},
"mode": {
"type": "string",
"enum": [
"inventory",
"alternate",
"inventory_or_alternate",
"buy_base",
"sell_base"
],
"default": "inventory_or_alternate",
"description": "inventory = only trade when pool inventory leaves the band; alternate = buy/sell flip-flop; inventory_or_alternate = inventory-corrective first, alternate only inside band."
},
"tradeSizeUnits": {
"type": "number",
"minimum": 0,
"description": "Nominal base-token size per support trade."
},
"tradesPerEpoch": {
"type": "integer",
"minimum": 0,
"description": "Requested support trades per epoch before gas-budget clipping."
},
"gasCostPerTradeUnits": {
"type": "number",
"minimum": 0,
"description": "Abstract gas cost per trade for scenario comparison; not chain-native gas units."
},
"gasBudgetPerEpochUnits": {
"type": "number",
"minimum": 0,
"description": "Per-epoch gas budget for support trades. Maximum trades = floor(budget / gasCostPerTradeUnits) when gasCostPerTradeUnits > 0."
},
"inventoryBandFraction": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.05,
"description": "Keep support trades inventory-aware within +/- this fraction of I_T^* before alternating."
},
"maxFractionOfTarget": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.01,
"description": "Clamp each support trade to this fraction of I_T^*."
}
}
},
"seed": {
"type": "integer",
"description": "Optional RNG seed for deterministic runs; if omitted, derived from scenario name"
},
"capitalEfficiency": {
"type": "object",
"description": "Optional simulation-only treasury/risk Monte Carlo overlay. Does not configure live contracts.",
"properties": {
"enabled": { "type": "boolean", "default": false },
"paths": { "type": "integer", "minimum": 1 },
"epochs": { "type": "integer", "minimum": 1 },
"seed": { "type": "integer" },
"initialCapital": { "type": "number", "minimum": 0 },
"alpha": { "type": "number", "minimum": 0, "maximum": 1 },
"leverage": { "type": "number", "minimum": 1 },
"spreadBps": { "type": "number", "minimum": 0 },
"volumeEfficiency": { "type": "number", "minimum": 0 },
"pmmK": { "type": "number", "minimum": 0 },
"liquidityTargetUnits": { "type": "number", "minimum": 0 },
"treasury": { "type": "object" },
"volatilityProcess": {
"type": "object",
"properties": {
"sigma0": { "type": "number", "minimum": 0 },
"sigmaBar": { "type": "number", "minimum": 0 },
"kappa": { "type": "number", "minimum": 0 },
"eta": { "type": "number", "minimum": 0 }
}
},
"pegDynamics": {
"type": "object",
"properties": {
"p0": { "type": "number" },
"beta": { "type": "number" },
"imbalanceStd": { "type": "number", "minimum": 0 },
"arbLiquidityCoefficient": { "type": "number", "minimum": 0 }
}
},
"risk": { "type": "object" },
"stress": {
"type": "object",
"properties": {
"preset": {
"type": "string",
"enum": ["crash_40pct_external_asset", "high_vol_sigma_spike", "bank_run_redemption_spike", "bridge_shock"]
},
"epoch": { "type": "integer", "minimum": 0 },
"durationEpochs": { "type": "integer", "minimum": 1 },
"externalAssetReturn": { "type": "number" },
"sigmaAdd": { "type": "number" },
"redemptionFraction": { "type": "number", "minimum": 0 },
"imbalanceAdd": { "type": "number" },
"events": { "type": "array", "items": { "type": "object" } }
}
},
"optimizer": {
"type": "object",
"properties": {
"enabled": { "type": "boolean", "default": false },
"paths": { "type": "integer", "minimum": 1 },
"topN": { "type": "integer", "minimum": 1 },
"maxCandidates": { "type": "integer", "minimum": 1 },
"grid": { "type": "object" }
}
}
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
{
"scenario": "bank_run_redemption_spike",
"graphMode": "design",
"topology": "hub",
"chainsIncluded": ["1", "56", "137"],
"tokensIncluded": ["cWUSDT", "cWUSDC"],
"epochBlocks": 300,
"epochs": 180,
"orderflowModel": {
"distribution": "pareto",
"volumeMinUnits": 2500,
"volumeMaxUnits": 80000,
"tradesPerEpoch": 25,
"paretoAlpha": 1.8
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
},
"capitalEfficiency": {
"enabled": true,
"paths": 1000,
"epochs": 180,
"seed": 138403,
"initialCapital": 1000000,
"alpha": 0.65,
"leverage": 1.5,
"spreadBps": 45,
"volumeEfficiency": 2.5,
"stress": {
"preset": "bank_run_redemption_spike",
"epoch": 30,
"durationEpochs": 12,
"redemptionFraction": 0.25
}
}
}

View File

@@ -0,0 +1,31 @@
{
"scenario": "chain138_deployed_capital_efficiency",
"graphMode": "deployed",
"topology": "hub",
"chainsIncluded": ["138"],
"tokensIncluded": ["cUSDT", "cUSDC", "cEURC", "cEURT", "cXAUC", "cXAUT"],
"epochBlocks": 300,
"epochs": 120,
"orderflowModel": {
"distribution": "uniform",
"volumeMinUnits": 1000,
"volumeMaxUnits": 25000,
"tradesPerEpoch": 12
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
},
"capitalEfficiency": {
"enabled": true,
"paths": 500,
"epochs": 120,
"seed": 138405,
"initialCapital": 1000000,
"alpha": 0.7,
"leverage": 2,
"spreadBps": 35,
"volumeEfficiency": 2
}
}

View File

@@ -0,0 +1,35 @@
{
"scenario": "crash_40pct_external_asset",
"graphMode": "design",
"topology": "hub",
"chainsIncluded": ["1", "56", "137"],
"tokensIncluded": ["cWUSDT", "cWUSDC"],
"epochBlocks": 300,
"epochs": 180,
"orderflowModel": {
"distribution": "uniform",
"volumeMinUnits": 5000,
"volumeMaxUnits": 30000,
"tradesPerEpoch": 15
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
},
"capitalEfficiency": {
"enabled": true,
"paths": 1000,
"epochs": 180,
"seed": 138401,
"initialCapital": 1000000,
"alpha": 0.65,
"leverage": 1.5,
"spreadBps": 40,
"volumeEfficiency": 2.5,
"stress": {
"preset": "crash_40pct_external_asset",
"epoch": 30
}
}
}

View File

@@ -0,0 +1,37 @@
{
"scenario": "high_vol_sigma_spike",
"graphMode": "design",
"topology": "hub",
"chainsIncluded": ["1", "56", "137"],
"tokensIncluded": ["cWUSDT", "cWUSDC"],
"epochBlocks": 300,
"epochs": 180,
"orderflowModel": {
"distribution": "lognormal",
"volumeMinUnits": 1000,
"volumeMaxUnits": 60000,
"tradesPerEpoch": 20
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
},
"capitalEfficiency": {
"enabled": true,
"paths": 1000,
"epochs": 180,
"seed": 138402,
"initialCapital": 1000000,
"alpha": 0.65,
"leverage": 1.5,
"spreadBps": 40,
"volumeEfficiency": 3,
"stress": {
"preset": "high_vol_sigma_spike",
"epoch": 30,
"durationEpochs": 36,
"sigmaAdd": 0.08
}
}
}

View File

@@ -0,0 +1,43 @@
{
"scenario": "leverage_sweep_1x_to_4x",
"graphMode": "design",
"topology": "hub",
"chainsIncluded": ["1", "56", "137"],
"tokensIncluded": ["cWUSDT", "cWUSDC"],
"epochBlocks": 300,
"epochs": 180,
"orderflowModel": {
"distribution": "uniform",
"volumeMinUnits": 5000,
"volumeMaxUnits": 30000,
"tradesPerEpoch": 15
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
},
"capitalEfficiency": {
"enabled": true,
"paths": 1000,
"epochs": 180,
"seed": 138404,
"initialCapital": 1000000,
"alpha": 0.7,
"leverage": 2,
"spreadBps": 40,
"volumeEfficiency": 2.5,
"optimizer": {
"enabled": true,
"paths": 250,
"topN": 12,
"grid": {
"alpha": [0.65, 0.7, 0.75, 0.8],
"leverage": [1, 1.25, 1.5, 2, 2.5, 3, 3.5, 4],
"spreadBps": [30, 40, 50],
"pmmK": [0.1, 0.15],
"liquidityTargetUnits": [500000, 1000000]
}
}
}
}

View File

@@ -0,0 +1,33 @@
{
"scenario": "micro_support_usd_wrappers_1_56_137",
"graphMode": "design",
"topology": "full_quote",
"chainsIncluded": ["1", "56", "137"],
"tokensIncluded": ["cWUSDT", "cWUSDC"],
"epochBlocks": 300,
"epochs": 720,
"orderflowModel": {
"distribution": "uniform",
"volumeMinUnits": 1000,
"volumeMaxUnits": 80000,
"tradesPerEpoch": 35
},
"microTradePolicy": {
"enabled": true,
"tokens": ["cWUSDT", "cWUSDC"],
"quoteTokens": ["USDT", "USDC"],
"preferMatchedQuote": true,
"mode": "inventory_or_alternate",
"tradeSizeUnits": 250,
"tradesPerEpoch": 8,
"gasCostPerTradeUnits": 2,
"gasBudgetPerEpochUnits": 16,
"inventoryBandFraction": 0.05,
"maxFractionOfTarget": 0.0025
},
"oracleModel": "static",
"latencyModel": {
"finalityBlocksPerChainPair": {},
"rhoPerBlockBps": 0.5
}
}

View File

@@ -114,6 +114,29 @@
}
}
},
"micro_trade_count": {
"type": "integer",
"minimum": 0,
"description": "Count of support-lane micro-trades executed during the run"
},
"micro_trade_buy_count": {
"type": "integer",
"minimum": 0
},
"micro_trade_sell_count": {
"type": "integer",
"minimum": 0
},
"micro_trade_volume_total": {
"type": "number",
"minimum": 0,
"description": "Base-token units traded through the support lane"
},
"micro_trade_gas_cost_total": {
"type": "number",
"minimum": 0,
"description": "Abstract gas budget consumed by support trades"
},
"worst_pool_diagnostic": {
"type": "object",
"description": "Last-epoch worst pool at pre_arb, post_arb, post_bot",
@@ -146,6 +169,36 @@
}
}
}
}
},
"capital_efficiency_enabled": {
"type": "boolean",
"description": "True when the simulation-only capital efficiency Monte Carlo overlay was run"
},
"capital_efficiency_paths": { "type": "integer", "minimum": 1 },
"capital_efficiency_epochs": { "type": "integer", "minimum": 1 },
"initial_capital": { "type": "number", "minimum": 0 },
"alpha": { "type": "number", "minimum": 0, "maximum": 1 },
"leverage": { "type": "number", "minimum": 1 },
"spread_bps": { "type": "number", "minimum": 0 },
"volume_efficiency": { "type": "number", "minimum": 0 },
"pmm_k": { "type": "number", "minimum": 0 },
"liquidity_target_units": { "type": "number", "minimum": 0 },
"roi_mean": { "type": "number" },
"roi_p05": { "type": "number" },
"roi_p95": { "type": "number" },
"pnl_distribution": {
"type": "object",
"properties": {
"p05": { "type": "number" },
"p50": { "type": "number" },
"p95": { "type": "number" }
}
},
"max_drawdown_p95": { "type": "number", "minimum": 0 },
"liquidation_probability": { "type": "number", "minimum": 0, "maximum": 1 },
"peg_deviation_frequency": { "type": "number", "minimum": 0, "maximum": 1 },
"external_liquidity_floor_violations": { "type": "integer", "minimum": 0 },
"volatility_throttle_events": { "type": "integer", "minimum": 0 },
"spread_adjustment_events": { "type": "integer", "minimum": 0 }
}
}
}

View File

@@ -0,0 +1,149 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Solana execution-oracle policy for the GRU v2 launch set bridged from Chain 138. Reference primacy remains upstream of public execution pools.",
"version": "1.0.0",
"updated": "2026-04-17",
"references": {
"referencePrimacyDoc": "docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md",
"solanaRuntimeConfig": "config/solana-relay-runtime.json",
"lineupManifest": "config/solana-gru-bridge-lineup.json"
},
"hubStables": {
"primary": {
"symbol": "USDC",
"mintEnv": "SOLANA_HUB_USDC_MINT",
"mintFallback": "operator_fill_before_pool_deploy",
"role": "deep_and_edge_primary_quote"
},
"secondary": {
"symbol": "USDT",
"mintEnv": "SOLANA_HUB_USDT_MINT",
"mintFallback": "operator_fill_before_secondary_pool_deploy",
"role": "overflow_quote_and_route_diversifier"
}
},
"oracleClasses": {
"weth_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 30,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_eth_usd",
"chain138_wrapper_parity_eth_usd",
"svm_market_sanity_eth_usd"
]
},
"usd_parity": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 60,
"maxExecutionDeviationBps": 25,
"pauseOnStale": true,
"sources": [
"gru_reference_service_usd_parity",
"chain138_canonical_reserve_parity",
"svm_market_sanity_stable_usd"
]
},
"eur_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_eur_usd",
"chain138_canonical_eur_usd",
"institutional_fx_backup_eur_usd"
]
},
"gbp_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_gbp_usd",
"chain138_canonical_gbp_usd",
"institutional_fx_backup_gbp_usd"
]
},
"aud_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_aud_usd",
"chain138_canonical_aud_usd",
"institutional_fx_backup_aud_usd"
]
},
"cad_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_cad_usd",
"chain138_canonical_cad_usd",
"institutional_fx_backup_cad_usd"
]
},
"chf_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_chf_usd",
"chain138_canonical_chf_usd",
"institutional_fx_backup_chf_usd"
]
},
"jpy_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 90,
"maxExecutionDeviationBps": 50,
"pauseOnStale": true,
"sources": [
"gru_reference_service_jpy_usd",
"chain138_canonical_jpy_usd",
"institutional_fx_backup_jpy_usd"
]
},
"xau_usd": {
"targetQuote": "USDC",
"maxOracleAgeSeconds": 60,
"maxExecutionDeviationBps": 40,
"pauseOnStale": true,
"sources": [
"gru_reference_service_xau_usd",
"chain138_canonical_xau_usd",
"institutional_commodity_backup_xau_usd"
]
}
},
"assetOracleAssignments": {
"WETH": "weth_usd",
"WETH10": "weth_usd",
"cWUSDT": "usd_parity",
"cWUSDC": "usd_parity",
"cWAUSDT": "usd_parity",
"cWEURC": "eur_usd",
"cWEURT": "eur_usd",
"cWGBPC": "gbp_usd",
"cWGBPT": "gbp_usd",
"cWAUDC": "aud_usd",
"cWCADC": "cad_usd",
"cWCHFC": "chf_usd",
"cWJPYC": "jpy_usd",
"cWXAUC": "xau_usd",
"cWXAUT": "xau_usd"
},
"operatorRequirements": {
"requireFreshReference": true,
"requireDualSourceForFiatAndGold": true,
"pausePoolActionsWhenReferenceMissing": true,
"recordOracleSnapshotWithEachPoolAction": true
}
}

View File

@@ -0,0 +1,388 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Deep-pool and single-sided edge-pool topology for the Solana GRU v2 launch set.",
"version": "1.0.0",
"updated": "2026-04-26",
"references": {
"solanaRuntimeConfig": "config/solana-relay-runtime.json",
"oraclePolicy": "cross-chain-pmm-lps/config/solana-oracle-policy.json",
"lineupManifest": "config/solana-gru-bridge-lineup.json",
"solanaRelayE2EReadiness": "scripts/verify/check-solana-relay-e2e-readiness.py"
},
"hubStables": [
{
"symbol": "USDC",
"role": "primary",
"mintEnv": "SOLANA_HUB_USDC_MINT"
},
{
"symbol": "USDT",
"role": "secondary",
"mintEnv": "SOLANA_HUB_USDT_MINT"
}
],
"deepVenueOrder": [
"phoenix_clob",
"orca_clmm"
],
"edgeVenueOrder": [
"meteora_dlmm",
"orca_clmm"
],
"assets": [
{
"symbol": "WETH",
"oracleClass": "weth_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 500000,
"singleSided": false
},
{
"quoteSymbol": "USDC",
"venue": "orca_clmm",
"targetDepthUsd": 250000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 100000,
"singleSided": true
}
]
},
{
"symbol": "WETH10",
"oracleClass": "weth_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 250000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 75000,
"singleSided": true
}
]
},
{
"symbol": "cWUSDT",
"oracleClass": "usd_parity",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 400000,
"singleSided": false
},
{
"quoteSymbol": "USDT",
"venue": "orca_clmm",
"targetDepthUsd": 300000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 125000,
"singleSided": true
}
]
},
{
"symbol": "cWUSDC",
"oracleClass": "usd_parity",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 400000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDT",
"venue": "meteora_dlmm",
"targetDepthUsd": 125000,
"singleSided": true
}
]
},
{
"symbol": "cWAUSDT",
"oracleClass": "usd_parity",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 250000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 100000,
"singleSided": true
}
]
},
{
"symbol": "cWEURC",
"oracleClass": "eur_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 200000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 75000,
"singleSided": true
}
]
},
{
"symbol": "cWEURT",
"oracleClass": "eur_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 150000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 60000,
"singleSided": true
}
]
},
{
"symbol": "cWGBPC",
"oracleClass": "gbp_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 150000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 60000,
"singleSided": true
}
]
},
{
"symbol": "cWGBPT",
"oracleClass": "gbp_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 125000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 50000,
"singleSided": true
}
]
},
{
"symbol": "cWAUDC",
"oracleClass": "aud_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 125000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 50000,
"singleSided": true
}
]
},
{
"symbol": "cWCADC",
"oracleClass": "cad_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 125000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 50000,
"singleSided": true
}
]
},
{
"symbol": "cWCHFC",
"oracleClass": "chf_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 125000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 50000,
"singleSided": true
}
]
},
{
"symbol": "cWJPYC",
"oracleClass": "jpy_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 125000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 50000,
"singleSided": true
}
]
},
{
"symbol": "cWXAUC",
"oracleClass": "xau_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 225000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 80000,
"singleSided": true
}
]
},
{
"symbol": "cWXAUT",
"oracleClass": "xau_usd",
"deepPools": [
{
"quoteSymbol": "USDC",
"venue": "phoenix_clob",
"targetDepthUsd": 225000,
"singleSided": false
}
],
"edgePools": [
{
"quoteSymbol": "USDC",
"venue": "meteora_dlmm",
"targetDepthUsd": 80000,
"singleSided": true
}
]
}
],
"deploymentGate": {
"status": "ready_for_external_pool_driver",
"strictRelayCheck": "python3 scripts/verify/check-solana-relay-e2e-readiness.py",
"poolReadinessCheck": "python3 scripts/verify/check-solana-pool-readiness.py",
"executionPlanCheck": "python3 scripts/verify/build-solana-pool-execution-plan.py",
"rule": "RCSC/cW* pools require every pool asset to have bridge-backed operator liquidity inventory, configured hub quote mints, and an explicit venue deployment driver."
},
"edgeQuoteAssets": [
{
"symbol": "RCSC",
"mint": "6dhRQ2PQTR5FSxK1K45GamWeZj9ggu5NUdBbgjCuXB4g",
"role": "reserve_currency_edge_quote",
"network": "solana-mainnet-beta"
}
],
"rcscEdgePoolPolicy": {
"status": "planned_ready_for_external_pool_driver",
"quoteSymbol": "RCSC",
"quoteMint": "6dhRQ2PQTR5FSxK1K45GamWeZj9ggu5NUdBbgjCuXB4g",
"venueOrder": [
"meteora_dlmm",
"orca_clmm"
],
"targetDepthUsdPerPool": 25000,
"singleSided": true,
"appliesToSymbols": [
"cWAUSDT",
"cWUSDT",
"cWUSDC",
"cWEURC",
"cWEURT",
"cWGBPC",
"cWGBPT",
"cWAUDC",
"cWJPYC",
"cWCHFC",
"cWCADC",
"cWXAUC",
"cWXAUT"
],
"deploymentGate": "requires canonical mints, strict Solana relay E2E readiness pass, hub quote mints, bridge-backed operator cW/WETH inventory, and an explicit venue deployment driver"
}
}

View File

@@ -0,0 +1,27 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"description": "Simulation evidence file for treasury/liquidity commitments. Replace placeholder sources with signed commitments before any live leverage contract work.",
"version": "1.0.0",
"updated": "2026-04-27",
"status": "simulation_only",
"minimumExternalLiquidityPct": 0.2,
"bridgeBufferPolicy": {
"formula": "bridgeReserve >= peakBridgeOutflow * latency",
"safetyFactor": 3
},
"sources": [
{
"id": "SIM-POL-001",
"type": "policy_floor",
"description": "At least 20% of capital remains external/idle liquidity in every deployable profile.",
"evidence": "config/capital-efficiency-policy.json",
"signedCommitment": null
}
],
"emergencyAuthority": {
"multisig": null,
"operatorGroup": null,
"notes": "Must be populated with real authority evidence before live leverage deployment."
},
"liveDeploymentAllowed": false
}

View File

@@ -0,0 +1,76 @@
{
"version": "1.2.0",
"updated": "2026-04-14",
"homeChainId": 138,
"chains": {
"1": {
"name": "Example Chain",
"cwTokens": {
"cWUSDT": "0x1111111111111111111111111111111111111111",
"cWUSDC": "0x2222222222222222222222222222222222222222"
},
"anchorAddresses": {
"USDC": "0x3333333333333333333333333333333333333333",
"USDT": "0x4444444444444444444444444444444444444444"
},
"pmmPools": [
{
"base": "cWUSDT",
"quote": "USDC",
"poolAddress": "0xd011000000000000000000000000000000000001",
"feeBps": 3,
"k": 1,
"role": "public_routing",
"publicRoutingEnabled": true
}
],
"gasQuoteAddresses": {
"WETH": "0x5555555555555555555555555555555555555555",
"USDC": "0x3333333333333333333333333333333333333333"
},
"gasPmmPools": [
{
"familyKey": "example",
"base": "cWUSDT",
"quote": "WETH",
"poolAddress": "0xd021000000000000000000000000000000000001",
"feeBps": 30,
"k": 1,
"role": "public_routing",
"poolType": "wrapped_native",
"venue": "dodo_pmm",
"publicRoutingEnabled": true
}
],
"gasReferenceVenues": [
{
"familyKey": "example",
"protocol": "uniswap_v3",
"base": "cWUSDT",
"quote": "WETH",
"venueAddress": "0x7111000000000000000000000000000000000001",
"supported": true,
"live": true,
"routingVisible": true,
"reference": true
},
{
"familyKey": "example",
"protocol": "1inch",
"base": "cWUSDT",
"quote": "USDC",
"venueAddress": null,
"supported": true,
"live": true,
"routingVisible": true,
"aggregatorOnly": true,
"dependsOn": [
"dodo_pmm",
"uniswap_v3"
],
"indexRequired": true
}
]
}
}
}

View File

@@ -0,0 +1,110 @@
{
"version": "1.2.0",
"updated": "2026-04-14",
"homeChainId": 138,
"chains": {
"1": {
"name": "Example Chain",
"cwTokens": {
"cWUSDT": "0x1111111111111111111111111111111111111111",
"cWUSDC": "0x2222222222222222222222222222222222222222"
},
"anchorAddresses": {
"USDC": "0x3333333333333333333333333333333333333333",
"USDT": "0x4444444444444444444444444444444444444444"
},
"pmmPools": [
{
"base": "cWUSDT",
"quote": "USDC",
"poolAddress": "0x1234567890123456789012345678901234567890",
"feeBps": 3,
"k": 1,
"role": "public_routing",
"publicRoutingEnabled": true
}
],
"gasQuoteAddresses": {
"WETH": "0x5555555555555555555555555555555555555555",
"USDC": "0x3333333333333333333333333333333333333333"
},
"gasPmmPools": [
{
"familyKey": "example",
"base": "cWUSDT",
"quote": "WETH",
"poolAddress": "0x6666666666666666666666666666666666666666",
"feeBps": 30,
"k": 1,
"role": "public_routing",
"poolType": "wrapped_native",
"venue": "dodo_pmm",
"publicRoutingEnabled": true
},
{
"familyKey": "example",
"base": "cWUSDT",
"quote": "USDC",
"poolAddress": "0x7777777777777777777777777777777777777777",
"feeBps": 30,
"k": 1,
"role": "public_routing",
"poolType": "stable_quote",
"venue": "dodo_pmm",
"publicRoutingEnabled": true
}
],
"gasReferenceVenues": [
{
"familyKey": "example",
"protocol": "uniswap_v3",
"base": "cWUSDT",
"quote": "WETH",
"venueAddress": "0x8888888888888888888888888888888888888888",
"supported": true,
"live": false,
"routingVisible": false,
"reference": true
},
{
"familyKey": "example",
"protocol": "balancer",
"base": "cWUSDT",
"quote": "USDC",
"venueAddress": null,
"supported": true,
"live": false,
"routingVisible": false,
"reference": false
},
{
"familyKey": "example",
"protocol": "curve",
"base": "cWUSDT",
"quote": "USDC",
"venueAddress": null,
"supported": true,
"live": false,
"routingVisible": false,
"reference": false
},
{
"familyKey": "example",
"protocol": "1inch",
"base": "cWUSDT",
"quote": "USDC",
"venueAddress": null,
"supported": true,
"live": false,
"routingVisible": false,
"aggregatorOnly": true,
"dependsOn": [
"dodo_pmm",
"uniswap_v3"
],
"indexRequired": true
}
]
}
}
}

View File

@@ -33,8 +33,27 @@ When multiple quotes exist (USDT/USDC/DAI), the bot routes to the best edge:
- If the bridge is congested or risk flags trip, bot widens bands / reduces exposure
### 5. Gas-budgeted micro-support lane
For selected wrapped USD rails, especially **cWUSDC** and **cWUSDT**, you can reserve a small gas budget for **micro-trades** against **USDC** / **USDT**:
- Prefer matched-quote rails when they exist: `cWUSDC/USDC`, `cWUSDT/USDT`
- Keep each trade tiny relative to `I_T^*`
- Use inventory-aware direction first: sell cW into the pool when inventory is too low; buy cW from the pool when inventory is too high
- If the pool is already near its inventory target, alternate tiny buys/sells only within a separate gas budget
Purpose:
- Give wrappers **observable turnover**
- Tighten route discovery and quote confidence
- Keep the support lane small enough that the PMM remains a **corridor defense tool**, not the primary venue
Important: this improves **tradability and price discovery**, but it does **not** create backing or intrinsic value by itself.
## Peg bands
**GRU reference primacy (proxmox parent repo):** Bot deviation logic implements **corridors around oracle targets**; it does not replace institution-grade FX/GRU/XDR references. Canonical policy + integration checklist: proxmox `docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md`. The peg config carries a machine hook **`gruPolicyIntegration`** in [../config/peg-bands.json](../config/peg-bands.json) (validated by parent `scripts/verify/check-gru-reference-primacy-integration.sh`).
See [../config/peg-bands.json](../config/peg-bands.json) and [05-oracles.md](05-oracles.md). Summary:
- **USD-pegged**: Normal ±1025 bps; stress ±50150 bps; circuit break >2%

View File

@@ -17,4 +17,6 @@
- Do not trade against a stale oracle; treat staleness as a risk trigger.
- Document fallback order (e.g. primary chainlink, secondary Pyth, tertiary internal).
Config and peg bands: [../config/peg-bands.json](../config/peg-bands.json).
Config and peg bands: [../config/peg-bands.json](../config/peg-bands.json) (includes **`gruPolicyIntegration`** linking proxmox `docs/04-configuration/GRU_REFERENCE_PRIMACY_AND_MESH_EXECUTION_MODEL.md` — oracle targets remain subordinate to institution-grade references).
Parent verifier: proxmox `scripts/verify/check-gru-reference-primacy-integration.sh`.

View File

@@ -29,8 +29,22 @@ Every run (hub-only, full-quote, bridge shock) should produce a scorecard with a
| `intervention_cost_inject_total` | number | Bot inject (bridge-in) cost only |
| `intervention_cost_withdraw_total` | number | Bot withdraw cost only |
| `intervention_cost_by_chain` | object | Per chain: `{ inject, withdraw }` — which chains are liquidity sinks |
| `micro_trade_count` | number | Count of gas-budgeted support trades executed |
| `micro_trade_buy_count` | number | Support-lane buys of cW from the pool |
| `micro_trade_sell_count` | number | Support-lane sells of cW into the pool |
| `micro_trade_volume_total` | number | Base-token units rotated through the support lane |
| `micro_trade_gas_cost_total` | number | Abstract gas budget consumed by support trades |
| `scenario` | string | e.g. `hub_only_11`, `full_quote_1_56_137`, `bridge_shock_137_56` |
| `runId` | string | Optional run identifier |
| `roi_mean` | number | Mean capital-efficiency ROI when Monte Carlo is enabled |
| `roi_p05` / `roi_p95` | number | 5th/95th percentile ROI band |
| `pnl_distribution` | object | PnL percentiles `{p05,p50,p95}` |
| `max_drawdown_p95` | number | 95th percentile max drawdown |
| `liquidation_probability` | number | Fraction of Monte Carlo paths that liquidated |
| `peg_deviation_frequency` | number | Fraction of path-epochs above peg circuit-break threshold |
| `external_liquidity_floor_violations` | integer | Count of path-epochs below minimum external liquidity before clamp |
| `volatility_throttle_events` | integer | Count of sigma-triggered deleverage/allocation throttle events |
| `spread_adjustment_events` | integer | Count of volatility/liquidity/peg-driven spread adjustments |
**Example (minimal):**
@@ -74,6 +88,17 @@ From [10-behavioral-stability-analysis.md](10-behavioral-stability-analysis.md):
**Pass:** All gates satisfied for the scenario.
**Fail:** Any gate violated; do not treat scenario as deployable without parameter change or topology reduction.
Capital-efficiency scenarios also use `config/capital-efficiency-policy.json` gates:
| Gate | Default |
|------|---------|
| Liquidation probability | `<= 0.02` |
| p95 max drawdown | `<= 0.25` |
| Peg deviation frequency | `<= 0.05` |
| External liquidity floor violations | `0` |
| Deployable leverage | `<= 1.5x` |
| Hard leverage ceiling | `<= 4x` |
---
## 3. Phase 0 comparison (three scenarios)
@@ -92,6 +117,14 @@ Compare deltas:
If churn jumps >50% with full-quote → clear “dont deploy full-quote” rule.
For **gas-budgeted support scenarios**, compare:
- **micro_trade_gas_cost_total** vs baseline intervention cost
- **micro_trade_volume_total / micro_trade_count** to verify trades stay genuinely micro
- **peak_deviation_bps_post_bot** vs the same scenario without micro-support
If support gas rises faster than the deviation improvement you get back, the support lane is too aggressive.
---
## 4. Phase 0: Runnable scenarios and knob guidance

View File

@@ -0,0 +1,58 @@
# Gas-Budgeted Micro-Trade Support
Use a small, explicit gas budget to run **tiny support trades** in the most important wrapped USD rails:
- `cWUSDC` against `USDC`
- `cWUSDT` against `USDT`
- fallback to the chain hub stable only when the matched rail is unavailable
## What this is for
The goal is to give wrapped assets:
- observable turnover
- fresher route discovery
- tighter quote confidence
- inventory-sensitive support when a pool drifts away from target stock
This is a **liquidity and price-discovery support lane**. It does **not** create reserve backing or intrinsic value on its own.
## Operating rule
Use the support lane only when all of these remain true:
- the trades stay **micro** relative to `I_T^*`
- gas is capped per epoch or time window
- matched rails are preferred: `cWUSDC/USDC`, `cWUSDT/USDT`
- inventory correction happens first
- alternating buys/sells are allowed only inside a small inventory band
## Suggested control surface
Model or enforce these knobs:
- `tradeSizeUnits`
- `tradesPerEpoch`
- `gasCostPerTradeUnits`
- `gasBudgetPerEpochUnits`
- `inventoryBandFraction`
- `maxFractionOfTarget`
- `preferMatchedQuote`
## Recommended interpretation
Think of this as paying a small amount of gas to keep the wrapper corridor **economically live**:
- If pool inventory is too low, sell a tiny amount of cW into the pool.
- If pool inventory is too high, buy a tiny amount of cW from the pool.
- If inventory is already near target, allow only very small alternating trades, still under the gas cap.
## Scenario
The repo includes a ready-made scenario for the first three high-signal public rails:
```bash
node scripts/run-scenario.cjs micro_support_usd_wrappers_1_56_137
```
This runs on chains `1`, `56`, and `137` with `cWUSDT` and `cWUSDC`, full-quote topology, and a separate micro-trade policy budget.

View File

@@ -0,0 +1,145 @@
# Capital Efficiency Risk Simulation
This module extends the existing PMM routing simulator with a simulation-only treasury/risk overlay. It evaluates capital allocation, leverage, spread policy, peg pressure, volatility throttles, external liquidity floors, and liquidation probability before any live contract work.
The model is intentionally wired to the current ecosystem:
- PMM routing, capture, churn, intervention cost, and peg deviation still come from `scripts/run-scenario.cjs`.
- Risk defaults live in `config/capital-efficiency-policy.json`.
- Scenario-specific capital assumptions live under `capitalEfficiency` in `config/scenarios/*.json`.
- `deployment-status.json` remains the deployed-graph source when `graphMode = deployed`.
This is not a live leverage configuration. Contract work remains gated by audit engagement evidence, governance approval, operational dashboards, and runbooks.
## Model
Each Monte Carlo path tracks:
- `T`: total capital
- `alpha`: treasury/yield allocation
- `L`: leverage
- `sigma`: mean-reverting volatility
- `P`: peg price around 1.0
- external liquidity floor
- collateral/debt liquidation state
Per epoch, capital updates with:
```text
T_next = T + T * (yield + market_making - volatility_drag - intervention_drag - redemption_drag)
```
Volatility follows:
```text
sigma_next = sigma + kappa * (sigma_bar - sigma) + eta * N(0, 1)
```
Peg dynamics follow a lightweight imbalance/arb model:
```text
P_next = P + beta * imbalance - arb_liquidity_coefficient * (P - 1)
```
If volatility exceeds `sigmaCrit`, the simulator reduces effective allocation/leverage and widens spread up to the configured ceiling. If external liquidity drops below the policy floor, the path records a violation and clamps allocation.
## Run
Baseline routing scenarios are unchanged:
```bash
node scripts/run-scenario.cjs hub_only_11
node scripts/run-scenario.cjs bridge_shock_137_56
```
Capital stress scenarios:
```bash
node scripts/run-scenario.cjs crash_40pct_external_asset
node scripts/run-scenario.cjs high_vol_sigma_spike
node scripts/run-scenario.cjs bank_run_redemption_spike
```
Optimizer sweep:
```bash
node scripts/run-scenario.cjs --optimizer leverage_sweep_1x_to_4x
```
`leverage_sweep_1x_to_4x` also enables optimizer mode by default.
CI-style validation:
```bash
node scripts/validate-capital-efficiency.cjs
```
## Scorecard Additions
Capital-enabled scenarios emit:
- `roi_mean`, `roi_p05`, `roi_p95`
- `pnl_distribution`
- `max_drawdown_p95`
- `liquidation_probability`
- `peg_deviation_frequency`
- `external_liquidity_floor_violations`
- `volatility_throttle_events`
- `spread_adjustment_events`
Optimizer output ranks parameter candidates by ROI penalized for liquidation, drawdown, and peg frequency. A candidate is deployable only if it passes the policy gates in `capital-efficiency-policy.json`.
## Institutional Defaults
The default posture is conservative:
- external liquidity floor: 20% of capital
- stress-deployable leverage: 1-1.5x
- target leverage for future audited optimization: 2-3x
- deployable optimizer candidates capped at 1.5x until external approvals exist
- hard leverage rejection above 4x
- default max LTV: 65%
- hard LTV ceiling: 75%
- target spread: 30-50 bps
- public PMM remains peg support, not the primary profit engine
Any later Solidity blueprint must consume the simulator outputs as evidence, not as authority to deploy leverage automatically.
## Latest Local Run
Generated on 2026-04-27 from the current configs:
| Scenario | ROI mean | Liquidation probability | p95 drawdown | Notes |
|---|---:|---:|---:|---|
| `chain138_deployed_capital_efficiency` | `0.0542` | `0` | `0` | Base deployed Chain 138 graph survives under defaults. |
| `crash_40pct_external_asset` | `0.0577` | `0` | `0` | Uses conservative 1.5x stress-deployable leverage. |
| `high_vol_sigma_spike` | `0.0409` | `0` | `0.0002` | Uses conservative 1.5x stress-deployable leverage. |
| `bank_run_redemption_spike` | `-0.1762` | `0` | `0.2186` | Redemption stress survives below the 25% drawdown gate. |
| `leverage_sweep_1x_to_4x` | `0.0679` top deployable | `0` | `0` | Top deployable candidate is capped at 1.5x by policy. |
Interpretation:
- Crash/high-volatility profiles require conservative leverage under current assumptions.
- Bank-run defense must remain below the 25% p95 drawdown gate.
- Optimizer may still simulate 2x-4x candidates, but policy prevents them from being marked deployable until governance/audit evidence changes the cap.
## Dashboard And Runbook Requirements
Before any live leverage contract work, operations must expose:
- ROI band: `roi_mean`, `roi_p05`, `roi_p95`
- Drawdown: `max_drawdown_p95`
- Liquidation: `liquidation_probability`
- Liquidity floor: `external_liquidity_floor_violations`
- Peg defense: `peg_deviation_frequency`
- Throttles: `volatility_throttle_events`
- Spread changes: `spread_adjustment_events`
- Existing PMM health: capture, churn, intervention cost, and worst-pool diagnostics
Deployment remains blocked until:
- Smart contract audit engagement evidence exists.
- Governance approval is recorded.
- Risk dashboard and alerting are live.
- Operator runbook covers deleverage, circuit breaker, redemption throttle, and treasury liquidity deployment.
- Treasury/liquidity commitments are documented.

View File

@@ -0,0 +1,27 @@
# Capital Efficiency Contract Blueprint Gate
Status: locally blocked only by external institutional prerequisites.
This document is the handoff point for the requested contract blueprint. It intentionally does not define deployable Solidity yet because live leverage remains blocked until audit engagement and governance evidence exist. The current local deployable simulation posture caps leverage at `1.5x`.
## Required Before Blueprint
- `node scripts/validate-capital-efficiency.cjs` passes.
- Stress scenarios pass the policy gates in `config/capital-efficiency-policy.json`.
- Audit engagement evidence is recorded.
- Governance approval evidence is recorded.
- Risk dashboard and alerting are specified in `docs/18-capital-efficiency-risk-dashboard-and-runbook.md` and operational before live deployment.
- Operator runbook covers deleverage, circuit breaker, redemption throttle, and treasury liquidity deployment.
- Treasury/liquidity commitments are documented.
## Blueprint Scope Once Unblocked
- Treasury engine: allocation caps, yield strategy adapter interface, idle/external liquidity floor.
- Liquidity engine: PMM/DODO provider hooks, pool role separation, route exposure controls.
- Leverage engine: LP-token collateral accounting, borrow/redeploy loop, max LTV checks.
- Risk engine: volatility throttle, spread adjustment, peg circuit breaker, liquidation guard.
- Keeper flow: rebalance, auto-deleverage, and dashboard event emission.
## Current Decision
Do not implement live leverage contracts. The local simulator gates can be satisfied at conservative leverage, but audit engagement and governance approval remain mandatory external prerequisites.

View File

@@ -0,0 +1,78 @@
# Capital Efficiency Risk Dashboard And Operator Runbook
Status: simulation-only operational specification.
This document removes the local documentation blocker for dashboard and runbook requirements. It does not remove external approval blockers: audit engagement and governance approval still require signed evidence.
## Dashboard Metrics
Expose these metrics from the latest scorecards:
| Metric | Source field | Alert |
|---|---|---|
| ROI mean | `roi_mean` | Informational |
| ROI lower band | `roi_p05` | Alert if negative in deployable profile |
| ROI upper band | `roi_p95` | Informational |
| p95 drawdown | `max_drawdown_p95` | Critical if `> 0.25` |
| Liquidation probability | `liquidation_probability` | Critical if `> 0.02` |
| Peg deviation frequency | `peg_deviation_frequency` | Critical if `> 0.05` |
| External liquidity floor violations | `external_liquidity_floor_violations` | Critical if `> 0` |
| Volatility throttle events | `volatility_throttle_events` | Warning if rising versus baseline |
| Spread adjustment events | `spread_adjustment_events` | Warning if rising versus baseline |
| PMM capture | `capture_mean` | Warning if sustained above target corridor |
| Inventory churn | `churn_mean`, `churn_p95` | Warning if outside scorecard gates |
| Intervention cost | `intervention_cost_per_1M_volume` | Warning if nonlinear versus volume |
## Operator Procedures
### Deleverage
1. Stop new leverage increases.
2. Set deployable profile to `leverage <= 1.5`.
3. Reduce `alpha` to preserve the external liquidity floor.
4. Re-run:
```bash
node scripts/validate-capital-efficiency.cjs
```
5. Resume only when crash, high-volatility, and bank-run scenarios pass policy gates.
### Spread Widening
1. If volatility exceeds `sigmaCrit`, widen spread to `throttleSpreadBps`.
2. If peg deviation exceeds circuit-break threshold, widen to `circuitBreakerSpreadBps`.
3. Confirm `spread_adjustment_events` stabilizes and peg deviation frequency remains within gate.
### Redemption Throttle
1. Trigger when bank-run scorecard approaches drawdown gate.
2. Increase redemption fee according to policy.
3. Pause non-essential outflows.
4. Deploy treasury liquidity only from documented sources in `config/treasury-liquidity-commitments.json`.
### Treasury Liquidity Deployment
1. Confirm external liquidity remains at or above 20%.
2. Confirm bridge buffer satisfies `bridgeReserve >= peakBridgeOutflow * latency`.
3. Execute only through approved operator/multisig authority.
4. Record evidence before marking any live deployment gate complete.
### Peg Circuit Breaker
1. Stop adding public-routing liquidity to affected pools.
2. Prefer defense-only rebalancing.
3. Re-run deployed Chain 138 and stress scenarios.
4. Re-enable only when peg deviation frequency is within gate.
## Evidence Status
| Gate | Local status |
|---|---|
| Risk dashboard specification | Complete in this document |
| Operator runbook | Complete in this document |
| Treasury/liquidity commitment structure | Complete in `config/treasury-liquidity-commitments.json` |
| Audit engagement | External evidence required |
| Governance approval | External evidence required |
## Current Deployable Posture
Until audit and governance evidence exists, the only locally gate-passing posture is simulation-only with deployable optimizer leverage capped at `1.5x`.

View File

@@ -0,0 +1,92 @@
# Capital Efficiency External Approval Evidence
**Status:** intake path **ready** (CyberSecur Global form live). **Submission / signed engagement** still pending — this register tracks evidence as it arrives.
This file is the canonical evidence register for the remaining non-local blockers. Populate it with signed references before changing `liveExecutionGuard.status` away from `simulation_only`.
## Audit intake path (ready)
| Field | Value |
|---|---|
| Audit firm (requested) | CyberSecur Global |
| Intake URL | `https://cybersecur.d-bis.org/intake.html` |
| Security contact | `https://cybersecur.d-bis.org/.well-known/security.txt` |
| Intake fields | Organization, contact email, repository URL, chains/deployments, timeline, notes |
| Blocker class | ~~Intake path unknown~~**submission / engagement pending** |
### Requested scope (for manual submission)
Use normal browser submission (Web3Forms may reject scripted POSTs). Notes should reference at minimum:
- **Chain 138** deployments and RPC/explorer context you want reviewed.
- **cW/c\* PMM mesh** — routing surfaces and reserves relevant to capital-efficiency claims.
- **Capital-efficiency simulator** — this repos Monte Carlo overlay (`config/capital-efficiency-policy.json`, scenarios, validators).
- **Future blueprint** — treasury / liquidity / leverage / risk / keeper alignment (design and audit-readiness; live leverage contracts remain gated).
## Intake submission record (pending)
Fill when submitted:
| Field | Value |
|---|---|
| Submission date | |
| Intake receipt / reference | (email confirmation, ticket id, or Web3Forms reference if provided) |
| Contact email | |
| Audit firm name | CyberSecur Global (expected) |
| Evidence URI / path | This file + policy JSON keys below |
## Audit engagement (signed)
Fill when a statement of work or engagement letter exists:
| Field | Value |
|---|---|
| Firm | |
| Engagement reference | |
| Signed date | |
| Final scope (short) | |
| Evidence URI | |
Historical placeholder row (superseded by tables above):
| Field | Value |
|---|---|
| Engagement reference | Pending external engagement |
| Signed date | Pending external engagement |
| Scope | Treasury engine, liquidity engine, leverage engine, risk engine, keeper/deleverage flow, oracle/circuit breaker integration |
| Evidence URI | Pending submitted intake receipt / signed engagement |
## Audit Intake Package
Use the CyberSecur Global intake form to request the audit. The request should include:
- Organization: DBIS / Chain 138 capital-efficiency simulation and future leverage blueprint.
- Repository URL: canonical repository or private review bundle URI.
- Chains / deployments: Chain 138, cW/c* PMM mesh, DODO PMM surfaces, vault/reserve/liquidation references.
- Timeline: simulation review first; Solidity blueprint review only after governance approval.
- Notes: live leverage contracts are blocked; requested scope is design/risk/audit-readiness plus future contract blueprint review.
## Governance Approval
| Field | Value |
|---|---|
| Body | Pending governance action |
| Resolution ID | Pending governance action |
| Approval date | Pending governance action |
| Approved policy cap | Simulation-only, max deployable leverage `1.5x` |
| Evidence URI | Pending governance action |
## Current Enforcement
- `config/capital-efficiency-policy.json` keeps `liveExecutionGuard.status = simulation_only`.
- `scripts/validate-capital-efficiency.cjs` requires dashboard, runbook, and liquidity commitment evidence paths.
- Live leverage contracts remain blocked until the pending audit and governance evidence is real, dated, and reviewable.
## Operator checklist (Web3Forms)
1. Rotate access key in Web3Forms dashboard if needed.
2. Set `CYBERSECUR_WEB3FORMS_ACCESS_KEY` in operator dotenv (see project `.env.master.example`).
3. Redeploy static site: `scripts/deployment/sync-cybersecur-global-to-ct7810.sh` from proxmox repo (renders intake when key is set).
4. Verify: `curl -I https://cybersecur.d-bis.org/intake.html` and `curl -I https://cybersecur.d-bis.org/.well-known/security.txt`.
**Proxmox repo parity (GitHub + Gitea):** Before audit submission, confirm parent **`proxmox`** `master` equals **`origin/master`** and **`gitea/master`** (same commit hash). See **`scripts/git/README-gitea-proxmox-sync.md`** in that repo (parity check section).

View File

@@ -30,7 +30,9 @@ Validates `config/deployment-status.json` for minimum viable deployed graph. Use
**Rules:**
- If `bridgeAvailable === true` on a chain, `cwTokens` must include at least **cWUSDT** and **cWUSDC** (phase 1).
- For each `pmmPool`: `role` ∈ {defense, public_routing}; `feeBps` and `k` present; `base`/`quote` (or `tokenIn`/`tokenOut`) exist in `cwTokens` or `anchorAddresses`.
- For each `pmmPool` and each `pmmPoolsVolatile[]` entry: `role` ∈ {defense, public_routing, truu_routing}; `feeBps` and `k` present; `base`/`quote` (or `tokenIn`/`tokenOut`) exist in `cwTokens` or `anchorAddresses` (e.g. mainnet **TRUU** under `anchorAddresses.TRUU`). Non-zero `poolAddress` must not be the zero address.
- For each `gasReferenceVenues[]` entry: `supported` must be explicit, `aggregatorOnly` is only valid for `1inch`, `supported=false` means the lane is explicitly unsupported (and can never be live), and `supported=true` with `live=false` / `routingVisible=false` means the lane is planned or staged.
- `aggregatorOnly=true` rows are routing overlays, not stand-alone live venues.
**Run:**
@@ -40,12 +42,25 @@ node scripts/validate-deployment-status.cjs
**Exit code:** 0 if valid, 1 if invalid (errors to stderr).
**Native protocol-only examples:**
```bash
node scripts/validate-deployment-status.cjs config/validation-examples/native-protocol-only.valid.json
node scripts/validate-deployment-status.cjs config/validation-examples/native-protocol-only.invalid.json
```
The invalid example intentionally includes a placeholder scaffold and a non-native live `1inch` row to exercise the rejection path.
**Parent proxmox repo:** live Mainnet cW/TRUU pool deploy and ratio-matched top-up scripts live under `scripts/deployment/` (`deploy-mainnet-pmm-cw-truu-pool.sh`, `add-mainnet-truu-pmm-topup.sh`); see `docs/03-deployment/MAINNET_PMM_TRUU_CWUSD_PEG_AND_BOT_RUNBOOK.md` §11.
---
## run-scenario.cjs
Builds the **real** routing graph from configs, runs epochs with PMM state updates, path enumeration + waterfilling, **arb step** (implied-price deviation, capped corrective trades, profit gate), **bot step** (inject/withdraw at 0.5×/1.5× I_T^* with intervention cost β/γ/ρ), and optional **bridge shock** trades. Emits a **real scorecard** (PR#2). Runs are **deterministic** when `scenario.seed` is set or derived from scenario name.
Scenarios may also include an optional **microTradePolicy** for gas-budgeted support trades in selected USD wrapper rails. This is meant to model tiny, controlled `cWUSDC` / `cWUSDT` turnover-seeding or inventory-corrective activity, not to turn the PMM into a venue.
**Configs used:** `simulation-params.json`, `token-map.json`, `routing-controls.json`; `deployment-status.json` only when `graphMode = deployed`. Pool topology from `pool-matrix.json` and scenario `topology` / `fullQuoteChains`.
**Tuning constants (in script):**
@@ -64,8 +79,33 @@ Builds the **real** routing graph from configs, runs epochs with PMM state updat
node scripts/run-scenario.cjs hub_only_11
node scripts/run-scenario.cjs --scenario full_quote_1_56_137
node scripts/run-scenario.cjs bridge_shock_137_56
node scripts/run-scenario.cjs micro_support_usd_wrappers_1_56_137
node scripts/run-scenario.cjs crash_40pct_external_asset
node scripts/run-scenario.cjs high_vol_sigma_spike
node scripts/run-scenario.cjs bank_run_redemption_spike
node scripts/run-scenario.cjs --optimizer leverage_sweep_1x_to_4x
```
**Output:** JSON scorecard including: `capture_mean`, `churn_mean`, `drain_half_life_epochs`, `path_concentration_index`; `intervention_cost_total` / `intervention_cost_inject_total` / `intervention_cost_withdraw_total` / `intervention_cost_by_chain` / `intervention_cost_per_1M_volume`; `peak_deviation_bps` (post-arb), `peak_deviation_bps_pre_arb`, `peak_deviation_bps_post_arb`, `peak_deviation_bps_post_bot`; `arb_volume_total`, `arb_profit_total` (execution-based, not mid). See [docs/12-sim-scorecard.md](../docs/12-sim-scorecard.md) and [config/scorecard-schema.json](../config/scorecard-schema.json).
**Output:** JSON scorecard including: `capture_mean`, `churn_mean`, `drain_half_life_epochs`, `path_concentration_index`; `intervention_cost_total` / `intervention_cost_inject_total` / `intervention_cost_withdraw_total` / `intervention_cost_by_chain` / `intervention_cost_per_1M_volume`; `micro_trade_count` / `micro_trade_volume_total` / `micro_trade_gas_cost_total`; `peak_deviation_bps` (post-arb), `peak_deviation_bps_pre_arb`, `peak_deviation_bps_post_arb`, `peak_deviation_bps_post_bot`; `arb_volume_total`, `arb_profit_total` (execution-based, not mid). See [docs/12-sim-scorecard.md](../docs/12-sim-scorecard.md) and [config/scorecard-schema.json](../config/scorecard-schema.json).
When `capitalEfficiency.enabled = true`, output also includes Monte Carlo capital-risk metrics: `roi_mean`, `roi_p05`, `roi_p95`, `pnl_distribution`, `max_drawdown_p95`, `liquidation_probability`, `peg_deviation_frequency`, `external_liquidity_floor_violations`, `volatility_throttle_events`, and `spread_adjustment_events`. Optimizer mode emits ranked parameter candidates and never treats leverage above the configured hard ceiling as deployable.
**Orderflow:** Trade sizes use `distribution: "uniform"` by default. Scenario schema supports `lognormal` / `pareto` for skewed (many small + occasional whale) flows; implement in `sampleTrade()` when needed.
---
## validate-capital-efficiency.cjs
Runs CI-style checks for the simulation-only capital efficiency overlay:
- JSON parse for policy, schemas, and scenarios
- Baseline scenario remains capital-overlay free
- Stress scenarios emit capital risk fields
- Deterministic repeat check
- Optimizer deployable candidates respect `maxDeployableLeverage`
**Run:**
```bash
node scripts/validate-capital-efficiency.cjs
```

View File

@@ -48,12 +48,32 @@ function rng() {
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
}
function normalSample() {
const u1 = Math.max(rng(), 1e-12);
const u2 = Math.max(rng(), 1e-12);
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
}
function hashScenarioName(name) {
let h = 0;
for (let i = 0; i < name.length; i++) h = (Math.imul(31, h) + name.charCodeAt(i)) >>> 0;
return h;
}
function percentile(values, p) {
if (!values.length) return 0;
const sorted = [...values].sort((a, b) => a - b);
const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));
return sorted[idx];
}
function round2(n) {
return Math.round((Number(n) || 0) * 100) / 100;
}
function round4(n) {
return Math.round((Number(n) || 0) * 10000) / 10000;
}
function loadJson(p) {
return JSON.parse(fs.readFileSync(p, 'utf8'));
}
@@ -61,6 +81,9 @@ function loadJson(p) {
function loadConfigs(scenario) {
const simulationParams = loadJson(path.join(CONFIG_DIR, 'simulation-params.json'));
const tokenMap = loadJson(path.join(CONFIG_DIR, 'token-map.json'));
const capitalEfficiencyPolicy = fs.existsSync(path.join(CONFIG_DIR, 'capital-efficiency-policy.json'))
? loadJson(path.join(CONFIG_DIR, 'capital-efficiency-policy.json'))
: {};
const routingControls = fs.existsSync(path.join(CONFIG_DIR, 'routing-controls.json'))
? loadJson(path.join(CONFIG_DIR, 'routing-controls.json'))
: { defaults: { publicRoutingEnabled: true, maxTradeSizeUnits: null } };
@@ -72,14 +95,25 @@ function loadConfigs(scenario) {
const poolMatrix = fs.existsSync(path.join(CONFIG_DIR, 'pool-matrix.json'))
? loadJson(path.join(CONFIG_DIR, 'pool-matrix.json'))
: { chains: {} };
return { simulationParams, tokenMap, routingControls, deploymentStatus, poolMatrix };
return { simulationParams, tokenMap, capitalEfficiencyPolicy, routingControls, deploymentStatus, poolMatrix };
}
function buildGraph(scenario, configs) {
const { simulationParams, tokenMap, poolMatrix } = configs;
const { simulationParams, tokenMap, poolMatrix, deploymentStatus } = configs;
const chains = simulationParams.chains || {};
const publicChains = tokenMap.publicChains || {};
const cwTokens = scenario.tokensIncluded || tokenMap.bridgedSymbols || ['cWUSDT', 'cWUSDC', 'cWAUSDT', 'cWEURC', 'cWEURT', 'cWUSDW'];
const deployedChains = deploymentStatus?.chains || {};
const deployedTokenSet = new Set();
if (scenario.graphMode === 'deployed') {
for (const chain of Object.values(deployedChains)) {
for (const t of Object.keys(chain.cwTokens || {})) deployedTokenSet.add(t);
for (const p of [...(chain.pmmPools || []), ...(chain.pmmPoolsVolatile || []), ...(chain.gasPmmPools || [])]) {
if (p.base) deployedTokenSet.add(p.base);
if (p.tokenIn) deployedTokenSet.add(p.tokenIn);
}
}
}
const cwTokens = scenario.tokensIncluded || (deployedTokenSet.size ? Array.from(deployedTokenSet) : tokenMap.bridgedSymbols) || ['cWUSDT', 'cWUSDC', 'cWAUSDT', 'cWEURC', 'cWEURT', 'cWUSDW'];
const chainIds = scenario.chainsIncluded || Object.keys(chains);
const topology = scenario.topology || 'hub';
const fullQuoteChains = scenario.fullQuoteChains
@@ -92,13 +126,57 @@ function buildGraph(scenario, configs) {
for (const chainId of chainIds) {
const chainConf = chains[chainId] || {};
const deployedChain = scenario.graphMode === 'deployed' ? deployedChains[chainId] : null;
const pub = publicChains[chainId] || {};
const hubStable = chainConf.hubStable || pub.hubStable || 'USDC';
const anchorStables = pub.anchorStables || [hubStable];
const anchorStables = deployedChain
? Object.keys(deployedChain.anchorAddresses || {})
: (pub.anchorStables || [hubStable]);
for (const t of cwTokens) nodes.add(`${chainId}:${t}`);
for (const a of anchorStables) nodes.add(`${chainId}:${a}`);
if (deployedChain) {
const deployedPools = [
...(deployedChain.pmmPools || []),
...(deployedChain.pmmPoolsVolatile || []),
...(deployedChain.gasPmmPools || []),
];
for (const pool of deployedPools) {
const base = pool.base || pool.tokenIn;
const quote = pool.quote || pool.tokenOut;
if (!base || !quote) continue;
nodes.add(`${chainId}:${base}`);
nodes.add(`${chainId}:${quote}`);
pmmEdges.push({
type: 'pmm',
chainId,
base,
quote,
key: `${chainId}:${base}:${quote}`,
k: pool.k,
feeBps: pool.feeBps,
inventoryTargetUnits: pool.inventoryTargetUnits,
depthD0Units: pool.depthD0Units,
role: pool.role || 'public_routing',
publicRoutingEnabled: pool.publicRoutingEnabled !== false,
poolAddress: pool.poolAddress,
});
}
for (let i = 0; i < anchorStables.length; i++) {
for (let j = i + 1; j < anchorStables.length; j++) {
ammEdges.push({
type: 'amm',
chainId,
tokenA: anchorStables[i],
tokenB: anchorStables[j],
key: `${chainId}:amm:${anchorStables[i]}:${anchorStables[j]}`,
});
}
}
continue;
}
const poolChains = poolMatrix.chains || {};
const pc = poolChains[chainId] || {};
const poolsFirst = pc.poolsFirst || [];
@@ -182,11 +260,11 @@ function buildPMMState(graph, configs) {
for (const e of graph.pmmEdges) {
const chainConf = graph.chains[e.chainId] || {};
const isEur = CW_EUR.includes(e.base);
const k = isEur ? (eurDefaults.k ?? 0.2) : (chainConf.k ?? defaultPmm.k ?? 0.1);
const feeBps = isEur ? (eurDefaults.feeBps ?? 35) : (chainConf.feeBps ?? defaultPmm.feeBps ?? 25);
const k = e.k != null ? Number(e.k) : (isEur ? (eurDefaults.k ?? 0.2) : (chainConf.k ?? defaultPmm.k ?? 0.1));
const feeBps = e.feeBps != null ? Number(e.feeBps) : (isEur ? (eurDefaults.feeBps ?? 35) : (chainConf.feeBps ?? defaultPmm.feeBps ?? 25));
const fee = feeBps / 10000;
const invTarget = parseInt(chainConf.inventoryTargetUnits || defaultPmm.inventoryTargetUnits || '1000000', 10);
const d0 = parseInt(chainConf.depthD0Units || defaultPmm.depthD0Units || '500000', 10);
const invTarget = parseInt(e.inventoryTargetUnits || chainConf.inventoryTargetUnits || defaultPmm.inventoryTargetUnits || '1000000', 10);
const d0 = parseInt(e.depthD0Units || chainConf.depthD0Units || defaultPmm.depthD0Units || '500000', 10);
const eurP = params.eurUsd != null ? Number(params.eurUsd) : (params.eurPegMultiplier != null && params.eurPegMultiplier !== 1 ? Number(params.eurPegMultiplier) : 1.1);
const P = isEur ? eurP : 1;
@@ -355,6 +433,173 @@ function getBridgeRho(scenario, fromChain, toChain) {
return (blocks ?? 10) * rhoPerBlock / 10000;
}
function getMatchedQuoteForBase(base) {
if (base === 'cWUSDT') return 'USDT';
if (base === 'cWUSDC') return 'USDC';
return null;
}
function getMicroTradeCandidates(graph, policy) {
const tokenFilter = new Set(policy.tokens || []);
const quoteFilter = new Set(policy.quoteTokens || []);
let candidates = graph.pmmEdges.filter((e) => {
if (tokenFilter.size > 0 && !tokenFilter.has(e.base)) return false;
if (quoteFilter.size > 0 && !quoteFilter.has(e.quote)) return false;
return true;
});
if (policy.preferMatchedQuote) {
const perChainBase = new Map();
for (const edge of candidates) {
const key = `${edge.chainId}:${edge.base}`;
const preferredQuote = getMatchedQuoteForBase(edge.base);
const existing = perChainBase.get(key);
if (!existing) {
perChainBase.set(key, edge);
continue;
}
const score = edge.quote === preferredQuote ? 0 : 1;
const existingScore = existing.quote === preferredQuote ? 0 : 1;
if (
score < existingScore
|| (score === existingScore && edge.quote.localeCompare(existing.quote) < 0)
) {
perChainBase.set(key, edge);
}
}
candidates = Array.from(perChainBase.values());
}
candidates.sort((a, b) => (
a.chainId.localeCompare(b.chainId)
|| a.base.localeCompare(b.base)
|| a.quote.localeCompare(b.quote)
));
return candidates;
}
function resolveMicroTradeDirection(policy, poolState, epochIndex, tradeIndex) {
const mode = policy.mode || 'inventory_or_alternate';
const bandFrac = Number(policy.inventoryBandFraction ?? 0.05);
const lower = (1 - bandFrac) * poolState.I_T_star;
const upper = (1 + bandFrac) * poolState.I_T_star;
if (mode === 'inventory' || mode === 'inventory_or_alternate') {
if (poolState.I_T < lower) return 'sell_base';
if (poolState.I_T > upper) return 'buy_base';
if (mode === 'inventory') return null;
}
if (mode === 'alternate' || mode === 'inventory_or_alternate') {
return ((epochIndex + tradeIndex) % 2 === 0) ? 'buy_base' : 'sell_base';
}
if (mode === 'buy_base') return 'buy_base';
if (mode === 'sell_base') return 'sell_base';
return null;
}
function runMicroTradeSupportStep(graph, state, scenario, epochIndex) {
const policy = scenario.microTradePolicy || {};
if (policy.enabled === false || Object.keys(policy).length === 0) {
return {
state,
microTradeCount: 0,
microTradeBuyCount: 0,
microTradeSellCount: 0,
microTradeVolumeTotal: 0,
microTradeGasCostTotal: 0,
};
}
const requestedTrades = Math.max(0, parseInt(policy.tradesPerEpoch ?? 0, 10));
if (requestedTrades === 0) {
return {
state,
microTradeCount: 0,
microTradeBuyCount: 0,
microTradeSellCount: 0,
microTradeVolumeTotal: 0,
microTradeGasCostTotal: 0,
};
}
const candidates = getMicroTradeCandidates(graph, policy);
if (candidates.length === 0) {
return {
state,
microTradeCount: 0,
microTradeBuyCount: 0,
microTradeSellCount: 0,
microTradeVolumeTotal: 0,
microTradeGasCostTotal: 0,
};
}
const gasCostPerTrade = Number(policy.gasCostPerTradeUnits ?? 0);
const gasBudgetPerEpoch = Number(policy.gasBudgetPerEpochUnits ?? 0);
let tradesAllowed = requestedTrades;
if (gasCostPerTrade > 0 && gasBudgetPerEpoch > 0) {
tradesAllowed = Math.min(tradesAllowed, Math.floor(gasBudgetPerEpoch / gasCostPerTrade));
}
if (tradesAllowed <= 0) {
return {
state,
microTradeCount: 0,
microTradeBuyCount: 0,
microTradeSellCount: 0,
microTradeVolumeTotal: 0,
microTradeGasCostTotal: 0,
};
}
let curState = state;
let microTradeCount = 0;
let microTradeBuyCount = 0;
let microTradeSellCount = 0;
let microTradeVolumeTotal = 0;
let microTradeGasCostTotal = 0;
for (let i = 0; i < tradesAllowed; i++) {
const edge = candidates[(epochIndex * tradesAllowed + i) % candidates.length];
const poolState = curState[edge.key];
if (!poolState || poolState.I_T_star == null) continue;
const rawTradeSize = Number(policy.tradeSizeUnits ?? 0);
const maxFractionOfTarget = Number(policy.maxFractionOfTarget ?? 0.01);
const maxTradeSize = maxFractionOfTarget > 0 ? poolState.I_T_star * maxFractionOfTarget : rawTradeSize;
const tradeSize = Math.max(0, Math.min(rawTradeSize, maxTradeSize || rawTradeSize));
if (tradeSize <= 0) continue;
const direction = resolveMicroTradeDirection(policy, poolState, epochIndex, i);
if (!direction) continue;
if (direction === 'sell_base') {
const { newState } = pmmSellT(edge.key, tradeSize, curState);
curState = newState;
microTradeSellCount += 1;
microTradeVolumeTotal += tradeSize;
} else {
const quoteSpend = tradeSize * (poolState.P || 1);
const { outputT, newState } = pmmBuyT(edge.key, quoteSpend, curState);
curState = newState;
microTradeBuyCount += 1;
microTradeVolumeTotal += outputT;
}
microTradeCount += 1;
microTradeGasCostTotal += gasCostPerTrade;
}
return {
state: curState,
microTradeCount,
microTradeBuyCount,
microTradeSellCount,
microTradeVolumeTotal,
microTradeGasCostTotal,
};
}
function runBotStep(graph, state, scenario, configs) {
const chains = graph.chains;
let curState = state;
@@ -519,6 +764,7 @@ function getCandidatePaths(chainId, fromToken, toToken, graph, state, probeSize,
paths = paths.filter((p) => {
const first = p[0];
if (first.type === 'pmm' && publicEnabled === false) return false;
if (first.type === 'pmm' && first.publicRoutingEnabled === false) return false;
return true;
});
@@ -625,6 +871,11 @@ function runEpoch(scenario, graph, state, configs, epochIndex) {
let pmmVolume = 0;
let churnSum = 0;
const I_T_start = {};
let microTradeCount = 0;
let microTradeBuyCount = 0;
let microTradeSellCount = 0;
let microTradeVolumeTotal = 0;
let microTradeGasCostTotal = 0;
for (const k of Object.keys(state)) {
if (state[k].I_T_star != null) I_T_start[k] = state[k].I_T;
@@ -682,6 +933,15 @@ function runEpoch(scenario, graph, state, configs, epochIndex) {
}
}
const micro = runMicroTradeSupportStep(graph, curState, scenario, epochIndex);
curState = micro.state;
microTradeCount += micro.microTradeCount || 0;
microTradeBuyCount += micro.microTradeBuyCount || 0;
microTradeSellCount += micro.microTradeSellCount || 0;
microTradeVolumeTotal += micro.microTradeVolumeTotal || 0;
microTradeGasCostTotal += micro.microTradeGasCostTotal || 0;
totalVolume += micro.microTradeVolumeTotal || 0;
const peakDeviationBpsPreArb = maxDeviationBpsOverPools(graph, curState);
const worstPreArb = getWorstPoolDiagnostic(graph, curState);
const { state: afterArb, arbVolumeTotal, arbProfitTotal, peakDeviationBps: peakDeviationBpsPostArb } = runArbStep(graph, curState, configs);
@@ -702,7 +962,7 @@ function runEpoch(scenario, graph, state, configs, epochIndex) {
const totalPathVol = Object.values(pathShares).reduce((a, b) => a + b, 0);
if (totalPathVol > 0) {
pmmVolume = Object.entries(pathShares)
.filter(([pk]) => pk.includes(':cW'))
.filter(([pk]) => pk.split('|').some((part) => !part.includes(':amm:')))
.reduce((a, [, v]) => a + v, 0);
}
@@ -717,6 +977,11 @@ function runEpoch(scenario, graph, state, configs, epochIndex) {
interventionCostInject: interventionCostInject || 0,
interventionCostWithdraw: interventionCostWithdraw || 0,
interventionCostByChain: interventionCostByChain || {},
microTradeCount,
microTradeBuyCount,
microTradeSellCount,
microTradeVolumeTotal,
microTradeGasCostTotal,
peakDeviationBpsPreArb: peakDeviationBpsPreArb || 0,
peakDeviationBpsPostArb: peakDeviationBpsPostArb || 0,
peakDeviationBpsPostBot: peakDeviationBpsPostBot || 0,
@@ -753,6 +1018,11 @@ function computeScorecard(scenario, scenarioName, graph, initialState, epochResu
let peakDeviationBpsPreArb = 0;
let peakDeviationBpsPostArb = 0;
let peakDeviationBpsPostBot = 0;
let microTradeCountTotal = 0;
let microTradeBuyCountTotal = 0;
let microTradeSellCountTotal = 0;
let microTradeVolumeTotal = 0;
let microTradeGasCostTotal = 0;
for (const r of epochResults) {
totalVolume += r.totalVolume;
@@ -763,6 +1033,11 @@ function computeScorecard(scenario, scenarioName, graph, initialState, epochResu
arbProfitTotal += r.arbProfitTotal || 0;
interventionCostInjectTotal += r.interventionCostInject || 0;
interventionCostWithdrawTotal += r.interventionCostWithdraw || 0;
microTradeCountTotal += r.microTradeCount || 0;
microTradeBuyCountTotal += r.microTradeBuyCount || 0;
microTradeSellCountTotal += r.microTradeSellCount || 0;
microTradeVolumeTotal += r.microTradeVolumeTotal || 0;
microTradeGasCostTotal += r.microTradeGasCostTotal || 0;
for (const [chainId, v] of Object.entries(r.interventionCostByChain || {})) {
if (!interventionCostByChain[chainId]) interventionCostByChain[chainId] = { inject: 0, withdraw: 0 };
interventionCostByChain[chainId].inject += v.inject || 0;
@@ -827,7 +1102,7 @@ function computeScorecard(scenario, scenarioName, graph, initialState, epochResu
return {
scenario: scenario.scenario || scenarioName,
runId: `run-${Date.now()}`,
runId: `run-${scenario.seed != null ? Number(scenario.seed) : hashScenarioName(scenarioName)}`,
capture_mean: Math.min(1, Math.max(0, captureMean)),
capture_p95: Math.min(1, captureMean * 1.2),
churn_mean: churnMeanNorm,
@@ -838,6 +1113,11 @@ function computeScorecard(scenario, scenarioName, graph, initialState, epochResu
intervention_cost_withdraw_total: Math.round(interventionCostWithdrawTotal),
intervention_cost_by_chain: interventionCostByChain,
intervention_cost_per_1M_volume: Math.round(interventionPer1M * 100) / 100,
micro_trade_count: Math.round(microTradeCountTotal),
micro_trade_buy_count: Math.round(microTradeBuyCountTotal),
micro_trade_sell_count: Math.round(microTradeSellCountTotal),
micro_trade_volume_total: Math.round(microTradeVolumeTotal),
micro_trade_gas_cost_total: Math.round(microTradeGasCostTotal * 100) / 100,
peak_deviation_bps: Math.round(Number.isFinite(peakDeviationBpsPostArb) ? peakDeviationBpsPostArb : 0),
peak_deviation_bps_pre_arb: Math.round(peakDeviationBpsPreArb),
peak_deviation_bps_post_arb: Math.round(peakDeviationBpsPostArb),
@@ -851,9 +1131,334 @@ function computeScorecard(scenario, scenarioName, graph, initialState, epochResu
};
}
function mergeCapitalConfig(policy, scenarioConfig = {}, overrides = {}) {
const defaults = policy.defaults || {};
const risk = { ...(policy.risk || {}), ...(scenarioConfig.risk || {}), ...(overrides.risk || {}) };
const treasury = { ...(policy.treasury || {}), ...(scenarioConfig.treasury || {}), ...(overrides.treasury || {}) };
const volatility = { ...(policy.volatilityProcess || {}), ...(scenarioConfig.volatilityProcess || {}), ...(overrides.volatilityProcess || {}) };
const peg = { ...(policy.pegDynamics || {}), ...(scenarioConfig.pegDynamics || {}), ...(overrides.pegDynamics || {}) };
const stress = { ...(scenarioConfig.stress || {}), ...(overrides.stress || {}) };
return {
enabled: scenarioConfig.enabled === true || overrides.enabled === true,
paths: Number(overrides.paths ?? scenarioConfig.paths ?? defaults.paths ?? 1000),
epochs: Number(overrides.epochs ?? scenarioConfig.epochs ?? defaults.epochs ?? 365),
seed: Number(overrides.seed ?? scenarioConfig.seed ?? defaults.seed ?? 138001),
initialCapital: Number(overrides.initialCapital ?? scenarioConfig.initialCapital ?? defaults.initialCapital ?? 1000000),
alpha: Number(overrides.alpha ?? scenarioConfig.alpha ?? defaults.alpha ?? 0.7),
leverage: Number(overrides.leverage ?? scenarioConfig.leverage ?? defaults.leverage ?? 2),
spreadBps: Number(overrides.spreadBps ?? scenarioConfig.spreadBps ?? defaults.spreadBps ?? 35),
volumeEfficiency: Number(overrides.volumeEfficiency ?? scenarioConfig.volumeEfficiency ?? defaults.volumeEfficiency ?? 2),
pmmK: Number(overrides.pmmK ?? scenarioConfig.pmmK ?? defaults.pmmK ?? 0.1),
liquidityTargetUnits: Number(overrides.liquidityTargetUnits ?? scenarioConfig.liquidityTargetUnits ?? defaults.liquidityTargetUnits ?? 1000000),
treasury,
volatility,
peg,
risk,
stress,
};
}
function getStressForEpoch(stress, epoch, initialCapital) {
const out = {
externalAssetReturn: 0,
volatilityAdd: 0,
redemptionFraction: 0,
imbalanceAdd: 0,
liquidationLossFraction: 0,
};
const events = Array.isArray(stress.events) ? stress.events : [];
for (const ev of events) {
const at = Number(ev.epoch ?? 0);
const duration = Math.max(1, Number(ev.durationEpochs ?? 1));
if (epoch < at || epoch >= at + duration) continue;
if (ev.type === 'crash') out.externalAssetReturn += Number(ev.externalAssetReturn ?? -0.4) / duration;
if (ev.type === 'high_volatility') out.volatilityAdd += Number(ev.sigmaAdd ?? 0.05);
if (ev.type === 'bank_run') out.redemptionFraction += Number(ev.redemptionFraction ?? 0.1) / duration;
if (ev.type === 'bridge_shock') out.imbalanceAdd += Number(ev.imbalanceAdd ?? 0.05);
if (ev.type === 'liquidation_loss') out.liquidationLossFraction += Number(ev.lossFraction ?? 0.05);
}
if (stress.preset === 'crash_40pct_external_asset' && epoch === Number(stress.epoch ?? 24)) {
out.externalAssetReturn -= 0.4;
}
if (stress.preset === 'high_vol_sigma_spike') {
const at = Number(stress.epoch ?? 24);
const duration = Math.max(1, Number(stress.durationEpochs ?? 24));
if (epoch >= at && epoch < at + duration) out.volatilityAdd += Number(stress.sigmaAdd ?? 0.08);
}
if (stress.preset === 'bank_run_redemption_spike') {
const at = Number(stress.epoch ?? 24);
const duration = Math.max(1, Number(stress.durationEpochs ?? 12));
if (epoch >= at && epoch < at + duration) out.redemptionFraction += Number(stress.redemptionFraction ?? 0.25) / duration;
}
if (stress.preset === 'bridge_shock') {
const at = Number(stress.epoch ?? 24);
const duration = Math.max(1, Number(stress.durationEpochs ?? 24));
if (epoch >= at && epoch < at + duration) out.imbalanceAdd += Number(stress.imbalanceAdd ?? 0.05);
}
if (initialCapital <= 0) out.redemptionFraction = 0;
return out;
}
function simulateCapitalPath(config, baselineScorecard) {
const risk = config.risk || {};
const treasury = config.treasury || {};
const vol = config.volatility || {};
const peg = config.peg || {};
const spreadRate = config.spreadBps / 10000;
const minExternalLiquidityPct = Number(risk.minExternalLiquidityPct ?? 0.2);
const maxLtv = Number(risk.maxLtvBps ?? 6500) / 10000;
const hardMaxLtv = Number(risk.hardMaxLtvBps ?? 7500) / 10000;
const hardMaxLeverage = Number(risk.hardMaxLeverage ?? 4);
const liquidationLtv = Math.min(hardMaxLtv, Number(risk.liquidationLtvBps ?? 8000) / 10000);
const sigmaCrit = Number(risk.sigmaCrit ?? 0.08);
const throttleLeverageMultiplier = Number(risk.throttleLeverageMultiplier ?? 0.7);
const throttleAlphaMultiplier = Number(risk.throttleAlphaMultiplier ?? 0.9);
const pegCircuitBreakerBps = Number(risk.pegCircuitBreakerBps ?? 200);
const volDrag = Number(treasury.volatilityDragLambda ?? 0.35);
const yieldRate = Number(treasury.yieldRatePerEpoch ?? 0.00035);
const mmScale = Number(treasury.marketMakingScale ?? 0.04);
const liquidationLossFraction = Number(risk.liquidationLossFraction ?? 0.08);
const redemptionFeeBps = Number(risk.bankRunRedemptionFeeBps ?? 100);
let T = config.initialCapital;
let highWater = T;
let maxDrawdown = 0;
let sigma = Number(vol.sigma0 ?? vol.sigmaBar ?? 0.03);
let P = Number(peg.p0 ?? 1);
let liquidated = false;
let pegDeviationEpochs = 0;
let externalLiquidityFloorViolations = 0;
let volatilityThrottleEvents = 0;
let spreadAdjustmentEvents = 0;
let liquidationEvents = 0;
let totalPnl = 0;
const baselineInterventionDrag = Math.min(0.002, Number(baselineScorecard.intervention_cost_per_1M_volume || 0) / 1e9);
const baselinePegPressure = Math.min(0.1, Number(baselineScorecard.peak_deviation_bps || 0) / 10000);
for (let e = 0; e < config.epochs; e++) {
if (liquidated || T <= 0) break;
const stress = getStressForEpoch(config.stress || {}, e, T);
const z = normalSample();
sigma = Math.max(0, sigma + Number(vol.kappa ?? 0.08) * (Number(vol.sigmaBar ?? 0.03) - sigma) + Number(vol.eta ?? 0.01) * z + stress.volatilityAdd);
let effectiveAlpha = config.alpha;
let effectiveLeverage = config.leverage;
let effectiveSpreadBps = config.spreadBps;
if (sigma > sigmaCrit) {
effectiveAlpha *= throttleAlphaMultiplier;
effectiveLeverage = Math.max(1, effectiveLeverage * throttleLeverageMultiplier);
effectiveSpreadBps = Math.min(Number(risk.maxSpreadBps ?? 100), Math.max(effectiveSpreadBps, Number(risk.throttleSpreadBps ?? 50)));
volatilityThrottleEvents += 1;
spreadAdjustmentEvents += 1;
}
if (effectiveLeverage > hardMaxLeverage) {
liquidated = true;
liquidationEvents += 1;
T = Math.max(0, T * (1 - liquidationLossFraction));
maxDrawdown = Math.max(maxDrawdown, highWater > 0 ? (highWater - T) / highWater : 0);
break;
}
const externalLiquidity = (1 - effectiveAlpha) * T;
if (externalLiquidity < minExternalLiquidityPct * T) {
externalLiquidityFloorViolations += 1;
effectiveAlpha = Math.min(effectiveAlpha, 1 - minExternalLiquidityPct);
spreadAdjustmentEvents += 1;
}
const grossLeveredExposure = effectiveLeverage * effectiveAlpha * T;
const debt = Math.max(0, (effectiveLeverage - 1) * effectiveAlpha * T);
const collateralShock = 1 + stress.externalAssetReturn - sigma * Number(risk.collateralVolatilityHaircut ?? 0.5);
const collateral = Math.max(0, grossLeveredExposure * collateralShock);
const ltv = collateral > 0 ? debt / collateral : 1;
if (ltv > liquidationLtv || ltv > maxLtv * Number(risk.maxLtvBreachMultiplier ?? 1.2)) {
liquidated = true;
liquidationEvents += 1;
T = Math.max(0, T * (1 - liquidationLossFraction - stress.liquidationLossFraction));
maxDrawdown = Math.max(maxDrawdown, highWater > 0 ? (highWater - T) / highWater : 0);
break;
}
const imbalance = Number(peg.imbalanceStd ?? 0.01) * normalSample() + stress.imbalanceAdd + baselinePegPressure;
const arbFlow = Number(peg.arbLiquidityCoefficient ?? 0.65) * (P - 1);
P = P + Number(peg.beta ?? 0.25) * imbalance - arbFlow;
const pegDeviationBps = Math.abs(P - 1) * 10000;
if (pegDeviationBps > pegCircuitBreakerBps) {
pegDeviationEpochs += 1;
effectiveSpreadBps = Math.min(Number(risk.maxSpreadBps ?? 100), Math.max(effectiveSpreadBps, Number(risk.circuitBreakerSpreadBps ?? 100)));
spreadAdjustmentEvents += 1;
}
const sqrtAllocation = Math.sqrt(Math.max(0, effectiveAlpha * (1 - effectiveAlpha)));
const yieldComponent = yieldRate * effectiveAlpha * effectiveLeverage;
const mmComponent = (effectiveSpreadBps / 10000) * config.volumeEfficiency * sqrtAllocation * sigma * mmScale;
const volatilityDrag = volDrag * sigma * Math.max(0.25, effectiveLeverage - 0.5) / 365;
const redemptionDrag = stress.redemptionFraction * (1 - redemptionFeeBps / 10000);
const pnlRate = yieldComponent + mmComponent - volatilityDrag - baselineInterventionDrag - redemptionDrag;
const pnl = T * pnlRate;
totalPnl += pnl;
T = Math.max(0, T + pnl);
highWater = Math.max(highWater, T);
maxDrawdown = Math.max(maxDrawdown, highWater > 0 ? (highWater - T) / highWater : 0);
}
return {
endingCapital: T,
roi: config.initialCapital > 0 ? (T - config.initialCapital) / config.initialCapital : 0,
totalPnl,
maxDrawdown,
liquidated,
liquidationEvents,
pegDeviationEpochs,
externalLiquidityFloorViolations,
volatilityThrottleEvents,
spreadAdjustmentEvents,
};
}
function runCapitalMonteCarlo(scenario, scenarioName, configs, baselineScorecard, overrides = {}) {
const capitalConfig = mergeCapitalConfig(configs.capitalEfficiencyPolicy || {}, scenario.capitalEfficiency || {}, overrides);
if (!capitalConfig.enabled) return null;
const baseSeed = capitalConfig.seed != null ? Number(capitalConfig.seed) : hashScenarioName(`${scenarioName}:capital`);
const rois = [];
const pnls = [];
const drawdowns = [];
let liquidationCount = 0;
let pegDeviationEpochs = 0;
let externalLiquidityFloorViolations = 0;
let volatilityThrottleEvents = 0;
let spreadAdjustmentEvents = 0;
for (let p = 0; p < capitalConfig.paths; p++) {
seedRng((baseSeed + Math.imul(p + 1, 2654435761)) >>> 0);
const result = simulateCapitalPath(capitalConfig, baselineScorecard);
rois.push(result.roi);
pnls.push(result.totalPnl);
drawdowns.push(result.maxDrawdown);
if (result.liquidated) liquidationCount += 1;
pegDeviationEpochs += result.pegDeviationEpochs;
externalLiquidityFloorViolations += result.externalLiquidityFloorViolations;
volatilityThrottleEvents += result.volatilityThrottleEvents;
spreadAdjustmentEvents += result.spreadAdjustmentEvents;
}
const totalEpochs = Math.max(1, capitalConfig.paths * capitalConfig.epochs);
return {
capital_efficiency_enabled: true,
capital_efficiency_paths: capitalConfig.paths,
capital_efficiency_epochs: capitalConfig.epochs,
initial_capital: Math.round(capitalConfig.initialCapital),
alpha: round4(capitalConfig.alpha),
leverage: round4(capitalConfig.leverage),
spread_bps: round2(capitalConfig.spreadBps),
volume_efficiency: round4(capitalConfig.volumeEfficiency),
pmm_k: round4(capitalConfig.pmmK),
liquidity_target_units: Math.round(capitalConfig.liquidityTargetUnits),
roi_mean: round4(rois.reduce((a, b) => a + b, 0) / Math.max(1, rois.length)),
roi_p05: round4(percentile(rois, 5)),
roi_p95: round4(percentile(rois, 95)),
pnl_distribution: {
p05: round2(percentile(pnls, 5)),
p50: round2(percentile(pnls, 50)),
p95: round2(percentile(pnls, 95)),
},
max_drawdown_p95: round4(percentile(drawdowns, 95)),
liquidation_probability: round4(liquidationCount / Math.max(1, capitalConfig.paths)),
peg_deviation_frequency: round4(pegDeviationEpochs / totalEpochs),
external_liquidity_floor_violations: externalLiquidityFloorViolations,
volatility_throttle_events: volatilityThrottleEvents,
spread_adjustment_events: spreadAdjustmentEvents,
};
}
function passesCapitalGates(metrics, policy, overrides = {}) {
const gates = { ...(policy.gates || {}), ...(overrides.gates || {}) };
return (
metrics.leverage <= Number((policy.risk || {}).hardMaxLeverage ?? 4)
&& metrics.leverage <= Number(gates.maxDeployableLeverage ?? (policy.risk || {}).hardMaxLeverage ?? 4)
&& metrics.liquidation_probability <= Number(gates.maxLiquidationProbability ?? 0.02)
&& metrics.max_drawdown_p95 <= Number(gates.maxDrawdownP95 ?? 0.25)
&& metrics.peg_deviation_frequency <= Number(gates.maxPegDeviationFrequency ?? 0.05)
&& metrics.external_liquidity_floor_violations <= Number(gates.maxExternalLiquidityFloorViolations ?? 0)
);
}
function buildOptimizerGrid(policy, scenarioConfig) {
const opt = scenarioConfig.optimizer || {};
const grid = opt.grid || {};
const alphas = grid.alpha || [0.65, 0.7, 0.75, 0.8, 0.85];
const leverages = grid.leverage || [1, 2, 2.5, 3];
const spreads = grid.spreadBps || [30, 40, 50];
const pmmKs = grid.pmmK || [0.1, 0.15, 0.2];
const liquidityTargets = grid.liquidityTargetUnits || [500000, 1000000, 1500000];
const out = [];
for (const alpha of alphas) {
for (const leverage of leverages) {
for (const spreadBps of spreads) {
for (const pmmK of pmmKs) {
for (const liquidityTargetUnits of liquidityTargets) {
out.push({ alpha, leverage, spreadBps, pmmK, liquidityTargetUnits });
}
}
}
}
}
const limit = Number(opt.maxCandidates ?? (policy.optimizer || {}).maxCandidates ?? 250);
return out.slice(0, limit);
}
function capitalBand(initialCapital) {
if (initialCapital < 500000) return "sub_500k";
if (initialCapital < 2000000) return "500k_2m";
if (initialCapital < 10000000) return "2m_10m";
return "10m_plus";
}
function runOptimizer(scenario, scenarioName, configs, baselineScorecard) {
const policy = configs.capitalEfficiencyPolicy || {};
const scenarioConfig = scenario.capitalEfficiency || {};
const grid = buildOptimizerGrid(policy, scenarioConfig);
const candidates = [];
for (let i = 0; i < grid.length; i++) {
const overrides = {
enabled: true,
...grid[i],
paths: Number((scenarioConfig.optimizer || {}).paths ?? (policy.optimizer || {}).paths ?? 250),
seed: (Number(scenarioConfig.seed ?? (policy.defaults || {}).seed ?? 138001) + i * 9973) >>> 0,
};
const metrics = runCapitalMonteCarlo(scenario, scenarioName, configs, baselineScorecard, overrides);
const deployable = passesCapitalGates(metrics, policy, scenarioConfig.optimizer || {});
candidates.push({
rank_score: round4(metrics.roi_mean - metrics.liquidation_probability * 2 - metrics.max_drawdown_p95 * 0.5 - metrics.peg_deviation_frequency),
deployable,
...metrics,
});
}
candidates.sort((a, b) => {
if (a.deployable !== b.deployable) return a.deployable ? -1 : 1;
return b.rank_score - a.rank_score;
});
const top = candidates.slice(0, Number((scenarioConfig.optimizer || {}).topN ?? 10));
return {
scenario: `${scenario.scenario || scenarioName}:optimizer`,
runId: `optimizer-${scenarioConfig.seed != null ? Number(scenarioConfig.seed) : hashScenarioName(`${scenarioName}:optimizer`)}`,
optimizer_enabled: true,
capital_band: capitalBand(Number((scenarioConfig.initialCapital ?? (policy.defaults || {}).initialCapital) || 0)),
candidates_evaluated: candidates.length,
deployable_candidates: candidates.filter((c) => c.deployable).length,
top_candidates: top,
};
}
function main() {
const idx = process.argv.indexOf('--scenario');
const scenarioName = idx >= 0 && process.argv[idx + 1] ? process.argv[idx + 1] : process.argv[2] || 'hub_only_11';
const optimizerMode = process.argv.includes('--optimizer') || process.argv.includes('--optimize');
const positional = process.argv.slice(2).filter((arg, i, args) => {
if (arg.startsWith('--')) return false;
const prev = args[i - 1];
return prev !== '--scenario';
});
const scenarioName = idx >= 0 && process.argv[idx + 1] ? process.argv[idx + 1] : positional[0] || 'hub_only_11';
const scenarioPath = path.join(SCENARIOS_DIR, `${scenarioName}.json`);
if (!fs.existsSync(scenarioPath)) {
process.stderr.write(`Scenario not found: ${scenarioPath}\n`);
@@ -877,7 +1482,13 @@ function main() {
}
const scorecard = computeScorecard(scenario, scenarioName, graph, initialState, epochResults);
console.log(JSON.stringify(scorecard, null, 2));
const capitalMetrics = runCapitalMonteCarlo(scenario, scenarioName, configs, scorecard);
const fullScorecard = capitalMetrics ? { ...scorecard, ...capitalMetrics } : scorecard;
if (optimizerMode || scenario.capitalEfficiency?.optimizer?.enabled === true) {
console.log(JSON.stringify(runOptimizer(scenario, scenarioName, configs, fullScorecard), null, 2));
return;
}
console.log(JSON.stringify(fullScorecard, null, 2));
}
main();

View File

@@ -0,0 +1,130 @@
#!/usr/bin/env node
/**
* CI-style validation for the simulation-only capital efficiency overlay.
*
* Checks:
* - JSON configs and scenario files parse.
* - Baseline scenario stays capital-overlay free.
* - Capital stress scenarios emit required risk metrics.
* - Deterministic seeds produce byte-identical scorecards.
* - Optimizer never marks leverage above policy gates as deployable.
*/
const fs = require('fs');
const path = require('path');
const { execFileSync } = require('child_process');
const ROOT = path.join(__dirname, '..');
const CONFIG_DIR = path.join(ROOT, 'config');
const SCENARIOS_DIR = path.join(CONFIG_DIR, 'scenarios');
const RUNNER = path.join(ROOT, 'scripts', 'run-scenario.cjs');
const REQUIRED_CAPITAL_FIELDS = [
'roi_mean',
'roi_p05',
'roi_p95',
'pnl_distribution',
'max_drawdown_p95',
'liquidation_probability',
'peg_deviation_frequency',
'external_liquidity_floor_violations',
'volatility_throttle_events',
'spread_adjustment_events',
];
const STRESS_SCENARIOS = [
'crash_40pct_external_asset',
'high_vol_sigma_spike',
'bank_run_redemption_spike',
];
function readJson(file) {
return JSON.parse(fs.readFileSync(file, 'utf8'));
}
function runScenario(name, extraArgs = []) {
const out = execFileSync(process.execPath, [RUNNER, ...extraArgs, name], {
cwd: ROOT,
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
});
return { raw: out, json: JSON.parse(out) };
}
function fail(msg) {
process.stderr.write(`[capital-efficiency] ${msg}\n`);
process.exit(1);
}
function assert(cond, msg) {
if (!cond) fail(msg);
}
function main() {
const files = [
path.join(CONFIG_DIR, 'scenario-schema.json'),
path.join(CONFIG_DIR, 'scorecard-schema.json'),
path.join(CONFIG_DIR, 'capital-efficiency-policy.json'),
...fs.readdirSync(SCENARIOS_DIR)
.filter((f) => f.endsWith('.json'))
.map((f) => path.join(SCENARIOS_DIR, f)),
];
for (const file of files) readJson(file);
const policy = readJson(path.join(CONFIG_DIR, 'capital-efficiency-policy.json'));
const maxDeployableLeverage = Number(policy.gates?.maxDeployableLeverage ?? policy.risk?.hardMaxLeverage ?? 4);
const gates = policy.gates || {};
const maxLiquidationProbability = Number(gates.maxLiquidationProbability ?? 0.02);
const maxDrawdownP95 = Number(gates.maxDrawdownP95 ?? 0.25);
const maxPegDeviationFrequency = Number(gates.maxPegDeviationFrequency ?? 0.05);
const maxExternalLiquidityFloorViolations = Number(gates.maxExternalLiquidityFloorViolations ?? 0);
const guard = policy.liveExecutionGuard || {};
assert(guard.status === 'simulation_only', 'liveExecutionGuard.status must remain simulation_only until external approvals exist');
assert(guard.riskDashboardEvidence, 'risk dashboard evidence path is required');
assert(guard.operatorRunbookEvidence, 'operator runbook evidence path is required');
assert(guard.treasuryLiquidityCommitmentEvidence, 'treasury liquidity commitment evidence path is required');
for (const evidencePath of [
guard.riskDashboardEvidence,
guard.operatorRunbookEvidence,
guard.treasuryLiquidityCommitmentEvidence,
]) {
assert(fs.existsSync(path.join(ROOT, evidencePath)), `evidence path missing: ${evidencePath}`);
}
const baseline = runScenario('hub_only_11').json;
assert(baseline.capital_efficiency_enabled !== true, 'hub_only_11 unexpectedly enabled capital overlay');
for (const scenario of [
'chain138_deployed_capital_efficiency',
...STRESS_SCENARIOS,
]) {
const scorecard = runScenario(scenario).json;
assert(scorecard.capital_efficiency_enabled === true, `${scenario} did not emit capital overlay`);
for (const field of REQUIRED_CAPITAL_FIELDS) {
assert(Object.prototype.hasOwnProperty.call(scorecard, field), `${scenario} missing ${field}`);
}
if (STRESS_SCENARIOS.includes(scenario)) {
assert(scorecard.liquidation_probability <= maxLiquidationProbability, `${scenario} liquidation probability exceeds gate`);
assert(scorecard.max_drawdown_p95 <= maxDrawdownP95, `${scenario} p95 drawdown exceeds gate`);
assert(scorecard.peg_deviation_frequency <= maxPegDeviationFrequency, `${scenario} peg deviation frequency exceeds gate`);
assert(scorecard.external_liquidity_floor_violations <= maxExternalLiquidityFloorViolations, `${scenario} external liquidity floor violations exceed gate`);
}
}
const a = runScenario('crash_40pct_external_asset').raw;
const b = runScenario('crash_40pct_external_asset').raw;
assert(a === b, 'deterministic seed repeat check failed for crash_40pct_external_asset');
const optimizer = runScenario('leverage_sweep_1x_to_4x', ['--optimizer']).json;
assert(optimizer.optimizer_enabled === true, 'optimizer did not emit optimizer payload');
for (const candidate of optimizer.top_candidates || []) {
if (candidate.deployable) {
assert(candidate.leverage <= maxDeployableLeverage, `deployable candidate exceeds maxDeployableLeverage: ${candidate.leverage}`);
}
}
process.stdout.write('capital efficiency validation OK\n');
}
main();

View File

@@ -5,8 +5,11 @@
*
* Rules:
* - If bridgeAvailable === true on a chain, cwTokens must include at least cWUSDT and cWUSDC (phase 1).
* - For each pmmPool: role in {defense, public_routing}, feeBps and k present,
* base/quote (or tokenIn/tokenOut) exist in cwTokens or anchorAddresses.
* - For each pmmPool / pmmPoolsVolatile[]: role in {defense, public_routing, truu_routing},
* feeBps and k present, base/quote (or tokenIn/tokenOut) exist in cwTokens or anchorAddresses.
* TRUU must be listed under anchorAddresses when used as quote (e.g. mainnet chain 1).
* - Any row marked live/routingVisible/publicRoutingEnabled must use a native protocol contract,
* not a placeholder scaffold or aggregator-only/non-native lane.
*
* Exit code: 0 if valid, 1 if invalid (and prints errors to stderr).
*/
@@ -15,27 +18,113 @@ const fs = require('fs');
const path = require('path');
const CONFIG_DIR = path.join(__dirname, '..', 'config');
const DEPLOYMENT_STATUS_PATH = path.join(CONFIG_DIR, 'deployment-status.json');
let DEPLOYMENT_STATUS_PATH = path.join(CONFIG_DIR, 'deployment-status.json');
const PHASE1_CW = ['cWUSDT', 'cWUSDC'];
const VALID_ROLES = ['defense', 'public_routing'];
const VALID_ROLES = ['defense', 'public_routing', 'truu_routing'];
const VALID_REFERENCE_PROTOCOLS = ['uniswap_v3', 'balancer', 'curve', '1inch'];
const VALID_NATIVE_REFERENCE_PROTOCOLS = ['uniswap_v3', 'balancer', 'curve'];
const HOME_CHAIN_CANONICAL_PREFIXES = ['c'];
function looksPlaceholderAddress(address) {
if (!address || typeof address !== 'string') return false;
const normalized = address.toLowerCase();
if (!/^0x[0-9a-f]{40}$/.test(normalized)) return false;
if (normalized === '0x0000000000000000000000000000000000000000') return true;
const body = normalized.slice(2);
const placeholderPrefixes = ['d0', '71', 'ba', 'c7'];
const zeroCount = body.split('0').length - 1;
return placeholderPrefixes.some((prefix) => body.startsWith(prefix)) && zeroCount >= 24;
}
function isLiveRow(row) {
return row?.live === true || row?.routingVisible === true || row?.publicRoutingEnabled === true;
}
function loadJson(p) {
return JSON.parse(fs.readFileSync(p, 'utf8'));
}
function validatePoolEntries(chainId, pools, listLabel, knownTokens, errors) {
for (let i = 0; i < pools.length; i++) {
const pool = pools[i];
const base = pool.base ?? pool.tokenIn;
const quote = pool.quote ?? pool.tokenOut;
if (!VALID_ROLES.includes(pool.role)) {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: role must be one of ${VALID_ROLES.join(', ')}`);
}
if (pool.feeBps == null || pool.k == null) {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: feeBps and k required`);
}
if (base && !knownTokens.has(base)) {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: base/tokenIn "${base}" not in cwTokens or anchorAddresses`);
}
if (quote && !knownTokens.has(quote)) {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: quote/tokenOut "${quote}" not in cwTokens or anchorAddresses`);
}
const addr = pool.poolAddress;
if (addr != null && addr !== '') {
const z = String(addr).toLowerCase();
if (z === '0x0000000000000000000000000000000000000000') {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: poolAddress must not be zero when set`);
}
if (pool.publicRoutingEnabled === true && looksPlaceholderAddress(z)) {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: live public routing poolAddress must use a native protocol contract, not a placeholder scaffold (${addr})`);
}
}
if (pool.publicRoutingEnabled === true && pool.venue && pool.venue !== 'dodo_pmm') {
errors.push(`Chain ${chainId} ${listLabel}[${i}]: public routing rows must use the native dodo_pmm venue, not "${pool.venue}"`);
}
}
}
function validateUniswapV2Entries(chainId, pools, knownTokens, errors) {
for (let i = 0; i < pools.length; i++) {
const pool = pools[i];
const base = pool.base;
const quote = pool.quote;
if (!base || !knownTokens.has(base)) {
errors.push(`Chain ${chainId} uniswapV2Pools[${i}]: base "${base}" not in cwTokens or anchorAddresses`);
}
if (!quote || !knownTokens.has(quote)) {
errors.push(`Chain ${chainId} uniswapV2Pools[${i}]: quote "${quote}" not in cwTokens or anchorAddresses`);
}
if (!pool.poolAddress || looksPlaceholderAddress(String(pool.poolAddress).toLowerCase())) {
errors.push(`Chain ${chainId} uniswapV2Pools[${i}]: poolAddress must use a real deployed pair address`);
}
if (pool.venue && pool.venue !== 'uniswap_v2_pair') {
errors.push(`Chain ${chainId} uniswapV2Pools[${i}]: venue must be "uniswap_v2_pair" when set`);
}
if (pool.publicRoutingEnabled === true && (!pool.factoryAddress || !pool.routerAddress)) {
errors.push(`Chain ${chainId} uniswapV2Pools[${i}]: publicRoutingEnabled rows require factoryAddress and routerAddress`);
}
}
}
function main() {
const status = loadJson(DEPLOYMENT_STATUS_PATH);
const chains = status.chains || {};
const homeChainId = String(status.homeChainId || '');
const errors = [];
for (const [chainId, chain] of Object.entries(chains)) {
const cwTokens = chain.cwTokens || {};
const gasMirrors = chain.gasMirrors || {};
const anchorAddresses = chain.anchorAddresses || {};
const gasQuoteAddresses = chain.gasQuoteAddresses || {};
const pmmPools = chain.pmmPools || [];
const uniswapV2Pools = chain.uniswapV2Pools || [];
const pmmPoolsVolatile = chain.pmmPoolsVolatile || [];
const gasPmmPools = chain.gasPmmPools || [];
const gasReferenceVenues = chain.gasReferenceVenues || [];
const bridgeAvailable = chain.bridgeAvailable;
if (bridgeAvailable === true) {
const isHomeChain = chainId === homeChainId;
const skipPhase1Requirement = isHomeChain || chainId === '651940';
if (bridgeAvailable === true && !skipPhase1Requirement) {
for (const sym of PHASE1_CW) {
if (!cwTokens[sym] || typeof cwTokens[sym] !== 'string' || !cwTokens[sym].trim()) {
errors.push(`Chain ${chainId} (${chain.name}): bridgeAvailable=true but cwTokens.${sym} missing or empty`);
@@ -43,24 +132,97 @@ function main() {
}
}
const knownTokens = new Set([...Object.keys(cwTokens), ...Object.keys(anchorAddresses)]);
const knownTokens = new Set([
...Object.keys(cwTokens),
...Object.keys(gasMirrors),
...Object.keys(anchorAddresses),
...Object.keys(gasQuoteAddresses),
]);
for (let i = 0; i < pmmPools.length; i++) {
const pool = pmmPools[i];
const base = pool.base ?? pool.tokenIn;
const quote = pool.quote ?? pool.tokenOut;
if (isHomeChain) {
for (const pool of [...pmmPools, ...pmmPoolsVolatile]) {
const base = pool.base ?? pool.tokenIn;
const quote = pool.quote ?? pool.tokenOut;
if (typeof base === 'string' && HOME_CHAIN_CANONICAL_PREFIXES.some((prefix) => base.startsWith(prefix))) {
knownTokens.add(base);
}
if (typeof quote === 'string' && HOME_CHAIN_CANONICAL_PREFIXES.some((prefix) => quote.startsWith(prefix))) {
knownTokens.add(quote);
}
}
}
if (!VALID_ROLES.includes(pool.role)) {
errors.push(`Chain ${chainId} pmmPools[${i}]: role must be one of ${VALID_ROLES.join(', ')}`);
validatePoolEntries(chainId, pmmPools, 'pmmPools', knownTokens, errors);
validateUniswapV2Entries(chainId, uniswapV2Pools, knownTokens, errors);
validatePoolEntries(chainId, pmmPoolsVolatile, 'pmmPoolsVolatile', knownTokens, errors);
validatePoolEntries(chainId, gasPmmPools, 'gasPmmPools', knownTokens, errors);
const gasPoolsByFamily = new Map();
for (const pool of gasPmmPools) {
if (!pool.familyKey || typeof pool.familyKey !== 'string') {
errors.push(`Chain ${chainId} gasPmmPools entry is missing familyKey`);
continue;
}
if (pool.feeBps == null || pool.k == null) {
errors.push(`Chain ${chainId} pmmPools[${i}]: feeBps and k required`);
if (!gasPoolsByFamily.has(pool.familyKey)) gasPoolsByFamily.set(pool.familyKey, []);
gasPoolsByFamily.get(pool.familyKey).push(pool);
}
for (const [familyKey, pools] of gasPoolsByFamily.entries()) {
const poolTypes = new Set(pools.map((pool) => pool.poolType));
if (!poolTypes.has('wrapped_native')) {
errors.push(`Chain ${chainId} gas family ${familyKey}: missing wrapped_native DODO pool`);
}
if (base && !knownTokens.has(base)) {
errors.push(`Chain ${chainId} pmmPools[${i}]: base/tokenIn "${base}" not in cwTokens or anchorAddresses`);
if (!poolTypes.has('stable_quote')) {
errors.push(`Chain ${chainId} gas family ${familyKey}: missing stable_quote DODO pool`);
}
if (quote && !knownTokens.has(quote)) {
errors.push(`Chain ${chainId} pmmPools[${i}]: quote/tokenOut "${quote}" not in cwTokens or anchorAddresses`);
}
const referenceVenuesByFamily = new Map();
for (let i = 0; i < gasReferenceVenues.length; i++) {
const venue = gasReferenceVenues[i];
if (!VALID_REFERENCE_PROTOCOLS.includes(venue.protocol)) {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: protocol must be one of ${VALID_REFERENCE_PROTOCOLS.join(', ')}`);
}
if (typeof venue.supported !== 'boolean') {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: supported must be set explicitly to true or false`);
}
if (!venue.familyKey || typeof venue.familyKey !== 'string') {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: familyKey required`);
continue;
}
if (!referenceVenuesByFamily.has(venue.familyKey)) referenceVenuesByFamily.set(venue.familyKey, []);
referenceVenuesByFamily.get(venue.familyKey).push(venue);
if (venue.aggregatorOnly === true && venue.protocol !== '1inch') {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: aggregatorOnly rows must use protocol "1inch"`);
}
if (isLiveRow(venue)) {
if (!VALID_NATIVE_REFERENCE_PROTOCOLS.includes(venue.protocol)) {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: live/routingVisible rows must use a native protocol contract, not "${venue.protocol}"`);
}
if (looksPlaceholderAddress(venue.venueAddress)) {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: live/routingVisible venueAddress must use a native protocol contract, not a placeholder scaffold (${venue.venueAddress})`);
}
}
if (venue.supported === false && isLiveRow(venue)) {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: supported=false rows cannot be live/routingVisible`);
}
if (venue.supported === false && venue.protocol === '1inch' && venue.aggregatorOnly !== true) {
errors.push(`Chain ${chainId} gasReferenceVenues[${i}]: unsupported 1inch rows must be marked aggregatorOnly=true`);
}
}
for (const [familyKey, venues] of referenceVenuesByFamily.entries()) {
const protocols = new Set(venues.map((venue) => venue.protocol));
if (!protocols.has('uniswap_v3')) {
errors.push(`Chain ${chainId} gas family ${familyKey}: missing uniswap_v3 reference venue`);
}
const oneInch = venues.find((venue) => venue.protocol === '1inch');
if (oneInch?.routingVisible === true || oneInch?.live === true) {
const hasUniswap = venues.some((venue) => venue.protocol === 'uniswap_v3' && venue.live === true);
const hasDodo = (gasPoolsByFamily.get(familyKey) || []).some((pool) => pool.publicRoutingEnabled === true);
if (!hasUniswap || !hasDodo) {
errors.push(`Chain ${chainId} gas family ${familyKey}: 1inch cannot be live/routingVisible before DODO and Uniswap venues are live`);
}
}
}
}
@@ -72,4 +234,33 @@ function main() {
process.exit(0);
}
main();
function resolveInputPath(argv) {
const candidate = argv[2];
if (!candidate || candidate === '-h' || candidate === '--help') {
return DEPLOYMENT_STATUS_PATH;
}
return path.isAbsolute(candidate) ? candidate : path.join(process.cwd(), candidate);
}
function printUsage() {
process.stdout.write('Usage: node scripts/validate-deployment-status.cjs [path/to/deployment-status.json]\n');
}
if (require.main === module) {
const argv = process.argv;
if (argv[2] === '-h' || argv[2] === '--help') {
printUsage();
process.exit(0);
}
if (argv[2]) {
DEPLOYMENT_STATUS_PATH = resolveInputPath(argv);
}
main();
}
module.exports = {
looksPlaceholderAddress,
isLiveRow,
validatePoolEntries,
main,
};

View File

@@ -22,9 +22,10 @@ For each epoch:
2. **Compute candidate paths** (e.g. k-shortest paths or enumerate swap+bridge combos).
3. **Allocate flow** by marginal-equalization heuristic (waterfilling): split volume across paths so marginal output equalizes.
4. **Update PMM inventories** and implied prices (use inventory-sensitive depth D = D_0·min(1, I_T/I_T^*)).
5. **Arb step (optional):** agents that trade toward oracle when profitable; update inventories again.
6. **Bot intervention step:** apply policy from config (or keep exogenous); record intervention cost.
7. **Emit scorecard** (or accumulate for end-of-run scorecard).
5. **Micro-support step (optional):** run gas-budgeted support trades for selected rails (e.g. `cWUSDC`, `cWUSDT`) to model tiny turnover-seeding or inventory-corrective activity.
6. **Arb step (optional):** agents that trade toward oracle when profitable; update inventories again.
7. **Bot intervention step:** apply policy from config (or keep exogenous); record intervention cost.
8. **Emit scorecard** (or accumulate for end-of-run scorecard).
---
@@ -46,9 +47,10 @@ AMM edges can be mocked (e.g. fixed 5 bps spread); relative behavior of PMM vs a
- **PMM state:** Per-pool `I_T`, `D = D_0·min(1, I_T/I_T^*)`, sell/buy with documented formula; routing controls applied.
- **Routing:** Candidate paths (same-chain, length ≤3), top-K by cost; waterfilling by chunk (5%), marginal-equalization.
- **Arb step (PR#2):** Implied price (sell/buy probe) vs oracle P; deviation δ; if |δ| > DELTA_ARB_BPS, trade in corrective direction with size min(x_max, α·|δ|·I_T^*); profit gate (skip if profit ≤ 0). Tuning: `DELTA_ARB_BPS`, `ARB_ALPHA`, `ARB_MAX_FRACTION_OF_TARGET`.
- **Micro-support step:** When `scenario.microTradePolicy` is enabled, run tiny support trades on selected cW rails before arb. Policy can prefer matched quotes (`cWUSDC/USDC`, `cWUSDT/USDT`), stay inside an inventory band, alternate when inside band, and clip the trade count by a per-epoch gas budget.
- **Bot step (PR#2):** If I_T < 0.5·I_T^* inject; if I_T > 1.5·I_T^* withdraw; action clipped to `BOT_MAX_FRACTION_OF_TARGET`·I_T^*; intervention cost = |u|·(β+ρ)+γ (bridge params + latency ρ from scenario `latencyModel`).
- **Bridge shock:** When `scenario.bridgeShock` is set, extra trades (sell cW on fromChain, buy cW on toChain) over `durationEpochs` at `magnitudeFraction` of baseline.
- **Determinism:** RNG seeded from `scenario.seed` or hash of scenario name.
- **Scorecard:** All PR#1 metrics plus `peak_deviation_bps`, `intervention_cost_*`, `arb_volume_total`, `arb_profit_total`.
- **Scorecard:** All PR#1 metrics plus `peak_deviation_bps`, `intervention_cost_*`, `arb_volume_total`, `arb_profit_total`, and support-lane `micro_trade_*` metrics.
Tuning: see constants in script and [scripts/README.md](../scripts/README.md).

View File

@@ -33,5 +33,6 @@ for each pool (cW* / quote):
- **Bridge throttle**: If bridge backlog or risk flag, widen bands or skip trade.
- **Global budget**: Before any trade, check per-token trade budget for current window; skip if exhausted.
- **Min improvement**: Only trade if expected |δ| improvement net of fees ≥ minImprovementBps.
- **Gas-budgeted micro-support**: For selected USD wrappers (especially `cWUSDC`, `cWUSDT`), allow tiny matched-quote trades (`cWUSDC/USDC`, `cWUSDT/USDT` when available) under a separate gas budget so wrappers stay economically live without converting the PMM into the destination venue.
Thresholds and bands from [../config/peg-bands.json](../config/peg-bands.json). Mesh reflexivity from [../docs/07-mesh-reflexivity.md](../docs/07-mesh-reflexivity.md).