Skip to content

Desk

A series is only useful if both legs fill. The Desk pools USDG and, on governance instruction, subscribes to COUPON when SHIELD demand exceeds COUPON demand, so stock holders can always find some protection to buy. Desk depositors earn the coupons (and take the note-buyer’s risk) on the notional the Desk fills.

fact Desk is an ERC-4626 vault over USDG (reconciled with contracts/src/token/Desk.sol).

PropertyValue
DepositsOpen (deposit/mint), pausable by guardian
NAVtotalAssets = idle USDG + deployed principal + held Stock Token value (unharvested coupons excluded, conservative)
FillsfillCoupon(seriesId, amount), owner (timelock) only, only while S > D during Subscription
CapsCaps{perSeriesCapBps, perUnderlyingCapBps, totalDeployedCapBps} as bps of totalAssets; DeployToken.s.sol sets 1,000 / 2,500 / 6,000. A breach reverts CapExceeded(cap, requested, limit) with cap one of "perSeries", "perUnderlying", "totalDeployed"
UtilisationutilisationBps = deployed × 1e4 / totalAssets
WithdrawalsImmediate up to idle USDG; otherwise FIFO requestWithdraw(shares, receiver) queue filled by processQueue(n) as series settle and coupons are harvested
Stock on breachHeld and valued at the Treasury feed; governance may liquidateToTreasury at feed price (Treasury.StockPurchased)
Harvestharvest(seriesId), permissionless: claims coupons, redeems or refunds, updates deployed
fillable(series) = min( S − D, perSeriesCapBps × totalAssets / 1e4 − deployedPerSeries[series], perUnderlyingCapBps × totalAssets / 1e4 − deployedPerUnderlying[underlying], totalDeployedCapBps × totalAssets / 1e4 − deployed, idleAssets ) utilisationBps = deployed × 1e4 / totalAssets

utilisationBps feeds the bond discount: when the Desk is heavily deployed, bonds cheapen to raise Treasury reserves.

illustrative Desk totalAssets 4,000,000 USDG (2,300,000 idle, 1,500,000 deployed, 200,000 held stock). NVDA series: SHIELD 900,000, COUPON 500,000. The Desk already holds 200,000 in another NVDA series.

ConstraintRoom
Gap S − D400,000
Per series 10%400,000 − 0 = 400,000
Per underlying 25%1,000,000 − 200,000 = 800,000
Total 60%2,400,000 − 1,500,000 = 900,000
Idle USDG2,300,000
Fillable400,000

After filling, D = 900,000 = S, the series matches fully at strike (subject to notionalCap), the Desk holds 400,000 COUPON units, deployed = 1,900,000 and utilisation is 47.5%.

  1. maxWithdraw(owner) is bounded by idleAssets(). Withdrawing up to that amount is a normal ERC-4626 withdraw/redeem.
  2. Beyond idle, requestWithdraw(shares, receiver) escrows shares and appends a request. cancelWithdrawRequest(id) returns them.
  3. Anyone may call processQueue(n) to fill up to n requests from idle USDG in FIFO order at the current share price. queueProcessLimit bounds n.

Withdrawals and queue processing are not pausable; maxDeposit/maxMint return zero while paused. processQueue(n) reverts QueueLimitTooHigh above queueProcessLimit (constructor default 10, hard maximum MAX_QUEUE_PROCESS = 50).

The Desk is a note buyer. It earns coupons while the barrier holds and receives stock at s0 if the barrier breaks at maturity, at which point NAV reflects the feed value of that stock. Depositors bear market risk on the underlyings the Desk has filled, concentration risk bounded by the caps, and liquidity risk when most assets are deployed. Desk shares are not NOTE and carry no governance rights.

The Desk never buys SHIELD and never fills a series above its notionalCap.

FunctionEffect
setCaps(Caps)Per-series, per-underlying, total caps
setMaxFeedStaleness(seconds)Valuation staleness bound for held stock
setQueueProcessLimit(n)Max requests per processQueue
fillCoupon(seriesId, amount)Subscribe to COUPON within caps
liquidateToTreasury(token, amount)Sell held stock to the Treasury at feed value
sweepToken(token, to, amount)Recover tokens that are not part of NAV
setGaugeController(controller)Sets the single address allowed to steer per-underlying caps; emits GaugeControllerUpdated
setPerUnderlyingCapFromGauge(underlying, bps)Gauge controller only, once per week per underlying via GaugeController.syncCaps; bounds 100 to 4,000 bps; emits PerUnderlyingCapSet

fact The governed Caps.perUnderlyingCapBps is a ceiling. Each week GaugeController.syncCaps writes a per-underlying value derived from the series-gauge vote, and effectivePerUnderlyingCapBps(underlying) returns the lower of the governed cap and the gauge value (min). fillCoupon uses the effective value; an underlying with no gauge, or one that has not been synced yet, keeps the governed cap. The mechanics and a worked example are under Gauges.

The module is a UUPS proxy whose implementation can only be replaced by the 7-day UpgradeTimelock; see Upgradeability and recovery.

fact Share price is computed from a marked NAV: deployed principal is valued at the Treasury’s live mark for each series (par for series not yet live) plus coupons accrued but not yet harvested, so depositing just before a harvest or withdrawing just before a mark-down no longer transfers value between holders. Direct withdraw/redeem require the shares to have been held for minHold (default 1 day, governance-settable up to 7 days) and are refused while a settled series is waiting to be harvested; the withdrawal queue is exempt from the hold and has its USDG reserved at request time. Bonds read the Desk’s utilisation as of the previous block.