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

# How the Vault Works

> ERC-4626 tokenized vault where LPs deposit USDC and receive share tokens — vault is sole counterparty to all positions, share price adjusts for aggregate unrealized PnL, standard ERC-4626 interface

The Open Nile Protocol uses a single ERC-4626 tokenized vault as the counterparty to every
trader position. Liquidity providers (LPs) deposit USDC into the PoolVault and receive share tokens
representing their proportional ownership of pool equity. The vault's share price rises when traders lose
or fees are collected, and falls when traders profit.

<Note>
  The PoolVault is deployed on Ethereum Sepolia testnet using MockUSDC (a test token with no monetary value).
  The vault mechanics are identical to what will be used in production with canonical USDC.
</Note>

## ERC-4626 Standard

The PoolVault implements the [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) tokenized vault standard,
which defines a standard interface for yield-bearing vaults. This means:

* **Deposits** accept USDC and mint proportional share tokens
* **Withdrawals** burn share tokens and return proportional USDC
* **Share price** is fully determined onchain by the ratio of pool equity to total shares outstanding
* **Composability** with any ERC-4626-compatible tooling, aggregators, or interfaces

<Columns cols={2}>
  <Card title="Deposit Functions" icon="arrow-down-to-bracket">
    `deposit(assets, receiver)` — specify USDC amount, receive proportional shares.
    `mint(shares, receiver)` — specify desired shares, deposit the required USDC.
  </Card>

  <Card title="Withdrawal Functions" icon="arrow-up-from-bracket">
    `withdraw(assets, owner, receiver)` — specify USDC amount to receive, burn required shares.
    `redeem(shares, owner, receiver)` — specify shares to burn, receive proportional USDC.
  </Card>
</Columns>

## Zero-Sum Counterparty Model

The pool is the counterparty to **all** trader positions. This creates a zero-sum dynamic between traders
and the pool:

| Event                 | Trader Impact            | Pool Impact           |
| --------------------- | ------------------------ | --------------------- |
| Trader profits        | +PnL to trader           | -PnL from pool equity |
| Trader loses          | -PnL from trader         | +PnL to pool equity   |
| Trading fee collected | Deducted from margin     | 70% accrues to pool   |
| Liquidation penalty   | Deducted from margin     | 70% accrues to pool   |
| Oracle fee collected  | Deducted from collateral | 70% accrues to pool   |

<Info>
  Fees partially offset pool losses from trader profits. Even if a trader is profitable, the pool may
  break even or gain if fees collected exceed the PnL payout. Over time, fee income provides a structural
  advantage to the pool, analogous to the "house edge" in a trading venue.
</Info>

## Share Price

The share price is the fundamental metric that determines the value of each LP share token:

```
sharePrice = poolEquity / totalSupply
```

When `totalSupply` is zero (no outstanding shares), the share price defaults to 1.0, meaning the first
depositor receives shares at a 1:1 ratio with USDC.

Share price changes reflect the cumulative performance of the pool:

<Steps>
  <Step title="LP deposits USDC">
    New shares are minted at the current share price. The deposit does not change the share price because
    both total assets and total shares increase proportionally.
  </Step>

  <Step title="Traders open positions">
    Opening a position does not immediately affect pool equity. Fees collected at open increase pool assets.
  </Step>

  <Step title="Forward prices move">
    Unrealized PnL across all open positions changes the aggregate trader PnL. Pool equity adjusts in
    the opposite direction (zero-sum).
  </Step>

  <Step title="Positions settle or are liquidated">
    Realized PnL is applied to the pool via `applyPnl()`. Trader profits are paid out from pool assets.
    Trader losses are absorbed by the pool. Fees are distributed.
  </Step>

  <Step title="LP redeems shares">
    Shares are burned at the current share price. The LP receives their proportional share of pool equity
    in USDC.
  </Step>
</Steps>

## Pool Equity

Pool equity is the total value backing all outstanding share tokens:

```
poolEquity = totalAssets + poolPnl
poolPnl    = -aggregateTraderPnl
```

* `totalAssets` is the USDC balance held by the vault contract
* `poolPnl` is the negative of the aggregate PnL across all open trader positions
* If `poolEquity` would go negative, it is clamped to 0

<Warning>
  Pool equity can decrease if traders are collectively profitable. In extreme scenarios where aggregate
  trader profits exceed total pool assets, pool equity is clamped to zero. This means LPs could lose their
  entire deposit in a worst-case scenario. The risk management system (exposure caps, margin requirements,
  liquidation) is designed to prevent this from occurring.
</Warning>

## LP Allowlist

The PoolVault supports an optional allowlist for deposits:

* **`allowlistEnabled`** — boolean flag that enables or disables the allowlist check
* **`setAllowlisted(address, bool)`** — admin function to add or remove addresses from the allowlist
* When enabled, only allowlisted addresses can call `deposit()` or `mint()`
* Withdrawals are never restricted by the allowlist (only by the utilization cap)

<Tip>
  On the M2 Sepolia testnet, the allowlist is currently disabled, so anyone can deposit. This may change
  in future milestones as the protocol matures toward mainnet.
</Tip>

## Exposure Tracking

The vault tracks directional and gross exposure to manage pool risk:

| Metric            | Type                  | Description                                                                                                   |
| ----------------- | --------------------- | ------------------------------------------------------------------------------------------------------------- |
| `netExposure`     | int256                | Directional exposure. LONG positions decrease it (pool is short), SHORT positions increase it (pool is long). |
| `grossNotional`   | uint256               | Sum of all open position notional values, regardless of direction.                                            |
| Per-pair exposure | Separate per `pairId` | `pairNetExposure` and `pairGrossNotional` tracked independently per currency pair.                            |

Exposure values are updated **atomically** on every position operation (open, close, increase, reduce).
The RiskManager reads these values to enforce pool-level exposure caps before allowing new positions.

## PnL Application

Only the SettlementEngine can modify pool equity through two privileged functions:

| Function                                  | Effect                                                                                 |
| ----------------------------------------- | -------------------------------------------------------------------------------------- |
| `applyPnl(int256 pnl)`                    | Positive value = pool gains (trader loss). Negative value = pool pays (trader profit). |
| `transferOut(address to, uint256 amount)` | Direct USDC transfer for settlement payouts to traders.                                |

<Note>
  These functions are access-controlled to the SettlementEngine contract. External accounts cannot call
  them directly. This ensures pool equity changes only occur through the proper settlement workflow.
</Note>

## Related Pages

<Columns cols={3}>
  <Card title="Deposit & Withdraw" icon="money-bill-transfer" href="/deploy/depositing-withdrawing">
    Step-by-step guide to depositing USDC and redeeming shares.
  </Card>

  <Card title="Share Price" icon="chart-line" href="/deploy/share-price">
    Detailed breakdown of what drives share price up and down.
  </Card>

  <Card title="Pool Utilization" icon="gauge-high" href="/deploy/pool-utilization">
    How utilization is measured and how it restricts withdrawals.
  </Card>
</Columns>
