diff --git a/justfile b/justfile index 93f230f38..48704fb94 100644 --- a/justfile +++ b/justfile @@ -7,7 +7,7 @@ lint: cargo clippy --no-deps --tests --features enable-gpl --features test-bpf -- --allow=clippy::result-large-err test TEST_NAME: - cargo test-sbf --features enable-gpl -- {{ TEST_NAME }} + RUST_LOG='test_all=debug' cargo test-sbf --features enable-gpl -- {{ TEST_NAME }} test-all: (cd ./programs/openbook-v2 && RUST_LOG=ERROR cargo test-sbf --features enable-gpl) diff --git a/programs/openbook-v2/tests/cases/test_take_order.rs b/programs/openbook-v2/tests/cases/test_take_order.rs index 618264e43..583f52287 100644 --- a/programs/openbook-v2/tests/cases/test_take_order.rs +++ b/programs/openbook-v2/tests/cases/test_take_order.rs @@ -1,3 +1,5 @@ +use log::{debug, error}; + use super::*; #[tokio::test] @@ -367,3 +369,114 @@ async fn test_negative_spread_ask() -> Result<(), TransportError> { Ok(()) } + +#[tokio::test] +async fn test_exact_match() -> Result<(), TransportError> { + + + let base_lot_size = 100; + let quote_lot_size = 10; + + let market_init = TestNewMarketInitialize { + fee_penalty: 0, + quote_lot_size: quote_lot_size.clone(), + base_lot_size: base_lot_size.clone(), + maker_fee: 500, + taker_fee: 1000, + open_orders_admin_bool: false, + close_market_admin_bool: false, + consume_events_admin_bool: false, + time_expiry: 0, + with_oracle: true, + payer_as_delegate: false, + }; + + 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(market_init).await?; + let solana = &context.solana.clone(); + debug!("price lots:{price_lots}"); + + // Set the initial oracle price + set_stub_oracle_price(solana, &tokens[1], collect_fee_admin, 1000.0).await; + + let order_base_native = 1_000_000_000; + + + // place bid 1 @ 1000 + 5bps fee + 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: order_base_native / base_lot_size, + max_quote_lots_including_fees: 1_005_000_000_000 / quote_lot_size, + + client_order_id: 0, + expiry_timestamp: 0, + order_type: PlaceOrderType::Limit, + self_trade_behavior: SelfTradeBehavior::default(), + remainings: vec![], + }, + ) + .await + .unwrap(); + + let balance_base_before = solana.token_account_balance(market_base_vault).await; + let balance_quote_before = solana.token_account_balance(market_quote_vault).await; + + debug!("vault before base:{balance_base_before} quote:{balance_quote_before}"); + + 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: price_lots, + max_base_lots: order_base_native / base_lot_size, + max_quote_lots_including_fees: 1_010_000_000_000 / quote_lot_size, + open_orders_admin: None, + }, + ) + .await + .unwrap(); + + let balance_base_after = solana.token_account_balance(market_base_vault).await; + let balance_quote_after = solana.token_account_balance(market_quote_vault).await; + + debug!("vault after base:{balance_base_after} quote:{balance_quote_after}"); + + let diff_base = balance_base_after as i64 - balance_base_before as i64; + let diff_quote = balance_quote_after as i64 - balance_quote_before as i64; + + debug!("base diff:{diff_base} lot:{base_lot_size}"); + debug!("quote diff:{diff_quote} lot:{quote_lot_size}"); + + assert_eq!(balance_base_after, balance_base_before + order_base_native as u64); + assert_eq!(balance_quote_after as i64, balance_quote_before as i64 - 1_000 * order_base_native); + + Ok(()) +} \ No newline at end of file