Skip to main content
Utilization tells you how close the pool is to its position-open capacity. Because the metric is denominated against the same maxNetExposure ceiling the protocol uses to gate position opens, hedged longs and shorts in the same (pair, maturity) bucket offset each other — a perfectly hedged book reads near-zero utilization regardless of how large the gross open interest is.

Utilization Formula

riskCapacityUtilization = sumAbsBucketExposure * BPS_DENOMINATOR / maxNetExposure
The result is expressed in basis points (bps), where 10,000 bps = 100% (position-open cap reached).
VariableTypeDescription
sumAbsBucketExposureOnchain: stored in PoolVaultSum of |netExposure| across every active (pair, fixingTimestamp) bucket. Maintained incrementally on every position open/close/increase/reduce.
BPS_DENOMINATORConstant10,000 (basis point scaling constant)
maxNetExposureComputed: read from RiskManagertotalAssets × netExposureCapFactorBps / stressMoveBps. The same ceiling that gates new position opens.
Utilization itself is Computed — derived at query time by PoolVault.riskCapacityUtilization().
If maxNetExposure returns 0 (e.g. empty vault) and sumAbsBucketExposure is non-zero, utilization returns type(uint256).max so the withdrawal gate trips. When both are zero, utilization is 0.

Maximum Utilization Cap

The protocol enforces a configurable cap on utilization:
ParameterDefaultDescription
maxRiskCapacityBps8,000 (80%)Maximum allowed utilization after any withdrawal
When an LP attempts to withdraw, the vault checks whether the resulting utilization would exceed maxRiskCapacityBps. If it would, the withdrawal is blocked.
The utilization cap is a hard constraint. If the pool’s utilization is already at or above 80%, no withdrawals are possible until positions close (or hedging opens) and utilization decreases.

Maximum Withdrawable Amount

The vault computes the maximum USDC that can be withdrawn without breaching the cap. Inverting the utilization formula and solving for the minimum retained assets gives:
maxWithdrawable = totalAssets - (sumAbsBucketExposure * BPS_DENOMINATOR * stressMoveBps
                                  / (netExposureCapFactorBps * maxRiskCapacityBps))
If the computed value is negative (utilization already exceeds the cap), maxWithdrawable returns 0.

Worked Examples

MetricValue
Total Assets120,000 USDC
sumAbsBucketExposure95,000 USDC (all in one bucket)
netExposureCapFactorBps / stressMoveBps10,000 / 200
maxNetExposure120,000 × 50 = 6,000,000 USDC
riskCapacityUtilization95,000 × 10,000 / 6,000,000 ≈ 158 bps (1.58%)
Max Utilization Cap8,000 bps (80%)
Well under the cap — withdrawals are unrestricted.
MetricValue
Total Assets120,000 USDC
Gross Notional95,000 USDC
sumAbsBucketExposure|50,000 − 45,000| = 5,000 USDC
maxNetExposure6,000,000 USDC
riskCapacityUtilization5,000 × 10,000 / 6,000,000 ≈ 8 bps (0.08%)
Gross open interest is identical to the one-sided case, but the bucket netting credits the hedge — utilization reads orders of magnitude lower.

Why Cap Utilization?

The cap serves four purposes:
1

Prevent bank-run dynamics

Without a cap, LPs could race to withdraw during adverse conditions, leaving the pool unable to honor its obligations. The cap ensures an orderly withdrawal process.
2

Ensure settlement liquidity

Matured positions must be settled with USDC payouts to profitable traders. The reserve ensures funds are always available.
3

Absorb potential bad debt

If a position’s losses exceed its locked margin, the pool absorbs the shortfall. A minimum reserve provides a buffer for these events.
4

Bound risk capacity

The bucket-aggregated net exposure is also what gates new position opens via the RiskManager. Using the same denominator for the withdrawal cap means LP withdrawals can never push the pool past the protocol’s risk-capacity ceiling.

Dynamic Utilization Changes

Utilization changes with every position operation:
EventEffect on Utilization
Position opened (new direction)sumAbsBucketExposure increases, utilization rises
Position opened (hedging an open trade in the same bucket)sumAbsBucketExposure decreases, utilization falls
Position closedsumAbsBucketExposure decreases, utilization falls
LP deposits USDCtotalAssets and maxNetExposure increase, utilization falls
LP withdraws USDCtotalAssets and maxNetExposure decrease, utilization rises

Disabling the Utilization Cap

Setting maxRiskCapacityBps to 0 disables the restriction entirely.
Disabling the cap removes a critical safety mechanism. It is only appropriate for controlled testing environments. On the M2 Sepolia deployment, the cap is set to the default of 8,000 bps (80%).

Querying Utilization Onchain

import { poolVaultAbi } from "@nile-markets/sdk";

// Read current utilization in basis points
const utilizationBps = await publicClient.readContract({
  address: POOL_VAULT_ADDRESS,
  abi: poolVaultAbi,
  functionName: "riskCapacityUtilization",
});

// Read max withdrawable in USDC for a specific share holder
const maxWithdrawable = await publicClient.readContract({
  address: POOL_VAULT_ADDRESS,
  abi: poolVaultAbi,
  functionName: "maxWithdraw",
  args: [userAddress],
});

ERC-4626 Vault

How the vault operates and tracks exposure.

Deposit & Withdraw

Step-by-step guide for LP operations.

Pool Exposure Caps

How the risk manager limits pool-level exposure.