Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

program: place order does not alter users order base asset amount #293

Merged
merged 4 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixes

- program: allow duplicative reduce only orders ([#293](https://github.com/drift-labs/protocol-v2/pull/293))
- program: fix should_cancel_reduce_only_order
- ts-sdk: add Oracle OrderType to dlob idl

Expand Down
28 changes: 2 additions & 26 deletions programs/drift/src/controller/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,9 @@ pub fn place_perp_order(
market.amm.order_step_size
)?;

let standardized_base_asset_amount =
let base_asset_amount =
standardize_base_asset_amount(params.base_asset_amount, market.amm.order_step_size)?;

let base_asset_amount = if params.reduce_only || force_reduce_only {
calculate_base_asset_amount_for_reduce_only_order(
standardized_base_asset_amount,
params.direction,
market_position.base_asset_amount,
market_position.open_bids,
market_position.open_asks,
)?
} else {
standardized_base_asset_amount
};

if !matches!(
&params.order_type,
OrderType::TriggerMarket | OrderType::TriggerLimit
Expand Down Expand Up @@ -2519,21 +2507,9 @@ pub fn place_spot_order(
spot_market.order_step_size
)?;

let standardized_base_asset_amount =
let base_asset_amount =
standardize_base_asset_amount(params.base_asset_amount, spot_market.order_step_size)?;

let base_asset_amount = if params.reduce_only || force_reduce_only {
calculate_base_asset_amount_for_reduce_only_order(
standardized_base_asset_amount,
params.direction,
signed_token_amount,
spot_position.open_bids,
spot_position.open_asks,
)?
} else {
standardized_base_asset_amount
};

validate!(
is_multiple_of_step_size(base_asset_amount, spot_market.order_step_size)?,
ErrorCode::InvalidOrderNotStepSizeMultiple,
Expand Down
38 changes: 0 additions & 38 deletions programs/drift/src/math/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,44 +144,6 @@ pub fn calculate_quote_asset_amount_for_maker_order(
}
}

pub fn calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount: u64,
order_direction: PositionDirection,
existing_position: i64,
open_bids: i64,
open_asks: i64,
) -> DriftResult<u64> {
let position_plus_open_orders = if existing_position > 0 {
existing_position.safe_add(open_asks)?
} else if existing_position < 0 {
existing_position.safe_add(open_bids)?
} else {
0
};

let signed_order_base_asset_amount: i64 = match order_direction {
PositionDirection::Long => order_base_asset_amount.cast()?,
PositionDirection::Short => -order_base_asset_amount.cast()?,
};

if position_plus_open_orders == 0
|| position_plus_open_orders.signum() == signed_order_base_asset_amount.signum()
{
msg!("Reduce Only Order must decrease existing position size");
msg!(
"position_plus_open_orders = {} signed_order_base_asset_amount = {}",
position_plus_open_orders,
signed_order_base_asset_amount
);
return Err(ErrorCode::InvalidOrderNotRiskReducing);
}

Ok(min(
position_plus_open_orders.unsigned_abs(),
signed_order_base_asset_amount.unsigned_abs(),
))
}

pub fn standardize_base_asset_amount_with_remainder_i128(
base_asset_amount: i128,
step_size: u128,
Expand Down
215 changes: 0 additions & 215 deletions programs/drift/src/math/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,221 +522,6 @@ mod should_expire_order {
}
}

mod calculate_base_asset_amount_for_reduce_only_order {
use crate::controller::position::PositionDirection;
use crate::error::ErrorCode;
use crate::math::orders::calculate_base_asset_amount_for_reduce_only_order;

#[test]
pub fn zero_position() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Long;
let existing_position = 0;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Err(ErrorCode::InvalidOrderNotRiskReducing))
}

#[test]
pub fn long_position_with_equal_asks() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Long;
let existing_position = 1;
let open_bids = 0;
let open_asks = -1;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Err(ErrorCode::InvalidOrderNotRiskReducing))
}

#[test]
pub fn short_position_with_equal_bids() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Long;
let existing_position = -1;
let open_bids = 1;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Err(ErrorCode::InvalidOrderNotRiskReducing))
}

#[test]
pub fn long_position_with_long_order() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Long;
let existing_position = 1;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Err(ErrorCode::InvalidOrderNotRiskReducing))
}

#[test]
pub fn short_position_with_long_order() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Short;
let existing_position = -1;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Err(ErrorCode::InvalidOrderNotRiskReducing))
}

#[test]
pub fn long_position_with_bigger_short_order() {
let order_base_asset_amount = 5;
let order_direction = PositionDirection::Short;
let existing_position = 1;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}

#[test]
pub fn long_position_with_smaller_short_order() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Short;
let existing_position = 5;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}

#[test]
pub fn long_position_with_asks_and_short_order() {
let order_base_asset_amount = 2;
let order_direction = PositionDirection::Short;
let existing_position = 5;
let open_bids = 0;
let open_asks = -4;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}

#[test]
pub fn short_position_with_bigger_long_order() {
let order_base_asset_amount = 5;
let order_direction = PositionDirection::Long;
let existing_position = -1;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}

#[test]
pub fn short_position_with_smaller_long_order() {
let order_base_asset_amount = 1;
let order_direction = PositionDirection::Long;
let existing_position = -5;
let open_bids = 0;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}

#[test]
pub fn short_position_with_bids_and_long_order() {
let order_base_asset_amount = 2;
let order_direction = PositionDirection::Long;
let existing_position = -5;
let open_bids = 4;
let open_asks = 0;

let result = calculate_base_asset_amount_for_reduce_only_order(
order_base_asset_amount,
order_direction,
existing_position,
open_bids,
open_asks,
);

assert_eq!(result, Ok(1))
}
}

mod get_max_fill_amounts {
use crate::controller::position::PositionDirection;
use crate::math::constants::{
Expand Down
1 change: 1 addition & 0 deletions tests/serumTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ describe('serum spot market', () => {
assert(orderActionRecord.quoteAssetAmountFilled.eq(new BN(100000000)));
assert(orderActionRecord.takerFee.eq(new BN(100000)));

await makerDriftClient.fetchAccounts();
assert(makerDriftClient.getQuoteAssetTokenAmount().eq(new BN(11800)));

const solSpotMarket =
Expand Down