All exposure cap parameters are managed by the
RISK_ADMIN_ROLE and take effect immediately upon update. Changes affect new position validation but do not retroactively close existing positions that exceed updated caps.Net Exposure Cap
The maximum net exposure the pool can take on is calculated using a stress-adjusted formula:| Parameter | Default | Description |
|---|---|---|
netExposureCapFactorBps | 10,000 (100%) | Pool equity fraction available for exposure |
stressMoveBps | 200 (2%) | Hypothetical adverse price move for stress testing |
Why stress-adjusted? The
stressMoveBps parameter represents a hypothetical worst-case price move. By dividing by this value, the formula ensures that even if the market moves by the stress amount, the pool’s total loss would not exceed the fraction of equity allocated for exposure. This is a fundamental risk management technique borrowed from traditional finance stress testing.Worked Example
With a pool equity of 10,000,000 USDC (10M):Exposure Tracking
The protocol tracks two distinct exposure metrics in real time, both per-pair and in aggregate:Net Exposure
netExposure (int256 — signed)Represents the pool’s directional bias. Updated on every position open, close, increase, and reduce:- LONG position opened:
netExposure -= notional(pool takes the short side) - SHORT position opened:
netExposure += notional(pool takes the long side)
Gross Notional
grossNotional (uint256 — unsigned)Sum of all open position notionals regardless of direction. Increases when positions are opened, decreases when positions are closed or reduced. Used for utilization calculations and rate-of-change limits.Pool Utilization
Utilization measures how much of the pool’s assets are backing open positions:Withdrawal Restriction
LP withdrawals are restricted when utilization is high. ThemaxUtilizationBps parameter (default: 8,000 = 80%) caps how much of the pool’s assets can be committed to open positions after a withdrawal:
Why cap utilization at 80%?
Why cap utilization at 80%?
The 80% default ensures a 20% liquidity buffer remains in the pool at all times. This buffer serves two purposes:
- Payout capacity: If all open positions move in the traders’ favor simultaneously, the pool needs unencumbered assets to pay out profits.
- Operational headroom: The buffer absorbs fee payments, bad debt events, and oracle-fee costs without immediately blocking withdrawals.
Rate-of-Change Limits
Beyond absolute caps, the protocol can enforce rolling window limits on how quickly exposure changes. This prevents sudden spikes in exposure that could indicate manipulation or a coordinated attack.- Gross Notional Rate Limit
- Net Exposure Rate Limit
Limits the total notional added within a rolling window:Prevents a burst of position openings from overwhelming the pool in a short time frame.
Window Configuration
| Parameter | Default | Description |
|---|---|---|
rateWindowSeconds | 3,600 (1 hour) | Rolling window duration |
maxGrossNotionalDeltaPerWindow | 0 (disabled) | Max gross notional added per window |
maxNetExposureDeltaPerWindow | 0 (disabled) | Max net exposure change per window |
In the current M2 deployment, both rate-of-change limits are set to 0, which disables them. They are available as defense mechanisms that the risk admin can activate if unusual trading patterns are detected. When enabled, exceeding either limit reverts with
RateOfChangeExceeded.block.timestamp exceeds windowStartTime + rateWindowSeconds, the counters reset and a new window begins.
Pool Equity Floor
In extreme scenarios where cumulative bad debt from liquidated positions exceeds pool equity, the pool equity is clamped to zero:Dynamic Scaling
All caps scale dynamically with pool equity, which creates a self-regulating system:Pool Grows
As LPs deposit more USDC,
poolEquity increases. This raises maxNetExposure, which in turn raises position and account caps. The protocol can support more trading activity.Pool Shrinks
When the pool pays out trader profits or absorbs bad debt,
poolEquity decreases. Caps tighten automatically. New positions must be smaller, and the pool becomes more conservative.Exposure Events
The protocol emits events whenever exposure changes, enabling off-chain monitoring and alerting:| Event | Fields | Indexed |
|---|---|---|
ExposureUpdated | netExposure, grossNotional | — |
PairExposureUpdated | pairId, netExposure, grossNotional | pairId |