> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nilemarkets.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pool Utilization

> riskCapacityUtilization = sumAbsBucketExposure × BPS_DENOMINATOR / maxNetExposure in basis points — withdrawals blocked when utilization exceeds maxRiskCapacityBps (default 8000 = 80%). Credits bucket-level netting between hedged longs and shorts.

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).

| Variable               | Type                                | Description                                                                                                                                           |
| ---------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sumAbsBucketExposure` | **Onchain**: stored in PoolVault    | Sum of `\|netExposure\|` across every active `(pair, fixingTimestamp)` bucket. Maintained incrementally on every position open/close/increase/reduce. |
| `BPS_DENOMINATOR`      | Constant                            | 10,000 (basis point scaling constant)                                                                                                                 |
| `maxNetExposure`       | **Computed**: read from RiskManager | `totalAssets × netExposureCapFactorBps / stressMoveBps`. The same ceiling that gates new position opens.                                              |

Utilization itself is **Computed** — derived at query time by `PoolVault.riskCapacityUtilization()`.

<Note>
  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.
</Note>

## Maximum Utilization Cap

The protocol enforces a configurable cap on utilization:

| Parameter            | Default     | Description                                      |
| -------------------- | ----------- | ------------------------------------------------ |
| `maxRiskCapacityBps` | 8,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.

<Warning>
  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.
</Warning>

## 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

<AccordionGroup>
  <Accordion title="One-sided book — 95k long, no hedge, 120k pool">
    | Metric                                  | Value                                             |
    | --------------------------------------- | ------------------------------------------------- |
    | Total Assets                            | 120,000 USDC                                      |
    | sumAbsBucketExposure                    | 95,000 USDC (all in one bucket)                   |
    | netExposureCapFactorBps / stressMoveBps | 10,000 / 200                                      |
    | maxNetExposure                          | 120,000 × 50 = 6,000,000 USDC                     |
    | riskCapacityUtilization                 | 95,000 × 10,000 / 6,000,000 ≈ **158 bps (1.58%)** |
    | Max Utilization Cap                     | 8,000 bps (80%)                                   |

    Well under the cap — withdrawals are unrestricted.
  </Accordion>

  <Accordion title="Hedged book — 50k long + 45k short same bucket, 120k pool">
    | Metric                  | Value                                          |
    | ----------------------- | ---------------------------------------------- |
    | Total Assets            | 120,000 USDC                                   |
    | Gross Notional          | 95,000 USDC                                    |
    | sumAbsBucketExposure    | \|50,000 − 45,000\| = 5,000 USDC               |
    | maxNetExposure          | 6,000,000 USDC                                 |
    | riskCapacityUtilization | 5,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.
  </Accordion>
</AccordionGroup>

## Why Cap Utilization?

The cap serves four purposes:

<Steps>
  <Step title="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.
  </Step>

  <Step title="Ensure settlement liquidity">
    Matured positions must be settled with USDC payouts to profitable traders. The reserve ensures funds
    are always available.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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.
  </Step>
</Steps>

## Dynamic Utilization Changes

Utilization changes with every position operation:

| Event                                                      | Effect 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 closed                                            | sumAbsBucketExposure decreases, utilization falls          |
| LP deposits USDC                                           | totalAssets and maxNetExposure increase, utilization falls |
| LP withdraws USDC                                          | totalAssets and maxNetExposure decrease, utilization rises |

## Disabling the Utilization Cap

Setting `maxRiskCapacityBps` to 0 disables the restriction entirely.

<Warning>
  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%).
</Warning>

## Querying Utilization Onchain

```typescript theme={null}
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],
});
```

## Related Pages

<Columns cols={3}>
  <Card title="ERC-4626 Vault" icon="vault" href="/deploy/vault-mechanics">
    How the vault operates and tracks exposure.
  </Card>

  <Card title="Deposit & Withdraw" icon="money-bill-transfer" href="/deploy/depositing-withdrawing">
    Step-by-step guide for LP operations.
  </Card>

  <Card title="Pool Exposure Caps" icon="shield-halved" href="/protocol/pool-exposure-caps">
    How the risk manager limits pool-level exposure.
  </Card>
</Columns>
