Skip to content

Commit 6b6ac04

Browse files
authored
Merge pull request #19 from drift-labs/ahzam/add-oracle-override
Add pyth price overrides to margin check
2 parents df8c576 + 616d521 commit 6b6ac04

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

src/margin.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,19 @@ pub fn calculate_simplified_margin_requirement(
8585
}
8686

8787
let spot_market = market_state.get_spot_market(spot_position.market_index);
88-
let oracle_price = market_state.get_spot_oracle_price(spot_position.market_index);
88+
let oracle_price = match market_state.get_spot_pyth_price(spot_position.market_index) {
89+
Some(pyth_price) => {
90+
let oracle = market_state.get_spot_oracle_price(spot_position.market_index);
91+
let diff_bps = (pyth_price.price.abs_diff(oracle.price) * 10_000)
92+
/ oracle.price.unsigned_abs();
93+
if diff_bps > market_state.pyth_oracle_diff_threshold_bps {
94+
pyth_price
95+
} else {
96+
*oracle
97+
}
98+
}
99+
None => *market_state.get_spot_oracle_price(spot_position.market_index),
100+
};
89101

90102
let signed_token_amount = spot_position.get_signed_token_amount(spot_market).unwrap();
91103

@@ -186,7 +198,19 @@ pub fn calculate_simplified_margin_requirement(
186198
}
187199

188200
let perp_market = market_state.get_perp_market(perp_position.market_index);
189-
let oracle_price = market_state.get_perp_oracle_price(perp_position.market_index);
201+
let oracle_price = match market_state.get_perp_pyth_price(perp_position.market_index) {
202+
Some(pyth_price) => {
203+
let oracle = market_state.get_perp_oracle_price(perp_position.market_index);
204+
let diff_bps = (pyth_price.price.abs_diff(oracle.price) * 10_000)
205+
/ oracle.price.unsigned_abs();
206+
if diff_bps > market_state.pyth_oracle_diff_threshold_bps {
207+
pyth_price
208+
} else {
209+
*oracle
210+
}
211+
}
212+
None => *market_state.get_perp_oracle_price(perp_position.market_index),
213+
};
190214

191215
let strict_quote_price = {
192216
let quote_price_data =
@@ -213,7 +237,7 @@ pub fn calculate_simplified_margin_requirement(
213237
) = calculate_perp_position_value_and_pnl(
214238
perp_position,
215239
perp_market,
216-
oracle_price,
240+
&oracle_price,
217241
&strict_quote_price,
218242
margin_type,
219243
user_custom_margin_ratio.max(perp_position_custom_margin_ratio),

src/types.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ pub struct MarketState {
227227
pub perp_markets: HashMap<u16, PerpMarket, FxBuildHasher>,
228228
pub spot_oracle_prices: HashMap<u16, OraclePriceData, FxBuildHasher>,
229229
pub perp_oracle_prices: HashMap<u16, OraclePriceData, FxBuildHasher>,
230+
pub spot_pyth_prices: HashMap<u16, i64, FxBuildHasher>, // Override spot with pyth price
231+
pub perp_pyth_prices: HashMap<u16, i64, FxBuildHasher>, // Override perp with pyth price
232+
pub pyth_oracle_diff_threshold_bps: u64, // Min bps diff to prefer pyth price over oracle. Defaults to 0 (always use pyth when set).
230233
}
231234

232235
impl MarketState {
@@ -246,6 +249,30 @@ impl MarketState {
246249
self.perp_oracle_prices.get(&market_index).unwrap()
247250
}
248251

252+
pub fn get_spot_pyth_price(&self, market_index: u16) -> Option<OraclePriceData> {
253+
self.spot_pyth_prices
254+
.get(&market_index)
255+
.map(|&price| OraclePriceData {
256+
price,
257+
confidence: 0,
258+
delay: 0,
259+
has_sufficient_number_of_data_points: true,
260+
sequence_id: None,
261+
})
262+
}
263+
264+
pub fn get_perp_pyth_price(&self, market_index: u16) -> Option<OraclePriceData> {
265+
self.perp_pyth_prices
266+
.get(&market_index)
267+
.map(|&price| OraclePriceData {
268+
price,
269+
confidence: 0,
270+
delay: 0,
271+
has_sufficient_number_of_data_points: true,
272+
sequence_id: None,
273+
})
274+
}
275+
249276
pub fn set_spot_market(&mut self, market: SpotMarket) {
250277
self.spot_markets.insert(market.market_index, market);
251278
}
@@ -261,4 +288,12 @@ impl MarketState {
261288
pub fn set_perp_oracle_price(&mut self, market_index: u16, price_data: OraclePriceData) {
262289
self.perp_oracle_prices.insert(market_index, price_data);
263290
}
291+
292+
pub fn set_spot_pyth_price(&mut self, market_index: u16, price_data: i64) {
293+
self.spot_pyth_prices.insert(market_index, price_data);
294+
}
295+
296+
pub fn set_perp_pyth_price(&mut self, market_index: u16, price_data: i64) {
297+
self.perp_pyth_prices.insert(market_index, price_data);
298+
}
264299
}

0 commit comments

Comments
 (0)