pub struct SafeOracleConfig {
pub max_deviation_bps: u32,
pub max_staleness_seconds: u32,
pub previous_max_staleness_seconds: u32,
pub max_cross_source_bps: u32,
pub max_snapshot_age_seconds: u64,
pub min_liquidity_usd: i128,
pub min_trade_count_1h: u32,
pub secondary_oracle: Option<Address>,
pub circuit_breaker_enabled: bool,
pub circuit_breaker_halt_ledgers: u32,
}Expand description
Configuration for the safe_oracle library — the per-pool tuning surface.
Holds the thresholds and toggles consumed by lastprice and the
circuit_breaker module. Integrators construct it once at init time
and pass it to every lastprice call. The library owns no storage of
its own — circuit-breaker halt state lives in the caller’s instance
storage — so the integrator owns where this config lives.
§Spec
See spec §4 — Config Struct. The defaults returned by
SafeOracleConfig::default match the spec’s recommended values
(max_deviation_bps=2000, max_staleness_seconds=300,
max_cross_source_bps=500, min_liquidity_usd=$10,000 at 7-decimal
precision, min_trade_count_1h=5); integrators requiring tighter or
looser thresholds override per-field.
Fields§
§max_deviation_bps: u32§max_staleness_seconds: u32§previous_max_staleness_seconds: u32Maximum staleness (in seconds) for the previous price reference used in deviation comparison.
Distinct from max_staleness_seconds, which gates the current
price. The previous price is intentionally older (one Reflector
resolution window earlier — typically ~5 min) and is allowed to be
further from “now” than the current price, but excessively-stale
references make deviation comparison meaningless: a years-old
previous price compared to a fresh current produces false-positive
ExcessiveDeviation halts.
Default: 900 (15 minutes) — three times the default
max_staleness_seconds = 300. Recommend 2-3× current threshold.
0 is rejected by validate() as a silent-disable.
Phase 7.2 closure of the lib.rs:713 plan — replaces the previous “Phase 7 will add a configurable previous_max_staleness_seconds” doc-only commitment.
max_cross_source_bps: u32§max_snapshot_age_seconds: u64Maximum age (in seconds) of a LiquidityRegistry snapshot still
considered fresh. Phase 4’s check_liquidity rejects snapshots older
than this against env.ledger().timestamp(); the field is wired here
in Phase 3.6 so config-construction sites do not need to change again
when the Layer 2 logic lands.
min_liquidity_usd: i128§min_trade_count_1h: u32§secondary_oracle: Option<Address>Optional secondary oracle for cross-source price verification.
None skips the cross-source guardrail entirely (single-source mode);
Some(addr) activates check_cross_source against the configured
max_cross_source_bps threshold.
Decimals reconciliation (Phase 7.2 closure): when this is
Some(addr), both primary and secondary decimals() are fetched at
cross-source check time and must agree, otherwise the call returns
OracleSafetyViolation::DecimalsMismatch. The pre-7.2 integrator
warning (“verify same precision”) is now enforced at library level.
circuit_breaker_enabled: bool§circuit_breaker_halt_ledgers: u32Implementations§
Source§impl SafeOracleConfig
impl SafeOracleConfig
Sourcepub fn validate(&self) -> Result<(), ConfigError>
pub fn validate(&self) -> Result<(), ConfigError>
Validates the config and returns an error if any field has an out-of-range value. Recommended call site: at integrator initialization, before storing the config in instance storage.
§Spec
See spec §4 — Config Struct. Validation is opt-in (the library
does not enforce it on every lastprice call) so integrators pay
the check exactly once per config change.
§Errors
ConfigError::InvalidDeviationBps—max_deviation_bps == 0or> 10_000.ConfigError::InvalidStalenessSeconds—max_staleness_seconds == 0or> 86_400.ConfigError::InvalidLiquidityThreshold—min_liquidity_usd <= 0(AR.H M1).ConfigError::InvalidCrossSourceBps— secondary configured andmax_cross_source_bps == 0or> 10_000(AR.H L2).ConfigError::InvalidHaltLedgers—circuit_breaker_enabledandcircuit_breaker_halt_ledgers == 0or> MAX_CIRCUIT_BREAKER_HALT_LEDGERS(AR.H L1).ConfigError::InvalidTradeCountThreshold—min_trade_count_1h == 0(Hardening Closure / Debt #22).ConfigError::InvalidSnapshotAge—max_snapshot_age_seconds == 0or> 86_400(Hardening Closure / Debt #22).
§Examples
let config = SafeOracleConfig::default();
config.validate().expect("default config is valid by construction");Trait Implementations§
Source§impl Clone for SafeOracleConfig
impl Clone for SafeOracleConfig
Source§fn clone(&self) -> SafeOracleConfig
fn clone(&self) -> SafeOracleConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SafeOracleConfig
impl Debug for SafeOracleConfig
Source§impl Default for SafeOracleConfig
impl Default for SafeOracleConfig
Source§impl TryFromVal<Env, &SafeOracleConfig> for Val
impl TryFromVal<Env, &SafeOracleConfig> for Val
type Error = ConversionError
fn try_from_val( env: &Env, val: &&SafeOracleConfig, ) -> Result<Self, ConversionError>
Source§impl TryFromVal<Env, SafeOracleConfig> for Val
impl TryFromVal<Env, SafeOracleConfig> for Val
type Error = ConversionError
fn try_from_val( env: &Env, val: &SafeOracleConfig, ) -> Result<Self, ConversionError>
Source§impl TryFromVal<Env, Val> for SafeOracleConfig
impl TryFromVal<Env, Val> for SafeOracleConfig
type Error = ConversionError
fn try_from_val(env: &Env, val: &Val) -> Result<Self, ConversionError>
Auto Trait Implementations§
impl Freeze for SafeOracleConfig
impl !RefUnwindSafe for SafeOracleConfig
impl !Send for SafeOracleConfig
impl !Sync for SafeOracleConfig
impl Unpin for SafeOracleConfig
impl UnsafeUnpin for SafeOracleConfig
impl !UnwindSafe for SafeOracleConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, U, V, W, E, C> Compare<(T, U, V, W)> for C
impl<T, U, V, W, E, C> Compare<(T, U, V, W)> for C
type Error = E
fn compare( &self, a: &(T, U, V, W), b: &(T, U, V, W), ) -> Result<Ordering, <C as Compare<(T, U, V, W)>>::Error>
Source§impl<T, U, V, W, X, E, C> Compare<(T, U, V, W, X)> for C
impl<T, U, V, W, X, E, C> Compare<(T, U, V, W, X)> for C
type Error = E
fn compare( &self, a: &(T, U, V, W, X), b: &(T, U, V, W, X), ) -> Result<Ordering, <C as Compare<(T, U, V, W, X)>>::Error>
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<E, T, U> FromVal<E, T> for Uwhere
E: Env,
U: TryFromVal<E, T>,
impl<E, T, U> FromVal<E, T> for Uwhere
E: Env,
U: TryFromVal<E, T>,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more