Skip to content

Commit

Permalink
program: more lenient w invalid deposit oracles (#1324)
Browse files Browse the repository at this point in the history
* program: dont have stale deposits cause a withdraw to fail

* add test

* increase oracle validity for stable coins

* sat mul

* CHANGELOG
  • Loading branch information
crispheaney authored Nov 13, 2024
1 parent 8402c60 commit fd424de
Show file tree
Hide file tree
Showing 11 changed files with 438 additions and 30 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: more lenient w invalid deposit oracles ([#1324](https://github.com/drift-labs/protocol-v2/pull/1324))

### Fixes

- sdk: getBestBids/Asks only considers price/time priority ([#1322](https://github.com/drift-labs/protocol-v2/pull/1322))
Expand Down
2 changes: 2 additions & 0 deletions programs/drift/src/controller/repeg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ pub fn _update_amm(
oracle_price_data,
&state.oracle_guard_rails.validity,
market.get_max_confidence_interval_multiplier()?,
&market.amm.oracle_source,
true,
)?;

Expand Down Expand Up @@ -246,6 +247,7 @@ pub fn update_amm_and_check_validity(
oracle_price_data,
&state.oracle_guard_rails.validity,
market.get_max_confidence_interval_multiplier()?,
&market.amm.oracle_source,
false,
)?;

Expand Down
2 changes: 2 additions & 0 deletions programs/drift/src/controller/repeg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ pub fn update_amm_test() {
&oracle_price_data,
&state.oracle_guard_rails.validity,
market.get_max_confidence_interval_multiplier().unwrap(),
&market.amm.oracle_source,
false,
)
.unwrap()
Expand Down Expand Up @@ -232,6 +233,7 @@ pub fn update_amm_test_bad_oracle() {
&oracle_price_data,
&state.oracle_guard_rails.validity,
market.get_max_confidence_interval_multiplier().unwrap(),
&market.amm.oracle_source,
false,
)
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions programs/drift/src/controller/spot_balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ pub fn update_spot_market_and_check_validity(
oracle_price_data,
validity_guard_rails,
spot_market.get_max_confidence_interval_multiplier()?,
&spot_market.oracle_source,
false,
)?;

Expand Down
54 changes: 38 additions & 16 deletions programs/drift/src/math/margin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,7 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
spot_market.get_max_confidence_interval_multiplier()?,
)?;

calculation.update_all_oracles_valid(is_oracle_valid_for_action(
oracle_validity,
Some(DriftAction::MarginCalc),
)?);
let oracle_valid = is_oracle_valid_for_action(oracle_validity, Some(DriftAction::MarginCalc))?;

let strict_oracle_price = StrictOraclePrice::new(
oracle_price_data.price,
Expand All @@ -293,13 +290,20 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(

calculation.update_fuel_spot_bonus(&spot_market, token_amount, &strict_oracle_price)?;

let token_value =
let mut token_value =
get_strict_token_value(token_amount, spot_market.decimals, &strict_oracle_price)?;

match spot_position.balance_type {
SpotBalanceType::Deposit => {
if calculation.context.ignore_invalid_deposit_oracles && !oracle_valid {
msg!("token_value set to 0 for market_index={}", spot_market.market_index);
token_value = 0;
}

calculation.add_total_collateral(token_value)?;

calculation.update_all_deposit_oracles_valid(oracle_valid);

#[cfg(feature = "drift-rs")]
calculation.add_spot_asset_value(token_value)?;
}
Expand All @@ -322,6 +326,8 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(

calculation.add_spot_liability()?;

calculation.update_all_liability_oracles_valid(oracle_valid);

#[cfg(feature = "drift-rs")]
calculation.add_spot_liability_value(token_value)?;
}
Expand All @@ -337,9 +343,9 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(

let OrderFillSimulation {
token_amount: worst_case_token_amount,
orders_value: worst_case_orders_value,
orders_value: mut worst_case_orders_value,
token_value: worst_case_token_value,
weighted_token_value: worst_case_weighted_token_value,
weighted_token_value: mut worst_case_weighted_token_value,
..
} = spot_position
.get_worst_case_fill_simulation(
Expand Down Expand Up @@ -372,9 +378,16 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(

match worst_case_token_value.cmp(&0) {
Ordering::Greater => {
if calculation.context.ignore_invalid_deposit_oracles && !oracle_valid {
msg!("worst_case_weighted_token_value set to 0 for market_index={}", spot_market.market_index);
worst_case_weighted_token_value = 0;
}

calculation
.add_total_collateral(worst_case_weighted_token_value.cast::<i128>()?)?;

calculation.update_all_deposit_oracles_valid(oracle_valid);

#[cfg(feature = "drift-rs")]
calculation.add_spot_asset_value(worst_case_token_value)?;
}
Expand Down Expand Up @@ -405,12 +418,15 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
spot_market.asset_tier == AssetTier::Isolated,
);

calculation.update_all_liability_oracles_valid(oracle_valid);

#[cfg(feature = "drift-rs")]
calculation.add_spot_liability_value(worst_case_token_value.unsigned_abs())?;
}
Ordering::Equal => {
if spot_position.has_open_order() {
calculation.add_spot_liability()?;
calculation.update_all_liability_oracles_valid(oracle_valid);
calculation.update_with_spot_isolated_liability(
spot_market.asset_tier == AssetTier::Isolated,
);
Expand All @@ -420,6 +436,11 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(

match worst_case_orders_value.cmp(&0) {
Ordering::Greater => {
if calculation.context.ignore_invalid_deposit_oracles && !oracle_valid {
msg!("worst_case_orders_value set to 0 for market_index={}", spot_market.market_index);
worst_case_orders_value = 0;
}

calculation.add_total_collateral(worst_case_orders_value.cast::<i128>()?)?;

#[cfg(feature = "drift-rs")]
Expand Down Expand Up @@ -459,11 +480,6 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
quote_spot_market.get_max_confidence_interval_multiplier()?,
)?;

calculation.update_all_oracles_valid(is_oracle_valid_for_action(
quote_oracle_validity,
Some(DriftAction::MarginCalc),
)?);

let strict_quote_price = StrictOraclePrice::new(
quote_oracle_price_data.price,
quote_spot_market
Expand Down Expand Up @@ -535,7 +551,11 @@ pub fn calculate_margin_requirement_and_total_collateral_and_liability_info(
}

if has_perp_liability || calculation.context.margin_type != MarginRequirementType::Initial {
calculation.update_all_oracles_valid(is_oracle_valid_for_action(
calculation.update_all_liability_oracles_valid(is_oracle_valid_for_action(
quote_oracle_validity,
Some(DriftAction::MarginCalc),
)?);
calculation.update_all_liability_oracles_valid(is_oracle_valid_for_action(
oracle_validity,
Some(DriftAction::MarginCalc),
)?);
Expand Down Expand Up @@ -594,7 +614,9 @@ pub fn meets_withdraw_margin_requirement(
margin_requirement_type: MarginRequirementType,
) -> DriftResult<bool> {
let strict = margin_requirement_type == MarginRequirementType::Initial;
let context = MarginContext::standard(margin_requirement_type).strict(strict);
let context = MarginContext::standard(margin_requirement_type)
.strict(strict)
.ignore_invalid_deposit_oracles(true);

let calculation = calculate_margin_requirement_and_total_collateral_and_liability_info(
user,
Expand All @@ -606,9 +628,9 @@ pub fn meets_withdraw_margin_requirement(

if calculation.margin_requirement > 0 || calculation.get_num_of_liabilities()? > 0 {
validate!(
calculation.all_oracles_valid,
calculation.all_liability_oracles_valid,
ErrorCode::InvalidOracle,
"User attempting to withdraw with outstanding liabilities when an oracle is invalid"
"User attempting to withdraw with outstanding liabilities when a liability oracle is invalid"
)?;
}

Expand Down
Loading

0 comments on commit fd424de

Please sign in to comment.