# Onchain Limit Order Book and Perpetual futures on Miden VM
This document outlines the implementation of an order book and perps on the Miden VM. Leveraging the high performance and privacy-preserving capabilities of Miden's ZKP technology, it provides an optimal environment for an order book DEX. Being fully onchain, the order book offers decentralization, enhancing its attractiveness from a regulatory perspective.
Additionally, Miden's privacy features add an extra layer of security, making it a compelling choice for implementing such financial instruments.
## Product Success Factors
The key to the product's success lies in attracting institutional traders by offering CEX-like UX. Miden's robust infrastructure supports this ambition, setting it apart in a landscape where many teams are developing order books across various networks without the necessary infrastructure to make it viable.
## System Design
The proposed design's objective is to bootstrap liquidity prior to engaging other developers with the order book, facilitating quicker community adoption.
The product comprises three core elements: **Perpetual Markets**, **Order Book**, and an **API set**, supplemented by a suite of third-party services, including a Liquidator, Risk Engine, Matching Engine, and a Price Oracle.
Combining Perpetual Markets with Spot Trading creates an ideal product mix, mirroring its popularity in the current DeFi landscape. This combination allows traders to profit in both low and high liquidity markets, catering to diverse trading strategies and market conditions.
## OrderBook
Miden's architecture, supported by zk-STARKs for computational integrity and secured by Ethereum for liquidity, presents an innovative environment for developing an on-chain order book. This system enables features crucial for a dynamic trading platform while ensuring privacy and scalability.
#### Core Features:
- **Limit Orders**: Traders can specify the exact price at which they wish to buy or sell an asset.
- **Market Orders**: Enables buying or selling at the best available price in the order book.
- **Stop Loss Orders**: A stop loss order automatically sells an asset when its price drops to a specified level, limiting potential losses. It's a key risk management tool within Miden, requiring real-time price monitoring and automated execution at predetermined thresholds.
- **Take Profit Orders**: Opposite to stop loss orders, take profit orders automatically execute a sale when the asset's price reaches a target level set by the trader, securing profits. It's vital for realizing gains in fluctuating markets by pre-setting profit targets and automating sales execution.
- **Order Taking**: Users can fulfill any available order directly, facilitating immediate transactions.
- **Order Cancellation**: Provides the flexibility to withdraw an order before it's executed.
- **Order Matching**: A mechanism to pair buy and sell orders based on price and order time.
- **Statistical Display**: Showcases trading volume, price movements, and other relevant market data for informed decision-making.
Miden's [Notes](https://0xpolygonmiden.github.io/miden-base/architecture/notes.html) concept is ingeniously applied to represent order entities. By utilizing Notes, each with a specific Tag corresponding to an order book, we can seamlessly organize and manage orders

#### Order Creation Configuration
Each Note contains a **Vault** where assets for sale are stored (e.g., 1 ETH) and cannot be altered. Additionally, a single executable **Script** defines the order's logic. When users are setting up orders on the frontend, they are required to specify several configurable parameters that define the terms of the order. Below is an explanation of these parameters, illustrated with examples
```rust
configurable {
ASSET0: b256 = ZERO_B256, // Asset that provides maker(Alice)
ASSET1: b256 = ZERO_B256, // Asset that provides taker(Bob)
MAKER: Address = Address::from(ZERO_B256), // Order owner
PRICE: u64 = 0, // asset1_amount / asset0_amount
ASSET0_DECIMALS: u8 = 1,
ASSET1_DECIMALS: u8 = 1,
PRICE_DECIMALS: u8 = 9, // optional
MIN_FULFILL_AMOUNT0: u64 = 1, // optional
}
```
#### Note Script Logic
The note script embodies the logic for transaction validation and execution, ensuring that the taker (Bob) provides the specified amount of the quote token (ASSET1) to the maker (Alice). This script is crucial for enforcing the terms of the trade as defined in the order's configuration.
The pseudo code for the note script, reflecting the logic described above, can be conceptualized as follows:
```rust
// Pseudo code for note script logic
// This script validates that the taker fulfills the order as per the specified configurations
if (taker_provides(ASSET1) && satisfies_order_conditions) {
execute_trade(ASSET0, ASSET1, MAKER, PRICE);
} else {
revert_transaction();
}
```
This model allows for the creation of flexible and configurable orders, where the frontend interface facilitates user input of these configurations, directly translating into the creation of notes (orders) within the Miden ecosystem. By adopting this approach, as exemplified in the Fuel blockchain's predicate implementation,

