Price Oracle Middleware
How the price oracle middleware resolves asset prices and how to add or override a feed.
Purpose and scope
The Price Oracle Middleware system provides standardized asset valuation and conversion for the PlasmaVault ecosystem. It is centered around the PriceOracleMiddlewareWithRoles contract, which acts as a centralized price hub, and the PriceOracleMiddlewareManager, which provides a vault-specific interface for price queries and validation.
The system is responsible for:
- Providing asset prices in a unified quote currency (USD) with 18 decimals contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol42-46 (opens in new tab)
- Managing custom price feed sources (e.g., Pendle PT, Curve, ERC4626) contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol125-135 (opens in new tab)
- Falling back to the Chainlink Feed Registry when custom sources are not defined contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol19-21 (opens in new tab)
- Implementing price change validation to protect vaults from extreme volatility or oracle manipulation contracts/managers/price/PriceOracleMiddlewareManagerLib.sol43-48 (opens in new tab)
System architecture
The architecture separates global price discovery from vault-specific price management and validation.
Logic flow and code entities

Architecture description:
- PlasmaVault and its Balance Fuses interact with the
PriceOracleMiddlewareManagerassigned to the vault contracts/vaults/PlasmaVault.sol75 (opens in new tab) - The PriceOracleMiddlewareManager handles vault-specific configuration, such as custom asset sources and price validation logic stored via
PriceOracleMiddlewareManagerLibcontracts/managers/price/PriceOracleMiddlewareManagerLib.sol64-75 (opens in new tab) - PriceOracleMiddlewareWithRoles serves as the protocol-wide price aggregator, managing specialized feeds like PtPriceFeed for Pendle tokens contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol140-150 (opens in new tab)
Core components
1. PriceOracleMiddlewareWithRoles
This contract provides the "Source of Truth" for asset prices. It normalizes all outputs to 18 decimals (WAD) contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol76-77 (opens in new tab)
- Quote Currency: Hardcoded to the Chainlink USD address
0x...0348contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol42 (opens in new tab) - Custom Sources: Allows administrators to map specific assets to custom
IPriceFeedimplementations contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol112-114 (opens in new tab) - Pendle Integration: Features specialized logic to deploy and manage
PtPriceFeedinstances for Pendle Principal Tokens contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol140-160 (opens in new tab)
2. PriceOracleMiddlewareManager
A per-vault manager that wraps the global middleware with validation and vault-specific overrides.
- getAssetPrice: The primary entry point. It checks for a vault-specific source in
PriceOracleMiddlewareManagerLibbefore falling back to the global middleware contracts/managers/price/PriceOracleMiddlewareManager.sol103-118 (opens in new tab) - Validation: Implements
validatePriceChangewhich compares the current price against alastValidatedPrice. If the delta exceedsmaxPriceDelta, the transaction reverts contracts/managers/price/PriceOracleMiddlewareManagerLib.sol43-48 (opens in new tab)
Specialized price feeds
The system supports various specialized feeds to handle complex DeFi assets.
Pendle PT Price Feed (PtPriceFeed)
Calculates the price of Pendle Principal Tokens using Pendle's TWAP oracle and the price of the underlying asset from the middleware contracts/price_oracle/price_feed/PtPriceFeed.sol12-18 (opens in new tab)
| Feature | Implementation Detail |
|---|---|
| TWAP Window | Minimum 5 minutes, recommended 15 minutes contracts/price_oracle/price_feed/PtPriceFeed.sol23 (opens in new tab) |
| Calculation | (PtToAssetRate * UnderlyingAssetPrice) / scalingFactor contracts/price_oracle/price_feed/PtPriceFeed.sol128 (opens in new tab) |
| Metadata | Returns Chainlink-compatible latestRoundData contracts/price_oracle/price_feed/PtPriceFeed.sol109-113 (opens in new tab) |
Feed factory pattern
Factories like PtPriceFeedFactory and CurveStableSwapNGPriceFeedFactory are used to deploy standardized feed instances that the middleware can then consume contracts/factory/price_feed/PtPriceFeedFactory.sol6-10 (opens in new tab)
Price validation mechanism
The validation system prevents the vault from transacting at "stale" or manipulated prices by enforcing a maximum allowed deviation.

- Configuration: Managed via
updatePriceValidationwhich sets themaxPriceDeltafor an asset contracts/managers/price/PriceOracleMiddlewareManagerLib.sol139-152 (opens in new tab) - Execution: Usually triggered via a Pre-Hook (
ValidateAllAssetsPricesPreHook) before vault actions likeexecuteordepositcontracts/handlers/pre_hooks/pre_hooks/ValidateAllAssetsPricesPreHook.sol18-23 (opens in new tab)
Access control and roles
The system utilizes a hierarchy of roles defined in Roles.sol to secure configuration.
| Role | Entity | Permission |
|---|---|---|
ADMIN_ROLE | AccessManager | Highest level; manages all roles contracts/libraries/Roles.sol11-13 (opens in new tab) |
ATOMIST_ROLE | PlasmaVault | Can update the priceOracleMiddleware address contracts/libraries/Roles.sol44-45 (opens in new tab) |
PRICE_ORACLE_MIDDLEWARE_MANAGER_ROLE | PriceOracleMiddlewareManager | Manages asset price sources and validation deltas contracts/libraries/Roles.sol102-105 (opens in new tab) |
SET_ASSETS_PRICES_SOURCES | PriceOracleMiddlewareWithRoles | Global permission to set price sources contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol27 (opens in new tab) |
ADD_PT_TOKEN_PRICE | PriceOracleMiddlewareWithRoles | Permission to deploy Pendle PT feeds contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol28 (opens in new tab) |
Data normalization
All prices returned by the middleware system are normalized to 18 decimals (WAD) to ensure consistency across the IPOR Fusion protocol.
- Normalization Formula: If a feed has decimals, the price is scaled by contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol76-77 (opens in new tab)
- Batch Processing:
getAssetsPricesallows fetching multiple asset prices in a single call, returning arrays of prices all in 18-decimal format contracts/price_oracle/PriceOracleMiddlewareWithRoles.sol92-107 (opens in new tab)