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:
microwavedcola1 2022-08-07 14:16:06 +02:00 committed by GitHub
parent ff19940ee7
commit e06736660a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 349 additions and 215 deletions

View File

@ -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)

View File

@ -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(())
}

View File

@ -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(())
}

View File

@ -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(

View File

@ -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,52 +901,63 @@ impl<
// expand dynamic components by first moving existing positions, and then setting new ones to defaults
// perp oo
unsafe {
sol_memmove(
&mut dynamic[new_header.perp_oo_offset(0)],
&mut dynamic[old_header.perp_oo_offset(0)],
size_of::<PerpOpenOrders>() * old_header.perp_oo_count(),
);
}
for i in old_header.perp_oo_count..new_perp_oo_count {
*get_helper_mut(dynamic, new_header.perp_oo_offset(i.into())) =
PerpOpenOrders::default();
if new_header.perp_oo_count() > old_header.perp_oo_count() {
unsafe {
sol_memmove(
&mut dynamic[new_header.perp_oo_offset(0)],
&mut dynamic[old_header.perp_oo_offset(0)],
size_of::<PerpOpenOrders>() * old_header.perp_oo_count(),
);
}
for i in old_header.perp_oo_count..new_perp_oo_count {
*get_helper_mut(dynamic, new_header.perp_oo_offset(i.into())) =
PerpOpenOrders::default();
}
}
// perp positions
unsafe {
sol_memmove(
&mut dynamic[new_header.perp_offset(0)],
&mut dynamic[old_header.perp_offset(0)],
size_of::<PerpPositions>() * old_header.perp_count(),
);
}
for i in old_header.perp_count..new_perp_count {
*get_helper_mut(dynamic, new_header.perp_offset(i.into())) = PerpPositions::default();
if new_header.perp_count() > old_header.perp_count() {
unsafe {
sol_memmove(
&mut dynamic[new_header.perp_offset(0)],
&mut dynamic[old_header.perp_offset(0)],
size_of::<PerpPositions>() * old_header.perp_count(),
);
}
for i in old_header.perp_count..new_perp_count {
*get_helper_mut(dynamic, new_header.perp_offset(i.into())) =
PerpPositions::default();
}
}
// serum3 positions
unsafe {
sol_memmove(
&mut dynamic[new_header.serum3_offset(0)],
&mut dynamic[old_header.serum3_offset(0)],
size_of::<Serum3Orders>() * old_header.serum3_count(),
);
}
for i in old_header.serum3_count..new_serum3_count {
*get_helper_mut(dynamic, new_header.serum3_offset(i.into())) = Serum3Orders::default();
if new_header.serum3_count() > old_header.serum3_count() {
unsafe {
sol_memmove(
&mut dynamic[new_header.serum3_offset(0)],
&mut dynamic[old_header.serum3_offset(0)],
size_of::<Serum3Orders>() * old_header.serum3_count(),
);
}
for i in old_header.serum3_count..new_serum3_count {
*get_helper_mut(dynamic, new_header.serum3_offset(i.into())) =
Serum3Orders::default();
}
}
// token positions
unsafe {
sol_memmove(
&mut dynamic[new_header.token_offset(0)],
&mut dynamic[old_header.token_offset(0)],
size_of::<TokenPosition>() * old_header.token_count(),
);
}
for i in old_header.token_count..new_token_count {
*get_helper_mut(dynamic, new_header.token_offset(i.into())) = TokenPosition::default();
if new_header.token_count() > old_header.token_count() {
unsafe {
sol_memmove(
&mut dynamic[new_header.token_offset(0)],
&mut dynamic[old_header.token_offset(0)],
size_of::<TokenPosition>() * old_header.token_count(),
);
}
for i in old_header.token_count..new_token_count {
*get_helper_mut(dynamic, new_header.token_offset(i.into())) =
TokenPosition::default();
}
}
// update header

View File

@ -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(
&[

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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: {} };
}

View File

@ -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,9 +1572,8 @@ export class MangoClient {
isSigner: false,
} as AccountMeta,
])
.rpc()
.rpc();
}
/// liquidations

View File

@ -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": {

View File

@ -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,
);
}

View File

@ -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