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
| Test | Discharges |
|---|---|
| refuses a claim before maturity | settlement_never_premature |
| pays after exactly one cycle | QueueMatchesCycle |
| never pays above the pro-rata share | FairShareBurn, burn_payout_le_nav |
| holders bear loss, not the protocol | the player-audit correction |
| pricing survives later loss | queue semantics |
| refuses a replayed claim | alreadyPerformed |
| refuses to accrue an unsettled occurrence | settlement_never_premature |
| accrues a settled coupon, raising the share price | the deck's accrual step |
| books a coupon at most once | alreadyPerformed |
| never books value it does not hold | vault-level COBS 19A.7.1 |
| runs the full cycle end to end | the deck's five steps |