Giter VIP home page Giter VIP logo

ica-oracle's Introduction

ICA Oracle CW Contract

Overview

The icaoracle facilities trustless data publication to cosmwasm outposts on adjacent chains. The full ICA Oracle solution consists of two components: the icaoracle module deployed on the source chain, as well as a corresponding cosmwasm oracle contract deployed on the destination chain (described here). The contract features a standard key-value store, that accepts push messages from this module via interchain accounts. The data sent is referred to as a Metric. For Stride, the primary application of this module is to enable integrations to trustlessly retrieve the redemption rate (internal exchange rate) of stTokens.

Pushing Metrics

This contract consists of a single transaction PostMetric that is responsible for publishing data to the oracle. Only the admin can push metrics to the oracle. The source chain controlled interchain account controlled is the contract admin.

Each metrics is represented as a generic key-value pair. When a metric is pushed, it's added to the METRICS store, which keeps track of the latest 100 values for the particular key.

Additionally, there's a REDEMPTION_RATES store that is meant specifically for redemption rate metrics. These redemption rate metrics are identified by the metric_type field which enables additional handling for metrics that fall into the same category.

Diagram

alt text alt text

Transactions

pub struct InstantiateMsg {
    /// Contract admin address which has authority to post metrics
    /// This will be an ICA account
    pub admin_address: String,
    /// The transfer channel ID from the Oracle chain to the Controller chain
    /// This field is only necessary for redemption rate metrics and queries
    ///
    /// Ex: If this oracle contract is deployed on Osmosis, but is controlled
    ///     by Stride, then the channel ID should be the Osmosis channel ID
    ///     for the Osmosis <> Stride transfer channel
    pub transfer_channel_id: Option<String>,
}

pub enum ExecuteMsg {
    /// Uploads and stores a new metric
    PostMetric {
        /// Key identifying the metric (e.g. `stuatom_redemption_rate`)
        key: String,
        /// Value for the metric (e.g. `1.1`)
        value: String,
        /// Category for the metric(e.g. `redemption_rate`)
        /// Helps determine handling of additional context
        metric_type: MetricType,
        /// Unix timestamp with which the metric was updated on the source chain
        update_time: u64,
        /// Block height with which the metric was updated on the source chain
        block_height: u64,
        /// Additional metric-specific attributes
        attributes: Option<Binary>,
    },
}

Queries

pub enum QueryMsg {
    /// Returns the contract's config
    #[returns(crate::state::Config)]
    Config {},

    /// Returns the latest metric, given the metric's key
    #[returns(Metric)]
    Metric { key: String },

    /// Returns the full history of values for a given metric key, up to the capacity
    /// Includes optional limit on the number of metrics returned
    #[returns(Metrics)]
    HistoricalMetrics { key: String, limit: Option<u64> },

    /// Returns the latest metric for each key
    #[returns(Metrics)]
    AllLatestMetrics {},

    /// Returns the redemption rate of an stToken
    #[returns(RedemptionRateResponse)]
    RedemptionRate {
        /// The denom should be the ibc hash of an stToken as it lives on the oracle chain
        /// (e.g. ibc/{hash(transfer/channel-326/stuatom)} on Osmosis)
        denom: String,
        /// Params should always be None, but was included in this query
        /// to align with other price oracles that take additional parameters such as TWAP
        params: Option<Binary>,
    },

    /// Returns a list of redemption rates over time for an stToken
    #[returns(RedemptionRates)]
    HistoricalRedemptionRates {
        /// The denom should be the ibc hash of an stToken as it lives on the oracle chain
        /// (e.g. ibc/{hash(transfer/channel-326/stuatom)} on Osmosis)
        denom: String,
        /// Params should always be None, but was included in this query
        /// to align with other price oracles that take additional parameters such as TWAP
        params: Option<Binary>,
        /// Optional limit on the number of entries to return
        limit: Option<u64>,
    },

    /// Returns the purchase rate of an stToken
    #[returns(PurchaseRateResponse)]
    PurchaseRate {
        /// The denom should be the ibc hash of an stToken as it lives on the oracle chain
        denom: String,
        /// Params should always be None, but was included in this query
        /// to align with other price oracles that take additional parameters such as TWAP
        params: Option<Binary>,
    },

    /// Returns a list of purchase rates over time for an stToken
    #[returns(PurchaseRates)]
    HistoricalPurchaseRates {
        /// The denom should be the ibc hash of an stToken as it lives on the oracle chain
        /// (e.g. ibc/{hash(transfer/channel-326/stuatom)} on Osmosis)
        denom: String,
        /// Params should always be None, but was included in this query
        /// to align with other price oracles that take additional parameters such as TWAP
        params: Option<Binary>,
        /// Optional limit on the number of entries to return
        limit: Option<u64>,
    },
}

Instructions for Testing Locally

  • Clone this repo so that it sits at the same directory level as the Stride repo
  • Navigate to the stride repo
cd ../stride
  • Update the HOST_CHAINS variable in config.sh to run only osmosis
HOST_CHAINS=(OSMO)
  • Start dockernet from Stride repo home directory
git submodule update --init --recursive
make start-docker build=sor

# Each ensuing run, you can just run `make start-docker` which will only rebuild the Stride binary
  • Get intergration tests running in background so redemption rate updates
make test-integration-docker
  • Navigate to the ica-oracle repo
cd ../ica-oracle
  • Build the contract
make build-optimized
  • Upload the contract
make store-contract 
  • Add the oracle to Stride which will instantiate the contract via an ICA
make add-oracle
  • Query the metrics and watch the redemption rate grow. Note: the query will fail if no redemption rate updates have been pushed yet.
make query-metrics
  • See makefile for additional commands

ica-oracle's People

Contributors

faboweb avatar larry0x avatar rustcandy avatar sampocs avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.