> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kimia.live/llms.txt
> Use this file to discover all available pages before exploring further.

# Oracles

> How Kimia consumes Pyth Hermes Pull Oracles, safely.

<style>
  {`
    .katex-display {
      overflow-x: auto;
      overflow-y: hidden;
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    .katex-display::-webkit-scrollbar {
      display: none;
      height: 0;
      width: 0;
    }
    `}
</style>

<div style={{ display: 'flex', alignItems: 'center', gap: '12px', margin: '12px 0' }}>
  <img src="https://mintcdn.com/kimia/R-0mb9LchgqcL7Y5/logo/pyth.webp?fit=max&auto=format&n=R-0mb9LchgqcL7Y5&q=85&s=979a2105bba5b3eb879abdc60565f4f5" alt="Pyth" style={{ height: '48px' }} width="860" height="860" data-path="logo/pyth.webp" />

  <div>Every price-sensitive operation in Kimia reads a <strong>Pyth Hermes Pull Oracle</strong>.</div>
</div>

Pull oracles are fundamentally different from the old "push" model: the
`PriceUpdateV2` account lands on-chain *in the same transaction that uses it*.

## The flow

<Steps>
  <Step title="Off-chain: fetch a signed update">
    ```ts theme={null}
    const res = await fetch(
      `https://hermes.pyth.network/v2/updates/price/latest?ids[]=${FEED_ID}`
    );
    const { binary } = await res.json();
    ```
  </Step>

  <Step title="Build a postPriceUpdate instruction">
    ```ts theme={null}
    import { PythSolanaReceiver } from '@pythnetwork/pyth-solana-receiver';
    const tx = await receiver.buildPostPriceUpdateInstructions(binary.data);
    ```
  </Step>

  <Step title="Prepend it to your Kimia instruction">
    The resulting `price_update` account becomes the `oracle` argument to
    `place_order`, `liquidate`, `update_funding_rate`, etc.
  </Step>

  <Step title="Atomic consumption">
    Post + consume happen in the same tx. No window for staleness. No chance of
    a front-run replacing the price you expected.
  </Step>
</Steps>

## On-chain validation

Kimia's `perps-common::validate_pyth_oracle` enforces five checks before any
price is used:

| Check               | What                                                                                             |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| **Owner**           | Account owner must be the Pyth Receiver program (`rec5EKMGg7MpqG6xfy3DaFUkbNvVz4vDRNPn1fPqMoh`). |
| **Deserialization** | Account must decode as `PriceUpdateV2`.                                                          |
| **Feed ID**         | Must match the market's configured `oracle` account's feed.                                      |
| **Staleness**       | `publish_time` within `oracle_staleness_threshold` (default 60s) of chain clock.                 |
| **Confidence**      | `confidence / price × 10_000 ≤ oracle_confidence_max_bps` (default 250 bps = 2.5%).              |

Any failure short-circuits the instruction with a clear error code (`6000..6002`).

## Normalization

Pyth feeds typically report with `expo = -8` (eight decimals). Kimia normalizes
to six decimals internally:

$$
\text{target\_price} = \frac{\text{pyth\_price} \times 10^{\text{pyth\_expo} - \text{target\_expo}}}{10^6}
$$

Example: SOL at 130.00000000 (`pyth_price = 13_000_000_000`, `expo = -8`) becomes
`130_000_000` at `expo = -6`.

## Where oracles are used

| Program     | Instruction           | Purpose                    |
| ----------- | --------------------- | -------------------------- |
| kimia-perp  | `place_order`         | Margin and slippage checks |
| kimia-perp  | `liquidate`           | Close price                |
| kimia-perp  | `update_funding_rate` | Oracle TWAP update         |
| kimia-perp  | `spot_swap`           | Swap price                 |
| delta-vault | `rebalance`           | Gap detection              |

## Read next

<CardGroup cols={2}>
  <Card title="Perpetuals" icon="chart-line" href="/concepts/perpetuals">
    Where oracle reads feed into margin and liquidation.
  </Card>

  <Card title="Error codes" icon="circle-exclamation" href="/resources/errors">
    Oracle error codes and how to handle them.
  </Card>
</CardGroup>
