Skip to content

Redemption Curve

The Vault-K-NO prices every redemption using a quadratic curve applied to aggregate NAVs. The curve fairly distributes available liquidity between investors who redeem early in a day window and those who redeem later.

The Formula

exitNAV(fill) = aggMarketNAV + (aggModeledNAV − aggMarketNAV) × (1 − fill)²

where:

// Conceptual (real-valued):
fill              = redeemedToday / dailyCap                    // in [0.0, 1.0]

// Integer arithmetic (mandatory — both values are USDC, 6 dec):
fill              = redeemedToday * 1e18 / dailyCap             // in [0, 1e18]

aggModeledNAV     = Σ positionModeledValue(i) + idleReserve    // all slots
aggMarketNAV      = Σ positionMarketValue(i)  + idleReserve    // all slots

exitNAV is the curve-weighted aggregate vault NAV (USDC, 6 dec) — a total vault valuation, not a per-share price. To convert to USDC for a redemption: exitValue = shares * exitNAV / totalShares.

Fill must be 1e18 fixed-point in integer arithmetic

Writing fill = redeemedToday / dailyCap produces 0 for all partial fills (integer division of two USDC values). This silently collapses the curve to aggMarketNAV on every withdrawal. The * 1e18 scaling is mandatory.

Curve Behavior

Fill Level Exit Price Interpretation
fill = 0 (start of day, no redemptions yet) aggModeledNAV Best case — full modeled NAV, no curve discount
fill = 0.5 (half the daily cap consumed) aggMarketNAV + 0.25 × (aggModeledNAV − aggMarketNAV) Discounted toward market NAV
fill = 1.0 (daily cap fully consumed) aggMarketNAV Worst case — pure market NAV

The quadratic shape means the discount is mild at low fills and accelerates near the cap. Early redeemers bear little discount; late redeemers receive pure market NAV pricing.

Example

Suppose: - aggModeledNAV = $2,000,000 - aggMarketNAV = $1,900,000 (gap = 5%) - dailyCap = $38,000 (2% of market NAV)

Redemption order Fill before Fill after Avg exit price per share
First $10K 0.00 0.263 ~$1.968 per $1 modeled
Next $10K 0.263 0.526 ~$1.939 per $1 modeled
Last $10K 0.526 0.789 ~$1.912 per $1 modeled

Aggregate Agnosticism

The curve is agnostic to how many positions exist. It sees two aggregate numbers — aggModeledNAV and aggMarketNAV — and prices the exit between them. Adding or removing positions changes the aggregates but not the formula.

Average Curve NAV Calculation

When processing a withdrawal request, the vault computes the average curve-weighted vault NAV over the fill range [fillBefore, fillAfter] using the exact closed-form integral:

function _avgCurvePrice(
    uint256 fillBefore,  // pre-scaled: redeemedToday * 1e18 / dailyCap
    uint256 fillAfter,   // pre-scaled: (redeemedToday + requestValue) * 1e18 / dailyCap
    uint256 mdl,         // aggModeledNAV (USDC, 6 dec)
    uint256 mkt          // aggMarketNAV  (USDC, 6 dec)
) internal pure returns (uint256 curveNAV)

curveNAV is a total vault valuation (USDC, 6 dec) between aggMarketNAV and aggModeledNAV — it is not a per-share price. The USDC owed to the investor is shares * curveNAV / totalShares. This ensures fair average pricing even when a single large withdrawal spans a significant fill range.

Daily Window Reset

At the start of each new 24-hour window (tracked by dayStart), redeemedToday resets to zero. This resets fill to 0, and the next redemption starts again at full modeled NAV pricing.

The DayRolled event is emitted with the new dayStart timestamp and the previous day's total redeemed amount.