use anchor_lang::prelude::*;
use bytemuck::{Pod, Zeroable};
pub const VAULT_TOKEN_DECIMALS: u8 = 6;
pub const VAULT_TOKEN_DECIMALS_FACTOR: u64 = 1_000_000;
pub const MAX_POSITIONS: usize = 5;
pub const MAX_ACTIVE_POSITIONS: usize = MAX_POSITIONS;
#[derive(Clone, Copy, AnchorDeserialize, AnchorSerialize, Pod, Zeroable)]
#[repr(C)]
pub struct VaultRatioCache {
pub total_token_a: u64,
pub total_token_b: u64,
pub lp_supply: u64,
pub cached_at: i64,
}
#[account(zero_copy)]
#[repr(C)]
pub struct ClpVault {
pub bump_seed: u8,
_padding0: [u8; 15],
pub nonce: u16,
_padding1: [u8; 14],
pub clp: Pubkey,
pub lp_mint: Pubkey,
pub lp_mint_bump: u8,
_padding2: [u8; 15],
pub token_mint_a: Pubkey,
pub token_vault_a: Pubkey,
pub token_mint_b: Pubkey,
pub token_vault_b: Pubkey,
pub performance_fee: u32,
_padding3: [u8; 12],
pub withdrawal_fee: u32,
_padding4: [u8; 12],
pub market_making_fee: u32,
_padding5: [u8; 12],
pub strategy: StrategyType,
_padding6: [u8; 15],
pub market_making_key: Pubkey,
pub admin_key: Pubkey,
pub fee_owner: Pubkey,
pub num_active_positions: u8,
_padding7: [u8; 15],
pub position_bundle_token_account: Pubkey,
pub position_bundle_mint: Pubkey,
pub position_bundle: Pubkey,
pub positions: [VaultPosition; MAX_POSITIONS],
pub initial_token_ratio: TokenRatio,
pub stake_pool: Pubkey,
pub ratio_cache: VaultRatioCache,
pub in_flight_fees: InFlightFees,
_reserved0: [u8; 256],
_reserved1: [u8; 64],
_reserved2: [u8; 32],
_reserved_128: [u128; 32],
}
impl ClpVault {
pub const LEN: usize = std::mem::size_of::<ClpVault>();
pub fn clp_vault_from_bytes(v: &[u8]) -> &ClpVault{
bytemuck::from_bytes(v)
}
pub fn clp_vault_from_bytes_mut(v: &mut [u8]) -> &mut ClpVault {
bytemuck::from_bytes_mut(v)
}
}
#[derive(Debug, Clone, Copy, AnchorDeserialize, AnchorSerialize)]
#[repr(u8)]
pub enum FlightType {
None,
OnlyA,
OnlyB,
Both,
}
impl PartialEq for FlightType {
fn eq(&self, other: &Self) -> bool {
match (*self as u8, *other as u8) {
(a, b) => a == b,
}
}
}
impl Eq for FlightType {}
unsafe impl Zeroable for FlightType {}
unsafe impl Pod for FlightType {}
#[derive(Clone, Copy, AnchorDeserialize, AnchorSerialize, Zeroable, Pod)]
#[repr(C)]
pub struct InFlightFees {
pub flight_admin_a: Pubkey,
pub flight_admin_b: Pubkey,
pub in_flight_a: u64,
pub in_flight_b: u64,
pub flight_type: FlightType,
_padding1: [u8; 15],
}
impl Default for InFlightFees {
fn default() -> Self {
Self {
flight_admin_a: Pubkey::default(),
flight_admin_b: Pubkey::default(),
in_flight_a: 0,
in_flight_b: 0,
flight_type: FlightType::None,
_padding1: [0; 15],
}
}
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Default, Zeroable, Pod)]
#[repr(C)]
pub struct TokenRatio {
pub token_a: u64,
pub token_b: u64,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy)]
#[repr(u8)]
pub enum StrategyType {
PriceDiscovery = 0,
VolatilePair = 1,
StablePair = 2,
StableSlowlyDiverging = 3,
}
unsafe impl Zeroable for StrategyType {}
unsafe impl Pod for StrategyType {}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Default, Zeroable, Pod)]
#[repr(C)]
pub struct VaultPosition {
pub position_key: Pubkey,
pub lower_tick: i32,
_padding0: [u8; 12],
pub upper_tick: i32,
_padding1: [u8; 12],
_reserve: [u128; 16],
}
impl VaultPosition {
pub fn new(
position: Pubkey,
lower_tick: i32,
upper_tick: i32,
) -> Self {
let mut res = VaultPosition::default();
res.position_key = position;
res.lower_tick = lower_tick;
res.upper_tick = upper_tick;
res
}
pub fn is_empty(&self) -> bool {
self.position_key == Pubkey::default()
}
}