Skip to main content
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.
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.

ERC-4626 Standard

The PoolVault implements the ERC-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

Deposit Functions

deposit(assets, receiver) — specify USDC amount, receive proportional shares. mint(shares, receiver) — specify desired shares, deposit the required USDC.

Withdrawal Functions

withdraw(assets, owner, receiver) — specify USDC amount to receive, burn required shares. redeem(shares, owner, receiver) — specify shares to burn, receive proportional USDC.

Zero-Sum Counterparty Model

The pool is the counterparty to all trader positions. This creates a zero-sum dynamic between traders and the pool:
EventTrader ImpactPool Impact
Trader profits+PnL to trader-PnL from pool equity
Trader loses-PnL from trader+PnL to pool equity
Trading fee collectedDeducted from margin70% accrues to pool
Liquidation penaltyDeducted from margin70% accrues to pool
Oracle fee collectedDeducted from collateral70% accrues to pool
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.

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:
1

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

Traders open positions

Opening a position does not immediately affect pool equity. Fees collected at open increase pool assets.
3

Forward prices move

Unrealized PnL across all open positions changes the aggregate trader PnL. Pool equity adjusts in the opposite direction (zero-sum).
4

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

LP redeems shares

Shares are burned at the current share price. The LP receives their proportional share of pool equity in USDC.

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

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

Exposure Tracking

The vault tracks directional and gross exposure to manage pool risk:
MetricTypeDescription
netExposureint256Directional exposure. LONG positions decrease it (pool is short), SHORT positions increase it (pool is long).
grossNotionaluint256Sum of all open position notional values, regardless of direction.
Per-pair exposureSeparate per pairIdpairNetExposure 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:
FunctionEffect
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.
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.

Deposit & Withdraw

Step-by-step guide to depositing USDC and redeeming shares.

Share Price

Detailed breakdown of what drives share price up and down.

Pool Utilization

How utilization is measured and how it restricts withdrawals.