---
# System prepended metadata

title: Perpetual Futures Contracts on Miden

---

# Perpetual Futures Contracts on Miden

## Introduction

A futures contract is an agreement to buy or sell a particular commodity, asset, or security at a predetermined price at a specified time in the future.


A perpetual futures contract is a futures contract without an expiry date, allowing traders to speculate on asset prices indefinitely.

Perpetual futures contracts use a funding rate mechanism to help keep their price close to the spot price of the underlying asset.


## Perpetual Futures Exchange Architecture

In this design, every opened perpetual contract will have a counterparty willing to match the trade by betting on the opposite price movement.

Pending trades that do not find a counterparty are not opened.

This design relies on an external off-chain order book matching algorithm to be implemented efficiently. When opening perpetual trades, public Miden notes can be created with a specific tag so that if the off-chain order book matching algorithm stops working, the perpetual exchange can continue to function, albeit at a slower pace.

Other design ideas that enable perpetual like trading, are the creation of a lending platform on Miden, where traders can borrow or deposit the asset they want to long or short. Leveraged trading enabled by a lending platform design is proven to work on EVM chains; however, it relies extensively on flashloans, thus would require additional research to implement in Miden VM.

Given these considerations, the most efficient and straightforward design is to require that each opened perpetual contract has a counterparty willing to bet on the inverse price movement. 

When two traders are matched together, their notes are batched together and sent to the perpetual contracts account where they are consumed, transfering the margin liquidity amount of both notes into the perpetual contracts exchange account. 

##  Architecture

Trader 1 submits a perpetual order note to the perpetual contract matcher.

