-
Notifications
You must be signed in to change notification settings - Fork 125
Drift Accounting: Pools & Settlement
Within Drift Protocol, all token deposits are held in a global collateral vault. This is required for seamless cross-margin and borrow-lend. The only exception to this is the insurance fund vault residing outside.
Ensuring proper accounting across users requires a robust settlement mechanism. The protocol uses intermediate Pool Balances to facilitate transfers and ensure that claimed gains are required to come from settled offsetting losses.
Perpetual Market
An individual perpetual market has two pools:
A. P&L Pool: to accumulate funds from users with losses for settlement to users with profits B. Fee Pool: to accumulate a fraction of exchange fees for the Quote Spot Market's Revenue Pool
The P&L Pool receives the highest priority on claimed funds, in order to give user's the best possible experience. The default fraction of exchange fees for the Fee Pool is total_exchange_fee / 2 and this fraction is determined by: SHARE_OF_FEES_ALLOCATED_TO_CLEARING_HOUSE.
The Fee Pool will only get partially filled up by up to 1% of intermediate P&L settled from a user's losses and aggressively drawn down for the benefit of the P&L Pool otherwise.
Spot Market
An individual spot market has two pools:
A. Revenue Pool: to accumulate revenue across the protocol, denominated in this token B. Fee Pool: to pay fillers and settle portions to the revenue pool
The Revenue Pool can collect fees from:
- Borrow interest
- Liquidations
- Perpetual Markets
and can pay out to
- Insurance Fund Stakers
- Perpetual Markets
(see details of these rules in Revenue Pool)
The Fee Pool collects exchange fees from swaps and uses them to pay out the Keeper Network Keepers & Decentralised Orderbook
Future Work
Currently, a Perpetuals Market can only pull from the Spot Market Revenue Pool and Insurance Fund for its quote currency.
- In the future, it may be possible for a distressed associative perp market (BTC-PERP) to be able to pull funds from the associated spot market (BTC) revenue/insurance pool and immediately swap for USDC to top off its fee/P&L pool.
Any account can call the settlePNL instruction, which will trigger negative P&L accounts to be settled, adding to each per-market P&L pool. Negative P&L being settled increases the amount available to be settled, whilst positive P&L being settled decreases the amount available for settlement.
Note: calling settlePNL does not affect open positions. The function only settles the funds available in the PNL Pool for withdrawal.
It's important to recognise the difference between settling P&L and realising P&L (read more here: P&L.
Calling settlePNL
Any account can call settlePNL instruction. Once called, all unrealised negative P&L will be settled and added to the market's P&L Pool to be made available for withdrawal.
Users with open positions that have negative unrealised P&L will have their unrealised P&L settled and sent to the P&L Pool; however, their position will be unaffected.
As users are settled against, the Cost Basis for their position will be adjusted so that their position remains unchanged even though a portion of their unrealised negative P&L has been realised and sent to the P&L Pool.
The P&L settled as a result of the settlePNL instruction will be reflected in theUnrealised P&L tab, specifically within theRealised P&L column. The adjusted cost basis for the position is reflected in the Cost Basis column.
Both Perpetual and Spot Markets have Fee Pools. Fee pools are set up to accumulate a fraction of exchange fees to eventually be sent to the associated Revenue Pool.
Perpetual Market Fee Pool can be utilized for bankruptcy resolution after its insurance fund threshold is reached.
A portion of the fees collected within the protocol (denominated in a particular token: USDC, SOL, etc) go into that spot market's revenue pool.
The revenue pool increases from various portions of the protocol:
- borrow fees
- spot market exchange fees
- perpetual market exchange fees
- liquidations
and ultimately goes to fund:
- insurance vault
- perpetual market amm (conditionally)
Insurance Fund
Every hour (on the hour), a portion of the revenue pool can be settled to the insurance fund using the permissionless settle_revenue_to_insurance_fund instruction:
If the insurance fund has users staked, each individual hourly settlement is capped to what would amount to 1000% APR
- thus an astronomically large inflow into the revenue pool (relatively to user insurance staked amounts) would result in revenue that slowly reaches the insurance over a longer period of time rather than immediately
- this encourages more insurance fund stakers (who require a medium horizon of insurance offering) to join during the high annualised cap inflow
Insurance Fund Stakers must adhere to the cooldown period for withdrawals (see Insurance Fund Staking).
Spot Markets
Spot Markets allow for swaps between tokens and interest payments between depositors and borrowers. These token swaps and flow of interest are parameterised to allow fee collection for the revenue pool and thus ultimately insurance.
Within the program, its parameterised by the following in bold:
Field | Description |
---|---|
total_if_factor | percentage of the borrow interest reserved for revenue pool |
user_if_factor | this proportion of total_if_factor is reserved for staked users (the other piece is reserved for the protocol itself) |
liquidation_if_factor | the proportion of liability transfer in liquidate_borrow that is sent to the revenue pool |
Thus the following must be true: user_if_factor <= total_if_factor. For example, if the total_if_factor is 100%, depositors would receive no interest from borrows.
The following instructions interact w/ the insurance fund:
- resolve_borrow_bankruptcy
Perpetual Markets
Perpetual Markets are bootstrapped by the Drift AMM which depending on market-making performance conditions can add and remove funds from the revenue pool.
Within the program, its parameterized by the following in bold:
Field | Description |
---|---|
max_revenue_withdraw_per_period | the amm's max revenue pool draw per period |
(note this doesn't include bankruptcy resolution) | |
revenue_withdraw_since_last_settle | revenue pool draws on behalf of user pnl since the last settle |
(note this doesn't include bankruptcy resolution) | |
last_revenue_withdraw_ts | the last timestamp of a revenue withdraw |
(track in order to reset the period) |
A perpetual market's amm may draw up to max_revenue_withdraw_per_period from the revenue pool every period.
Additionally, for direct draws from the insurance fund, it parameterized by the following in bold:
Field | Description |
---|---|
quote_settled_insurance | settled funds from the insurance fund since inception |
quote_max_insurance | max funds it can settle from insurance fund since inception |
unrealized_max_imbalance | max amount of pnl the net users can be owed within a market before: |
- draws from insurance are allowed
- initial asset weights for this pnl gets discounted |
Unlike spot markets, perp markets are capped by the max draw from insurance via quote_max_insurance
quote_settled_insurance tracks the insurance fund draw amount since inception. Once this threshold is reached or the insurance fund is depleted, the market will then resort to the AMM Fee Pool. For any remaining losses not covered, the market will perform socialized losses in bankruptcy events.
The following instructions interact w/ the insurance fund:
- resolve_perp_pnl_deficit
- resolve_perp_bankruptcy
notes:
resolve_perp_pnl_deficit can only be resolved by insurance fund deposits (within the market's constraints), not by social loss with other users
Staking
Reward
For providing liquidity to the Insurance Fund, Insurance Fund Stakers are rewarded with their proportionate share of the Revenue Pool every hour.
The Revenue Pool is funded by various aspects of the protocol:
- borrow fees;
- spot market exchange fees;
- perpetual market exchange fees; and
- liquidation fees.
An Insurance Fund Staker's proportionate share is calculated by: Total Staked Amount / Total Insurance Fund
Each revenue settlement is split between Insurance Fund Stakers and a protocol-owned portion of the insurance fund.
Example
- The Insurance Fund is at $5000 USDC. You decide to stake $10,000 USDC, bringing the total to $15,000 USDC.
Your proportionate share of the Revenue Pool paid every hour for stakers would be 10000/15000 = 66.6%.
Each hour, as the revenue pool settles fees earned to the Insurance Fund, let's say $30. Half of this is reserved for the protocol, while the other half is designated for stakers, making the staker payout $15. You will receive 66.6% of the payout ($10) and the remaining Insurance Fund stakers would receive 33.3% ($5).
Unstaking (Cooldown Period)
There is a cooldown period of ~14 days for unstaking any collateral from the Insurance Fund.
A user first requests to unstake a specific amount (denominated in shares). During the cooldown period, the user still receives rewards and is liable for user deficit resolution. After the elapsed period, the user can then unstake. Upon unstake, a net winning during the cooldown period is forgone and split amongst the current set of stakers and while a net loss is incurred by the unstaker. This means the unstake process downside only for the unstaker, and upside only for the stakers who remain.
Additionally, during the cooldown period, if a user wishes to cancel the unstake request, they forgo any gains made during the unstake request period and their share is adjusted according. Those forgone gains are also split amongst the current stakers upon cancellation.