# Safe Inventory Target Sizing (Closed-Form Approximation) A closed-form approximation for **I_T^*** (inventory target) per chain so capital allocation can be justified mathematically instead of heuristically. Inputs: expected routed volume, bridge β/γ, refill latency, and target band. --- ## 1. Objective Choose **I_T^*** per chain and per cW token so that: 1. With high probability we do **not** deplete inventory before bridge/mint can refill. 2. Peg stays inside the target band during normal and stressed flow. 3. Intervention cost (bridge/mint/burn) remains bounded and preferably linear in volume. --- ## 2. Assumptions - **Epoch**: time window over which we measure flow (e.g. 1 hour or “refill cycle”). - **V_epoch**: expected **net outflow** of cW token from the pool during one epoch (routed volume, one-sided; we conservatively use net outflow). - **σ**: volatility multiplier for V (e.g. 1.5–2 for “stress”); so worst-case net outflow in one epoch is on the order of **V_epoch · σ**. - **T_refill**: refill latency (time or blocks) for bridge/mint to restore inventory on this chain. - **β**: bridge fee (fraction) for refill path; **γ**: fixed cost per refill (gas + relayer). - **Band**: we require that after a shock we do not breach the circuit-break band (e.g. 2% for USD). That effectively caps how far inventory can fall before we must intervene. --- ## 3. First-order formula **Safe inventory target (units of cW token):** ``` I_T^* ≥ V_epoch · σ · (1 + T_refill / T_epoch) / (1 - β) + γ_buffer ``` **Interpretation:** - **V_epoch · σ**: worst-case net outflow in one epoch. - **T_refill / T_epoch**: number of “epochs” in one refill cycle; we need to cover outflow over that period without going to zero. - **(1 − β)**: bridge fee reduces effective refill; we size so that after fee we still refill enough. - **γ_buffer**: small buffer for fixed costs (e.g. one or a few refill batches); can be set to a multiple of γ or a constant. **Simpler variant (single refill cycle):** If refill is exactly one epoch and we want to absorb one full shock without depleting: ``` I_T^* ≥ V_epoch · σ / (1 - β) + buffer ``` **buffer** = small constant or γ · (typical refill count per epoch). --- ## 4. Per-chain inputs (from your config) From `config/simulation-params.json` and `config/token-map.json`: - **β** = `bridgeBeta` for the chain (refill path). - **γ** = `bridgeGammaUnits` (nominal; use for γ_buffer if desired). - **V_epoch**: not in config; must be estimated or taken from simulation (e.g. expected routed volume per epoch for that chain/token). - **σ**: e.g. 1.5–2 for stress. - **T_refill, T_epoch**: in blocks or seconds; chain-dependent (e.g. 1 epoch = 1 hour, T_refill = 20 min → T_refill/T_epoch ≈ 1/3). --- ## 5. Depth consistency (D_0 vs I_T^*) Your PMM uses **D = D_0 · min(1, I_T / I_T^*)**. For the pool to stay “deep” enough under stress: - **D_0** should be sized so that at **I_T = I_T^***, the pool can absorb a typical trade size without slipping past the band. A simple rule: **D_0** on the order of **I_T^* / 2** to **I_T^*** (so that at target inventory, effective depth is meaningful). So: ``` D_0 ≈ (0.5 to 1.0) · I_T^* ``` Then the formula above gives **I_T^***; set **D_0** accordingly. --- ## 6. EUR tokens (cWEURC, cWEURT) - Same formula applies, but use **EUR-specific** expected volume and, if refill is via a different path, **EUR bridge β/γ**. - Use **wider band** (and possibly higher σ) to reflect FX and dual-source peg risk; that may imply a **larger buffer** or **higher σ** in the sizing formula. --- ## 7. Usage 1. **Estimate V_epoch** per chain (and per token if needed) from historical or simulated routed volume. 2. Set **σ** (e.g. 1.5–2) and **T_refill / T_epoch** from chain/contract data. 3. Read **β** (and optionally **γ**) from `simulation-params.json`. 4. Compute **I_T^*** from the formula; optionally add **γ_buffer**. 5. Set **D_0 ≈ (0.5–1) · I_T^*** for that pool. 6. Put **inventoryTargetUnits** (and depth) into `simulation-params.json` or `deployment-status.json` and run simulations to validate churn and intervention cost. This gives a **justified starting point** for capital allocation per chain; tune from there using the three metrics (capture, churn, intervention cost) and stress tests (hub-only, full-quote, bridge shock). --- ## 8. Example first pass (chains 1, 56, 137, 25) Assumptions: σ = 1.5 (USD), σ = 2 (EUR); T_refill/T_epoch = 0.33; γ_buffer = 2·γ. Formula: I_T^* ≥ V_epoch·σ·(1 + 0.33)/(1 − β) + γ_buffer; D_0 = 0.75·I_T^*. | Chain | Name | Hub | β | γ | V_epoch (example) | I_T^* (USD) | I_T^* (EUR) | D_0 (USD) | |-------|---------|------|-------|----|-------------------|-------------|-------------|-----------| | 1 | Ethereum| USDC | 0.001 | 50 | 100_000 | ~200k | ~266k | ~150k | | 56 | BSC | USDT | 0.001 | 10 | 80_000 | ~160k | ~213k | ~120k | | 137 | Polygon | USDC | 0.001 | 5 | 60_000 | ~120k | ~160k | ~90k | | 25 | Cronos | USDT | 0.002 | 15 | 30_000 | ~60k | ~80k | ~45k | Run `node scripts/size-inventory.cjs` or `node scripts/size-inventory.cjs --v-epoch '{"1":100000,"56":80000,"137":60000,"25":30000}'` to regenerate from your `simulation-params.json`. Use **k = 0.15–0.2** on thin chains (e.g. Cronos) if sims show excessive capture; EUR tokens use `eurDefaults` (higher k, σ, feeBps).