Some checks failed
CI/CD Pipeline / Solidity Contracts (push) Failing after 1m11s
CI/CD Pipeline / Security Scanning (push) Has been cancelled
CI/CD Pipeline / Lint and Format (push) Has been cancelled
CI/CD Pipeline / Terraform Validation (push) Has been cancelled
CI/CD Pipeline / Kubernetes Validation (push) Has been cancelled
Validation / validate-genesis (push) Has been cancelled
Validation / validate-terraform (push) Has been cancelled
Validation / validate-kubernetes (push) Has been cancelled
Validation / validate-smart-contracts (push) Has been cancelled
Validation / validate-security (push) Has been cancelled
Validation / validate-documentation (push) Has been cancelled
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 1m4s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 31s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 29s
Verify Deployment / Verify Deployment (push) Failing after 57s
Relay router, reserve system, oracle publisher, token-aggregation compliance middleware, and Monad deployment scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
118 lines
8.1 KiB
Markdown
118 lines
8.1 KiB
Markdown
# 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/DEPLOYMENT_CHECKLIST.md), [MASTER_TASK_LIST.md](../operations/tasks/MASTER_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`.
|
|
|
|
**One-shot on-chain alignment (aggregator → ReserveSystem → DODO oracle path):** parent repo `scripts/deployment/fix-chain138-pricing-feeds.sh` (see `docs/04-configuration/CHAIN138_PRICING_FEEDS_LIVE.md`). Forge helper: `script/reserve/SyncChain138ReserveFromOracle.s.sol`. Live WETH pools are **DVM** (pool `i` not resettable); optional DPP-only helper: `scripts/deployment/reset-chain138-weth-pmm-pool-i.sh`.
|
|
|
|
| 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). |
|
|
|
|
**Dedicated keeper signer:** generate and store a separate keeper key with
|
|
`scripts/deployment/generate-chain138-keeper-key.sh`.
|
|
By default it writes the secret to `~/.secure-secrets/chain138-keeper.env` and a local helper
|
|
to `.env.keeper.local` (gitignored) that sources the secret file.
|
|
|
|
**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` should be a dedicated keeper signer with `KEEPER_ROLE` on the keeper.
|
|
The mesh now skips keeper writes cleanly when no dedicated keeper key is present.
|
|
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(address)`; **`getPoolPriceOrOracle`** uses ReserveSystem **`getPrice`** (quote per base) when both asset feeds exist. On live Chain 138, **`ReserveConversionPriceAdapter`** (`0xA740EFF8C1339ea46833A6A968F24f3183a503C4`) is wired on Stack A — deploy with **`FOUNDRY_PROFILE=chain138`** (Paris EVM). See [CHAIN138_PRICING_FEEDS_LIVE.md](../../../docs/04-configuration/CHAIN138_PRICING_FEEDS_LIVE.md).
|
|
- **Official USDT/USDC** must be wired on **OraclePriceFeed** (`RefreshChain138UsdFeedsAndWireUsdc.s.sol`) so WETH/USDT and WETH/USDC oracle paths do not fall back to DVM **`getMidPrice()`** (~$1).
|
|
- **Token-aggregation**: Set `CHAIN_138_DODO_PMM_INTEGRATION=0x86ADA6Ef91A3B450F89f2b751e93B1b7A3218895` 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).
|
|
|
|
## Sibling archive keeper imports (2026-06-02)
|
|
|
|
Chainlink/Gelato keeper stack imported from sibling WIP archive (see [docs/00-meta/SIBLING_WIP_IMPORT.md](../00-meta/SIBLING_WIP_IMPORT.md)):
|
|
|
|
- `contracts/reserve/ChainlinkKeeperCompatible.sol`, `contracts/reserve/GelatoKeeperCompatible.sol`
|
|
- `script/reserve/DeployChainlinkKeeper.s.sol`, `script/reserve/DeployGelatoKeeper.s.sol`
|
|
- `docker/Dockerfile.keeper`, `docker/docker-compose.keeper.yml`, `systemd/price-feed-keeper.service`
|
|
- `scripts/reserve/chainlink-keeper-setup.js`, `gelato-keeper-setup.js`, `monitor-keeper.js`, `deploy-all.sh`
|
|
|
|
---
|
|
|
|
## deploy-all.sh dry-run
|
|
|
|
Validate keeper deploy wiring without broadcasting transactions or mutating `.env`.
|
|
|
|
```bash
|
|
cd smom-dbis-138
|
|
DRY_RUN=1 bash scripts/reserve/deploy-all.sh
|
|
# or
|
|
bash scripts/reserve/deploy-all.sh --dry-run
|
|
```
|
|
|
|
Dry-run behavior:
|
|
|
|
- Prints each deployment step and the `PRICE_FEED_KEEPER_ADDRESS` read from `.env` (must match `0xD3AD6831aacB5386B8A25BB8D8176a6C8a026f04` for Chain 138).
|
|
- Skips `forge script` `--broadcast` / `--verify` and does not append addresses to `.env`.
|
|
- When `DEPLOY_CHAINLINK=true` or `DEPLOY_GELATO=true`, prints the optional Chainlink/Gelato forge commands and follow-up setup scripts that would run.
|
|
|
|
Live deploy (no `DRY_RUN`): same script without dry-run flags; requires `PRIVATE_KEY` and uses `RPC_URL_138` (default `https://rpc.d-bis.org`).
|