# SharePriceOracle

## Cross-Chain ERC4626 Vault Share Price Oracle

### Overview

SharePriceOracle is a multi-adapter oracle system designed for cross-chain ERC4626 vault share price propagation. The system enables protocols to access and share vault share prices across different blockchains using LayerZero as a messaging layer. It provides a unified interface for fetching accurate price data from various sources and serves as a critical infrastructure for cross-chain vault strategies, yield aggregators, and DeFi protocols.

### Key Features

* **Multi-adapter architecture**: Supports multiple price feed providers (Chainlink, Pyth, API3, Redstone, AMMs)
* **Cross-chain compatibility**: Propagates vault share prices across different blockchains via LayerZero
* **Price normalization**: Converts prices to standardized 18-decimal precision (WAD)
* **Fallback mechanisms**: Implements priority-based fallback for price sources
* **Price validation**: Enforces bounds checking and staleness prevention
* **L2 sequencer awareness**: Handles L2 sequencer downtime gracefully

### System Architecture

The SharePriceOracle system consists of three main components:

1. **SharePriceOracle**: The core contract that serves as the router and price aggregator
2. **Oracle Adapters**: Specialized contracts for interfacing with different price feed providers
3. **MaxLzEndpoint**: LayerZero endpoint for cross-chain communication

#### Data Flow

```
┌───────────────────┐          ┌───────────────────┐
│  SharePriceOracle │          │  SharePriceOracle │
│    (Chain A)      │◄─────────┤    (Chain B)      │
└─────────┬─────────┘          └─────────┬─────────┘
          │                              │
          ▼                              ▼
┌─────────────────────┐      ┌─────────────────────┐
│ Oracle Adapters     │      │ Oracle Adapters     │
│ (Chainlink, Pyth,   │      │ (Chainlink, Pyth,   │
│  UniswapV3, etc.)   │      │  UniswapV3, etc.)   │
└─────────────────────┘      └─────────────────────┘
```

### Core Contracts

#### SharePriceOracle

The SharePriceOracle is the central contract that:

1. Manages a registry of price adapters
2. Handles cross-chain asset mappings
3. Stores and updates share prices
4. Provides normalized price conversion
5. Enforces access control for different operations

```solidity
contract SharePriceOracle is ISharePriceOracle, OwnableRoles {
    // Roles
    uint256 public constant ADMIN_ROLE = _ROLE_0;
    uint256 public constant ENDPOINT_ROLE = _ROLE_1;
    uint256 public constant ADAPTER_ROLE = _ROLE_2;
    
    // Mappings
    mapping(address => mapping(uint8 => LocalAssetConfig)) public localAssetConfigs;
    mapping(address => StoredSharePrice) public storedSharePrices;
    mapping(bytes32 => address) public crossChainAssetMap;
    mapping(bytes32 => VaultReport) public sharePrices;
}
```

Key functions:

* `getSharePrices`: Fetches current share prices for multiple vaults
* `updateSharePrices`: Updates share prices received from other chains
* `getLatestSharePrice`: Gets the latest share price for a specific vault
* `getPrice`: Gets the price of an asset from available adapters
* `setLocalAssetConfig`: Configures a price feed for a local asset
* `setCrossChainAssetMapping`: Maps cross-chain assets to local equivalents

#### MaxLzEndpoint

The MaxLzEndpoint contract handles cross-chain messaging via LayerZero:

1. Sends vault share prices to other chains
2. Receives and processes share price updates
3. Manages messaging options and peers
4. Implements request-response patterns for price updates

```solidity
contract MaxLzEndpoint is ILayerZeroReceiver, Ownable {
    // Message pattern identifiers
    uint8 private constant AB_TYPE = 1;  // Simple send-receive
    uint8 private constant ABA_TYPE = 2; // Request-response pattern
    
    // Mappings
    mapping(uint32 eid => bytes32 peer) public peers;
}
```

Key functions:

* `sendSharePrices`: Sends share prices to a destination chain
* `requestSharePrices`: Requests share prices from a destination chain
* `lzReceive`: Processes incoming messages from LayerZero

### Oracle Adapters

The system supports multiple oracle adapters, each specialized for a different price feed provider:

#### 1. Chainlink Adapter

Fetches price data from Chainlink price feeds with heartbeat validation and price bounds checking.

```solidity
contract ChainlinkAdapter is BaseOracleAdapter {
    function getPrice(address asset, bool inUSD) 
        external view override returns (ISharePriceOracle.PriceReturnData memory);
}
```

