Files
smom-dbis-138/docs/integration/PRICE_FEED_SETUP.md
defiQUG 1fb7266469 Add Oracle Aggregator and CCIP Integration
- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control.
- Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities.
- Created .gitmodules to include OpenZeppelin contracts as a submodule.
- Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment.
- Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks.
- Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring.
- Created scripts for resource import and usage validation across non-US regions.
- Added tests for CCIP error handling and integration to ensure robust functionality.
- Included various new files and directories for the orchestration portal and deployment scripts.
2025-12-12 14:57:48 -08:00

7.3 KiB

Price Feed Setup Guide

Date: 2025-01-27 Status: COMPLETE


Overview

This guide explains how to set up price feeds for the Reserve System, including both mock feeds for testing and real Chainlink aggregators for production.


Architecture

Components

  1. OraclePriceFeed - Integrates Reserve System with Chainlink-compatible aggregators
  2. MockPriceFeed - Mock price feed for testing and development
  3. ReserveSystem - Core reserve system that receives price updates

Flow

Chainlink Aggregator / MockPriceFeed
         │
         ▼
   OraclePriceFeed
         │
         ▼
   ReserveSystem

Setup Options

Option 1: Mock Price Feeds (Testing/Development)

Use mock price feeds for testing and development environments.

Advantages:

  • No external dependencies
  • Full control over prices
  • Easy to test edge cases
  • No API costs

Usage:

export USE_MOCK_FEEDS=true
export XAU_ASSET=<xau_token_address>
export USDC_ASSET=<usdc_token_address>
export ETH_ASSET=<eth_token_address>

forge script script/reserve/SetupPriceFeeds.s.sol:SetupPriceFeeds \
  --rpc-url chain138 \
  --broadcast

Use real Chainlink aggregators for production environments.

Advantages:

  • Real-time market prices
  • High reliability
  • Industry standard
  • Multiple data sources

Usage:

export USE_MOCK_FEEDS=false
export XAU_ASSET=<xau_token_address>
export XAU_AGGREGATOR=<chainlink_xau_usd_aggregator>
export USDC_ASSET=<usdc_token_address>
export USDC_AGGREGATOR=<chainlink_usdc_usd_aggregator>
export ETH_ASSET=<eth_token_address>
export ETH_AGGREGATOR=<chainlink_eth_usd_aggregator>

forge script script/reserve/SetupPriceFeeds.s.sol:SetupPriceFeeds \
  --rpc-url chain138 \
  --broadcast

Step-by-Step Setup

Step 1: Deploy OraclePriceFeed (if not already deployed)

The SetupPriceFeeds.s.sol script will automatically deploy OraclePriceFeed if not provided via environment variable.

Step 2: Configure Aggregators

For Mock Feeds:

# Set environment variables
export RESERVE_SYSTEM=<reserve_system_address>
export RESERVE_ADMIN=<admin_address>
export USE_MOCK_FEEDS=true

# Asset addresses (use test token addresses)
export XAU_ASSET=0x1111111111111111111111111111111111111111
export USDC_ASSET=0x2222222222222222222222222222222222222222
export ETH_ASSET=0x3333333333333333333333333333333333333333

# Run setup script
forge script script/reserve/SetupPriceFeeds.s.sol:SetupPriceFeeds \
  --rpc-url chain138 \
  --broadcast

For Real Aggregators:

# Set environment variables
export RESERVE_SYSTEM=<reserve_system_address>
export RESERVE_ADMIN=<admin_address>
export USE_MOCK_FEEDS=false

# Asset addresses
export XAU_ASSET=<xau_token_address>
export USDC_ASSET=<usdc_token_address>
export ETH_ASSET=<eth_token_address>

# Chainlink aggregator addresses (example for Ethereum mainnet)
export XAU_AGGREGATOR=0x214eD9Da11D2fbe465a6fc601a91E62EbEc1a0D6  # XAU/USD
export USDC_AGGREGATOR=0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6  # USDC/USD
export ETH_AGGREGATOR=0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419  # ETH/USD

