pub enum OracleSafetyViolation {
ExcessiveDeviation = 1,
StaleData = 2,
CrossSourceMismatch = 3,
InsufficientLiquidity = 4,
ThinSampling = 5,
CircuitBreakerOpen = 6,
StaleSnapshot = 7,
ExternalContractFailure = 8,
DecimalsMismatch = 9,
UnexpectedDecimals = 10,
}Expand description
Reasons a guardrail has rejected a price; the Err payload of every
safe_oracle public API.
Discriminants are stable u32 values (1..=10) so they can be carried as the
u32 inside PriceResult::Err and re-hydrated through
PriceResult::into_result. Integrators surfacing oracle violations to
their own callers typically mirror these discriminants 1:1 in their own
error enum (see mock_lending::MockLendingError for the canonical
reference) so audit logs preserve which guardrail tripped.
§Spec
See spec §4 — Error Enum. The seven variants here implement the spec’s required violation taxonomy. Phases 1–5 wired the variants in order: 1–3 (Layer 1) in Phase 2, 4–5 (Layer 2) in Phase 4, 6 (circuit breaker) in Phase 5, and 7 (stale snapshot) introduced alongside the freshness check in Phase 4.
Variants§
ExcessiveDeviation = 1
StaleData = 2
CrossSourceMismatch = 3
InsufficientLiquidity = 4
ThinSampling = 5
CircuitBreakerOpen = 6
StaleSnapshot = 7
ExternalContractFailure = 8
An external contract (Reflector primary feed or LiquidityRegistry)
failed unexpectedly — host-level trap, contract upgrade
incompatibility, storage corruption, or any other invocation error
surfaced through Soroban’s try_* client variants. Hardening Phase
debt #4 added this variant so cross-contract failures arrive as
regular guardrail violations rather than propagating to the caller
(which would prevent auto-halt from committing — same Phase 5.2 v1
root cause).
Secondary-feed failures intentionally do NOT surface as this variant
— check_cross_source skips silently on secondary trap, consistent
with None and “secondary returned None” semantics.
DecimalsMismatch = 9
Cross-source check rejected because primary and secondary oracles
report different decimals() values. Comparing prices across
different scales would produce false signals; fail explicitly so
integrators see a misconfigured pair rather than always-fires
CrossSourceMismatch.
Recovery: verify both oracles target the same precision (Reflector mainnet = 14). Phase 7.2 closure of the lib.rs:262 reconciliation plan — what was previously documented as integrator responsibility is now enforced at library level.
UnexpectedDecimals = 10
Primary Reflector reported a decimals() value different from
REFLECTOR_DECIMALS_EXPECTED (14). The library’s BPS arithmetic and
staleness calculations are calibrated for 14-decimal precision; a
different value indicates a misconfigured oracle address or a
Reflector contract upgrade that has changed the precision contract.
Recovery: verify oracle address matches Reflector’s published mainnet/testnet address. If Reflector intentionally changed decimals, safe-oracle library version bump is required. Phase 7.2 closure of the lib.rs:820 plan.
Implementations§
Trait Implementations§
Source§impl Clone for OracleSafetyViolation
impl Clone for OracleSafetyViolation
Source§fn clone(&self) -> OracleSafetyViolation
fn clone(&self) -> OracleSafetyViolation
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 OracleSafetyViolation
impl Debug for OracleSafetyViolation
Source§impl From<&OracleSafetyViolation> for Error
impl From<&OracleSafetyViolation> for Error
Source§fn from(val: &OracleSafetyViolation) -> Error
fn from(val: &OracleSafetyViolation) -> Error
Source§impl From<&OracleSafetyViolation> for InvokeError
impl From<&OracleSafetyViolation> for InvokeError
Source§fn from(val: &OracleSafetyViolation) -> InvokeError
fn from(val: &OracleSafetyViolation) -> InvokeError
Source§impl From<OracleSafetyViolation> for Error
impl From<OracleSafetyViolation> for Error
Source§fn from(val: OracleSafetyViolation) -> Error
fn from(val: OracleSafetyViolation) -> Error
Source§impl From<OracleSafetyViolation> for InvokeError
impl From<OracleSafetyViolation> for InvokeError
Source§fn from(val: OracleSafetyViolation) -> InvokeError
fn from(val: OracleSafetyViolation) -> InvokeError
Source§impl PartialEq for OracleSafetyViolation
impl PartialEq for OracleSafetyViolation
Source§fn eq(&self, other: &OracleSafetyViolation) -> bool
fn eq(&self, other: &OracleSafetyViolation) -> bool
self and other values to be equal, and is used by ==.Source§impl TryFrom<&Error> for OracleSafetyViolation
impl TryFrom<&Error> for OracleSafetyViolation
Source§impl TryFrom<&InvokeError> for OracleSafetyViolation
impl TryFrom<&InvokeError> for OracleSafetyViolation
Source§type Error = InvokeError
type Error = InvokeError
Source§fn try_from(error: &InvokeError) -> Result<Self, InvokeError>
fn try_from(error: &InvokeError) -> Result<Self, InvokeError>
Source§impl TryFrom<Error> for OracleSafetyViolation
impl TryFrom<Error> for OracleSafetyViolation
Source§impl TryFrom<InvokeError> for OracleSafetyViolation
impl TryFrom<InvokeError> for OracleSafetyViolation
Source§type Error = InvokeError
type Error = InvokeError
Source§fn try_from(error: InvokeError) -> Result<Self, InvokeError>
fn try_from(error: InvokeError) -> Result<Self, InvokeError>
Source§impl TryFromVal<Env, &OracleSafetyViolation> for Val
impl TryFromVal<Env, &OracleSafetyViolation> for Val
type Error = ConversionError
fn try_from_val( env: &Env, val: &&OracleSafetyViolation, ) -> Result<Self, ConversionError>
Source§impl TryFromVal<Env, OracleSafetyViolation> for Val
impl TryFromVal<Env, OracleSafetyViolation> for Val
type Error = ConversionError
fn try_from_val( env: &Env, val: &OracleSafetyViolation, ) -> Result<Self, ConversionError>
Source§impl TryFromVal<Env, Val> for OracleSafetyViolation
impl TryFromVal<Env, Val> for OracleSafetyViolation
type Error = ConversionError
fn try_from_val(env: &Env, val: &Val) -> Result<Self, ConversionError>
impl Copy for OracleSafetyViolation
impl Eq for OracleSafetyViolation
impl StructuralPartialEq for OracleSafetyViolation
Auto Trait Implementations§
impl Freeze for OracleSafetyViolation
impl RefUnwindSafe for OracleSafetyViolation
impl Send for OracleSafetyViolation
impl Sync for OracleSafetyViolation
impl Unpin for OracleSafetyViolation
impl UnsafeUnpin for OracleSafetyViolation
impl UnwindSafe for OracleSafetyViolation
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<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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