Files
smom-dbis-138/docs/integration/KEEPER_SETUP.md

410 lines
8.5 KiB
Markdown
Raw Normal View History

# Automated Price Feed Keeper Setup Guide
**Date**: 2025-01-27
**Status**: ✅ **COMPLETE**
---
## Overview
This guide explains how to set up automated price feed updates using the PriceFeedKeeper contract. The keeper automatically updates price feeds at regular intervals, ensuring prices stay current.
---
## Architecture
### Components
1. **PriceFeedKeeper Contract** - On-chain keeper contract
2. **Keeper Service** - Off-chain service that calls the keeper
3. **OraclePriceFeed** - Price feed oracle integration
### Flow
```
Keeper Service (Off-chain)
PriceFeedKeeper Contract
OraclePriceFeed
ReserveSystem
```
---
## Deployment
### Step 1: Deploy PriceFeedKeeper
```bash
# Set environment variables
export PRIVATE_KEY=<deployer_private_key>
export RPC_URL_138=<chain138_rpc_url>
export ORACLE_PRICE_FEED=<oracle_price_feed_address>
export RESERVE_ADMIN=<admin_address>
# Optional: Asset addresses to track
export XAU_ASSET=<xau_token_address>
export USDC_ASSET=<usdc_token_address>
export ETH_ASSET=<eth_token_address>
# Optional: Keeper address (defaults to deployer)
export KEEPER_ADDRESS=<keeper_address>
# Deploy keeper
forge script script/reserve/DeployKeeper.s.sol:DeployKeeper \
--rpc-url chain138 \
--broadcast \
--verify
```
### Step 2: Track Assets
Assets must be tracked before the keeper can update them:
```solidity
// Via contract call
keeper.trackAsset(xauAsset);
keeper.trackAsset(usdcAsset);
keeper.trackAsset(ethAsset);
```
Or use the deployment script which automatically tracks assets if provided.
---
## Keeper Service Options
### Option 1: Node.js Keeper Service (Recommended)
**Requirements**:
- Node.js 16+
- npm packages: `ethers`, `dotenv`
**Setup**:
```bash
# Install dependencies
npm install ethers dotenv
# Set environment variables
export RPC_URL_138=<chain138_rpc_url>
export KEEPER_PRIVATE_KEY=<keeper_wallet_private_key>
export PRICE_FEED_KEEPER_ADDRESS=<keeper_contract_address>
export UPDATE_INTERVAL=30 # seconds
# Run keeper service
node scripts/reserve/keeper-service.js
```
**Features**:
- Automatic retry logic
- Error handling
- Statistics tracking
- Graceful shutdown
- Event parsing
### Option 2: Bash Keeper Service
**Setup**:
```bash
# Set environment variables
export RPC_URL_138=<chain138_rpc_url>
export PRICE_FEED_KEEPER_ADDRESS=<keeper_contract_address>
export UPDATE_INTERVAL=30 # seconds
# Make script executable
chmod +x scripts/reserve/keeper-service.sh
# Run keeper service
./scripts/reserve/keeper-service.sh
```
**Features**:
- Simple bash implementation
- Uses Foundry scripts
- Basic error handling
### Option 3: Chainlink Keepers
**Setup**:
1. Register keeper contract with Chainlink Keepers
2. Fund keeper with LINK tokens
3. Configure upkeep interval
**Configuration**:
```javascript
// Register upkeep
const keeperRegistry = await ethers.getContractAt("KeeperRegistry", registryAddress);
await keeperRegistry.registerUpkeep(
keeperAddress, // Keeper contract address
gasLimit, // Gas limit for upkeep
adminAddress, // Admin address
checkData, // Check data (empty for our keeper)
amount, // LINK amount to fund
source, // Source address
encryptedEmail // Encrypted email (optional)
);
```
### Option 4: Gelato Network
**Setup**:
1. Register task with Gelato
2. Configure execution interval
3. Fund with native token
**Configuration**:
```javascript
// Register task
const gelato = await ethers.getContractAt("Gelato", gelatoAddress);
await gelato.createTask(
keeperAddress, // Task contract
"performUpkeep()", // Function selector
interval, // Execution interval
executor // Executor address
);
```
---
## Manual Upkeep
### Check if Upkeep is Needed
```bash
forge script script/reserve/CheckUpkeep.s.sol:CheckUpkeep \
--rpc-url chain138
```
### Perform Upkeep
```bash
export KEEPER_PRIVATE_KEY=<keeper_private_key>
export PRICE_FEED_KEEPER_ADDRESS=<keeper_address>
forge script script/reserve/PerformUpkeep.s.sol:PerformUpkeep \
--rpc-url chain138 \
--broadcast
```
---
## Configuration
### Update Interval
Set the update interval (in seconds):
```solidity
keeper.setUpdateInterval(60); // 60 seconds
```
### Maximum Updates Per Call
Limit the number of assets updated per call:
```solidity
keeper.setMaxUpdatesPerCall(20); // Update up to 20 assets per call
```
### Track/Untrack Assets
```solidity
// Track asset
keeper.trackAsset(assetAddress);
// Untrack asset
keeper.untrackAsset(assetAddress);
```
---
## Monitoring
### Check Keeper Status
```solidity
// Get tracked assets
address[] memory assets = keeper.getTrackedAssets();
// Check if asset needs update
bool needsUpdate = keeper.needsUpdate(assetAddress);
// Get update interval
uint256 interval = keeper.updateInterval();
```
### Monitor Events
Listen for `PriceFeedsUpdated` events:
```javascript
keeper.on("PriceFeedsUpdated", (assets, timestamp, event) => {
console.log("Updated assets:", assets);
console.log("Timestamp:", timestamp);
});
```
---
## Running as a Service
### Systemd Service
Create `/etc/systemd/system/price-feed-keeper.service`:
```ini
[Unit]
Description=Price Feed Keeper Service
After=network.target
[Service]
Type=simple
User=keeper
WorkingDirectory=/path/to/smom-dbis-138
Environment="RPC_URL_138=https://rpc.d-bis.org"
Environment="KEEPER_PRIVATE_KEY=0x..."
Environment="PRICE_FEED_KEEPER_ADDRESS=0x..."
Environment="UPDATE_INTERVAL=30"
ExecStart=/usr/bin/node scripts/reserve/keeper-service.js
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
**Enable and start**:
```bash
sudo systemctl enable price-feed-keeper
sudo systemctl start price-feed-keeper
sudo systemctl status price-feed-keeper
```
### Docker Service
Create `docker-compose.yml`:
```yaml
version: '3.8'
services:
keeper:
image: node:18
working_dir: /app
volumes:
- .:/app
environment:
- RPC_URL_138=${RPC_URL_138}
- KEEPER_PRIVATE_KEY=${KEEPER_PRIVATE_KEY}
- PRICE_FEED_KEEPER_ADDRESS=${PRICE_FEED_KEEPER_ADDRESS}
- UPDATE_INTERVAL=30
command: node scripts/reserve/keeper-service.js
restart: unless-stopped
```
**Run**:
```bash
docker-compose up -d
docker-compose logs -f keeper
```
---
## Troubleshooting
### Keeper Not Updating
**Check**:
1. Keeper has `KEEPER_ROLE`
2. Assets are tracked
3. Update interval has passed
4. Keeper service is running
**Solution**:
```bash
# Check upkeep status
forge script script/reserve/CheckUpkeep.s.sol:CheckUpkeep --rpc-url chain138
# Manually perform upkeep
forge script script/reserve/PerformUpkeep.s.sol:PerformUpkeep --rpc-url chain138 --broadcast
```
### Gas Estimation Errors
**Error**: `Gas estimation failed`
**Solution**:
1. Check keeper has sufficient balance
2. Verify assets are tracked
3. Check update interval hasn't passed
4. Verify oracle price feed is configured
### Transaction Failures
**Error**: `Transaction reverted`
**Solution**:
1. Check keeper role permissions
2. Verify oracle price feed address
3. Check asset aggregators are set
4. Verify price feeds are not stale
---
## Security Considerations
1. **Private Key Security**: Store keeper private key securely
2. **Access Control**: Use multi-sig for admin functions
3. **Rate Limiting**: Set appropriate update intervals
4. **Monitoring**: Monitor keeper transactions and failures
5. **Backup**: Run multiple keeper instances for redundancy
---
## Best Practices
1. **Multiple Keepers**: Run multiple keeper instances for redundancy
2. **Monitoring**: Set up alerts for keeper failures
3. **Gas Management**: Monitor gas prices and adjust intervals
4. **Error Handling**: Implement retry logic and error reporting
5. **Logging**: Log all keeper activities for auditing
---
## Cost Estimation
### Gas Costs
- **Check Upkeep**: ~30,000 gas (view function, no cost)
- **Perform Upkeep**: ~100,000 - 300,000 gas per asset
- **Update 10 Assets**: ~1,000,000 - 3,000,000 gas
### Frequency
- **Update Interval**: 30 seconds (recommended)
- **Updates Per Day**: 2,880
- **Gas Per Day**: ~2.88M - 8.64M gas (for 10 assets)
### Cost (at 20 gwei)
- **Per Update**: 0.02 - 0.06 ETH
- **Per Day**: 57.6 - 172.8 ETH
- **Per Month**: 1,728 - 5,184 ETH
**Note**: Costs vary based on gas prices and number of assets.
---
## References
- [Price Feed Setup](./PRICE_FEED_SETUP.md)
- [Reserve System Integration](./INTEGRATION_COMPLETE.md)
- [Chainlink Keepers](https://docs.chain.link/chainlink-automation)
- [Gelato Network](https://docs.gelato.network)