Feature/centralized pricefeed Introducing Modular, Secure Oracle Infrastructure - #28
Merged
Merged
Conversation
This commit finalizes the core components of the Baobab Protocol's decentralized oracle infrastructure, migrating to a unified interface across all data sources (Chainlink, Pyth, Computed Feeds, and TWAP).
The central goal is to enhance manipulation resistance, data consistency, and security through a multi-layered validation approach enforced by the new contract.
### Key Features and Changes:
1. **BaobabOracleSecurity Integration:**
* Implements a central security gateway () enforcing sequential checks: Circuit Breakers, Global Pause, Global Staleness (), and contextual risk-based Confidence checks ().
* **Refinement:** Streamlined price fetching to rely solely on the output, eliminating redundant internal calls and improving gas efficiency.
2. **OracleRegistry (Assumed Role):**
* Acknowledges the reliance on the core to manage asset configuration (Primary/Fallback feeds) and enforce internal heartbeat/staleness logic before data is passed to the Security layer. The Registry acts as the sole source of data for the layer.
3. **ComputedOracle (Derived Prices):**
* Introduced a system for deriving secondary asset prices (e.g., ETH/BTC) via multiplication or division of two base feeds.
* **Security Fix:** Updated logic to return the **oldest** component timestamp, preventing the computed price from falsely appearing fresh when an underlying feed is stale.
* **Refinement:** Optimized fixed-point division math for gas efficiency while preserving 8-decimal output precision.
4. **Oracle Adapters (Chainlink & Pyth):**
* Created and to strictly conform to the interface.
* **Consistency:** Standardized output to 8 decimals for Pyth by implementing a robust helper that handles variable exponents.
* **Efficiency:** Refactored all adapters to ensure only a single external call is made per price query, drastically reducing transaction gas costs.
* **Fail Safe:** Ensured adapters return the sentinel value () on any failure (call revert, stale data, non-positive price).
5. **TWAPAdapter (Manipulation Resistance):**
* Implemented a Time-Weighted Average Price (TWAP) adapter used for sensitive actions, sourcing only validated prices from .
* **Security Principle:** The price pushing mechanism is permissionless to decentralize maintenance cost and increase data freshness.
* **Note on Pruning:** Identified and noted the gas-inefficiency of the current array pruning method, which is marked for a future refactor to a Ring/Circular Buffer structure for superior scalability.
This commit finalizes the core components of the Baobab Protocol's decentralized oracle infrastructure, migrating to a unified `IPriceFeed` interface across all data sources (Chainlink, Pyth, Computed Feeds, and TWAP). The central goal is to enhance manipulation resistance, data consistency, and security through a multi-layered validation approach enforced by the new `BaobabOracleSecurity` contract. ### Key Features and Changes: 1. **BaobabOracleSecurity Integration:** - Implements a central security gateway (`getValidatedPrice`) enforcing sequential checks: Circuit Breakers, Global Pause, Global Staleness (`maxStalenessPeriod`), and contextual risk-based Confidence checks (`PriceUse`). - **Refinement:** Streamlined price fetching to rely solely on the `OracleRegistry` output, eliminating redundant internal calls and improving gas efficiency. 2. **OracleRegistry Role:** - Relies on the core `OracleRegistry` to manage asset configuration (Primary/Fallback feeds) and enforce internal heartbeat/staleness logic before data is passed to the Security layer. - The Registry acts as the sole source of data for the `BaobabOracleSecurity` layer. 3. **ComputedOracle (Derived Prices):** - Introduced a system for deriving secondary asset prices (e.g., ETH/BTC) via multiplication or division of two base feeds. - **Security Fix:** Updated `latestTimestamp()` logic to return the **oldest** component timestamp, preventing the computed price from falsely appearing "fresh" when an underlying feed is stale. - **Refinement:** Optimized fixed-point division math for gas efficiency while preserving 8-decimal output precision. 4. **Oracle Adapters (Chainlink & Pyth):** - Created `ChainlinkAdapter` and `PythAdapter` to strictly conform to the `IPriceFeed` interface. - **Consistency:** Standardized output to 8 decimals for Pyth by implementing a robust `_scalePrice` helper that handles variable exponents. - **Efficiency:** Refactored all adapters to ensure only a single external call is made per price query, drastically reducing transaction gas costs. - **Fail Safe:** Ensured adapters return the sentinel value (`type(int256).min`) on any failure (call revert, stale data, non-positive price). 5. **TWAPAdapter (Manipulation Resistance):** - Implemented a Time-Weighted Average Price (TWAP) adapter used for sensitive actions, sourcing only validated prices from `BaobabOracleSecurity`. - **Security Principle:** The price pushing mechanism is permissionless to decentralize maintenance cost and increase data freshness. - **Note on Pruning:** Identified gas-inefficiency in the current `_shiftLeft` array pruning method; marked for future refactor to a Ring/Circular Buffer structure for superior scalability.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR: Introduce Modular, Secure Oracle Infrastructure
Executive Summary
This PR establishes a production-grade oracle infrastructure for the Baobab Protocol built on a fundamental security principle:
We implement a three-layer security model that separates data ingestion, routing, and validation into distinct, upgradeable components. This architecture prevents the common DeFi failure mode where oracle issues brick entire protocols.
PerpEngine. We're building the foundation correctly first, ensuring trust boundaries are properly established before wiring them into critical protocol logic.Architecture Overview
What Was Implemented
1. Unified IPriceFeed Interface
All oracle sources conform to a single interface, enabling protocol-wide consistency:
Why this matters:
2. Oracle Adapters (Layer 1: Data Ingestion)
Adapters are intentionally "dumb" — they only fetch data, with zero validation logic.
Implemented adapters:
ChainlinkAdapter— Wraps Chainlink aggregatorsPythAdapter— Wraps Pyth Network feedsTrustedOracle— Admin-controlled price feedComputedOracle— Derives prices from two feeds (e.g., ETH/USD from ETH/BTC × BTC/USD)TWAPAdapter— Time-weighted average pricingExample: ChainlinkAdapter
Critical Design Decision:
Adapters do NOT enforce:
Why? Because if we enforced confidence checks at the adapter level:
confidence = 0)Validation happens at Layer 3 (OracleSecurity), not here.
3. OracleRegistry (Layer 2: Routing + Fallback)
The registry is the single source of price data for the protocol. It handles routing and fallback logic, but still doesn't make trust decisions.
Responsibilities:
Key features:
Fallback logic:
success = falseThis allows the protocol to gracefully degrade rather than halt on oracle failures.
4. OracleSecurity (Layer 3: Trust Boundary)
This is the only contract protocol logic should call.
It enforces global and context-specific safety guarantees on top of raw prices.
Security guarantees enforced:
Context-aware validation via
PriceUseenum:Why this matters:
Example usage:
No accidental misuse. No silent assumptions. The risk profile is explicit in the code.
5. Computed Oracle Factory
Safely deploys and registers derived price feeds:
Use case: Creating synthetic prices
Example:
ETH/USDfromETH/BTCandBTC/USD:Benefits:
🧠 Why This Architecture?
1. Prevents Protocol-Level Bricking
The problem with naive approaches:
If confidence checks were enforced at the adapter level:
confidence = 0Our solution:
By separating layers:
The protocol stays flexible and resilient.
2. Enables Future Upgrades Without Rewrites
Want to:
OracleSecurityOracleRegistryYou do all of this without touching
PerpEngineor any consumer contracts.This is critical for a production protocol where:
3. Makes Oracle Risk Explicit
Consumers must declare why they're asking for a price:
This prevents:
The risk profile is now part of the type system.
What This PR Does NOT Do (By Design)
This PR intentionally lays infrastructure only:
PerpEngineWhy?
Because getting the trust boundaries right is more important than rushing integration. A poorly designed oracle system cannot be fixed retroactively without protocol-wide rewrites.
We're building the foundation correctly first.
🔜 Follow-Up Work (Next PRs)
Wire
PerpEnginetoOracleSecurityPriceUsefor each operationAdd TWAP fallback routing inside registry
Add funding-rate specific confidence logic
Introduce oracle slashing / monitoring hooks
✅ Testing & Validation
Unit tests cover:
Integration tests validate:
🎓 Final Notes
This PR intentionally front-loads correctness and safety.
It prioritizes:
All of which are critical for perpetual protocols, where oracle failures can lead to:
Once merged, the protocol gains a production-grade oracle foundation ready for live market integration.
📚 Additional Context
Why three layers instead of two?
Two-layer designs (adapter + validation) couple routing logic with security logic. This means:
Three layers provide separation of concerns:
Each layer can evolve independently.
Why
PriceUseenum instead of per-function validation?Alternative design:
Problems:
Our design:
Benefits:
Review Checklist: