precolator-program 1.0.0

Core Rust library for the Precolator perpetual futures trading protocol on Solana — oracle management, position handling, risk engine, and liquidation system.
Documentation
// State structures for market and position data

use serde::{Deserialize, Serialize};
use solana_program::pubkey::Pubkey;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Market {
    pub market_id: Pubkey,
    pub admin: Pubkey,
    pub collateral_mint: Pubkey,
    pub vault: Pubkey,
    pub oracle: Pubkey,
    pub max_leverage: u8,
    pub total_volume: u64,
    pub trade_count: u64,
    pub open_interest: u64,
    pub insurance_fund: u64,
    pub created_at: i64,
    pub is_resolved: bool,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum PositionSide {
    Long,
    Short,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum PositionStatus {
    Open,
    Closed,
    Liquidated,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Position {
    pub position_id: Pubkey,
    pub trader: Pubkey,
    pub market_id: Pubkey,
    pub side: PositionSide,
    pub size: u64,
    pub entry_price: u64,
    pub current_price: u64,
    pub collateral: u64,
    pub leverage: u8,
    pub liquidation_price: u64,
    pub status: PositionStatus,
    pub pnl: i64,
    pub pnl_percent: i32,
    pub opened_at: i64,
    pub closed_at: i64,
    pub last_updated: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Account {
    pub owner: Pubkey,
    pub market_id: Pubkey,
    pub balance: u64,
    pub total_deposited: u64,
    pub total_withdrawn: u64,
    pub position_count: u64,
    pub created_at: i64,
    pub is_active: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LiquidityPool {
    pub pool_id: Pubkey,
    pub market_id: Pubkey,
    pub available_liquidity: u64,
    pub utilization_pct: u8,
    pub fee_accrued: u64,
}

impl Market {
    pub fn new(market_id: Pubkey, admin: Pubkey, collateral_mint: Pubkey, vault: Pubkey, oracle: Pubkey) -> Self {
        Self {
            market_id,
            admin,
            collateral_mint,
            vault,
            oracle,
            max_leverage: 50,
            total_volume: 0,
            trade_count: 0,
            open_interest: 0,
            insurance_fund: 0,
            created_at: 0,
            is_resolved: false,
        }
    }
}

impl Position {
    pub fn new(
        position_id: Pubkey,
        trader: Pubkey,
        market_id: Pubkey,
        side: PositionSide,
        size: u64,
        entry_price: u64,
        collateral: u64,
        leverage: u8,
    ) -> Self {
        let liquidation_price = match side {
            PositionSide::Long => {
                ((entry_price as u128 * (leverage - 1) as u128) / leverage as u128) as u64
            }
            PositionSide::Short => {
                ((entry_price as u128 * (leverage + 1) as u128) / leverage as u128) as u64
            }
        };

        Self {
            position_id,
            trader,
            market_id,
            side,
            size,
            entry_price,
            current_price: entry_price,
            collateral,
            leverage,
            liquidation_price,
            status: PositionStatus::Open,
            pnl: 0,
            pnl_percent: 0,
            opened_at: 0,
            closed_at: 0,
            last_updated: 0,
        }
    }
}