Skip to content

Commit

Permalink
Merge pull request #228 from openbook-dex/fix/invalid_post_order
Browse files Browse the repository at this point in the history
Do not post invalid price ask if not match
  • Loading branch information
skrrb authored Feb 26, 2024
2 parents 89386c1 + 4a1a1a6 commit 796a470
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
8 changes: 6 additions & 2 deletions programs/openbook-v2/src/state/orderbook/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,18 +162,22 @@ impl<'a> Orderbook<'a> {

if !side.is_price_within_limit(best_opposing_price, price_lots) {
break;
} else if post_only {
}
if post_only {
msg!("Order could not be placed due to PostOnly");
post_target = None;
break; // return silently to not fail other instructions in tx
} else if limit == 0 {
}
if limit == 0 {
msg!("Order matching limit reached");
post_target = None;
break;
}

let max_match_by_quote = remaining_quote_lots / best_opposing_price;
// Do not post orders in the book due to bad pricing and negative spread
if max_match_by_quote == 0 {
post_target = None;
break;
}

Expand Down
79 changes: 79 additions & 0 deletions programs/openbook-v2/tests/cases/test_take_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,82 @@ async fn test_take_bid_order() -> Result<(), TransportError> {

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::<OpenOrdersAccount>(account_2)
.await
.position;

assert_eq!(position.asks_base_lots, 0);
assert_eq!(position.bids_base_lots, 0);

Ok(())
}

0 comments on commit 796a470

Please sign in to comment.