use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::pubkey::Pubkey;
use super::types::{AmmCreatorFeeOn, VestingSchedule};
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug)]
pub struct GlobalConfig {
pub epoch: u64,
pub quote_mint: Pubkey,
pub protocol_fee_owner: Pubkey,
pub migrate_fee_owner: Pubkey,
pub migrate_to_amm_wallet: Pubkey,
pub migrate_to_cpswap_wallet: Pubkey,
pub trade_fee_rate: u64,
pub migrate_fee: u64,
pub curve_type: u8,
pub index: u16,
pub padding: [u8; 64],
}
impl Default for GlobalConfig {
fn default() -> Self {
Self {
epoch: 0,
quote_mint: Pubkey::default(),
protocol_fee_owner: Pubkey::default(),
migrate_fee_owner: Pubkey::default(),
migrate_to_amm_wallet: Pubkey::default(),
migrate_to_cpswap_wallet: Pubkey::default(),
trade_fee_rate: 0,
migrate_fee: 0,
curve_type: 0,
index: 0,
padding: [0u8; 64],
}
}
}
impl GlobalConfig {
pub const DISCRIMINATOR: [u8; 8] = [149, 8, 156, 202, 160, 252, 176, 217];
pub const LEN: usize = 8 + 32 + 32 + 32 + 32 + 32 + 8 + 8 + 1 + 2 + 64;
pub const TOTAL_LEN: usize = 8 + Self::LEN;
pub fn try_from_bytes(data: &[u8]) -> Result<Self, std::io::Error> {
if data.len() < 8 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Data too short",
));
}
let (discriminator, rest) = data.split_at(8);
if discriminator != Self::DISCRIMINATOR {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid discriminator",
));
}
Self::try_from_slice(rest)
}
}
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug)]
pub struct PlatformConfig {
pub epoch: u64,
pub platform_admin: Pubkey,
pub platform_fee_wallet: Pubkey,
pub platform_nft_wallet: Pubkey,
pub cpswap_config: Pubkey,
pub transfer_fee_extension_authority: Pubkey,
pub fee_rate: u64,
pub creator_fee_rate: u64,
pub name: String,
pub web: String,
pub img: String,
pub nft_symbol: String,
pub nft_name: String,
pub nft_uri: String,
pub nft_is_mutable: bool,
pub padding: [u8; 64],
}
impl Default for PlatformConfig {
fn default() -> Self {
Self {
epoch: 0,
platform_admin: Pubkey::default(),
platform_fee_wallet: Pubkey::default(),
platform_nft_wallet: Pubkey::default(),
cpswap_config: Pubkey::default(),
transfer_fee_extension_authority: Pubkey::default(),
fee_rate: 0,
creator_fee_rate: 0,
name: String::new(),
web: String::new(),
img: String::new(),
nft_symbol: String::new(),
nft_name: String::new(),
nft_uri: String::new(),
nft_is_mutable: false,
padding: [0u8; 64],
}
}
}
impl PlatformConfig {
pub const DISCRIMINATOR: [u8; 8] = [160, 78, 128, 0, 248, 83, 230, 160];
pub fn try_from_bytes(data: &[u8]) -> Result<Self, std::io::Error> {
if data.len() < 8 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Data too short",
));
}
let (discriminator, rest) = data.split_at(8);
if discriminator != Self::DISCRIMINATOR {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid discriminator",
));
}
Self::try_from_slice(rest)
}
}
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug)]
pub struct PoolState {
pub epoch: u64,
pub auth_bump: u8,
pub status: u8,
pub base_decimals: u8,
pub quote_decimals: u8,
pub migrate_type: u8,
pub supply: u64,
pub total_base_sell: u64,
pub virtual_base: u64,
pub virtual_quote: u64,
pub real_base: u64,
pub real_quote: u64,
pub total_quote_fund_raising: u64,
pub quote_protocol_fee: u64,
pub platform_fee: u64,
pub migrate_fee: u64,
pub vesting_schedule: VestingSchedule,
pub global_config: Pubkey,
pub platform_config: Pubkey,
pub base_mint: Pubkey,
pub quote_mint: Pubkey,
pub base_vault: Pubkey,
pub quote_vault: Pubkey,
pub creator: Pubkey,
pub token_program_flag: u8,
pub amm_creator_fee_on: AmmCreatorFeeOn,
pub padding: [u8; 62],
}
impl Default for PoolState {
fn default() -> Self {
Self {
epoch: 0,
auth_bump: 0,
status: 0,
base_decimals: 0,
quote_decimals: 0,
migrate_type: 0,
supply: 0,
total_base_sell: 0,
virtual_base: 0,
virtual_quote: 0,
real_base: 0,
real_quote: 0,
total_quote_fund_raising: 0,
quote_protocol_fee: 0,
platform_fee: 0,
migrate_fee: 0,
vesting_schedule: VestingSchedule::default(),
global_config: Pubkey::default(),
platform_config: Pubkey::default(),
base_mint: Pubkey::default(),
quote_mint: Pubkey::default(),
base_vault: Pubkey::default(),
quote_vault: Pubkey::default(),
creator: Pubkey::default(),
token_program_flag: 0,
amm_creator_fee_on: AmmCreatorFeeOn::default(),
padding: [0u8; 62],
}
}
}
impl PoolState {
pub const DISCRIMINATOR: [u8; 8] = [247, 237, 227, 245, 215, 195, 222, 70];
pub fn try_from_bytes(data: &[u8]) -> Result<Self, std::io::Error> {
if data.len() < 8 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Data too short",
));
}
let (discriminator, rest) = data.split_at(8);
if discriminator != Self::DISCRIMINATOR {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid discriminator",
));
}
Self::try_from_slice(rest)
}
pub fn is_funding(&self) -> bool {
self.status == 0
}
pub fn is_migrate(&self) -> bool {
self.status == 1
}
pub fn is_trading(&self) -> bool {
self.status == 2
}
pub fn is_base_token_2022(&self) -> bool {
self.token_program_flag & 0x01 != 0
}
pub fn is_quote_token_2022(&self) -> bool {
self.token_program_flag & 0x02 != 0
}
pub fn get_current_price(&self) -> Option<f64> {
if self.virtual_base == 0 {
return None;
}
Some(self.virtual_quote as f64 / self.virtual_base as f64)
}
pub fn get_funding_progress(&self) -> f64 {
if self.total_quote_fund_raising == 0 {
return 0.0;
}
(self.real_quote as f64 / self.total_quote_fund_raising as f64) * 100.0
}
}
#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Default)]
pub struct VestingRecord {
pub epoch: u64,
pub pool: Pubkey,
pub beneficiary: Pubkey,
pub claimed_amount: u64,
pub token_share_amount: u64,
pub padding: [u64; 8],
}
impl VestingRecord {
pub const DISCRIMINATOR: [u8; 8] = [106, 243, 221, 205, 230, 126, 85, 83];
pub const LEN: usize = 8 + 32 + 32 + 8 + 8 + (8 * 8);
pub const TOTAL_LEN: usize = 8 + Self::LEN;
pub fn try_from_bytes(data: &[u8]) -> Result<Self, std::io::Error> {
if data.len() < 8 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Data too short",
));
}
let (discriminator, rest) = data.split_at(8);
if discriminator != Self::DISCRIMINATOR {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"Invalid discriminator",
));
}
Self::try_from_slice(rest)
}
pub fn remaining_amount(&self) -> u64 {
self.token_share_amount.saturating_sub(self.claimed_amount)
}
}