From 44d7608d8e0749c5468f9d88d0a671bb72a4a971 Mon Sep 17 00:00:00 2001 From: skrrb Date: Thu, 14 Sep 2023 16:19:21 +0200 Subject: [PATCH] fix confidence if combined variance --- programs/openbook-v2/src/state/market.rs | 15 ++------------- programs/openbook-v2/src/state/oracle.rs | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/programs/openbook-v2/src/state/market.rs b/programs/openbook-v2/src/state/market.rs index 16a2c76d9..96e407982 100644 --- a/programs/openbook-v2/src/state/market.rs +++ b/programs/openbook-v2/src/state/market.rs @@ -250,24 +250,13 @@ impl Market { if oracle_a.is_stale(oracle_a_acc.key(), &self.oracle_config, now_slot) || oracle_b.is_stale(oracle_b_acc.key(), &self.oracle_config, now_slot) + || !oracle_a.has_valid_combined_confidence(&oracle_b, &self.oracle_config) { - return Ok(None); - } - - let (price, var) = oracle_a.combine_div_with_var(&oracle_b); - - let target_var = self.oracle_config.conf_filter.powi(2); - if var > target_var { - msg!( - "Combined variance too high; value {}, target {}", - var, - target_var - ); Ok(None) } else { + let price = oracle_a.price / oracle_b.price; let decimals = (self.quote_decimals as i8) - (self.base_decimals as i8); let decimal_adj = oracle::power_of_ten_float(decimals); - Ok(I80F48::checked_from_num(price * decimal_adj)) } } diff --git a/programs/openbook-v2/src/state/oracle.rs b/programs/openbook-v2/src/state/oracle.rs index f6a03ce31..ff920f2f3 100644 --- a/programs/openbook-v2/src/state/oracle.rs +++ b/programs/openbook-v2/src/state/oracle.rs @@ -111,16 +111,26 @@ impl OracleState { } } - pub fn combine_div_with_var(&self, other: &Self) -> (f64, f64) { - let price = self.price / other.price; - + pub fn has_valid_combined_confidence(&self, other: &Self, config: &OracleConfig) -> bool { // target uncertainty reads // $ \sigma \approx \frac{A}{B} * \sqrt{(\sigma_A/A)^2 + (\sigma_B/B)^2} $ // but alternatively, to avoid costly operations, we compute the square - let var = ((self.deviation / self.price).powi(2) + (other.deviation / other.price).powi(2)) - * price.powi(2); + // Also note that the relative scaled var, i.e. without the \frac{A}{B} factor, is computed + let relative_var = + (self.deviation / self.price).powi(2) + (other.deviation / other.price).powi(2); + + let relative_target_var = config.conf_filter.powi(2); - (price, var) + if relative_var > relative_target_var { + msg!( + "Combined confidence too high: computed^2: {}, conf_filter^2: {}", + relative_var, + relative_target_var + ); + false + } else { + true + } } }