Skip to content

Commit

Permalink
add posted slot check and test (#1459)
Browse files Browse the repository at this point in the history
* add posted slot check and test

* add postedSlotTail to order type in sdk

* use wrapping sub

* add cargo test for wrapping sub

* add to decode user

* changelog

* add posted slot to helper funcs for orders
  • Loading branch information
NourAlharithi authored Feb 4, 2025
1 parent 68595ec commit 30b2aa9
Show file tree
Hide file tree
Showing 13 changed files with 270 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: add posted slot tail to order struct, use it to determine vamm availability for high volume users ([#1459](https://github.com/drift-labs/protocol-v2/pull/1459))

### Fixes

### Breaking
Expand Down
2 changes: 1 addition & 1 deletion deps/configs/pyth_lazer_storage.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"account": {
"lamports": 1461600,
"data": [
"0XX/ucSvRAlWNZeaIhw0kx4yYguSk6RjBlVV6nH+l81iN63odbEunuz6CK1Zcd4o+Nzo01LZHY6D+ZzeT/uCfsSHQTkBH7V1AQAAAAAAAAABgO/B9IDFYVrz+2c9Qih+mT2p+8NQa25B36MpUIIMLmy5aFZ6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"0XX/ucSvRAkL/td28gTUmmjn6CkzKyvYXJOMcup4pEKu3cXcP7cvDAv+13byBNSaaOfoKTMrK9hck4xy6nikQq7dxdw/ty8MAQAAAAAAAAAB9lIQvuT89bHO4eU3+rz9lQECl2U7lK8E1FT8Rz6Ug0/oNgZ6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"base64"
],
"owner": "pytd2yyk641x7ak7mkaasSJVXh6YYZnC7wTmtgAyxPt",
Expand Down
18 changes: 15 additions & 3 deletions programs/drift/src/controller/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ pub fn place_perp_order(
auction_end_price,
auction_duration,
max_ts,
padding: [0; 3],
posted_slot_tail: get_posted_slot_from_clock_slot(slot),
padding: [0; 2],
};

let valid_oracle_price = Some(oracle_price_data.price);
Expand Down Expand Up @@ -1108,6 +1109,7 @@ pub fn fill_perp_order(
order_oracle_price_offset,
order_direction,
order_auction_duration,
order_posted_slot_tail,
) = get_struct_values!(
user.orders[order_index],
status,
Expand All @@ -1116,7 +1118,8 @@ pub fn fill_perp_order(
price,
oracle_price_offset,
direction,
auction_duration
auction_duration,
posted_slot_tail
);

validate!(
Expand Down Expand Up @@ -1389,9 +1392,17 @@ pub fn fill_perp_order(
return Ok((0, 0));
}

let clock_slot_tail = get_posted_slot_from_clock_slot(slot);

let amm_availability = if amm_is_available {
if amm_can_skip_duration && user_can_skip_duration {
AMMAvailability::Immediate
} else if !user_can_skip_duration
&& (clock_slot_tail.wrapping_sub(order_posted_slot_tail)
< state.min_perp_auction_duration)
{
msg!("Overriding toxic user from afterminduration to unavailble");
AMMAvailability::Unavailable
} else {
AMMAvailability::AfterMinDuration
}
Expand Down Expand Up @@ -3694,7 +3705,8 @@ pub fn place_spot_order(
auction_end_price,
auction_duration,
max_ts,
padding: [0; 3],
posted_slot_tail: get_posted_slot_from_clock_slot(slot),
padding: [0; 2],
};

validate_spot_order(
Expand Down
4 changes: 4 additions & 0 deletions programs/drift/src/math/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1379,3 +1379,7 @@ pub fn select_margin_type_for_perp_maker(

Ok(MarginRequirementType::Fill)
}

pub fn get_posted_slot_from_clock_slot(slot: u64) -> u8 {
(slot & 0xFF) as u8
}
24 changes: 24 additions & 0 deletions programs/drift/src/math/orders/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3891,3 +3891,27 @@ mod fallback_price_logic {
assert_eq!(result, 99500000);
}
}

mod posted_slot_tail {
use crate::math::orders::get_posted_slot_from_clock_slot;

#[test]
fn easy_test() {
let slot: u64 = 318454856;
let posted_slot_tail = get_posted_slot_from_clock_slot(slot);
assert_eq!(posted_slot_tail, (slot % 256) as u8);
}

#[test]
fn constant_diff() {
let starting_slot: u64 = 318454856;

for i in 0..1000 {
let slot = starting_slot + i;
let slot_minus_50 = slot - 50;
let posted_slot_tail = get_posted_slot_from_clock_slot(slot);
let posted_slot_tail_minus_50 = get_posted_slot_from_clock_slot(slot_minus_50);
assert_eq!(posted_slot_tail.wrapping_sub(posted_slot_tail_minus_50), 50);
}
}
}
4 changes: 3 additions & 1 deletion programs/drift/src/state/order_params/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,7 @@ mod update_perp_auction_params {
}

mod get_close_perp_params {
use crate::math::orders::get_posted_slot_from_clock_slot;
use crate::state::oracle::HistoricalOracleData;
use crate::state::order_params::PostOnlyParam;
use crate::state::perp_market::{PerpMarket, AMM};
Expand Down Expand Up @@ -1380,7 +1381,8 @@ mod get_close_perp_params {
auction_end_price: params.auction_end_price.unwrap_or(0),
auction_duration: params.auction_duration.unwrap_or(0),
max_ts: 100,
padding: [0; 3],
posted_slot_tail: get_posted_slot_from_clock_slot(slot),
padding: [0; 2],
}
}

Expand Down
7 changes: 5 additions & 2 deletions programs/drift/src/state/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,9 @@ pub struct Order {
pub trigger_condition: OrderTriggerCondition,
/// How many slots the auction lasts
pub auction_duration: u8,
pub padding: [u8; 3],
/// Last 8 bits of the slot the order was posted on-chain (not order slot for swift orders)
pub posted_slot_tail: u8,
pub padding: [u8; 2],
}

#[derive(Clone, Copy, BorshSerialize, BorshDeserialize, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -1614,7 +1616,8 @@ impl Default for Order {
auction_end_price: 0,
auction_duration: 0,
max_ts: 0,
padding: [0; 3],
posted_slot_tail: 0,
padding: [0; 2],
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion sdk/src/decode/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ export function decodeUser(buffer: Buffer): UserAccount {
offset += 1;
const auctionDuration = buffer.readUInt8(offset);
offset += 1;
offset += 3; // padding
const postedSlotTail = buffer.readUint8(offset);
offset += 2; // padding
orders.push({
slot,
price,
Expand All @@ -263,6 +264,7 @@ export function decodeUser(buffer: Buffer): UserAccount {
immediateOrCancel,
triggerCondition,
auctionDuration,
postedSlotTail,
});
}

Expand Down
9 changes: 8 additions & 1 deletion sdk/src/idl/drift.json
Original file line number Diff line number Diff line change
Expand Up @@ -10875,12 +10875,19 @@
],
"type": "u8"
},
{
"name": "postedSlotTail",
"docs": [
"Last 8 bits of the slot the order was posted on-chain (not order slot for swift orders)"
],
"type": "u8"
},
{
"name": "padding",
"type": {
"array": [
"u8",
3
2
]
}
}
Expand Down
1 change: 1 addition & 0 deletions sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ export type Order = {
auctionStartPrice: BN;
auctionEndPrice: BN;
maxTs: BN;
postedSlotTail: number;
};

export type OrderParams = {
Expand Down
1 change: 1 addition & 0 deletions sdk/tests/user/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const mockOrder: Order = {
auctionStartPrice: ZERO,
auctionEndPrice: ZERO,
maxTs: ZERO,
postedSlotTail: 0,
};

export const mockSpotPosition: SpotPosition = {
Expand Down
Loading

0 comments on commit 30b2aa9

Please sign in to comment.