use {
crate::{traits::Init, vault_info::VaultInfo},
solana_farm_sdk::{
id::zero,
instruction::vault::VaultInstruction,
program::{account, pda, protocol::saber},
token::Token,
traits::Packed,
vault::Vault,
},
solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
},
};
impl Init for VaultInstruction {
fn init(vault: &Vault, accounts: &[AccountInfo], step: u64) -> ProgramResult {
#[allow(clippy::deprecated_cfg_attr)]
#[cfg_attr(rustfmt, rustfmt_skip)]
if let [
admin_account,
_vault_metadata,
vault_info_account,
_multisig_account,
vault_authority,
vault_program,
_system_program,
_spl_token_program,
_associated_token_program,
rent_program,
farm_program,
vault_token_mint,
vault_token_ref,
vault_stake_info,
vault_miner_account,
fees_account_a,
fees_account_b,
usdc_token_custody,
wrapped_token_custody,
lp_token_custody,
usdc_token_mint,
non_usdc_token_mint,
wrapped_token_mint,
lp_token_mint,
sbr_token_reward_custody,
iou_token_reward_custody,
sbr_token_mint,
iou_token_mint,
quarry,
rewarder
] = accounts
{
if vault_authority.key != &vault.vault_authority
|| vault_token_ref.key != &vault.vault_token_ref
|| vault_program.key != &vault.vault_program_id
{
msg!("Error: Invalid Vault accounts");
return Err(ProgramError::InvalidArgument);
}
if step <= 1 {
msg!("Init vault authority");
pda::init_system_account(
admin_account,
vault_authority,
&vault.vault_program_id,
&vault.vault_program_id,
&[b"vault_authority", vault.name.as_bytes()],
0,
)?;
msg!("Init vault info");
pda::init_system_account(
admin_account,
vault_info_account,
&vault.vault_program_id,
&vault.vault_program_id,
&[b"info_account", vault.name.as_bytes()],
VaultInfo::LEN,
)?;
let mut vault_info = VaultInfo::new(vault_info_account);
vault_info.init(&vault.name)?;
msg!("Init vault token mint");
let vault_token = Token::unpack(&vault_token_ref.try_borrow_data()?)?;
if vault_token_mint.key != &vault_token.mint {
msg!("Error: Invalid Vault token mint");
return Err(ProgramError::InvalidArgument);
}
pda::init_mint(
admin_account,
vault_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"vault_token_mint", vault.name.as_bytes()],
vault_token.decimals,
)?;
msg!("Init vault miner");
pda::init_associated_token_account(
admin_account,
vault_stake_info,
vault_miner_account,
lp_token_mint,
rent_program,
)?;
if account::is_empty(vault_stake_info)? {
msg!("Init stake info");
let seeds: &[&[&[u8]]] = &[&[
b"vault_authority",
vault.name.as_bytes(),
&[vault.authority_bump],
]];
saber::user_init_with_seeds(
&[
vault_authority.clone(),
admin_account.clone(),
farm_program.clone(),
lp_token_mint.clone(),
vault_stake_info.clone(),
vault_miner_account.clone(),
quarry.clone(),
rewarder.clone(),
],
seeds,
)?;
}
}
if step == 0 || step == 2 {
msg!("Init fees account a");
pda::init_token_account(
admin_account,
fees_account_a,
sbr_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"fees_account_a", vault.name.as_bytes()],
)?;
msg!("Init fees account b");
pda::init_token_account(
admin_account,
fees_account_b,
non_usdc_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"fees_account_b", vault.name.as_bytes()],
)?;
msg!("Init lp token custody account");
pda::init_token_account(
admin_account,
lp_token_custody,
lp_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"lp_token_custody", vault.name.as_bytes()],
)?;
msg!("Init USDC token custody account");
pda::init_token_account(
admin_account,
usdc_token_custody,
usdc_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"token_a_custody", vault.name.as_bytes()],
)?;
if wrapped_token_custody.key != &zero::id() {
msg!("Init wrapped USDC token custody account");
pda::init_token_account(
admin_account,
wrapped_token_custody,
wrapped_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"token_b_custody", vault.name.as_bytes()],
)?;
}
msg!("Init SBR token reward custody account");
pda::init_token_account(
admin_account,
sbr_token_reward_custody,
sbr_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"token_a_reward_custody", vault.name.as_bytes()],
)?;
if *iou_token_reward_custody.key != zero::id() {
msg!("Init IOU token reward custody account");
pda::init_token_account(
admin_account,
iou_token_reward_custody,
iou_token_mint,
vault_authority,
rent_program,
&vault.vault_program_id,
&[b"token_b_reward_custody", vault.name.as_bytes()],
)?;
}
}
Ok(())
} else {
Err(ProgramError::NotEnoughAccountKeys)
}
}
}