diff --git a/program/src/ids.rs b/program/src/ids.rs index 7b4caae6..5c1b20f1 100644 --- a/program/src/ids.rs +++ b/program/src/ids.rs @@ -26,3 +26,20 @@ pub mod luna_pyth_oracle { use solana_program::declare_id; declare_id!("5bmWuR1dgP4avtGYMNKLuxumZTVKGgoN2BCMXWDNL9nY"); } + +pub mod mainnet_1_group { + use solana_program::declare_id; + #[cfg(feature = "devnet")] + declare_id!("Ec2enZyoC4nGpEfu2sUNAa2nUGJHWxoUWYSEJ2hNTWTA"); + #[cfg(not(feature = "devnet"))] + declare_id!("98pjRuQjK3qA6gXts96PqZT4Ze5QmnCmt3QYjhbUSPue"); +} + +// Owner of the reimbursement fund multisig accounts +pub mod recovery_authority { + use solana_program::declare_id; + #[cfg(feature = "devnet")] + declare_id!("8pANRWCcw8vn8DszUP7hh4xFbCiBiMWX3WbwUTipArSJ"); + #[cfg(not(feature = "devnet"))] + declare_id!("9mM6NfXauEFviFY1S1thbo7HXYNiSWSvwZEhguJw26wY"); +} diff --git a/program/src/instruction.rs b/program/src/instruction.rs index 2dd4cbf9..dbe5a5dd 100644 --- a/program/src/instruction.rs +++ b/program/src/instruction.rs @@ -1194,6 +1194,62 @@ pub enum MangoInstruction { ref_mngo_required: u64, ref_mngo_tier_2_factor: u8, }, + + /// Force cancellation and settlement of open orders for a user in a recovery group + /// + /// Accounts expected: 18 + open orders accounts (MAX_PAIRS) + /// 0. `[]` mango_group_ai - MangoGroup + /// 1. `[writable]` mango_account_ai - MangoAccount + /// 2. `[]` base_root_bank_ai - RootBank + /// 3. `[writable]` base_node_bank_ai - NodeBank + /// 4. `[writable]` base_vault_ai - MangoGroup base vault acc + /// 5. `[]` quote_root_bank_ai - RootBank + /// 6. `[writable]` quote_node_bank_ai - NodeBank + /// 7. `[writable]` quote_vault_ai - MangoGroup quote vault acc + /// 8. `[writable]` spot_market_ai - SpotMarket + /// 9. `[writable]` bids_ai - SpotMarket bids acc + /// 10. `[writable]` asks_ai - SpotMarket asks acc + /// 12. `[signer]` signer_ai - Signer + /// 12. `[writable]` dex_event_queue_ai - Market event queue acc + /// 13. `[writable]` dex_base_ai - + /// 14. `[writable]` dex_quote_ai - + /// 15. `[]` dex_signer_ai - + /// 16. `[]` dex_prog_ai - Dex Program acc + /// 17. `[]` token_prog_ai - Token Program acc + /// 18+... `[]` open_orders_ais - open orders accs + RecoveryForceSettleSpotOrders { + limit: u8, + }, + + /// Allow withdrawal of token accounts in a recovery group + /// Accounts expected: 6 + /// 0. `[]` mango_group_ai - MangoGroup + /// 1. `[writable]` vault_ai - Vault TokenAccount + /// 2. `[writable]` token_account_ai - Recovery authority ata + /// 3. `[]` root_bank_ai - RootBank + /// 4. `[]` node_bank_ai - NodeBank + /// 5. `[]` signer_ai - Group Signer Key + /// 6. `[]` token_prog_ai - Token program + RecoveryWithdrawTokenVault, + + /// Allow withdrawal of unused mngo rewards in a recovery group + /// Accounts expected: 5 + /// 0. `[]` mango_group_ai - MangoGroup + /// 1. `[writable]` vault_ai - Vault TokenAccount + /// 2. `[writable]` token_account_ai - Recovery authority MNGO ata + // 3. `[]` perp_market_ai - Perp market + /// 4. `[]` signer_ai - Group Signer Key + /// 5. `[]` token_prog_ai - Token program + RecoveryWithdrawMngoVault, + + /// Allow withdrawal of the insurance vault in a recovery group + /// Accounts expected: 4 + /// 0. `[]` mango_group_ai - MangoGroup + /// 1. `[writable]` vault_ai - Vault TokenAccount + /// 2. `[writable]` token_account_ai - Recovery authority USDC ata + /// 3. `[]` signer_ai - Group Signer Key + /// 4. `[]` token_prog_ai - Token program + RecoveryWithdrawInsuranceVault, } impl MangoInstruction { @@ -1745,6 +1801,16 @@ impl MangoInstruction { ref_mngo_tier_2_factor: u8::from_le_bytes(*ref_mngo_tier_2_factor), } } + 75 => { + let data_arr = array_ref![data, 0, 1]; + + MangoInstruction::RecoveryForceSettleSpotOrders { + limit: u8::from_le_bytes(*data_arr), + } + } + 76 => MangoInstruction::RecoveryWithdrawTokenVault, + 77 => MangoInstruction::RecoveryWithdrawMngoVault, + 78 => MangoInstruction::RecoveryWithdrawInsuranceVault, _ => { return None; } diff --git a/program/src/processor.rs b/program/src/processor.rs index 7e08cacf..ddc6dc39 100644 --- a/program/src/processor.rs +++ b/program/src/processor.rs @@ -35,7 +35,7 @@ use mango_logs::{ }; use crate::error::{check_assert, MangoError, MangoErrorCode, MangoResult, SourceFileId}; -use crate::ids::{luna_pyth_oracle, msrm_token, srm_token}; +use crate::ids::{luna_pyth_oracle, mainnet_1_group, msrm_token, recovery_authority, srm_token}; use crate::instruction::MangoInstruction; use crate::matching::{Book, BookSide, ExpiryType, OrderType, Side}; use crate::oracle::{determine_oracle_type, OracleType, StubOracle, STUB_MAGIC}; @@ -7412,553 +7412,883 @@ impl Processor { Ok(()) } + fn recovery_force_settle_spot_orders( + program_id: &Pubkey, + accounts: &[AccountInfo], + limit: u8, + ) -> MangoResult<()> { + const NUM_FIXED: usize = 18; + let accounts = array_ref![accounts, 0, NUM_FIXED + MAX_PAIRS]; + let (fixed_ais, open_orders_ais) = array_refs![accounts, NUM_FIXED, MAX_PAIRS]; + + let [ + mango_group_ai, // read + mango_account_ai, // write + base_root_bank_ai, // read + base_node_bank_ai, // write + base_vault_ai, // write + quote_root_bank_ai, // read + quote_node_bank_ai, // write + quote_vault_ai, // write + + spot_market_ai, // write + bids_ai, // write + asks_ai, // write + signer_ai, // read + dex_event_queue_ai, // write + dex_base_ai, // write + dex_quote_ai, // write + dex_signer_ai, // read + dex_prog_ai, // read + token_prog_ai, // read + ] = fixed_ais; + + check_eq!(mango_group_ai.key, &mainnet_1_group::ID, MangoErrorCode::InvalidAccount)?; + // Check token program id + check_eq!(token_prog_ai.key, &spl_token::ID, MangoErrorCode::InvalidProgramId)?; + + let mango_group = MangoGroup::load_checked(mango_group_ai, program_id)?; + check_eq!(dex_prog_ai.key, &mango_group.dex_program_id, MangoErrorCode::InvalidProgramId)?; + check!(signer_ai.key == &mango_group.signer_key, MangoErrorCode::InvalidSignerKey)?; + + let mut mango_account = + MangoAccount::load_mut_checked(mango_account_ai, program_id, mango_group_ai.key)?; + mango_account.check_open_orders(&mango_group, open_orders_ais)?; + + let market_index = mango_group.find_spot_market_index(spot_market_ai.key).unwrap(); + check!(mango_account.in_margin_basket[market_index], MangoErrorCode::Default)?; + + check_eq!( + &mango_group.tokens[market_index].root_bank, + base_root_bank_ai.key, + MangoErrorCode::InvalidRootBank + )?; + let base_root_bank = RootBank::load_checked(base_root_bank_ai, program_id)?; + + check!( + base_root_bank.node_banks.contains(base_node_bank_ai.key), + MangoErrorCode::InvalidNodeBank + )?; + let base_node_bank = NodeBank::load_mut_checked(base_node_bank_ai, program_id)?; + check_eq!(&base_node_bank.vault, base_vault_ai.key, MangoErrorCode::InvalidVault)?; + + check_eq!( + &mango_group.tokens[QUOTE_INDEX].root_bank, + quote_root_bank_ai.key, + MangoErrorCode::InvalidRootBank + )?; + let quote_root_bank = RootBank::load_checked(quote_root_bank_ai, program_id)?; + + check!( + quote_root_bank.node_banks.contains(quote_node_bank_ai.key), + MangoErrorCode::InvalidNodeBank + )?; + let quote_node_bank = NodeBank::load_mut_checked(quote_node_bank_ai, program_id)?; + check_eq!("e_node_bank.vault, quote_vault_ai.key, MangoErrorCode::InvalidVault)?; + + // Cancel orders up to the limit + let open_orders_ai = &open_orders_ais[market_index]; + let signers_seeds = gen_signer_seeds(&mango_group.signer_nonce, mango_group_ai.key); + invoke_cancel_orders( + open_orders_ai, + dex_prog_ai, + spot_market_ai, + bids_ai, + asks_ai, + signer_ai, + dex_event_queue_ai, + &[&signers_seeds], + limit, + )?; + + let (pre_base, pre_quote) = { + let open_orders = load_open_orders(open_orders_ai)?; + ( + open_orders.native_coin_free, + open_orders.native_pc_free + open_orders.referrer_rebates_accrued, + ) + }; + + if pre_base == 0 && pre_quote == 0 { + // margin basket may be in an invalid state; correct it before returning + let open_orders = load_open_orders(open_orders_ai)?; + mango_account.update_basket(market_index, &open_orders)?; + msg!("recovery-settle: {} {} {} {}", pre_base, pre_quote, 0, 0); + return Ok(()); + } + + // Settle funds released by canceling open orders + invoke_settle_funds( + dex_prog_ai, + spot_market_ai, + open_orders_ai, + signer_ai, + dex_base_ai, + dex_quote_ai, + base_vault_ai, + quote_vault_ai, + dex_signer_ai, + token_prog_ai, + &[&signers_seeds], + )?; + + let (post_base, post_quote) = { + let open_orders = load_open_orders(open_orders_ai)?; + mango_account.update_basket(market_index, &open_orders)?; + + ( + open_orders.native_coin_free, + open_orders.native_pc_free + open_orders.referrer_rebates_accrued, + ) + }; + + msg!("recovery-settle: {} {} {} {}", pre_base, pre_quote, post_base, post_quote); + + check!(post_base <= pre_base, MangoErrorCode::Default)?; + check!(post_quote <= pre_quote, MangoErrorCode::Default)?; + + Ok(()) + } + + #[inline(never)] + fn recovery_withdraw_token_vault( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> MangoResult<()> { + const NUM_FIXED: usize = 7; + let accounts = array_ref![accounts, 0, NUM_FIXED]; + let [ + mango_group_ai, // read + vault_ai, // write + token_account_ai, // write + root_bank_ai, // read + node_bank_ai, // read + signer_ai, // read + token_prog_ai, // read + ] = accounts; + + check_eq!(mango_group_ai.key, &mainnet_1_group::ID, MangoErrorCode::InvalidAccount)?; + check_eq!(&spl_token::ID, token_prog_ai.key, MangoErrorCode::InvalidProgramId)?; + + let mango_group = MangoGroup::load_checked(mango_group_ai, program_id)?; + + check!(signer_ai.key == &mango_group.signer_key, MangoErrorCode::InvalidSignerKey)?; + let quantity; + + { + let root_bank = RootBank::load_checked(root_bank_ai, program_id)?; + + let node_bank = NodeBank::load_checked(node_bank_ai, program_id)?; + check!( + root_bank.node_banks.contains(node_bank_ai.key), + MangoErrorCode::InvalidNodeBank + )?; + check_eq!(&node_bank.vault, vault_ai.key, MangoErrorCode::InvalidVault)?; + + let source_account = TokenAccount::load_checked(vault_ai)?; + let destination_account = TokenAccount::load_checked(token_account_ai)?; + check_eq!( + destination_account.mint, + source_account.mint, + MangoErrorCode::InvalidAccount + )?; + check_eq!( + destination_account.owner, + recovery_authority::ID, + MangoErrorCode::InvalidOwner + )?; + quantity = source_account.amount; + } + + let signers_seeds = gen_signer_seeds(&mango_group.signer_nonce, mango_group_ai.key); + invoke_transfer( + token_prog_ai, + vault_ai, + token_account_ai, + signer_ai, + &[&signers_seeds], + quantity, + )?; + + Ok(()) + } + + #[inline(never)] + fn recovery_withdraw_mngo_vault( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> MangoResult<()> { + const NUM_FIXED: usize = 6; + let accounts = array_ref![accounts, 0, NUM_FIXED]; + let [ + mango_group_ai, // read + vault_ai, // write + token_account_ai, // write + perp_market_ai, // read + signer_ai, // read + token_prog_ai, // read + ] = accounts; + + check_eq!(mango_group_ai.key, &mainnet_1_group::ID, MangoErrorCode::InvalidAccount)?; + check_eq!(&spl_token::ID, token_prog_ai.key, MangoErrorCode::InvalidProgramId)?; + + let mango_group = MangoGroup::load_checked(mango_group_ai, program_id)?; + + check!(signer_ai.key == &mango_group.signer_key, MangoErrorCode::InvalidSignerKey)?; + let quantity; + + { + let perp_market = + PerpMarket::load_checked(perp_market_ai, program_id, mango_group_ai.key)?; + + check_eq!(&perp_market.mngo_vault, vault_ai.key, MangoErrorCode::InvalidAccount)?; + + let source_account = TokenAccount::load_checked(vault_ai)?; + let destination_account = TokenAccount::load_checked(token_account_ai)?; + check_eq!( + destination_account.mint, + source_account.mint, + MangoErrorCode::InvalidAccount + )?; + check_eq!( + destination_account.owner, + recovery_authority::ID, + MangoErrorCode::InvalidOwner + )?; + quantity = source_account.amount; + } + + let signers_seeds = gen_signer_seeds(&mango_group.signer_nonce, mango_group_ai.key); + invoke_transfer( + token_prog_ai, + vault_ai, + token_account_ai, + signer_ai, + &[&signers_seeds], + quantity, + )?; + + Ok(()) + } + + #[inline(never)] + fn recovery_withdraw_insurance_vault( + program_id: &Pubkey, + accounts: &[AccountInfo], + ) -> MangoResult<()> { + const NUM_FIXED: usize = 5; + let accounts = array_ref![accounts, 0, NUM_FIXED]; + let [ + mango_group_ai, // read + vault_ai, // write + token_account_ai, // write + signer_ai, // read + token_prog_ai, // read + ] = accounts; + + check_eq!(mango_group_ai.key, &mainnet_1_group::ID, MangoErrorCode::InvalidAccount)?; + check_eq!(&spl_token::ID, token_prog_ai.key, MangoErrorCode::InvalidProgramId)?; + + let mango_group = MangoGroup::load_checked(mango_group_ai, program_id)?; + + check!(signer_ai.key == &mango_group.signer_key, MangoErrorCode::InvalidSignerKey)?; + let quantity; + + { + check_eq!(&mango_group.insurance_vault, vault_ai.key, MangoErrorCode::InvalidAccount)?; + + let source_account = TokenAccount::load_checked(vault_ai)?; + let destination_account = TokenAccount::load_checked(token_account_ai)?; + check_eq!( + destination_account.mint, + source_account.mint, + MangoErrorCode::InvalidAccount + )?; + check_eq!( + destination_account.owner, + recovery_authority::ID, + MangoErrorCode::InvalidOwner + )?; + quantity = source_account.amount; + } + + let signers_seeds = gen_signer_seeds(&mango_group.signer_nonce, mango_group_ai.key); + invoke_transfer( + token_prog_ai, + vault_ai, + token_account_ai, + signer_ai, + &[&signers_seeds], + quantity, + )?; + + Ok(()) + } + pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], data: &[u8]) -> MangoResult { - Err(throw!()) - // let instruction = - // MangoInstruction::unpack(data).ok_or(ProgramError::InvalidInstructionData)?; - // match instruction { - // MangoInstruction::InitMangoGroup { - // signer_nonce, - // valid_interval, - // quote_optimal_util, - // quote_optimal_rate, - // quote_max_rate, - // } => { - // msg!("Mango: InitMangoGroup"); - // Self::init_mango_group( - // program_id, - // accounts, - // signer_nonce, - // valid_interval, - // quote_optimal_util, - // quote_optimal_rate, - // quote_max_rate, - // ) - // } - // MangoInstruction::InitMangoAccount => { - // msg!("Mango: InitMangoAccount DEPRECATED"); - // Self::init_mango_account(program_id, accounts) - // } - // MangoInstruction::CreateMangoAccount { account_num } => { - // msg!("Mango: CreateMangoAccount"); - // Self::create_mango_account(program_id, accounts, account_num) - // } - // MangoInstruction::CloseMangoAccount => { - // msg!("Mango: CloseMangoAccount"); - // Self::close_mango_account(program_id, accounts) - // } - // MangoInstruction::UpgradeMangoAccountV0V1 => { - // msg!("Mango: UpgradeMangoAccountV0V1"); - // Self::upgrade_mango_account_v0_v1(program_id, accounts) - // } - // MangoInstruction::Deposit { quantity } => { - // msg!("Mango: Deposit"); - // Self::deposit(program_id, accounts, quantity) - // } - // MangoInstruction::Withdraw { quantity, allow_borrow } => { - // msg!("Mango: Withdraw"); - // Self::withdraw(program_id, accounts, quantity, allow_borrow) - // } - // MangoInstruction::AddSpotMarket { - // maint_leverage, - // init_leverage, - // liquidation_fee, - // optimal_util, - // optimal_rate, - // max_rate, - // } => { - // msg!("Mango: AddSpotMarket"); - // Self::add_spot_market( - // program_id, - // accounts, - // maint_leverage, - // init_leverage, - // liquidation_fee, - // optimal_util, - // optimal_rate, - // max_rate, - // ) - // } - // MangoInstruction::AddToBasket { .. } => { - // msg!("Mango: AddToBasket Deprecated"); - // Ok(()) - // } - // MangoInstruction::Borrow { .. } => { - // msg!("Mango: Borrow DEPRECATED"); - // Ok(()) - // } - // MangoInstruction::CachePrices => { - // msg!("Mango: CachePrices"); - // Self::cache_prices(program_id, accounts) - // } - // MangoInstruction::CacheRootBanks => { - // msg!("Mango: CacheRootBanks"); - // Self::cache_root_banks(program_id, accounts) - // } - // MangoInstruction::PlaceSpotOrder { order } => { - // msg!("Mango: PlaceSpotOrder"); - // Self::place_spot_order(program_id, accounts, order) - // } - // MangoInstruction::CancelSpotOrder { order, .. } => { - // msg!("Mango: CancelSpotOrder"); - // let data = serum_dex::instruction::MarketInstruction::CancelOrderV2(order).pack(); - // Self::cancel_spot_order(program_id, accounts, data) - // } - // MangoInstruction::AddOracle => { - // msg!("Mango: AddOracle"); - // Self::add_oracle(program_id, accounts) - // } - // MangoInstruction::SettleFunds => { - // msg!("Mango: SettleFunds"); - // Self::settle_funds(program_id, accounts) - // } - // MangoInstruction::UpdateRootBank => { - // msg!("Mango: UpdateRootBank"); - // Self::update_root_bank(program_id, accounts) - // } - // MangoInstruction::AddPerpMarket { .. } => { - // msg!("DEPRECATED Mango: AddPerpMarket"); - // Ok(()) - // } - // MangoInstruction::PlacePerpOrder { - // side, - // price, - // quantity, - // client_order_id, - // order_type, - // reduce_only, - // } => { - // msg!("Mango: PlacePerpOrder client_order_id={}", client_order_id); - // Self::place_perp_order( - // program_id, - // accounts, - // side, - // price, - // quantity, - // client_order_id, - // order_type, - // reduce_only, - // ) - // } - // MangoInstruction::CancelPerpOrderByClientId { client_order_id, invalid_id_ok } => { - // msg!("Mango: CancelPerpOrderByClientId client_order_id={}", client_order_id); - // let result = - // Self::cancel_perp_order_by_client_id(program_id, accounts, client_order_id); - // if invalid_id_ok { - // if let Err(MangoError::MangoErrorCode { mango_error_code, .. }) = result { - // if mango_error_code == MangoErrorCode::InvalidOrderId - // || mango_error_code == MangoErrorCode::ClientIdNotFound - // { - // return Ok(()); - // } - // } - // } - // result - // } - // MangoInstruction::CancelPerpOrder { order_id, invalid_id_ok } => { - // // TODO OPT this log may cost too much compute - // msg!("Mango: CancelPerpOrder order_id={}", order_id); - // let result = Self::cancel_perp_order(program_id, accounts, order_id); - // if invalid_id_ok { - // if let Err(MangoError::MangoErrorCode { mango_error_code, .. }) = result { - // if mango_error_code == MangoErrorCode::InvalidOrderId { - // return Ok(()); - // } - // } - // } - // result - // } - // MangoInstruction::ConsumeEvents { limit } => { - // msg!("Mango: ConsumeEvents limit={}", limit); - // Self::consume_events(program_id, accounts, limit) - // } - // MangoInstruction::CachePerpMarkets => { - // msg!("Mango: CachePerpMarkets"); - // Self::cache_perp_markets(program_id, accounts) - // } - // MangoInstruction::UpdateFunding => { - // msg!("Mango: UpdateFunding"); - // Self::update_funding(program_id, accounts) - // } - // MangoInstruction::SetOracle { price } => { - // // msg!("Mango: SetOracle {:?}", price); - // msg!("Mango: SetOracle"); - // Self::set_oracle(program_id, accounts, price) - // } - // MangoInstruction::SettlePnl { market_index } => { - // msg!("Mango: SettlePnl"); - // Self::settle_pnl(program_id, accounts, market_index) - // } - // MangoInstruction::SettleBorrow { .. } => { - // msg!("Mango: SettleBorrow DEPRECATED"); - // Ok(()) - // } - // MangoInstruction::ForceCancelSpotOrders { limit } => { - // msg!("Mango: ForceCancelSpotOrders"); - // Self::force_cancel_spot_orders(program_id, accounts, limit) - // } - // MangoInstruction::ForceCancelPerpOrders { limit } => { - // msg!("Mango: ForceCancelPerpOrders"); - // Self::force_cancel_perp_orders(program_id, accounts, limit) - // } - // MangoInstruction::LiquidateTokenAndToken { max_liab_transfer } => { - // msg!("Mango: LiquidateTokenAndToken"); - // Self::liquidate_token_and_token(program_id, accounts, max_liab_transfer) - // } - // MangoInstruction::LiquidateTokenAndPerp { - // asset_type, - // asset_index, - // liab_type, - // liab_index, - // max_liab_transfer, - // } => { - // msg!("Mango: LiquidateTokenAndPerp"); - // Self::liquidate_token_and_perp( - // program_id, - // accounts, - // asset_type, - // asset_index, - // liab_type, - // liab_index, - // max_liab_transfer, - // ) - // } - // MangoInstruction::LiquidatePerpMarket { base_transfer_request } => { - // msg!("Mango: LiquidatePerpMarket"); - // Self::liquidate_perp_market(program_id, accounts, base_transfer_request) - // } - // MangoInstruction::SettleFees => { - // msg!("Mango: SettleFees"); - // Self::settle_fees(program_id, accounts) - // } - // MangoInstruction::ResolvePerpBankruptcy { liab_index, max_liab_transfer } => { - // msg!("Mango: ResolvePerpBankruptcy"); - // Self::resolve_perp_bankruptcy(program_id, accounts, liab_index, max_liab_transfer) - // } - // MangoInstruction::ResolveTokenBankruptcy { max_liab_transfer } => { - // msg!("Mango: ResolveTokenBankruptcy"); - // Self::resolve_token_bankruptcy(program_id, accounts, max_liab_transfer) - // } - // MangoInstruction::InitSpotOpenOrders => { - // msg!("Mango: InitSpotOpenOrders"); - // Self::init_spot_open_orders(program_id, accounts) - // } - // MangoInstruction::CloseSpotOpenOrders => { - // msg!("Mango: CloseSpotOpenOrders"); - // Self::close_spot_open_orders(program_id, accounts) - // } - // MangoInstruction::RedeemMngo => { - // msg!("Mango: RedeemMngo"); - // Self::redeem_mngo(program_id, accounts) - // } - // MangoInstruction::AddMangoAccountInfo { info } => { - // msg!("Mango: AddMangoAccountInfo"); - // Self::add_mango_account_info(program_id, accounts, info) - // } - // MangoInstruction::DepositMsrm { quantity } => { - // msg!("Mango: DepositMsrm"); - // Self::deposit_msrm(program_id, accounts, quantity) - // } - // MangoInstruction::WithdrawMsrm { quantity } => { - // msg!("Mango: WithdrawMsrm"); - // Self::withdraw_msrm(program_id, accounts, quantity) - // } - // MangoInstruction::ChangePerpMarketParams { .. } => { - // msg!("Mango: ChangePerpMarketParams DEPRECATED - use ChangePerpMarketParams2 instead"); - // Ok(()) - // } - // MangoInstruction::SetGroupAdmin => { - // msg!("Mango: SetGroupAdmin"); - // Self::set_group_admin(program_id, accounts) - // } - // MangoInstruction::CancelAllPerpOrders { limit } => { - // msg!("Mango: CancelAllPerpOrders | limit={}", limit); - // Self::cancel_all_perp_orders(program_id, accounts, limit) - // } - // MangoInstruction::ForceSettleQuotePositions => { - // msg!("DEPRECATED Mango: ForceSettleQuotePositions"); - // Ok(()) - // } - // MangoInstruction::PlaceSpotOrder2 { order } => { - // msg!("Mango: PlaceSpotOrder2"); - // Self::place_spot_order2(program_id, accounts, order) - // } - // MangoInstruction::InitAdvancedOrders => { - // msg!("Mango: InitAdvancedOrders"); - // Self::init_advanced_orders(program_id, accounts) - // } - // MangoInstruction::CloseAdvancedOrders => { - // msg!("Mango: CloseAdvancedOrders"); - // Self::close_advanced_orders(program_id, accounts) - // } - // MangoInstruction::AddPerpTriggerOrder { - // order_type, - // side, - // trigger_condition, - // reduce_only, - // client_order_id, - // price, - // quantity, - // trigger_price, - // } => { - // msg!( - // "Mango: AddPerpTriggerOrder client_order_id={} type={:?} side={:?} trigger_condition={:?} price={} quantity={} trigger={}", - // client_order_id, - // order_type, - // side, - // trigger_condition, - // price, - // quantity, - // trigger_price.to_num::() - // ); - // Self::add_perp_trigger_order( - // program_id, - // accounts, - // order_type, - // side, - // trigger_condition, - // reduce_only, - // client_order_id, - // price, - // quantity, - // trigger_price, - // ) - // } - // MangoInstruction::RemoveAdvancedOrder { order_index } => { - // msg!("Mango: RemoveAdvancedOrder {}", order_index); - // Self::remove_advanced_order(program_id, accounts, order_index) - // } - // MangoInstruction::ExecutePerpTriggerOrder { order_index } => { - // msg!("Mango: ExecutePerpTriggerOrder {}", order_index); - // Self::execute_perp_trigger_order(program_id, accounts, order_index) - // } - // MangoInstruction::CreatePerpMarket { - // maint_leverage, - // init_leverage, - // liquidation_fee, - // maker_fee, - // taker_fee, - // base_lot_size, - // quote_lot_size, - // rate, - // max_depth_bps, - // target_period_length, - // mngo_per_period, - // exp, - // version, - // lm_size_shift, - // base_decimals, - // } => { - // msg!("Mango: CreatePerpMarket"); - // Self::create_perp_market( - // program_id, - // accounts, - // maint_leverage, - // init_leverage, - // liquidation_fee, - // maker_fee, - // taker_fee, - // base_lot_size, - // quote_lot_size, - // rate, - // max_depth_bps, - // target_period_length, - // mngo_per_period, - // exp, - // version, - // lm_size_shift, - // base_decimals, - // ) - // } - // MangoInstruction::ChangePerpMarketParams2 { - // maint_leverage, - // init_leverage, - // liquidation_fee, - // maker_fee, - // taker_fee, - // rate, - // max_depth_bps, - // target_period_length, - // mngo_per_period, - // exp, - // version, - // lm_size_shift, - // } => { - // msg!("Mango: ChangePerpMarketParams2"); - // Self::change_perp_market_params2( - // program_id, - // accounts, - // maint_leverage, - // init_leverage, - // liquidation_fee, - // maker_fee, - // taker_fee, - // rate, - // max_depth_bps, - // target_period_length, - // mngo_per_period, - // exp, - // version, - // lm_size_shift, - // ) - // } - // MangoInstruction::UpdateMarginBasket => { - // msg!("Mango: UpdateMarginBasket"); - // Self::update_margin_basket(program_id, accounts) - // } - // MangoInstruction::ChangeMaxMangoAccounts { max_mango_accounts } => { - // msg!("Mango: ChangeMaxMangoAccounts"); - // Self::change_max_mango_accounts(program_id, accounts, max_mango_accounts) - // } - // MangoInstruction::CreateDustAccount => { - // msg!("Mango: CreateDustAccount"); - // Self::create_dust_account(program_id, accounts) - // } - // MangoInstruction::ResolveDust => { - // msg!("Mango: ResolveDust"); - // Self::resolve_dust(program_id, accounts) - // } - // MangoInstruction::CancelPerpOrdersSide { side, limit } => { - // msg!("Mango: CancelSidePerpOrders"); - // Self::cancel_perp_orders_side(program_id, accounts, side, limit) - // } - // MangoInstruction::SetDelegate => { - // msg!("Mango: SetDelegate"); - // Self::set_delegate(program_id, accounts) - // } - // MangoInstruction::ChangeSpotMarketParams { - // maint_leverage, - // init_leverage, - // liquidation_fee, - // optimal_util, - // optimal_rate, - // max_rate, - // version, - // } => { - // msg!("Mango: ChangeSpotMarketParams"); - // Self::change_spot_market_params( - // program_id, - // accounts, - // maint_leverage, - // init_leverage, - // liquidation_fee, - // optimal_util, - // optimal_rate, - // max_rate, - // version, - // ) - // } - // MangoInstruction::CreateSpotOpenOrders => { - // msg!("Mango: CreateSpotOpenOrders"); - // Self::create_spot_open_orders(program_id, accounts) - // } - // MangoInstruction::ChangeReferralFeeParams { - // ref_surcharge_centibps, - // ref_share_centibps, - // ref_mngo_required, - // } => { - // msg!("Mango: ChangeReferralFeeParams"); - // Self::change_referral_fee_params( - // program_id, - // accounts, - // ref_surcharge_centibps, - // ref_share_centibps, - // ref_mngo_required, - // ) - // } - // MangoInstruction::SetReferrerMemory => { - // msg!("Mango: SetReferrerMemory"); - // Self::set_referrer_memory(program_id, accounts) - // } - // MangoInstruction::RegisterReferrerId { referrer_id } => { - // msg!("Mango: RegisterReferrerId"); - // Self::register_referrer_id(program_id, accounts, referrer_id) - // } - // MangoInstruction::PlacePerpOrder2 { - // side, - // price, - // max_base_quantity, - // max_quote_quantity, - // client_order_id, - // expiry_timestamp, - // order_type, - // reduce_only, - // limit, - // expiry_type, - // } => { - // msg!("Mango: PlacePerpOrder2 client_order_id={}", client_order_id); - // Self::place_perp_order2( - // program_id, - // accounts, - // side, - // price, - // max_base_quantity, - // max_quote_quantity, - // client_order_id, - // order_type, - // reduce_only, - // expiry_timestamp, - // limit, - // expiry_type, - // ) - // } - // MangoInstruction::CancelAllSpotOrders { limit } => { - // msg!("Mango: CancelAllSpotOrders"); - // Self::cancel_all_spot_orders(program_id, accounts, limit) - // } - // MangoInstruction::Withdraw2 { quantity, allow_borrow } => { - // msg!("Mango: Withdraw2"); - // Self::withdraw2(program_id, accounts, quantity, allow_borrow) - // } - // MangoInstruction::SetMarketMode { market_index, market_type, mode } => { - // msg!("Mango: SetMarketMode"); - // Self::set_market_mode(program_id, accounts, market_index, mode, market_type) - // } - // MangoInstruction::RemovePerpMarket => { - // msg!("Mango: RemovePerpMarket"); - // Self::remove_perp_market(program_id, accounts) - // } - // MangoInstruction::SwapSpotMarket => { - // msg!("Mango: SwapSpotMarket"); - // Self::swap_spot_market(program_id, accounts) - // } - // MangoInstruction::RemoveSpotMarket => { - // msg!("Mango: RemoveSpotMarket"); - // Self::remove_spot_market(program_id, accounts) - // } - // MangoInstruction::RemoveOracle => { - // msg!("Mango: RemoveOracle"); - // Self::remove_oracle(program_id, accounts) - // } - // MangoInstruction::LiquidateDelistingToken { max_liquidate_amount } => { - // msg!("Mango: LiquidateDelistingToken"); - // Self::liquidate_delisting_token(program_id, accounts, max_liquidate_amount) - // } - // MangoInstruction::ForceSettlePerpPosition => { - // msg!("Mango: ForceSettlePerpPosition"); - // Self::force_settle_perp_position(program_id, accounts) - // } - // MangoInstruction::ChangeReferralFeeParams2 { - // ref_surcharge_centibps_tier_1, - // ref_share_centibps_tier_1, - // ref_surcharge_centibps_tier_2, - // ref_share_centibps_tier_2, - // ref_mngo_required, - // ref_mngo_tier_2_factor, - // } => { - // msg!("Mango: ChangeReferralFeeParams2"); - // Self::change_referral_fee_params2( - // program_id, - // accounts, - // ref_surcharge_centibps_tier_1, - // ref_share_centibps_tier_1, - // ref_surcharge_centibps_tier_2, - // ref_share_centibps_tier_2, - // ref_mngo_required, - // ref_mngo_tier_2_factor, - // ) - // } - // } + let instruction = + MangoInstruction::unpack(data).ok_or(ProgramError::InvalidInstructionData)?; + match instruction { + // MangoInstruction::InitMangoGroup { + // signer_nonce, + // valid_interval, + // quote_optimal_util, + // quote_optimal_rate, + // quote_max_rate, + // } => { + // msg!("Mango: InitMangoGroup"); + // Self::init_mango_group( + // program_id, + // accounts, + // signer_nonce, + // valid_interval, + // quote_optimal_util, + // quote_optimal_rate, + // quote_max_rate, + // ) + // } + // MangoInstruction::InitMangoAccount => { + // msg!("Mango: InitMangoAccount DEPRECATED"); + // Self::init_mango_account(program_id, accounts) + // } + // MangoInstruction::CreateMangoAccount { account_num } => { + // msg!("Mango: CreateMangoAccount"); + // Self::create_mango_account(program_id, accounts, account_num) + // } + // MangoInstruction::CloseMangoAccount => { + // msg!("Mango: CloseMangoAccount"); + // Self::close_mango_account(program_id, accounts) + // } + // MangoInstruction::UpgradeMangoAccountV0V1 => { + // msg!("Mango: UpgradeMangoAccountV0V1"); + // Self::upgrade_mango_account_v0_v1(program_id, accounts) + // } + // MangoInstruction::Deposit { quantity } => { + // msg!("Mango: Deposit"); + // Self::deposit(program_id, accounts, quantity) + // } + // MangoInstruction::Withdraw { quantity, allow_borrow } => { + // msg!("Mango: Withdraw"); + // Self::withdraw(program_id, accounts, quantity, allow_borrow) + // } + // MangoInstruction::AddSpotMarket { + // maint_leverage, + // init_leverage, + // liquidation_fee, + // optimal_util, + // optimal_rate, + // max_rate, + // } => { + // msg!("Mango: AddSpotMarket"); + // Self::add_spot_market( + // program_id, + // accounts, + // maint_leverage, + // init_leverage, + // liquidation_fee, + // optimal_util, + // optimal_rate, + // max_rate, + // ) + // } + // MangoInstruction::AddToBasket { .. } => { + // msg!("Mango: AddToBasket Deprecated"); + // Ok(()) + // } + // MangoInstruction::Borrow { .. } => { + // msg!("Mango: Borrow DEPRECATED"); + // Ok(()) + // } + // MangoInstruction::CachePrices => { + // msg!("Mango: CachePrices"); + // Self::cache_prices(program_id, accounts) + // } + // MangoInstruction::CacheRootBanks => { + // msg!("Mango: CacheRootBanks"); + // Self::cache_root_banks(program_id, accounts) + // } + // MangoInstruction::PlaceSpotOrder { order } => { + // msg!("Mango: PlaceSpotOrder"); + // Self::place_spot_order(program_id, accounts, order) + // } + // MangoInstruction::CancelSpotOrder { order, .. } => { + // msg!("Mango: CancelSpotOrder"); + // let data = serum_dex::instruction::MarketInstruction::CancelOrderV2(order).pack(); + // Self::cancel_spot_order(program_id, accounts, data) + // } + // MangoInstruction::AddOracle => { + // msg!("Mango: AddOracle"); + // Self::add_oracle(program_id, accounts) + // } + // MangoInstruction::SettleFunds => { + // msg!("Mango: SettleFunds"); + // Self::settle_funds(program_id, accounts) + // } + // MangoInstruction::UpdateRootBank => { + // msg!("Mango: UpdateRootBank"); + // Self::update_root_bank(program_id, accounts) + // } + // MangoInstruction::AddPerpMarket { .. } => { + // msg!("DEPRECATED Mango: AddPerpMarket"); + // Ok(()) + // } + // MangoInstruction::PlacePerpOrder { + // side, + // price, + // quantity, + // client_order_id, + // order_type, + // reduce_only, + // } => { + // msg!("Mango: PlacePerpOrder client_order_id={}", client_order_id); + // Self::place_perp_order( + // program_id, + // accounts, + // side, + // price, + // quantity, + // client_order_id, + // order_type, + // reduce_only, + // ) + // } + // MangoInstruction::CancelPerpOrderByClientId { client_order_id, invalid_id_ok } => { + // msg!("Mango: CancelPerpOrderByClientId client_order_id={}", client_order_id); + // let result = + // Self::cancel_perp_order_by_client_id(program_id, accounts, client_order_id); + // if invalid_id_ok { + // if let Err(MangoError::MangoErrorCode { mango_error_code, .. }) = result { + // if mango_error_code == MangoErrorCode::InvalidOrderId + // || mango_error_code == MangoErrorCode::ClientIdNotFound + // { + // return Ok(()); + // } + // } + // } + // result + // } + // MangoInstruction::CancelPerpOrder { order_id, invalid_id_ok } => { + // // TODO OPT this log may cost too much compute + // msg!("Mango: CancelPerpOrder order_id={}", order_id); + // let result = Self::cancel_perp_order(program_id, accounts, order_id); + // if invalid_id_ok { + // if let Err(MangoError::MangoErrorCode { mango_error_code, .. }) = result { + // if mango_error_code == MangoErrorCode::InvalidOrderId { + // return Ok(()); + // } + // } + // } + // result + // } + // MangoInstruction::ConsumeEvents { limit } => { + // msg!("Mango: ConsumeEvents limit={}", limit); + // Self::consume_events(program_id, accounts, limit) + // } + // MangoInstruction::CachePerpMarkets => { + // msg!("Mango: CachePerpMarkets"); + // Self::cache_perp_markets(program_id, accounts) + // } + // MangoInstruction::UpdateFunding => { + // msg!("Mango: UpdateFunding"); + // Self::update_funding(program_id, accounts) + // } + // MangoInstruction::SetOracle { price } => { + // // msg!("Mango: SetOracle {:?}", price); + // msg!("Mango: SetOracle"); + // Self::set_oracle(program_id, accounts, price) + // } + // MangoInstruction::SettlePnl { market_index } => { + // msg!("Mango: SettlePnl"); + // Self::settle_pnl(program_id, accounts, market_index) + // } + // MangoInstruction::SettleBorrow { .. } => { + // msg!("Mango: SettleBorrow DEPRECATED"); + // Ok(()) + // } + // MangoInstruction::ForceCancelSpotOrders { limit } => { + // msg!("Mango: ForceCancelSpotOrders"); + // Self::force_cancel_spot_orders(program_id, accounts, limit) + // } + // MangoInstruction::ForceCancelPerpOrders { limit } => { + // msg!("Mango: ForceCancelPerpOrders"); + // Self::force_cancel_perp_orders(program_id, accounts, limit) + // } + // MangoInstruction::LiquidateTokenAndToken { max_liab_transfer } => { + // msg!("Mango: LiquidateTokenAndToken"); + // Self::liquidate_token_and_token(program_id, accounts, max_liab_transfer) + // } + // MangoInstruction::LiquidateTokenAndPerp { + // asset_type, + // asset_index, + // liab_type, + // liab_index, + // max_liab_transfer, + // } => { + // msg!("Mango: LiquidateTokenAndPerp"); + // Self::liquidate_token_and_perp( + // program_id, + // accounts, + // asset_type, + // asset_index, + // liab_type, + // liab_index, + // max_liab_transfer, + // ) + // } + // MangoInstruction::LiquidatePerpMarket { base_transfer_request } => { + // msg!("Mango: LiquidatePerpMarket"); + // Self::liquidate_perp_market(program_id, accounts, base_transfer_request) + // } + // MangoInstruction::SettleFees => { + // msg!("Mango: SettleFees"); + // Self::settle_fees(program_id, accounts) + // } + // MangoInstruction::ResolvePerpBankruptcy { liab_index, max_liab_transfer } => { + // msg!("Mango: ResolvePerpBankruptcy"); + // Self::resolve_perp_bankruptcy(program_id, accounts, liab_index, max_liab_transfer) + // } + // MangoInstruction::ResolveTokenBankruptcy { max_liab_transfer } => { + // msg!("Mango: ResolveTokenBankruptcy"); + // Self::resolve_token_bankruptcy(program_id, accounts, max_liab_transfer) + // } + // MangoInstruction::InitSpotOpenOrders => { + // msg!("Mango: InitSpotOpenOrders"); + // Self::init_spot_open_orders(program_id, accounts) + // } + // MangoInstruction::CloseSpotOpenOrders => { + // msg!("Mango: CloseSpotOpenOrders"); + // Self::close_spot_open_orders(program_id, accounts) + // } + // MangoInstruction::RedeemMngo => { + // msg!("Mango: RedeemMngo"); + // Self::redeem_mngo(program_id, accounts) + // } + // MangoInstruction::AddMangoAccountInfo { info } => { + // msg!("Mango: AddMangoAccountInfo"); + // Self::add_mango_account_info(program_id, accounts, info) + // } + // MangoInstruction::DepositMsrm { quantity } => { + // msg!("Mango: DepositMsrm"); + // Self::deposit_msrm(program_id, accounts, quantity) + // } + MangoInstruction::WithdrawMsrm { quantity } => { + msg!("Mango: WithdrawMsrm"); + Self::withdraw_msrm(program_id, accounts, quantity) + } + // MangoInstruction::ChangePerpMarketParams { .. } => { + // msg!("Mango: ChangePerpMarketParams DEPRECATED - use ChangePerpMarketParams2 instead"); + // Ok(()) + // } + // MangoInstruction::SetGroupAdmin => { + // msg!("Mango: SetGroupAdmin"); + // Self::set_group_admin(program_id, accounts) + // } + // MangoInstruction::CancelAllPerpOrders { limit } => { + // msg!("Mango: CancelAllPerpOrders | limit={}", limit); + // Self::cancel_all_perp_orders(program_id, accounts, limit) + // } + // MangoInstruction::ForceSettleQuotePositions => { + // msg!("DEPRECATED Mango: ForceSettleQuotePositions"); + // Ok(()) + // } + // MangoInstruction::PlaceSpotOrder2 { order } => { + // msg!("Mango: PlaceSpotOrder2"); + // Self::place_spot_order2(program_id, accounts, order) + // } + // MangoInstruction::InitAdvancedOrders => { + // msg!("Mango: InitAdvancedOrders"); + // Self::init_advanced_orders(program_id, accounts) + // } + // MangoInstruction::CloseAdvancedOrders => { + // msg!("Mango: CloseAdvancedOrders"); + // Self::close_advanced_orders(program_id, accounts) + // } + // MangoInstruction::AddPerpTriggerOrder { + // order_type, + // side, + // trigger_condition, + // reduce_only, + // client_order_id, + // price, + // quantity, + // trigger_price, + // } => { + // msg!( + // "Mango: AddPerpTriggerOrder client_order_id={} type={:?} side={:?} trigger_condition={:?} price={} quantity={} trigger={}", + // client_order_id, + // order_type, + // side, + // trigger_condition, + // price, + // quantity, + // trigger_price.to_num::() + // ); + // Self::add_perp_trigger_order( + // program_id, + // accounts, + // order_type, + // side, + // trigger_condition, + // reduce_only, + // client_order_id, + // price, + // quantity, + // trigger_price, + // ) + // } + // MangoInstruction::RemoveAdvancedOrder { order_index } => { + // msg!("Mango: RemoveAdvancedOrder {}", order_index); + // Self::remove_advanced_order(program_id, accounts, order_index) + // } + // MangoInstruction::ExecutePerpTriggerOrder { order_index } => { + // msg!("Mango: ExecutePerpTriggerOrder {}", order_index); + // Self::execute_perp_trigger_order(program_id, accounts, order_index) + // } + // MangoInstruction::CreatePerpMarket { + // maint_leverage, + // init_leverage, + // liquidation_fee, + // maker_fee, + // taker_fee, + // base_lot_size, + // quote_lot_size, + // rate, + // max_depth_bps, + // target_period_length, + // mngo_per_period, + // exp, + // version, + // lm_size_shift, + // base_decimals, + // } => { + // msg!("Mango: CreatePerpMarket"); + // Self::create_perp_market( + // program_id, + // accounts, + // maint_leverage, + // init_leverage, + // liquidation_fee, + // maker_fee, + // taker_fee, + // base_lot_size, + // quote_lot_size, + // rate, + // max_depth_bps, + // target_period_length, + // mngo_per_period, + // exp, + // version, + // lm_size_shift, + // base_decimals, + // ) + // } + // MangoInstruction::ChangePerpMarketParams2 { + // maint_leverage, + // init_leverage, + // liquidation_fee, + // maker_fee, + // taker_fee, + // rate, + // max_depth_bps, + // target_period_length, + // mngo_per_period, + // exp, + // version, + // lm_size_shift, + // } => { + // msg!("Mango: ChangePerpMarketParams2"); + // Self::change_perp_market_params2( + // program_id, + // accounts, + // maint_leverage, + // init_leverage, + // liquidation_fee, + // maker_fee, + // taker_fee, + // rate, + // max_depth_bps, + // target_period_length, + // mngo_per_period, + // exp, + // version, + // lm_size_shift, + // ) + // } + // MangoInstruction::UpdateMarginBasket => { + // msg!("Mango: UpdateMarginBasket"); + // Self::update_margin_basket(program_id, accounts) + // } + // MangoInstruction::ChangeMaxMangoAccounts { max_mango_accounts } => { + // msg!("Mango: ChangeMaxMangoAccounts"); + // Self::change_max_mango_accounts(program_id, accounts, max_mango_accounts) + // } + // MangoInstruction::CreateDustAccount => { + // msg!("Mango: CreateDustAccount"); + // Self::create_dust_account(program_id, accounts) + // } + // MangoInstruction::ResolveDust => { + // msg!("Mango: ResolveDust"); + // Self::resolve_dust(program_id, accounts) + // } + // MangoInstruction::CancelPerpOrdersSide { side, limit } => { + // msg!("Mango: CancelSidePerpOrders"); + // Self::cancel_perp_orders_side(program_id, accounts, side, limit) + // } + // MangoInstruction::SetDelegate => { + // msg!("Mango: SetDelegate"); + // Self::set_delegate(program_id, accounts) + // } + // MangoInstruction::ChangeSpotMarketParams { + // maint_leverage, + // init_leverage, + // liquidation_fee, + // optimal_util, + // optimal_rate, + // max_rate, + // version, + // } => { + // msg!("Mango: ChangeSpotMarketParams"); + // Self::change_spot_market_params( + // program_id, + // accounts, + // maint_leverage, + // init_leverage, + // liquidation_fee, + // optimal_util, + // optimal_rate, + // max_rate, + // version, + // ) + // } + // MangoInstruction::CreateSpotOpenOrders => { + // msg!("Mango: CreateSpotOpenOrders"); + // Self::create_spot_open_orders(program_id, accounts) + // } + // MangoInstruction::ChangeReferralFeeParams { + // ref_surcharge_centibps, + // ref_share_centibps, + // ref_mngo_required, + // } => { + // msg!("Mango: ChangeReferralFeeParams"); + // Self::change_referral_fee_params( + // program_id, + // accounts, + // ref_surcharge_centibps, + // ref_share_centibps, + // ref_mngo_required, + // ) + // } + // MangoInstruction::SetReferrerMemory => { + // msg!("Mango: SetReferrerMemory"); + // Self::set_referrer_memory(program_id, accounts) + // } + // MangoInstruction::RegisterReferrerId { referrer_id } => { + // msg!("Mango: RegisterReferrerId"); + // Self::register_referrer_id(program_id, accounts, referrer_id) + // } + // MangoInstruction::PlacePerpOrder2 { + // side, + // price, + // max_base_quantity, + // max_quote_quantity, + // client_order_id, + // expiry_timestamp, + // order_type, + // reduce_only, + // limit, + // expiry_type, + // } => { + // msg!("Mango: PlacePerpOrder2 client_order_id={}", client_order_id); + // Self::place_perp_order2( + // program_id, + // accounts, + // side, + // price, + // max_base_quantity, + // max_quote_quantity, + // client_order_id, + // order_type, + // reduce_only, + // expiry_timestamp, + // limit, + // expiry_type, + // ) + // } + // MangoInstruction::CancelAllSpotOrders { limit } => { + // msg!("Mango: CancelAllSpotOrders"); + // Self::cancel_all_spot_orders(program_id, accounts, limit) + // } + // MangoInstruction::Withdraw2 { quantity, allow_borrow } => { + // msg!("Mango: Withdraw2"); + // Self::withdraw2(program_id, accounts, quantity, allow_borrow) + // } + // MangoInstruction::SetMarketMode { market_index, market_type, mode } => { + // msg!("Mango: SetMarketMode"); + // Self::set_market_mode(program_id, accounts, market_index, mode, market_type) + // } + // MangoInstruction::RemovePerpMarket => { + // msg!("Mango: RemovePerpMarket"); + // Self::remove_perp_market(program_id, accounts) + // } + // MangoInstruction::SwapSpotMarket => { + // msg!("Mango: SwapSpotMarket"); + // Self::swap_spot_market(program_id, accounts) + // } + // MangoInstruction::RemoveSpotMarket => { + // msg!("Mango: RemoveSpotMarket"); + // Self::remove_spot_market(program_id, accounts) + // } + // MangoInstruction::RemoveOracle => { + // msg!("Mango: RemoveOracle"); + // Self::remove_oracle(program_id, accounts) + // } + // MangoInstruction::LiquidateDelistingToken { max_liquidate_amount } => { + // msg!("Mango: LiquidateDelistingToken"); + // Self::liquidate_delisting_token(program_id, accounts, max_liquidate_amount) + // } + // MangoInstruction::ForceSettlePerpPosition => { + // msg!("Mango: ForceSettlePerpPosition"); + // Self::force_settle_perp_position(program_id, accounts) + // } + // MangoInstruction::ChangeReferralFeeParams2 { + // ref_surcharge_centibps_tier_1, + // ref_share_centibps_tier_1, + // ref_surcharge_centibps_tier_2, + // ref_share_centibps_tier_2, + // ref_mngo_required, + // ref_mngo_tier_2_factor, + // } => { + // msg!("Mango: ChangeReferralFeeParams2"); + // Self::change_referral_fee_params2( + // program_id, + // accounts, + // ref_surcharge_centibps_tier_1, + // ref_share_centibps_tier_1, + // ref_surcharge_centibps_tier_2, + // ref_share_centibps_tier_2, + // ref_mngo_required, + // ref_mngo_tier_2_factor, + // ) + // } + // } + MangoInstruction::RecoveryWithdrawTokenVault => { + msg!("Mango: RecoveryWithdrawTokenVault"); + Self::recovery_withdraw_token_vault(program_id, accounts) + } + MangoInstruction::RecoveryWithdrawMngoVault => { + msg!("Mango: RecoveryWithdrawMngoVault"); + Self::recovery_withdraw_mngo_vault(program_id, accounts) + } + MangoInstruction::RecoveryWithdrawInsuranceVault => { + msg!("Mango: RecoveryWithdrawInsuranceVault"); + Self::recovery_withdraw_insurance_vault(program_id, accounts) + } + MangoInstruction::RecoveryForceSettleSpotOrders { limit } => { + msg!("Mango: RecoveryForceSettleOrders"); + Self::recovery_force_settle_spot_orders(program_id, accounts, limit) + } + _ => Err(throw!()), + } } }