282 lines
8.9 KiB
JSON
282 lines
8.9 KiB
JSON
{
|
||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||
"title": "ScenarioSpec",
|
||
"description": "Formal scenario input for reproducible, comparable sim runs. PRs that tweak k/fee can be tested against the same scenario file.",
|
||
"type": "object",
|
||
"required": [
|
||
"scenario",
|
||
"graphMode",
|
||
"topology",
|
||
"chainsIncluded",
|
||
"tokensIncluded",
|
||
"epochs"
|
||
],
|
||
"properties": {
|
||
"scenario": {
|
||
"type": "string",
|
||
"description": "Unique id, e.g. hub_only_11, full_quote_1_56_137, bridge_shock_137_56"
|
||
},
|
||
"graphMode": {
|
||
"type": "string",
|
||
"enum": [
|
||
"design",
|
||
"deployed"
|
||
],
|
||
"description": "design = topology + params only; deployed = deployment-status.json"
|
||
},
|
||
"topology": {
|
||
"type": "string",
|
||
"enum": [
|
||
"hub",
|
||
"full_quote",
|
||
"mixed"
|
||
],
|
||
"description": "hub = one PMM per cW vs hub per chain; full_quote = cW vs all anchors; mixed = hub on some chains, full_quote on others"
|
||
},
|
||
"chainsIncluded": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "Chain IDs, e.g. [\"1\", \"56\", \"137\"]"
|
||
},
|
||
"tokensIncluded": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
},
|
||
"description": "cW token symbols, e.g. [\"cWUSDT\", \"cWUSDC\"]"
|
||
},
|
||
"epochBlocks": {
|
||
"type": "integer",
|
||
"minimum": 1,
|
||
"description": "Blocks per epoch (optional; if absent, epoch is logical)"
|
||
},
|
||
"epochs": {
|
||
"type": "integer",
|
||
"minimum": 1,
|
||
"description": "Number of epochs to run"
|
||
},
|
||
"orderflowModel": {
|
||
"type": "object",
|
||
"description": "Distribution + volume ranges for synthetic trades",
|
||
"properties": {
|
||
"distribution": {
|
||
"type": "string",
|
||
"enum": [
|
||
"uniform",
|
||
"lognormal",
|
||
"pareto",
|
||
"poisson"
|
||
],
|
||
"default": "uniform"
|
||
},
|
||
"volumeMinUnits": {
|
||
"type": "number",
|
||
"minimum": 0
|
||
},
|
||
"volumeMaxUnits": {
|
||
"type": "number",
|
||
"minimum": 0
|
||
},
|
||
"tradesPerEpoch": {
|
||
"type": "integer",
|
||
"minimum": 0
|
||
},
|
||
"paretoAlpha": {
|
||
"type": "number",
|
||
"minimum": 0.5,
|
||
"description": "Pareto alpha (e.g. 1.5–2.5 for whale-heavy)"
|
||
}
|
||
}
|
||
},
|
||
"bridgeShock": {
|
||
"type": "object",
|
||
"description": "Optional bridge shock: from chain, to chain, magnitude, duration",
|
||
"properties": {
|
||
"fromChain": {
|
||
"type": "string"
|
||
},
|
||
"toChain": {
|
||
"type": "string"
|
||
},
|
||
"magnitudeFraction": {
|
||
"type": "number",
|
||
"minimum": 0,
|
||
"maximum": 1
|
||
},
|
||
"durationEpochs": {
|
||
"type": "integer",
|
||
"minimum": 1
|
||
}
|
||
}
|
||
},
|
||
"oracleModel": {
|
||
"type": "string",
|
||
"enum": [
|
||
"static",
|
||
"stochastic"
|
||
],
|
||
"default": "static"
|
||
},
|
||
"latencyModel": {
|
||
"type": "object",
|
||
"description": "Finality per bridge, rho(Delta t) params",
|
||
"properties": {
|
||
"finalityBlocksPerChainPair": {
|
||
"type": "object",
|
||
"additionalProperties": {
|
||
"type": "number"
|
||
}
|
||
},
|
||
"rhoPerBlockBps": {
|
||
"type": "number",
|
||
"description": "Latency penalty per block in bps (piecewise linear)"
|
||
}
|
||
}
|
||
},
|
||
"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" }
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|