Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

SdrUSD — the yield leg

A pro-rata share of the strategy pool, redeemable through a queue whose length matches the facility cycle.

Invariants

Holders bear loss first. A loss reduces net asset value, so it falls on holders by construction rather than by policy. This corrects an error found by auditing the player model: the economic layer had been paying this holder a fixed yield, making it a creditor, while the kernel and the legal classification both treat it as a share that absorbs loss ahead of the protocol.

Fair-share burn. A redemption pays floor(shares × NAV / totalShares) — never more than the pro-rata claim.

The queue matches the cycle, and is enforced. Claiming before maturity reverts, exactly as the settlement primitive refuses a premature occurrence. The length is the facility cycle: shorter promises liquidity the assets do not produce; longer locks holders up for nothing.

if (block.timestamp < c.maturesAt) revert QueueNotMatured(c.maturesAt, uint64(block.timestamp));

Redemptions price at request time. A later loss cannot claw back a priced claim; it falls on the holders who stayed. That is what a queue is — a claim fixed at the moment it joins.

Wired to the facility lifecycle

Staking moves tokens — it previously credited shares without taking any drUSD, which is an assertion rather than a transfer. A settled facility occurrence books into net asset value through accrueSettled, behind two gates that mirror the proofs: the occurrence must genuinely have settled, which the registry permits only at or after its due time, and it may be booked at most once. Without the second gate one coupon could be accrued repeatedly, inventing value.

The bug the tests found

The first version booked the coupon to net asset value without receiving the cash. A redeemer priced at the raised value could then not be paid — the vault held a thousand against a claim of eleven hundred. Accrual now delivers the coupon in the same call, and backing() exposes the assets actually held.

The invariant that came out of it: net asset value never exceeds backing — the vault-level echo of the reserve rule, one layer up from where it was already proved for the payment leg. It existed nowhere until a test written against the deck's own five-step flow demanded it.

Tests

TestDischarges
refuses a claim before maturitysettlement_never_premature
pays after exactly one cycleQueueMatchesCycle
never pays above the pro-rata shareFairShareBurn, burn_payout_le_nav
holders bear loss, not the protocolthe player-audit correction
pricing survives later lossqueue semantics
refuses a replayed claimalreadyPerformed
refuses to accrue an unsettled occurrencesettlement_never_premature
accrues a settled coupon, raising the share pricethe deck's accrual step
books a coupon at most oncealreadyPerformed
never books value it does not holdvault-level COBS 19A.7.1
runs the full cycle end to endthe deck's five steps