Technical Overview
At a high level, Perp v3 is a DEX system that uses a vault to hold user collateral, a router to choose from among several liquidity/pricing options in a liquidity framework, and a clearinghouse to record user account information.
For details about liquidity framework components, see Maker.
Contracts
The core Perp v3 contracts handle user deposits, trades, settlement and liquidation.
Vault contract
User deposits and withdrawals are made to/from the vault contract (called Funding Account for users). All collateral deposits are kept in the user's exchange funding account. All trades are backed by margin drawn from this collateral, and each position has its own margin. All user deposits remain in the vault at all times, and user accounts are updated according to the clearinghouse contract (below).
See Vault for details and code examples.
Order Gateway contract
You may choose to let the order gateway find the best price for you, or directly trade with the pool you want to use. This section assumes you want to trade using the order gateway.
The benefit of using the order gateway is easier setup via API, simplified quoting and automated price finding. The cons of using the order gateway are slightly slower execution and slightly increased potential for downtime due to an increased number of moving parts.
See Order Gateway for details and code examples.
Clearinghouse contract
Only one position of each asset can be open at a time, for a given account. If a second order for an asset with an existing position is created, the two resulting positions will be summed together. E.g. if you have a 1 ETH long and open a 1 ETH short, the two positions will sum to 0.
All trades and updates to account balance are handled by the clearinghouse contract.
Adding and removing position margin is controlled by the clearinghouse. Perp v3 uses isolated margin (each position has its own discrete margin). Rules regarding removal of margin are set and enforced by the clearinghouse.
See Clearinghouse for details and code examples.
Clearinghouse role in trade sequence
Quoter contract
Prices for trades (quotes) can be obtained using the Quoter contract.
Note: Quoter contract only considers onchain prices. Ie. it does not take live limit orders into account.
Maker contracts
Each maker has a contract housed under Maker. See each type for details.
Some maker types allow LPs to use leverage, such as Perp v3 oracle maker pools.
Fees
Borrowing fee
A fee is paid to maintain an open position in the same way you would pay interest on a loan from a Defi lending platform. All takers pay borrowing fees, and makers may pay in some circumstances.
The borrowing fee for each market is calculated based on the aggregate utilization ratio of all makers (LPs) in that market.
Details: Borrowing Fee
Funding fees / funding payments
Notes
Funding payments only apply to some markets. See Perp contract specs.
Funding payments relate to the ratio of long/short open interest, not the ratio of market and index prices. Regardless, longs still pay shorts when funding is positive, and vice versa.
Funding fees are designed to mitigate makers' exposure to price movement in cases where hedging is not possible (e.g. Oracle pools). The funding rate is based on the long/short skew of the basePool
.
If the basePool has more shorts, takers (and possibly some makers) holding longs will pay funding fees.
If the basePool had more longs, takers (and possibly some makers) holding shorts will pay funding fees.
Non-basePool makers pay or receive funding based on their own long/short skew.
Traders holding positions opposite to the base maker's direction need to pay a funding fee to traders holding positions in the same direction as the base maker.
Matcher fee
In general the matcher fee applies to UI users only. At launch this is a flat fee and in the future may be dynamic based on volume.
Account value
Account value is dependent on margin and unrealized PnL, and derived as follows.
Margin & Leverage
Each market may have separate parameters for initial and maintenance margin ratios (and corresponding leverage values). See values in Perp contract specs.
Initial Margin Ratio
Positions must have a margin ration equal to or higher than the initial margin ratio when opened. The open position transaction will revert if the margin ratio is lower than the initial margin ratio. Initial Margin Ratio applies to
Open position (including when trading in reverse direction, e.g. opening a short with an existing long)
Increase position size*
Maintenance Margin Ratio
Positions must have a margin ratio higher than the maintenance margin ratio. Positions with a lower margin ratio may be liquidated. Maintenance margin ratio applies to
Decrease position size* (includes close position and partial close)
Liquidation conditions (margin ratio must be equal to or lower than MMR for a liquidation transaction to succeed)
Reduce vs Close Position
Reducing a position is done by calling openingPosition
in the opposite direction of the existing position. The clearinghouse will evaluate the position's margin according to positionSizeBefore
and positionSizeAfter
as well as taking into account position direction (long or short).
Depending on the result of the trade, either maintenanceMarginRatio
or initialMarginRatio
will be used to evaluate the validity of the transaction.
Close or partial close will always use maintenanceMarginRatio
.
Free collateral
The vault (funding account) contract checks the user's free collateral when trades and withdrawals. Depending on the action, the method for calculating free collateral is as follows.
Collateral needed for untriggered limit orders, etc., will cause orders to fail if removed.
For trades
For withdrawals
Liquidation
When the account value falls below the maintenance margin requirement, the position will start to undergo liquidation. When a position is liquidated, it will be transferred to the liquidator at the current oracle price. This means that the liquidator must hold sufficient margin to take over the liquidated position. The margin amount will determine how many positions they can take over.
Maximum Liquidatable Position Size
When the account margin ratio falls below the maintenance margin requirement (MMR) but remains above 0.5*MMR, the liquidator may only liquidate up to half of the position size. If the margin ratio < 0.5*MMR, liquidators may liquidate the entire position.
Liquidation Penalty & Liquidation Fee
Traders pay a liquidation penalty after liquidation, and the liquidator will receive a portion of the liquidation penalty as fee for triggering the liquidation. The remaining penalty is reserved by the protocol. To prevent bad debt exploits, both the liquidation penalty and liquidation fee are settled through the Pnl Pool. Traders pay liquidation penalties to Pnl Pool, and liquidators and the protocol receive liquidation fees from the Pnl Pool.
Liqudation Penalty Calculation
Liquidation Fee Calculation
PnL Pool
PnL pool is pending confirmation
Each market has a separate PnL pool
All PnL, positive or negative, passes through the market's PnL pool before being withdrawn to the user's funding account (vault). The purpose of the PnL pool is to settle PnL and ensuring all losses match profits for the given market before profits can be withdrawn. Negative PnL is retained by the pool to pay to accounts that settle positive PnL.
If settlement is not possible (settled positive PnL > PnL pool balance), withdrawal will be delayed until positions with negative PnL (unrealized losses) are settled, adding funds to the PnL pool. Withdrawal delays could occur for example when there is a large amount of realized profit and unrealized loss within one market. Traders in profit would need to wait for some of the unrealized losses to be realized before being able to withdraw fully. In general conditions when withdrawals would be blocked are considered an edge case.
This architecture allows the protocol trading engine to be less restrictive without compromising the safety of user funds. Using the PnL pool, the protocol ensures that PnL always balances and user funds are safe from exploitation. The PnL Pool replaces the Insurance Fund in more traditional leverage trading.
PnL Pool Actions
Open position
no action needed
Reduce, close or liquidate position
If PnL > 0 →
Withdraw only if PnL Pool has enough funds
When positive PnL is settled, the PnL pool balance decreases
If PnL < 0 →
Withdraw only if
trader.margin
has enough fundsWhen negative PnL is settled, the PnL pool balance increases
_settlePnl()
What is it
Deposit: Should
_settlePnl()
as much as possible to clear the trader’s existing unsettled PnL.Withdraw: Should
_settlePnl()
as much as possible before calculating free collateral so it could maximize withdrawal limit.
Bad debt
The PnL pool is intended to serve in place of an insurance fund, which means it will have to handle cases where bad debt occurs.
Price band
A price band is in place to ensure trades happen within a safe range compared to the underlying price mechanism (e.g. oracle price). This guards against exploits and extreme volatility. Query priceBandRatio
using Config.
baseMaker
The baseMaker is used when calculating funding rates. A base maker is a whitelisted liquidity provider that meets the following conditions:
Cannot increase/decrease positions actively (may increase/decrease margin)
Must always accept taker orders
Must use index price as main pricing mechanism
Only one
baseMaker
per marketThe
baseMaker
always receives funding, and other makers and takers that have positions with the same direction as thebaseMaker
also receive funding
Updating baseMaker
🏗️ Admin function - how this is updated is a future decision.
Circuit Breaker
Perp v3 employs the ERC-7265 circuit breaker in order to rate limit withdrawals. The withdrawal rate is limited to a set percentage of TVL withdrawn per time period. The circuit breaker is controlled by a multisig that is controlled by the team and/or protocol governance.
Rate Limit Procedure
The rate limit will revert any operation that exceeds the set limit. Operations within the limit can continue to execute, e.g. if rate limit is 1000 and current rate is 900, a withdrawal of 200 will be limited but a subsequent withdrawal of 50 will be permitted.
When rate limit is triggered:
Vault withdrawal transactions will revert
Some withdrawals from maker (LP) positions will revert
Spot hedge maker
fillOrder()
may also revert because it withdraws from vault
Multisig owners check if there’s a hack or just a whale withdrawing or trading against spot hedge maker.
Next steps
It's a hack: Multisig is used to call
markAsNotOperational()
. Withdrawals are permanently locked and funds can only be removed by callingmigrateFundsAfterExploit()
.It's not a hack:
Take no action - withdrawals will be limited until the
_rateLimitCooldownPeriod
has passed. After cooldown, anyone can calloverrideExpiredRateLimit()
to remove rate limiting once_rateLimitCooldownPeriod
has passed.If it’s not a hack, the multisig owners can choose to call
overrideRateLimit()
to establish a grace period. Rate limit will be suspended untilgracePeriodEndTimestamp
.
Oracle System
In oracle price markets, Perp v3 relies on oracle prices to calculate account value and for liquidations. The Pyth Network is currently used as the source for oracle prices. To avoid oracle front-running issues, most actions require two steps separated by a delay to execute, or actions are handled via a trusted off-chain service to relay the tx:
Send transactions in two steps, first to update the oracle price and second to execute the transaction, with a min. timestamp delay of 3 seconds (applies to add/remove margin, open/close positions, and liquidations)
Bundle the two transactions using the
multicaller
contract
(Trades performed using the UI use multicaller
.)
Limit orders
Limit orders are held in an offchain database (orderbook) and will be matched against orders (market or limit orders) or filled using liquidity framework makers when the trigger conditions are met.
Key considerations
Limit order creation via contract or API is not currently supported but may be in the future.
Limit orders are treated like market orders once they are triggered; all fees are paid the same as market orders.
Order expiry is currently fixed and will be updatable in a future release.
A min. order size (openNotional, currently 10 USDT) applies to limit orders.
Market orders can be matched directly against open limit orders, if the price is preferential.
Order will be cancelled if user's futures account does not hold enough funds to back the order.
Limit orders are filled FCFS (lower timestamps fill first; if timestamp is the same, order may be determined according to the database specs.)
Fees
Limit orders are subject to a relayer fee:
Fee is paid one time, no matter how many times order is filled
Fee is paid from the user's futures account
Fee is paid at the time of the first fill for each order
Multicaller Library
Perp v3 uses the Multicaller library to "efficiently call multiple contracts in a single transaction." See the library here: https://github.com/vectorized/multicaller
Last updated