Contract a193c0653d3da5d5d0f23302ccdebc979fb16d7e3b6dad14291d0c627319a723

← Back to Index 📥 Download WASM

Meta

cliver 23.2.1#496ac35be7a7d8d923fcde9bbbc650ee593d1f6f
rssdkver 26.1.0#175aa41306f383057a8cdfc84b68d931664fc34e
rsver 1.95.0

Instances

  • CCN75KEGLETGRTVJJDMXB2ZRQD6PC2S56VUOEKVLQPVEIJYGSOV55G57

Interface

Initialize the VRF Oracle contract.

Parameters

  • fee_token: SAC token address used to charge per-request fees.
  • fee_amount: Amount of fee_token charged per VRF request (transferred from requester to oracle). Set to 0 for fee-free operation.
fn init(
    env: soroban_sdk::Env,
    oracle_pk: soroban_sdk::BytesN<192>,
    oracle_address: soroban_sdk::Address,
    oracle_ed25519_pk: soroban_sdk::BytesN<32>,
    drand_pk: soroban_sdk::BytesN<192>,
    g2_generator: soroban_sdk::BytesN<192>,
    drand_genesis_time: u64,
    drand_period: u32,
    round_offset: u32,
    fee_token: soroban_sdk::Address,
    fee_amount: i128,
)

Fulfill a VRF request with a BLS proof and oracle Ed25519 signature.

Checks-Effects-Interactions (CEI) pattern

  1. Checks: validate oracle identity, proof, alpha seed, BLS signatures.
  2. Effects: write Fulfilled = true and store proof BEFORE any external call.
  3. Interactions: invoke consumer callback (if registered) only AFTER state is fully committed, with a re-entrancy guard to block nested fulfill() calls.

Re-entrancy protection

DataKey::Fulfilling(request_id) is set to true before callback invocation and cleared after. Any re-entrant call to fulfill() for the same request_id will see Fulfilled = true and panic with "already fulfilled".

fn fulfill(
    env: soroban_sdk::Env,
    request_id: u64,
    proof: BlsVrfProof,
    signature: soroban_sdk::BytesN<64>,
)
fn request(
    env: soroban_sdk::Env,
    context: soroban_sdk::Bytes,
    requester: soroban_sdk::Address,
) -> u64
fn get_proof(env: soroban_sdk::Env, request_id: u64) -> BlsVrfProof
fn oracle_pk(env: soroban_sdk::Env) -> soroban_sdk::BytesN<192>
fn callback_of(
    env: soroban_sdk::Env,
    request_id: u64,
) -> Option<(soroban_sdk::Address, soroban_sdk::Symbol)>
fn get_context(env: soroban_sdk::Env, request_id: u64) -> soroban_sdk::Bytes
fn is_refunded(env: soroban_sdk::Env, request_id: u64) -> bool
fn is_fulfilled(env: soroban_sdk::Env, request_id: u64) -> bool
fn requester_of(env: soroban_sdk::Env, request_id: u64) -> soroban_sdk::Address

Allows the requester (or oracle) to remove proof data for a fulfilled request, reclaiming the associated storage rent. The fulfillment flag is preserved.

TTL edge case

After cleanup, DataKey::Proof is removed but DataKey::Fulfilled is kept. Callers relying on is_fulfilled() will continue to get true. Callers calling get_proof() or derive_random() after cleanup will panic — consumers must call derive_random() before cleanup or cache the result.

fn cleanup_proof(env: soroban_sdk::Env, request_id: u64, caller: soroban_sdk::Address)
fn derive_random(
    env: soroban_sdk::Env,
    request_id: u64,
    context: soroban_sdk::Bytes,
) -> u64
fn request_round(env: soroban_sdk::Env, request_id: u64) -> u64
fn oracle_address(env: soroban_sdk::Env) -> soroban_sdk::Address
fn timeout_refund(env: soroban_sdk::Env, request_id: u64)
fn timeout_rounds(env: soroban_sdk::Env) -> u64

Rotate the drand public key used to verify BLS beacon signatures.

This is required when the drand network performs a key rotation or when switching to a different drand chain (e.g., quicknet → a future chain).

Authorization model

The current oracle must authorize this call.

fn rotate_drand_pk(env: soroban_sdk::Env, new_drand_pk: soroban_sdk::BytesN<192>)

Rotate the oracle's BLS public key, Stellar address, and Ed25519 signing key.

Authorization model

The current oracle address must authorize this call. This prevents an attacker who obtains a new keypair from hijacking the oracle role.

Security note

Only rotate keys after the new oracle node is running and ready to fulfill requests. Any unfulfilled requests locked to the old PK will fail verification after rotation — they must be refunded via timeout_refund().

fn rotate_oracle_keys(
    env: soroban_sdk::Env,
    new_oracle_pk: soroban_sdk::BytesN<192>,
    new_oracle_address: soroban_sdk::Address,
    new_oracle_ed25519_pk: soroban_sdk::BytesN<32>,
)
fn request_with_callback(
    env: soroban_sdk::Env,
    context: soroban_sdk::Bytes,
    requester: soroban_sdk::Address,
    callback_contract: soroban_sdk::Address,
    callback_fn: soroban_sdk::Symbol,
) -> u64

Derives a random u64 in the range [0, max) with no modulo bias. Uses iterative hashing (rejection sampling variant) to ensure uniform distribution. Worst-case bounded at 10 iterations (p < 2^-640 of exceeding).

fn derive_random_in_range(
    env: soroban_sdk::Env,
    request_id: u64,
    context: soroban_sdk::Bytes,
    max: u64,
) -> u64

Imports

WebAssembly Text (WAT) ▶