UMA Optimistic Oracle V3: Integration



UMA Optimistic Oracle V3: Integration
What is UMA
UMA stands for Universal Market Access. It is a protocol that lets smart contracts safely use facts from the real world. Two core parts make this work:
-
Optimistic Oracle (OO)
A system where a person or contract posts a claim and a bond. If nobody disputes the claim during a set time window, the claim is accepted. If there is a dispute, UMA voters decide the truth. -
Data Verification Mechanism (DVM)
The voting and arbitration layer. If a claim is disputed, voters review the claim and the rules, then return a final answer. The losing side pays costs by losing bonds and fees.
Why this matters
With UMA, your smart contract can react to real world events. It can trigger payouts if a price goes up, if a match was won, or if a weather limit was passed.
Simple analogies before we code
-
Assertion
Think of an assertion like pinning a statement on a community board with a kitchen timer beside it. The statement must be true or false. Example: “The daily max temperature in Manhattan NY exceeded 35 C on 2022-07-25 UTC.” You start the timer. -
Bond
The bond is a refundable security deposit. It says “I believe this statement.” If nobody objects before the timer ends, the statement is accepted and the bond returns. If someone proves it wrong, the bond helps cover costs. -
Liveness
Liveness is the length of that timer. While it is ticking, anyone can dispute.
With UMA OO V3 you submit a claim, post a bond in an ERC-20 token, wait through liveness, then settle to get a boolean result that your contract can use.
What we will build
A tiny contract that:
First, stores a clear yes or no claim, second starts an OO V3 assertion after a chosen time,
Third, waits for the liveness window,
and lastly settles and stores YES
or NO
. This will also expose a simple getter for UIs or payout logic.
Minimal V3 contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@uma/core/contracts/optimistic-oracle-v3/interfaces/OptimisticOracleV3Interface.sol";
contract OOv3_GettingStarted {
// UMA V3 oracle and settings
OptimisticOracleV3Interface public immutable oo;
IERC20 public immutable bondCurrency; // ERC20 used for fees and bond, for example WETH or USDC
bytes32 public immutable identifier; // usually bytes32("ASSERT_TRUTH")
uint64 public immutable liveness; // seconds to allow disputes
uint256 public immutable resolutionTime; // when the fact is considered fixed
// Human readable statement (your question phrased as a claim)
string public claimText;
// Optional extra metadata for routing or context
bytes public extraAncillary;
// Assertion lifecycle
bytes32 public assertionId;
enum Outcome { UNRESOLVED, YES, NO }
Outcome public outcome = Outcome.UNRESOLVED;
constructor(
address _oo,
address _bondCurrency,
bytes32 _identifier, // bytes32("ASSERT_TRUTH")
uint64 _liveness, // example: 1800
uint256 _resolutionTime, // unix timestamp when the fact is fixed
string memory _claimText, // statement that is true or false
bytes memory _extraAncillary// optional, can be ""
) {
oo = OptimisticOracleV3Interface(_oo);
bondCurrency = IERC20(_bondCurrency);
identifier = _identifier;
liveness = _liveness;
resolutionTime = _resolutionTime;
claimText = _claimText;
extraAncillary = _extraAncillary;
}
/// Start the assertion after the resolution time.
/// Fund this contract with enough bondCurrency to cover UMA fees and any extra bond.
function startAssertion(uint256 bond) external {
require(block.timestamp >= resolutionTime, "Too early");
require(assertionId == bytes32(0), "Already asserted");
// Approve the oracle to pull fee and bond from this contract
bondCurrency.approve(address(oo), type(uint256).max);
// Convert the human readable claim to bytes
bytes memory claim = bytes(claimText);
assertionId = oo.assertTruth(
claim,
address(this), // asserter
address(0), // no callback in this minimal example
address(0), // no custom escalation manager
liveness,
bondCurrency,
bond, // extra bond (can be 0 for demos)
identifier, // bytes32("ASSERT_TRUTH")
extraAncillary // optional metadata, can be ""
);
}
/// Settle with UMA and store the final outcome.
function finalize() external returns (bool yes) {
require(assertionId != bytes32(0), "No assertion");
require(outcome == Outcome.UNRESOLVED, "Already finalized");
yes = oo.settleAndGetAssertionResult(assertionId);
outcome = yes ? Outcome.YES : Outcome.NO;
}
function getResult() external view returns (string memory) {
if (outcome == Outcome.UNRESOLVED) return "UNRESOLVED";
return outcome == Outcome.YES ? "YES" : "NO";
}
}
What is the question vs ancillary data in V3
-
claim is the actual statement that must be true or false. Example:
The daily max temperature in Manhattan NY exceeded 35 C on 2022-07-25 UTC.
Voters judge this statement. -
extraAncillary is optional machine readable bytes for context or routing. You can leave it empty, or include JSON like bytes that describe the source and method.
-
identifier is usually
bytes32("ASSERT_TRUTH")
for boolean assertions.
Step by step flow
-
Prepare
Deploy the contract with the OO V3 address, ERC-20 bond token, identifier, liveness, resolution time, and claim. -
Fund
Transfer the bond token to this contract. The contract will approve OO to pull fees and the extra bond duringstartAssertion
. -
Assert
AfterresolutionTime
, callstartAssertion(bond)
. UMA records your claim and starts liveness. -
Wait
During liveness, anyone can dispute. If nobody disputes before time runs out, your claim is accepted. -
Settle
Callfinalize()
. UMA returnstrue
orfalse
. The contract storesYES
orNO
. -
Read
CallgetResult()
or readoutcome
. Use it for payouts or UI.
Common pitfalls
- Do not pass native ETH as the bond currency. Use an ERC-20 like WETH or USDC.
- Make the claim precise. Include date, time zone, place, units, and a clear rule.
- Set a realistic liveness so challengers have time to react.
- Fund and approve the bond currency before asserting.
- Use the correct OO V3 address and identifier for your network.
- Store and reuse
assertionId
. You need it for settlement and checks.