Added token program id to partial liquidate instruction
This commit is contained in:
parent
e2bde96d1c
commit
81ab0f7680
|
@ -5,16 +5,14 @@ use std::mem::size_of;
|
|||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use arrayref::array_ref;
|
||||
use clap::Clap;
|
||||
use common::{Cluster, convert_assertion_error, create_account_rent_exempt, create_signer_key_and_nonce, create_token_account, read_keypair_file, send_instructions};
|
||||
use fixed::types::U64F64;
|
||||
use mango::processor::get_prices;
|
||||
use mango::state::{Loadable, MangoGroup, MarginAccount, NUM_MARKETS, NUM_TOKENS};
|
||||
use mango::state::{Loadable, MangoGroup, MarginAccount, NUM_TOKENS};
|
||||
use serde_json::{json, Value};
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_client::rpc_request::TokenAccountsFilter;
|
||||
use solana_sdk::account::{Account, create_account_infos};
|
||||
use solana_sdk::account::{Account};
|
||||
use solana_sdk::commitment_config::CommitmentConfig;
|
||||
use solana_sdk::program_pack::Pack;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
@ -127,15 +125,6 @@ pub enum Command {
|
|||
CancelOrder {
|
||||
|
||||
},
|
||||
PrintMarginAccountInfo {
|
||||
#[clap(long, short)]
|
||||
ids_path: String,
|
||||
#[clap(long)]
|
||||
mango_group_name: String,
|
||||
#[clap(long)]
|
||||
margin_account: String
|
||||
},
|
||||
|
||||
ChangeBorrowLimit {
|
||||
#[clap(long, short)]
|
||||
payer: String, // assumes for now payer is same as admin
|
||||
|
@ -157,7 +146,7 @@ impl Opts {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[allow(unused)]
|
||||
fn get_accounts(client: &RpcClient, pks: &[Pubkey]) -> Vec<(Pubkey, Account)> {
|
||||
client.get_multiple_accounts(pks)
|
||||
.unwrap()
|
||||
|
@ -602,60 +591,6 @@ pub fn start(opts: Opts) -> Result<()> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Command::PrintMarginAccountInfo {
|
||||
ids_path,
|
||||
mango_group_name,
|
||||
margin_account
|
||||
} => {
|
||||
println!("PrintMarginAccountInfo");
|
||||
let ids: Value = serde_json::from_reader(File::open(&ids_path)?)?;
|
||||
let cluster_name = opts.cluster.name();
|
||||
let cluster_ids = &ids[cluster_name];
|
||||
let cids = ClusterIds::load(cluster_ids);
|
||||
let margin_account_pk = Pubkey::from_str(margin_account.as_str())?;
|
||||
let margin_account = client.get_account(&margin_account_pk)?;
|
||||
let margin_account = MarginAccount::load_from_bytes(margin_account.data.as_slice())?;
|
||||
|
||||
let mgids = &cids.mango_groups[&mango_group_name];
|
||||
let mango_group_acc = client.get_account(&mgids.mango_group_pk)?;
|
||||
let mango_group = MangoGroup::load_from_bytes(mango_group_acc.data.as_slice())?;
|
||||
let tokens: Vec<&str> = mango_group_name.split("_").collect();
|
||||
|
||||
|
||||
let mut oracle_accs = get_accounts(&client, &mgids.oracle_pks);
|
||||
let oracle_accs = create_account_infos(oracle_accs.as_mut_slice());
|
||||
let oracle_accs = array_ref![oracle_accs.as_slice(), 0, NUM_MARKETS];
|
||||
|
||||
let mut open_orders_accs = get_accounts(&client, &margin_account.open_orders);
|
||||
let open_orders_accs = create_account_infos(open_orders_accs.as_mut_slice());
|
||||
let open_orders_accs = array_ref![open_orders_accs.as_slice(), 0, NUM_MARKETS];
|
||||
|
||||
let prices = get_prices(mango_group, oracle_accs)?;
|
||||
|
||||
let equity = margin_account.get_equity(mango_group, &prices, open_orders_accs)?;
|
||||
println!("MarginAccount: {} | equity: {}", margin_account_pk, equity);
|
||||
println!("deposits");
|
||||
for i in 0..NUM_TOKENS {
|
||||
println!("{} {}", tokens[i], margin_account.deposits[i] * mango_group.indexes[i].deposit);
|
||||
}
|
||||
|
||||
// println!("positions");
|
||||
// for i in 0..NUM_TOKENS {
|
||||
// println!("{} {}", tokens[i], margin_account.positions[i]);
|
||||
// }
|
||||
|
||||
println!("borrows");
|
||||
for i in 0..NUM_TOKENS {
|
||||
println!("{} {}", tokens[i], margin_account.borrows[i] * mango_group.indexes[i].borrow);
|
||||
}
|
||||
|
||||
// total value in quote currency
|
||||
// deposits
|
||||
// positions
|
||||
// borrows
|
||||
// val in open orders
|
||||
}
|
||||
Command::SettleBorrow {
|
||||
payer,
|
||||
ids_path,
|
||||
|
|
|
@ -265,7 +265,7 @@ pub fn send_txn(client: &RpcClient, txn: &Transaction, _simulate: bool) -> Resul
|
|||
// }
|
||||
//
|
||||
// )?)
|
||||
|
||||
client.get
|
||||
let txid = client.send_transaction_with_config(txn, RpcSendTransactionConfig {
|
||||
skip_preflight: true,
|
||||
..RpcSendTransactionConfig::default()
|
||||
|
@ -404,6 +404,7 @@ pub fn send_instructions(
|
|||
payer_pk: &Pubkey
|
||||
) -> Result<()> {
|
||||
let (recent_hash, _fee_calc) = client.get_recent_blockhash()?;
|
||||
|
||||
let txn = Transaction::new_signed_with_payer(
|
||||
&instructions,
|
||||
Some(payer_pk),
|
||||
|
|
|
@ -329,7 +329,7 @@ pub enum MangoInstruction {
|
|||
|
||||
/// Take over a MarginAccount that is below init_coll_ratio by depositing funds
|
||||
///
|
||||
/// Accounts expected by this instruction (9 + 2 * NUM_MARKETS):
|
||||
/// Accounts expected by this instruction (10 + 2 * NUM_MARKETS):
|
||||
///
|
||||
/// 0. `[writable]` mango_group_acc - MangoGroup that this margin account is for
|
||||
/// 1. `[signer]` liqor_acc - liquidator's solana account
|
||||
|
@ -339,9 +339,10 @@ pub enum MangoInstruction {
|
|||
/// 5. `[writable]` in_vault_acc - Mango vault of in_token
|
||||
/// 6. `[writable]` out_vault_acc - Mango vault of out_token
|
||||
/// 7. `[]` signer_acc
|
||||
/// 8. `[]` clock_acc - Clock sysvar account
|
||||
/// 9..9+NUM_MARKETS `[]` open_orders_accs - open orders for each of the spot market
|
||||
/// 9+NUM_MARKETS..9+2*NUM_MARKETS `[]`
|
||||
/// 8. `[]` token_prog_acc - Token program id
|
||||
/// 9. `[]` clock_acc - Clock sysvar account
|
||||
/// 10..10+NUM_MARKETS `[]` open_orders_accs - open orders for each of the spot market
|
||||
/// 10+NUM_MARKETS..10+2*NUM_MARKETS `[]`
|
||||
/// oracle_accs - flux aggregator feed accounts
|
||||
PartialLiquidate {
|
||||
/// Quantity of the token being deposited to repay borrows
|
||||
|
@ -1174,6 +1175,7 @@ pub fn partial_liquidate(
|
|||
AccountMeta::new(*in_vault_pk, false),
|
||||
AccountMeta::new(*out_vault_pk, false),
|
||||
AccountMeta::new_readonly(*signer_pk, false),
|
||||
AccountMeta::new_readonly(spl_token::ID, false),
|
||||
AccountMeta::new_readonly(solana_program::sysvar::clock::ID, false),
|
||||
];
|
||||
|
||||
|
|
|
@ -1250,13 +1250,11 @@ impl Processor {
|
|||
mango_group.update_indexes(&clock)?;
|
||||
let prices = get_prices(&mango_group, oracle_accs)?;
|
||||
let coll_ratio = liqee_margin_account.get_collateral_ratio(
|
||||
&mango_group, &prices, open_orders_accs
|
||||
)?;
|
||||
&mango_group, &prices, open_orders_accs)?;
|
||||
|
||||
// Only allow liquidations on accounts already being liquidated and below init or accounts below maint
|
||||
if liqee_margin_account.being_liquidated {
|
||||
if coll_ratio >= mango_group.init_coll_ratio {
|
||||
// TODO do same check in place_and_settle
|
||||
liqee_margin_account.being_liquidated = false;
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -1267,7 +1265,7 @@ impl Processor {
|
|||
let signers_seeds = gen_signer_seeds(&mango_group.signer_nonce, mango_group_acc.key);
|
||||
|
||||
invoke_cancel_orders(open_orders_acc, dex_prog_acc, spot_market_acc, bids_acc, asks_acc, signer_acc,
|
||||
dex_event_queue_acc, &[&signers_seeds], 5)?;
|
||||
dex_event_queue_acc, &[&signers_seeds], 10)?;
|
||||
|
||||
let (pre_base, pre_quote) = {
|
||||
let open_orders = load_open_orders(open_orders_acc)?;
|
||||
|
@ -1305,7 +1303,7 @@ impl Processor {
|
|||
max_deposit: u64
|
||||
) -> MangoResult<()> {
|
||||
|
||||
const NUM_FIXED: usize = 9;
|
||||
const NUM_FIXED: usize = 10;
|
||||
// TODO make it so canceling orders feature is optional if no orders outstanding to cancel
|
||||
let accounts = array_ref![accounts, 0, NUM_FIXED + 2 * NUM_MARKETS];
|
||||
let (
|
||||
|
@ -1323,9 +1321,10 @@ impl Processor {
|
|||
in_vault_acc,
|
||||
out_vault_acc,
|
||||
signer_acc,
|
||||
token_prog_acc,
|
||||
clock_acc,
|
||||
] = fixed_accs;
|
||||
|
||||
check!(token_prog_acc.key == &spl_token::ID, MangoErrorCode::InvalidProgramId)?;
|
||||
check!(liqor_acc.is_signer, MangoErrorCode::SignerNecessary)?;
|
||||
let mut mango_group = MangoGroup::load_mut_checked(
|
||||
mango_group_acc, program_id
|
||||
|
@ -1421,7 +1420,7 @@ impl Processor {
|
|||
// Pull funds from liqor
|
||||
let signer_nonce = mango_group.signer_nonce;
|
||||
let signers_seeds = gen_signer_seeds(&signer_nonce, mango_group_acc.key);
|
||||
invoke_transfer(liqor_in_token_acc, in_vault_acc, liqor_acc,
|
||||
invoke_transfer(token_prog_acc, liqor_in_token_acc, in_vault_acc, liqor_acc,
|
||||
&[&signers_seeds], in_quantity)?;
|
||||
let deposit: U64F64 = U64F64::from_num(in_quantity) / mango_group.indexes[in_token_index].borrow;
|
||||
checked_sub_borrow(&mut mango_group, &mut liqee_margin_account, in_token_index, deposit)?;
|
||||
|
@ -1430,7 +1429,7 @@ impl Processor {
|
|||
let in_val: U64F64 = U64F64::from_num(in_quantity) * prices[in_token_index];
|
||||
let out_val: U64F64 = in_val * PARTIAL_LIQ_INCENTIVE;
|
||||
let out_quantity: u64 = (out_val / prices[out_token_index]).checked_floor().unwrap().to_num();
|
||||
invoke_transfer(out_vault_acc, liqor_out_token_acc, signer_acc,
|
||||
invoke_transfer(token_prog_acc, out_vault_acc, liqor_out_token_acc, signer_acc,
|
||||
&[&signers_seeds], out_quantity)?;
|
||||
|
||||
let withdraw = U64F64::from_num(out_quantity) / mango_group.indexes[out_token_index].deposit;
|
||||
|
@ -1908,6 +1907,7 @@ fn invoke_cancel_orders<'a>(
|
|||
}
|
||||
|
||||
fn invoke_transfer<'a>(
|
||||
token_prog_acc: &AccountInfo<'a>,
|
||||
source_acc: &AccountInfo<'a>,
|
||||
dest_acc: &AccountInfo<'a>,
|
||||
authority_acc: &AccountInfo<'a>,
|
||||
|
@ -1924,6 +1924,7 @@ fn invoke_transfer<'a>(
|
|||
quantity
|
||||
)?;
|
||||
let accs = [
|
||||
token_prog_acc.clone(),
|
||||
source_acc.clone(),
|
||||
dest_acc.clone(),
|
||||
authority_acc.clone()
|
||||
|
|
Loading…
Reference in New Issue