> For the complete documentation index, see [llms.txt](https://docs.blockscholes.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.blockscholes.com/blockchain-oracle/pull-based-oracle.md).

# Pull Model

The Pull-Based Oracle is ideal for latency-sensitive use cases where developers want control over when and how data is retrieved and fed into smart contracts.

## How It Works

In this model, developers:

1. **Fetch** data from Block Scholes off-chain via [**WebSocket**](https://block-scholes.gitbook.io/block-scholes/data-access/websocket-api) or [**REST**](https://block-scholes.gitbook.io/block-scholes/data-access/rest-api) APIs.
2. **Relay** this data into any smart contract of choice.
3. **Verify** its authenticity using **EIP-712 signatures**.

## Verification via EIP-712

To ensure that the data originates from Block Scholes and is not tampered with, every data payload is signed using EIP-712. Developers must implement signature verification logic in their contracts to check the integrity of this data.

An open-source example for verifying **`strike.iv`** feeds is available [here](https://github.com/blockscholes/IvCheckVerifier/blob/main/src/IvCheckVerifier.sol)

You can adapt this verification flow for other feed types by changing the structs and type hashes accordingly.

***

## Feed-Specific Structs and Type Hashes

Below are the Solidity structs and EIP-712 type hashes for each supported feed. Replace the definitions in the [example repo](https://github.com/blockscholes/IvCheckVerifier) accordingly.

***

### 1. Interest rate

Interest rate term structure for given currency

**Structs**

```solidity
struct Values {
    string sid;
    int256 v;
}

struct Data {
    Values[] values;
    int256 timestamp;
}
```

**Type Hashes**

```solidity
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 constant VALUES_TYPEHASH = keccak256("Values(string sid,int256 v)");
bytes32 constant DATA_TYPEHASH = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256 v)");
```

### 2. Mark price

Mark price for any option strike for a given expiry.

**Structs and Type Hashes**

```solidity
struct Data {
    Values[] values;
    int256 timestamp;
}


// ---------------------
// 📦 Format A: Moneyness
// ---------------------
struct Values {
    string sid;
    uint256[] v;
    uint256[] moneyness;
}

bytes32 constant VALUES_TYPEHASH_A = keccak256("Values(string sid,uint256[] v,uint256[] moneyness)");
bytes32 constant DATA_TYPEHASH_A = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256[] v,uint256[] moneyness)");


// ---------------------
// 📦 Format B: Strike
// ---------------------
struct Values {
    string sid;
    uint256[] v;
    uint256[] strike;
}

bytes32 constant VALUES_TYPEHASH_B = keccak256("Values(string sid,uint256[] v,uint256[] strike)");
bytes32 constant DATA_TYPEHASH_B = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256[] v,uint256[] strike)");


// ---------------------
// 📦 Format C: Delta
// ---------------------
struct Values {
    string sid;
    uint256[] v;
    int256[] delta;
}

bytes32 constant VALUES_TYPEHASH_C = keccak256("Values(string sid,uint256[] v,int256[] delta)");
bytes32 constant DATA_TYPEHASH_C = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256[] v,int256[] delta)");


// 📌 Common to all
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
```

Additional optional fields may be included to represent first-order Greeks in value structs

```solidity
int256[] delta;
int256[] vega;
int256[] theta;
int256[] rho;
int256[] phi;

// Example
struct Values {
    string sid;
    int256[] v;
    int256[] moneyness;
    // Optional Greek
    int256[] delta;
}

bytes32 constant VALUES_TYPEHASH_A = keccak256("Values(string sid,int256[] v,int256[] moneyness,int256[] delta)");
bytes32 constant DATA_TYPEHASH_A = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256[] v,int256[] moneyness,int256[] delta)");

```

#### Future mark price

When querying **futures** mark prices, the structure is simplified. Instead of returning arrays or multiple buckets, the response contains only a **single value per `sid`**.

**Structs**

```solidity
struct Values {
    string sid;
    int256 v;
}

struct Data {
    Values[] values;
    int256 timestamp;
}
```

Type Hashes

```solidity
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 constant VALUES_TYPEHASH = keccak256("Values(string sid,int256 v)");
bytes32 constant DATA_TYPEHASH = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256 v)");
```

### 3. Model params

Calibrated SVI model parameters defining the implied volatility smile for a specific expiry.

**Structs**

```solidity
struct Values {
    string sid;
    int256 alpha;
    int256 beta;
    int256 rho;
    int256 m;
    int256 sigma;
}

struct Data {
    Values[] values;
    int256 timestamp;
}


```

**Type Hashes**

```solidity
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 constant VALUES_TYPEHASH = keccak256("Values(string sid,int256 alpha,int256 beta,int256 rho,int256 m,int256 sigma)");
bytes32 constant DATA_TYPEHASH = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256 alpha,int256 beta,int256 rho,int256 m,int256 sigma)");
```

### 4. Settlement and Index Price

**Settlement Price:** Time-weighted average of the spot index price at a specified expiry.\
Designed for robust and manipulation-resistant settlement of derivatives contracts (including futures and options).

**Index Price:** Block Scholes index price for the given asset.

**Structs**

```solidity
int256 spread;

struct Values {
    string sid;
    uint256 v;
    // Optional Spread
    int256 spread;
}

struct Data {
    Values[] values;
    int256 timestamp;
}
```

**Type Hashes**

```solidity
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 constant VALUES_TYPEHASH = bytes32 constant VALUES_TYPEHASH = keccak256("Values(string sid,uint256 v)");
bytes32 constant DATA_TYPEHASH = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256 v)");
```

### 5. Implied Volatility Surface (IV)

IV datapoints are supported in different formats:

* **Strike-based IV** — Implied volatilities at different strikes
* **Moneyness-based IV** — Implied volatilities at different forward-moneyness levels
* **Delta-based IV** — Implied volatilities at different delta levels
* **IV Index (BSIV) -** Weighted expectation of IV across all strikes on the smile

Strike, moneyness and delta IV share one layout: the `sid`, an array of levels, and the implied volatilities `v` at those levels, in that order. The level field's name and type are part of the EIP-712 type string, so each format has its own type hashes:

* `strike` and `moneyness` levels are `uint256[]`
* `delta` levels are `int256[]`, as put deltas are negative
* implied volatilities `v` are always `uint256[]`

The fields are arrays even when a single level is requested (for example `"moneyness": 1` or `"delta": 0.25`).

**Structs and Type Hashes**

```solidity
struct Data {
    Values[] values;
    int256 timestamp;
}


// ---------------------
// 📦 Format A: Strike
// ---------------------
struct Values {
    string sid;
    uint256[] strike;
    uint256[] v;
}

bytes32 constant VALUES_TYPEHASH_A = keccak256("Values(string sid,uint256[] strike,uint256[] v)");
bytes32 constant DATA_TYPEHASH_A = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256[] strike,uint256[] v)");


// ---------------------
// 📦 Format B: Moneyness
// ---------------------
struct Values {
    string sid;
    uint256[] moneyness;
    uint256[] v;
}

bytes32 constant VALUES_TYPEHASH_B = keccak256("Values(string sid,uint256[] moneyness,uint256[] v)");
bytes32 constant DATA_TYPEHASH_B = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256[] moneyness,uint256[] v)");


// ---------------------
// 📦 Format C: Delta
// ---------------------
struct Values {
    string sid;
    int256[] delta;
    uint256[] v;
}

bytes32 constant VALUES_TYPEHASH_C = keccak256("Values(string sid,int256[] delta,uint256[] v)");
bytes32 constant DATA_TYPEHASH_C = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256[] delta,uint256[] v)");


// 📌 Common to all
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
```

Format A matches the [example verifier](https://github.com/blockscholes/IvCheckVerifier/blob/main/src/IvCheckVerifier.sol).

#### Index IV

```solidity
struct Values {
    string sid;
    uint256 v;
}

struct Data {
    Values[] values;
    int256 timestamp;
}
```

Type hashes

```solidity
bytes32 constant TYPE_HASH_DOMAIN = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 constant VALUES_TYPEHASH = keccak256("Values(string sid,uint256 v)");
bytes32 constant DATA_TYPEHASH = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,uint256 v)");

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
