Treasury floor
Reserves
Section titled “Reserves”fact The Treasury holds USDG, whitelisted Stock Tokens, COUPON legs and NOTE. reserveValueQuote() values everything except NOTE in USDG:
| Asset | Valuation |
|---|---|
| USDG | Par |
| Stock Tokens | Chainlink-style feed (addStockAsset), reverts StaleFeed if older than maxFeedStaleness (26 hours by default) or InvalidPrice if the answer is not positive |
| COUPON legs | legValueFactorWad: par (1 USDG per unit) when Autocalled or Matured unbreached, and while Live with the barrier intact on both the last observation and the latest fresh print; otherwise while Live min(1, liveMark / s0) with liveMark = min(last observed price, latest fresh print within 30 minutes); Matured breached at min(1, lastPrice / s0); zero in any other status. Series must be registered with registerLegSeries (owner or BondDepository). Accrued coupons and terminal payouts are pulled by the permissionless harvestSeries(seriesId) |
| NOTE | Excluded (it is the liability side) |
Floor and redemption
Section titled “Floor and redemption”redeem(noteAmount, minQuoteOut) burns the caller’s NOTE and pays previewRedeem in USDG, provided it does not exceed dailyRedemptionRemaining() and the Treasury holds enough USDG (InsufficientLiquidity otherwise). The limiter is a leaky bucket: redemptionUsed() is the usage recorded at the last redemption, amortised linearly to zero over REDEMPTION_WINDOW = 1 day, so over any span t the Treasury pays at most cap × (1 + t / 1 day) and never more than cap in one burst.
| Parameter | Value | Hard maximum |
|---|---|---|
redemptionHaircutBps | 0 in DeployToken.s.sol; PROTOCOL_SPEC.md anticipates 200 (2%) | 5,000 (50%) |
dailyRedemptionCapBps | 500 (5%) in DeployToken.s.sol; PROTOCOL_SPEC.md specifies 200 (2%) | 10,000 |
maxFeedStaleness | 26 hours | — |
tbd The deploy script and the specification currently disagree on both redemption parameters. Both are constructor arguments and can be changed by the owner with setRedemptionParams(haircutBps, dailyCapBps). The examples below use the specification’s 2% haircut and 2% daily cap and are illustrative.
Worked example
Section titled “Worked example”illustrative Reserves: 3,000,000 USDG + 4,000 NVDA tokens at 180.00 = 720,000 + 280,000 USDG of COUPON legs at par. reserveValueQuote = 4,000,000. Total NOTE supply 12,000,000 of which 2,000,000 is held by the Treasury; circulating 10,000,000.
| Quantity | Value |
|---|---|
| Floor | 4,000,000 / 10,000,000 = 0.400 USDG per NOTE |
| Redemption of 100,000 NOTE at 2% haircut | 100,000 × 0.400 × 0.98 = 39,200 USDG |
| Daily allowance | 2% × 4,000,000 = 80,000 USDG |
| Redemptions possible today | 80,000 / 0.392 ≈ 204,081 NOTE |
| After redeeming 100,000 NOTE | reserves 3,960,800; circulating 9,900,000; floor 0.40008 |
Redemption at a haircut slightly raises the floor for remaining holders, because the redeemer leaves 2% of their share behind.
Why a cap and a haircut
Section titled “Why a cap and a haircut”- The daily cap prevents a run from draining the Treasury’s liquid USDG in one block while Stock Tokens and legs, which are less liquid, remain. Redeemers queue across days and the Treasury can rebalance.
- The haircut makes redemption a floor rather than an arbitrage engine: NOTE has to trade below
floor × (1 − haircut)before burning beats selling. - Liquidity:
redeempays only USDG. If USDG on hand is insufficient the call reverts; governance can sell Stock Tokens or wait for legs to settle. The floor is a valuation, not a guarantee of same-day liquidity for all reserves.
Reserve flows
Section titled “Reserve flows”| Inflow | Source |
|---|---|
| Bond proceeds | BondDepository (USDG, Stock Tokens, COUPON legs) |
| 10% of protocol fees | RevenueRouter |
| Desk returns | COUPON coupons and principal from Desk positions |
| Stock Tokens bought from the Desk at feed value | Desk.liquidateToTreasury → Treasury.purchaseStock |
| Outflow | Authority |
|---|---|
| NOTE redemption | Permissionless, capped |
| USDG paid to the Desk for Stock Tokens | purchaseStock (Desk only, at feed value, StockPurchased) |
withdrawERC20(token, to, amount), withdrawLegs(seriesId, to, units) | Timelock owner only (Withdrawn, LegsWithdrawn); registered, enabled reserve assets and COUPON legs are valued through the reserve mark and consume the daily redemption budget shared with redeem (DailyCapExceeded) |
mintNote(to, amount) | Timelock owner, within epoch cap (NoteMinted) |
Governance withdrawal authority is the main trust assumption on the floor; see Governance for timelock and guardian arrangements.