From 479bd60ecf4a91f2d56fd4e4bc531124fdb80542 Mon Sep 17 00:00:00 2001 From: microwavedcola1 Date: Sat, 19 Mar 2022 07:28:37 +0100 Subject: [PATCH] extend perp market with indices, which make it easier to lookup the perp market and base and quote tokens Signed-off-by: microwavedcola1 --- .../src/instructions/create_perp_market.rs | 18 +++++++++++++++++- programs/mango-v4/src/lib.rs | 15 +++++++++++++-- programs/mango-v4/src/state/mango_account.rs | 4 ++-- .../mango-v4/src/state/perp/perp_market.rs | 13 +++++++++++++ .../tests/program_test/mango_client.rs | 13 +++++++++++-- programs/mango-v4/tests/test_perp.rs | 3 +++ 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/programs/mango-v4/src/instructions/create_perp_market.rs b/programs/mango-v4/src/instructions/create_perp_market.rs index ee1500862..3fb1d1486 100644 --- a/programs/mango-v4/src/instructions/create_perp_market.rs +++ b/programs/mango-v4/src/instructions/create_perp_market.rs @@ -4,6 +4,7 @@ use crate::error::MangoError; use crate::state::*; #[derive(Accounts)] +#[instruction(perp_market_index: PerpMarketIndex)] pub struct CreatePerpMarket<'info> { #[account( has_one = admin, @@ -15,7 +16,7 @@ pub struct CreatePerpMarket<'info> { #[account( init, - seeds = [group.key().as_ref(), b"PerpMarket".as_ref(), oracle.key().as_ref()], + seeds = [group.key().as_ref(), b"PerpMarket".as_ref(), &perp_market_index.to_le_bytes().as_ref()], bump, payer = payer, space = 8 + std::mem::size_of::(), @@ -54,6 +55,9 @@ pub struct CreatePerpMarket<'info> { pub fn create_perp_market( ctx: Context, + perp_market_index: PerpMarketIndex, + base_token_index_opt: Option, + quote_token_index: TokenIndex, quote_lot_size: i64, base_lot_size: i64, // todo @@ -80,7 +84,19 @@ pub fn create_perp_market( // liquidity_mining_info, // mngo_vault: ctx.accounts.mngo_vault.key(), bump: *ctx.bumps.get("perp_market").ok_or(MangoError::SomeError)?, + perp_market_index, + base_token_index: base_token_index_opt.ok_or(TokenIndex::MAX).unwrap(), + quote_token_index, }; + let mut asks = ctx.accounts.asks.load_init()?; + *asks = Book {}; + + let mut bids = ctx.accounts.bids.load_init()?; + *bids = Book {}; + + let mut event_queue = ctx.accounts.event_queue.load_init()?; + *event_queue = EventQueue {}; + Ok(()) } diff --git a/programs/mango-v4/src/lib.rs b/programs/mango-v4/src/lib.rs index 37ae14ff8..74590dd45 100644 --- a/programs/mango-v4/src/lib.rs +++ b/programs/mango-v4/src/lib.rs @@ -15,12 +15,13 @@ pub mod instructions; mod serum3_cpi; pub mod state; -use state::{Serum3MarketIndex, TokenIndex}; +use state::{PerpMarketIndex, Serum3MarketIndex, TokenIndex}; declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); #[program] pub mod mango_v4 { + use super::*; pub fn create_group(ctx: Context) -> Result<()> { @@ -104,10 +105,20 @@ pub mod mango_v4 { pub fn create_perp_market( ctx: Context, + perp_market_index: PerpMarketIndex, + base_token_index_opt: Option, + quote_token_index: TokenIndex, quote_lot_size: i64, base_lot_size: i64, ) -> Result<()> { - instructions::create_perp_market(ctx, quote_lot_size, base_lot_size) + instructions::create_perp_market( + ctx, + perp_market_index, + base_token_index_opt, + quote_token_index, + quote_lot_size, + base_lot_size, + ) } } diff --git a/programs/mango-v4/src/state/mango_account.rs b/programs/mango-v4/src/state/mango_account.rs index c32462238..a681bc4a7 100644 --- a/programs/mango-v4/src/state/mango_account.rs +++ b/programs/mango-v4/src/state/mango_account.rs @@ -4,8 +4,8 @@ use fixed::types::I80F48; use crate::error::*; use crate::state::*; -const MAX_INDEXED_POSITIONS: usize = 32; -const MAX_SERUM_OPEN_ORDERS: usize = 16; +const MAX_INDEXED_POSITIONS: usize = 16; +const MAX_SERUM_OPEN_ORDERS: usize = 8; #[zero_copy] pub struct TokenAccount { diff --git a/programs/mango-v4/src/state/perp/perp_market.rs b/programs/mango-v4/src/state/perp/perp_market.rs index ee64cf28c..e5e49a05d 100644 --- a/programs/mango-v4/src/state/perp/perp_market.rs +++ b/programs/mango-v4/src/state/perp/perp_market.rs @@ -1,5 +1,9 @@ use anchor_lang::prelude::*; +use crate::state::TokenIndex; + +pub type PerpMarketIndex = u16; + #[account(zero_copy)] pub struct PerpMarket { // todo @@ -65,4 +69,13 @@ pub struct PerpMarket { /// pda bump pub bump: u8, + + /// useful for looking up respective perp account + pub perp_market_index: PerpMarketIndex, + /// useful for looking up respective base token, + /// note: is optional, since perp market can exist without a corresponding base token, + /// should be TokenIndex::MAX in that case + pub base_token_index: TokenIndex, + /// useful for looking up respective quote token + pub quote_token_index: TokenIndex, } diff --git a/programs/mango-v4/tests/program_test/mango_client.rs b/programs/mango-v4/tests/program_test/mango_client.rs index c6a69b03d..cfa586df6 100644 --- a/programs/mango-v4/tests/program_test/mango_client.rs +++ b/programs/mango-v4/tests/program_test/mango_client.rs @@ -932,12 +932,14 @@ impl<'keypair> ClientInstruction for Serum3SettleFundsInstruction<'keypair> { vec![self.owner] } } - pub struct CreatePerpMarketInstruction<'keypair> { pub group: Pubkey, pub mint: Pubkey, pub admin: &'keypair Keypair, pub payer: &'keypair Keypair, + pub perp_market_index: PerpMarketIndex, + pub base_token_index: TokenIndex, + pub quote_token_index: TokenIndex, pub quote_lot_size: i64, pub base_lot_size: i64, } @@ -951,6 +953,9 @@ impl<'keypair> ClientInstruction for CreatePerpMarketInstruction<'keypair> { ) -> (Self::Accounts, instruction::Instruction) { let program_id = mango_v4::id(); let instruction = Self::Instruction { + perp_market_index: self.perp_market_index, + base_token_index_opt: Option::from(self.base_token_index), + quote_token_index: self.quote_token_index, quote_lot_size: self.quote_lot_size, base_lot_size: self.base_lot_size, }; @@ -962,7 +967,11 @@ impl<'keypair> ClientInstruction for CreatePerpMarketInstruction<'keypair> { .0; let perp_market = Pubkey::find_program_address( - &[self.group.as_ref(), b"PerpMarket".as_ref(), oracle.as_ref()], + &[ + self.group.as_ref(), + b"PerpMarket".as_ref(), + self.perp_market_index.to_le_bytes().as_ref(), + ], &program_id, ) .0; diff --git a/programs/mango-v4/tests/test_perp.rs b/programs/mango-v4/tests/test_perp.rs index 3a9ae11da..60aeb4105 100644 --- a/programs/mango-v4/tests/test_perp.rs +++ b/programs/mango-v4/tests/test_perp.rs @@ -140,6 +140,9 @@ async fn test_perp() -> Result<(), TransportError> { admin, payer, mint: mint0.pubkey, + perp_market_index: 0, + base_token_index, + quote_token_index, // e.g. BTC mango-v3 mainnet.1 quote_lot_size: 10, base_lot_size: 100,