Skip to content

Commit

Permalink
program: add auction_duration_percentage to place and take (#1320)
Browse files Browse the repository at this point in the history
* program: add auction_duration_percentage to place and take

* change defaults and make more readable

* change sdk default

* cargo fmt -- and yarn prettify:fix

* CHANGELOG
  • Loading branch information
crispheaney authored Nov 13, 2024
1 parent fd424de commit 5117f94
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 25 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: add auction_duration_percentage to place and take ([#1320](https://github.com/drift-labs/protocol-v2/pull/1320))
- program: more lenient w invalid deposit oracles ([#1324](https://github.com/drift-labs/protocol-v2/pull/1324))

### Fixes
Expand Down
2 changes: 1 addition & 1 deletion programs/drift/src/controller/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10784,7 +10784,7 @@ pub mod get_maker_orders_info {
Some(2),
clock.unix_timestamp,
clock.slot,
FillMode::PlaceAndTake(false),
FillMode::PlaceAndTake(false, 0),
)
.unwrap();

Expand Down
39 changes: 21 additions & 18 deletions programs/drift/src/instructions/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ use crate::state::high_leverage_mode_config::HighLeverageModeConfig;
use crate::state::oracle::StrictOraclePrice;
use crate::state::order_params::RFQMatch;
use crate::state::order_params::{
ModifyOrderParams, OrderParams, PlaceAndTakeOrderSuccessCondition, PlaceOrderOptions,
PostOnlyParam,
parse_optional_params, ModifyOrderParams, OrderParams, PlaceAndTakeOrderSuccessCondition,
PlaceOrderOptions, PostOnlyParam,
};
use crate::state::paused_operations::{PerpOperation, SpotOperation};
use crate::state::perp_market::ContractType;
Expand Down Expand Up @@ -1299,7 +1299,7 @@ pub fn handle_place_orders<'c: 'info, 'info>(
pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceAndTake<'info>>,
params: OrderParams,
success_condition: Option<u32>, // u32 for backwards compatibility
optional_params: Option<u32>, // u32 for backwards compatibility
) -> Result<()> {
let clock = Clock::get()?;
let state = &ctx.accounts.state;
Expand Down Expand Up @@ -1339,6 +1339,8 @@ pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
let mut user = load_mut!(ctx.accounts.user)?;
let clock = Clock::get()?;

let (success_condition, auction_duration_percentage) = parse_optional_params(optional_params);

controller::orders::place_perp_order(
&ctx.accounts.state,
&mut user,
Expand Down Expand Up @@ -1370,7 +1372,10 @@ pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
&makers_and_referrer_stats,
None,
&Clock::get()?,
FillMode::PlaceAndTake(is_immediate_or_cancel || success_condition.is_some()),
FillMode::PlaceAndTake(
is_immediate_or_cancel || optional_params.is_some(),
auction_duration_percentage,
),
)?;

let order_exists = load!(ctx.accounts.user)?
Expand All @@ -1389,20 +1394,18 @@ pub fn handle_place_and_take_perp_order<'c: 'info, 'info>(
)?;
}

if let Some(success_condition) = success_condition {
if success_condition == PlaceAndTakeOrderSuccessCondition::PartialFill as u32 {
validate!(
base_asset_amount_filled > 0,
ErrorCode::PlaceAndTakeOrderSuccessConditionFailed,
"no partial fill"
)?;
} else if success_condition == PlaceAndTakeOrderSuccessCondition::FullFill as u32 {
validate!(
base_asset_amount_filled > 0 && !order_exists,
ErrorCode::PlaceAndTakeOrderSuccessConditionFailed,
"no full fill"
)?;
}
if success_condition == PlaceAndTakeOrderSuccessCondition::PartialFill as u8 {
validate!(
base_asset_amount_filled > 0,
ErrorCode::PlaceAndTakeOrderSuccessConditionFailed,
"no partial fill"
)?;
} else if success_condition == PlaceAndTakeOrderSuccessCondition::FullFill as u8 {
validate!(
base_asset_amount_filled > 0 && !order_exists,
ErrorCode::PlaceAndTakeOrderSuccessConditionFailed,
"no full fill"
)?;
}

Ok(())
Expand Down
15 changes: 11 additions & 4 deletions programs/drift/src/state/fill_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod tests;
pub enum FillMode {
Fill,
PlaceAndMake,
PlaceAndTake(bool),
PlaceAndTake(bool, u8),
Liquidation,
RFQ,
}
Expand All @@ -35,11 +35,18 @@ impl FillMode {
is_prediction_market,
)
}
FillMode::PlaceAndTake(_) => {
FillMode::PlaceAndTake(_, auction_duration_percentage) => {
let auction_duration = order
.auction_duration
.cast::<u64>()?
.safe_mul(auction_duration_percentage.min(&100).cast()?)?
.safe_div(100)?
.cast::<u64>()?;

if order.has_auction() {
calculate_auction_price(
order,
order.slot.safe_add(order.auction_duration.cast()?)?,
order.slot.safe_add(auction_duration)?,
tick_size,
valid_oracle_price,
is_prediction_market,
Expand Down Expand Up @@ -67,6 +74,6 @@ impl FillMode {
}

pub fn is_ioc(&self) -> bool {
self == &FillMode::PlaceAndTake(true)
matches!(self, FillMode::PlaceAndTake(true, _))
}
}
2 changes: 1 addition & 1 deletion programs/drift/src/state/fill_mode/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn test() {

assert_eq!(limit_price, Some(100 * PRICE_PRECISION_U64));

let place_and_take_mode = FillMode::PlaceAndTake(false);
let place_and_take_mode = FillMode::PlaceAndTake(false, 100);

let limit_price = place_and_take_mode
.get_limit_price(&market_order, oracle_price, slot, tick_size, false)
Expand Down
10 changes: 10 additions & 0 deletions programs/drift/src/state/order_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,3 +872,13 @@ pub enum PlaceAndTakeOrderSuccessCondition {
PartialFill = 1,
FullFill = 2,
}

pub fn parse_optional_params(optional_params: Option<u32>) -> (u8, u8) {
match optional_params {
Some(optional_params) => (
(optional_params & 255) as u8,
((optional_params >> 8) & 255) as u8,
),
None => (0, 100),
}
}
9 changes: 9 additions & 0 deletions programs/drift/src/state/order_params/tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::state::order_params::parse_optional_params;

mod get_auction_duration {
use crate::state::order_params::get_auction_duration;
use crate::{ContractTier, PRICE_PRECISION_U64};
Expand Down Expand Up @@ -1443,3 +1445,10 @@ mod get_close_perp_params {
validate_order(&order, &perp_market, Some(oracle_price), slot).unwrap();
}
}

#[test]
fn test_parse_optional_params() {
let (success_condition, auction_duration_percentage) = parse_optional_params(Some(0x00001234));
assert_eq!(success_condition, 0x34);
assert_eq!(auction_duration_percentage, 0x12);
}
12 changes: 11 additions & 1 deletion sdk/src/driftClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5271,6 +5271,7 @@ export class DriftClient {
makerInfo?: MakerInfo | MakerInfo[],
referrerInfo?: ReferrerInfo,
successCondition?: PlaceAndTakeOrderSuccessCondition,
auctionDurationPercentage?: number,
txParams?: TxParams,
subAccountId?: number
): Promise<TransactionSignature> {
Expand All @@ -5281,6 +5282,7 @@ export class DriftClient {
makerInfo,
referrerInfo,
successCondition,
auctionDurationPercentage,
subAccountId
),
txParams
Expand Down Expand Up @@ -5329,6 +5331,7 @@ export class DriftClient {
makerInfo,
referrerInfo,
undefined,
undefined,
subAccountId
);

Expand Down Expand Up @@ -5520,6 +5523,7 @@ export class DriftClient {
makerInfo?: MakerInfo | MakerInfo[],
referrerInfo?: ReferrerInfo,
successCondition?: PlaceAndTakeOrderSuccessCondition,
auctionDurationPercentage?: number,
subAccountId?: number
): Promise<TransactionInstruction> {
orderParams = getOrderParams(orderParams, { marketType: MarketType.PERP });
Expand Down Expand Up @@ -5574,9 +5578,15 @@ export class DriftClient {
}
}

let optionalParams = null;
if (auctionDurationPercentage || successCondition) {
optionalParams =
((successCondition ?? 0) << 8) | (auctionDurationPercentage ?? 100);
}

return await this.program.instruction.placeAndTakePerpOrder(
orderParams,
successCondition ?? null,
optionalParams,
{
accounts: {
state: await this.getStatePublicKey(),
Expand Down

0 comments on commit 5117f94

Please sign in to comment.