The first price provider supported by Coin X Oracle is Pyth Network. It is the leading Oracle provider on Sui Network and the largest first-party Oracle Network in the world. It supports of over 50 chains and offers 450 price feeds.
First Party Institutional Providers
Pyth network data sources do not rely on intermediaries to ensure reliability and liveness of the data.
Price Confidence
Pyth Network is the only provider that offers a price confidence metric in all price feeds. Assets do not have a single price in a market at any given point in time. By providing a confidence range, DeFi dApps can design their invariant to take into account price variance.
module coin_x_oracle::pyth_oracle {// === Imports ===use std::type_name;use sui::object;use sui::math::pow;use sui::object::ID;use sui::clock::Clock;use sui::dynamic_field as df;use suitears::fixed_point_wad;use suitears::math256::mul_div_down;use suitears::owner::{Self, OwnerCap};use suitears::oracle::{Self, Oracle, Request}; use pyth::i64;use pyth::state::State as PythState;use pyth::price::Self as pyth_price;use pyth::pyth::get_price as pyth_get_price;use pyth::price_info::{Self, PriceInfoObject};// === Errors ===const EInvalidPriceObjectInfo: u64 = 0;const EZeroPrice: u64 = 1;const EPriceConfidenceOutOfRange: u64 = 2;// === Constants ===const POW_10_18: u256 = 1000000000000000000; // 1e18const TWO_PERCENT: u256 = 20000000000000000; // 0.02e18const HUNDRED_PERCENT: u256 = 1000000000000000000; // 1e18const TIME_SCALAR: u64 = 1000;// === Structs ===structPriceInfoObjectKeyhascopy, drop, store {}structConfidenceKeyhascopy, drop, store {}structPythFeedhasdrop {}// === Public-Mutative Functions ===/* * @notice Adds a `PythFeed` report to a `suitears::oracle::Request`. * * @param self A `suiterars::oracle::Oracle` with this module's witness. * @param request A hot potato issued from the `self` to create a `suiterars::oracle::Price`. * @param wormhole_state The state of the Wormhole module on Sui. * @param pyth_state The state of the Pyth module on Sui. * @param price_info_object An object that contains price information. One per asset. * @param clock_object The shared Clock object from Sui. * * aborts-if: * - The `price_info_object` is not whitelisted. * - The price confidence is out of range. * - The price is negative or zero. */publicfunreport<Witness: drop>( oracle: &Oracle<Witness>, request: &mutRequest, pyth_state: &PythState, price_info_object: &mutPriceInfoObject, clock_object: &Clock ) {let whitelisted_id = *df::borrow<PriceInfoObjectKey, ID>(oracle::uid(oracle), PriceInfoObjectKey {});assert!(whitelisted_id == price_info::uid_to_inner(price_info_object), EInvalidPriceObjectInfo);// Get the price raw value, exponent and timestamplet pyth_price = pyth_get_price(pyth_state, price_info_object, clock_object);let pyth_price_value = pyth_price::get_price(&pyth_price);let pyth_price_expo = pyth_price::get_expo(&pyth_price);let latest_timestamp = pyth_price::get_timestamp(&pyth_price);let price_conf = pyth_price::get_conf(&pyth_price);let pyth_price_u64 = i64::get_magnitude_if_positive(&pyth_price_value);assert_price_conf(oracle, pyth_price_u64, price_conf);assert!(pyth_price_u64 != 0, EZeroPrice);let is_exponent_negative = i64::get_is_negative(&pyth_price_expo);let pyth_exp_u64 = if (is_exponent_negative) i64::get_magnitude_if_negative(&pyth_price_expo) else i64::get_magnitude_if_positive(&pyth_price_expo);let value = if (is_exponent_negative) mul_div_down((pyth_price_u64 asu256), POW_10_18, (pow(10, (pyth_exp_u64 asu8)) asu256))else (pyth_price_u64 asu256) * (pow(10, 18 - (pyth_exp_u64 asu8)) asu256); oracle::report(request, PythFeed {}, latest_timestamp * TIME_SCALAR, (value asu128), 18); } // === Admin Functions === /* * @notice Adds the `PythFeed` feed to the `oracle`. * * @dev By default, this oracle will require prices to have a confidence level of 98% or higher. * * @param self The `suiterars::oracle::Oracle` that will require a Pyth report. * @param cap The `suitears::owner::OwnerCap` of `self`. * @param price_info_object This Pyth Network Price Info Object will be whitelisted. */publicfunadd<Witness: drop>(oracle: &mutOracle<Witness>, cap: &OwnerCap<Witness>, price_info_object: &PriceInfoObject) { oracle::add(oracle, cap, type_name::get<PythFeed>());let uid = oracle::uid_mut(oracle, cap); df::add(uid, PriceInfoObjectKey {}, price_info::uid_to_inner(price_info_object)); df::add(uid, ConfidenceKey {}, TWO_PERCENT); } /* * @notice Updates the required confidence interval percentage for the `self`. * * @dev Note that you can add a confidence interval percentage of 0%. We recommend a value higher than 95%. * * @param self The `suiterars::oracle::Oracle` that will require a Pyth report. * @param cap The `suitears::owner::OwnerCap` of `self`. * @param conf The new confidence. * * aborts-if * - The `cap` does not own the `self`. * - The `conf` is higher than 100%. */publicfunupdate_confidence<Witness: drop>(oracle: &mutOracle<Witness>, cap: &OwnerCap<Witness>, conf: u256) { owner::assert_ownership(cap, object::id(oracle));let saved_conf = df::borrow_mut<ConfidenceKey, u256>(oracle::uid_mut(oracle, cap), ConfidenceKey {}); *saved_conf = HUNDRED_PERCENT - conf; }// === Private Functions ===/* * @notice Ensures that we are reporting a price within the required confidence interval. * * @dev Read about price confidence intervals here: https://docs.pyth.network/price-feeds/pythnet-price-feeds/best-practices * * @param self The `suiterars::oracle::Oracle` that contains the required confidence percentage. * @param price_value The price * @param price_conf The confidence interval for the `price_value` * * aborts-if: * - The `price_value`'s confidence interval is lower than the `oracle` allows. */funassert_price_conf<Witness: drop>(oracle: &Oracle<Witness>, price_value: u64, price_conf: u64) {let price_conf_percentage = fixed_point_wad::div_up((price_conf asu256), (price_value asu256));let required_conf = *df::borrow<ConfidenceKey, u256>(oracle::uid(oracle), ConfidenceKey {});assert!(required_conf >= price_conf_percentage, EPriceConfidenceOutOfRange); } }