use super::*; #[tokio::test] async fn test_take_ask_order() -> Result<(), TransportError> { let TestInitialize { context, collect_fee_admin, owner, owner_token_0, owner_token_1, market, market_base_vault, market_quote_vault, price_lots, tokens, account_1, account_2, .. } = TestContext::new_with_market(TestNewMarketInitialize::default()).await?; let solana = &context.solana.clone(); // Set the initial oracle price set_stub_oracle_price(solana, &tokens[1], collect_fee_admin, 1000.0).await; send_tx( solana, PlaceOrderInstruction { open_orders_account: account_1, open_orders_admin: None, market, signer: owner, user_token_account: owner_token_1, market_vault: market_quote_vault, side: Side::Bid, price_lots, max_base_lots: 1, max_quote_lots_including_fees: 10000, client_order_id: 0, expiry_timestamp: 0, order_type: PlaceOrderType::Limit, self_trade_behavior: SelfTradeBehavior::default(), remainings: vec![], }, ) .await .unwrap(); let balance_base = solana.token_account_balance(owner_token_0).await; let balance_quote = solana.token_account_balance(owner_token_1).await; send_tx( solana, PlaceTakeOrderInstruction { market, signer: owner, user_base_account: owner_token_0, user_quote_account: owner_token_1, market_base_vault, market_quote_vault, side: Side::Ask, price_lots, max_base_lots: 1, max_quote_lots_including_fees: 10000, open_orders_admin: None, }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.bids_base_lots, 1); assert_eq!(open_orders_account_2.position.bids_base_lots, 0); assert_eq!(open_orders_account_1.position.asks_base_lots, 0); assert_eq!(open_orders_account_2.position.asks_base_lots, 0); assert_eq!(open_orders_account_1.position.base_free_native, 0); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 0); assert_eq!(open_orders_account_2.position.quote_free_native, 0); assert_eq!( balance_base - 100, solana.token_account_balance(owner_token_0).await ); assert_eq!( balance_quote + 99980, solana.token_account_balance(owner_token_1).await ); } send_tx( solana, ConsumeEventsInstruction { consume_events_admin: None, market, open_orders_accounts: vec![account_1], }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.bids_base_lots, 0); assert_eq!(open_orders_account_2.position.bids_base_lots, 0); assert_eq!(open_orders_account_1.position.asks_base_lots, 0); assert_eq!(open_orders_account_2.position.asks_base_lots, 0); assert_eq!(open_orders_account_1.position.base_free_native, 100); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 20); assert_eq!(open_orders_account_2.position.quote_free_native, 0); } send_tx( solana, SettleFundsInstruction { owner, market, open_orders_account: account_1, market_base_vault, market_quote_vault, user_base_account: owner_token_0, user_quote_account: owner_token_1, referrer_account: None, }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.base_free_native, 0); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 0); assert_eq!(open_orders_account_2.position.quote_free_native, 0); } Ok(()) } #[tokio::test] async fn test_take_bid_order() -> Result<(), TransportError> { let TestInitialize { context, collect_fee_admin, owner, owner_token_0, owner_token_1, market, market_base_vault, market_quote_vault, price_lots, tokens, account_1, account_2, .. } = TestContext::new_with_market(TestNewMarketInitialize::default()).await?; let solana = &context.solana.clone(); // Set the initial oracle price set_stub_oracle_price(solana, &tokens[1], collect_fee_admin, 1000.0).await; send_tx( solana, PlaceOrderInstruction { open_orders_account: account_1, open_orders_admin: None, market, signer: owner, user_token_account: owner_token_0, market_vault: market_base_vault, side: Side::Ask, price_lots, max_base_lots: 1, max_quote_lots_including_fees: 10000, client_order_id: 0, expiry_timestamp: 0, order_type: PlaceOrderType::Limit, self_trade_behavior: SelfTradeBehavior::default(), remainings: vec![], }, ) .await .unwrap(); let balance_base = solana.token_account_balance(owner_token_0).await; let balance_quote = solana.token_account_balance(owner_token_1).await; send_tx( solana, PlaceTakeOrderInstruction { market, signer: owner, user_base_account: owner_token_0, user_quote_account: owner_token_1, market_base_vault, market_quote_vault, side: Side::Bid, price_lots, max_base_lots: 1, max_quote_lots_including_fees: 10040, open_orders_admin: None, }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.bids_base_lots, 0); assert_eq!(open_orders_account_2.position.bids_base_lots, 0); assert_eq!(open_orders_account_1.position.asks_base_lots, 1); assert_eq!(open_orders_account_2.position.asks_base_lots, 0); assert_eq!(open_orders_account_1.position.base_free_native, 0); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 0); assert_eq!(open_orders_account_2.position.quote_free_native, 0); assert_eq!( balance_base + 100, solana.token_account_balance(owner_token_0).await ); assert_eq!( balance_quote - 100020, solana.token_account_balance(owner_token_1).await ); } send_tx( solana, ConsumeEventsInstruction { consume_events_admin: None, market, open_orders_accounts: vec![account_1], }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.bids_base_lots, 0); assert_eq!(open_orders_account_2.position.bids_base_lots, 0); assert_eq!(open_orders_account_1.position.asks_base_lots, 0); assert_eq!(open_orders_account_2.position.asks_base_lots, 0); assert_eq!(open_orders_account_1.position.base_free_native, 0); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 100020); assert_eq!(open_orders_account_2.position.quote_free_native, 0); } send_tx( solana, SettleFundsInstruction { owner, market, open_orders_account: account_1, market_base_vault, market_quote_vault, user_base_account: owner_token_0, user_quote_account: owner_token_1, referrer_account: None, }, ) .await .unwrap(); { let open_orders_account_1 = solana.get_account::(account_1).await; let open_orders_account_2 = solana.get_account::(account_2).await; assert_eq!(open_orders_account_1.position.base_free_native, 0); assert_eq!(open_orders_account_2.position.base_free_native, 0); assert_eq!(open_orders_account_1.position.quote_free_native, 0); assert_eq!(open_orders_account_2.position.quote_free_native, 0); } Ok(()) } #[tokio::test] async fn test_negative_spread_ask() -> Result<(), TransportError> { let TestInitialize { context, owner, owner_token_0, owner_token_1, market, market_base_vault, market_quote_vault, account_1, account_2, .. } = TestContext::new_with_market(TestNewMarketInitialize { quote_lot_size: 100, base_lot_size: 1_000_000_000, ..TestNewMarketInitialize::default() }) .await?; let solana = &context.solana.clone(); send_tx( solana, PlaceOrderInstruction { open_orders_account: account_1, open_orders_admin: None, market, signer: owner, user_token_account: owner_token_1, market_vault: market_quote_vault, side: Side::Bid, price_lots: 10_000, // $1 max_base_lots: 1000000, // wahtever max_quote_lots_including_fees: 10_000, client_order_id: 1, expiry_timestamp: 0, order_type: PlaceOrderType::Limit, self_trade_behavior: SelfTradeBehavior::default(), remainings: vec![], }, ) .await .unwrap(); // This order doesn't take any due max_quote_lots_including_fees but it's also don't post in on the book send_tx( solana, PlaceOrderInstruction { open_orders_account: account_2, open_orders_admin: None, market, signer: owner, user_token_account: owner_token_0, market_vault: market_base_vault, side: Side::Ask, price_lots: 7_500, max_base_lots: 1, max_quote_lots_including_fees: 7_500, client_order_id: 25, expiry_timestamp: 0, order_type: PlaceOrderType::Limit, self_trade_behavior: SelfTradeBehavior::AbortTransaction, remainings: vec![], }, ) .await .unwrap(); let position = solana .get_account::(account_2) .await .position; assert_eq!(position.asks_base_lots, 0); assert_eq!(position.bids_base_lots, 0); Ok(()) }