Contract 5ecd9779a93a4d2286d35654eeb3d12989ceba746530c413e1cb5189e33992cc

← Back to Index 📥 Download WASM

Meta

cliver 26.0.0#60f7458e7ecffddf2f2d91dc6d0d2db4fab03ecc
rssdkver 22.0.11#34f7f53ae31e0fd02aab436a9872e79fa671ca02
rsver 1.88.0

Instances

  • CAOVRE2BZYD2EKNY2O7TK6ICO6RHNNPLL7LZB6JOPVKOIR3CRZS2JLTO
  • CD46L6MBSQZR7OPLYGIIXTQMRM4U2KD3C33MD2DKKQMYRL4PO35LNSXT

Interface

Initialise the oracle. Idempotent against re-init: a second call reverts with AlreadyInitialized.

Validates:

  • max_delta_per_sync_wad > 0 && < WAD (a 100%+ allowed delta would disable the rate-limit entirely).
  • observation_window >= 2 (a 1-slot buffer cannot do TWAP).
  • max_staleness_ledgers > 0.

Constructor wiring

Soroban's __constructor runs once on register(). We treat the admin arg as the multisig/timelocked controller (ADR-002).

fn __constructor(env: soroban_sdk::Env, admin: soroban_sdk::Address, cfg: OracleConfig)

Refresh the cached rate from Blend.

Permissionless: anyone can prod the oracle. Validates monotonicity and the per-sync delta cap; on violation the oracle freezes, the violation is emitted as an event, and the last-known-good cached rate is returned. The freeze flag must persist across the call, so this function deliberately returns Ok(cached_rate) instead of Err: a Soroban Err return rolls back storage writes, which would defeat the freeze. Consumers must check is_frozen() after sync_rate and refuse to proceed if it returns true.

Returns:

  • Ok(new_rate) on a clean sync.
  • Ok(cached_rate) (the last-known-good rate) on a violation; the oracle is frozen as a side effect.
  • Err(Paused) if the oracle is paused.
  • Err(OracleRejected) only if the oracle was already frozen before the call, or Blend returned a non-positive rate.
fn sync_rate(env: soroban_sdk::Env) -> Result

Push an observation into the TWAP ring buffer.

Called by the AMM on each swap. Auth is not enforced at the contract level (the AMM signs the call as itself, which is the only address that should bother); the worst an adversary can do by spamming is write their own price into the buffer, which the time-weighted formula naturally amortises — and the AMM's lock against same-block reads (ADR-001 §4) eliminates the single-block manipulation vector.

fn update_observation(
    env: soroban_sdk::Env,
    price: i128,
) -> Result<(), soroban_sdk::Error>

View: latest cached rate, WAD-scaled. Reverts with OracleStale if the cache hasn't been refreshed within the configured staleness window. Consumers should call sync_rate and retry.

fn get_rate(env: soroban_sdk::Env) -> Result

View: TWAP across the populated portion of the ring buffer.

Reverts with OracleStale if fewer than 2 observations are recorded (TWAP is undefined). The weight of each observation is ts[i+1] - ts[i]; the final observation runs to now.

fn get_twap(env: soroban_sdk::Env) -> Result

View: latest single observation (price, ts). Convenience for indexers; protocol logic should prefer get_twap.

fn latest_observation(env: soroban_sdk::Env) -> Result<(i128, u64), soroban_sdk::Error>

View: whether the oracle is frozen.

fn is_frozen(env: soroban_sdk::Env) -> bool

View: whether the oracle is paused.

fn is_paused(env: soroban_sdk::Env) -> bool

Admin-only: pause the oracle. Instant. While paused, all sync / read / observation paths revert with Paused.

fn pause(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>

Admin-only: propose unpause. Records a 48h-eta proposal; the asymmetric pause from ADR-002 forbids instant unpause.

fn propose_unpause(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>

Permissionless after eta: finalize the pending unpause.

fn execute_unpause(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>

Admin-only: propose a re-attestation. Records (attested_rate, eta = now + 48h). After the eta, execute_reattest finalises the operation, writes the attested rate as the new cached rate, and clears the frozen flag.

Repeated calls overwrite the pending proposal (and reset the timer), so the admin can revise the attested rate before execution. This is desirable: between proposal and execution, the admin may observe Blend's true rate moving and want to update.

fn reattest(
    env: soroban_sdk::Env,
    attested_rate: i128,
) -> Result<(), soroban_sdk::Error>

Cancel a pending reattest proposal. Admin-only.

fn cancel_reattest(env: soroban_sdk::Env) -> Result<(), soroban_sdk::Error>

Permissionless: execute a previously-proposed reattest after its eta. Unfreezes the oracle and overwrites the cached rate.

fn execute_reattest(env: soroban_sdk::Env) -> Result

View: the active config.

fn config(env: soroban_sdk::Env) -> OracleConfig

View: the current admin address.

fn admin(env: soroban_sdk::Env) -> soroban_sdk::Address

View: the cached rate and its timestamp without applying the staleness gate. Returns (0, 0) if never synced.

fn cached_rate_raw(env: soroban_sdk::Env) -> (i128, u64)

View: how many observations are currently populated.

fn observation_count(env: soroban_sdk::Env) -> u32

Imports

WebAssembly Text (WAT) ▶