# HYBX OMNL — frozen policy specification

This document locks **deterministic** monetary rules for GRU v2 (ISO-4217 lines) and **cXAU\*** (troy ounce) instruments. On-chain code in `contracts/hybx-omnl/` must match this spec.

## Scope

- **Per-line aggregates:** Each `lineId` (e.g. USD-stable line, EUR line, XAU line) has independent `S0`, `S1`, `R`. The **5:1 M1 cap** applies **per line**, not globally across unrelated ISO codes.
- **Units:** All of `S0`, `S1`, `R` for a given `lineId` use the **same minor unit** as the registered M0 token (e.g. 6 decimals for typical c\* stables). For XAU lines, **1.0 token = 1 troy ounce** at full precision (see explorer cross-check); reserves `R` are **troy ounces** in that same atom.

## Rounding (mulDiv)

Let `M0_NUM = 12`, `M0_DEN = 10` (1.2× backing).

- **Minimum reserves** required for current M0 supply `S0`:

  `minR(S0) = ceil(S0 * M0_NUM / M0_DEN)` using `Math.mulDiv(S0, M0_NUM, M0_DEN, Rounding.Ceil)`.

  Intuition: any fractional atom of M0 requires full ceil so backing never falls below 1.2× in discrete units.

- **M1 cap** for current `S0`:

  `maxS1(S0) = S0 * 5` (exact; no rounding down of the cap in favor of more M1).

Compliance:

- **M0 backing:** `R >= minR(S0)`.
- **M1 expansion:** `S1 <= maxS1(S0)`.

**Mint simulation:** Before minting `Δ` M0: require `R >= minR(S0 + Δ)`. Before minting `Δ` M1: require `S1 + Δ <= maxS1(S0)`.

## Instrument registration

- Each **line** registers exactly one **M0** ERC-20 and one **M1** ERC-20 (`InstrumentRegistry`).
- Tokens used for supply reads must be **standard** `ERC20.totalSupply()`; rebasing or fee-on-transfer tokens are **out of scope** unless wrapped to a fixed-supply view.
- **ISO-4217** numeric code is stored for GRU v2 fiat lines; XAU lines set `isXAU = true` and ignore ISO fiat code.

## Attestation vs price oracles

- **Reserve commitments `R`** come only from `ReserveCommitmentStore` (manual multisig / HSM pipeline). They are **not** PMM or CoinGecko prices.
- **Price / PMM oracles** remain separate ([ORACLE_AND_KEEPER_CHAIN138](../integration/ORACLE_AND_KEEPER_CHAIN138.md)).

## Primary chain for writes

- **Default:** Chain **138** is the **primary** committer for `R` and policy parameter updates; ALL Mainnet (**651940**) receives **mirrored** commitments via CCIP (`OMNLMirrorReceiver`). Operators may switch primary only via governance-controlled addresses documented at deploy time.

## Stale attestation (operational default)

- If `now > validUntil` for a line’s last commitment, the **API** surfaces `attestationStale: true`. On-chain **pause** of M1 mint is **optional** and controlled by `OMNLCircuitBreaker` TTL — default **warn-only** until `enforceStaleBlockM0/M1` is enabled.
- **`reportingCompliant` (on-chain / API):** `policyOk && !attestationStale && operational` — use this for dashboards when stale attestations must fail the “green” status even if pure math (`policyOk`) still holds.
- **Merkle evidence:** `ReserveCommitmentStore` stores `merkleRoot` alongside `evidenceHash` for periodic reconciliation roots.

## Cross-chain aggregated supply (API)

- For lines with M0/M1 on both 138 and 651940, configure [`config/hybx-omnl-cross-chain-lines.json`](../../config/hybx-omnl-cross-chain-lines.json) and call **`GET /api/v1/omnl/compliance-aggregated/:lineId`**. Reserves `R` / TTL are taken from primary (**138**) `ComplianceCore`; supplies are summed per `totalSupply()` across chains.
