use solana_farm_sdk::program::protocol::raydium::{
raydium_stake, raydium_stake_v4, raydium_stake_v5, raydium_stake_v5_dev, raydium_v4,
};
use std::ops::Deref;
use vipers::unwrap_int;
use crate::*;
pub const MILLIBPS_PER_WHOLE: u64 = 10_000 * 1_000;
#[account]
#[derive(Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct UserInfo {
pub vault: Pubkey,
pub bump: u8,
pub user_account: Pubkey,
pub manager: Pubkey,
pub last_deposit_at: i64,
pub last_withdraw_at: i64,
pub token_a_added: u64,
pub token_a_removed: u64,
pub token_b_added: u64,
pub token_b_removed: u64,
pub lp_tokens_debt: u64,
}
impl UserInfo {
pub fn update_deposit_time(&mut self) -> Result<()> {
let clock = Clock::get()?;
self.last_deposit_at = clock.unix_timestamp;
Ok(())
}
pub fn update_withdraw_time(&mut self) -> Result<()> {
let clock = Clock::get()?;
self.last_withdraw_at = clock.unix_timestamp;
Ok(())
}
pub fn add_liquidity(&mut self, token_a_added: u64, token_b_added: u64) -> Result<()> {
if token_a_added > 0 {
self.token_a_added = unwrap_int!(self.token_a_added.checked_add(token_a_added));
}
if token_b_added > 0 {
self.token_b_added = unwrap_int!(self.token_b_added.checked_add(token_b_added));
}
if token_a_added > 0 || token_b_added > 0 {
self.update_deposit_time()?;
}
Ok(())
}
pub fn remove_liquidity(&mut self, token_a_removed: u64, token_b_removed: u64) -> Result<()> {
if token_a_removed > 0 {
self.token_a_removed = unwrap_int!(self.token_a_removed.checked_add(token_a_removed));
}
if token_b_removed > 0 {
self.token_b_removed = unwrap_int!(self.token_b_removed.checked_add(token_b_removed));
}
if token_a_removed > 0 || token_b_removed > 0 {
self.update_withdraw_time()?;
}
Ok(())
}
pub fn add_lp_tokens_debt(&mut self, token_added: u64) -> Result<()> {
self.lp_tokens_debt = unwrap_int!(self.lp_tokens_debt.checked_add(token_added));
Ok(())
}
pub fn remove_lp_tokens_debt(&mut self, token_removed: u64) -> Result<()> {
if self.lp_tokens_debt <= token_removed {
self.lp_tokens_debt = 0;
} else {
self.lp_tokens_debt = unwrap_int!(self.lp_tokens_debt.checked_sub(token_removed));
}
Ok(())
}
}
#[account]
#[derive(Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Vault {
pub base: Pubkey,
pub bump: u8,
pub bump1: u8,
pub bump2: u8,
pub bump3: u8,
pub manager: Pubkey,
pub vault_lp_token_mint: Pubkey,
pub farm_lp_mint: Pubkey,
pub farm_reward_token_a_mint: Pubkey,
pub farm_reward_token_b_mint: Pubkey,
pub pool_lp_custody_account: Pubkey,
pub pool_token_a_custody_account: Pubkey,
pub pool_token_b_custody_account: Pubkey,
pub farm_token_a_reward_custody_account: Pubkey,
pub farm_token_b_reward_custody_account: Pubkey,
pub pool_coin_token_account: Pubkey,
pub pool_pc_token_account: Pubkey,
pub pool_token_a_mint: Pubkey,
pub pool_token_b_mint: Pubkey,
pub pool_lp_token_mint: Pubkey,
pub amm: Pubkey,
pub amm_authority: Pubkey,
pub amm_open_orders: Pubkey,
pub amm_target: Pubkey,
pub pool_withdraw_queue: Pubkey,
pub pool_temp_lp_token_account: Pubkey,
pub farm: Pubkey,
pub farm_authority: Pubkey,
pub farm_lp_token_account: Pubkey,
pub farm_reward_token_a_account: Pubkey,
pub farm_reward_token_b_account: Pubkey,
pub serum_market: Pubkey,
pub serum_program_id: Pubkey,
pub serum_coin_vault_account: Pubkey,
pub serum_pc_vault_account: Pubkey,
pub serum_vault_signer: Pubkey,
pub pool_program_id: Pubkey,
pub farm_program_id: Pubkey,
pub farm_version: u64,
pub deposits_allowed: bool,
pub withdraws_allowed: bool,
pub fee_millibps: u64,
pub external_fee_millibps: u64,
pub crank_time: u64,
pub crank_step: u64,
pub min_crank_interval: u64,
pub token_a_added: u64,
pub token_a_removed: u64,
pub token_b_added: u64,
pub token_b_removed: u64,
pub token_a_rewards: u64,
pub token_b_rewards: u64,
pub stake_info_account: Pubkey,
pub stake_info_account_v4: Pubkey,
pub stake_info_account_v5: Pubkey,
pub fees_account_a: Pubkey,
pub fees_account_b: Pubkey,
pub serum_bids: Pubkey,
pub serum_asks: Pubkey,
pub serum_event_queue: Pubkey,
pub stake_info_account_v5_mainnet: Pubkey,
pub bump4: u8,
pub bump5: u8,
pub stake_info_account_orca: Pubkey,
}
impl Vault {
pub fn add_rewards(&mut self, token_a_rewards: u64, token_b_rewards: u64) -> Result<()> {
if token_a_rewards > 0 {
self.token_a_rewards = unwrap_int!(self.token_a_rewards.checked_add(token_a_rewards));
}
if token_b_rewards > 0 {
self.token_b_rewards = unwrap_int!(self.token_b_rewards.checked_add(token_b_rewards));
}
Ok(())
}
pub fn add_liquidity(&mut self, token_a_added: u64, token_b_added: u64) -> Result<()> {
if token_a_added > 0 {
self.token_a_added = unwrap_int!(self.token_a_added.checked_add(token_a_added));
}
if token_b_added > 0 {
self.token_b_added = unwrap_int!(self.token_b_added.checked_add(token_b_added));
}
Ok(())
}
pub fn remove_liquidity(&mut self, token_a_removed: u64, token_b_removed: u64) -> Result<()> {
if token_a_removed > 0 {
self.token_a_removed = unwrap_int!(self.token_a_removed.checked_add(token_a_removed));
}
if token_b_removed > 0 {
self.token_b_removed = unwrap_int!(self.token_b_removed.checked_add(token_b_removed));
}
Ok(())
}
pub fn update_crank_time(&mut self) -> Result<()> {
self.crank_time = clock::get_time_as_u64()?;
Ok(())
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AmmInfoV4(solana_farm_sdk::program::protocol::raydium::AmmInfoV4);
impl AmmInfoV4 {
pub const LEN: usize = solana_farm_sdk::program::protocol::raydium::AmmInfoV4::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for AmmInfoV4 {
fn id() -> Pubkey {
raydium_v4::ID
}
}
impl Owner for AmmInfoV4 {
fn owner() -> Pubkey {
raydium_v4::ID
}
}
impl Deref for AmmInfoV4 {
type Target = solana_farm_sdk::program::protocol::raydium::AmmInfoV4;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for AmmInfoV4 {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for AmmInfoV4 {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
AmmInfoV4::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(solana_farm_sdk::program::protocol::raydium::AmmInfoV4::unpack(buf).map(AmmInfoV4)?)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RaydiumUserStakeInfo(solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfo);
impl RaydiumUserStakeInfo {
pub const LEN: usize = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfo::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for RaydiumUserStakeInfo {
fn id() -> Pubkey {
raydium_stake::ID
}
}
impl Owner for RaydiumUserStakeInfo {
fn owner() -> Pubkey {
raydium_stake::ID
}
}
impl Deref for RaydiumUserStakeInfo {
type Target = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfo;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for RaydiumUserStakeInfo {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for RaydiumUserStakeInfo {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
RaydiumUserStakeInfo::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfo::unpack(buf)
.map(RaydiumUserStakeInfo)?,
)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RaydiumUserStakeInfoV5Mainnet(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5,
);
impl RaydiumUserStakeInfoV5Mainnet {
pub const LEN: usize = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for RaydiumUserStakeInfoV5Mainnet {
fn id() -> Pubkey {
raydium_stake_v5::ID
}
}
impl Owner for RaydiumUserStakeInfoV5Mainnet {
fn owner() -> Pubkey {
raydium_stake_v5::ID
}
}
impl Deref for RaydiumUserStakeInfoV5Mainnet {
type Target = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for RaydiumUserStakeInfoV5Mainnet {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for RaydiumUserStakeInfoV5Mainnet {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
RaydiumUserStakeInfoV5Mainnet::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5::unpack(buf)
.map(RaydiumUserStakeInfoV5Mainnet)?,
)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct OrcaUserStakeInfo(solana_farm_sdk::program::protocol::orca::OrcaUserStakeInfo);
impl OrcaUserStakeInfo {
pub const LEN: usize = solana_farm_sdk::program::protocol::orca::OrcaUserStakeInfo::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for OrcaUserStakeInfo {
fn id() -> Pubkey {
raydium_stake_v5::ID
}
}
impl Owner for OrcaUserStakeInfo {
fn owner() -> Pubkey {
raydium_stake_v5::ID
}
}
impl Deref for OrcaUserStakeInfo {
type Target = solana_farm_sdk::program::protocol::orca::OrcaUserStakeInfo;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for OrcaUserStakeInfo {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for OrcaUserStakeInfo {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
OrcaUserStakeInfo::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(
solana_farm_sdk::program::protocol::orca::OrcaUserStakeInfo::unpack(buf)
.map(OrcaUserStakeInfo)?,
)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RaydiumUserStakeInfoV4(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV4,
);
impl RaydiumUserStakeInfoV4 {
pub const LEN: usize = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV4::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for RaydiumUserStakeInfoV4 {
fn id() -> Pubkey {
raydium_stake_v4::ID
}
}
impl Owner for RaydiumUserStakeInfoV4 {
fn owner() -> Pubkey {
raydium_stake_v4::ID
}
}
impl Deref for RaydiumUserStakeInfoV4 {
type Target = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV4;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for RaydiumUserStakeInfoV4 {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for RaydiumUserStakeInfoV4 {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
RaydiumUserStakeInfoV4::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV4::unpack(buf)
.map(RaydiumUserStakeInfoV4)?,
)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RaydiumUserStakeInfoV5(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5,
);
impl RaydiumUserStakeInfoV5 {
pub const LEN: usize = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5::LEN;
pub fn minimum_rent_exempt_balance() -> Result<u64> {
Ok(Rent::get()?.minimum_balance(Self::LEN))
}
}
impl anchor_lang::Id for RaydiumUserStakeInfoV5 {
fn id() -> Pubkey {
raydium_stake_v5_dev::ID
}
}
impl Owner for RaydiumUserStakeInfoV5 {
fn owner() -> Pubkey {
raydium_stake_v5_dev::ID
}
}
impl Deref for RaydiumUserStakeInfoV5 {
type Target = solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl anchor_lang::AccountSerialize for RaydiumUserStakeInfoV5 {
fn try_serialize<W: std::io::Write>(&self, _writer: &mut W) -> Result<()> {
Ok(())
}
}
impl anchor_lang::AccountDeserialize for RaydiumUserStakeInfoV5 {
fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
RaydiumUserStakeInfoV5::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self> {
Ok(
solana_farm_sdk::program::protocol::raydium::RaydiumUserStakeInfoV5::unpack(buf)
.map(RaydiumUserStakeInfoV5)?,
)
}
}