Skip to content

Commit

Permalink
Merge pull request #100 from openbook-dex/feature/penalty
Browse files Browse the repository at this point in the history
Feature/penalty
  • Loading branch information
binyebarwe authored Jul 13, 2023
2 parents 9febfe0 + 32480e0 commit 5474b42
Show file tree
Hide file tree
Showing 10 changed files with 7 additions and 186 deletions.
4 changes: 0 additions & 4 deletions programs/openbook-v2/src/instructions/create_market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub fn create_market(
base_lot_size: i64,
maker_fee: i64,
taker_fee: i64,
fee_penalty: u64,
time_expiry: i64,
) -> Result<()> {
let now_ts: u64 = Clock::get()?.unix_timestamp.try_into().unwrap();
Expand Down Expand Up @@ -87,11 +86,8 @@ pub fn create_market(
base_lot_size,
seq_num: 0,
registration_time: now_ts,

maker_fee,
taker_fee,
fee_penalty,

fees_accrued: 0,
fees_to_referrers: 0,
taker_volume_wo_oo: 0,
Expand Down
4 changes: 2 additions & 2 deletions programs/openbook-v2/src/instructions/place_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub fn place_order(ctx: Context<PlaceOrder>, order: Order, limit: u8) -> Result<
Side::Bid => {
let free_quote = position.quote_free_native;
let max_quote_including_fees =
total_quote_taken_native + posted_quote_native as u64 + maker_fees;
total_quote_taken_native + posted_quote_native + maker_fees;

let free_qty_to_lock = cmp::min(max_quote_including_fees, free_quote);
let deposit_amount = max_quote_including_fees - free_qty_to_lock;
Expand All @@ -93,7 +93,7 @@ pub fn place_order(ctx: Context<PlaceOrder>, order: Order, limit: u8) -> Result<

Side::Ask => {
let free_assets_native = position.base_free_native;
let max_base_native = total_base_taken_native + posted_base_native as u64;
let max_base_native = total_base_taken_native + posted_base_native;

let free_qty_to_lock = cmp::min(max_base_native, free_assets_native);
let deposit_amount = max_base_native - free_qty_to_lock;
Expand Down
2 changes: 0 additions & 2 deletions programs/openbook-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ pub mod openbook_v2 {
base_lot_size: i64,
maker_fee: i64,
taker_fee: i64,
fee_penalty: u64,
time_expiry: i64,
) -> Result<()> {
#[cfg(feature = "enable-gpl")]
Expand All @@ -56,7 +55,6 @@ pub mod openbook_v2 {
base_lot_size,
maker_fee,
taker_fee,
fee_penalty,
time_expiry,
)?;
Ok(())
Expand Down
12 changes: 1 addition & 11 deletions programs/openbook-v2/src/state/market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ pub struct Market {
pub maker_fee: i64,
/// Fee (in 10^-6) for taker orders, always >= 0.
pub taker_fee: i64,
/// Fee (in quote native) to charge for ioc orders that don't match to avoid spam
pub fee_penalty: u64,

/// Total fees accrued in native quote
pub fees_accrued: u64,
Expand Down Expand Up @@ -133,7 +131,6 @@ const_assert_eq!(
8 + // registration_time
8 + // maker_fee
8 + // taker_fee
8 + // fee_penalty
8 + // fees_accrued
8 + // fees_to_referrers
8 + // taker_volume_wo_oo
Expand All @@ -144,7 +141,7 @@ const_assert_eq!(
8 + // referrer_rebates_accrued
1768 // reserved
);
const_assert_eq!(size_of::<Market>(), 2392);
const_assert_eq!(size_of::<Market>(), 2384);
const_assert_eq!(size_of::<Market>() % 8, 0);

impl Market {
Expand Down Expand Up @@ -200,13 +197,6 @@ impl Market {
)
}

/// Update the market's quote fees acrued and returns the penalty fee
pub fn apply_penalty(&mut self) -> u64 {
self.quote_fees_accrued += self.fee_penalty;
self.fees_accrued += self.fee_penalty;
self.fee_penalty
}

pub fn subtract_taker_fees(&self, quote: i64) -> i64 {
((quote as i128) * FEES_SCALE_FACTOR / (FEES_SCALE_FACTOR + (self.taker_fee as i128)))
.try_into()
Expand Down
11 changes: 4 additions & 7 deletions programs/openbook-v2/src/state/orderbook/book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ pub struct Orderbook<'a> {

pub struct OrderWithAmounts {
pub order_id: Option<u128>,
pub posted_base_native: i64,
pub posted_quote_native: i64,
pub posted_base_native: u64,
pub posted_quote_native: u64,
pub total_base_taken_native: u64,
pub total_quote_taken_native: u64,
pub maker_fees: u64,
Expand Down Expand Up @@ -294,9 +294,6 @@ impl<'a> Orderbook<'a> {
total_quantity_received,
fees: taker_fees,
});
} else if order.needs_penalty_fee() {
// IOC orders have a fee penalty applied if not match to avoid spam
total_quote_taken_native += market.apply_penalty();
}

// Update remaining based on quote_lots taken. If nothing taken, same as the beginning
Expand Down Expand Up @@ -450,8 +447,8 @@ impl<'a> Orderbook<'a> {

Ok(OrderWithAmounts {
order_id: placed_order_id,
posted_base_native,
posted_quote_native,
posted_base_native: posted_base_native as u64,
posted_quote_native: posted_quote_native as u64,
total_base_taken_native,
total_quote_taken_native,
referrer_amount,
Expand Down
111 changes: 0 additions & 111 deletions programs/openbook-v2/src/state/orderbook/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,117 +428,6 @@ mod queue;
// );
// }

// #[test]
// fn test_fee_penalty_applied_only_on_limit_order() -> Result<()> {
// let (mut market, oracle_price, mut event_queue, book_accs) = test_setup(1000.0);
// let mut book = book_accs.orderbook();

// let buffer = OpenOrdersAccount::default_for_tests().try_to_vec().unwrap();
// let mut account = OpenOrdersAccountValue::from_bytes(&buffer).unwrap();
// let taker_pk = Pubkey::new_unique();
// let now_ts = 1000000;

// market.taker_fee = I80F48::from_num(0.01);
// market.fee_penalty = 5.0;
// account.ensure_position(market.market_index, 0)?;

// // Passive order
// book.new_order(
// Order {
// side: Side::Ask,
// max_base_lots: 2,
// max_quote_lots_including_fees: i64::MAX,
// client_order_id: 43,
// time_in_force: 0,
// params: OrderParams::Fixed {
// price_lots: 1000,
// order_type: PostOrderType::Limit,
// },
// },
// &mut market,
// &mut event_queue,
// oracle_price,
// &mut account.borrow_mut(),
// &taker_pk,
// now_ts,
// u8::MAX,
// )
// .unwrap();

// // Partial taker
// book.new_order(
// Order {
// side: Side::Bid,
// max_base_lots: 1,
// max_quote_lots_including_fees: i64::MAX,
// client_order_id: 43,
// time_in_force: 0,
// params: OrderParams::Fixed {
// price_lots: 1000,
// order_type: PostOrderType::Limit,
// },
// },
// &mut market,
// &mut event_queue,
// oracle_price,
// &mut account.borrow_mut(),
// &taker_pk,
// now_ts,
// u8::MAX,
// )
// .unwrap();

// let pos = account.position(market.market_index)?;

// assert_eq!(
// pos.quote_position_native().round(),
// I80F48::from_num(-10),
// "Regular fees applied on limit order"
// );

// assert_eq!(
// market.fees_accrued.round(),
// I80F48::from_num(10),
// "Fees moved to market"
// );

// // Full taker
// book.new_order(
// Order {
// side: Side::Bid,
// max_base_lots: 1,
// max_quote_lots_including_fees: i64::MAX,
// client_order_id: 43,
// time_in_force: 0,
// params: OrderParams::ImmediateOrCancel { price_lots: 1000 },
// },
// &mut market,
// &mut event_queue,
// oracle_price,
// &mut account.borrow_mut(),
// &taker_pk,
// now_ts,
// u8::MAX,
// )
// .unwrap();

// let pos = account.position(market.market_index)?;

// assert_eq!(
// pos.quote_position_native().round(),
// I80F48::from_num(-25), // -10 - 5
// "Regular fees + fixed penalty applied on IOC order"
// );

// assert_eq!(
// market.fees_accrued.round(),
// I80F48::from_num(25), // 10 + 5
// "Fees moved to market"
// );

// Ok(())
// }

// // Check that there are no zero-quantity fills when max_quote_lots is not
// // enough for a single lot
// #[test]
Expand Down
8 changes: 0 additions & 8 deletions programs/openbook-v2/src/state/orderbook/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ impl Order {
}
}

/// Should this order be penalized with an extra fee?
///
/// Some programs opportunistically call ioc orders, wasting lots of compute. This
/// is intended to encourage people to be smarter about it.
pub fn needs_penalty_fee(&self) -> bool {
matches!(self.params, OrderParams::ImmediateOrCancel { .. })
}

/// Is this order required to be posted to the orderbook? It will fail if it would take.
pub fn is_post_only(&self) -> bool {
let order_type = match self.params {
Expand Down
39 changes: 0 additions & 39 deletions programs/openbook-v2/tests/cases/test_fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use super::*;

#[tokio::test]
async fn test_fees_accrued() -> Result<(), TransportError> {
let fee_penalty = 1000;
let TestInitialize {
context,
collect_fee_admin,
Expand All @@ -19,7 +18,6 @@ async fn test_fees_accrued() -> Result<(), TransportError> {
account_1,
..
} = TestContext::new_with_market(TestNewMarketInitialize {
fee_penalty,
maker_fee: -100,
taker_fee: 200,
..TestNewMarketInitialize::default()
Expand Down Expand Up @@ -161,43 +159,6 @@ async fn test_fees_accrued() -> Result<(), TransportError> {
assert_eq!(market.fees_to_referrers, 0);
}

let balance_quote = solana.token_account_balance(owner_token_1).await;

// Order with penalty fees
send_tx(
solana,
PlaceOrderInstruction {
open_orders_account: account_1,
open_orders_admin: None,
market,
owner,
token_deposit_account: owner_token_1,
market_vault: quote_vault,
side: Side::Bid,
price_lots: price_lots - 1000,
max_base_lots: 1,
max_quote_lots_including_fees: 10000,
client_order_id: 0,
expiry_timestamp: 0,
order_type: PlaceOrderType::ImmediateOrCancel,
self_trade_behavior: SelfTradeBehavior::default(),
remainings: vec![],
},
)
.await
.unwrap();

{
let market = solana.get_account::<Market>(market).await;
assert_eq!(market.quote_fees_accrued, 1000);
assert_eq!(market.fees_accrued, 10 + market.fee_penalty);
assert_eq!(market.fees_to_referrers, 0);
assert_eq!(
balance_quote - fee_penalty,
solana.token_account_balance(owner_token_1).await
);
}

Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion programs/openbook-v2/tests/cases/test_ioc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ async fn test_ioc() -> Result<(), TransportError> {
account_1,
..
} = TestContext::new_with_market(TestNewMarketInitialize {
fee_penalty,
maker_fee: 200,
taker_fee: 200,
..TestNewMarketInitialize::default()
Expand Down
1 change: 0 additions & 1 deletion programs/openbook-v2/tests/program_test/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ impl ClientInstruction for CreateMarketInstruction {
base_lot_size: self.base_lot_size,
maker_fee: self.maker_fee,
taker_fee: self.taker_fee,
fee_penalty: self.fee_penalty,
time_expiry: self.time_expiry,
};

Expand Down

0 comments on commit 5474b42

Please sign in to comment.