# Oracle Gateway

Das Oracle Gateway stellt Solana-native Preisfeeds (Pyth Network, Switchboard V3) über Chainlinks `AggregatorV3Interface`. Ethereum-Protokolle, die nach Rome portiert werden, können ihren bestehenden Oracle-Integrationscode unverändert verwenden.

## Das Problem

Ethereum-DeFi-Protokolle erwarten Chainlinks `AggregatorV3Interface`:

```solidity
(, int256 price,,,) = priceFeed.latestRoundData();
```

Solana hat andere Oracle-Anbieter (Pyth, Switchboard) mit unterschiedlichen Datenformaten. Ohne Anpassung müsste jedes Ethereum-Protokoll eine benutzerdefinierte Oracle-Integration implementieren.

## Die Lösung

Oracle Gateway V2 stellt leichte Adapterverträge bereit, die:

1. Preis-Daten aus Pyth- oder Switchboard-Konten auf Solana per CPI lesen
2. Die on-chain in Borsh kodierten Daten parsen
3. Preise auf 8 Nachkommastellen normalisieren
4. Die standardmäßige Chainlink `AggregatorV3Interface`

```solidity
import {IAggregatorV3Interface} from "@rome-protocol/solidity-sdk/contracts/oracle/IAggregatorV3Interface.sol";

// Gleiche Schnittstelle wie Chainlink auf Ethereum
IAggregatorV3 priceFeed = IAggregatorV3(ORACLE_ADAPTER_ADDRESS);
(, int256 price,,,) = priceFeed.latestRoundData();
// Preis = SOL/USD mit 8 Dezimalstellen (z. B. 15000000000 = 150,00 $)
```

## Architektur

### OracleAdapterFactory

Stellt Oracle-Adapter bereit und verwaltet sie:

```solidity
OracleAdapterFactory factory = OracleAdapterFactory(0xa4647955a16b72d15f13b51b5277036755d297be);

// Einen Pyth-Preisfeed-Adapter bereitstellen
address adapter = factory.createPythFeed(
    pythAccountPubkey,    // Pyth-Preiskonto auf Solana
    "SOL/USD",            // Beschreibung
    60                    // maximale Aktualitätsgrenze in Sekunden
);

// Einen Switchboard-Preisfeed-Adapter bereitstellen
address adapter = factory.createSwitchboardFeed(
    sbAccountPubkey,      // Switchboard-Aggregator auf Solana
    "SOL/USD",
    60
);
```

Die Factory validiert, dass das Konto tatsächlich dem Pyth-/Switchboard-Programm gehört, bevor es bereitgestellt wird.

### Adapter-Typen

**PythPullAdapter** — Liest Pyth `PriceUpdateV2` Konten. Unterstützt Preis, Konfidenzintervall, EMA-Preis und Veröffentlichungszeit.

**SwitchboardV3Adapter** — Liest Switchboard `AggregatorAccountData` Konten. Unterstützt Preis und Zeitstempel. EMA nicht verfügbar.

Beide Adapter verwenden **EIP-1167-Minimal-Proxy-Klone** für eine gas-effiziente Bereitstellung.

## Schnittstellen

### Standard-Chainlink-Schnittstelle

```solidity
interface IAggregatorV3Interface {
    function decimals() external view returns (uint8);          // Immer 8
    function description() external view returns (string memory);
    function version() external view returns (uint256);
    function latestRoundData() external view returns (
        uint80 roundId,
        int256 answer,        // Preis auf 8 Dezimalstellen normalisiert
        uint256 startedAt,
        uint256 updatedAt,
        uint80 answeredInRound
    );
}
```

### Erweiterte Schnittstelle

```solidity
interface IExtendedOracleAdapter {
    function latestPriceData() external view returns (
        int64 price, uint64 conf, int32 expo, uint64 publishTime
    );
    function latestEMAData() external view returns (        // Nur Pyth
        int64 emaPrice, uint64 emaConf, int32 expo, uint64 publishTime
    );
    function priceStatus() external view returns (uint8);   // 0=Handel, 1=Veraltet, 2=Angehalten
    function maxStaleness() external view returns (uint256);
    function oracleType() external view returns (uint8);    // 0=PythPull, 1=Switchboard
}
```

### Batch-Reader

Mehrere Feeds in einem Aufruf lesen:

```solidity
BatchReader reader = BatchReader(0x70da375e5680f84032f5b15d35ba0e6f9871d3fd);

address[] memory adapters = new address[](3);
adapters[0] = solUsdAdapter;
adapters[1] = btcUsdAdapter;
adapters[2] = ethUsdAdapter;

// Gibt ein Array von (adapter, answer, updatedAt, success) zurück
// Ein veralteter Feed führt nicht zum Revert des gesamten Batches
reader.getLatestPrices(adapters);
```

## Schutz vor Veraltbarkeit

Adapter erzwingen einen `maxStaleness` Parameter. Wenn `block.timestamp - publishTime > maxStaleness`, wird der Aufruf mit `StalePriceFeed()`abgebrochen. Standard: 60 Sekunden.

Der Factory-Besitzer kann die Veraltbarkeit pro Adapter oder global anpassen:

```solidity
factory.setDefaultMaxStaleness(120); // 2 Minuten
```

## Bereitgestellte Adressen (Devnet)

| Vertrag                      | Adresse                                      |
| ---------------------------- | -------------------------------------------- |
| OracleAdapterFactory         | `0xa4647955a16b72d15f13b51b5277036755d297be` |
| PythPullAdapter (Impl.)      | `0x4fd11aed44ee5f71df22fb804cfcbb4c50535db9` |
| SwitchboardV3Adapter (Impl.) | `0xb57e3589b880aa3f6b66ce2df6aa42cd9c36925e` |
| BatchReader                  | `0x70da375e5680f84032f5b15d35ba0e6f9871d3fd` |
| SOL/USD (Switchboard)        | `0xF0864572019c295407CF2ed46e6FD3615e10E19d` |

Siehe [Contract-Adressen](/de/referenz/contract-addresses.md) für die vollständige Liste.

## Einschränkungen

* **Keine historischen Rundendaten** — `getRoundData(roundId)` führt zu einem Revert mit `HistoricalRoundsNotSupported()`
* **Switchboard-EMA nicht unterstützt** — `latestEMAData()` führt bei Switchboard-Adapter-Reverts zu
* **Parser-Offsets empirisch validiert** — vor einer erneuten Bereitstellung gegen neue Pyth-/Switchboard-Versionen mit Validierungsskripten erneut validieren
* **Preisnormalisierung** — Pyth-Preise normalisiert als `price * 10^(expo - (-8))`; Switchboard als `(mantissa * 10^8) / 10^scale`

## Status

**V1 ausgeliefert** (2026-04-01) — V2 in Arbeit mit Schutz vor Veraltbarkeit, Batch-Lesungen, Switchboard-Adapter, EIP-1167-Klone.

## Was kommt als Nächstes

* [Contract-Adressen](/de/referenz/contract-addresses.md) — alle bereitgestellten Oracle-Adressen
* [Solidity bereitstellen](/de/entwicklerhandbucher/deploy-solidity.md) — Verträge bereitstellen, die Oracle-Feeds verwenden


---

# 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.rome.builders/de/produkte/oracle-gateway.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.
