Fix margin_trade instruction call

This commit is contained in:
Christian Kamm 2022-03-07 15:43:29 +01:00
parent cea0f9441a
commit 2d65078c23
2 changed files with 40 additions and 37 deletions

View File

@ -105,8 +105,6 @@ pub struct MangoAccount {
// Alternative authority/signer of transactions for a mango account // Alternative authority/signer of transactions for a mango account
pub delegate: Pubkey, pub delegate: Pubkey,
pub address_lookup_table: Pubkey,
// pub in_margin_basket: [bool; MAX_PAIRS], // pub in_margin_basket: [bool; MAX_PAIRS],
// pub num_in_margin_basket: u8, // pub num_in_margin_basket: u8,
// TODO: this should be a separate struct for convenient use, like MangoGroup::tokens // TODO: this should be a separate struct for convenient use, like MangoGroup::tokens

View File

@ -82,7 +82,8 @@ async fn get_mint_info(
async fn derive_health_check_remaining_account_metas( async fn derive_health_check_remaining_account_metas(
account_loader: &impl ClientAccountLoader, account_loader: &impl ClientAccountLoader,
account: &MangoAccount, account: &MangoAccount,
affected_bank: Pubkey, affected_bank: Option<Pubkey>,
writable_banks: bool,
) -> Vec<AccountMeta> { ) -> Vec<AccountMeta> {
let group: MangoGroup = account_loader.load(&account.group).await.unwrap(); let group: MangoGroup = account_loader.load(&account.group).await.unwrap();
@ -100,28 +101,34 @@ async fn derive_health_check_remaining_account_metas(
banks.push(addresses[mint_info.address_lookup_table_bank_index as usize]); banks.push(addresses[mint_info.address_lookup_table_bank_index as usize]);
oracles.push(addresses[mint_info.address_lookup_table_oracle_index as usize]); oracles.push(addresses[mint_info.address_lookup_table_oracle_index as usize]);
} }
if banks.iter().find(|&&v| v == affected_bank).is_none() { if let Some(affected_bank) = affected_bank {
// If there is not yet an active position for the token, we need to pass if banks.iter().find(|&&v| v == affected_bank).is_none() {
// the bank/oracle for health check anyway. // If there is not yet an active position for the token, we need to pass
let new_position = account // the bank/oracle for health check anyway.
.indexed_positions let new_position = account
.values .indexed_positions
.iter() .values
.position(|p| !p.is_active()) .iter()
.unwrap(); .position(|p| !p.is_active())
banks.insert(new_position, affected_bank); .unwrap();
let affected_bank: TokenBank = account_loader.load(&affected_bank).await.unwrap(); banks.insert(new_position, affected_bank);
oracles.insert(new_position, affected_bank.oracle); let affected_bank: TokenBank = account_loader.load(&affected_bank).await.unwrap();
oracles.insert(new_position, affected_bank.oracle);
}
} }
banks banks
.iter() .iter()
.chain(oracles.iter())
.map(|&pubkey| AccountMeta { .map(|&pubkey| AccountMeta {
pubkey,
is_writable: writable_banks,
is_signer: false,
})
.chain(oracles.iter().map(|&pubkey| AccountMeta {
pubkey, pubkey,
is_writable: false, is_writable: false,
is_signer: false, is_signer: false,
}) }))
.collect() .collect()
} }
@ -154,10 +161,6 @@ impl<'keypair> ClientInstruction for MarginTradeInstruction<'keypair> {
}; };
let account: MangoAccount = account_loader.load(&self.account).await.unwrap(); let account: MangoAccount = account_loader.load(&self.account).await.unwrap();
let lookup_table = account_loader
.load_bytes(&account.address_lookup_table)
.await
.unwrap();
let accounts = Self::Accounts { let accounts = Self::Accounts {
group: account.group, group: account.group,
@ -165,20 +168,12 @@ impl<'keypair> ClientInstruction for MarginTradeInstruction<'keypair> {
owner: self.owner.pubkey(), owner: self.owner.pubkey(),
}; };
let banks_and_oracles = mango_v4::address_lookup_table::addresses(&lookup_table); let health_check_metas =
derive_health_check_remaining_account_metas(&account_loader, &account, None, true)
.await;
let mut instruction = make_instruction(program_id, &accounts, instruction); let mut instruction = make_instruction(program_id, &accounts, instruction);
instruction.accounts.push(AccountMeta { instruction.accounts.extend(health_check_metas.into_iter());
pubkey: banks_and_oracles[0],
// since user doesnt return all loan after margin trade, we want to mark withdrawal from the bank
is_writable: true,
is_signer: false,
});
instruction.accounts.push(AccountMeta {
pubkey: banks_and_oracles[1],
is_writable: false,
is_signer: false,
});
instruction.accounts.push(AccountMeta { instruction.accounts.push(AccountMeta {
pubkey: self.margin_trade_program_id, pubkey: self.margin_trade_program_id,
is_writable: false, is_writable: false,
@ -258,8 +253,13 @@ impl<'keypair> ClientInstruction for WithdrawInstruction<'keypair> {
) )
.0; .0;
let health_check_metas = let health_check_metas = derive_health_check_remaining_account_metas(
derive_health_check_remaining_account_metas(&account_loader, &account, bank).await; &account_loader,
&account,
Some(bank),
false,
)
.await;
let accounts = Self::Accounts { let accounts = Self::Accounts {
group: account.group, group: account.group,
@ -325,8 +325,13 @@ impl<'keypair> ClientInstruction for DepositInstruction<'keypair> {
) )
.0; .0;
let health_check_metas = let health_check_metas = derive_health_check_remaining_account_metas(
derive_health_check_remaining_account_metas(&account_loader, &account, bank).await; &account_loader,
&account,
Some(bank),
false,
)
.await;
let accounts = Self::Accounts { let accounts = Self::Accounts {
group: account.group, group: account.group,