remove account size, make mango account feature position counts explicit (#148)
* remove account size from program, make position counts explicit Signed-off-by: microwavedcola1 <microwavedcola@gmail.com> * cargo-fix Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
ff19940ee7
commit
e06736660a
|
@ -15,7 +15,7 @@ use bincode::Options;
|
|||
use fixed::types::I80F48;
|
||||
use itertools::Itertools;
|
||||
use mango_v4::instructions::{Serum3OrderType, Serum3SelfTradeBehavior, Serum3Side};
|
||||
use mango_v4::state::{AccountSize, Bank, Group, MangoAccountValue, Serum3MarketIndex, TokenIndex};
|
||||
use mango_v4::state::{Bank, Group, MangoAccountValue, Serum3MarketIndex, TokenIndex};
|
||||
|
||||
use solana_client::nonblocking::rpc_client::RpcClient as RpcClientAsync;
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
|
@ -206,7 +206,10 @@ impl MangoClient {
|
|||
data: anchor_lang::InstructionData::data(&mango_v4::instruction::AccountCreate {
|
||||
account_num,
|
||||
name: mango_account_name.to_owned(),
|
||||
account_size: AccountSize::Small,
|
||||
token_count: 8,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
}),
|
||||
})
|
||||
.signer(owner)
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::state::*;
|
|||
use crate::util::fill32_from_str;
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(account_num: u32, account_size: AccountSize)]
|
||||
#[instruction(account_num: u32, token_count: u8, serum3_count: u8, perp_count: u8, perp_oo_count: u8)]
|
||||
pub struct AccountCreate<'info> {
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
|
||||
|
@ -14,7 +14,7 @@ pub struct AccountCreate<'info> {
|
|||
seeds = [group.key().as_ref(), b"MangoAccount".as_ref(), owner.key().as_ref(), &account_num.to_le_bytes()],
|
||||
bump,
|
||||
payer = payer,
|
||||
space = MangoAccount::space(account_size),
|
||||
space = MangoAccount::space(token_count, serum3_count, perp_count, perp_oo_count)?,
|
||||
)]
|
||||
pub account: AccountLoaderDynamic<'info, MangoAccount>,
|
||||
pub owner: Signer<'info>,
|
||||
|
@ -28,7 +28,10 @@ pub struct AccountCreate<'info> {
|
|||
pub fn account_create(
|
||||
ctx: Context<AccountCreate>,
|
||||
account_num: u32,
|
||||
account_size: AccountSize,
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
perp_count: u8,
|
||||
perp_oo_count: u8,
|
||||
name: String,
|
||||
) -> Result<()> {
|
||||
let mut account = ctx.accounts.account.load_init()?;
|
||||
|
@ -47,7 +50,7 @@ pub fn account_create(
|
|||
account.fixed.set_being_liquidated(false);
|
||||
account.fixed.set_bankrupt(false);
|
||||
|
||||
account.expand_dynamic_content(account_size)?;
|
||||
account.expand_dynamic_content(token_count, serum3_count, perp_count, perp_oo_count)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -20,15 +20,14 @@ pub struct AccountExpand<'info> {
|
|||
pub system_program: Program<'info, System>,
|
||||
}
|
||||
|
||||
pub fn account_expand(ctx: Context<AccountExpand>) -> Result<()> {
|
||||
let account_size = {
|
||||
let account = ctx.accounts.account.load()?;
|
||||
account.size()
|
||||
};
|
||||
|
||||
require_eq!(account_size, AccountSize::Small);
|
||||
|
||||
let new_space = MangoAccount::space(AccountSize::Large);
|
||||
pub fn account_expand(
|
||||
ctx: Context<AccountExpand>,
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
perp_count: u8,
|
||||
perp_oo_count: u8,
|
||||
) -> Result<()> {
|
||||
let new_space = MangoAccount::space(token_count, serum3_count, perp_count, perp_oo_count)?;
|
||||
let new_rent_minimum = Rent::get()?.minimum_balance(new_space);
|
||||
|
||||
let realloc_account = ctx.accounts.account.as_ref();
|
||||
|
@ -55,7 +54,7 @@ pub fn account_expand(ctx: Context<AccountExpand>) -> Result<()> {
|
|||
|
||||
// expand dynamic content, e.g. to grow token positions, we need to slide serum3orders further later, and so on....
|
||||
let mut account = ctx.accounts.account.load_mut()?;
|
||||
account.expand_dynamic_content(AccountSize::Large)?;
|
||||
account.expand_dynamic_content(token_count, serum3_count, perp_count, perp_oo_count)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -19,16 +19,14 @@ pub mod serum3_cpi;
|
|||
pub mod state;
|
||||
pub mod types;
|
||||
|
||||
use state::{
|
||||
AccountSize, OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex,
|
||||
};
|
||||
use state::{OracleConfig, OrderType, PerpMarketIndex, Serum3MarketIndex, Side, TokenIndex};
|
||||
|
||||
declare_id!("m43thNJ58XCjL798ZSq6JGAG1BnWskhdq5or6kcnfsD");
|
||||
|
||||
#[program]
|
||||
pub mod mango_v4 {
|
||||
|
||||
use crate::state::{AccountSize, OracleConfig};
|
||||
use crate::state::OracleConfig;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -146,14 +144,31 @@ pub mod mango_v4 {
|
|||
pub fn account_create(
|
||||
ctx: Context<AccountCreate>,
|
||||
account_num: u32,
|
||||
account_size: AccountSize,
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
perp_count: u8,
|
||||
perp_oo_count: u8,
|
||||
name: String,
|
||||
) -> Result<()> {
|
||||
instructions::account_create(ctx, account_num, account_size, name)
|
||||
instructions::account_create(
|
||||
ctx,
|
||||
account_num,
|
||||
token_count,
|
||||
serum3_count,
|
||||
perp_count,
|
||||
perp_oo_count,
|
||||
name,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn account_expand(ctx: Context<AccountExpand>) -> Result<()> {
|
||||
instructions::account_expand(ctx)
|
||||
pub fn account_expand(
|
||||
ctx: Context<AccountExpand>,
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
perp_count: u8,
|
||||
perp_oo_count: u8,
|
||||
) -> Result<()> {
|
||||
instructions::account_expand(ctx, token_count, serum3_count, perp_count, perp_oo_count)
|
||||
}
|
||||
|
||||
pub fn account_edit(
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
use std::fmt;
|
||||
|
||||
use std::mem::size_of;
|
||||
|
||||
use anchor_lang::prelude::*;
|
||||
use arrayref::array_ref;
|
||||
|
||||
use fixed::types::I80F48;
|
||||
use num_enum::IntoPrimitive;
|
||||
use num_enum::TryFromPrimitive;
|
||||
|
||||
use solana_program::program_memory::sol_memmove;
|
||||
use static_assertions::const_assert_eq;
|
||||
|
||||
|
@ -33,42 +30,6 @@ const BORSH_VEC_PADDING_BYTES: usize = 4;
|
|||
const BORSH_VEC_SIZE_BYTES: usize = 4;
|
||||
const DEFAULT_MANGO_ACCOUNT_VERSION: u8 = 1;
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Clone,
|
||||
Copy,
|
||||
TryFromPrimitive,
|
||||
IntoPrimitive,
|
||||
AnchorSerialize,
|
||||
AnchorDeserialize,
|
||||
)]
|
||||
#[repr(u8)]
|
||||
|
||||
pub enum AccountSize {
|
||||
Small = 0,
|
||||
Large = 1,
|
||||
}
|
||||
|
||||
impl fmt::Display for AccountSize {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
AccountSize::Small => write!(f, "Small"),
|
||||
AccountSize::Large => write!(f, "Large"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AccountSize {
|
||||
pub fn space(&self) -> (u8, u8, u8, u8) {
|
||||
match self {
|
||||
AccountSize::Small => (8, 2, 2, 2),
|
||||
AccountSize::Large => (16, 8, 8, 8),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mango Account
|
||||
// This struct definition is only for clients e.g. typescript, so that they can easily use out of the box
|
||||
// deserialization and not have to do custom deserialization
|
||||
|
@ -157,11 +118,19 @@ impl Default for MangoAccount {
|
|||
}
|
||||
|
||||
impl MangoAccount {
|
||||
pub fn space(account_size: AccountSize) -> usize {
|
||||
let (token_count, serum3_count, perp_count, perp_oo_count) = account_size.space();
|
||||
pub fn space(
|
||||
token_count: u8,
|
||||
serum3_count: u8,
|
||||
perp_count: u8,
|
||||
perp_oo_count: u8,
|
||||
) -> Result<usize> {
|
||||
require_gte!(16, token_count);
|
||||
require_gte!(8, serum3_count);
|
||||
require_gte!(8, perp_count);
|
||||
require_gte!(64, perp_oo_count);
|
||||
|
||||
8 + size_of::<MangoAccountFixed>()
|
||||
+ Self::dynamic_size(token_count, serum3_count, perp_count, perp_oo_count)
|
||||
Ok(8 + size_of::<MangoAccountFixed>()
|
||||
+ Self::dynamic_size(token_count, serum3_count, perp_count, perp_oo_count))
|
||||
}
|
||||
|
||||
pub fn dynamic_token_vec_offset() -> usize {
|
||||
|
@ -201,7 +170,7 @@ impl MangoAccount {
|
|||
#[test]
|
||||
fn test_dynamic_offsets() {
|
||||
let mut account = MangoAccount::default();
|
||||
account.tokens.resize(16, TokenPosition::default());
|
||||
account.tokens.resize(8, TokenPosition::default());
|
||||
account.serum3.resize(8, Serum3Orders::default());
|
||||
account.perps.resize(8, PerpPositions::default());
|
||||
account
|
||||
|
@ -209,7 +178,7 @@ fn test_dynamic_offsets() {
|
|||
.resize(8, PerpOpenOrders::default());
|
||||
assert_eq!(
|
||||
8 + AnchorSerialize::try_to_vec(&account).unwrap().len(),
|
||||
MangoAccount::space(AccountSize::Large)
|
||||
MangoAccount::space(8, 8, 8, 8).unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -563,13 +532,6 @@ impl<
|
|||
dynamic: self.dynamic(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> AccountSize {
|
||||
if self.header().perp_count() > 4 {
|
||||
return AccountSize::Large;
|
||||
}
|
||||
AccountSize::Small
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
|
@ -914,14 +876,17 @@ impl<
|
|||
dst.copy_from_slice(&BorshVecLength::from(count).to_le_bytes());
|
||||
}
|
||||
|
||||
pub fn expand_dynamic_content(&mut self, account_size: AccountSize) -> Result<()> {
|
||||
let (new_token_count, new_serum3_count, new_perp_count, new_perp_oo_count) =
|
||||
account_size.space();
|
||||
|
||||
require_gt!(new_token_count, self.header().token_count);
|
||||
require_gt!(new_serum3_count, self.header().serum3_count);
|
||||
require_gt!(new_perp_count, self.header().perp_count);
|
||||
require_gt!(new_perp_oo_count, self.header().perp_oo_count);
|
||||
pub fn expand_dynamic_content(
|
||||
&mut self,
|
||||
new_token_count: u8,
|
||||
new_serum3_count: u8,
|
||||
new_perp_count: u8,
|
||||
new_perp_oo_count: u8,
|
||||
) -> Result<()> {
|
||||
require_gte!(new_token_count, self.header().token_count);
|
||||
require_gte!(new_serum3_count, self.header().serum3_count);
|
||||
require_gte!(new_perp_count, self.header().perp_count);
|
||||
require_gte!(new_perp_oo_count, self.header().perp_oo_count);
|
||||
|
||||
// create a temp copy to compute new starting offsets
|
||||
let new_header = MangoAccountDynamicHeader {
|
||||
|
@ -936,6 +901,7 @@ impl<
|
|||
// expand dynamic components by first moving existing positions, and then setting new ones to defaults
|
||||
|
||||
// perp oo
|
||||
if new_header.perp_oo_count() > old_header.perp_oo_count() {
|
||||
unsafe {
|
||||
sol_memmove(
|
||||
&mut dynamic[new_header.perp_oo_offset(0)],
|
||||
|
@ -947,8 +913,10 @@ impl<
|
|||
*get_helper_mut(dynamic, new_header.perp_oo_offset(i.into())) =
|
||||
PerpOpenOrders::default();
|
||||
}
|
||||
}
|
||||
|
||||
// perp positions
|
||||
if new_header.perp_count() > old_header.perp_count() {
|
||||
unsafe {
|
||||
sol_memmove(
|
||||
&mut dynamic[new_header.perp_offset(0)],
|
||||
|
@ -957,10 +925,13 @@ impl<
|
|||
);
|
||||
}
|
||||
for i in old_header.perp_count..new_perp_count {
|
||||
*get_helper_mut(dynamic, new_header.perp_offset(i.into())) = PerpPositions::default();
|
||||
*get_helper_mut(dynamic, new_header.perp_offset(i.into())) =
|
||||
PerpPositions::default();
|
||||
}
|
||||
}
|
||||
|
||||
// serum3 positions
|
||||
if new_header.serum3_count() > old_header.serum3_count() {
|
||||
unsafe {
|
||||
sol_memmove(
|
||||
&mut dynamic[new_header.serum3_offset(0)],
|
||||
|
@ -969,10 +940,13 @@ impl<
|
|||
);
|
||||
}
|
||||
for i in old_header.serum3_count..new_serum3_count {
|
||||
*get_helper_mut(dynamic, new_header.serum3_offset(i.into())) = Serum3Orders::default();
|
||||
*get_helper_mut(dynamic, new_header.serum3_offset(i.into())) =
|
||||
Serum3Orders::default();
|
||||
}
|
||||
}
|
||||
|
||||
// token positions
|
||||
if new_header.token_count() > old_header.token_count() {
|
||||
unsafe {
|
||||
sol_memmove(
|
||||
&mut dynamic[new_header.token_offset(0)],
|
||||
|
@ -981,7 +955,9 @@ impl<
|
|||
);
|
||||
}
|
||||
for i in old_header.token_count..new_token_count {
|
||||
*get_helper_mut(dynamic, new_header.token_offset(i.into())) = TokenPosition::default();
|
||||
*get_helper_mut(dynamic, new_header.token_offset(i.into())) =
|
||||
TokenPosition::default();
|
||||
}
|
||||
}
|
||||
|
||||
// update header
|
||||
|
|
|
@ -1083,7 +1083,10 @@ impl<'keypair> ClientInstruction for GroupCloseInstruction<'keypair> {
|
|||
|
||||
pub struct AccountCreateInstruction<'keypair> {
|
||||
pub account_num: u32,
|
||||
pub account_size: AccountSize,
|
||||
pub token_count: u8,
|
||||
pub serum3_count: u8,
|
||||
pub perp_count: u8,
|
||||
pub perp_oo_count: u8,
|
||||
pub group: Pubkey,
|
||||
pub owner: &'keypair Keypair,
|
||||
pub payer: &'keypair Keypair,
|
||||
|
@ -1099,7 +1102,10 @@ impl<'keypair> ClientInstruction for AccountCreateInstruction<'keypair> {
|
|||
let program_id = mango_v4::id();
|
||||
let instruction = mango_v4::instruction::AccountCreate {
|
||||
account_num: self.account_num,
|
||||
account_size: self.account_size,
|
||||
token_count: self.token_count,
|
||||
serum3_count: self.serum3_count,
|
||||
perp_count: self.perp_count,
|
||||
perp_oo_count: self.perp_oo_count,
|
||||
name: "my_mango_account".to_string(),
|
||||
};
|
||||
|
||||
|
@ -1136,6 +1142,10 @@ pub struct AccountExpandInstruction<'keypair> {
|
|||
pub group: Pubkey,
|
||||
pub owner: &'keypair Keypair,
|
||||
pub payer: &'keypair Keypair,
|
||||
pub token_count: u8,
|
||||
pub serum3_count: u8,
|
||||
pub perp_count: u8,
|
||||
pub perp_oo_count: u8,
|
||||
}
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl<'keypair> ClientInstruction for AccountExpandInstruction<'keypair> {
|
||||
|
@ -1146,7 +1156,12 @@ impl<'keypair> ClientInstruction for AccountExpandInstruction<'keypair> {
|
|||
_account_loader: impl ClientAccountLoader + 'async_trait,
|
||||
) -> (Self::Accounts, instruction::Instruction) {
|
||||
let program_id = mango_v4::id();
|
||||
let instruction = mango_v4::instruction::AccountExpand {};
|
||||
let instruction = mango_v4::instruction::AccountExpand {
|
||||
token_count: self.token_count,
|
||||
serum3_count: self.serum3_count,
|
||||
perp_count: self.perp_count,
|
||||
perp_oo_count: self.perp_oo_count,
|
||||
};
|
||||
|
||||
let account = Pubkey::find_program_address(
|
||||
&[
|
||||
|
|
|
@ -44,7 +44,10 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 2,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -90,7 +93,10 @@ async fn test_bankrupt_tokens_socialize_loss() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -353,7 +359,10 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 2,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -399,7 +408,10 @@ async fn test_bankrupt_tokens_insurance_fund() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -41,7 +41,10 @@ async fn test_basic() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Small,
|
||||
token_count: 8,
|
||||
serum3_count: 0,
|
||||
perp_count: 0,
|
||||
perp_oo_count: 0,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -55,6 +58,10 @@ async fn test_basic() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountExpandInstruction {
|
||||
account_num: 0,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -37,7 +37,10 @@ async fn test_delegate() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -37,7 +37,10 @@ async fn test_health_compute_tokens() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -102,7 +105,10 @@ async fn test_health_compute_serum() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -214,7 +220,10 @@ async fn test_health_compute_perp() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -42,7 +42,10 @@ async fn test_liq_tokens_force_cancel() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 2,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -98,7 +101,10 @@ async fn test_liq_tokens_force_cancel() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -253,7 +259,10 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 2,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -284,7 +293,10 @@ async fn test_liq_tokens_with_token() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -51,7 +51,10 @@ async fn test_margin_trade() -> Result<(), BanksClientError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 1,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -94,7 +97,10 @@ async fn test_margin_trade() -> Result<(), BanksClientError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -36,7 +36,10 @@ async fn test_perp() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -50,7 +53,10 @@ async fn test_perp() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 1,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -38,7 +38,10 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -52,7 +55,10 @@ async fn test_position_lifetime() -> Result<()> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 1,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -40,7 +40,10 @@ async fn test_serum() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -36,7 +36,10 @@ async fn test_token_update_index_and_rate() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 0,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
@ -64,7 +67,10 @@ async fn test_token_update_index_and_rate() -> Result<(), TransportError> {
|
|||
solana,
|
||||
AccountCreateInstruction {
|
||||
account_num: 1,
|
||||
account_size: AccountSize::Large,
|
||||
token_count: 16,
|
||||
serum3_count: 8,
|
||||
perp_count: 8,
|
||||
perp_oo_count: 8,
|
||||
group,
|
||||
owner,
|
||||
payer,
|
||||
|
|
|
@ -594,8 +594,3 @@ export class EquityDto {
|
|||
tokens: { tokenIndex: number; value: I80F48Dto }[];
|
||||
perps: { perpMarketIndex: number; value: I80F48Dto }[];
|
||||
}
|
||||
|
||||
export class AccountSize {
|
||||
static small = { small: {} };
|
||||
static large = { large: {} };
|
||||
}
|
||||
|
|
|
@ -30,11 +30,7 @@ import bs58 from 'bs58';
|
|||
import { Bank, MintInfo } from './accounts/bank';
|
||||
import { Group } from './accounts/group';
|
||||
import { I80F48 } from './accounts/I80F48';
|
||||
import {
|
||||
AccountSize,
|
||||
MangoAccount,
|
||||
MangoAccountData,
|
||||
} from './accounts/mangoAccount';
|
||||
import { MangoAccount, MangoAccountData } from './accounts/mangoAccount';
|
||||
import { StubOracle } from './accounts/oracle';
|
||||
import { OrderType, PerpMarket, Side } from './accounts/perp';
|
||||
import {
|
||||
|
@ -467,12 +463,11 @@ export class MangoClient {
|
|||
group: Group,
|
||||
ownerPk: PublicKey,
|
||||
accountNumber?: number,
|
||||
accountSize?: AccountSize,
|
||||
name?: string,
|
||||
): Promise<MangoAccount> {
|
||||
let mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
||||
if (mangoAccounts.length === 0) {
|
||||
await this.createMangoAccount(group, accountNumber, accountSize, name);
|
||||
await this.createMangoAccount(group, accountNumber, name);
|
||||
mangoAccounts = await this.getMangoAccountsForOwner(group, ownerPk);
|
||||
}
|
||||
return mangoAccounts[0];
|
||||
|
@ -481,15 +476,10 @@ export class MangoClient {
|
|||
public async createMangoAccount(
|
||||
group: Group,
|
||||
accountNumber?: number,
|
||||
accountSize?: AccountSize,
|
||||
name?: string,
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.program.methods
|
||||
.accountCreate(
|
||||
accountNumber ?? 0,
|
||||
accountSize ?? AccountSize.small,
|
||||
name ?? '',
|
||||
)
|
||||
.accountCreate(accountNumber ?? 0, 8, 0, 0, 0, name ?? '')
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
owner: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
|
@ -501,9 +491,13 @@ export class MangoClient {
|
|||
public async expandMangoAccount(
|
||||
group: Group,
|
||||
account: MangoAccount,
|
||||
tokenCount: number,
|
||||
serum3Count: number,
|
||||
perpCount: number,
|
||||
perpOoCount: number,
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.program.methods
|
||||
.accountExpand()
|
||||
.accountExpand(tokenCount, serum3Count, perpCount, perpOoCount)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
account: account.publicKey,
|
||||
|
@ -1560,15 +1554,17 @@ export class MangoClient {
|
|||
}
|
||||
|
||||
async updateIndexAndRate(group: Group, tokenName: string) {
|
||||
|
||||
let bank = group.banksMap.get(tokenName)!;
|
||||
let mintInfo = group.mintInfosMap.get(bank.tokenIndex)!;
|
||||
|
||||
await this.program.methods.tokenUpdateIndexAndRate().accounts({
|
||||
'group': group.publicKey,
|
||||
'mintInfo': mintInfo.publicKey,
|
||||
'oracle': mintInfo.oracle,
|
||||
'instructions': SYSVAR_INSTRUCTIONS_PUBKEY})
|
||||
await this.program.methods
|
||||
.tokenUpdateIndexAndRate()
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
mintInfo: mintInfo.publicKey,
|
||||
oracle: mintInfo.oracle,
|
||||
instructions: SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||
})
|
||||
.remainingAccounts([
|
||||
{
|
||||
pubkey: bank.publicKey,
|
||||
|
@ -1576,10 +1572,9 @@ export class MangoClient {
|
|||
isSigner: false,
|
||||
} as AccountMeta,
|
||||
])
|
||||
.rpc()
|
||||
.rpc();
|
||||
}
|
||||
|
||||
|
||||
/// liquidations
|
||||
|
||||
async liqTokenWithToken(
|
||||
|
|
|
@ -820,10 +820,20 @@ export type MangoV4 = {
|
|||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"name": "accountSize",
|
||||
"type": {
|
||||
"defined": "AccountSize"
|
||||
}
|
||||
"name": "tokenCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "serum3Count",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpOoCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
|
@ -860,7 +870,24 @@ export type MangoV4 = {
|
|||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": []
|
||||
"args": [
|
||||
{
|
||||
"name": "tokenCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "serum3Count",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpOoCount",
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "accountEdit",
|
||||
|
@ -3980,6 +4007,21 @@ export type MangoV4 = {
|
|||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baseEntryLots",
|
||||
"docs": [
|
||||
"Tracks what the position is to calculate average entry & break even price"
|
||||
],
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "quoteEntryNative",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "quoteExitNative",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "longSettledFunding",
|
||||
"docs": [
|
||||
|
@ -4287,20 +4329,6 @@ export type MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AccountSize",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "Small"
|
||||
},
|
||||
{
|
||||
"name": "Large"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OracleType",
|
||||
"type": {
|
||||
|
@ -5833,10 +5861,20 @@ export const IDL: MangoV4 = {
|
|||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"name": "accountSize",
|
||||
"type": {
|
||||
"defined": "AccountSize"
|
||||
}
|
||||
"name": "tokenCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "serum3Count",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpOoCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
|
@ -5873,7 +5911,24 @@ export const IDL: MangoV4 = {
|
|||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": []
|
||||
"args": [
|
||||
{
|
||||
"name": "tokenCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "serum3Count",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpCount",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "perpOoCount",
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "accountEdit",
|
||||
|
@ -8993,6 +9048,21 @@ export const IDL: MangoV4 = {
|
|||
"defined": "I80F48"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "baseEntryLots",
|
||||
"docs": [
|
||||
"Tracks what the position is to calculate average entry & break even price"
|
||||
],
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "quoteEntryNative",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "quoteExitNative",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "longSettledFunding",
|
||||
"docs": [
|
||||
|
@ -9300,20 +9370,6 @@ export const IDL: MangoV4 = {
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AccountSize",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "Small"
|
||||
},
|
||||
{
|
||||
"name": "Large"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OracleType",
|
||||
"type": {
|
||||
|
|
|
@ -107,9 +107,8 @@ async function main() {
|
|||
group,
|
||||
mangoAccount,
|
||||
group.findBank(token.tokenIndex)!.name,
|
||||
nativeFlooredNumber,
|
||||
nativeFlooredNumber - 1 /* see comment in token_withdraw in program */,
|
||||
false,
|
||||
user,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,14 @@ async function main() {
|
|||
console.log(mangoAccount.toString());
|
||||
}
|
||||
|
||||
if (true) {
|
||||
console.log(
|
||||
`...expanding mango account to have serum3 and perp position slots`,
|
||||
);
|
||||
await client.expandMangoAccount(group, mangoAccount, 16, 8, 8, 8);
|
||||
await mangoAccount.reload(client, group);
|
||||
}
|
||||
|
||||
if (true) {
|
||||
// deposit and withdraw
|
||||
|
||||
|
|
Loading…
Reference in New Issue