use alloy::primitives::{Address, B256, U256};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Deployments {
pub perp_manager: Address,
pub usdc: Address,
pub fees_module: Option<Address>,
pub margin_ratios_module: Option<Address>,
pub lockup_period_module: Option<Address>,
pub sqrt_price_impact_limit_module: Option<Address>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PerpData {
pub id: B256,
pub tick_spacing: i32,
pub mark: f64,
pub beacon: Address,
pub bounds: Bounds,
pub fees: Fees,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Bounds {
pub min_margin: f64,
pub min_taker_leverage: f64,
pub max_taker_leverage: f64,
pub liquidation_taker_ratio: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Fees {
pub creator_fee: f64,
pub insurance_fee: f64,
pub lp_fee: f64,
pub liquidation_fee: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct LiveDetails {
pub pnl: f64,
pub funding_payment: f64,
pub effective_margin: f64,
pub is_liquidatable: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenInterest {
pub long_oi: f64,
pub short_oi: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct PerpSnapshot {
pub mark_price: f64,
pub index_price: f64,
pub funding_rate_daily: f64,
pub open_interest: OpenInterest,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenTakerParams {
pub is_long: bool,
pub margin: f64,
pub leverage: f64,
pub unspecified_amount_limit: u128,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenMakerParams {
pub margin: f64,
pub price_lower: f64,
pub price_upper: f64,
pub liquidity: u128,
pub max_amt0_in: u128,
pub max_amt1_in: u128,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CloseParams {
pub min_amt0_out: u128,
pub min_amt1_out: u128,
pub max_amt1_in: u128,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct AdjustNotionalParams {
pub usd_delta: f64,
pub perp_limit: u128,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct AdjustMarginParams {
pub margin_delta: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenResult {
pub pos_id: U256,
pub is_maker: bool,
pub perp_delta: f64,
pub usd_delta: f64,
pub tick_lower: i32,
pub tick_upper: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct AdjustNotionalResult {
pub new_perp_delta: f64,
pub swap_perp_delta: f64,
pub swap_usd_delta: f64,
pub funding: f64,
pub utilization_fee: f64,
pub adl: f64,
pub trading_fees: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct AdjustMarginResult {
pub new_margin: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct CloseResult {
pub tx_hash: B256,
pub was_maker: bool,
pub was_liquidated: bool,
pub remaining_position_id: Option<U256>,
pub exit_perp_delta: f64,
pub exit_usd_delta: f64,
pub net_usd_delta: f64,
pub funding: f64,
pub utilization_fee: f64,
pub adl: f64,
pub liquidation_fee: f64,
pub net_margin: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct SwapQuote {
pub perp_delta: f64,
pub usd_delta: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenTakerQuote {
pub perp_delta: f64,
pub usd_delta: f64,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct OpenMakerQuote {
pub perp_delta: f64,
pub usd_delta: f64,
}
#[cfg(test)]
mod tests {
use super::*;
use alloy::primitives::{B256, U256};
#[test]
fn open_result_serde_roundtrip() {
let result = OpenResult {
pos_id: U256::from(42),
is_maker: false,
perp_delta: -1234.567,
usd_delta: 98765.43,
tick_lower: -69090,
tick_upper: 69090,
};
let json = serde_json::to_string(&result).unwrap();
let recovered: OpenResult = serde_json::from_str(&json).unwrap();
assert_eq!(result, recovered);
}
#[test]
fn close_result_serde_roundtrip() {
let result = CloseResult {
tx_hash: B256::ZERO,
was_maker: false,
was_liquidated: false,
remaining_position_id: None,
exit_perp_delta: -100.0,
exit_usd_delta: 200.0,
net_usd_delta: 195.0,
funding: -0.5,
utilization_fee: 0.1,
adl: 0.0,
liquidation_fee: 0.0,
net_margin: 150.0,
};
let json = serde_json::to_string(&result).unwrap();
let recovered: CloseResult = serde_json::from_str(&json).unwrap();
assert_eq!(result, recovered);
}
#[test]
fn deployments_serde_roundtrip() {
let deployments = Deployments {
perp_manager: Address::ZERO,
usdc: Address::ZERO,
fees_module: None,
margin_ratios_module: None,
lockup_period_module: None,
sqrt_price_impact_limit_module: None,
};
let json = serde_json::to_string(&deployments).unwrap();
let recovered: Deployments = serde_json::from_str(&json).unwrap();
assert_eq!(deployments, recovered);
}
}