use crate::*;
use anchor_spl::token::TokenAccount;
use solana_farm_sdk::program::protocol::raydium;
use vipers::{assert_is_zero_token_account, assert_keys_eq, Validate};
#[derive(Accounts)]
pub struct CreateVaultTwo<'info> {
#[account(mut)]
pub vault: Box<Account<'info, Vault>>,
pub base: Signer<'info>,
pub manager: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
pub system_program: Program<'info, System>,
#[account(
init,
seeds = [
b"two_staker_info".as_ref(),
base.key.as_ref(),
vault.to_account_info().key.as_ref(),
],
bump,
payer = payer,
space = 96
)]
pub stake_info_account_v4: Box<Account<'info, RaydiumUserStakeInfoV4>>,
#[account(
init,
seeds = [
b"three_staker_info_v2".as_ref(),
base.key.as_ref(),
vault.to_account_info().key.as_ref(),
],
owner= raydium::raydium_stake_v5_dev::ID,
bump,
payer = payer,
space = 96
)]
pub stake_info_account_v5: UncheckedAccount<'info>,
pub farm_token_a_reward_custody_account: Box<Account<'info, TokenAccount>>,
pub farm_token_b_reward_custody_account: Box<Account<'info, TokenAccount>>,
pub farm_lp_token_account: Box<Account<'info, TokenAccount>>,
pub farm_reward_token_a_account: Box<Account<'info, TokenAccount>>,
pub farm_reward_token_b_account: Box<Account<'info, TokenAccount>>,
pub serum_coin_vault_account: Box<Account<'info, TokenAccount>>,
pub serum_pc_vault_account: Box<Account<'info, TokenAccount>>,
pub fees_account_a: Box<Account<'info, TokenAccount>>,
pub fees_account_b: Box<Account<'info, TokenAccount>>,
pub serum_bids: UncheckedAccount<'info>,
pub serum_asks: UncheckedAccount<'info>,
pub serum_event_queue: UncheckedAccount<'info>,
}
pub fn handler(ctx: Context<CreateVaultTwo>, farm_version: u64) -> Result<()> {
msg!("Starting vault creation.");
let vault = &mut ctx.accounts.vault;
vault.bump2 = *ctx.bumps.get("stake_info_account_v4").unwrap();
vault.bump3 = *ctx.bumps.get("stake_info_account_v5").unwrap();
vault.stake_info_account_v4 = ctx.accounts.stake_info_account_v4.key();
vault.stake_info_account_v5 = ctx.accounts.stake_info_account_v5.key();
vault.farm_version = farm_version;
vault.fees_account_a = ctx.accounts.fees_account_a.key();
vault.fees_account_b = ctx.accounts.fees_account_b.key();
vault.farm_token_a_reward_custody_account =
ctx.accounts.farm_token_a_reward_custody_account.key();
vault.farm_token_b_reward_custody_account =
ctx.accounts.farm_token_b_reward_custody_account.key();
vault.farm_lp_token_account = ctx.accounts.farm_lp_token_account.key();
vault.farm_reward_token_a_account = ctx.accounts.farm_reward_token_a_account.key();
vault.farm_reward_token_b_account = ctx.accounts.farm_reward_token_b_account.key();
vault.serum_coin_vault_account = ctx.accounts.serum_coin_vault_account.key();
vault.serum_pc_vault_account = ctx.accounts.serum_pc_vault_account.key();
vault.serum_bids = ctx.accounts.serum_bids.key();
vault.serum_asks = ctx.accounts.serum_asks.key();
vault.serum_event_queue = ctx.accounts.serum_event_queue.key();
msg!("Finished creating vaults.");
Ok(())
}
impl<'info> Validate<'info> for CreateVaultTwo<'info> {
fn validate(&self) -> Result<()> {
assert_is_zero_token_account!(self.farm_token_a_reward_custody_account);
assert_is_zero_token_account!(self.farm_token_b_reward_custody_account);
assert_is_zero_token_account!(self.fees_account_a);
assert_is_zero_token_account!(self.fees_account_b);
assert_keys_eq!(self.farm_token_a_reward_custody_account.owner, self.vault,);
assert_keys_eq!(self.farm_token_b_reward_custody_account.owner, self.vault,);
assert_keys_eq!(self.fees_account_a.owner, self.vault);
assert_keys_eq!(self.fees_account_b.owner, self.vault);
assert_keys_eq!(
self.farm_token_a_reward_custody_account.mint,
self.vault.farm_reward_token_a_mint
);
assert_keys_eq!(
self.farm_token_b_reward_custody_account.mint,
self.vault.farm_reward_token_b_mint
);
assert_keys_eq!(self.farm_lp_token_account.mint, self.vault.farm_lp_mint);
Ok(())
}
}