MM0 Accounting Specification
Version: 0.1 (Stage 0) · Implementation: src/accounting/accounting.ts
The goal is P&L that can't mislead. Gross LP fees are never presented as profit.
1. Holdings
H_base = vault base + Σ base inside positions
H_quote = vault quote + Σ quote inside positions + gas budget (valued in quote)
U = uncollected fees (base, quote), claimable but not yet claimed
P = reference price (independent oracle; venue TWAP flagged LOW confidence when no oracle exists)
NAV = H_base · P + H_quote + U_base · P + U_quote
2. Flows and units (time-weighted returns)
Deposits and withdrawals mint and burn units at the current unit price:
on deposit of value V: units += V / unitPrice contributed += V
on withdrawal of V: units −= V / unitPrice contributed −= V
unitPrice = NAV / units return(t0,t1) = unitPrice(t1) / unitPrice(t0) − 1
Capital additions never look like returns (test: deposits do not count as returns).
A parallel unitized HODL benchmark is kept: deposits buy benchmark units at the benchmark's unit price, whose holdings are the deposited assets left untouched. Two families of risk metrics follow:
- absolute:
drawdown = 1 − unitPrice / max(unitPrice), daily loss from the UTC-day-start unit price - market-making:
rel = unitPrice / hodlUnitPrice,mmDrawdown = 1 − rel / max(rel),mmDailyLossfrom the day-startrel
Mandate loss limits apply to the market-making family. Both families are reported.
3. Fill inference and cost basis
Between updates, any change in holdings not explained by known non-trade events is a fill:
- known events: deposit / withdrawal, fee collection (claimed fees enter holdings at mark value), transaction cost (debited from gas)
ΔB = H_base − H_base⁻,ΔQ = H_quote − H_quote⁻after removing known eventsΔB > 0(bought base):avgCost ← (avgCost · B⁻ − ΔQ) / BΔB < 0(sold base):realized += ΔQ − avgCost · |ΔB|
LP fills, MM0 inventory swaps, and venue haircuts (exploits) all flow through this rule. A haircut appears as a sale for negative proceeds, which is a realized loss.
4. The identity (checked every tick)
NAV − contributed = realizedTrading + feesCollected + U·P − txCosts + unrealized
unrealized = H_base · (P − avgCost)
A residual > 1e-6·NAV trips VAULT_INVARIANT → HALT. A property test runs this across 500 random steps with fills, fees, costs and a mid-stream deposit.
5. Vault reconciliation (checked every tick)
Expected vault balances are derived only from deposits, executed receipts' vaultDelta, and tx costs. Any difference from actual token-account balances means something moved funds outside MM0's action path. That trips VAULT_INVARIANT → HALT (stress: vault-tamper).
6. Reported metrics
| Metric | Definition |
|---|---|
| Total maker capital | NAV |
| Deployed / reserve | position value / undeployed vault value (gas excluded from reserve) |
| LP fees earned | feesCollected + uncollected (at mark) |
| Realized P&L | realizedTrading + feesCollected − txCosts |
| Unrealized P&L | unrealized + uncollected |
| Net MM P&L | NAV − contributed (= realized + unrealized) |
| HODL benchmark | contributed holdings held unchanged, marked at P |
| vs HODL | NAV − HODL |
| Divergence | NAV − fees + costs − HODL (LP-specific loss incl. adverse selection and own swap costs) |
| Fee / loss ratio | fees / max(ε, −divergence) |
| Max drawdown | max over time of 1 − unitPrice / HWM |
| Capital utilization | time-average deployed / NAV |
| Depth contribution | MM0-owned quote value executable within ±1/2/5% |
| Active liquidity uptime | fraction of time any MM0 position contains the active price |
7. Performance attribution
Net MM P&L = Fees + Inventory P&L (realized + unrealized trading) − Costs
Inventory P&L = HODL P&L + Divergence
So: Net = HODL P&L + Fees + Divergence − Costs. The maker page shows this split.
8. Performance fee definition (if ever charged)
perf_t = max(0, (unitPrice_t − HWM_unit) · units − (HODLunit_t − HODLunit_HWM) · units)
That is, the value created beyond holding the deposited inventory, flow-adjusted and net of every cost, above a high-water mark. It is never charged on gross fees.
9. Valuation policy
- Mark at the independent reference price. With no oracle (bootstrap), mark at the venue TWAP and label the valuation LOW confidence on every surface.
- Uncollected fees are included in NAV (claimable) and shown separately.
- Gas (SOL) is valued in quote at the reference SOL price (Stage 3). The simulator uses a quote-denominated gas account.
- Position rent deposits (Solana) are tracked as recoverable assets, not costs (Stage 3).