![Perp Architecture (1)](https://hackmd.io/_uploads/BJsTtR3mR.png)


Once two counter balancing perpetual contract trades are matched, they are passed together inside of a note which is consumed by the perpetual contracts account on-chain. Both trade notes contain the initial margin liquidity of the perpetual contract.

In case Trader 1's perpetual contract is not matched, i.e. a willing counterparty is not found, Trader 1 can reclaim the liquidity in the note, similar to a P2IDR Miden note.

This design also allows to batch multiple matched user perpetual contract order notes into a single transaction which is then passed to the Perpetual contract smart contract. 

![Untitled presentation](https://hackmd.io/_uploads/ryGB7bb70.svg)

Once the counter-balancing perpetual contracts are consumed by the perpetual contracts account smart contract, funding rates, as well as trade P&L are updated every hour.

The perpetual contract account smart contract consumes a price feed note every hour. This price feed note also calls a function inside of the perpetual contracts account to update the cumulative funding rate.

The mark price, or the price of the perpetual contracts is stored inside the perpetual contract account as a time weighted average price (TWAP). As new perpetual contracts are added to the perpetual contract account smart contract, the TWAP oracle is updated. 

### Partial Order Fulfilment

In cases where a trader cannot find a counterpart willing to bet on the inverse price movement with the same margin amount, it is possible to create a Perpetual Contracts Account on Miden that enables partial fulfillment of perpetual futures contracts. This same method of partial order fulfillment can be applied to Spark's spot order book exchange on Miden as well.

Partial fulfillment of spot orders can be achieved with a conditional note output inside a Miden account.

![Perp Architecture (2)](https://hackmd.io/_uploads/rJJUOeaQA.png)


In this design, two notes with order data and liquidity are paired together and sent to the partial SWAP note matcher contract. This contract can consume two swap notes in the same transaction and output two or more notes. If the two SWAP orders match perfectly, then two P2ID notes are outputted. If the two SWAP orders do not match but agree on the ratio of the assets being exchanged (price), then the smart contract can output 3 notes: two P2ID notes and one modified SWAP note which can be paired with another SWAP note in a subsequent transaction.

This same concept of partial order filling of notes can be extended to the perpetual futures exchange. Instead of two P2ID notes being outputted in addition to a modified SWAP note, the liquidity of the two matched perpetual futures orders remains in the perpetual futures exchange smart contract, and the leftover liquidity can be outputted as a perpetual futures order which can subsequently be matched with another perpetual futures order. The outputted perpetual futures order with the leftover margin liquidity would have the same note script and RECIPIENT data as the user-created perpetual futures order. This means that a trader with a large order would possibly have several counterparties in the perpetual futures contract.




### Funding Payment Calculation

At the start of each funding interval, an account receives or pays based on the funding rate. The payment (F) is calculated as:

$$ F = (-1) \times S \times P \times R $$

Where:
- **S**: Size of the position (positive if long, negative if short).
- **P**: Mark price of the perpetual contract.
- **R**: Funding rate for the period.

### Premium and Interest Rate Components

The funding rate consists of two components: the premium component and the interest rate component.

#### Premium Component

The premium component accounts for the difference between the perpetual contract's price and the spot price. It is calculated using the following formula:

$$ \text{Premium} = \frac{\text{Time Weighted Average Mark Price - Spot Price}}{\text{Spot Price}} $$

Where:
- **Time Weighted Average Mark Price**: The time weighted average price of the perpetual contract in the given period.
- **Spot Price**: The oracle-provided price for the asset.


#### Interest Rate Component

The interest rate component accounts for the difference in interest rates of the base and quote currencies. Currently, a fixed interest rate component is added to the funding rate:

$$ \text{Interest Rate Component} = 0.01\% \text{ per 8 hours} $$

The total funding rate is then:

$$ \text{Funding Rate} = \frac{\text{Premium Component}}{8} + \text{Interest Rate Component} $$

### Index Price and Funding Rate Bounding

The index price is provided by a relevant oracle, ensuring an accurate and reliable spot price for the underlying asset. To prevent extreme funding rates, bounds are set:

- **Minimum Funding Rate**: -4.00%
- **Maximum Funding Rate**: 4.00%

This ensures stability and predictability in funding payments.


## Miden Smart Contract Components

### Perpetual Contract Note Structure
- `size`: Represents the size of the position (number of contracts).
- `entryPrice`: The price at which the position was entered.
- `margin`: The amount of collateral backing the position.
- `isLong`: Boolean indicating if the position is long or short.
- `lastFundingRate`: Stores the cumulative funding rate at the last user interaction.

### Global Variables (in Perp Contract)
- `lastFundingUpdateTime`: Timestamp of the last funding rate update.
- `positions`: Mapping from user addresses to their position details.


### Key Functions in Perpetual Contract

#### `updateFundingRate()`

- Uses `calculateNewFundingRate()` to determine the new funding rate.
- Adjusts `lastFundingUpdateTime` to the current timestamp.

## Profit and Loss (P&L) Calculation

Profit and loss are calculated based on the difference between the entry price and the current mark price of the contract, adjusted for the size of the position and any funding payments made. 

## Example

#### Initial Setup
- Alice is long 2x with $1000 margin.
- Bob is short 2x with $1000 margin.
- Starting price: 1000 ETH/USD.


#### Example Price Movements

##### Price Increases to 1500 ETH/USD
- **Alice's P&L**:
  - Entry price: 1000 ETH/USD, current price: 1500 ETH/USD.
  - P&L = (1500 - 1000) * 2 = $1000.
  - New margin = $1000 (initial margin) + $1000 (P&L) = $2000.
- **Bob's P&L**:
  - Entry price: 1000 ETH/USD, current price: 1500 ETH/USD.
  - P&L = (1000 - 1500) * 2 = -$1000.
  - New margin = $1000 (initial margin) - $1000 (P&L) = $0.
  - Bob gets liquidated since his margin is 0 (less than 10% of the position value).
  - Alice receives 90% of Bob's margin: 90% of $1000 = $900.
  - Liquidator receives 10% of Bob's margin: 10% of $1000 = $100.
  - Alice's final margin: $2000 + $900 = $2900.

##### Price Decreases to 500 ETH/USD
- **Alice's P&L**:
  - Entry price: 1000 ETH/USD, current price: 500 ETH/USD.
  - P&L = (500 - 1000) * 2 = -$1000.
  - New margin = $1000 (initial margin) - $1000 (P&L) = $0.
  - Alice gets liquidated since her margin is 0 (less than 10% of the position value).
  - Bob receives 90% of Alice's margin: 90% of $1000 = $900.
  - Liquidator receives 10% of Alice's margin: 10% of $1000 = $100.
  - Bob's final margin: $2000 + $900 = $2900.

#### Funding Rate Calculation Example

- Assume the mark price is 1010 ETH/USD and the spot price is 1000 ETH/USD.
- **Funding Rate**:
  - Interest Rate: 0.0001 (0.01%).
  - Funding Rate = 0.0001 * (1010 - 1000) / 1000 = 0.0001 or 0.01%.

At the end of the 8-hour period, funding payments are made based on this rate.

- **Alice's funding payment**:
  - Position size: 2 contracts.
  - Mark price: 1010 ETH/USD.
  - Funding payment: (-1) * 2 * 1010 * 0.0001 = -$0.202 (Alice pays $0.202).

- **Bob's funding payment**:
  - Position size: -2 contracts.
  - Mark price: 1010 ETH/USD.
  - Funding payment: (-1) * -2 * 1010 * 0.0001 = $0.202 (Bob receives $0.202).

This example illustrates how slight deviations between the mark price and the spot price result in funding rate adjustments and payments between long and short position holders. The funding mechanism helps keep the perpetual contract price close to the spot price, maintaining market stability.

## Liquidation Price Formula

In a perpetual futures contract, a position is liquidated if the margin health falls below a certain threshold. Here, we consider a health threshold of 10%, meaning that the margin must be at least 10% of the position value. If the margin falls below this threshold, the position is liquidated. The liquidation prices for both long and short positions can be calculated using the following formulas:

### Liquidation Price for Long Position

For a long position, the liquidation price ($P_{liquidation\_long}$) is the price at which the margin health falls below 10% of the position value. The formula is:

$$
P_{liquidation\_long} = P_{entry} \times \left( 1 - \frac{(1 - \text{Health Threshold}) \times \text{Leverage}}{1 + \text{Leverage}} \right)
$$

Where:
- $P_{entry}$ is the entry price.
- Health Threshold is 0.10 (10%).
- Leverage is the leverage ratio (e.g., 2x).

### Liquidation Price for Short Position

For a short position, the liquidation price ($P_{liquidation\_short}$) is the price at which the margin health falls below 10% of the position value. The formula is:

$$
P_{liquidation\_short} = P_{entry} \times \left( 1 + \frac{(1 - \text{Health Threshold}) \times \text{Leverage}}{1 + \text{Leverage}} \right)
$$

Where:
- $P_{entry}$ is the entry price.
- Health Threshold is 0.10 (10%).
- Leverage is the leverage ratio (e.g., 2x).

### Example Calculation

#### Initial Setup
- Alice is long 2x with $1000 margin.
- Bob is short 2x with $1000 margin.
- Starting price: 1000 ETH/USD.
- Health Threshold: 10%.

#### Long Position (Alice)

$$
P_{liquidation\_long} = 1000 \times \left( 1 - \frac{(1 - 0.10) \times 2}{1 + 2} \right)
$$
$$
P_{liquidation\_long} = 1000 \times \left( 1 - \frac{0.90 \times 2}{3} \right)
$$
$$
P_{liquidation\_long} = 1000 \times \left( 1 - 0.60 \right)
$$
$$
P_{liquidation\_long} = 1000 \times 0.40
$$
$$
P_{liquidation\_long} = 400 \text{ ETH/USD}
$$

#### Short Position (Bob)

$$
P_{liquidation\_short} = 1000 \times \left( 1 + \frac{(1 - 0.10) \times 2}{1 + 2} \right)
$$
$$
P_{liquidation\_short} = 1000 \times \left( 1 + \frac{0.90 \times 2}{3} \right)
$$
$$
P_{liquidation\_short} = 1000 \times \left( 1 + 0.60 \right)
$$
$$
P_{liquidation\_short} = 1000 \times 1.60
$$
$$
P_{liquidation\_short} = 1600 \text{ ETH/USD}
$$

### Summary
- **Alice's liquidation price**: 400 ETH/USD.
- **Bob's liquidation price**: 1600 ETH/USD.


### Limitations
Currently, under this architecture, whenever a user decides to exit their position, the counterparty is also exited from the trade.

A solution to avoid permanently closing the counterparty's trade when a user closes their position is for the perpetual contract to output two notes upon closing a position: one note for the assets that the user who closed the trade wanted, and another note that can be recycled back into the matching algorithm to see if another trader is willing to fill the recently exited trade.


### Efficiently Calculating Funding Rates for All Positions

It is still an area of research on how to update all of the funding positions each hour for all of the open perpetual contracts inside the perpetual exchange smart contract.

The perpetual exchange smart contract could output an asset-less note with the data for all of the positions alongside a Unix timestamp of when the note was created.

An off-chain account could process the data with recent information from the price oracle, calculate the funding rate delta for all of the open positions, and output a proof note that this calculation is valid, i.e., honest.

The perpetual exchange smart contract could consume this note and copy the new trade data with the updated funding rates to storage.


**Schema Slides**: https://docs.google.com/presentation/d/1wZTdYcorQ69534A6CgsJOoDNokBP-MsjsT4ndc-UwrM/edit?usp=sharing