# 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=<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
```

### 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=<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:

```bash
# 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:

```bash
# 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:

```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)
- [Price Feed and Reserve Summary](./PRICE_FEED_AND_RESERVES_COMPLETE.md)
- [Chainlink Price Feeds](https://docs.chain.link/data-feeds/price-feeds)
