Oracle Price Updates
Custom on-chain oracle contract on Base stores Twin token prices, updated by cron via Belo API + BitGo Express.
Overview
The oracle provides on-chain price data for Twin tokens (ARGt, BRAt, COLt, MEXt) quoted in USDC. Prices are fetched from the Belo exchange API, converted to 18-decimal fixed-point, and written on-chain via BitGo Express contract calls.
Oracle Contract: 0x2152C44D14B6D0A2831eF929F3f1B529F9163c45 (Base)
Contract Interface
| Function | Description |
|---|---|
updatePrice(address tokenA, address tokenB, uint256 price) | Write new price (restricted to updater) |
getLatestPrice(address tokenA, address tokenB) | Read current price (public) |
- Price scale: 18 decimals. A price of
1466.5 ARGT/USDCis stored as1466500000000000000000(1466.5 * 10^18). - Price direction: The oracle stores the price as
1 / midPrice * 1e18(USDC per token, inverted from Belo's quote).
Token Pairs
| Token | Belo Pair Code | Token Address (Base) | Quote |
|---|---|---|---|
| ARGt | (from config) | 0xf016413834E6D1A14F3D628B11D6Ef725a6bdbDD | USDC |
| BRAt | (from config) | 0xFEE29845569570F8e0119291dff77B7b93283aaB | USDC |
| COLt | (from config) | 0xD70ad085684b2A9f4B5d54D7BDB2ecA37a273216 | USDC |
| MEXt | (from config) | 0x59863989d080B22476DB95656d0C3CC18be92214 | USDC |
Cron ORACLE_PRICE_UPDATE Flow
Detailed Flowchart
Oracle Wallet Configuration
The oracle wallet is stored in the oracle_wallet table with the following structure:
| Field | Description |
|---|---|
bitgoWalletId | BitGo wallet ID for signing |
bitgoCoin | "baseeth" (base coin, NOT token-qualified) |
passphraseEncrypted | Encrypted BitGo wallet passphrase |
oracleAddress | Oracle contract address |
updaterAddress | Authorized updater EOA |
oracleTokens | JSON config object |
oracleTokens Structure
Code
Dashboard Endpoint
| Method | Path | Description |
|---|---|---|
GET | /api/operations/oracle-price?symbol=ARGT | Read current on-chain price for a token |
Returns the price from getLatestPrice() converted to human-readable format.
Important Notes
coin = "baseeth" (NOT token-qualified)
The oracle update is a pure contract call to the oracle contract, not a token transfer. Therefore:
Code
The baseeth:argt coin format is only used when sending ARGT tokens (e.g., minting). Oracle updates write to a separate contract and don't involve token transfers.
Timeouts
| Operation | Timeout | Default | Why Changed |
|---|---|---|---|
| Belo API fetch | 30s | Was 10s | Belo occasionally slow, caused "timeout of 10000ms exceeded" |
| RPC calls | 20s | Was 10s | On-chain reads can be slow under load |
Sanity Check (50% deviation)
Before writing a new price, the cron compares it against the current on-chain value. If the deviation exceeds 50%, the update is skipped and a warning is logged. This prevents:
- Writing corrupted prices from API errors
- Flash crash / spike propagation
- Stale data overwrite with wildly incorrect values
Error Handling
- If all token updates fail in a single run, the cron throws an error (marking the job as failed in the DB with
lastError). - If at least one token succeeds, the job completes successfully (partial updates are acceptable).
- Individual token failures are logged but don't block other tokens.
No Direct Wallet
The oracle previously used a direct ethers.js wallet (bypassing BitGo). This was removed and all updates now go through BitGo Express for consistency and security. The privateKeyEncrypted field is no longer used.
Price Calculation Example
For ARGt with a Belo quote of ask: 1470, bid: 1463:
Code
This means 1 ARGt = 0.000681... USDC (or equivalently, 1 USDC = 1466.5 ARGt).