Skip to content

Commit

Permalink
Merge pull request #71 from openbook-dex/feature/fix-selftrade
Browse files Browse the repository at this point in the history
Feature/fix selftrade
  • Loading branch information
binyebarwe authored Jun 19, 2023
2 parents 196e571 + 1393907 commit 0d32e32
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 13 deletions.
26 changes: 15 additions & 11 deletions programs/openbook-v2/src/state/open_orders_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,12 @@ impl<
}

pub fn execute_maker(&mut self, market: &mut Market, fill: &FillEvent) -> Result<()> {
let is_self_trade = fill.maker == fill.taker;

let side = fill.taker_side().invert_side();
let (base_change, quote_change) = fill.base_quote_change(side);
let quote_native_abs = (market.quote_lot_size * quote_change).unsigned_abs();
let fees = if market.maker_fee.is_positive() {
let fees = if is_self_trade || market.maker_fee.is_positive() {
// Maker pays fee. Fees already subtracted before sending to the book
0
} else {
Expand Down Expand Up @@ -397,7 +399,7 @@ impl<
}
};

if market.maker_fee.is_positive() {
if !is_self_trade && market.maker_fee.is_positive() {
// Apply rebates
let maker_fees = (I80F48::from(quote_to_free) * market.maker_fee)
.ceil()
Expand All @@ -416,15 +418,17 @@ impl<
}

// Update market fees
let fee_amount: i64 = {
let amount = I80F48::from(quote_native_abs) * market.maker_fee;
if market.maker_fee.is_positive() {
amount.ceil().to_num()
} else {
amount.floor().to_num()
}
};
market.fees_accrued += fee_amount;
if !is_self_trade {
let fee_amount: i64 = {
let amount = I80F48::from(quote_native_abs) * market.maker_fee;
if market.maker_fee.is_positive() {
amount.ceil().to_num()
} else {
amount.floor().to_num()
}
};
market.fees_accrued += fee_amount;
}

//Emit event
emit!(FillLog {
Expand Down
2 changes: 1 addition & 1 deletion programs/openbook-v2/src/state/orderbook/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<'a> Orderbook<'a> {
side,
market,
total_base_taken_native,
total_quote_taken_native_wo_self,
total_quote_taken_native,
taker_fees as u64,
)?;
} else {
Expand Down
91 changes: 90 additions & 1 deletion programs/openbook-v2/tests/cases/test_self_trade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ async fn test_self_trade_decrement_take() -> Result<(), TransportError> {
assert_eq!(open_orders_account_0.position.bids_base_lots, 0);
assert_eq!(open_orders_account_0.position.asks_base_lots, 0);
assert_eq!(open_orders_account_0.position.base_free_native, 200);
assert_eq!(open_orders_account_0.position.quote_free_native, 20004);
assert_eq!(open_orders_account_0.position.quote_free_native, 20000);

assert_eq!(open_orders_account_1.position.bids_base_lots, 0);
assert_eq!(open_orders_account_1.position.asks_base_lots, 1);
Expand Down Expand Up @@ -459,3 +459,92 @@ async fn test_self_abort_transaction() -> Result<(), TransportError> {

Ok(())
}

#[tokio::test]
async fn test_self_trade_no_fees() -> Result<(), TransportError> {
let TestInitialize {
context,
owner,
owner_token_0: owner_base_ata,
owner_token_1: owner_quote_ata,
market,
base_vault,
quote_vault,
account_0: open_orders_account,
..
} = TestContext::new_with_market(TestNewMarketInitialize::default()).await?;
let solana = &context.solana.clone();

let place_bid_ix = PlaceOrderInstruction {
open_orders_account,
open_orders_admin: None,
market,
owner,
token_deposit_account: owner_quote_ata,
base_vault,
quote_vault,
side: Side::Bid,
price_lots: 1000,
max_base_lots: 1,
max_quote_lots_including_fees: 10000,
client_order_id: 1,
expiry_timestamp: 0,
order_type: PlaceOrderType::Limit,
self_trade_behavior: SelfTradeBehavior::default(),
remainings: vec![],
};

let place_ask_ix = PlaceOrderInstruction {
side: Side::Ask,
token_deposit_account: owner_base_ata,
..place_bid_ix.clone()
};

let consume_events_ix = ConsumeEventsInstruction {
consume_events_admin: None,
market,
open_orders_accounts: vec![open_orders_account],
};

let settle_funds_ix = SettleFundsInstruction {
owner,
market,
open_orders_account,
base_vault,
quote_vault,
token_base_account: owner_base_ata,
token_quote_account: owner_quote_ata,
referrer: None,
};

let balances_before = (
solana.token_account_balance(owner_base_ata).await,
solana.token_account_balance(owner_quote_ata).await,
);

send_tx(solana, place_bid_ix.clone()).await.unwrap();
send_tx(solana, place_ask_ix.clone()).await.unwrap();
send_tx(solana, consume_events_ix.clone()).await.unwrap();
send_tx(solana, settle_funds_ix.clone()).await.unwrap();

let balances_after = (
solana.token_account_balance(owner_base_ata).await,
solana.token_account_balance(owner_quote_ata).await,
);

assert_eq!(balances_before, balances_after);

send_tx(solana, place_ask_ix).await.unwrap();
send_tx(solana, place_bid_ix).await.unwrap();
send_tx(solana, consume_events_ix).await.unwrap();
send_tx(solana, settle_funds_ix).await.unwrap();

let balances_after = (
solana.token_account_balance(owner_base_ata).await,
solana.token_account_balance(owner_quote_ata).await,
);

assert_eq!(balances_before, balances_after);

Ok(())
}
3 changes: 3 additions & 0 deletions programs/openbook-v2/tests/program_test/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ impl ClientInstruction for CreateMarketInstruction {
}
}

#[derive(Clone)]
pub struct PlaceOrderInstruction {
pub open_orders_account: Pubkey,
pub open_orders_admin: Option<TestKeypair>,
Expand Down Expand Up @@ -637,6 +638,7 @@ impl ClientInstruction for CancelAllOrdersInstruction {
}
}

#[derive(Clone)]
pub struct ConsumeEventsInstruction {
pub consume_events_admin: Option<TestKeypair>,
pub market: Pubkey,
Expand Down Expand Up @@ -724,6 +726,7 @@ impl ClientInstruction for ConsumeGivenEventsInstruction {
}
}

#[derive(Clone)]
pub struct SettleFundsInstruction {
pub owner: TestKeypair,
pub open_orders_account: Pubkey,
Expand Down

0 comments on commit 0d32e32

Please sign in to comment.