This setup allows anyone interested in fulfilling an order to consume the **Note**, executing its **Script** to complete the transaction. This approach supports instantaneous updates for limit orders, providing a dynamic and responsive trading environment.
#### Order Book Visualization
The order book will list all **Notes** sharing the same **Tag**, serving as a comprehensive view of the market. This order book will be accessible through a Single Page Application (**SPA**), offering real-time updates and a user-friendly interface for traders.

<blockquote style="background-color: #e7f3fe; color: #3178c6; border-left: 4px solid #3178c6; padding: 0.5em 10px; margin: 1em 0; box-shadow: 0 2px 4px rgba(0,0,0,0.06);">
<strong>Note:</strong> The Indexer on Miden is essential for the effective visualization of the order book. It meticulously indexes newly created notes, ensuring their swift display on the frontend, thus providing traders with real-time market data crucial for informed decision-making note.
</blockquote>
#### Order canceling
For market makers, especially during high volatility, efficient order cancellation is crucial as it's a key component of their trading strategies. Here are the refined strategies:
**Batch Updates**: This feature allows the updating of multiple orders in a single transaction or request, significantly reducing the gas cost associated with individual order modifications.
**Order Edits**: It's essential to design a system where orders can be modified (either price or size) without necessitating a change in the order ID or altering its position in the price node array used for matching and execution. This maintains order continuity and efficiency in the matching process.

#### Matching
To efficiently match orders in an order book, use a binary search tree where each node represents a unique price, conwe can taining a list of orders sorted by time (**FIFO**). **Buy** and **sell** orders are stored separately to streamline matching.
Maker orders add liquidity and await execution, while taker orders immediately execute against available maker orders.
A matching function in the contract executes transactions between matched orders, triggered by external agents. This design optimizes for gas efficiency and minimizes operational delays.

## Perp
Perpetual Futures are cash-settled (stablecoin) contracts without an expiration date, resembling margin-based spot trading without the application of an interest rate on positions. The price of a perpetual future can deviate from the underlying asset's price (index price). Futures may trade at a premium when traders anticipate an increase in the underlying asset's price. Conversely, futures may trade at a discount when a decrease is expected.
To align the future's price more closely with the index price, a funding payment mechanism is employed.
Implementing a perpetual protocol on Miden involves a single account with logic that can be divided into several key modules:
- Clearing House: This contains the primary functions for interacting with the protocol.
- Account Balance: Responsible for storing user position information and logic related to the funding rate and PnL.
- Insurance Fund: Accumulates fees and pays out rewards to users.
- Orderbook: Stores user orders, including a matching mechanism.
- Vault: Handles deposits, withdrawals, and the storage of deposits.
The perpetual protocol is a complex system encompassing numerous functions, interactions with external oracles, and the need for auxiliary services such as a risk engine, matching engine, and liquidation engine. These services utilize on-chain data to perform certain calculations and call corresponding contract methods, receiving rewards to prevent losses. The external functions of the perpetual protocol can be categorized into three groups:
**Administrative Functions** - Functions that can only be initiated by an admin or the risk engine:
- `create_market` - Creates a perpetual market.
- `pause_market` - Pauses a perpetual market.
- `close_market` - Closes a perpetual market.
- `set_configuration` - Updates protocol configuration.
- `set_risk_parameters` - Updates protocol risk parameters.
**User Functions**
- `deposit_collateral` - Adds stablecoin collateral to a user's account, enabling trade.
- `withdraw_collateral` - Removes stablecoin collateral from a user's account.
- `open_order` - Initiates a trade order in the perpetual market.
- `remove_order` - Cancels an existing trade order.
**Additional Functions (getters)**
- `get_markets` - Retrieves available perpetual markets.
- `get_collateral_balance` - Shows the collateral balance of a user.
- `get_max_abs_position_size` - Displays the maximum position size a trader can hold.
- `get_trader_orders` - Lists active orders placed by a trader.
- `get_free_collateral` - Calculates the available collateral for new trades.
- `get_insurance_fund_capacity` - Indicates the current capacity of the insurance fund.
- etc...
**Service Functions** - These assist services in their operations, and services will also use getters and some user functions:
- `liquidate` - Liquidates a position.
- `match_orders` - Matches orders.
- `fulfill_order` - Creates an order and matches it with a selected order in a single transaction.
### Liquidations
Futures trading amplifies the potential for gains and equally, the risk of losses by employing leverage.
Consider a scenario where a trader initiates a position with a 3x leverage using 200 USDC. This makes the starting value of the position 600 USDC, with 400 USDC being borrowed funds. Should the position's value fall by approximately 30%, the entire collateral of 200 USDN would be engaged.
Liquidation acts as a safeguard to close out positions that fail to meet the minimum margin criteria, which could otherwise place the exchange in jeopardy should the losses outpace the available margin. To counter such events, we enforce a minimum margin ratio that provides a buffer against market volatility.
***Margin = Collateral + UnrealizedPnL + CumulativeFundingPayment***
***MarginRatio = Margin / PositionNotional***
Liquidation processes are executed by liquidation engine. Initially managed by the Spark team, this liquidation engine will eventually be open-sourced, allowing the community to operate and manage their own instances.
## API and Libraries
To effectively capture institutional liquidity, a protocol must offer a WebSocket API akin to those found in CEXs. This ensures seamless integration for institutional traders accustomed to the high-performance, real-time data feeds of traditional financial markets.
For a comprehensive trader API, three primary data sources are utilized:
1. **Miden Nodes**: Supply smart contract ABIs and detailed function calls required for executing various trading strategies. Specific functions and their applications will be detailed in subsequent documentation.
2. **DEX SDK (CCXT Library)**: A versatile library for cryptocurrency trading and market data access, supporting over 124 exchanges. It facilitates rapid development and integration for trading applications.
3. **Indexer**: Provides a streamlined way to access aggregated market data and individual trading positions, enhancing the trading strategy's efficiency and responsiveness.
### DEX SDK (CCXT Library)
The DEX SDK, utilizing the CCXT library, offers a unified approach to interact with various cryptocurrency exchanges. It abstracts the complexities of individual exchange APIs into a consistent and easy-to-use set of functions.
**Installation**:
```bash
npm install ccxt
```
**Initialization**:
Create an instance of the `sparkprotocol` class, encapsulating the methods for interacting with the Spark Protocol API.
```javascript
const { sparkprotocol } = require('ccxt');
const spark = new sparkprotocol({
apiKey: 'YOUR_PUBLIC_KEY',
secret: 'YOUR_PRIVATE_KEY',
});
(async () => {
await spark.loadMarkets();
})();
```
**Methods**:
CCXT methods are asynchronous, returning promises with decoded JSON data. They are accessible in both camelCase and underscore_notation for convenience.
**Load Markets**: Preloads the list of markets and currencies for efficient data retrieval.
```javascript
(async () => {
await spark.loadMarkets(); // Loads market and currency data
const currencies = spark.currencies; // Access currency dictionary
const symbols = spark.symbols; // Access trading pair dictionary
const market = spark.markets['SRPK/USDT']; // Access specific market structure
})();
```
**Market Data**:
The `fetchOrderBook` method retrieves the current state of the order book for a specified trading pair, crucial for real-time trading decisions.
### Indexer
#### 1. Get Address
This endpoint retrieves detailed information about a specific address and their respective positions.
**Endpoint**:
```
https://indexer.sprk.fi/v1/addresses/{address}
```
**Example Request**:
```javascript
const result = await axios.get(`https://indexer.sprk.fi/v1/addresses/{address}`, { headers });
```
**Example Response**:
```json
{
"subaccounts": [
{
"address": "string",
"subaccountNumber": 0,
"equity": "string",
"freeCollateral": "string",
"openPerpetualPositions": {
"property1": {
"market": "string",
"status": "OPEN",
"side": "LONG",
"size": "string",
"maxSize": "string",
"entryPrice": "string",
"realizedPnl": "string",
"createdAt": "string",
"createdAtHeight": "string",
"sumOpen": "string",
"sumClose": "string",
"netFunding": "string",
"unrealizedPnl": "string",
"closedAt": null,
"exitPrice": "string"
},
"property2": {
...
}
},
"assetPositions": {
"property1": {
"symbol": "string",
"side": "LONG",
"size": "string",
"assetId": "string"
},
"property2": {
...
}
},
"marginEnabled": true
}
],
"totalTradingRewards": "string"
}
```
#### 2. Get Asset Positions
Fetches current asset positions for a given address and subaccount number.
**Endpoint**:
```
https://indexer.sprk.fi/v1/assetPositions
```
**Example Request**:
```javascript
const result = await axios.get(`https://indexer.sprk.fi/v1/assetPositions`, { params: { 'address': 'string', 'subaccountNumber': '0'}, headers });
```
**Example Response**:
```json
{
"positions": [
{
"symbol": "string",
"side": "LONG",
"size": "string",
"assetId": "string"
}
]
}
```
#### 3. Get Candles
Retrieves historical market data for a specified perpetual market and resolution.
**Endpoint**:
```
https://indexer.sprk.fi/v1/candles/perpetualMarkets/{ticker}
```
**Example Request**:
```javascript
const result = await axios.get(`https://indexer.sprk.fi/v1/candles/perpetualMarkets/{ticker}`, { params: { 'resolution': '1MIN', 'limit': '0'}, headers });
```
**Example Response**:
```json
{
"candles": [
{
"startedAt": "string",
"ticker": "string",
"resolution": "1MIN",
"low": "string",
"high": "string",
"open": "string",
"close": "string",
"baseTokenVolume": "string",
"usdVolume": "string",
"trades": 0,
"startingOpenInterest": "string",
"id": "string"
}
]
}
```
#### 4. Get Trading Rewards
Provides the historical trading rewards for a given address.
**Endpoint**:
```
https://indexer.sprk.fi/v1/historicalBlockTradingRewards/{address}
```
**Example Request**:
```javascript
const result = await axios.get(`https://indexer.sprk.fi/v1/historicalBlockTradingRewards/{address}`, { params: { 'limit': '0'}, headers });
```
**Example Response**:
```json
{
"rewards": [
{
"tradingReward": "string",
"createdAt": "string",
"createdAtHeight": "string"
}
]
}
```
### WebSocket Indexer
The WebSocket Indexer provides real-time updates for various market activities, enhancing the responsiveness of trading strategies.
**Connect**:
Upon connecting, you receive an initial message confirming the connection.
```json
{
"type": "connected",
"connection_id": "id",
"message_id": 0
}
```
**Subscribe**:
Subscribe to desired channels by specifying the channel type and, if applicable, the market or subaccount ID.
```json
{
"type": "subscribe",
"channel": "channel_name",
"id": "market_or_subaccount_id"
}
```
**Unsubscribe**:
To unsubscribe, use the same format but replace "subscribe" with "unsubscribe".
```json
{
"type": "unsubscribe",
"channel": "channel_name",
"id": "market_or_subaccount_id"
}
```
## Outside this document
- Spark liquidity strategy
- Offchain and later onchain solvers decentralization strategy
- Liquidity Mining program (will require cooperation with Miden)
- Community Growth strategy
## References
- https://github.com/0xPolygonMiden/examples/discussions/138
- https://github.com/ccxt/ccxt