# Push Model

## Summary

This oracle is a push-based oracle - meaning that data is automatically pushed on-chain which may be read by consumers asynchronously. Our oracle contracts are permissioned, meaning that clients' contracts must be authorized by Block Scholes to read data from specific feeds. Please contact our team to discuss your requirements for feed data access. The payment for reading data is handled off-chain, there is no fee mechanism built into the contracts themselves.

## Key Concepts

There is a single access point for all oracle feeds - the `AccessContolBS` contract. A single client-facing method is exposed - `getLatestFeedData()`, which takes a Feed object as its only parameter and returns a `FeedData` object. A feed is identified by a combination of values:

* The feed ID, which broadly defines what type of feed is being requested (e.g. a spot price, an IV value, an option price etc.) - see the [#feed-ids](#feed-ids "mention") for reference.
* A set of enumerable parameters, which are uint8 values. Each of these represents a parameter which takes one of a finite number of possible values - for example, the base asset (e.g. BTC), the IV level type (strike or moneyness) or the expiry type (timestamp or tenor). The exact meaning of each of these is detailed under [#enumerable-parameters](#enumerable-parameters "mention") below. Every feed will require at least one enumerable parameter.
* A set of additional parameters, which contain values required to identify the feed which do not fit into a `uint8` enumerable parameter. Broadly these represent continuous real-world values - such as an expiry timestamp or a strike value. Not every feed will require additional parameters, however those that do will define a specific struct type containing the values required. In order to pass these distinct struct types into a generic interface, the objects must first be abi-encoded into a `bytes` type. Feeds requiring additional parameters will be detailed under the [#feed-ids](#feed-ids "mention").

The resulting `FeedData` object contains both the latest value for the specified feed and the timestamp when this value was last updated. Client applications should check the returned timestamp to ensure that the data meets their liveness requirements. All prices are denominated in USD.

Decimal values such as expiry or strike are generally provided to the oracle in an encoded `int64` representation with a fixed 9 decimals precision. So for example the number 1.23 would be encoded as 1,230,000,000. Timestamps are given as unix timestamps to the precision of seconds. The same encoding rules apply to values and timestamps returned from the Oracle.

## Public Interface

The public interface for the solidity contracts can be installed via npm: <https://www.npmjs.com/package/@blockscholes/oracle-interface> - `IBlockScholesOracle` is the interface that should be imported, defining the `getLatestFeedData()`function and relevant types. Reference documentation for the package can be found here: [Solidity Interface Reference](/blockchain-oracle/push-based-oracle/interface.md).

## Deployments

We currently maintain deployments on the following networks:

<table><thead><tr><th width="174">Name</th><th width="119">Chain ID</th><th>Contract Address (Access Control)</th></tr></thead><tbody><tr><td>Arbitrum One</td><td>42161</td><td>0xeC21d64f6b28913bfEb83914C5628F8bb3AC5D54</td></tr><tr><td>Arbitrum Sepolia Testnet</td><td>421614</td><td>0xA5cC45bA54df501EBdE4e16838fc3125daAfd037</td></tr><tr><td>Plume Testnet</td><td>98867</td><td>0xDA3a5746aE221087244B9016373Fe43119519F57</td></tr><tr><td>Plume Mainnet</td><td>98866</td><td>0xDA3a5746aE221087244B9016373Fe43119519F57</td></tr><tr><td>Base Sepolia Testnet</td><td>84532</td><td>0x3B8E70f4761423D48B22dE4187Cc0740C18B2843</td></tr></tbody></table>

## Example Integration

Putting these above concepts together, here is an example of how a client can integrate with our contracts to read the latest data for an option price feed:\\

```
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.24;

import {IOracleBS} from "@blockscholes/oracle-interface/contracts/IOracleBS.sol";
import {IFeedProviderBS} from "@blockscholes/oracle-interface/contracts/IFeedProviderBS.sol";
import {ConstantsBS} from "@blockscholes/oracle-interface/contracts/ConstantsBS.sol";

// This contract demonstrates how to retrieve the latest feed data from the oracle.
//
// It is only intended for demonstration purposes and is not deployed as part
// of the oracle system.
contract Example {
    IOracleBS public oracle;

    // Error to be thrown when the data is too old.
    error ErrDataTooOld(uint256 dataAge);

    constructor(IOracleBS _oracle) {
        oracle = _oracle;
    }

    // This functions shows how to retrieve the latest feed data from the oracle.
    function getOptionPrice(
        int64 expiryTenor,
        int64 strike
    ) internal view returns (int64) {
        IFeedProviderBS.Feed memory feed = IFeedProviderBS.Feed({
            id: ConstantsBS.FEED_ID_OPTION_MARK_PRICE,
            parameters: IFeedProviderBS.FeedParameters({
                enumerable: new uint8[](4),
                other: abi.encode(
                    IOracleBS.OptionParameters({
                        expiry: expiryTenor,
                        ivLevelValue: strike
                    })
                )
            })
        });

        // Parameters must be set individually - Solidity does not yet
        // support conversion from an array literal to a dynamic array.
        feed.parameters.enumerable[0] = ConstantsBS.OPTION_TYPE_CALL;
        feed.parameters.enumerable[1] = ConstantsBS.IV_LEVEL_TYPE_STRIKE;
        feed.parameters.enumerable[2] = ConstantsBS.EXPIRY_TYPE_TENOR;
        feed.parameters.enumerable[3] = ConstantsBS.BASE_ASSET_BTC;

        IOracleBS.FeedData memory feedData = oracle.getLatestFeedData(feed);

        uint256 dataAge = block.timestamp - feedData.timestamp;
        if (dataAge < 1 hours) {
            revert ErrDataTooOld(dataAge);
        }

        return feedData.value;
    }
}
```

## Feeds Reference

Below is a reference for the feeds currently supported by the Oracle. The values are provided below for reference but we recommend using the named constants defined within the `ConstantsBS` library in the [public interface](/blockchain-oracle/push-based-oracle/interface.md). The Oracle is flexible - if you have a request for data that is not covered by the feeds below please contact us at [info@blockscholes.com ](mailto:info@blockscholes.com)to discuss your requirements.

### Feed IDs

The table below details the types of feed data that are offered:

<table><thead><tr><th width="111">Feed ID</th><th>Name</th><th>Enumerable Parameters</th><th>Other Parameters</th></tr></thead><tbody><tr><td>1</td><td>Futures</td><td>ExpiryType<br>Exchange<br>BaseAsset</td><td>Expiry (int64)</td></tr><tr><td>2</td><td>Volatility Surface SVI Calibration Model Parameters</td><td>SVIParam<br>ExpiryType<br>Exchange<br>BaseAsset</td><td>Expiry (int64)</td></tr><tr><td>3</td><td>Crypto Spot Price</td><td>Exchange<br>BaseAsset</td><td></td></tr><tr><td>4</td><td>Interest Rate</td><td>ExpiryType<br>Exchange<br>BaseAsset</td><td>Expiry (int64)</td></tr><tr><td>5</td><td>Settlement Price</td><td>ExpiryType<br>Exchange<br>BaseAsset</td><td>Expiry (int64)</td></tr><tr><td>7</td><td>Implied Volatility</td><td>IVLevelType<br>ExpiryType<br>Exchange<br>BaseAsset</td><td>Expiry (int64)<br>IVLevelValue (int64)</td></tr><tr><td>8</td><td>Option Mark Price</td><td>OptionType<br>IVLevelType<br>ExpiryType<br>BaseAsset</td><td>Expiry (int64)<br>IVLevelValue (int64)</td></tr><tr><td>9</td><td>Equity Spot Price</td><td>Exchange<br>BaseAsset</td><td></td></tr></tbody></table>

### Enumerable Parameters

#### ExpiryType

<table><thead><tr><th width="156">Name</th><th width="96">Value</th><th>Description</th></tr></thead><tbody><tr><td>TIMESTAMP</td><td>0</td><td>Expiry will be supplied as an absolute timestamp value - the total number of seconds since the Unix epoch</td></tr><tr><td>TENOR</td><td>1</td><td>Expiry will be supplied as a relative tenor given as the fractional number of years from the current time. The decimal value should be encoded as an int64 with 9 decimals.</td></tr></tbody></table>

#### Exchange

<table><thead><tr><th width="185">Name</th><th width="109">Value</th><th>Description</th></tr></thead><tbody><tr><td>BLOCKSCHOLES</td><td>0</td><td>Special value indicating to use the BlockScholes composite exchange. Currently this is the only supported exchange for the futures, spot price, interest rate and settlement price feeds.</td></tr><tr><td>DERIBIT</td><td>1</td><td>Other exchanges may be specified for the model parameters and implied volatility feeds.</td></tr><tr><td>BYBIT</td><td>2</td><td></td></tr><tr><td>OKX</td><td>3</td><td></td></tr></tbody></table>

#### BaseAsset

<table><thead><tr><th width="189">Name</th><th width="109">Value</th><th>Description</th></tr></thead><tbody><tr><td>BTC</td><td>1</td><td></td></tr><tr><td>ETH</td><td>2</td><td></td></tr></tbody></table>

#### OptionType

<table><thead><tr><th width="189">Name</th><th width="111">Value</th><th>Description</th></tr></thead><tbody><tr><td>CALL</td><td>0</td><td></td></tr><tr><td>PUT</td><td>1</td><td></td></tr></tbody></table>

#### IVLevelType

<table><thead><tr><th width="195">Name</th><th width="118">Value</th><th>Description</th></tr></thead><tbody><tr><td>STRIKE</td><td>0</td><td>The IV level type will be specified as a strike amount of the underlying asset. The decimal strike should be provided as an int64 value with 9 decimals - regardless of the underlying token's decimal precision.</td></tr><tr><td>MONEYNESS</td><td>1</td><td>The IV level type will be specified as a moneyness value, equivalent to the strike divided by the forward price for the underlying asset. The moneyness should also be provided as an int64 with 9 decimals.</td></tr></tbody></table>

#### SVIParam

<table><thead><tr><th width="200">Name</th><th width="119">Value</th><th>Description</th></tr></thead><tbody><tr><td>SVI_A</td><td>0</td><td>Alpha - level parameter</td></tr><tr><td>SVI_B</td><td>1</td><td>Beta - slope parameter</td></tr><tr><td>SVI_RHO</td><td>2</td><td>Rho - correlation parameter</td></tr><tr><td>SVI_M</td><td>3</td><td>M - log-moneyness shift</td></tr><tr><td>SVI_SIGMA</td><td>4</td><td>Sigma - curvature parameter</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blockscholes.com/blockchain-oracle/push-based-oracle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
