# Pull Based Oracle

The Pull-Based Oracle is Block Scholes’ original mechanism for delivering real-time financial data on-chain. It 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 via **WebSocket** or **REST API**.
2. **Relay** this data into smart contract using own infrastructure.&#x20;
3. **Verify** its authenticity using **EIP-712 signatures**.

***

### 🔗 API Documentation

* **WebSocket API**: [WSAPI Doc](https://docs.google.com/document/d/1Htduc25agB0Ut9Yb960bIq6AzWWIMf9oQbm1HjSL8do/edit?tab=t.0#heading=h.u597gjliaeor)
* **REST API**: [RestAPI Doc](https://docs.google.com/document/d/12qE-HgzhBQSJH8zr_4hsl48AhSmPYf5xIl4J2qF67W8/edit?tab=t.0#heading=h.gjdgxs)

***

### 🔐 Authentication

All API requests require a valid API key.\
To request access, please email us at [support@blockscholes.com](mailto:support@blockscholes.com).

***

### ✅ 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:\
👉 [IvCheckVerifier GitHub Repo](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 on the volatility smile for the 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&#x20;

> 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
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 = 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 (IV) Feeds

Block Scholes supports three types of implied volatility feeds based on how the data is bucketed:

* **Strike-based IV** — Implied volatilities for different strike values
* **Moneyness-based IV** — Implied volatilities for different moneyness values
* **Delta-based IV** — Implied volatilities for different delta values
* **Index-based IV -** Implied volatility value for a given index, typically representing ATM IV or a snapshot of the vol surface.

All three types follow the **same struct and EIP-712 signature pattern** — only the bucket field name changes depending on the dimension used.

### Solidity structs

```solidity
struct Values {
    string sid;
    int256[] bucket; // This can be strike, moneyness, or delta
    int256[] v;      // Corresponding implied volatilities
}

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

// Example for strike-based IV
struct Values {
    string sid;
    int256[] strike;
    int256[] v;      
}
```

#### Type Hashes&#x20;

For generic usage:

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

For concrete implementations, replace `bucket` with the actual field:

**Example: Strike-based IV**

```solidity
bytes32 constant TYPE_HASH_VALUES = keccak256("Values(string sid,int256[] strike,int256[] v)");
bytes32 constant TYPE_HASH_DATA = keccak256("Data(Values[] values,int256 timestamp)Values(string sid,int256[] strike,int256[] v)");
```

#### 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)");

```
