# Chain 138 Oracle and Keeper Reference **Purpose**: ORACLE_AGGREGATOR / ORACLE_PROXY for Chain 138 and keeper/price-update flows so PMM and reporting stay aligned with oracle data. --- ## Environment Variables (Chain 138) Set in project `.env` (and in token-aggregation or relay when they consume oracle): | Variable | Description | |----------|-------------| | `ORACLE_AGGREGATOR_ADDRESS` | Oracle aggregator contract on Chain 138 (e.g. from deployment). Used by CCIP and other consumers. | | `ORACLE_PROXY_ADDRESS` | Oracle proxy contract on Chain 138 when applicable. | | `ORACLE_PRICE_FEED` | **OraclePriceFeed** wired to **PriceFeedKeeper** and **ReserveSystem** — not the same as `ORACLE_PROXY_ADDRESS`. | | `CHAIN138_WETH_MOCK_PRICE_FEED` | Optional **MockPriceFeed** for WETH on the keeper path when Besu block time lags the public aggregator `updatedAt`. Sync: `scripts/reserve/sync-weth-mock-price.sh`. | | `RESERVE_SYSTEM` | ReserveSystem address (Chain 138). Required for DODOPMMIntegration oracle-backed mid price. | | `RPC_URL_138` / `RPC_URL` | RPC endpoint for Chain 138 (keeper and scripts). | References: [DEPLOYMENT_COMPLETE_GUIDE.md](../deployment/DEPLOYMENT_COMPLETE_GUIDE.md), [DEPLOYMENT_CHECKLIST.md](../DEPLOYMENT_CHECKLIST.md), [PARALLEL_COMPLETION_TASK_LIST.md](../PARALLEL_COMPLETION_TASK_LIST.md). --- ## Keeper and Price Feed Updates 1. **OraclePriceFeed → ReserveSystem** ReserveSystem receives prices from OraclePriceFeed. Ensure assets used by PMM pairs (e.g. cUSDT, cUSDC, USDT, USDC) have aggregators set in OraclePriceFeed and are updated on schedule. See: [PRICE_FEED_SETUP.md](PRICE_FEED_SETUP.md). 2. **Keeper (on-chain / off-chain)** - **PriceFeedKeeper** and scripts: `script/reserve/DeployKeeper.s.sol`, `scripts/reserve/keeper-service.js`, `scripts/reserve/keeper-service.sh`. - **Check/perform upkeep**: `PerformUpkeep.s.sol`, `CheckUpkeep.s.sol`. See: [KEEPER_COMPLETE.md](KEEPER_COMPLETE.md), [KEEPER_SETUP.md](KEEPER_SETUP.md) (if present). 3. **Oracle publisher (off-chain)** Service that pushes external prices (e.g. CoinGecko) into the system: - `services/oracle-publisher/` (e.g. `oracle_publisher.py`, `oracle_publisher_optimized.py`). Use for assets that do not have a Chainlink-style aggregator on Chain 138. 4. **Update oracle price script** One-off or cron-driven update of oracle/oracle proxy with current price: - `scripts/update-oracle-price.sh` — usage: `[rpc-url] [oracle-address] [private-key]`; uses `AGGREGATOR_ADDRESS` and fetches ETH/USD from CoinGecko. **CoinGecko Demo keys** (`CG-…`): use `https://api.coingecko.com` with header `x-cg-demo-api-key` (not `pro-api.coingecko.com` with `x-cg-pro-api-key`). Paid Pro uses the pro host and pro header; the script tries demo first, then pro, then unauthenticated public. Schedule this (or the keeper service) so PMM oracle-backed prices and reporting stay fresh. --- ## PMM mesh automation (6-second tick) **Policy:** Run off-chain ticks every **6 seconds** so oracle pushes, `PriceFeedKeeper` upkeep, and PMM/WETH read paths stay warm—supporting peg alignment with `DODOPMMIntegration` / optional `ReserveSystem`. | Component | Role | |-----------|------| | `scripts/reserve/pmm-mesh-6s-automation.sh` | Loop: `getPoolPriceOrOracle` on `PMM_MESH_POLL_POOLS`, WETH9/WETH10 `totalSupply` reads, conditional `performUpkeep`, `update-oracle-price.sh`. | | `PMM_MESH_INTERVAL_SEC` | Default **6**. | | `PriceFeedKeeper.updateInterval` | Default on **new** deployments is **6s** (`PriceFeedKeeper.sol`). **Existing** keepers: run `scripts/reserve/set-price-feed-keeper-interval.sh 6` as admin. | | `KEEPER_PRIVATE_KEY` | Wallet with **KEEPER_ROLE** on `PriceFeedKeeper` for `performUpkeep` txs. | | `MESH_WETH_WRAP_WEI` | Optional tiny `WETH.deposit{value}` on a throttled cadence (`MESH_WETH_WRAP_EVERY_N`); costs gas—default **0** (off). | **systemd:** `config/systemd/chain138-pmm-mesh-automation.service.example` in the Proxmox repo—copy, fix paths, `enable --now`. **Bring-up checklist (operator):** 1. `PRICE_FEED_KEEPER_ADDRESS` in `smom-dbis-138/.env` (Chain 138: `0xD3AD6831aacB5386B8A25BB8D8176a6C8a026f04` per explorer docs—verify live). 2. `KEEPER_PRIVATE_KEY` optional if same as `PRIVATE_KEY` (must have `KEEPER_ROLE` on the keeper). 3. `./scripts/reserve/set-price-feed-keeper-interval.sh 6` once if the keeper still used a 30s interval. 4. Oracle: `scripts/update-oracle-price.sh` needs Besu-safe paths (eth_call + explicit `--gas-limit`); set `AGGREGATOR_ADDRESS` / transmitter as deployed. 5. If the keeper uses a **WETH MockPriceFeed** (`CHAIN138_WETH_MOCK_PRICE_FEED`), run `scripts/reserve/sync-weth-mock-price.sh` on a schedule (or from the same cron as the mesh) so ReserveSystem WETH tracks the market. 6. Start: `nohup ./scripts/reserve/pmm-mesh-6s-automation.sh >> logs/pmm-mesh-automation.log 2>&1 &` (optional: `MESH_CAST_GAS_PRICE=2gwei` for Besu) **Note:** On-chain PMM curves still move on **swaps**; this loop **does not** replace liquidity. It **feeds** oracles/keeper and **observes** PMM/WETH state on a fixed cadence. --- ## PMM and Reporting - **DODOPMMIntegration**: Optional `setReserveSystem(ReserveSystem)`; then `getPoolPriceOrOracle(pool)` uses ReserveSystem when base/quote are registered. - **Token-aggregation**: Set `CHAIN_138_DODO_PMM_INTEGRATION` so the pool indexer ingests PMM pools; report API then includes them in `/report/all`, `/report/coingecko`, `/report/cross-chain`. See: [DODO_PMM_INTEGRATION.md](DODO_PMM_INTEGRATION.md#oracle-and-reporting).