Aggregated Price Oracle
When a market is created, the Market Manager admin must specify an oracle compliant with the SEP-40 standard. This allows markets to use existing Stellar-based solutions, such as Reflector and RedStone oracles, or Alula's aggregated oracle at deployment time (the oracle address is immutable and cannot be updated afterward).
For higher reliability, Alula provides an optional aggregated oracle that computes the median price across multiple SEP-40-compliant sources, checks every source for staleness and can be configured with circuit breakers.
Circuit Breaker
The aggregated oracle implements a circuit breaker that halts price updates when a rapid, large deviation is detected (e.g., 10% within 5 minutes). This protection operates at the oracle layer; when triggered, the oracle returns no price.
The circuit breaker compares the newly computed median against the last accepted valid median, rather than any individual source or the immediately preceding raw reading. On every lastprice() call:
- A new median is computed from all non-stale, non-expired, positive oracle prices.
- The contract loads the previously stored valid median for that asset.
- If the time elapsed since the previous valid median is within the configured
max_dev_consecutive_diff_secswindow, the deviation is checked:
deviation_bps = |new_median - previous_valid_median| / previous_valid_median × 10,000
- If
deviation_bpsexceeds the asset'smax_dev_bps, the circuit breaker trips. APriceDeviationExceedsMaxevent is emitted and no price is returned. The stored valid median is not updated. - If the deviation is within bounds, the new median is accepted, stored as the new valid reference, and returned.
INFO
If the time elapsed exceeds the configured window, the deviation check is skipped and the new median is accepted and stored as the new valid reference. This prevents false positives after legitimate extended periods of inactivity.
Price Manipulation Resistance
Comparing the new median against the last accepted valid median compounds the difficulty for an attacker:
- Outlier filtering: The median discards outliers; an attacker needs to control ⌈N/2⌉ sources to move the median.
- Per-tick caps: Even if the median shifts, an attacker must sustain manipulation across multiple consecutive ticks, moving at most
max_dev_bpseach time. A multi-minute update frequency for a source further increases the required manipulation window.
The following diagrams illustrate three attack scenarios against a three-source aggregated oracle:
Scenario 1: Single source manipulated. The median discards the outlier and a valid price is reported.
Scenario 2: Majority manipulated, within deviation window. The circuit breaker detects the deviation and no price is reported.
Scenario 3: Majority manipulated, after deviation window. The manipulated price can pass, but an attacker must control at least half the sources for an extended period to reach this state.
Per-asset Configuration
Each asset is registered with its own circuit breaker parameters via add_asset:
| Parameter | Type | Description |
|---|---|---|
max_dev_bps | u32 | Maximum allowed deviation in basis points. |
max_dev_consecutive_diff_secs | u64 | Time window in seconds; deviation is only enforced when consecutive reads fall within this window. |
This allows volatile assets to use wider bands than stablecoins, and the time window can be tuned to the expected oracle update frequency.
Effect on Market Operations
- Obligations without active borrows: Withdrawals can remain possible, allowing users to reduce exposure while prices are paused.
- Obligations with open borrows: Withdrawals and new borrows cannot proceed because the protocol cannot confirm collateralization without a price.
- Liquidations: Liquidations are also blocked because the protocol cannot evaluate the obligation's health factor without a current price.