Optimistic Oracle for arbitrary off-chain data. Asserters post a bonded claim that is treated as truth unless disputed within a liveness window; disputes escalate to UMA's Data Verification Mechanism (DVM) where UMA tokenholders vote. Powers Polymarket resolution, cross-chain insurance, and KPI options.
- 01prediction market resolution (Polymarket-style)
- 02arbitrary off-chain truth claims
- 03KPI options / outcome tokens
- 04cross-chain insurance and bridge security
- 05any data not covered by price oracles
- pnpm add @uma/sdk @uma/contracts-node
- forge install UMAprotocol/protocol
| Variable | Scope | Description |
|---|---|---|
| UMA_OOV3_ADDRESS | Client | OptimisticOracleV3 contract address on the target chain. Look up at docs.uma.xyz/resources/network-addresses. |
| UMA_BOND_CURRENCY | Client | ERC-20 bond/whitelisted currency address on the target chain (commonly USDC). Approve before calling `assertTruth`. |
Use UMA's Optimistic Oracle V3 (OOV3) for off-chain truth claims. Import `OptimisticOracleV3Interface` from `@uma/contracts-node` (or `OptimisticOracleV3CallbackRecipientInterface` if you want callbacks), approve the bond currency, then call `oo.assertTruth(claim, asserter, callbackRecipient, escalationManager, liveness, currency, bond, identifier, domainId)` — `claim` is `bytes` (e.g. ASCII-encoded statement), `liveness` defaults to 7200s if zero. After the dispute window passes with no challenge, anyone calls `oo.settleAssertion(assertionId)` and your contract receives `assertionResolvedCallback(assertionId, true)`. If disputed, UMA tokenholders vote via the DVM (48-96h voting period) and `requestPrice` is invoked under the hood. Read by `oo.getAssertion(assertionId)` for status. For price-style requests use the legacy OOv2 `requestPrice` / `proposePrice` / `settle` flow.
- ⚑UMA is NOT a low-latency price oracle — every assertion must wait the liveness window (default 7200s / 2h, configurable) before it settles; design UX around this delay.
- ⚑Dispute window risk: any actor can dispute by posting an equal bond. If disputed, settlement waits for the full DVM vote (48-96 hours) and the LOSER forfeits their bond — only assert claims you can defend.
- ⚑Bond currency must be on the OOV3 whitelist for that chain AND have a `finalFee` set — assertions with non-whitelisted currencies revert; check `addressWhitelist` and `Store.finalFees`.
- ⚑`identifier` (bytes32) must be in the IdentifierWhitelist (e.g. `ASSERT_TRUTH`) — using a custom identifier without governance approval reverts at assertion time.
- ⚑Network fees and bonds: total cost = bond (refunded if undisputed) + finalFee (always paid to the Store) + gas. Budget for the worst case where you must defend a dispute and post the dispute bond too.
- ⚑Decimal scaling: bonds are in the bond currency's native decimals (USDC = 6, DAI = 18). Hardcoding 18 decimals for USDC is a 1e12 overpayment bug.
- ⚑Callbacks are best-effort — `assertionResolvedCallback` and `assertionDisputedCallback` MUST be `nonReentrant` and gas-bounded; reverts in the callback DO NOT block settlement but leave your protocol out of sync.
- ⚑Cross-chain: OOV3 is deployed per-chain; assertions on Optimism are independent of mainnet — pick the chain matching your collateral and dispute economics.