fn admin(env: soroban_sdk::Env) -> soroban_sdk::Address
Every registered asset, in registration order (lets consumers enumerate the hub).
fn assets(env: soroban_sdk::Env) -> soroban_sdk::Vec
Replace the contract's wasm (admin-gated). Address and storage are kept.
fn upgrade(env: soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>)
Transfer the admin role to new_admin (current admin only). Hands the hub over to the
governance timelock; the price-source routing (set_sep40_source /
set_redstone_feed_source) moves with the role.
fn set_admin(env: soroban_sdk::Env, new_admin: soroban_sdk::Address)
Storage/schema version, bumped by a post-upgrade migration when the layout changes.
fn get_version(env: soroban_sdk::Env) -> u32
fn __constructor(env: soroban_sdk::Env, admin: soroban_sdk::Address)
Unregister asset's price source (admin only): it prices as (0, 0, false) again,
exactly like an asset that was never routed. The escape hatch for a wedged feed — a
yield wrapper whose upstream broke, a decommissioned oracle — so it can be neutralised
without inventing a fake quoted price. Re-registering via set_*_source restores it.
fn remove_source(env: soroban_sdk::Env, asset: soroban_sdk::Address)
fn get_price_source(
env: soroban_sdk::Env,
asset: soroban_sdk::Address,
) -> Option
Route asset to a SEP-40 oracle (Reflector / RedStone SEP-40), keyed by
sep40_asset (admin only). Caches the oracle's decimals().
fn set_sep40_source(
env: soroban_sdk::Env,
asset: soroban_sdk::Address,
oracle: soroban_sdk::Address,
sep40_asset: Asset,
max_age: u64,
)
Route asset to XOXNO's price aggregator under key (admin only).
Probes with the fail-closed price rather than the soft quote the hub reads at runtime:
registration is the one moment we want a hard failure. A key the aggregator cannot
resolve would otherwise register cleanly and price the asset (0, 0, false) forever, which
downstream reads as "stale oracle" and traps every valuation touching it — far from the
call that actually got it wrong.
fn set_xoxno_source(
env: soroban_sdk::Env,
asset: soroban_sdk::Address,
aggregator: soroban_sdk::Address,
key: PriceKey,
max_age: u64,
)
USD price of asset in WAD (1e18), the source timestamp, and a freshness flag.
Returns (0, 0, false) when no source is registered, a quoted source has no price,
or a source read fails. Every arm degrades rather than trapping: this hub sits inside
every margin, liquidation and settlement flow, and consumers cannot guard a panic in a
dependency — one wedged source would freeze all of them for every account holding the
asset (S2-M-04). "No price" is the one verdict consumers already handle safely.
fn get_price_usd_wad(
env: soroban_sdk::Env,
asset: soroban_sdk::Address,
) -> (i128, u64, bool)
Route asset to a feed on the RedStone Adapter (admin only). feed_id is the
adapter's key for the asset ("USDC", "XLM", "BENJI", …); decimals is the
deployment's price scale — 8 on RedStone's Stellar deployments (the adapter
doesn't expose it on-chain). Probes the adapter once so a wrong adapter address
or feed id fails here instead of silently pricing as (0, 0, false).
fn set_redstone_source(
env: soroban_sdk::Env,
asset: soroban_sdk::Address,
adapter: soroban_sdk::Address,
feed_id: soroban_sdk::String,
decimals: u32,
max_age: u64,
)
Route a yield-wrapper share to its underlying's price scaled by the wrapper's live
share→underlying rate (admin only). base_asset must already have a quoted source; a
derived base is rejected so sources cannot nest.
The three arguments must describe one wrapper: share and base_asset are checked
against the wrapper's own share_token() and underlying(), so the triple cannot be
assembled from parts of two.
Probing the rate is not enough on its own — it passes for any contract exposing
assets_per_share_wad() > 0, which is every other wrapper in the deployment. Registration
happens in a loop over reserves and tenors, so a transposed pair is a live risk, and it
produces a well-formed price: the share ends up quoted at some other asset's price times
this wrapper's rate. Nothing downstream can tell — the error is a constant factor, so it
reads as a plausible number and mis-values margin by the ratio of the two assets until an
off-chain reconciliation catches it.
Also probes the base price
fn set_yield_share_source(
env: soroban_sdk::Env,
share: soroban_sdk::Address,
base_asset: soroban_sdk::Address,
wrapper: soroban_sdk::Address,
)