# Run setup script
forge script script/reserve/SetupPriceFeeds.s.sol:SetupPriceFeeds \
  --rpc-url chain138 \
  --broadcast

Step 3: Update Price Feeds

Price feeds can be updated manually or via automated keeper:

// Manual update
oraclePriceFeed.updatePriceFeed(assetAddress);

// Update multiple assets
address[] memory assets = [xauAsset, usdcAsset, ethAsset];
oraclePriceFeed.updateMultiplePriceFeeds(assets);

Step 4: Verify Price Feeds

// Check if update is needed
bool needsUpdate = oraclePriceFeed.needsUpdate(assetAddress);

// Get current price
(uint256 price, uint256 timestamp) = reserveSystem.getPrice(assetAddress);

Price Feed Configuration

Supported Assets

Common assets to configure:

  1. Gold (XAU)

    • Token: XAU token address
    • Aggregator: Chainlink XAU/USD
    • Decimals: 8 (Chainlink) → 18 (Reserve System)
    • Multiplier: 1e10
  2. USDC

    • Token: USDC token address
    • Aggregator: Chainlink USDC/USD
    • Decimals: 8 (Chainlink) → 18 (Reserve System)
    • Multiplier: 1e10
  3. ETH

    • Token: ETH/WETH token address
    • Aggregator: Chainlink ETH/USD
    • Decimals: 8 (Chainlink) → 18 (Reserve System)
    • Multiplier: 1e10

Price Multipliers

Price multipliers convert from aggregator decimals (typically 8) to Reserve System decimals (18):

  • 8 decimals → 18 decimals: Multiplier = 1e10
  • 18 decimals → 18 decimals: Multiplier = 1e0 (1)

Update Interval

Default update interval: 30 seconds

Can be configured:

oraclePriceFeed.setUpdateInterval(60); // 60 seconds

Mock Price Feed Usage

Deploy Mock Price Feed

// Deploy with initial price
MockPriceFeed mockFeed = new MockPriceFeed(2000 * 1e8, 8); // $2000, 8 decimals

Update Mock Price

// Update price
mockFeed.updatePrice(2100 * 1e8); // $2100

// Update with custom timestamp
mockFeed.updatePriceWithTimestamp(2100 * 1e8, block.timestamp - 10);

Get Price Data

// Get latest answer
int256 price = mockFeed.latestAnswer();

// Get latest round data
(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) =
    mockFeed.latestRoundData();

Automated Price Updates

Keeper Integration

Set up a keeper to automatically update price feeds:

// Example keeper script
const OraclePriceFeed = await ethers.getContractAt("OraclePriceFeed", oraclePriceFeedAddress);
const assets = [xauAsset, usdcAsset, ethAsset];

// Check if updates are needed
for (const asset of assets) {
    const needsUpdate = await OraclePriceFeed.needsUpdate(asset);
    if (needsUpdate) {
        await OraclePriceFeed.updatePriceFeed(asset);
    }
}

Cron Job Example

#!/bin/bash
# Update price feeds every 30 seconds

while true; do
    forge script script/reserve/UpdatePriceFeeds.s.sol:UpdatePriceFeeds \
      --rpc-url chain138 \
      --broadcast
    sleep 30
done

Troubleshooting

Price Feed Not Available

Error: ReserveSystem: price feed not available

Solution:

  1. Verify aggregator is set: oraclePriceFeed.aggregators(asset)
  2. Update price feed: oraclePriceFeed.updatePriceFeed(asset)
  3. Check aggregator is returning valid data

Stale Price

Error: ReserveSystem: stale source price

Solution:

  1. Update price feed more frequently
  2. Increase update interval if needed
  3. Check aggregator is updating regularly

Invalid Price

Error: OraclePriceFeed: invalid price

Solution:

  1. Verify aggregator is returning positive values
  2. Check aggregator is not paused
  3. Verify aggregator address is correct

Security Considerations

  1. Access Control: Only authorized addresses can update price feeds
  2. Price Validation: Prices are validated before updating Reserve System
  3. Staleness Check: Prices older than threshold are rejected
  4. Multi-Sig: Consider using multi-sig for critical price feed updates

References