# 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**: ```bash export USE_MOCK_FEEDS=true export XAU_ASSET= export USDC_ASSET= export ETH_ASSET= forge script script/reserve/SetupPriceFeeds.s.sol:SetupPriceFeeds \ --rpc-url chain138 \ --broadcast ``` ### Option 2: Real Chainlink Aggregators (Production) Use real Chainlink aggregators for production environments. **Advantages**: - Real-time market prices - High reliability - Industry standard - Multiple data sources **Usage**: ```bash export USE_MOCK_FEEDS=false export XAU_ASSET= export XAU_AGGREGATOR= export USDC_ASSET= export USDC_AGGREGATOR= export ETH_ASSET= export ETH_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: ```bash # Set environment variables export RESERVE_SYSTEM= export RESERVE_ADMIN= 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: ```bash # Set environment variables export RESERVE_SYSTEM= export RESERVE_ADMIN= export USE_MOCK_FEEDS=false # Asset addresses export XAU_ASSET= export USDC_ASSET= export ETH_ASSET= # 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: ```solidity // Manual update oraclePriceFeed.updatePriceFeed(assetAddress); // Update multiple assets address[] memory assets = [xauAsset, usdcAsset, ethAsset]; oraclePriceFeed.updateMultiplePriceFeeds(assets); ``` ### Step 4: Verify Price Feeds ```solidity // 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: ```solidity oraclePriceFeed.setUpdateInterval(60); // 60 seconds ``` --- ## Mock Price Feed Usage ### Deploy Mock Price Feed ```solidity // Deploy with initial price MockPriceFeed mockFeed = new MockPriceFeed(2000 * 1e8, 8); // $2000, 8 decimals ``` ### Update Mock Price ```solidity // Update price mockFeed.updatePrice(2100 * 1e8); // $2100 // Update with custom timestamp mockFeed.updatePriceWithTimestamp(2100 * 1e8, block.timestamp - 10); ``` ### Get Price Data ```solidity // 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: ```javascript // 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 ```bash #!/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 - [Reserve System Documentation](./INTEGRATION_COMPLETE.md) - [Oracle System Documentation](../oracle/README.md) - [Chainlink Price Feeds](https://docs.chain.link/data-feeds/price-feeds)