Skip to content
Open
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
4 changes: 4 additions & 0 deletions programs/drift/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,10 @@ pub enum ErrorCode {
MarketIndexNotFoundAmmCache,
#[msg("Invalid Isolated Perp Market")]
InvalidIsolatedPerpMarket,
#[msg("Invalid scale order count - must be between 2 and 10")]
InvalidOrderScaleOrderCount,
#[msg("Invalid scale order price range")]
InvalidOrderScalePriceRange,
}

#[macro_export]
Expand Down
59 changes: 54 additions & 5 deletions programs/drift/src/instructions/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ use crate::state::order_params::{
PlaceOrderOptions, PostOnlyParam,
};
use crate::state::paused_operations::{PerpOperation, SpotOperation};
use crate::state::scale_order_params::ScaleOrderParams;
use crate::state::perp_market::MarketStatus;
use crate::state::perp_market_map::{get_writable_perp_market_set, MarketSet};
use crate::state::protected_maker_mode_config::ProtectedMakerModeConfig;
Expand Down Expand Up @@ -2606,6 +2607,31 @@ pub fn handle_modify_order_by_user_order_id<'c: 'info, 'info>(
pub fn handle_place_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: Vec<OrderParams>,
) -> Result<()> {
place_orders(&ctx, PlaceOrdersInput::Orders(params))
}

#[access_control(
exchange_not_paused(&ctx.accounts.state)
)]
pub fn handle_place_scale_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: ScaleOrderParams,
) -> Result<()> {
place_orders(&ctx, PlaceOrdersInput::ScaleOrders(params))
}

/// Input for place_orders - either direct OrderParams or ScaleOrderParams to expand
enum PlaceOrdersInput {
Orders(Vec<OrderParams>),
ScaleOrders(ScaleOrderParams),
}

/// Internal implementation for placing multiple orders.
/// Used by both handle_place_orders and handle_place_scale_orders.
fn place_orders<'c: 'info, 'info>(
ctx: &Context<'_, '_, 'c, 'info, PlaceOrder>,
input: PlaceOrdersInput,
) -> Result<()> {
let clock = &Clock::get()?;
let state = &ctx.accounts.state;
Expand All @@ -2625,17 +2651,40 @@ pub fn handle_place_orders<'c: 'info, 'info>(

let high_leverage_mode_config = get_high_leverage_mode_config(&mut remaining_accounts)?;

// Convert input to order params, expanding scale orders if needed
let order_params = match input {
PlaceOrdersInput::Orders(params) => params,
PlaceOrdersInput::ScaleOrders(scale_params) => {
let order_step_size = match scale_params.market_type {
MarketType::Perp => {
let market = perp_market_map.get_ref(&scale_params.market_index)?;
market.amm.order_step_size
}
MarketType::Spot => {
let market = spot_market_map.get_ref(&scale_params.market_index)?;
market.order_step_size
}
};

scale_params.expand_to_order_params(order_step_size)
.map_err(|e| {
msg!("Failed to expand scale order params: {:?}", e);
ErrorCode::InvalidOrder
})?
}
};

validate!(
params.len() <= 32,
order_params.len() <= 32,
ErrorCode::DefaultError,
"max 32 order params"
)?;

let user_key = ctx.accounts.user.key();
let mut user = load_mut!(ctx.accounts.user)?;

let num_orders = params.len();
for (i, params) in params.iter().enumerate() {
let num_orders = order_params.len();
for (i, params) in order_params.iter().enumerate() {
validate!(
!params.is_immediate_or_cancel(),
ErrorCode::InvalidOrderIOC,
Expand All @@ -2654,7 +2703,7 @@ pub fn handle_place_orders<'c: 'info, 'info>(

if params.market_type == MarketType::Perp {
controller::orders::place_perp_order(
&ctx.accounts.state,
state,
&mut user,
user_key,
&perp_market_map,
Expand All @@ -2668,7 +2717,7 @@ pub fn handle_place_orders<'c: 'info, 'info>(
)?;
} else {
controller::orders::place_spot_order(
&ctx.accounts.state,
state,
&mut user,
user_key,
&perp_market_map,
Expand Down
8 changes: 8 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::controller::position::PositionDirection;
use crate::state::if_rebalance_config::IfRebalanceConfigParams;
use crate::state::oracle::PrelaunchOracleParams;
use crate::state::order_params::{ModifyOrderParams, OrderParams};
use crate::state::scale_order_params::ScaleOrderParams;
use crate::state::perp_market::{ContractTier, MarketStatus};
use crate::state::settle_pnl_mode::SettlePnlMode;
use crate::state::spot_market::AssetTier;
Expand Down Expand Up @@ -367,6 +368,13 @@ pub mod drift {
handle_place_orders(ctx, params)
}

pub fn place_scale_orders<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, PlaceOrder>,
params: ScaleOrderParams,
) -> Result<()> {
handle_place_scale_orders(ctx, params)
}

pub fn begin_swap<'c: 'info, 'info>(
ctx: Context<'_, '_, 'c, 'info, Swap<'info>>,
in_market_index: u16,
Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub mod oracle;
pub mod oracle_map;
pub mod order_params;
pub mod paused_operations;
pub mod scale_order_params;
pub mod perp_market;
pub mod perp_market_map;
pub mod protected_maker_mode_config;
Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/state/order_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,3 +1027,4 @@ pub fn parse_optional_params(optional_params: Option<u32>) -> (u8, u8) {
None => (0, 100),
}
}

Loading
Loading