diff --git a/programs/drift_vaults/src/cpi.rs b/programs/drift_vaults/src/cpi.rs index 292a1baa..c7239c1d 100644 --- a/programs/drift_vaults/src/cpi.rs +++ b/programs/drift_vaults/src/cpi.rs @@ -29,3 +29,25 @@ pub trait UpdateUserMarginTradingEnabledCPI { pub trait TokenTransferCPI { fn token_transfer(&self, amount: u64) -> Result<()>; } + +pub trait InitializeInsuranceFundStakeCPI { + fn drift_initialize_insurance_fund_stake(&self, market_index: u16) -> Result<()>; +} + +pub trait AddInsuranceFundStakeCPI { + fn drift_add_insurance_fund_stake(&self, market_index: u16, amount: u64) -> Result<()>; +} + +pub trait RequestRemoveInsuranceFundStakeCPI { + fn drift_request_remove_insurance_fund_stake( + &self, + market_index: u16, + amount: u64, + ) -> Result<()>; + + fn drift_cancel_request_remove_insurance_fund_stake(&self, market_index: u16) -> Result<()>; +} + +pub trait RemoveInsuranceFundStakeCPI { + fn drift_remove_insurance_fund_stake(&self, market_index: u16) -> Result<()>; +} diff --git a/programs/drift_vaults/src/error.rs b/programs/drift_vaults/src/error.rs index 4abcfb05..11159600 100644 --- a/programs/drift_vaults/src/error.rs +++ b/programs/drift_vaults/src/error.rs @@ -51,6 +51,8 @@ pub enum ErrorCode { InvalidVaultDeposit, #[msg("OngoingLiquidation")] OngoingLiquidation, + #[msg("InvalidInsuranceFundSize")] + InvalidAddInsuranceFundSize, } impl From for ErrorCode { diff --git a/programs/drift_vaults/src/instructions/add_insurance_fund_stake.rs b/programs/drift_vaults/src/instructions/add_insurance_fund_stake.rs new file mode 100644 index 00000000..12b5f0eb --- /dev/null +++ b/programs/drift_vaults/src/instructions/add_insurance_fund_stake.rs @@ -0,0 +1,137 @@ +use crate::constraints::{is_manager_for_vault, is_spot_market_for_vault, is_user_stats_for_vault}; +use crate::cpi::{AddInsuranceFundStakeCPI, WithdrawCPI}; +use crate::error::ErrorCode; +use crate::Vault; +use crate::{declare_vault_seeds, implement_withdraw, validate, AccountMapProvider}; +use anchor_lang::prelude::*; +use anchor_spl::token::{Token, TokenAccount}; +use drift::cpi::accounts::AddInsuranceFundStake as DriftAddInsuranceFundStake; +use drift::cpi::accounts::Withdraw as DriftWithdraw; +use drift::instructions::optional_accounts::AccountMaps; +use drift::program::Drift; +use drift::state::insurance_fund_stake::InsuranceFundStake; +use drift::state::spot_market::SpotMarket; +use drift::state::user::User; + +pub fn add_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, AddInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, +) -> Result<()> { + let clock = &Clock::get()?; + let vault = ctx.accounts.vault.load()?; + + let user = ctx.accounts.drift_user.load()?; + let spot_market_index = vault.spot_market_index; + + validate!(!vault.in_liquidation(), ErrorCode::OngoingLiquidation)?; + + let AccountMaps { + perp_market_map, + spot_market_map, + mut oracle_map, + } = ctx.load_maps(clock.slot, Some(spot_market_index))?; + + let vault_equity = + vault.calculate_equity(&user, &perp_market_map, &spot_market_map, &mut oracle_map)?; + + validate!( + amount <= vault_equity, + ErrorCode::InvalidAddInsuranceFundSize + )?; + + ctx.drift_withdraw(amount)?; + + ctx.drift_add_insurance_fund_stake(market_index, amount)?; + + Ok(()) +} + +#[derive(Accounts)] +#[instruction(market_index: u16)] +pub struct AddInsuranceFundStake<'info> { + #[account( + constraint = is_manager_for_vault(&vault, &manager)?, + )] + pub vault: AccountLoader<'info, Vault>, + pub manager: Signer<'info>, + #[account( + mut, + token::authority = vault.key(), + token::mint = vault_token_account.mint + )] + pub vault_token_account: Box>, + #[account( + constraint = is_spot_market_for_vault(&vault, &drift_spot_market, market_index)?, + )] + pub drift_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + mut, + seeds = [b"insurance_fund_stake", vault.key().as_ref(), market_index.to_le_bytes().as_ref()], + bump + )] + pub insurance_fund_stake: AccountLoader<'info, InsuranceFundStake>, + #[account( + mut, + seeds = [b"spot_market_vault".as_ref(), market_index.to_le_bytes().as_ref()], + bump, + )] + pub drift_spot_market_vault: Box>, + #[account( + mut, + seeds = [b"insurance_fund_vault".as_ref(), market_index.to_le_bytes().as_ref()], + bump, + )] + pub insurance_fund_vault: Box>, + #[account( + mut, + constraint = is_user_stats_for_vault(&vault, &drift_user_stats)? + )] + /// CHECK: checked in drift cpi + pub drift_user: AccountLoader<'info, User>, + /// CHECK: checked in drift cpi + pub drift_user_stats: AccountInfo<'info>, + /// CHECK: checked in drift cpi + pub drift_signer: AccountInfo<'info>, + /// CHECK: checked in drift cpi + pub drift_state: AccountInfo<'info>, + pub drift_program: Program<'info, Drift>, + pub token_program: Program<'info, Token>, +} + +impl<'info> AddInsuranceFundStakeCPI for Context<'_, '_, '_, 'info, AddInsuranceFundStake<'info>> { + fn drift_add_insurance_fund_stake(&self, market_index: u16, amount: u64) -> Result<()> { + declare_vault_seeds!(self.accounts.vault, seeds); + + let cpi_accounts = DriftAddInsuranceFundStake { + state: self.accounts.drift_state.clone(), + spot_market: self.accounts.drift_spot_market.to_account_info().clone(), + insurance_fund_stake: self.accounts.insurance_fund_stake.to_account_info().clone(), + user_stats: self.accounts.drift_user_stats.clone(), + authority: self.accounts.vault.to_account_info().clone(), // sign? + spot_market_vault: self + .accounts + .drift_spot_market_vault + .to_account_info() + .clone(), + insurance_fund_vault: self.accounts.insurance_fund_stake.to_account_info().clone(), + drift_signer: self.accounts.drift_signer.to_account_info().clone(), + user_token_account: self.accounts.vault_token_account.to_account_info().clone(), + token_program: self.accounts.token_program.to_account_info().clone(), + }; + + let drift_program = self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts(self.remaining_accounts.into()); + drift::cpi::add_insurance_fund_stake(cpi_context, market_index, amount)?; + + Ok(()) + } +} + +impl<'info> WithdrawCPI for Context<'_, '_, '_, 'info, AddInsuranceFundStake<'info>> { + fn drift_withdraw(&self, amount: u64) -> Result<()> { + implement_withdraw!(self, amount); + Ok(()) + } +} diff --git a/programs/drift_vaults/src/instructions/constraints.rs b/programs/drift_vaults/src/instructions/constraints.rs index bd124138..e1949198 100644 --- a/programs/drift_vaults/src/instructions/constraints.rs +++ b/programs/drift_vaults/src/instructions/constraints.rs @@ -1,6 +1,7 @@ use crate::{Vault, VaultDepositor}; use anchor_lang::prelude::*; +use drift::state::spot_market::SpotMarket; pub fn is_vault_for_vault_depositor( vault_depositor: &AccountLoader, @@ -43,3 +44,14 @@ pub fn is_user_stats_for_vault( ) -> anchor_lang::Result { Ok(vault_depositor.load()?.user_stats.eq(user_stats.key)) } + +pub fn is_spot_market_for_vault( + vault_depositor: &AccountLoader, + drift_spot_market: &AccountLoader, + market_index: u16, +) -> anchor_lang::Result { + Ok( + (&vault_depositor.load()?.spot_market_index).eq(&drift_spot_market.load()?.market_index) + && (&vault_depositor.load()?.spot_market_index).eq(&market_index), + ) +} diff --git a/programs/drift_vaults/src/instructions/deposit.rs b/programs/drift_vaults/src/instructions/deposit.rs index 17ddcb7f..a773b8a0 100644 --- a/programs/drift_vaults/src/instructions/deposit.rs +++ b/programs/drift_vaults/src/instructions/deposit.rs @@ -3,7 +3,7 @@ use crate::constraints::{ }; use crate::cpi::{DepositCPI, TokenTransferCPI}; use crate::error::ErrorCode; -use crate::{declare_vault_seeds, validate, AccountMapProvider}; +use crate::{declare_vault_seeds, implement_deposit, validate, AccountMapProvider}; use crate::{Vault, VaultDepositor}; use anchor_lang::prelude::*; use anchor_spl::token::{self, Token, TokenAccount, Transfer}; @@ -110,27 +110,7 @@ impl<'info> TokenTransferCPI for Context<'_, '_, '_, 'info, Deposit<'info>> { impl<'info> DepositCPI for Context<'_, '_, '_, 'info, Deposit<'info>> { fn drift_deposit(&self, amount: u64) -> Result<()> { - declare_vault_seeds!(self.accounts.vault, seeds); - let spot_market_index = self.accounts.vault.load()?.spot_market_index; - - let cpi_program = self.accounts.drift_program.to_account_info().clone(); - let cpi_accounts = DriftDeposit { - state: self.accounts.drift_state.clone(), - user: self.accounts.drift_user.to_account_info().clone(), - user_stats: self.accounts.drift_user_stats.clone(), - authority: self.accounts.vault.to_account_info().clone(), - spot_market_vault: self - .accounts - .drift_spot_market_vault - .to_account_info() - .clone(), - user_token_account: self.accounts.vault_token_account.to_account_info().clone(), - token_program: self.accounts.token_program.to_account_info().clone(), - }; - let cpi_context = CpiContext::new_with_signer(cpi_program, cpi_accounts, seeds) - .with_remaining_accounts(self.remaining_accounts.into()); - drift::cpi::deposit(cpi_context, spot_market_index, amount, false)?; - + implement_deposit!(self, amount); Ok(()) } } diff --git a/programs/drift_vaults/src/instructions/initialize_insurance_fund_stake.rs b/programs/drift_vaults/src/instructions/initialize_insurance_fund_stake.rs new file mode 100644 index 00000000..cfd297f4 --- /dev/null +++ b/programs/drift_vaults/src/instructions/initialize_insurance_fund_stake.rs @@ -0,0 +1,78 @@ +use crate::constraints::{is_manager_for_vault, is_spot_market_for_vault, is_user_stats_for_vault}; +use crate::cpi::InitializeInsuranceFundStakeCPI; +use crate::declare_vault_seeds; +use crate::Vault; +use anchor_lang::prelude::*; +use drift::cpi::accounts::InitializeInsuranceFundStake as DriftInitializeInsuranceFundStake; +use drift::program::Drift; +use drift::state::insurance_fund_stake::InsuranceFundStake; +use drift::state::spot_market::SpotMarket; + +pub fn initialize_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, InitializeInsuranceFundStake<'info>>, + market_index: u16, +) -> Result<()> { + ctx.drift_initialize_insurance_fund_stake(market_index)?; + Ok(()) +} + +#[derive(Accounts)] +#[instruction(market_index: u16)] +pub struct InitializeInsuranceFundStake<'info> { + #[account( + mut, + constraint = is_manager_for_vault(&vault, &manager)?, + )] + pub vault: AccountLoader<'info, Vault>, + pub manager: Signer<'info>, + #[account(mut)] + pub payer: Signer<'info>, + pub rent: Sysvar<'info, Rent>, + pub system_program: Program<'info, System>, + + #[account( + constraint = is_spot_market_for_vault(&vault, &drift_spot_market, market_index)?, + )] + pub drift_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + mut, + seeds = [b"insurance_fund_stake", vault.key().as_ref(), market_index.to_le_bytes().as_ref()], + bump + )] + pub insurance_fund_stake: AccountLoader<'info, InsuranceFundStake>, + #[account( + mut, + constraint = is_user_stats_for_vault(&vault, &drift_user_stats)? + )] + /// CHECK: checked in drift cpi + pub drift_user_stats: AccountInfo<'info>, + /// CHECK: checked in drift cpi + pub drift_state: AccountInfo<'info>, + pub drift_program: Program<'info, Drift>, +} + +impl<'info> InitializeInsuranceFundStakeCPI + for Context<'_, '_, '_, 'info, InitializeInsuranceFundStake<'info>> +{ + fn drift_initialize_insurance_fund_stake(&self, market_index: u16) -> Result<()> { + declare_vault_seeds!(self.accounts.vault, seeds); + + let cpi_accounts = DriftInitializeInsuranceFundStake { + spot_market: self.accounts.drift_spot_market.to_account_info().clone(), + insurance_fund_stake: self.accounts.insurance_fund_stake.to_account_info().clone(), + user_stats: self.accounts.drift_user_stats.clone(), + state: self.accounts.drift_state.clone(), + authority: self.accounts.vault.to_account_info().clone(), // sign? + payer: self.accounts.payer.to_account_info().clone(), + rent: self.accounts.rent.to_account_info().clone(), + system_program: self.accounts.system_program.to_account_info().clone(), + }; + + let drift_program = self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts(self.remaining_accounts.into()); + drift::cpi::initialize_insurance_fund_stake(cpi_context, market_index)?; + + Ok(()) + } +} diff --git a/programs/drift_vaults/src/instructions/mod.rs b/programs/drift_vaults/src/instructions/mod.rs index 77c1a5b9..0a46d432 100644 --- a/programs/drift_vaults/src/instructions/mod.rs +++ b/programs/drift_vaults/src/instructions/mod.rs @@ -1,7 +1,9 @@ +pub use add_insurance_fund_stake::*; pub use apply_profit_share::*; pub use cancel_withdraw_request::*; pub use deposit::*; pub use force_withdraw::*; +pub use initialize_insurance_fund_stake::*; pub use initialize_vault::*; pub use initialize_vault_depositor::*; pub use liquidate::*; @@ -9,6 +11,8 @@ pub use manager_cancel_withdraw_request::*; pub use manager_deposit::*; pub use manager_request_withdraw::*; pub use manager_withdraw::*; +pub use remove_insurance_fund_stake::*; +pub use request_remove_insurance_fund_stake::*; pub use request_withdraw::*; pub use reset_delegate::*; @@ -17,11 +21,13 @@ pub use update_margin_trading_enabled::*; pub use update_vault::*; pub use withdraw::*; +mod add_insurance_fund_stake; mod apply_profit_share; mod cancel_withdraw_request; pub mod constraints; mod deposit; mod force_withdraw; +mod initialize_insurance_fund_stake; mod initialize_vault; mod initialize_vault_depositor; mod liquidate; @@ -29,6 +35,8 @@ mod manager_cancel_withdraw_request; mod manager_deposit; mod manager_request_withdraw; mod manager_withdraw; +mod remove_insurance_fund_stake; +mod request_remove_insurance_fund_stake; mod request_withdraw; mod reset_delegate; mod update_delegate; diff --git a/programs/drift_vaults/src/instructions/remove_insurance_fund_stake.rs b/programs/drift_vaults/src/instructions/remove_insurance_fund_stake.rs new file mode 100644 index 00000000..5ab01766 --- /dev/null +++ b/programs/drift_vaults/src/instructions/remove_insurance_fund_stake.rs @@ -0,0 +1,111 @@ +use crate::constraints::{is_manager_for_vault, is_spot_market_for_vault, is_user_stats_for_vault}; +use crate::cpi::{DepositCPI, RemoveInsuranceFundStakeCPI}; +use crate::Vault; +use crate::{declare_vault_seeds, implement_deposit}; +use anchor_lang::prelude::*; +use anchor_spl::token::{Token, TokenAccount}; +use drift::cpi::accounts::Deposit as DriftDeposit; +use drift::cpi::accounts::RemoveInsuranceFundStake as DriftRemoveInsuranceFundStake; +use drift::program::Drift; +use drift::state::insurance_fund_stake::InsuranceFundStake; +use drift::state::spot_market::SpotMarket; +use drift::state::user::User; + +pub fn remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RemoveInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, +) -> Result<()> { + ctx.drift_remove_insurance_fund_stake(market_index)?; + ctx.drift_deposit(amount)?; + + Ok(()) +} + +#[derive(Accounts)] +#[instruction(market_index: u16)] +pub struct RemoveInsuranceFundStake<'info> { + #[account( + mut, + constraint = is_manager_for_vault(&vault, &manager)?, + )] + pub vault: AccountLoader<'info, Vault>, + pub manager: Signer<'info>, + #[account( + mut, + token::authority = vault.key(), + token::mint = vault_token_account.mint + )] + pub vault_token_account: Box>, + #[account( + mut, + seeds = [b"insurance_fund_stake", vault.key().as_ref(), market_index.to_le_bytes().as_ref()], + bump, + constraint = insurance_fund_stake.load()?.authority == vault.key(), + )] + pub insurance_fund_stake: AccountLoader<'info, InsuranceFundStake>, + #[account( + constraint = is_spot_market_for_vault(&vault, &drift_spot_market, market_index)?, + )] + pub drift_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + mut, + seeds = [b"insurance_fund_vault".as_ref(), market_index.to_le_bytes().as_ref()], + bump, + token::authority = vault.key(), + )] + pub insurance_fund_vault: Box>, + #[account( + mut, + token::mint = vault_token_account.mint + )] + pub drift_spot_market_vault: Box>, + #[account( + mut, + constraint = is_user_stats_for_vault(&vault, &drift_user_stats)? + )] + /// CHECK: checked in drift cpi + pub drift_user_stats: AccountInfo<'info>, + /// CHECK: checked in drift cpi + pub drift_user: AccountLoader<'info, User>, + /// CHECK: checked in drift cpi + pub drift_state: AccountInfo<'info>, + /// CHECK: checked in drift cpi + pub drift_signer: AccountInfo<'info>, + pub drift_program: Program<'info, Drift>, + pub token_program: Program<'info, Token>, +} + +impl<'info> RemoveInsuranceFundStakeCPI + for Context<'_, '_, '_, 'info, RemoveInsuranceFundStake<'info>> +{ + fn drift_remove_insurance_fund_stake(&self, market_index: u16) -> Result<()> { + declare_vault_seeds!(self.accounts.vault, seeds); + + let cpi_accounts = DriftRemoveInsuranceFundStake { + spot_market: self.accounts.drift_spot_market.to_account_info().clone(), + insurance_fund_stake: self.accounts.insurance_fund_stake.to_account_info().clone(), + user_stats: self.accounts.drift_user_stats.to_account_info().clone(), + authority: self.accounts.vault.to_account_info().clone(), + insurance_fund_vault: self.accounts.insurance_fund_vault.to_account_info().clone(), + drift_signer: self.accounts.drift_signer.to_account_info().clone(), + user_token_account: self.accounts.vault_token_account.to_account_info().clone(), + token_program: self.accounts.token_program.to_account_info().clone(), + state: self.accounts.drift_state.to_account_info().clone(), + }; + + let drift_program = self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts(self.remaining_accounts.into()); + drift::cpi::remove_insurance_fund_stake(cpi_context, market_index)?; + + Ok(()) + } +} + +impl<'info> DepositCPI for Context<'_, '_, '_, 'info, RemoveInsuranceFundStake<'info>> { + fn drift_deposit(&self, amount: u64) -> Result<()> { + implement_deposit!(self, amount); + Ok(()) + } +} diff --git a/programs/drift_vaults/src/instructions/request_remove_insurance_fund_stake.rs b/programs/drift_vaults/src/instructions/request_remove_insurance_fund_stake.rs new file mode 100644 index 00000000..e936a6b1 --- /dev/null +++ b/programs/drift_vaults/src/instructions/request_remove_insurance_fund_stake.rs @@ -0,0 +1,106 @@ +use crate::constraints::{is_manager_for_vault, is_spot_market_for_vault, is_user_stats_for_vault}; +use crate::cpi::RequestRemoveInsuranceFundStakeCPI; +use crate::declare_vault_seeds; +use crate::Vault; +use anchor_lang::prelude::*; +use anchor_spl::token::TokenAccount; +use drift::cpi::accounts::RequestRemoveInsuranceFundStake as DriftRequestRemoveInsuranceFundStake; +use drift::program::Drift; +use drift::state::insurance_fund_stake::InsuranceFundStake; +use drift::state::spot_market::SpotMarket; + +pub fn request_remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RequestRemoveInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, +) -> Result<()> { + ctx.drift_request_remove_insurance_fund_stake(market_index, amount)?; + Ok(()) +} + +pub fn cancel_request_remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RequestRemoveInsuranceFundStake<'info>>, + market_index: u16, +) -> Result<()> { + ctx.drift_cancel_request_remove_insurance_fund_stake(market_index)?; + Ok(()) +} + +#[derive(Accounts)] +#[instruction(market_index: u16)] +pub struct RequestRemoveInsuranceFundStake<'info> { + #[account( + constraint = is_manager_for_vault(&vault, &manager)?, + )] + pub vault: AccountLoader<'info, Vault>, + pub manager: Signer<'info>, + #[account( + constraint = is_spot_market_for_vault(&vault, &drift_spot_market, market_index)?, + )] + pub drift_spot_market: AccountLoader<'info, SpotMarket>, + #[account( + mut, + seeds = [b"insurance_fund_stake", vault.key().as_ref(), market_index.to_le_bytes().as_ref()], + bump + )] + pub insurance_fund_stake: AccountLoader<'info, InsuranceFundStake>, + #[account( + mut, + seeds = [b"insurance_fund_vault".as_ref(), market_index.to_le_bytes().as_ref()], + bump, + )] + pub insurance_fund_vault: Box>, + #[account( + mut, + constraint = is_user_stats_for_vault(&vault, &drift_user_stats)? + )] + /// CHECK: checked in drift cpi + pub drift_user_stats: AccountInfo<'info>, + pub drift_program: Program<'info, Drift>, +} + +impl<'info> RequestRemoveInsuranceFundStakeCPI + for Context<'_, '_, '_, 'info, RequestRemoveInsuranceFundStake<'info>> +{ + fn drift_request_remove_insurance_fund_stake( + &self, + market_index: u16, + amount: u64, + ) -> Result<()> { + declare_vault_seeds!(self.accounts.vault, seeds); + + let cpi_accounts = DriftRequestRemoveInsuranceFundStake { + spot_market: self.accounts.drift_spot_market.to_account_info().clone(), + insurance_fund_stake: self.accounts.insurance_fund_stake.to_account_info().clone(), + user_stats: self.accounts.drift_user_stats.to_account_info().clone(), + insurance_fund_vault: self.accounts.insurance_fund_vault.to_account_info().clone(), + authority: self.accounts.vault.to_account_info().clone(), + }; + + let drift_program = self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts(self.remaining_accounts.into()); + drift::cpi::request_remove_insurance_fund_stake(cpi_context, market_index, amount)?; + + Ok(()) + } + + fn drift_cancel_request_remove_insurance_fund_stake(&self, market_index: u16) -> Result<()> { + declare_vault_seeds!(self.accounts.vault, seeds); + + let cpi_accounts = DriftRequestRemoveInsuranceFundStake { + spot_market: self.accounts.drift_spot_market.to_account_info().clone(), + insurance_fund_stake: self.accounts.insurance_fund_stake.to_account_info().clone(), + user_stats: self.accounts.drift_user_stats.to_account_info().clone(), + insurance_fund_vault: self.accounts.insurance_fund_vault.to_account_info().clone(), + authority: self.accounts.vault.to_account_info().clone(), + }; + + let drift_program = self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts(self.remaining_accounts.into()); + drift::cpi::cancel_request_remove_insurance_fund_stake(cpi_context, market_index)?; + + Ok(()) + } +} diff --git a/programs/drift_vaults/src/instructions/withdraw.rs b/programs/drift_vaults/src/instructions/withdraw.rs index 6b8f874b..52281cad 100644 --- a/programs/drift_vaults/src/instructions/withdraw.rs +++ b/programs/drift_vaults/src/instructions/withdraw.rs @@ -4,7 +4,7 @@ use crate::constraints::{ use crate::cpi::{TokenTransferCPI, UpdateUserDelegateCPI, UpdateUserReduceOnlyCPI, WithdrawCPI}; use crate::{ declare_vault_seeds, implement_update_user_delegate_cpi, implement_update_user_reduce_only_cpi, - AccountMapProvider, + implement_withdraw, AccountMapProvider, }; use crate::{Vault, VaultDepositor}; use anchor_lang::prelude::*; @@ -108,29 +108,7 @@ pub struct Withdraw<'info> { impl<'info> WithdrawCPI for Context<'_, '_, '_, 'info, Withdraw<'info>> { fn drift_withdraw(&self, amount: u64) -> Result<()> { - declare_vault_seeds!(self.accounts.vault, seeds); - let spot_market_index = self.accounts.vault.load()?.spot_market_index; - - let cpi_accounts = DriftWithdraw { - state: self.accounts.drift_state.to_account_info().clone(), - user: self.accounts.drift_user.to_account_info().clone(), - user_stats: self.accounts.drift_user_stats.to_account_info().clone(), - authority: self.accounts.vault.to_account_info().clone(), - spot_market_vault: self - .accounts - .drift_spot_market_vault - .to_account_info() - .clone(), - drift_signer: self.accounts.drift_signer.to_account_info().clone(), - user_token_account: self.accounts.vault_token_account.to_account_info().clone(), - token_program: self.accounts.token_program.to_account_info().clone(), - }; - - let drift_program = self.accounts.drift_program.to_account_info().clone(); - let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) - .with_remaining_accounts(self.remaining_accounts.into()); - drift::cpi::withdraw(cpi_context, spot_market_index, amount, false)?; - + implement_withdraw!(self, amount); Ok(()) } } diff --git a/programs/drift_vaults/src/lib.rs b/programs/drift_vaults/src/lib.rs index fe7eb42a..65398805 100644 --- a/programs/drift_vaults/src/lib.rs +++ b/programs/drift_vaults/src/lib.rs @@ -121,4 +121,42 @@ pub mod drift_vaults { ) -> Result<()> { instructions::force_withdraw(ctx) } + + pub fn initialize_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, InitializeInsuranceFundStake<'info>>, + market_index: u16, + ) -> Result<()> { + instructions::initialize_insurance_fund_stake(ctx, market_index) + } + + pub fn add_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, AddInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, + ) -> Result<()> { + instructions::add_insurance_fund_stake(ctx, market_index, amount) + } + + pub fn request_remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RequestRemoveInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, + ) -> Result<()> { + instructions::request_remove_insurance_fund_stake(ctx, market_index, amount) + } + + pub fn cancel_request_remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RequestRemoveInsuranceFundStake<'info>>, + market_index: u16, + ) -> Result<()> { + instructions::cancel_request_remove_insurance_fund_stake(ctx, market_index) + } + + pub fn remove_insurance_fund_stake<'info>( + ctx: Context<'_, '_, '_, 'info, RemoveInsuranceFundStake<'info>>, + market_index: u16, + amount: u64, + ) -> Result<()> { + instructions::remove_insurance_fund_stake(ctx, market_index, amount) + } } diff --git a/programs/drift_vaults/src/macros.rs b/programs/drift_vaults/src/macros.rs index 84680aac..7a8696b9 100644 --- a/programs/drift_vaults/src/macros.rs +++ b/programs/drift_vaults/src/macros.rs @@ -63,3 +63,59 @@ macro_rules! implement_update_user_reduce_only_cpi { drift::cpi::update_user_reduce_only(cpi_context, 0, $reduce_only)?; }; } + +#[macro_export] +macro_rules! implement_withdraw { + ( $self:expr, $amount:expr ) => { + declare_vault_seeds!($self.accounts.vault, seeds); + + let spot_market_index = $self.accounts.vault.load()?.spot_market_index; + + let cpi_accounts = DriftWithdraw { + state: $self.accounts.drift_state.to_account_info().clone(), + user: $self.accounts.drift_user.to_account_info().clone(), + user_stats: $self.accounts.drift_user_stats.to_account_info().clone(), + authority: $self.accounts.vault.to_account_info().clone(), + spot_market_vault: $self + .accounts + .drift_spot_market_vault + .to_account_info() + .clone(), + drift_signer: $self.accounts.drift_signer.to_account_info().clone(), + user_token_account: $self.accounts.vault_token_account.to_account_info().clone(), + token_program: $self.accounts.token_program.to_account_info().clone(), + }; + + let drift_program = $self.accounts.drift_program.to_account_info().clone(); + let cpi_context = CpiContext::new_with_signer(drift_program, cpi_accounts, seeds) + .with_remaining_accounts($self.remaining_accounts.into()); + drift::cpi::withdraw(cpi_context, spot_market_index, $amount, false)?; + }; +} + +#[macro_export] +macro_rules! implement_deposit { + ( $self:expr, $amount:expr ) => { + declare_vault_seeds!($self.accounts.vault, seeds); + + let spot_market_index = $self.accounts.vault.load()?.spot_market_index; + + let cpi_program = $self.accounts.drift_program.to_account_info().clone(); + let cpi_accounts = DriftDeposit { + state: $self.accounts.drift_state.clone(), + user: $self.accounts.drift_user.to_account_info().clone(), + user_stats: $self.accounts.drift_user_stats.clone(), + authority: $self.accounts.vault.to_account_info().clone(), + spot_market_vault: $self + .accounts + .drift_spot_market_vault + .to_account_info() + .clone(), + user_token_account: $self.accounts.vault_token_account.to_account_info().clone(), + token_program: $self.accounts.token_program.to_account_info().clone(), + }; + let cpi_context = CpiContext::new_with_signer(cpi_program, cpi_accounts, seeds) + .with_remaining_accounts($self.remaining_accounts.into()); + drift::cpi::deposit(cpi_context, spot_market_index, $amount, false)?; + }; +} diff --git a/ts/sdk/cli/commands/initVault.ts b/ts/sdk/cli/commands/initVault.ts index f3db84aa..01780b85 100644 --- a/ts/sdk/cli/commands/initVault.ts +++ b/ts/sdk/cli/commands/initVault.ts @@ -16,7 +16,6 @@ import { } from "../../src"; import { getCommandContext } from "../utils"; import { VAULT_PROGRAM_ID } from "../../src/types/types"; -import { red } from "bn.js"; export const initVault = async (program: Command, cmdOpts: OptionValues) => { const { @@ -24,7 +23,7 @@ export const initVault = async (program: Command, cmdOpts: OptionValues) => { driftVault } = await getCommandContext(program, true); - let newVaultName = cmdOpts.name; + const newVaultName = cmdOpts.name; if (!newVaultName) { throw new Error("Must provide vault name with -n/--name"); } @@ -119,7 +118,7 @@ export const initVault = async (program: Command, cmdOpts: OptionValues) => { readline.close(); process.exit(0); } - console.log('Creating vault...') + console.log('Creating vault...'); const initTx = await driftVault.initializeVault({ name: vaultNameBytes, diff --git a/ts/sdk/cli/commands/managerUpdateVault.1.ts b/ts/sdk/cli/commands/managerUpdateVault.1.ts deleted file mode 100644 index af1fa3ad..00000000 --- a/ts/sdk/cli/commands/managerUpdateVault.1.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; -import { - OptionValues, - Command -} from "commander"; -import { getCommandContext } from "../utils"; -import { BN, TEN } from "@drift-labs/sdk"; - - -export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues) => { - - let vaultAddress: PublicKey; - try { - vaultAddress = new PublicKey(cmdOpts.vaultAddress as string); - } catch (err) { - console.error("Invalid vault address"); - process.exit(1); - } - - const { - driftVault, driftClient, - } = await getCommandContext(program, true); - - - let spotMarketIndex = cmdOpts.marketIndex; - if (!spotMarketIndex) { - spotMarketIndex = "0"; - } - spotMarketIndex = parseInt(spotMarketIndex); - const spotMarket = driftClient.getSpotMarketAccount(spotMarketIndex); // takes USDC deposits - if (!spotMarket) { - throw new Error("No spot market found"); - } - const spotPrecision = TEN.pow(new BN(spotMarket.decimals)); - const spotMarketName = decodeName(spotMarket.name); - - let redeemPeriodSec = cmdOpts.redeemPeriod; - if (!redeemPeriodSec) { - redeemPeriodSec = (7 * 60 * 60 * 24).toString(); // 7 days - } - redeemPeriodSec = parseInt(redeemPeriodSec); - - let maxTokens = cmdOpts.maxTokens; - if (!maxTokens) { - maxTokens = "0"; - } - maxTokens = parseInt(maxTokens); - const maxTokensBN = new BN(maxTokens).mul(spotPrecision); - - let managementFee = cmdOpts.managementFee; - if (!managementFee) { - managementFee = "0"; - } - managementFee = parseInt(managementFee); - const managementFeeBN = new BN(managementFee).mul(PERCENTAGE_PRECISION).div(new BN(100)); - - let profitShare = cmdOpts.profitShare; - if (!profitShare) { - profitShare = "0"; - } - profitShare = parseInt(profitShare); - const profitShareBN = new BN(profitShare).mul(PERCENTAGE_PRECISION).div(new BN(100)); - - let permissioned = cmdOpts.permissioned; - if (!permissioned) { - permissioned = false; - } - - let minDepositAmount = cmdOpts.minDepositAmount; - if (!minDepositAmount) { - minDepositAmount = "0"; - } - minDepositAmount = parseInt(minDepositAmount); - const minDepositAmountBN = new BN(minDepositAmount).mul(spotPrecision); - - // null means unchanged - const newParams = { - redeemPeriod: null, // new BN(30 * 60 * 60 * 24), // 30 days - maxTokens: new BN("5000000000000"), - managementFee: null, - minDepositAmount: null, //new BN("1000000000"), - profitShare: null, - hurdleRate: null, - permissioned: null, - }; - - const tx = await driftVault.managerUpdateVault(vaultAddress, newParams); - console.log(`Updated vault params as vault manager: https://solscan.io/tx/${tx}`); -}; diff --git a/ts/sdk/cli/commands/managerUpdateVault.ts b/ts/sdk/cli/commands/managerUpdateVault.ts index 1653c701..876fbbdb 100644 --- a/ts/sdk/cli/commands/managerUpdateVault.ts +++ b/ts/sdk/cli/commands/managerUpdateVault.ts @@ -81,7 +81,7 @@ export const managerUpdateVault = async (program: Command, cmdOpts: OptionValues const profitShareAfter = profitShareNumber !== null ? `${profitShareNumber / PERCENTAGE_PRECISION.toNumber() * 100.0}%` : 'unchanged'; console.log(` ProfitShare: ${profitShareBefore}% -> ${profitShareAfter}`); const permissionedBefore = vault.permissioned; - const permissionedAfter = permissioned !== null ? permissioned : 'unchanged ' + const permissionedAfter = permissioned !== null ? permissioned : 'unchanged '; console.log(` Permissioned: ${permissionedBefore} -> ${permissionedAfter}`); const readline = require('readline').createInterface({ diff --git a/ts/sdk/cli/utils.ts b/ts/sdk/cli/utils.ts index 7b9bbac8..84a4660b 100644 --- a/ts/sdk/cli/utils.ts +++ b/ts/sdk/cli/utils.ts @@ -51,7 +51,7 @@ export function printVault(vault: Vault) { return { managerShares, managerSharePct, - } + }; } export function printVaultDepositor(vaultDepositor) { diff --git a/ts/sdk/src/idl/drift_vaults.json b/ts/sdk/src/idl/drift_vaults.json index b484ef74..1531a9f3 100644 --- a/ts/sdk/src/idl/drift_vaults.json +++ b/ts/sdk/src/idl/drift_vaults.json @@ -789,6 +789,323 @@ } ], "args": [] + }, + { + "name": "initializeInsuranceFundStake", + "accounts": [ + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "manager", + "isMut": false, + "isSigner": true + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "rent", + "isMut": false, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "driftSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "insuranceFundStake", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUserStats", + "isMut": true, + "isSigner": false + }, + { + "name": "driftState", + "isMut": false, + "isSigner": false + }, + { + "name": "driftProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + } + ] + }, + { + "name": "addInsuranceFundStake", + "accounts": [ + { + "name": "vault", + "isMut": false, + "isSigner": false + }, + { + "name": "manager", + "isMut": false, + "isSigner": true + }, + { + "name": "vaultTokenAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "driftSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "insuranceFundStake", + "isMut": true, + "isSigner": false + }, + { + "name": "driftSpotMarketVault", + "isMut": true, + "isSigner": false + }, + { + "name": "insuranceFundVault", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUser", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUserStats", + "isMut": false, + "isSigner": false + }, + { + "name": "driftSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "driftState", + "isMut": false, + "isSigner": false + }, + { + "name": "driftProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "requestRemoveInsuranceFundStake", + "accounts": [ + { + "name": "vault", + "isMut": false, + "isSigner": false + }, + { + "name": "manager", + "isMut": false, + "isSigner": true + }, + { + "name": "driftSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "insuranceFundStake", + "isMut": true, + "isSigner": false + }, + { + "name": "insuranceFundVault", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUserStats", + "isMut": true, + "isSigner": false + }, + { + "name": "driftProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "amount", + "type": "u64" + } + ] + }, + { + "name": "cancelRequestRemoveInsuranceFundStake", + "accounts": [ + { + "name": "vault", + "isMut": false, + "isSigner": false + }, + { + "name": "manager", + "isMut": false, + "isSigner": true + }, + { + "name": "driftSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "insuranceFundStake", + "isMut": true, + "isSigner": false + }, + { + "name": "insuranceFundVault", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUserStats", + "isMut": true, + "isSigner": false + }, + { + "name": "driftProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + } + ] + }, + { + "name": "removeInsuranceFundStake", + "accounts": [ + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "manager", + "isMut": false, + "isSigner": true + }, + { + "name": "vaultTokenAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "insuranceFundStake", + "isMut": true, + "isSigner": false + }, + { + "name": "driftSpotMarket", + "isMut": false, + "isSigner": false + }, + { + "name": "insuranceFundVault", + "isMut": true, + "isSigner": false + }, + { + "name": "driftSpotMarketVault", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUserStats", + "isMut": true, + "isSigner": false + }, + { + "name": "driftUser", + "isMut": false, + "isSigner": false + }, + { + "name": "driftState", + "isMut": false, + "isSigner": false + }, + { + "name": "driftSigner", + "isMut": false, + "isSigner": false + }, + { + "name": "driftProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "amount", + "type": "u64" + } + ] } ], "accounts": [ @@ -1539,6 +1856,11 @@ "code": 6021, "name": "OngoingLiquidation", "msg": "OngoingLiquidation" + }, + { + "code": 6022, + "name": "InvalidAddInsuranceFundSize", + "msg": "InvalidInsuranceFundSize" } ], "metadata": { diff --git a/ts/sdk/src/types/drift_vaults.ts b/ts/sdk/src/types/drift_vaults.ts index 356b4e99..b78175b7 100644 --- a/ts/sdk/src/types/drift_vaults.ts +++ b/ts/sdk/src/types/drift_vaults.ts @@ -789,6 +789,323 @@ export type DriftVaults = { } ]; args: []; + }, + { + name: 'initializeInsuranceFundStake'; + accounts: [ + { + name: 'vault'; + isMut: true; + isSigner: false; + }, + { + name: 'manager'; + isMut: false; + isSigner: true; + }, + { + name: 'payer'; + isMut: true; + isSigner: true; + }, + { + name: 'rent'; + isMut: false; + isSigner: false; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'driftSpotMarket'; + isMut: false; + isSigner: false; + }, + { + name: 'insuranceFundStake'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUserStats'; + isMut: true; + isSigner: false; + }, + { + name: 'driftState'; + isMut: false; + isSigner: false; + }, + { + name: 'driftProgram'; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: 'marketIndex'; + type: 'u16'; + } + ]; + }, + { + name: 'addInsuranceFundStake'; + accounts: [ + { + name: 'vault'; + isMut: false; + isSigner: false; + }, + { + name: 'manager'; + isMut: false; + isSigner: true; + }, + { + name: 'vaultTokenAccount'; + isMut: true; + isSigner: false; + }, + { + name: 'driftSpotMarket'; + isMut: false; + isSigner: false; + }, + { + name: 'insuranceFundStake'; + isMut: true; + isSigner: false; + }, + { + name: 'driftSpotMarketVault'; + isMut: true; + isSigner: false; + }, + { + name: 'insuranceFundVault'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUser'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUserStats'; + isMut: false; + isSigner: false; + }, + { + name: 'driftSigner'; + isMut: false; + isSigner: false; + }, + { + name: 'driftState'; + isMut: false; + isSigner: false; + }, + { + name: 'driftProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: 'marketIndex'; + type: 'u16'; + }, + { + name: 'amount'; + type: 'u64'; + } + ]; + }, + { + name: 'requestRemoveInsuranceFundStake'; + accounts: [ + { + name: 'vault'; + isMut: false; + isSigner: false; + }, + { + name: 'manager'; + isMut: false; + isSigner: true; + }, + { + name: 'driftSpotMarket'; + isMut: false; + isSigner: false; + }, + { + name: 'insuranceFundStake'; + isMut: true; + isSigner: false; + }, + { + name: 'insuranceFundVault'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUserStats'; + isMut: true; + isSigner: false; + }, + { + name: 'driftProgram'; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: 'marketIndex'; + type: 'u16'; + }, + { + name: 'amount'; + type: 'u64'; + } + ]; + }, + { + name: 'cancelRequestRemoveInsuranceFundStake'; + accounts: [ + { + name: 'vault'; + isMut: false; + isSigner: false; + }, + { + name: 'manager'; + isMut: false; + isSigner: true; + }, + { + name: 'driftSpotMarket'; + isMut: false; + isSigner: false; + }, + { + name: 'insuranceFundStake'; + isMut: true; + isSigner: false; + }, + { + name: 'insuranceFundVault'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUserStats'; + isMut: true; + isSigner: false; + }, + { + name: 'driftProgram'; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: 'marketIndex'; + type: 'u16'; + } + ]; + }, + { + name: 'removeInsuranceFundStake'; + accounts: [ + { + name: 'vault'; + isMut: true; + isSigner: false; + }, + { + name: 'manager'; + isMut: false; + isSigner: true; + }, + { + name: 'vaultTokenAccount'; + isMut: true; + isSigner: false; + }, + { + name: 'insuranceFundStake'; + isMut: true; + isSigner: false; + }, + { + name: 'driftSpotMarket'; + isMut: false; + isSigner: false; + }, + { + name: 'insuranceFundVault'; + isMut: true; + isSigner: false; + }, + { + name: 'driftSpotMarketVault'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUserStats'; + isMut: true; + isSigner: false; + }, + { + name: 'driftUser'; + isMut: false; + isSigner: false; + }, + { + name: 'driftState'; + isMut: false; + isSigner: false; + }, + { + name: 'driftSigner'; + isMut: false; + isSigner: false; + }, + { + name: 'driftProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + } + ]; + args: [ + { + name: 'marketIndex'; + type: 'u16'; + }, + { + name: 'amount'; + type: 'u64'; + } + ]; } ]; accounts: [ @@ -1466,19 +1783,164 @@ export type DriftVaults = { msg: 'InvalidVaultDeposit'; }, { - code: 6021; - name: 'OngoingLiquidation'; - msg: 'OngoingLiquidation'; - } - ]; -}; - -export const IDL: DriftVaults = { - version: '0.1.0', - name: 'drift_vaults', - instructions: [ - { - name: 'initializeVault', + code: 6021; + name: 'OngoingLiquidation'; + msg: 'OngoingLiquidation'; + }, + { + code: 6022; + name: 'InvalidAddInsuranceFundSize'; + msg: 'InvalidInsuranceFundSize'; + } + ]; +}; + +export const IDL: DriftVaults = { + version: '0.1.0', + name: 'drift_vaults', + instructions: [ + { + name: 'initializeVault', + accounts: [ + { + name: 'vault', + isMut: true, + isSigner: false, + }, + { + name: 'tokenAccount', + isMut: true, + isSigner: false, + }, + { + name: 'driftUserStats', + isMut: true, + isSigner: false, + }, + { + name: 'driftUser', + isMut: true, + isSigner: false, + }, + { + name: 'driftState', + isMut: true, + isSigner: false, + }, + { + name: 'driftSpotMarket', + isMut: false, + isSigner: false, + }, + { + name: 'driftSpotMarketMint', + isMut: false, + isSigner: false, + }, + { + name: 'manager', + isMut: false, + isSigner: true, + }, + { + name: 'payer', + isMut: true, + isSigner: true, + }, + { + name: 'rent', + isMut: false, + isSigner: false, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'params', + type: { + defined: 'VaultParams', + }, + }, + ], + }, + { + name: 'updateDelegate', + accounts: [ + { + name: 'vault', + isMut: true, + isSigner: false, + }, + { + name: 'manager', + isMut: false, + isSigner: true, + }, + { + name: 'driftUser', + isMut: true, + isSigner: false, + }, + { + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'delegate', + type: 'publicKey', + }, + ], + }, + { + name: 'updateMarginTradingEnabled', + accounts: [ + { + name: 'vault', + isMut: true, + isSigner: false, + }, + { + name: 'manager', + isMut: false, + isSigner: true, + }, + { + name: 'driftUser', + isMut: true, + isSigner: false, + }, + { + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'enabled', + type: 'bool', + }, + ], + }, + { + name: 'updateVault', accounts: [ { name: 'vault', @@ -1486,55 +1948,104 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'tokenAccount', - isMut: true, + name: 'manager', + isMut: false, + isSigner: true, + }, + ], + args: [ + { + name: 'params', + type: { + defined: 'UpdateVaultParams', + }, + }, + ], + }, + { + name: 'initializeVaultDepositor', + accounts: [ + { + name: 'vault', + isMut: false, isSigner: false, }, { - name: 'driftUserStats', + name: 'vaultDepositor', isMut: true, isSigner: false, }, { - name: 'driftUser', - isMut: true, + name: 'authority', + isMut: false, isSigner: false, }, { - name: 'driftState', + name: 'payer', isMut: true, - isSigner: false, + isSigner: true, }, { - name: 'driftSpotMarket', + name: 'rent', isMut: false, isSigner: false, }, { - name: 'driftSpotMarketMint', + name: 'systemProgram', isMut: false, isSigner: false, }, + ], + args: [], + }, + { + name: 'deposit', + accounts: [ { - name: 'manager', + name: 'vault', + isMut: true, + isSigner: false, + }, + { + name: 'vaultDepositor', + isMut: true, + isSigner: false, + }, + { + name: 'authority', isMut: false, isSigner: true, }, { - name: 'payer', + name: 'vaultTokenAccount', isMut: true, - isSigner: true, + isSigner: false, }, { - name: 'rent', - isMut: false, + name: 'driftUserStats', + isMut: true, isSigner: false, }, { - name: 'systemProgram', + name: 'driftUser', + isMut: true, + isSigner: false, + }, + { + name: 'driftState', isMut: false, isSigner: false, }, + { + name: 'driftSpotMarketVault', + isMut: true, + isSigner: false, + }, + { + name: 'userTokenAccount', + isMut: true, + isSigner: false, + }, { name: 'driftProgram', isMut: false, @@ -1548,15 +2059,13 @@ export const IDL: DriftVaults = { ], args: [ { - name: 'params', - type: { - defined: 'VaultParams', - }, + name: 'amount', + type: 'u64', }, ], }, { - name: 'updateDelegate', + name: 'requestWithdraw', accounts: [ { name: 'vault', @@ -1564,30 +2073,46 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'manager', + name: 'vaultDepositor', + isMut: true, + isSigner: false, + }, + { + name: 'authority', isMut: false, isSigner: true, }, + { + name: 'driftUserStats', + isMut: false, + isSigner: false, + }, { name: 'driftUser', - isMut: true, + isMut: false, isSigner: false, }, { - name: 'driftProgram', + name: 'driftState', isMut: false, isSigner: false, }, ], args: [ { - name: 'delegate', - type: 'publicKey', + name: 'withdrawAmount', + type: 'u64', + }, + { + name: 'withdrawUnit', + type: { + defined: 'WithdrawUnit', + }, }, ], }, { - name: 'updateMarginTradingEnabled', + name: 'cancelRequestWithdraw', accounts: [ { name: 'vault', @@ -1595,30 +2120,35 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'manager', + name: 'vaultDepositor', + isMut: true, + isSigner: false, + }, + { + name: 'authority', isMut: false, isSigner: true, }, { - name: 'driftUser', - isMut: true, + name: 'driftUserStats', + isMut: false, isSigner: false, }, { - name: 'driftProgram', + name: 'driftUser', isMut: false, isSigner: false, }, - ], - args: [ { - name: 'enabled', - type: 'bool', + name: 'driftState', + isMut: false, + isSigner: false, }, ], + args: [], }, { - name: 'updateVault', + name: 'withdraw', accounts: [ { name: 'vault', @@ -1626,26 +2156,69 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'manager', + name: 'vaultDepositor', + isMut: true, + isSigner: false, + }, + { + name: 'authority', isMut: false, isSigner: true, }, - ], - args: [ { - name: 'params', - type: { - defined: 'UpdateVaultParams', - }, + name: 'vaultTokenAccount', + isMut: true, + isSigner: false, + }, + { + name: 'driftUserStats', + isMut: true, + isSigner: false, + }, + { + name: 'driftUser', + isMut: true, + isSigner: false, + }, + { + name: 'driftState', + isMut: false, + isSigner: false, + }, + { + name: 'driftSpotMarketVault', + isMut: true, + isSigner: false, + }, + { + name: 'driftSigner', + isMut: false, + isSigner: false, + }, + { + name: 'userTokenAccount', + isMut: true, + isSigner: false, + }, + { + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, }, ], + args: [], }, { - name: 'initializeVaultDepositor', + name: 'liquidate', accounts: [ { name: 'vault', - isMut: false, + isMut: true, isSigner: false, }, { @@ -1656,20 +2229,25 @@ export const IDL: DriftVaults = { { name: 'authority', isMut: false, + isSigner: true, + }, + { + name: 'driftUserStats', + isMut: true, isSigner: false, }, { - name: 'payer', + name: 'driftUser', isMut: true, - isSigner: true, + isSigner: false, }, { - name: 'rent', + name: 'driftState', isMut: false, isSigner: false, }, { - name: 'systemProgram', + name: 'driftProgram', isMut: false, isSigner: false, }, @@ -1677,7 +2255,7 @@ export const IDL: DriftVaults = { args: [], }, { - name: 'deposit', + name: 'resetDelegate', accounts: [ { name: 'vault', @@ -1685,12 +2263,33 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'vaultDepositor', + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'driftUser', isMut: true, isSigner: false, }, { - name: 'authority', + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: 'managerDeposit', + accounts: [ + { + name: 'vault', + isMut: true, + isSigner: false, + }, + { + name: 'manager', isMut: false, isSigner: true, }, @@ -1743,7 +2342,7 @@ export const IDL: DriftVaults = { ], }, { - name: 'requestWithdraw', + name: 'managerRequestWithdraw', accounts: [ { name: 'vault', @@ -1751,12 +2350,7 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'vaultDepositor', - isMut: true, - isSigner: false, - }, - { - name: 'authority', + name: 'manager', isMut: false, isSigner: true, }, @@ -1790,7 +2384,7 @@ export const IDL: DriftVaults = { ], }, { - name: 'cancelRequestWithdraw', + name: 'mangerCancelWithdrawRequest', accounts: [ { name: 'vault', @@ -1798,12 +2392,7 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'vaultDepositor', - isMut: true, - isSigner: false, - }, - { - name: 'authority', + name: 'manager', isMut: false, isSigner: true, }, @@ -1826,7 +2415,7 @@ export const IDL: DriftVaults = { args: [], }, { - name: 'withdraw', + name: 'managerWithdraw', accounts: [ { name: 'vault', @@ -1834,12 +2423,7 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'vaultDepositor', - isMut: true, - isSigner: false, - }, - { - name: 'authority', + name: 'manager', isMut: false, isSigner: true, }, @@ -1892,7 +2476,7 @@ export const IDL: DriftVaults = { args: [], }, { - name: 'liquidate', + name: 'applyProfitShare', accounts: [ { name: 'vault', @@ -1905,7 +2489,7 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'authority', + name: 'manager', isMut: false, isSigner: true, }, @@ -1925,29 +2509,8 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'driftProgram', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'resetDelegate', - accounts: [ - { - name: 'vault', - isMut: true, - isSigner: false, - }, - { - name: 'authority', + name: 'driftSigner', isMut: false, - isSigner: true, - }, - { - name: 'driftUser', - isMut: true, isSigner: false, }, { @@ -1959,7 +2522,7 @@ export const IDL: DriftVaults = { args: [], }, { - name: 'managerDeposit', + name: 'forceWithdraw', accounts: [ { name: 'vault', @@ -1971,6 +2534,11 @@ export const IDL: DriftVaults = { isMut: false, isSigner: true, }, + { + name: 'vaultDepositor', + isMut: true, + isSigner: false, + }, { name: 'vaultTokenAccount', isMut: true, @@ -1996,6 +2564,11 @@ export const IDL: DriftVaults = { isMut: true, isSigner: false, }, + { + name: 'driftSigner', + isMut: false, + isSigner: false, + }, { name: 'userTokenAccount', isMut: true, @@ -2012,15 +2585,10 @@ export const IDL: DriftVaults = { isSigner: false, }, ], - args: [ - { - name: 'amount', - type: 'u64', - }, - ], + args: [], }, { - name: 'managerRequestWithdraw', + name: 'initializeInsuranceFundStake', accounts: [ { name: 'vault', @@ -2033,71 +2601,59 @@ export const IDL: DriftVaults = { isSigner: true, }, { - name: 'driftUserStats', - isMut: false, - isSigner: false, + name: 'payer', + isMut: true, + isSigner: true, }, { - name: 'driftUser', + name: 'rent', isMut: false, isSigner: false, }, { - name: 'driftState', + name: 'systemProgram', isMut: false, isSigner: false, }, - ], - args: [ - { - name: 'withdrawAmount', - type: 'u64', - }, { - name: 'withdrawUnit', - type: { - defined: 'WithdrawUnit', - }, + name: 'driftSpotMarket', + isMut: false, + isSigner: false, }, - ], - }, - { - name: 'mangerCancelWithdrawRequest', - accounts: [ { - name: 'vault', + name: 'insuranceFundStake', isMut: true, isSigner: false, }, - { - name: 'manager', - isMut: false, - isSigner: true, - }, { name: 'driftUserStats', - isMut: false, + isMut: true, isSigner: false, }, { - name: 'driftUser', + name: 'driftState', isMut: false, isSigner: false, }, { - name: 'driftState', + name: 'driftProgram', isMut: false, isSigner: false, }, ], - args: [], + args: [ + { + name: 'marketIndex', + type: 'u16', + }, + ], }, { - name: 'managerWithdraw', + name: 'addInsuranceFundStake', accounts: [ { name: 'vault', - isMut: true, + isMut: false, isSigner: false, }, { @@ -2111,33 +2667,43 @@ export const IDL: DriftVaults = { isSigner: false, }, { - name: 'driftUserStats', + name: 'driftSpotMarket', + isMut: false, + isSigner: false, + }, + { + name: 'insuranceFundStake', isMut: true, isSigner: false, }, { - name: 'driftUser', + name: 'driftSpotMarketVault', isMut: true, isSigner: false, }, { - name: 'driftState', - isMut: false, + name: 'insuranceFundVault', + isMut: true, isSigner: false, }, { - name: 'driftSpotMarketVault', + name: 'driftUser', isMut: true, isSigner: false, }, + { + name: 'driftUserStats', + isMut: false, + isSigner: false, + }, { name: 'driftSigner', isMut: false, isSigner: false, }, { - name: 'userTokenAccount', - isMut: true, + name: 'driftState', + isMut: false, isSigner: false, }, { @@ -2151,44 +2717,98 @@ export const IDL: DriftVaults = { isSigner: false, }, ], - args: [], + args: [ + { + name: 'marketIndex', + type: 'u16', + }, + { + name: 'amount', + type: 'u64', + }, + ], }, { - name: 'applyProfitShare', + name: 'requestRemoveInsuranceFundStake', accounts: [ { name: 'vault', + isMut: false, + isSigner: false, + }, + { + name: 'manager', + isMut: false, + isSigner: true, + }, + { + name: 'driftSpotMarket', + isMut: false, + isSigner: false, + }, + { + name: 'insuranceFundStake', isMut: true, isSigner: false, }, { - name: 'vaultDepositor', + name: 'insuranceFundVault', + isMut: true, + isSigner: false, + }, + { + name: 'driftUserStats', isMut: true, isSigner: false, }, + { + name: 'driftProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'marketIndex', + type: 'u16', + }, + { + name: 'amount', + type: 'u64', + }, + ], + }, + { + name: 'cancelRequestRemoveInsuranceFundStake', + accounts: [ + { + name: 'vault', + isMut: false, + isSigner: false, + }, { name: 'manager', isMut: false, isSigner: true, }, { - name: 'driftUserStats', - isMut: true, + name: 'driftSpotMarket', + isMut: false, isSigner: false, }, { - name: 'driftUser', + name: 'insuranceFundStake', isMut: true, isSigner: false, }, { - name: 'driftState', - isMut: false, + name: 'insuranceFundVault', + isMut: true, isSigner: false, }, { - name: 'driftSigner', - isMut: false, + name: 'driftUserStats', + isMut: true, isSigner: false, }, { @@ -2197,10 +2817,15 @@ export const IDL: DriftVaults = { isSigner: false, }, ], - args: [], + args: [ + { + name: 'marketIndex', + type: 'u16', + }, + ], }, { - name: 'forceWithdraw', + name: 'removeInsuranceFundStake', accounts: [ { name: 'vault', @@ -2213,43 +2838,48 @@ export const IDL: DriftVaults = { isSigner: true, }, { - name: 'vaultDepositor', + name: 'vaultTokenAccount', isMut: true, isSigner: false, }, { - name: 'vaultTokenAccount', + name: 'insuranceFundStake', isMut: true, isSigner: false, }, { - name: 'driftUserStats', - isMut: true, + name: 'driftSpotMarket', + isMut: false, isSigner: false, }, { - name: 'driftUser', + name: 'insuranceFundVault', isMut: true, isSigner: false, }, { - name: 'driftState', - isMut: false, + name: 'driftSpotMarketVault', + isMut: true, isSigner: false, }, { - name: 'driftSpotMarketVault', + name: 'driftUserStats', isMut: true, isSigner: false, }, { - name: 'driftSigner', + name: 'driftUser', isMut: false, isSigner: false, }, { - name: 'userTokenAccount', - isMut: true, + name: 'driftState', + isMut: false, + isSigner: false, + }, + { + name: 'driftSigner', + isMut: false, isSigner: false, }, { @@ -2263,7 +2893,16 @@ export const IDL: DriftVaults = { isSigner: false, }, ], - args: [], + args: [ + { + name: 'marketIndex', + type: 'u16', + }, + { + name: 'amount', + type: 'u64', + }, + ], }, ], accounts: [ @@ -2945,5 +3584,10 @@ export const IDL: DriftVaults = { name: 'OngoingLiquidation', msg: 'OngoingLiquidation', }, + { + code: 6022, + name: 'InvalidAddInsuranceFundSize', + msg: 'InvalidInsuranceFundSize', + }, ], };