#### 2. Pyth Adapter

Integrates with Pyth Network for high-frequency, decentralized price updates.

```solidity
contract PythAdapter is BaseOracleAdapter {
    function getPrice(address asset, bool inUSD) 
        external view override returns (ISharePriceOracle.PriceReturnData memory);
    
    function updateAndGetPrice(address asset, bool inUSD, bytes[] calldata updateData) 
        external payable returns (ISharePriceOracle.PriceReturnData memory);
}
```

#### 3. API3 Adapter

Uses API3's dAPI (data feed) system for price data.

```solidity
contract Api3Adapter is BaseOracleAdapter {
    function getPrice(address asset, bool inUSD) 
        external view override returns (ISharePriceOracle.PriceReturnData memory);
}
```

#### 4. Redstone Adapter

Integrates with Redstone's oracle network for price data.

```solidity
contract RedStoneAdapter is BaseOracleAdapter {
    function getPrice(address asset, bool inUSD) 
        external view override returns (ISharePriceOracle.PriceReturnData memory);
}
```

#### 5. AMM-based Adapters

Several adapters for extracting prices from AMM pools:

* **UniswapV3Adapter**: Uses TWAP (Time-Weighted Average Price) from Uniswap V3 pools
* **BalancerAdapter**: Extracts prices from Balancer weighted pools
* **AerodromeV1Adapter/AerodromeV2Adapter**: Works with Aerodrome pools (Base-specific)
* **Curve2PoolAssetAdapter**: Extracts prices from Curve pools with reentrancy protection

### Key Data Structures

#### VaultReport

Contains vault share price information and metadata for cross-chain communication:

```solidity
struct VaultReport {
    uint256 sharePrice;
    uint64 lastUpdate;
    uint32 chainId;
    address rewardsDelegate;
    address vaultAddress;
    address asset;
    uint256 assetDecimals;
}
```

#### PriceReturnData

Standardized structure for price data returned by adapters:

```solidity
struct PriceReturnData {
    uint240 price;     // Price normalized to WAD (1e18)
    bool hadError;     // Error flag
    bool inUSD;        // Price denomination
}
```

#### LocalAssetConfig

Configuration for local assets (e.g., USDC, WETH):

```solidity
struct LocalAssetConfig {
    address priceFeed; // Priority-ordered price feeds
    bool inUSD;        // Whether price should be in USD
    address adaptor;   // Adapter address
}
```

### Security Considerations

The SharePriceOracle implements several security mechanisms:

1. **Access control**: Role-based permissions for administrative and update operations
2. **Price validation**: Minimum and maximum bounds for prices to prevent manipulation
3. **Staleness prevention**: Timestamp-based checks to ensure price freshness
4. **Sequencer awareness**: Checks for L2 sequencer status before using prices
5. **Multiple price sources**: Fallback mechanism to increase resilience

### Common Workflows

#### Adding a New Vault to Monitor

To start monitoring a new vault's share price:

1. Ensure the vault's underlying asset has a price feed configured
2. Call `getSharePrices()` with the vault address to get its current share price
3. Use `sendSharePrices()` on the MaxLzEndpoint to propagate the price to other chains

#### Configuring a New Price Feed

To add a new price feed for an asset:

1. Deploy and configure the appropriate adapter contract
2. Grant the adapter the ADAPTER\_ROLE
3. Call `setLocalAssetConfig()` to register the asset with the adapter

#### Cross-Chain Asset Mapping

To enable price conversion for cross-chain assets:

1. Identify the local equivalent of the cross-chain asset
2. Call `setCrossChainAssetMapping()` with the source chain ID, source asset, and local asset

### Error Handling

The system uses custom errors to provide clear failure reasons:

* `InvalidAsset`: Asset not supported or not properly configured
* `NoValidPrice`: Unable to get a valid price
* `StalePrice`: Price is too old to be considered valid
* `SequencerUnavailable`: L2 sequencer is down or in grace period
* `MessageAlreadyProcessed`: Prevents duplicate processing of cross-chain messages

### Glossary

* **WAD**: Standard unit representing 1 with 18 decimal places (10^18)
* **EID**: Endpoint ID in LayerZero, representing a specific blockchain
* **TWAP**: Time-Weighted Average Price, used by DEX-based oracles
* **ERC4626**: Token standard for tokenized vaults
* **Share Price**: The price of one vault share expressed in terms of the underlying asset


---

# 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://devs.maxapy.io/periphery/sharepriceoracle.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.
