# Table of Contents - [Optimistic Oracle v2 | UMA Documentation](#optimistic-oracle-v2-uma-documentation) - [Welcome to UMA | UMA Documentation](#welcome-to-uma-uma-documentation) - [What's New! | UMA Documentation](#what-s-new-uma-documentation) - [Using Blacklisting Tokens as Currency | UMA Documentation](#using-blacklisting-tokens-as-currency-uma-documentation) - [ManagedOptimisticOracleV2 | UMA Documentation](#managedoptimisticoraclev2-uma-documentation) - [Quick Start | UMA Documentation](#quick-start-uma-documentation) - [Deposit Box | UMA Documentation](#deposit-box-uma-documentation) - [Proposing Programmatically | UMA Documentation](#proposing-programmatically-uma-documentation) - [Proposing via the Oracle Dapp | UMA Documentation](#proposing-via-the-oracle-dapp-uma-documentation) - [Event-Based Prediction Market | UMA Documentation](#event-based-prediction-market-uma-documentation) - [Default Proposer Whitelist | UMA Documentation](#default-proposer-whitelist-uma-documentation) - [Insurance Claim Arbitration | UMA Documentation](#insurance-claim-arbitration-uma-documentation) - [ASSERT_TRUTH Deprecation | UMA Documentation](#assert-truth-deprecation-uma-documentation) - [Setting Custom Bond and Liveness Parameters | UMA Documentation](#setting-custom-bond-and-liveness-parameters-uma-documentation) - [Using Blacklisting Tokens as Currency | UMA Documentation](#using-blacklisting-tokens-as-currency-uma-documentation) - [Example Projects | UMA Documentation](#example-projects-uma-documentation) - [Voter Guide | UMA Documentation](#voter-guide-uma-documentation) - [DVM 2.0 FAQ | UMA Documentation](#dvm-2-0-faq-uma-documentation) - [DVM 2.0 | UMA Documentation](#dvm-2-0-uma-documentation) - [Voting Gas Rebates | UMA Documentation](#voting-gas-rebates-uma-documentation) - [Discord Summaries | UMA Documentation](#discord-summaries-uma-documentation) - [DAO Proposals | UMA Documentation](#dao-proposals-uma-documentation) - [How does UMA's Oracle work? | UMA Documentation](#how-does-uma-s-oracle-work-uma-documentation) - [The UMIP Process | UMA Documentation](#the-umip-process-uma-documentation) - [Resolving Disputes | UMA Documentation](#resolving-disputes-uma-documentation) - [Disputing Oracle Data | UMA Documentation](#disputing-oracle-data-uma-documentation) - [Governance | UMA Documentation](#governance-uma-documentation) - [Optimistic Oracle v3 | UMA Documentation](#optimistic-oracle-v3-uma-documentation) - [Quick start | UMA Documentation](#quick-start-uma-documentation) - [Polymarket | UMA Documentation](#polymarket-uma-documentation) - [Proposing Oracle Data | UMA Documentation](#proposing-oracle-data-uma-documentation) - [New Network Requests | UMA Documentation](#new-network-requests-uma-documentation) - [Voting Walkthrough | UMA Documentation](#voting-walkthrough-uma-documentation) - [Unsupported Contracts | UMA Documentation](#unsupported-contracts-uma-documentation) - [Approved Price Identifiers | UMA Documentation](#approved-price-identifiers-uma-documentation) - [Disabling oSnap | UMA Documentation](#disabling-osnap-uma-documentation) - [Glossary | UMA Documentation](#glossary-uma-documentation) - [Sandboxed Oracle Environment | UMA Documentation](#sandboxed-oracle-environment-uma-documentation) - [Additional Resources | UMA Documentation](#additional-resources-uma-documentation) - [Links | UMA Documentation](#links-uma-documentation) - [oSnap | UMA Documentation](#osnap-uma-documentation) - [Across | UMA Documentation](#across-uma-documentation) - [Subgraphs | UMA Documentation](#subgraphs-uma-documentation) - [Approved Collateral Types | UMA Documentation](#approved-collateral-types-uma-documentation) - [Queries | UMA Documentation](#queries-uma-documentation) - [oSnap (Deprecated) | UMA Documentation](#osnap-deprecated-uma-documentation) - [Verification System | UMA Documentation](#verification-system-uma-documentation) - [oSnap Proposal Verification | UMA Documentation](#osnap-proposal-verification-uma-documentation) - [Voting with a 2-Key Contract | UMA Documentation](#voting-with-a-2-key-contract-uma-documentation) - [Audit & Bug Bounty Programs | UMA Documentation](#audit-bug-bounty-programs-uma-documentation) - [Data Asserter | UMA Documentation](#data-asserter-uma-documentation) - [Network Information | UMA Documentation](#network-information-uma-documentation) - [Escalation Managers | UMA Documentation](#escalation-managers-uma-documentation) - [FAQs | UMA Documentation](#faqs-uma-documentation) - [Mainnet Voting Entities | UMA Documentation](#mainnet-voting-entities-uma-documentation) - [Internal Optimistic Oracle | UMA Documentation](#internal-optimistic-oracle-uma-documentation) - [Email Protection | Cloudflare](#email-protection-cloudflare) - [Prediction Market | UMA Documentation](#prediction-market-uma-documentation) - [Insurance | UMA Documentation](#insurance-uma-documentation) --- # Optimistic Oracle v2 | UMA Documentation This section showcases different design patterns for building contracts that integrate with the UMA Optimistic Oracle (OO). These include: * A [simple deposit box](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples) to showcase the basic OO request lifecycle. * An [event based prediction market](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market) . In this example, settlement requests are submitted at the time of contract deployment, and the OO proposer network is used as a decentralized keeper service that identifies when settlement events happen and propose the outcomes. * An ["internal Optimistic Oracle"](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle) , where an integrating contract handles proposals and state management, and only uses the OO when proposal verification is needed or a dispute is filed. [PreviousFAQs](https://docs.uma.xyz/faqs) [NextUsing Blacklisting Tokens as Currency](https://docs.uma.xyz/developers/optimistic-oracle/using-blacklisting-tokens-as-currency) Last updated 7 months ago Was this helpful? Was this helpful? --- # Welcome to UMA | UMA Documentation **An optimistic oracle (OO) that can record any verifiable truth or data onto a blockchain** 🔮 UMA is an optimistic oracle and dispute arbitration system that securely allows for arbitrary types of data to be brought onchain. UMA’s oracle system provides verified onchain data for projects including: 1. Crosschain bridge 2. Prediction markets 3. Insurance protocols 4. Custom derivatives UMA's optimistic oracle (OO) is designed to be modular and extensible with focus on building real-world use cases. Two main versions of the optimistic oracle (OO) are currently live: **OOv2** and **OOv3**. Choosing the right one depends on your use case. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252Fg0jSGPiJNj4pZMB8gvXy%252FFor%2520Kanishk%2520%281%29.png%3Falt%3Dmedia%26token%3D99039816-7b12-422a-8d44-494db8971f8f&width=768&dpr=4&quality=100&sign=7484e589&sv=2) * * * [](https://docs.uma.xyz/#core-concepts) Core Concepts ---------------------------------------------------------- Learn the fundamentals of UMA's optimistic oracle. [](https://docs.uma.xyz/developers/optimistic-oracle) ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F0CYDogTFBqkD3H77SJA9%252FOOv2.png%3Falt%3Dmedia%26token%3D2c6dbb7b-d7a8-4adb-9684-f608babf883b&width=490&dpr=4&quality=100&sign=c9c1dafc&sv=2) **Optimistic Oracle V2** Build prediction markets and insurance protocols [](https://docs.uma.xyz/developers/optimistic-oracle-v3) ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FAPfTZwisLKThEVympit5%252FOOv3.png%3Falt%3Dmedia%26token%3D09c302ad-f7f3-4eac-97be-1de37cdcc70f&width=490&dpr=4&quality=100&sign=ff661f6d&sv=2) **Optimistic Oracle V3** Build data asserters and escalation managers [](https://docs.uma.xyz/using-uma/voting-walkthrough) ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FGyKRFupbgKX7ie1BLi63%252Fvoting.png%3Falt%3Dmedia%26token%3Dbc75344a-b9bd-47e9-9d04-549a42b827f3&width=490&dpr=4&quality=100&sign=fa7d2476&sv=2) **Voting Walkthrough** Learn how to stake tokens, vote, and claim rewards ### [](https://docs.uma.xyz/#correct-oracle-for-your-use-case) Correct Oracle for Your Use Case UMA offers OOv2 and OOv3. Based on your idea and product, let's learn which one fits your use case best: OOv2 OOv3 Integrations must submit data requests that can then be answered by third-party proposers. Integrations submit assertions, where they propose data to their own request along with its parameters. The specific parameters for proposers and disputers to follow must be included in the request. The challenge period and dispute process remains the same. Primary use cases: Prediction markets, sports betting applications, and insurance protocols. Primary use cases: Crosschain infrastructure, content moderation, transaction verification. We understand that your product needs can be complex and would require a larger discussion on which optimistic oracle version to use. Feel free to reach out to us [here](https://docs.uma.xyz/resources/links#links) and get help. * * * [](https://docs.uma.xyz/#developer-quickstart) Developer Quickstart ------------------------------------------------------------------------ Having decided the correct optimistic oracle for your use case, let's now dive deeper into how you can ship apps powered by verifiable onchain truth using UMA's optimistic oracle. OOv2 OOv3 OOv2 prioritizes protocols that need third-parties to propose answers to data requests. Here are some app guides to help you build on UMA OOv2: ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FytPCp9dfZzdlGwOLHizL%252FDev%2520Quickstart%2520-%2520Prediction%2520Markets.png%3Falt%3Dmedia%26token%3D13be8b92-f7ad-4ef5-81b0-916147208880&width=752&dpr=4&quality=100&sign=c6153d57&sv=2) **Prediction Market** Use OOv2 to identify and settle real-world events in prediction markets. ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F2BKwtl5qBU6yLuVtQdpj%252FDev%2520Quickstart%2520-%2520Insurance.png%3Falt%3Dmedia%26token%3D9a61b000-2b69-4708-a31d-147f1601cc0c&width=752&dpr=4&quality=100&sign=eaeeffbd&sv=2) **Insurance** Use OOv2 to verify and resolve claims in insurance applications. OOv3 prioritizes protocols that simply needs asserted data to be verified. Here are some app guides to help you build on UMA OOv3: ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FA6DapiUbGrSkjKKjOXjL%252FDev%2520Quickstart%2520-%2520Data%2520assertion.png%3Falt%3Dmedia%26token%3Dc1f135e3-4cfa-45bd-92c3-a36af1ab9ad7&width=752&dpr=4&quality=100&sign=862d190&sv=2) **Data Asserter** Use OOv3 to asserts arbitrary offchain data onchain through flexible assertions ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FUtveYdM6OOal2qLo3Cbl%252FDev%2520Quickstart%2520-%2520Escalation%2520managers.png%3Falt%3Dmedia%26token%3D6cda6510-8353-4ef1-a89b-d68e42a5ce5a&width=752&dpr=4&quality=100&sign=9cf36c37&sv=2) **Escalation Managers** Use OOv3 to enable modular functionality via custom escalation managers * * * [](https://docs.uma.xyz/#community) Community -------------------------------------------------- The UMA token secures UMA’s optimistic oracle through decentralized governance and economic guarantees against corruption. Token holders vote on upgrades, price requests, and disputes, earning rewards for honest participation. **UMA Improvement Proposals (UMIPs)** are design documents used to propose changes to the UMA ecosystem. They are an important part of UMA's governance processes. The **UMA DAO** accepts proposals for onchain actions that require tokenholders approval. An example would be a request for funding from the UMA treasury. ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FKuBd8cs2aSpIRubuQEBa%252F01UMA%2520governance.png%3Falt%3Dmedia%26token%3Dcd1e3000-688a-4b33-ab02-33bc1ecac181&width=490&dpr=4&quality=100&sign=4f3f9de1&sv=2) **Governance** Learn about UMA token, UMIPs and voting on UMA's DVM ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FtdjBImNfhtSTcxf8lqpv%252F02UMIP%2520process.png%3Falt%3Dmedia%26token%3D7c47970e-c594-4e29-bc47-93149e729d34&width=490&dpr=4&quality=100&sign=8e690e3d&sv=2) **UMIP Process** Learn how UMIPs propose changes to the UMA Ecosystem ![Cover](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FsBwXOxdR3HfyjmlcFg2l%252F03DAO%2520proposal.png%3Falt%3Dmedia%26token%3D3872b6cf-0902-42f3-a9eb-a47a6a9c36df&width=490&dpr=4&quality=100&sign=a9cf7f99&sv=2) **DAO Proposals** Learn how you can submit onchain proposals to the UMA Ecosystem * * * [](https://docs.uma.xyz/#resources-and-support) Resources and Support -------------------------------------------------------------------------- We request all community members and developers to [join our discord server](https://discord.umaproject.org/) and gain instant help on any issues they face while voting or submitting proposals to UMA. You can [find more support resources here](https://docs.uma.xyz/resources/network-addresses) . The security of our protocol is extremely crucial. If you notice any bugs in the protocol, [please report them here](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#submissions) . You can also find details of our [audits here](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs) . [NextWhat's New!](https://docs.uma.xyz/whats-new) Last updated 21 days ago Was this helpful? * [Core Concepts](https://docs.uma.xyz/#core-concepts) * [Correct Oracle for Your Use Case](https://docs.uma.xyz/#correct-oracle-for-your-use-case) * [Developer Quickstart](https://docs.uma.xyz/#developer-quickstart) * [Community](https://docs.uma.xyz/#community) * [Resources and Support](https://docs.uma.xyz/#resources-and-support) Was this helpful? --- # What's New! | UMA Documentation [](https://docs.uma.xyz/whats-new#may-8-2025) May 8, 2025 -------------------------------------------------------------- 1 **Showing Polymarket Clarifications in the Voter dApp** We’ve updated the voter dApp to show Polymarket clarifications right within the dApp to ensure that all UMA voters have access to the same critical information before voting on disputes. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FxC1fAasFFW3xnYx7FEN2%252Fimage.png%3Falt%3Dmedia%26token%3De44ec5f7-efaf-4b8d-8793-994efc45254b&width=768&dpr=4&quality=100&sign=c2ab1bc1&sv=2) 2 **Increased the Settlement Price Approval Threshold (SPAT)** The Settlement Price Approval Threshold (SPAT) is basically the level of agreement needed among voters to resolve a dispute. Before now, the OO used to accept a simple majority (50%+), which meant disputes could be resolved, even on rare occasions when opinions were pretty divided. We’ve now raised SPAT to 65% to strengthen the required consensus for vote outcomes. If we don't hit that threshold, the vote "rolls" to another round, giving everyone time to reconsider and discuss until there’s a stronger community agreement. 3 **Enhanced Voter Information and Warnings** We've added clear warnings and guidance for voters within the dApp to help voters understand that they have a responsibility to verify claims independently. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252Fy966U6eYjyFqcMx20LoI%252Fimage.png%3Falt%3Dmedia%26token%3Daa87f2b0-c1fe-43b8-ac02-bf66c571d2a4&width=768&dpr=4&quality=100&sign=9d66ed7c&sv=2) 4 **Improved Discussion Environment** We've updated how discussions are sorted in the voter dApp; instead of the initial chronological order where the earliest comments are seen first in the discussion pane, users can now sort from the most recent ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F6l1kgsJHVGxqOleu3kPD%252Fimage.png%3Falt%3Dmedia%26token%3Da69a8efc-d535-465e-8722-274117d605b1&width=768&dpr=4&quality=100&sign=6031493f&sv=2) 5 **Fixed PM Market Linking** We've resolved technical issues with links to Polymarket markets, ensuring voters can easily access the associated market information directly from the voter dApp. This provides crucial context about market odds and trading activity. [PreviousWelcome to UMA](https://docs.uma.xyz/) [NextFAQs](https://docs.uma.xyz/faqs) Last updated 7 months ago Was this helpful? Was this helpful? --- # Using Blacklisting Tokens as Currency | UMA Documentation Using a token that allows backlisting (e.g. USDC) as your [requestPrice](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L120) `currency` opens up a griefing vector that integrators should be aware of. The [`proposePriceFor`](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L304) and [`disputePriceFor`](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L382) functions allow the caller to set any address as the `proposer` and `disputer` that will receive payouts if their proposal/dispute is correct upon settlement. If a bad actor calls both [`proposePriceFor`](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L304) and [`disputePriceFor`](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L382) and specifies a blacklisted address for repayment, the [settle](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L498) function will revert and cause the request to be frozen unless the address is unblacklisted. This costs the malicious user 2 bonds and does not result in any gain, but freezing the request could cause issues for the integrator. To avoid this, integrations that use tokens with blacklisting functionality should ensure that their admins can call a function that ignores the frozen request and creates a new OOV2 request. In this way they can prevent a frozen request from having any negative consequences to their protocol. [PreviousOptimistic Oracle v2](https://docs.uma.xyz/developers/optimistic-oracle) [NextQuick Start](https://docs.uma.xyz/developers/optimistic-oracle/getting-started) Last updated 3 months ago Was this helpful? Was this helpful? --- # ManagedOptimisticOracleV2 | UMA Documentation The [ManagedOptimisticOracleV2](https://github.com/UMAprotocol/managed-oracle/blob/master/src/optimistic-oracle-v2/implementation/ManagedOptimisticOracleV2.sol) contract is modified version of the OptimisticOracleV2 intended to be deployed for a single integration. It allows the integration to designate a request manager address that can set a default proposer whitelist and easily manage an existing request's bond size, liveness and proposer whitelist before the request has been proposed. [PreviousInsurance Claim Arbitration](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration) [NextProposing via the Oracle Dapp](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-via-the-oracle-dapp) Last updated 5 months ago Was this helpful? Was this helpful? --- # Quick Start | UMA Documentation The primary integration point into the UMA ecosystem is the Optimistic Oracle (OO). The OO is an _**oracle for arbitrary off-chain data**_ which leverages an interactive escalation game between _requesters_, _proposers_ and _disputers_ and is secured by _economic incentives_. This getting started tutorial will show you how to go from 0 to 1 with the Optimistic Oracle by executing the simplest possible request flow. Later in the docs you can find more information on [how the Optimistic Oracle works](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#optimistic-oracle) and dig deeper into its mechanism and [more sophisticated code examples](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market) . **If you prefer, you can also watch the following video tutorial in which we follow the step-by-step instructions described below. Please note, the Optimistic Oracle now supports Sepolia testnet.** ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#a-minimum-viable-optimistic-oracle-integration) **A minimum viable Optimistic Oracle integration** You will be working through a simple smart contract that asks the oracle the question: `Q:Did the temperature on the 25th of July 2022 in Manhattan NY exceed 35c? A:1 for yes. 0 for no.` After submitting the request, you will propose a solution using the UMA Optimistic Oracle UI. Once through liveness, you will fetch the price from the smart contract. This shows the full lifecycle of an Optimistic Oracle data request on the Sepolia testnet, interacting with an actual Optimistic Oracle contract deployment, without needing to write any code or clone any repos. It should give you the basic intuition as to how the Optimistic Oracle works without too much overhead and is a great starting point before digging deeper. Let's get started! ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#prerequisites) **Prerequisites** To complete this tutorial you will need**:** 1. Metamask installed in a Chromium based browser (such as [Google Chrome](https://www.google.com/chrome/) ) If you don't have it already, you can get Metamask [here](https://metamask.io/) . 2. A wallet set up in Metamask. 3. [Sepolia](https://sepolia.dev/) test ETH to send test transactions. You can get Sepolia ETH from one of these faucets: [Infura](https://www.infura.io/faucet/sepolia) , [Alchemy,](https://www.alchemy.com/faucets/ethereum-sepolia) [PoW Faucet](https://sepolia-faucet.pk910.de/) , or [LearnWeb3](https://learnweb3.io/faucets/sepolia/) , ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#requesting-data) Requesting data First, we will work through the basic flow for _asking the oracle for a piece of data_. In this example, we are asking the Oracle for information on the weather but the request could be much more complex to could power any kind of smart contract system requiring data. See [approved price identifies](https://docs.uma.xyz/resources/approved-price-identifiers) and the sample projects for more inspiration on what is possible with the OO. The contract used in this tutorial is meant to be a simple data request flow. The contract exposes a simple `requestData` function which asks the OO a simple question about the weather. 1. [Go to this example contract on Remix](https://remix.ethereum.org/#version=soljson-v0.8.16+commit.07a7930e.js&optimize=false&runs=200&gist=fba5d2812d940759f4f7585741b529a4) . This gives you the minimum data request and retrieval flow possible. We'll work through the code in the sections that follow. 2. Click on "gist-fba..." to see the files in the gist, and click `OO_GettingStarted.sol` to open to Solidity file. 3. In the far left hand menu, click the link to deploy and run transactions (which looks like the Ethereum logo and a right arrow). 4. In the "Environment" dropdown, choose "Injected Provider," and connect to your wallet. **Make sure you are connected to Sepolia within your Metamask wallet!** You don't want to deploy to a real network and spend real gas, and the Sepolia Optimistic Oracle address hardcoded into the contract will not work on other networks. 5. Under the "Contract" dropdown, select `OO_GettingStarted`. 6. Click "Deploy" and confirm the transaction with your wallet. 7. You should now see the `OO_GettingStarted` contract under "Deployed Contracts". Clicking the dropdown carrot will reveal buttons for each of the functions in the contract. 8. Click `requestData` to request the data specified in the contract's ancillary data, asking about the temperature in Manhattan on July 25th, 2022. Confirm the transaction in your wallet. This will submit a data request to the Optimistic Oracle. What we've done in the above steps is: a) deploy a smart contract and b) submit a "price request" to the Optimistic oracle through the call to the Optimistic Oracle's `requestPrice` function. ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#proposing-data) Proposing data Now that we've asked the OO a question, it's time to propose a solution! The Optimistic Oracle works via an _interactive escalation game_ wherein a) requesters ask questions b) proposers provide solutions and c) disputers monitor the proposals and dispute if they are invalid. If no dispute is done then the proposal is taken as valid. In this example, we'll be acting as the proposer who will be answering the question we asked in the previous section 1. Go to the Sepolia [Optimistic Oracle UI](https://testnet.oracle.umaproject.org/) to see your request, which should be a `YES_OR_NO_QUERY` at the top of the index page. Click on the request to go to the details page. 2. Click "Connect Wallet" and make sure you are connected to the Sepolia testnet so that you can make a proposal. You should see all the information posed in the data request: the requester, identifier, timestamp, ancillary data and a link to the UMIP. 3. Submit your proposal (either `1` or `0`). The actual value you submit is not super important in this case since this is just for testing purposes, but the [correct response](https://www.wunderground.com/history/daily/us/ny/williston-park/KJFK/date/2022-7-25) is `0`. In doing this we are acting as the "proposer" providing a solution. Once you've provided an answer to the question the proposal enters into a liveness period of 30 seconds. During this time it's up to Disputers to verify the correctness of what the proposer provided. Note that in a main net price request you'll normally set the liveness to much longer than 30 seconds (say two hours), the proposer will be bonded (if they propose wrong they lose money) and the proposer will be rewarded for providing a valid answer to the question. ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#settling-the-final-answer) Settling the final answer Finally, we can fetch the data proposed in the previous step from the smart contract. For this example, we assume that there the proposed data was correct (was not disputed). Head back to your Remix tab and: 1. After the transaction finalizes, wait 30 seconds (the challenge window) and then click `settleRequest` on the `OO_GettingStarted` contract on Remix. Confirm the transaction in your wallet. Because the proposal was not disputed within the challenge window, it can now be settled. 2. Click `getSettledPrice` to get the settled value. It should look like `int256: 0` under `getSettledPrice` if you proposed an answer of `0`. You can also see details in the console logs. Congratulations! you've successfully integrated with the Optimistic Oracle, requested data, proposed data and fetched it within your smart contract! Note that the incentives in this toy example mean that there is no reason that anyone would provide the _correct_ price (there was no reward for the proposers or disputes and there was no bond). A real world version of this should [leverage custom bonds and more realistic liveness parameters](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters) . ### [](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#next-steps) Next Steps Hopefully you got a basic understanding of the OO request flow from this getting started guide. Check out some of the [example tutorials](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples) where we walk through more details on the functions discussed in this guide. [PreviousUsing Blacklisting Tokens as Currency](https://docs.uma.xyz/developers/optimistic-oracle/using-blacklisting-tokens-as-currency) [NextDeposit Box](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples) Last updated 1 year ago Was this helpful? * [A minimum viable Optimistic Oracle integration](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#a-minimum-viable-optimistic-oracle-integration) * [Prerequisites](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#prerequisites) * [Requesting data](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#requesting-data) * [Proposing data](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#proposing-data) * [Settling the final answer](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#settling-the-final-answer) * [Next Steps](https://docs.uma.xyz/developers/optimistic-oracle/getting-started#next-steps) Was this helpful? --- # Deposit Box | UMA Documentation #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#uma-contract-lifecycle) UMA Contract Lifecycle UMA's Optimistic Oracle allows contracts to quickly request and receive price information. A request is made when a contract submits the following parameters with a request to the Optimistic Oracle contract: * **identifier:** price identifier being requested. * **timestamp:** timestamp of the price being requested. * **ancillaryData:** additional arguments passed with the price request. * **currency:** ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * **reward:** reward offered to a successful proposer. Will be paid by the caller. Note: this can be 0. Proposers respond to price requests by referencing off-chain price feeds to submit the price of an asset. In return for their work they will receive a pre-defined proposal reward set by the Requestor. To propose prices, the Proposer is required to stake a proposal bond. In the event that the price information they proposed is disputed and deemed incorrect, the Proposer will lose their bond. Disputers can refute a price submitted by a Proposer within the proposal liveness period by referencing their own off-chain price feeds. The proposal liveness period is a pre-defined amount of time a proposal can be disputed before the Requestor receives the price of the asset. If Disputers do not refute the price submitted by the Proposer within the proposal liveness period, the price is sent to the Requestor. If a proposal is disputed, the price will be submitted to UMA’s DVM and resolved after a 48-96 hour voting period. #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#integrating-with-the-optimistic-oracle) Integrating with the Optimistic Oracle We continue to use the [OptimisticDepositBox](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/OptimisticDepositBox.sol) contract as an example. The OptimisticDepositBox is a minimal financial contract that allows a user to deposit collateral into a contract and later withdraw their collateral corresponding to a desired USD amount. When the user wants to make a withdrawal, a price request is made to the Optimistic Oracle. Let's first take a look at the OptimisticDepositBox constructor. Optimistic Oracle price requests require the use of a whitelisted identifier and collateral. The OptimisticDepositBox uses the protocol Finder to discover UMA protocol contracts and call the `isOnWhitelist` method on the `AddressWhitelist` and the `isIdentifierSupported` method on the `IdentifierWhitelist` contract to confirm both are whitelisted before deployment. Copy constructor( address _collateralAddress, address _finderAddress, bytes32 _priceIdentifier, address _timerAddress ) nonReentrant() Testable(_timerAddress) { finder = FinderInterface(_finderAddress); require(_getIdentifierWhitelist().isIdentifierSupported(_priceIdentifier), "Unsupported price identifier"); require(_getAddressWhitelist().isOnWhitelist(_collateralAddress), "Unsupported collateral type"); collateralCurrency = IERC20(_collateralAddress); priceIdentifier = _priceIdentifier; } ... function _getIdentifierWhitelist() internal view returns (IdentifierWhitelistInterface) { return IdentifierWhitelistInterface(finder.getImplementationAddress(OracleInterfaces.IdentifierWhitelist)); } function _getAddressWhitelist() internal view returns (AddressWhitelist) { return AddressWhitelist(finder.getImplementationAddress(OracleInterfaces.CollateralWhitelist)); } Example arguments used to deploy the contract can be found and tested in the [OptimisticDepositBox fixture](https://github.com/UMAprotocol/dev-quickstart/blob/main/test/fixtures/OptimisticDepositBox.Fixture.ts) . A whitelisted USDC contract is used for collateral, the Finder and Timer addresses use existing UMA ecosystem contracts that are deployed, and a price identifier that has been [whitelisted with the IdentifierWhitelist](https://github.com/UMAprotocol/dev-quickstart/blob/main/test/fixtures/UmaEcosystem.Fixture.ts#L29) contract. #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#requesting-a-price) Requesting a Price A price request is made when the `requestWithdrawal` [method](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/OptimisticDepositBox.sol#L162) is called. A depositor submits the `denominatedCollateralAmount` to withdrawal and a `requestPrice` call is constructed with the following arguments [shown above](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#requesting-a-price) and in the [requestPrice interface](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/interfaces/OptimisticOracleV2Interface.sol#L111) : After price request functionality has been implemented into your contracts, you can test your changes by creating a test in the developer quickstart repo similar to the OptimisticDepositBox test below: #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#price-proposals) Price Proposals The code snippets above represent the core functionality for deploying a minimal contract and requesting a price. The next step in the contract lifecycle after a request has been made is a price can be proposed. [Here](https://github.com/UMAprotocol/protocol/blob/b0558f37a5ce240a08d694ebd40f9ed327c897ed/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L304) is the `proposePriceFor` function from the Optimistic Oracle contract that is used to propose a price for requests. The price proposal will revert if the parameters do not match an existing price request. For reference, the [developer quickstart repo](https://github.com/UMAprotocol/dev-quickstart/blob/0c46e1fcdeb0a2543fa3ea0dbeebcfe2da072632/test/OptimisticDepositBox/OptimisticDepositBox.Proposal.ts#L26) demonstrates how to call the `proposePriceFor` method. #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#liveness) Liveness An important aspect to consider when using the Optimistic Oracle is the liveness period which is the number of seconds a proposal must wait before a price can be resolved and contracts can be settled. A `defaultLiveness` value is set (currently 7,200) or developers can set a customLiveness value. To set a `customLiveness` value with our OptimisticDepositBox example above, we could add line 5 to change the liveness period from 7,200 seconds to 3,600: #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#proposal-bond) Proposal Bond A proposal bond is a preloaded reward to incentivize price proposals. Similar to the liveness period, a custom bond amount can be set for a price request. Two important aspects to remember when setting a proposal bond is: * When making a price request, the caller must approve the contract to transfer the value of the proposer reward for the collateral being used. * The value corresponds to the collateral decimal value. So setting the reward to 1 for USDC that uses 6 decimals would be 1000000 while an 18 decimal token would be 1. The below shows an example of setting the proposer bond to 50 USDC (6 decimals): #### [](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples#settlement) Settlement The OptimisticDepositBox contract uses the `executeWithdrawal` method to settle contracts. It first checks if a price has been resolved by calling the `hasPrice` method on the Optimistic Oracle which reverts if the request is not settled or settleable. If a price has been resolved, `settleAndGetPrice` is called. [PreviousQuick Start](https://docs.uma.xyz/developers/optimistic-oracle/getting-started) [NextEvent-Based Prediction Market](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market) Last updated 1 year ago Was this helpful? Was this helpful? Copy // Deploy the OptimisticDepositBox contract. const optimisticDepositBox = await ( await getContractFactory("OptimisticDepositBox", deployer) ).deploy(usdc.address, parentFixture.finder.address, identifier, parentFixture.timer.address); Copy function requestWithdrawal(uint256 denominatedCollateralAmount) public noPendingWithdrawal(msg.sender) nonReentrant { OptimisticDepositBoxData storage depositBoxData = depositBoxes[msg.sender]; require(denominatedCollateralAmount > 0, "Invalid collateral amount"); // Update the position data for the user. depositBoxData.withdrawalRequestAmount = denominatedCollateralAmount; depositBoxData.withdrawalRequestTimestamp = getCurrentTime(); emit RequestWithdrawal(msg.sender, denominatedCollateralAmount, depositBoxData.withdrawalRequestTimestamp); // A price request is sent for the current timestamp. _requestOraclePrice(depositBoxData.withdrawalRequestTimestamp); } ..... // Requests a price for `priceIdentifier` at `requestedTime` from the Optimistic Oracle. function _requestOraclePrice(uint256 requestedTime) internal { OptimisticOracleInterface oracle = _getOptimisticOracle(); // For other use cases, you may need ancillary data or a reward. Here, they are both zero. oracle.requestPrice(priceIdentifier, requestedTime, "", IERC20(collateralCurrency), 0); } Copy await expect(optimisticeDepositBox.connect(depositor).requestWithdrawal(amountToWithdraw)) .to.emit(optimisticDepositBox, "RequestWithdrawal") .withArgs(depositor.address, amountToWithdraw, requestTimestamp); Copy request.expirationTime = getCurrentTime().add( request.customLiveness != 0 ? request.customLiveness : defaultLiveness ); Copy function _requestOraclePrice(uint256 requestedTime) internal { OptimisticOracleInterface oracle = _getOptimisticOracle(); // For other use cases, you may need ancillary data or a reward. Here, they are both zero. oracle.requestPrice(priceIdentifier, requestedTime, "", IERC20(collateralCurrency), 0); oracle.setCustomLiveness(priceIdentifier, requestedTime, "", 3600); } Copy function _requestOraclePrice(uint256 requestedTime) internal { OptimisticOracleInterface oracle = _getOptimisticOracle(); // For other use cases, you may need ancillary data. Here, the ancillary data is set to zero. oracle.requestPrice(priceIdentifier, requestedTime, "", IERC20(collateralCurrency), 0); oracle.setBond(priceIdentifier, requestedTime, "", 50000000); } Copy function _getOraclePrice(uint256 withdrawalRequestTimestamp) internal returns (uint256) { OptimisticOracleInterface oracle = _getOptimisticOracle(); require( oracle.hasPrice(address(this), priceIdentifier, withdrawalRequestTimestamp, ""), "Unresolved oracle price" ); int256 oraclePrice = oracle.settleAndGetPrice(priceIdentifier, withdrawalRequestTimestamp, ""); // For simplicity we don't want to deal with negative prices. if (oraclePrice < 0) { oraclePrice = 0; } return uint256(oraclePrice); } --- # Proposing Programmatically | UMA Documentation Proposing and disputing ManagedOptimisticOracleV2 requests is largely the same as OptimisticOracleV2 requests with the following differences: #### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically#adding-the-managedoptimisticoraclev2-addresses) Adding the ManagedOptimisticOracleV2 Addresses Programmatic proposers and disputers will be used to listening for OptimisticOracleV2 events and sending proposing and disputing transactions to these addresses. To add support to new ManagedOptimisticOracleV2 deployments, programmatic proposers and disputers will have to add these new deployment addresses to their bot configs. Note: the first ManagedOptimisticOracleV2 deployment is managed by Polymarket and can be found [here](https://polygonscan.com/address/0x2C0367a9DB231dDeBd88a94b4f6461a6e47C58B1) . #### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically#viewing-a-requests-proposer-whitelist) Viewing a Request's Proposer Whitelist ManagedOptimisticOracleV2 requests have defined proposer whitelists. The whitelist for a given request can be found by calling the [`getProposerWhitelistWithEnforcementStatus`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/optimistic-oracle-v2/implementation/ManagedOptimisticOracleV2.sol#L381C14-L381C55) function with the request's `requester` , `identifier` , and `ancillaryData`. The function will return an `isEnforced` boolean that defines whether a whitelist is enforced and an address array of `allowedProposers` . If `isEnforced` is true, then only `allowedProposers` may propose the request. If `isEnforced` is false, any address will be able to propose. When a new request is created on ManagedOptimisticOracleV2 it will default to the `defaultProposerWhitelist` unless overridden by the `requestManager` . This default whitelist can be viewed with the following steps: 1. Call the [`defaultProposerWhitelist`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/optimistic-oracle-v2/implementation/ManagedOptimisticOracleV2.sol#L94) view function on a deployed ManagedOptimisticOracleV2 contract to get the address of the default whitelist. 2. Call [`getWhitelist`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/common/implementation/AddressWhitelist.sol#L79) on the default whitelist address to view all address on the whitelist. Alternatively, call [`isOnWhitelist`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/common/implementation/AddressWhitelist.sol#L67) to check if a given address is on the whitelist. #### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically#proposing-on-managedoptimisticoraclev2) Proposing on ManagedOptimisticOracleV2 Proposing on ManagedOptimisticOracleV2 can be done by calling the same [`proposePrice`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L382) or [`proposePriceFor`](https://github.com/UMAprotocol/managed-oracle/blob/fc03083eca91c880efa8918c6d9532af9362f00d/src/optimistic-oracle-v2/implementation/ManagedOptimisticOracleV2.sol#L327) functions with the same arguments as proposing on OptimisticOracleV2. Proposal transactions from addresses that are not whitelisted will revert with the following error messages, `"Sender not whitelisted"` or, `"Proposer not whitelisted"`. #### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically#listening-for-managedoptimisticoraclev2-events) Listening for ManagedOptimisticOracleV2 Events The emitted events that are relevant to oracle participants (`RequestPrice, ProposePrice and DisputePrice, SettlePrice`) are unchanged from the OptimisticOracleV2 contract. These events can be queried via RPCs or by using our [subgraph](https://github.com/UMAprotocol/subgraphs/blob/master/README.md#managed-optimistic-oracle-v2-events-and-calls) that indexes ManagedOptimisticOracleV2 events. [PreviousProposing via the Oracle Dapp](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-via-the-oracle-dapp) [NextDefault Proposer Whitelist](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist) Last updated 4 months ago Was this helpful? Was this helpful? --- # Proposing via the Oracle Dapp | UMA Documentation Viewing, proposing and disputing ManagedOptimisticOracleV2 requests on the Oracle Dapp is the same as other OptimisticOracleV2 requests except for the following differences: * If your connected address is not on the request's proposer whitelist, the propose button on the request's sidebar will be disabled. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F08Ov9s8qVQ62VXkxBxcN%252Fimage.png%3Falt%3Dmedia%26token%3Df834ed25-8c48-43a3-8967-c71b1b82f7c2&width=768&dpr=4&quality=100&sign=15574485&sv=2) * The request's proposer whitelist is displayed under the "More Information" heading at the bottom of the request sidebar. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F8X0Ka6eF45lM9Yk02zul%252Fimage.png%3Falt%3Dmedia%26token%3D3c5359c2-0180-403d-a17d-3c237af37b24&width=768&dpr=4&quality=100&sign=94617e59&sv=2) * ManagedOptimisticOracleV2 requests are tagged "Managed Optimistic Oracle V2" on the Oracle Dapp. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FeBGDi4jCAZld51fUzah7%252Fimage.png%3Falt%3Dmedia%26token%3D0952a42c-cb63-4caf-89ce-2b863898b943&width=768&dpr=4&quality=100&sign=e2cc0c26&sv=2) [PreviousManagedOptimisticOracleV2](https://docs.uma.xyz/developers/managedoptimisticoraclev2) [NextProposing Programmatically](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically) Last updated 5 months ago Was this helpful? Was this helpful? --- # Event-Based Prediction Market | UMA Documentation In this section, we'll talk about the [Event Based Prediction market contract](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/EventBasedPredictionMarket.sol) , which you can find in the [developer's quick-start repo](https://github.com/UMAprotocol/dev-quickstart) . This tutorial will show how event-based OO data requests can be used in a binary prediction market. You will find out how this smart contract works and how to test it and deploy it. Refer to the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) contract for additional information on the event-based price requests. ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#the-event-based-prediction-market) The Event-Based Prediction Market This smart contract lets you set up prediction markets that are based on an event-based price request. For example, you could ask a question like, "Will BTC be over $1M when the first Moon hotel opens?" _(Note: Although these are called "price" requests in the code, you can request any kind of data from the optimistic oracle. If it's helpful, you can mentally replace "price" with "data" when you see it in the code and documentation.)_ In addition, an event-based price request cannot expire early and automatically returns the requester's reward in the event of a dispute. By participating in the contract, users are issued long and short position tokens, which, when held, provide exposure to the prediction market. This contract's logic is a streamlined version of the [LongShortPair](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/financial-templates/long-short-pair/LongShortPair.sol) with an event-based pricing request. ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#development-environment-and-tests) Development environment and tests #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#clone-the-dev-quickstart-repo) Clone the dev-quickstart repo Copy git clone [email protected]:UMAprotocol/dev-quickstart.git cd dev-quickstart To install dependencies, you will need to install the long-term support version of nodejs, currently nodejs v16, and yarn. You can then install dependencies by running yarn with no arguments: Copy yarn #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#compiling-your-contracts) Compiling your contracts We will need to run the following command to compile the contracts and make the typescript interfaces so that they are easy to work with: Copy yarn hardhat compile ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#contract-design) Contract design #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#contract-creation-and-initialization) Contract creation and initialization The contract is created by setting up the prediction market with a series of parameters. With the parameters, you can choose what kind of collateral you want to use with `_collateralToken`. With `_pairName`, we can choose a name for the pair of long and short tokens. `_customAncillaryData` is where we define the price request question. The addresses of the `_finder` and `_timerAddress` set the rest of the contracts addresses we interact with. For reference, [here](https://github.com/UMAprotocol/protocol/tree/master/packages/core/networks) is the full list of UMA contract deployments. Once the contract has been deployed, the owner can call `initializeMarket()` after approving the `proposerReward` amount to be paid to the wallet that resolves the price request. To keep things simple, `proposerReward` is set to `10e18.` Also observe how `priceIdentifier` is set to `"YES_OR_NO_QUERY"`. This function sets up the prediction market by getting the proposer reward and calling `_requestOraclePrice`. This last function starts the price request in [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) and sets up a number of options that are explained below. `_requestOraclePrice` is in charge of initializing the price request in the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) by performing the following actions: 1. Create the price request with the above-mentioned parameters. 2. Define the custom liveness period that a proposed oracle response must sit through before being accepted as truth. 3. Specify the bond that the proposer and disputer must post in order to resolve a request. 4. Set the type of request to Event Based. 5. Turn on the `priceSettled` and `priceDisputed` callbacks so that our contract can use OO callbacks to respond to these kinds of events #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#long-and-short-tokens-creation-and-redemption) Long and Short tokens creation and redemption Any user can now call the `create` function with the `tokensToCreate` parameter to mint the same number of short and long tokens. Having both tokens in the same proportion means being in a neutral position, as is the case when calling `create`. Holding only long tokens (by transferring short tokens to another wallet or adding liquidity to an AMM pair), gives exposure to the long position and vice versa. At any time a token holder with both tokens in the same proportion can exchange them for collateral with \`redeem\`. Any long-short token holder can settle tokens for collateral with `settle` if the oracle has processed the price request. The returned collateral amount is a function of `longTokensToRedeem`, `shortTokensToRedeem`, and `settlementPrice`. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#price-request-lifecycle-callbacks-pricesettled-and-pricedisputed) Price request lifecycle callbacks: priceSettled and priceDisputed When the price request we set up above is settled in the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) , the `priceSettled` function of this contract is invoked. This function calculates and stores settlementPrice as `0`, `0.5`, or `1`. This number is used in the `settle` function to calculate the collateral to pay in exchange for long tokens and short tokens. In the same way, this contract's `priceDisputed` function is called when a price request is disputed. This function re-starts the same price request with the bond amount that was given back to the requester, which in our case is the `EventBasedPredictionMarket`. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#tests) Tests To execute the EventBasedPredictionMarket tests, run: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#deployment) Deployment Before deploying the contract check/edit the default arguments defined in [the deployment script](https://github.com/UMAprotocol/dev-quickstart/blob/main/deploy/002_deploy_event_based_prediction_market.ts) . To deploy `EventBasedPredictionMarket` in Görli network, run: Optionally, you can verify the deployed contract on Etherscan: [PreviousDeposit Box](https://docs.uma.xyz/developers/optimistic-oracle/solidity-examples) [NextInsurance Claim Arbitration](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration) Last updated 7 months ago Was this helpful? * [The Event-Based Prediction Market](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#the-event-based-prediction-market) * [Development environment and tests](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#development-environment-and-tests) * [Contract design](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market#contract-design) Was this helpful? Copy constructor( string memory _pairName, ExpandedERC20 _collateralToken, bytes memory _customAncillaryData, FinderInterface _finder, address _timerAddress ) ... Copy function _requestOraclePrice() internal { OptimisticOracleV2Interface optimisticOracle = getOptimisticOracle(); collateralToken.safeApprove(address(optimisticOracle), proposerReward); optimisticOracle.requestPrice( priceIdentifier, requestTimestamp, customAncillaryData, collateralToken, proposerReward ); // Set the Optimistic oracle liveness for the price request. optimisticOracle.setCustomLiveness( priceIdentifier, requestTimestamp, customAncillaryData, optimisticOracleLivenessTime ); // Set the Optimistic oracle proposer bond for the price request. optimisticOracle.setBond(priceIdentifier, requestTimestamp, customAncillaryData, optimisticOracleProposerBond); // Make the request an event-based request. optimisticOracle.setEventBased(priceIdentifier, requestTimestamp, customAncillaryData); // Enable the priceDisputed and priceSettled callback optimisticOracle.setCallbacks(priceIdentifier, requestTimestamp, customAncillaryData, false, true, true); priceRequested = true; } Copy function create(uint256 tokensToCreate) public requestInitialized { collateralToken.safeTransferFrom(msg.sender, address(this), tokensToCreate); require(longToken.mint(msg.sender, tokensToCreate)); require(shortToken.mint(msg.sender, tokensToCreate)); emit TokensCreated(msg.sender, tokensToCreate, tokensToCreate); } Copy function redeem(uint256 tokensToRedeem) public { require(longToken.burnFrom(msg.sender, tokensToRedeem)); require(shortToken.burnFrom(msg.sender, tokensToRedeem)); collateralToken.safeTransfer(msg.sender, tokensToRedeem); emit TokensRedeemed(msg.sender, tokensToRedeem, tokensToRedeem); } Copy function settle(uint256 longTokensToRedeem, uint256 shortTokensToRedeem) public returns (uint256 collateralReturned) { require(receivedSettlementPrice, "price not yet resolved"); require(longToken.burnFrom(msg.sender, longTokensToRedeem)); require(shortToken.burnFrom(msg.sender, shortTokensToRedeem)); // settlementPrice is a number between 0 and 1e18. 0 means all collateral goes to short tokens and 1e18 means // all collateral goes to the long token. Total collateral returned is the sum of payouts. uint256 longCollateralRedeemed = (longTokensToRedeem * settlementPrice) / (1e18); uint256 shortCollateralRedeemed = (shortTokensToRedeem * (1e18 - settlementPrice)) / (1e18); collateralReturned = longCollateralRedeemed + shortCollateralRedeemed; collateralToken.safeTransfer(msg.sender, collateralReturned); emit PositionSettled(msg.sender, collateralReturned, longTokensToRedeem, shortTokensToRedeem); } Copy function priceSettled( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, int256 price ) external { OptimisticOracleV2Interface optimisticOracle = getOptimisticOracle(); require(msg.sender == address(optimisticOracle), "not authorized"); require(identifier == priceIdentifier, "same identifier"); require(keccak256(ancillaryData) == keccak256(customAncillaryData), "same ancillary data"); // We only want to process the price if it is for the current price request. if (timestamp != requestTimestamp) return; // Calculate the value of settlementPrice using either 0, 0.5e18, or 1e18 as the expiryPrice. if (price >= 1e18) { settlementPrice = 1e18; } else if (price == 5e17) { settlementPrice = 5e17; } else { settlementPrice = 0; } receivedSettlementPrice = true; } Copy function priceDisputed( bytes32 identifier, uint256 timestamp, bytes memory ancillaryData, uint256 refund ) external { OptimisticOracleV2Interface optimisticOracle = getOptimisticOracle(); require(msg.sender == address(optimisticOracle), "not authorized"); requestTimestamp = getCurrentTime(); require(timestamp <= requestTimestamp, "different timestamps"); require(identifier == priceIdentifier, "same identifier"); require(keccak256(ancillaryData) == keccak256(customAncillaryData), "same ancillary data"); require(refund == proposerReward, "same proposerReward amount"); _requestOraclePrice(); } Copy yarn test test/EventBasedPredictionMarket/* Copy NODE_URL_5=YOUR_GOERLI_NODE MNEMONIC=YOUR_MNEMONIC yarn hardhat deploy --network goerli --tags EventBasedPredictionMarket Copy ETHERSCAN_API_KEY=YOUR_API_KEY yarn hardhat etherscan-verify --network goerli --license AGPL-3.0 --force-license --solc-input --- # Default Proposer Whitelist | UMA Documentation Risk Labs manages the default proposer whitelist for Polymarket's ManagedOptimisticOracleV2 contract. The current whitelist can be viewed [here](https://polygonscan.com/address/0x9f35885ce8f67a942d7b2f4fbf937987da08c463#readContract#F1) and is subject to updates and changes in guidelines. Polymarket, as the request manager for the contract, may also change an unproposed request’s proposer whitelist at any time. ### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#current-proposer-whitelist-criteria) Current Proposer Whitelist Criteria Proposer addresses must meet the two below criteria over the last 6 months: * 5 or more Polymarket proposals on OptimisticOracleV2 or ManagedOptimisticOracleV2 * Proposal accuracy greater than 95% in the last 6 months. ### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#how-do-i-get-on-the-whitelist) How do I get on the whitelist? Propose [OOV2 Polymarket requests](https://oracle.uma.xyz/propose?oracleType=Optimistic+Oracle+V2&project=Polymarket) that are not whitelisted to meet the criteria for the next update. ### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#when-will-the-whitelist-be-updated) When will the whitelist be updated? Updates are based on data pulled on the 2nd of each month for the preceding 6 months (e.g. June 2nd to December 2nd). The whitelist is updated within the following week. ### [](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#are-address-removed-from-the-whitelist) Are address removed from the whitelist? Yes, if a whitelisted address no longer meets the criteria of the most recent update it will be removed from the whitelist. [PreviousProposing Programmatically](https://docs.uma.xyz/developers/managedoptimisticoraclev2/proposing-programmatically) [NextOptimistic Oracle v3](https://docs.uma.xyz/developers/optimistic-oracle-v3) Last updated 1 month ago Was this helpful? * [Current Proposer Whitelist Criteria](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#current-proposer-whitelist-criteria) * [How do I get on the whitelist?](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#how-do-i-get-on-the-whitelist) * [When will the whitelist be updated?](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#when-will-the-whitelist-be-updated) * [Are address removed from the whitelist?](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist#are-address-removed-from-the-whitelist) Was this helpful? --- # Insurance Claim Arbitration | UMA Documentation This section covers the [insurance claims arbitration contract](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/InsuranceArbitrator.sol) , which is available in the [developer's quick-start repo](https://github.com/UMAprotocol/dev-quickstart) . This tutorial shows an example of how insurance claims can be resolved and settled through the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) contract. You will find out how to test and deploy this smart contract and how it integrates with the Optimistic Oracle. ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#insurance-arbitrator-contract) Insurance Arbitrator Contract This smart contract allows insurers to issue insurance policies by depositing the insured amount, designating the insured beneficiary, and describing the insured event. Anyone can submit a claim that the insured event has occurred at any time. Insurance Arbitrators resolve the claim through the Optimistic Oracle by passing a question with a description of the insured event in ancillary data using the `YES_OR_NO_QUERY` price identifier specified in [UMIP-107](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-107.md) . If the claim is confirmed and settled through the Optimistic Oracle, this contract automatically pays out insurance coverage to the beneficiary. If the claim is rejected, the policy continues to be active and ready for subsequent claim attempts. ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#development-environment-and-tests) Development environment and tests #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#clone-repository-and-install-dependencies) Clone repository and Install dependencies Clone the UMA dev-quickstart repository and install the dependencies. To install dependencies, you will need to install the long-term support version of nodejs, currently Nodejs v16, and yarn. You can then install dependencies by running yarn with no arguments: Copy git clone [email protected]:UMAprotocol/dev-quickstart.git cd dev-quickstart yarn #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#compiling-your-contracts) Compiling your contracts We will need to run the following command to compile the contracts and make the Typescript interfaces so that they are easy to work with: Copy yarn hardhat compile ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#contract-implementation) Contract implementation The contract discussed in this tutorial can be found at `dev-quickstart/contracts/InsuranceArbitrator.sol` ([here](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/InsuranceArbitrator.sol) ) within the repo. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#contract-creation-and-initialization) Contract creation and initialization `_finder` parameter in the constructor points the Insurance Arbitrator to the Finder contract that stores the addresses of the rest of the UMA contracts. The Finder address can be fetched from the relevant [networks](https://github.com/UMAprotocol/protocol/tree/master/packages/core/networks) file, if you are on a live network, or you can provide your own `Finder` instance if deploying UMA [protocol](https://github.com/UMAprotocol/protocol) in your own sandboxed testing environment. `_currency` parameter in the constructor identifies the token used for settlement of insurance claims, as well as the bond currency for proposals and disputes. This token should be approved as whitelisted UMA collateral. Please check [Approved Collateral Types](https://docs.uma.xyz/resources/approved-collateral-types) for production networks or call `getWhitelist()` on the [Address Whitelist](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/common/implementation/AddressWhitelist.sol) contract for any of the test networks. Alternatively, you can approve a new token address with `addToWhitelist` method in the Address Whitelist contract if working in a sandboxed UMA environment. `_timer` is used only when running unit tests locally to simulate the advancement of time. For all the public networks (including testnets) the zero address should be used. As part of initialization, the `oo` variable is set to the address of the `OptimisticOracleV2` implementation as discovered through `getImplementationAddress` method in the [Finder](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/implementation/Finder.sol) contract. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#issuing-insurance) Issuing insurance `issueInsurance` method allows any insurer to deposit `insuredAmount` of `currency` tokens by designating an insurance beneficiary (`insuredAddress`) and defining the insured event (`insuredEvent`). Before calling this method, the insurer should have approved this contract to spend the required amount of `currency` tokens. Internally, the issued policy is stored in the `insurancePolicies` mapping using the calculated `policyId` key that is generated by hashing the current block number with the provided insurance parameters in the internal `_getPolicyId` function. After pulling `insuredAmount` from the caller in the `issueInsurance` method, the contract emits a `PolicyIssued` event including the `policyId` parameter that should be used when claiming insurance. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#submitting-insurance-claim) Submitting insurance claim Anyone can submit an insurance claim on the issued policy by calling the `submitClaim` method with the relevant `policyId` parameter. This method will initiate both a data request and proposal with the Optimistic Oracle. A proposal bond is required, hence the caller should have approved this contract to spend the required amount of `currency` tokens for the proposal bond. After checking that the `policyId` represents a valid unclaimed insurance policy, the contract gets the current `timestamp` and composes `ancillaryData` that will be required for making requests and proposals to the Optimistic Oracle: The resulting `timestamp` and `ancillaryData` parameters are hashed in the internal `_getClaimId` method that is used as a key when storing the linked `policyId` in the `insuranceClaims` mapping. This information will be required when receiving a callback from the Optimistic Oracle. The concatenated `ancillaryData` will have a valid question as specified in [UMIP-107](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-107.md) for `YES_OR_NO_QUERY` price identifier. An Optimistic Oracle data request is initiated without providing any proposer reward since the proposal will be done within the `submitClaim` method: Before the proposal is made, the Optimistic Oracle allows the requesting contract (this Insurance Arbitrator) to set additional parameters like bonding, liveness, and callback settings. This requires passing the same `priceIdentifier`, `timestamp`, and `ancillaryData` parameters to identify the request. Total bond to be pulled from the claim initiator consists of the Optimistic Oracle proposer bond and final fee for the relevant `currency` token. This contract sets the proposer bond as a fixed percentage (constant `oracleBondPercentage`) from `insuredAmount`. When calling the `setBond` method, the Optimistic Oracle calculates and returns the total bond that would be pulled when making the proposal: Optimistic Oracle liveness is set by calling the `setCustomLiveness` method. This contract uses 24 hours so that verifiers have sufficient time to check the claim, but one can adjust the `optimisticOracleLivenessTime` constant for testing. (You probably don't want to wait a full day to resolve your test requests!) In contrast to earlier versions, the Optimistic Oracle V2 by default does not use callbacks and requesting contracts have to explicitly subscribe to them if intending to perform any logic when a data request has changed state. Here, in calling `setCallbacks`, this contract only subscribes to a callback for settlement, as implemented in the `priceSettled` method. (Note: Subscribing to any other callbacks that are not implemented in the requesting contract would make data requests unresolvable.) After `totalBond` amount of `currency` token is pulled from the claim initiator and approved to be taken by Optimistic Oracle, this contract proposes `1e18` representing an answer of `YES` to the raised question. Requesting and proposing affirmative answers atomically allows us to reduce the number of steps taken by end users and it is most likely expected that the insured beneficiary would be initiating the claim. #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#disputing-insurance-claim) Disputing insurance claim For the sake of simplicity this contract does not implement a dispute method, but the disputer can dispute the submitted claim directly through Optimistic Oracle before the liveness passes by calling its `disputePrice` method: The disputer should pass the address of this Insurance Arbitrator contract as `requester` and all the other parameters from the original request when the claim was initiated as emitted by the Optimistic Oracle in its `RequestPrice` event. If the claim is disputed, the request is escalated to the UMA DVM and it can be settled only after UMA voters have resolved it. To learn more about the DVM, see the docs section on the DVM: [how does UMA's DVM work](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) . #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#settling-insurance-claim) Settling insurance claim Similar to disputes, claim settlement should be initiated through the Optimistic Oracle contract by calling its `settle` method with the same parameters: In case the liveness has expired or a dispute has been resolved by the UMA DVM, this call would initiate a `priceSettled` callback in the Insurance Arbitrator contract: Based on the received callback parameters, this contract can identify the relevant `claimId` that is used to get the stored insurance policy: Importantly, all callbacks should be restricted to accept calls only from the Optimistic Oracle to avoid someone spoofing a resolved answer: Depending on the resolved answer, this contract would either pay out the insured beneficiary and delete the insurance (in case of `1e18` representing the answer `YES`, the insurance claim was valid) or reject the payout and re-open the policy for any subsequent claims: ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#tests-and-deployment) Tests and deployment All the unit tests covering the functionality described above are available [here](https://github.com/UMAprotocol/dev-quickstart/tree/main/test/InsuranceArbitrator) . To execute all of them, run: Before deploying the contract check the comments on available environment variables in [the deployment script](https://github.com/UMAprotocol/dev-quickstart/blob/main/deploy/003_deploy_insurance_arbitrator.ts) . In the case of the Görli testnet, the defaults would use the Finder instance that references the [Mock Oracle](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/oracle/test/MockOracleAncillary.sol) implementation for resolving DVM requests. This exposes a `pushPrice` method to be used for simulating a resolved answer in case of disputed proposals. Also, the default Görli deployment would use the already whitelisted `TestnetERC20` currency that can be minted by anyone using its `allocateTo` method. To deploy the Insurance Arbitrator contract on Görli, run: Optionally you can verify the deployed contract on Etherscan: ### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#interacting-with-deployed-contract) Interacting with deployed contract The following section provide instructions on how to interact with the deployed contract from the Hardhat console, though one can also use it for guidance for interacting through another interface (e.g. Remix or Etherscan). Start Hardhat console with: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#initial-setup) Initial setup From the Hardhat console, start by adding the required `getAbi` dependency for interacting with UMA contracts and use the first two accounts as insurer and insured beneficiary: Grab the deployed Insurance Arbitrator contract: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#issue-insurance) Issue insurance Assuming `TestnetERC20` was used as `currency` when deploying, mint the required insurance amount (e.g. 10,000 TEST tokens) and approve the Insurance Arbitrator to pull them: Issue the insurance policy and grab the resulting `policyId` from the emitted `PolicyIssued` event: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#submit-insurance-claim) Submit insurance claim First calculate the expected proposer bond: Fetch the expected final fee from the `Store` contract (which is discovered through the `Finder`): Calculate the expected total bond and provide funding/approval for the insured claimant: Now initiate the insurance claim and grab request details from the `RequestPrice` event emitted by the Optimistic Oracle: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#dispute-insurance-claim) Dispute insurance claim Before liveness passes, the insurer can dispute the claim through the Optimistic Oracle. First, they must fund and approve with the same bonding amount: If you are on a testnet like Göerli, in order to simulate UMA voting on a testnet, you can use the [Mock Oracle](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/test/MockOracleAncillary.sol) : Now initiate the dispute and grab the vote request details from the `PriceRequestAdded` event emitted by the Mock Oracle: #### [](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#settle-insurance-claim) Settle insurance claim Before settling the claim, we can take a look at the vote request as seen by UMA voters: The `ancillaryData` should start with `q:"Had the following insured event occurred as of request timestamp: Bad things have happened?"`. It is then followed by the `ooRequester` key with our Insurance Arbitrator address in its value. In order to simulate `YES` as the resolved answer we would pass `1e18` as the `price` parameter in the Mock Oracle `pushPrice` method: Now we can settle the request through the Optimistic Oracle and observe the emitted `ClaimAccepted` from our Insurance Arbitrator contract: The above settlement transaction should also transfer `insuredAmount` tokens to the insured beneficiary as well as return the proposer bond to the claim initiator. Alternatively, if `0` value was resolved, the settlement transaction should emit the `ClaimRejected` event without paying out the `insuredAmount` and returning the bond to the disputer, along with half of the proposer's bond. [PreviousEvent-Based Prediction Market](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-event-based-prediction-market) [NextManagedOptimisticOracleV2](https://docs.uma.xyz/developers/managedoptimisticoraclev2) Last updated 1 year ago Was this helpful? * [Insurance Arbitrator Contract](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#insurance-arbitrator-contract) * [Development environment and tests](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#development-environment-and-tests) * [Contract implementation](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#contract-implementation) * [Tests and deployment](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#tests-and-deployment) * [Interacting with deployed contract](https://docs.uma.xyz/developers/optimistic-oracle/in-depth-tutorial-insurance-claims-arbitration#interacting-with-deployed-contract) Was this helpful? Copy constructor( FinderInterface _finder, address _currency, address _timer ) Testable(_timerAddress) { finder =_finderAddress; currency = IERC20(_currency); oo = OptimisticOracleV2Interface(finder.getImplementationAddress(OracleInterfaces.OptimisticOracleV2)); } Copy function issueInsurance( string calldata insuredEvent, address insuredAddress, uint256 insuredAmount ) external returns (bytes32 policyId) ... Copy function submitClaim(bytes32 policyId) ... Copy uint256 timestamp = getCurrentTime(); // note that `getCurrentTime` is exported from testable to enable easy time manipulation. bytes memory ancillaryData = abi.encodePacked(ancillaryDataHead, claimedPolicy.insuredEvent, ancillaryDataTail); bytes32 claimId = _getClaimId(timestamp, ancillaryData); insuranceClaims[claimId] = policyId; Copy oo.requestPrice(priceIdentifier, timestamp, ancillaryData, currency, 0); Copy uint256 proposerBond = (claimedPolicy.insuredAmount * oracleBondPercentage) / 1e18; uint256 totalBond = oo.setBond(priceIdentifier, timestamp, ancillaryData, proposerBond); Copy oo.setCustomLiveness(priceIdentifier, timestamp, ancillaryData, optimisticOracleLivenessTime); Copy oo.setCallbacks(priceIdentifier, timestamp, ancillaryData, false, false, true); Copy oo.proposePriceFor(msg.sender, address(this), priceIdentifier, timestamp, ancillaryData, int256(1e18)); Copy function disputePrice( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) ... Copy function settle( address requester, bytes32 identifier, uint256 timestamp, bytes memory ancillaryData ) ... Copy function priceSettled( bytes32, // identifier passed by Optimistic Oracle, but not used here as it is always the same. uint256 timestamp, bytes memory ancillaryData, int256 price ) ... Copy bytes32 claimId = _getClaimId(timestamp, ancillaryData); Copy require(address(oo) == msg.sender, "Unauthorized callback"); Copy // Deletes insurance policy and transfers claim amount if the claim was confirmed. if (price == 1e18) { delete insurancePolicies[policyId]; currency.safeTransfer(claimedPolicy.insuredAddress, claimedPolicy.insuredAmount); emit ClaimAccepted(claimId, policyId); // Otherwise just reset the flag so that repeated claims can be made. } else { insurancePolicies[policyId].claimInitiated = false; emit ClaimRejected(claimId, policyId); } Copy yarn test test/InsuranceArbitrator/* Copy NODE_URL_5=YOUR_GOERLI_NODE MNEMONIC=YOUR_MNEMONIC yarn hardhat deploy --network goerli --tags InsuranceArbitrator Copy ETHERSCAN_API_KEY=YOUR_API_KEY yarn hardhat etherscan-verify --network goerli --license AGPL-3.0 --force-license --solc-input Copy NODE_URL_5=YOUR_GOERLI_NODE MNEMONIC=YOUR_MNEMONIC yarn hardhat console --network goerli Copy const { getAbi } = require("@uma/contracts-node"); const [insurer, insured] = await ethers.getSigners(); Copy const insuranceArbitratorDeployment = await deployments.get("InsuranceArbitrator"); const insuranceArbitrator = new ethers.Contract( insuranceArbitratorDeployment.address, insuranceArbitratorDeployment.abi, ethers.provider ); Copy const insuredAmount = ethers.utils.parseEther("10000"); const currency = new ethers.Contract(await insuranceArbitrator.currency(), getAbi("TestnetERC20"), ethers.provider); await (await currency.connect(insurer).allocateTo(insurer.address, insuredAmount)).wait(); await (await currency.connect(insurer).approve(insuranceArbitrator.address, insuredAmount)).wait(); Copy const issueReceipt = await (await insuranceArbitrator.connect(insurer).issueInsurance( "Bad things have happened", insured.address, insuredAmount )).wait(); const policyId = (await insuranceArbitrator.queryFilter( "PolicyIssued", issueReceipt.blockNumber, issueReceipt.blockNumber ))[0].args.policyId; Copy const proposerBond = insuredAmount.mul(await insuranceArbitrator.oracleBondPercentage()).div(ethers.utils.parseEther("1")); Copy const finder = new ethers.Contract(await insuranceArbitrator.finder(), getAbi("Finder"), ethers.provider); const store = new ethers.Contract(await finder.getImplementationAddress( ethers.utils.formatBytes32String("Store")), getAbi("Store"), ethers.provider); const finalFee = (await store.computeFinalFee(currency.address)).rawValue; Copy const totalBond = proposerBond.add(finalFee); await (await currency.connect(insured).allocateTo(insured.address, totalBond)).wait(); await (await currency.connect(insured).approve(insuranceArbitrator.address, totalBond)).wait(); Copy const oo = new ethers.Contract(await insuranceArbitrator.oo(), getAbi("OptimisticOracleV2"), ethers.provider); const claimReceipt = await (await insuranceArbitrator.connect(insured).submitClaim(policyId)).wait(); const request = (await oo.queryFilter("RequestPrice", claimReceipt.blockNumber, claimReceipt.blockNumber))[0].args; Copy await (await currency.connect(insurer).allocateTo(insurer.address, totalBond)).wait(); await (await currency.connect(insurer).approve(oo.address, totalBond)).wait(); Copy const mockOracle = new ethers.Contract(await finder.getImplementationAddress( ethers.utils.formatBytes32String("Oracle")), getAbi("MockOracleAncillary"), ethers.provider); Copy const disputeReceipt = await (await oo.connect(insurer).disputePrice( request.requester, request.identifier, request.timestamp, request.ancillaryData )).wait(); const voteRequest = (await mockOracle.queryFilter( "PriceRequestAdded", disputeReceipt.blockNumber, disputeReceipt.blockNumber ))[0].args; Copy console.log("identifier:", ethers.utils.parseBytes32String(voteRequest.identifier)); console.log("time:", Number(voteRequest.time)); console.log("ancillaryData:", ethers.utils.toUtf8String(voteRequest.ancillaryData)); Copy await (await mockOracle.connect(insured).pushPrice( voteRequest.identifier, voteRequest.time, voteRequest.ancillaryData, ethers.utils.parseEther("1") )).wait(); Copy const settleReceipt = await (await oo.connect(insured).settle( request.requester, request.identifier, request.timestamp, request.ancillaryData )).wait(); const claimSettlementEvent = (await insuranceArbitrator.queryFilter( "ClaimAccepted", settleReceipt.blockNumber, settleReceipt.blockNumber ))[0]; console.log(claimSettlementEvent); --- # ASSERT_TRUTH Deprecation | UMA Documentation As of December 8th, 2025. [ASSERT\_TRUTH2](https://github.com/UMAprotocol/UMIPs/pull/629/files#diff-f961c56cb0d079742c67cdc3d0f1a36119daf1f46416a59c1f3ac68be7bade0c) is the intended identifier to be used with OOV3. The original [ASSERT\_TRUTH](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-170.md) identifier will be deprecated as of December 15, 2025. These identifiers have the same specifications and the change is only to break support for deprecated projects. **Please note:** after these changes do not use the following OOV3 functions: * the `assertTruthWithDefaults` function will always revert as it hardcodes in the ASSERT\_TRUTH identifier * the `defaultIdentifier` public constant variable will return the deprecated ASSERT\_TRUTH identifier [PreviousOptimistic Oracle v3](https://docs.uma.xyz/developers/optimistic-oracle-v3) [NextUsing Blacklisting Tokens as Currency](https://docs.uma.xyz/developers/optimistic-oracle-v3/using-blacklisting-tokens-as-currency) Last updated 20 days ago Was this helpful? Was this helpful? --- # Setting Custom Bond and Liveness Parameters | UMA Documentation Every request to UMA's Optimistic Oracle includes bond and liveness settings that specify the size of the bond that proposers (and disputers) are required to post, the token used for bonding, and the liveness window, which is the challenge period during which a proposal can be challenged. The minimum bond is the same as [final fee](https://docs.uma.xyz/resources/approved-collateral-types) for Optimistic Oracle V2 (OOV2) or can be queried by calling getMinimumBond(token) for Optimistic Oracle V3 (OOV3). The default liveness window is two hours. For many cases, you may want to customize these values. The primary reason to increase the bond size or challenge window is to increase your security for complex requests or requests that could move large amounts of money. ### [](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#how-to-think-about-proposer-and-disputer-bonds) How to think about proposer and disputer bonds In most cases, you will want to set a bond higher than the minimum. The reason for this is that the bond provides a financial incentive for disputers to dispute invalid proposals. Disputers receive half of the proposer bond in the case of a successful dispute in the OOV3. For the OOV2, it's half of the excess above the final fee. The part of the bond that doesn't go to the disputer in a successful dispute goes to the UMA `Store` contract. The reason the disputer does not get the full amount is to prevent a malicious proposer from making a bad proposal and then front-running an honest disputer to dispute themselves if they get caught. #### [](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#example-bond-payouts-oov3) Example bond payouts (OOV3) As an example, imagine an application that requires a 10,000 USDC bond to assert a claim via OOV3. To make an assertion, a proposer must post a 10,000 USDC bond, which they will get back after the liveness window if the assertion is not disputed. To make a dispute, a disputer must also post a 10,000 USDC bond. If the disputer wins, they receive 15,000 USDC (10,000 USDC disputer bond + 5,000 USDC from the excess proposer bond) and the `Store` receives 5,000 USDC. If the proposer wins, they receive 15,000 USDC (10,000 USDC proposer bond + 5,000 USDC from the disputer bond) and the `Store` receives 5,000 USDC (half of the disputer bond). #### [](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#higher-or-lower-bonds) Higher or lower bonds? If data received from the oracle could potentially move large amounts of value, you may want to set a higher bond to make it more costly for an attacker to attempt to steal funds through a false proposal. (Remember that the proposer will lose their entire bond if they are disputed and found to be incorrect.) The tradeoff to setting a higher bond is that it may be more difficult to run a project that requires frequent proposals, since good proposers will have funds locked up for at least the length of the challenge window. Another tradeoff is that a very high bond may make it difficult for disputers to post bonds to challenge bad proposals. Remember also that disputers will lose their bond if they are incorrect, so the disputer has a capital cost and a risk of loss. Before launching your contract, you should think about who you expect to be proposers and disputers, whether they have adequate access to capital, how much value the oracle is securing, how many requests you expect to make in a given day, and whether you should add a proposer reward (to incentivize independent proposers to take on the capital cost and risk of proposing answers to your requests). There are no exact answers to how high or low your bond should be, although it is almost always a good idea to set a bond that is larger than the final fee so that disputers have an incentive to dispute bad proposals. ### [](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#how-to-think-about-liveness) How to think about liveness The liveness period is the challenge window where disputers can dispute a proposal, and is another knob you can turn to increase security (while accepting UX trade-offs). A typical challenge period is two hours, which is usually plenty of time for disputers to recognize and dispute bad proposals. In some cases, you may want to increase the length of the challenge period. A classic example is an insurance contract, since insurance contracts usually have these qualities: 1. Large amounts of value are at stake. 2. Payouts are rare. 3. Proposals and disputes require a greater amount of thought and consideration. 4. Payouts are not very time sensitive, and a long delay (even a day or more) to allow proposers and disputers to think through the situation will not seriously inconvenience users. You may want to consider a two-hour challenge window in these situations: 1. Requests happen frequently and proposers and disputers will need to reuse their capital regularly for bonding. 2. The dollar value secured by a request is lower. 3. The request is easy to reason about (and proposals and disputes could potentially be automated). 4. Users are sensitive to the settlement time. At this time, it is generally not recommended to set a challenge window shorter than two hours. If your users are very sensitive to settlement time, you may want to consider a smart contract architecture that allows a particular type of user to fully insure a piece of data that is acted on instantly, and then waiting to be reimbursed after the challenge window. Think of this user as a "designated waiter," who is probably compensated in some way. A good example is the [relayer](https://docs.across.to/how-across-works/overview/roles-within-across#relayer) in the Across protocol. Users of the Across bridge receive their funds almost instantly, because a relayer sends them funds on the receiving chain and then submits for reimbursement from the protocol, and has to wait for several hours for their relay to be bundled with other relays, proposed, and then settled after the challenge window. In this case, the UX for most users is excellent (nearly instant transfers) but the protocol is still secured by a long challenge window that is absorbed by a less time sensitive user type (the relayer) who is paid fees for their trouble. [PreviousSandboxed Oracle Environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment) [NextHow does UMA's Oracle work?](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work) Last updated 26 days ago Was this helpful? * [How to think about proposer and disputer bonds](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#how-to-think-about-proposer-and-disputer-bonds) * [How to think about liveness](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters#how-to-think-about-liveness) Was this helpful? --- # Using Blacklisting Tokens as Currency | UMA Documentation Using a token that allows backlisting (e.g. USDC) as your [assertTruth](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol#L138) `currency` opens up a griefing vector that integrators should be aware of. The [assertTruth](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol#L138) and [disputeAssertion](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol#L220) functions allow the caller to set any address as the `asserter` and `disputer` that will receive payouts if their assertion/dispute is correct upon settlement. If a bad actor calls these functions and specifies a blacklisted address for repayment, the [settle](https://github.com/UMAprotocol/protocol/blob/dd9d1fa988d8520ad36db145db13591e9a104fa9/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol#L498) function will revert and cause the request to be frozen unless the address is unblacklisted. This costs malicious users their bonds and does not result in any gain, but freezing the assertion could cause issues for the integrator. Integrations that use tokens with blacklisting functionality should ensure that they have a way to manage frozen assertions (e.g. an admin function that can ignore a frozen assertion) without negatively affecting their integration. [PreviousASSERT\_TRUTH Deprecation](https://docs.uma.xyz/developers/optimistic-oracle-v3/assert_truth-deprecation) [NextQuick start](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start) Last updated 2 months ago Was this helpful? Was this helpful? --- # Example Projects | UMA Documentation For a complete list of all current integrations see: [projects.uma.xyz](https://projects.uma.xyz/) Integrations Description [Across](https://across.to/) Across protocol is a novel bridging method that combines UMA's Optimistic Oracle with bonded relayers and single-sided liquidity pools to provide decentralized instant transactions from rollup chains to Ethereum mainnet. [Polymarket](https://polymarket.com/) Polymarket is an information markets platform that lets you trade on the world’s most highly-debated topics. Polymarket supports UMA and its Optimistic Oracle as a resolution source for its markets. [Jarvis Network](https://jarvis.network/) Jarvis Network is a set of protocols on Ethereum allowing anyone to gain exposure to the price of any traditional or digital assets with stablecoins, against liquidity pools. Jarvis leverages UMA's Optimistic Oracle and DVM as its liquidation and dispute mechanism to ensure that jFIATs are properly collateralized. [Sherlock](https://www.sherlock.xyz/) Sherlock is a protocol on the Ethereum blockchain that protects users from smart contract exploits with proprietary security analysis and protocol-level coverage. UMA acts as an unbiased, decentralized arbiter for Sherlock where disputes are escalated to UMA's DVM and voted on to be resolved. [Domination Finance](https://domination.finance/) Domination Finance is a decentralized exchange (DEX) deployed on Ethereum and Polygon. Domination Finance uses UMA's Optimistic Oracle to enable users to speculate on popular market dominance metrics, such as Bitcoin Dominance (BTCDOM). [Yam Synths](https://synths.yam.xyz/) Yam Synths is a powerful platform from the Yam DAO community providing easily accessible and innovative synthetic assets. UMA's Optimistic Oracle helps Yam to allow anyone in the world to access and trade cutting-edge synthetic products. [Hats.finance](https://hats.finance/) Hats.finance is a proactive bounty protocol for white hat hackers and auditors, where projects, community members, and stakeholders incentivize protocol security and responsible disclosure. Hats.finance and UMA have collaborated on a product called protected tokens which enable users to recover funds in the event of a hack, bug, or other cause of lost funds. ### [](https://docs.uma.xyz/protocol-overview/example-projects#developers) [PreviousHow does UMA's Oracle work?](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work) [NextDVM 2.0](https://docs.uma.xyz/protocol-overview/dvm-2.0) Last updated 1 year ago Was this helpful? Was this helpful? --- # Voter Guide | UMA Documentation * Read through the vote Description under the Details tab. Carefully review how the vote should resolve and if provided, the timing of when the request can resolve and any listed sources. * Review the Timestamp under the Details tab. This is the point in time at which the vote should be evaluated. * The vote Discussion tabs lists comments from the UMA Discord with arguments, resources, and suggested votes that may be helpful. **However, some commenters may try to influence the vote for their own profit. Always ​independently verify​ any claims before relying on them.** * **For prediction market votes, it is helpful to review the market odds over time to sanity check your vote.** The market odds after an event has expired are a reflection of how bettors with skin in the game think a market should resolve. You should not vote based on the market odds, but if you are planning on voting against strong market odds you may want to do extra research to ensure your vote is correct. [PreviousVoting Walkthrough](https://docs.uma.xyz/using-uma/voting-walkthrough) [NextVoting Gas Rebates](https://docs.uma.xyz/using-uma/voting-walkthrough/voting-gas-rebates) Last updated 4 months ago Was this helpful? Was this helpful? --- # DVM 2.0 FAQ | UMA Documentation ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-kind-of-apy-can-i-expect-to-receive-for-staking) What kind of APY can I expect to receive for staking? To learn more about how exact APY is calculated, you can refer [here](https://docs.uma.xyz/protocol-overview/dvm-2.0#staking-apy) . At a high level though, all UMA voters on average will receive an APY determined by the annual UMA emissions amount divided by the average total UMA staked over the year. Before the DVM 2.0 upgrade, approximately 18-20mm UMA was voting on average for each vote. If this holds relatively constant, it means that average UMA voter APYs will be approximately 28-32%. This can of course fluctuate on an individual voter basis dependent on voter performance. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#how-do-i-maximize-my-apy) How do I maximize my APY? Maximizing your APY should be simple. To maximize APY you should: * Remain staked within the system. * Claim and restake your rewards at times when it makes sense based off balancing your increased stake’s additional future rewards received against gas costs of claiming and restaking. * Vote consistently and carefully. Incorrect or absent voter stakes are slashed and distributed to correct / participating voters after each voting round. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-is-the-current-uma-voter-rewards-emission-rate) What is the current UMA voter rewards emission rate? The UMA emission rate is currently 0.155 UMA/second. This will be distributed pro-rata to all stakers within the UMA system on a per second basis. The UMA emissions rate is controlled by UMA governance and can be updated at any time by a DVM vote. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-is-the-unstake-timer-why-does-this-exist) What is the unstake timer? Why does this exist? The unstake timer is a set amount of time that a staker must wait before they can execute a request to unstake from the UMA system. With the initial DVM 2.0 upgrade, this unstake timer was set to 7 days. The unstake timer exists to make the UMA voting system more hardened against attempted manipulation attacks. UMA has always had an assumption that if a malicious attacker could manage to either vote with or bribe a majority of voters to vote incorrectly on a dispute, the UMA token would go to zero in value. This is known as the UMA cost of corruption. In practice, this is probably not entirely true as markets are not entirely efficient. Attackers could likely dump voted with tokens for some amount of value after a successful attack. Having a required 7 hold period more strongly enforces that UMA’s cost of corruption is enforced by the market if a manipulation attempt is successful. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-kind-of-things-does-the-dvm-vote-on) What kind of things does the DVM vote on? The Optimistic Oracle & DVM can provide all kinds of different data, from crypto prices, to sports, to verifying if a bridging transaction was valid, with new use cases being added all the time, so its hard to anticipate precisely what you might be asked to vote on, however all questions will be asking something about the state of the world at a particular time, indicated by the timestamp. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#how-should-i-determine-what-i-should-vote) How should I determine what I should vote? There are two primary data sources to assist a voter in determining what value they should vote with. First, the UMIP that the DVM request references. This will tell you general information about how that question should be answered. The second place to check is the ancillary data of the question. This will provide more context for the question and is likely to include a source, which a link that will take you to a place where that data is likely to be published. Disputes are also discussed at length in the [UMA Discord](https://discord.com/invite/jsb9XQJ) #voting-chat and #evidence-rationale channels. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#why-do-i-have-to-commit-and-reveal-votes) Why do I have to commit and reveal votes? The commit/reveal cycle prevents people from seeing how others have voted by encrypting all initial votes and only decrypting them once all votes are cast. The oracle is built on Schelling Point theory, which indicates that the most likely consensus of non-colluding participants is the truth. By obscuring how other people have voted, this ensures that each tokenholder votes independently. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-vote-with-tokens-that-havent-been-staked) Can I vote with tokens that haven’t been staked? No. Only tokens that have been staked can be voted with. If you have already initiated the unstaking process for any or all of your coins, they also will not receive rewards or be able to be voted with. However if you have unstaked coins when a vote starts, you can stake your coins any time up to the end of the commit period, and they will be eligible to vote with. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-vote-while-i-am-unstaking) Can I vote while I am unstaking? Unstaked tokens cannot vote. This includes tokens that are in the “cooldown period” after an unstake request has been submitted. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-cancel-an-unstake-request-while-it-is-pending) Can I cancel an unstake request while it is pending? You cannot. Unstake requests cannot be canceled once submitted. If you once again wish for those tokens to be staked, you can wait for the unstake period to finish, claim your tokens and restake them. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-get-someone-else-to-vote-on-my-behalf) Can I get someone else to vote on my behalf? It is possible to delegate your staked UMA in one wallet to a different wallet, allowing voters to keep their UMA on a cold wallet and vote with hot wallet, however there is a 1-1 relationship between voting wallets and staking wallets, therefore it is not possible for one person to vote on behalf of multiple other people. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#do-i-still-get-gas-rebates) Do I still get gas rebates? Yes! Risk Labs will still be continuing with the existing voting gas rebate program. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#i-still-dont-know-how-this-works-where-can-i-get-help) I still don't know how this works - where can I get help? Jump into our [discord](https://discord.com/invite/jsb9XQJ) and ask questions about anything that you are unsure of. [PreviousDVM 2.0](https://docs.uma.xyz/protocol-overview/dvm-2.0) [NextGovernance](https://docs.uma.xyz/community/governance) Last updated 10 months ago Was this helpful? * [What kind of APY can I expect to receive for staking?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-kind-of-apy-can-i-expect-to-receive-for-staking) * [How do I maximize my APY?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#how-do-i-maximize-my-apy) * [What is the current UMA voter rewards emission rate?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-is-the-current-uma-voter-rewards-emission-rate) * [What is the unstake timer? Why does this exist?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-is-the-unstake-timer-why-does-this-exist) * [What kind of things does the DVM vote on?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#what-kind-of-things-does-the-dvm-vote-on) * [How should I determine what I should vote?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#how-should-i-determine-what-i-should-vote) * [Why do I have to commit and reveal votes?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#why-do-i-have-to-commit-and-reveal-votes) * [Can I vote with tokens that haven’t been staked?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-vote-with-tokens-that-havent-been-staked) * [Can I vote while I am unstaking?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-vote-while-i-am-unstaking) * [Can I cancel an unstake request while it is pending?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-cancel-an-unstake-request-while-it-is-pending) * [Can I get someone else to vote on my behalf?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#can-i-get-someone-else-to-vote-on-my-behalf) * [Do I still get gas rebates?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#do-i-still-get-gas-rebates) * [I still don't know how this works - where can I get help?](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq#i-still-dont-know-how-this-works-where-can-i-get-help) Was this helpful? --- # DVM 2.0 | UMA Documentation The UMA DVM is the arbitrator for the Optimistic Oracle and other UMA ecosystem contracts. It facilitates dispute resolution wherein UMA token holders vote in a commit reveal schelling point mechanism. For an overview of how the DVM see [here.](https://docs.umaproject.org/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) The DVM has been rebuilt with the new iteration being released in Q1 of 2023. At a high level, the upgrade adds a new staking and slashing mechanism wherein voters earn a pro-rata share of emissions for staking and are slashed for voting wrong (or not voting). This upgrade also reworks a number of other DVM contracts such as the governor, proposer contract and a new designated voting contract. Finally, this upgrade adds a new emergency recovery mechanism to the DVM that enables admin proposals to bypass the DVM's schelling point oracle system in the event of an emergency. More detail on the individual changes are broken down in the sections that follow. This doc page outlines some of the changes between DVM 1.0 and DVM 2.0 and some other relevant implementation details. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#mechanism-changes-and-uma-tokenomics-update) Mechanism changes & UMA tokenomics update The DVM2.0 introduces three key changes to how the UMA token interacts with DVM system: 1. Voters now must **stake UMA in the DVM** to participate in the schelling point and to receive rewards. 2. Voters now **earn a pro-rata share of a fixed emission rate** simply for staking their tokens. Staking rewards are emitted at a constant rate per block. This means you can work out the overall UMA inflation over time and stakers can easily work out their APY for staking in the system. In comparison to the previous inflation system, the total inflation rate is no longer a factor of the number of votes held by the DVM. The pro-rata share of tokens received by stakers is independent of their voting performance. The emissions rate is set through UMA governance. 3. Voters' staked balances are also now **susceptible to slashing**. The slashing mechanism redistributes tokens from inactive and wrong voters to the stakers who voted correctly. This hardens the schelling point by adding a more punitive cost function to being wrong. Governance votes are treated as a special price request category where the slashing mechanism is not applied. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#vote-delegation) Vote Delegation First class vote delegation support enabling a 1 to 1 relationship between the delegator and delegate wallets. This lets a voter delegate from a secure cold storage wallet to a hot wallet. The hot wallet can commit, reveal and claim and re-stake their rewards but cannot access the underlying stake. If desired, more complex delegation systems (pooled UMA staking with delegate voting etc) can be built on top of this externally to the core UMA contracts. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#emergency-recovery-system) Emergency recovery system The DVM 2.0 now has an emergency recovery mechanism where bonded emergency proposals can be executed to short-circuiting and bypass the normal voting mechanism. This enables the DVM to recover from any kind of internal failure mode that could occur (breakage in the commit reveal system, contract issues or other) through a permissionless upgrade flow. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#other-system-wide-changes) Other system wide changes There are a number of other changes made, including: 1. Governance proposals now include ancillary data enabling better identifying information to be passed along to voters. 2. Price requests now contain a unique identifier, enabling easier tracking and support in front ends. 3. A number of gas optimizations were made throughout the protocol. ### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#implementation-details) Implementation details The sections below contain some details on nuanced implementation details of the DVM2.0 system. #### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#staking-apy) Staking APY Staking rewards (and the associated APY) consists of two discrete components: a) rewards from being **staked** and b) balance changes from **slashing**. The net staking APY you receive considers both of these values. Let's consider them separately. **Staking rewards** are a pro-rata share of a fixed emission rate, calculated on a per block basis. The rewards you are entitled to, from the last time you claimed, are calculated as follows: stakingRewards\=stakedDuration∗stake∗emissionsPerBlockcumulativeStakestakingRewards = \\frac{stakedDuration\*stake\*emissionsPerBlock}{cumulativeStake}stakingRewards\=cumulativeStakestakedDuration∗stake∗emissionsPerBlock​ **Slashing rewards & penalties** at the time of DVM 2.0 launch are designed to be as simple as possible, with the ability to update them at a later point through the use of a Slashing Library. At launch, slashing penalties will be approximately equal to the rewards one would have earned for an estimated stake duration. This has been targeted based off historical DVM 1.0 vote frequency, and means that someone who stakes but does not participate in any votes (or gets all votes wrong) should have their slashed stake and accumulated rewards cancel out for a 0% APY. This amounts to losing 0.1% of your staked amount per vote that is incorrect or missed. Note that each voting round (48 hour commit-reveal cycle) can have multiple votes in it (for example multiple price requests or governance actions). The amount you earn for voting correctly is the voters pro-rata share of the slashing of the incorrect voters. This can be calculated per voter per round as follows: slashPerVoterPerRound\=∑stake∗numberOfIncorrectVotes∗0.001slashPerVoterPerRound = \\sum stake \* numberOfIncorrectVotes \* 0.001slashPerVoterPerRound\=∑stake∗numberOfIncorrectVotes∗0.001 Then, the total amount slashed per round is the sum of all voters slash for that round: totalSlashPerRound\=∑slashPerVoterPerRoundtotalSlashPerRound = \\sum slashPerVoterPerRoundtotalSlashPerRound\=∑slashPerVoterPerRound A voter, who was correct, will then earn a pro-rater share of the totalSlashPerRound as: positiveSlashForCorrectVotePerRound\=totalSlashPerRound∗stakecumlativeCorrectVoteStakepositiveSlashForCorrectVotePerRound=\\frac{totalSlashPerRound\*stake}{cumlativeCorrectVoteStake}positiveSlashForCorrectVotePerRound\=cumlativeCorrectVoteStaketotalSlashPerRound∗stake​ A staker's net APY is therefore the sum of their `stakingRewards` and `positiveSlashForCorrectVotePerRound` annualized over a 1 year period. #### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#rolled-votes) Rolled votes Under some situations votes can "roll". We define a rolled vote as a vote that was not resolved in one vote round and was moved into the subsequent voting round due to not successfully reaching the two types of needed quorums. These quorums are known as GAT (God Awful Threshold) and SPAT (Schelling Point Activation Threshold). The GAT within the DVM 2.0 is a constant amount of UMA that must vote on any given vote for it to not roll. In the DVM 1.0, this was set as a percentage of circulating UMA. At the time of DVM 2.0 initial deployment, the required GAT per vote is a constant 5 million UMA. The SPAT is a new concept from the DVM 2.0. It is a percentage of staked tokens that must vote and agree in order for a vote to not roll. The required SPAT is 65% currently of staked tokens. If a vote does not satisfy both of these constraints, it will roll. #### [](https://docs.uma.xyz/protocol-overview/dvm-2.0#vote-deletion) Vote Deletion There are certain situations in the DVM 2.0 where voters may want to delete votes. A good example of this would be in the case of spam deletion, where needless price requests are submitted in order by an attacker to try to create some sort of desired slashing conditions. In the DVM 2.0, votes are deleted once they have rolled a certain number of times. So if voters choose to not vote on the resolution of price requests, and either the GAT or SPAT are not met for a set number of voting rounds, those price requests will become deletable. At the time of DVM 2.0 initial deployment, the number of times a vote is rolled before being deleted is 4. [PreviousExample Projects](https://docs.uma.xyz/protocol-overview/example-projects) [NextDVM 2.0 FAQ](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq) Last updated 1 month ago Was this helpful? * [Mechanism changes & UMA tokenomics update](https://docs.uma.xyz/protocol-overview/dvm-2.0#mechanism-changes-and-uma-tokenomics-update) * [Vote Delegation](https://docs.uma.xyz/protocol-overview/dvm-2.0#vote-delegation) * [Emergency recovery system](https://docs.uma.xyz/protocol-overview/dvm-2.0#emergency-recovery-system) * [Other system wide changes](https://docs.uma.xyz/protocol-overview/dvm-2.0#other-system-wide-changes) * [Implementation details](https://docs.uma.xyz/protocol-overview/dvm-2.0#implementation-details) Was this helpful? --- # Voting Gas Rebates | UMA Documentation Risk Labs currently provides gas rebates for voters who have staked 1000 or more UMA to encourage more community members to participate in securing the Optimistic Oracle. * Rebates cover the gas cost for commit and reveal transactions and are denominated in ETH. * Voters must have at least 1000 UMA staked at the start of the commit period for that voting period's commit and reveal transactions to be rebated. * Commited votes must be revealed to be rebated. * If a voter commits more than once on a dispute, only the first commit will be rebated. * If a delegate address is used to vote, the rebate will be sent to the delegate address. * Rebates are calculated for one calendar month and are sent out within the first half of the following month. Announcements are made in the UMA Discord at the time each rebate is sent out. [PreviousVoter Guide](https://docs.uma.xyz/using-uma/voting-walkthrough/voter-guide) [NextDiscord Summaries](https://docs.uma.xyz/using-uma/voting-walkthrough/discord-summaries) Last updated 2 months ago Was this helpful? Was this helpful? --- # Discord Summaries | UMA Documentation The Voterdapp contains a "Discussion Summary" tab with an LLM summary of Discord comments on the vote. The summary removes duplicate arguments across all comments to give voters an overview of all arguments which is useful for long or spammed comment threads. The summary does not fact check comments, add additional arguments, or give voting recommendations. Voters should always verify all arguments included in the summaries with their own research. The raw comments are also provided in the "Discord Comments" tab so voters can review them against the summary in case of LLM error. [PreviousVoting Gas Rebates](https://docs.uma.xyz/using-uma/voting-walkthrough/voting-gas-rebates) [NextProposing Oracle Data](https://docs.uma.xyz/using-uma/providing-oracle-data) Last updated 4 months ago Was this helpful? Was this helpful? --- # DAO Proposals | UMA Documentation The UMA DAO accepts proposals for on-chain actions that require tokenholders approval. An example would be a request for funding from the UMA treasury. The steps to complete a proposal: **Step 1: Post to Discourse** The first step is making a post in the UMA discourse under [non-technical UMIPs](https://discourse.umaproject.org/c/uma-protocol/non-technical-umips/41) . The post should outline the key components of a proposal and give the community a chance to submit feedback and recommend changes. An example submission is [Polymarket's Liquidity Mining Program](https://discourse.umaproject.org/t/revised-funding-request-for-liquidity-mining-program-extension-from-polymarket/1716) . **Step 2: Snapshot Vote** When the proposal appears ready, a Snapshot vote can be created by the proposer with a 5 day close. Should it receive majority support at the end of 5 days, it will then pass to snapshot for an indicative vote prior to being put to an on-chain vote. Proposals that require movement of treasury funds require a 4,000 UMA bond to be posted which is returned if the proposal is successful in an on-chain vote of tokenholders. RiskLabs, the foundation which established UMA, has indicated its willingness to handle the on-chain proposal and cover the bond payment for proposals which attract majority support on a snapshot poll of tokenholders. Here is the snapshot for [Polymarket's Liquidity Mining Program](https://discourse.umaproject.org/t/revised-funding-request-for-liquidity-mining-program-extension-from-polymarket/1716) . **Step 3: On-chain Vote** After a Snapshot vote has successfully passed, an on-chain vote is held to transfer the funds. If the vote is successful, the funds are transferred to the recipient wallet address. [PreviousThe UMIP Process](https://docs.uma.xyz/community/governance/the-umip-process) [NextVoting Walkthrough](https://docs.uma.xyz/using-uma/voting-walkthrough) Last updated 3 years ago Was this helpful? Was this helpful? --- # How does UMA's Oracle work? | UMA Documentation UMA's Optimistic Oracle allows contracts to quickly request and receive data information. The Optimistic Oracle acts as a generalized escalation game between contracts that initiate a price request and UMA's dispute resolution system known as the Data Verification Mechanism (DVM). Prices proposed by the Optimistic Oracle will not be sent to the DVM unless it is disputed. If a dispute is raised, a request is sent to the DVM. All contracts built on UMA use the DVM as a backstop to resolve disputes. Disputes sent to the DVM will be resolved within a few days - after UMA tokenholders vote on what the correct outcome should have been. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FQpaIpBCOAA9CoWX2lbVH%252FAsserterupdatemarch.png%3Falt%3Dmedia%26token%3D7b147ab2-4a8a-4241-b4b2-0608604e5019&width=768&dpr=4&quality=100&sign=d63d322d&sv=2) Oracle system diagram ### [](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#optimistic-oracle) Optimistic Oracle The first part of UMA's oracle system is the Optimistic Oracle. This is a layer that is designed to optimistically verify pieces of data quickly. It is secured by the UMA DVM, because disputes can be escalated from the Optimistic Oracle layer to the DVM for dispute arbitration. The main lifecycle of the OO looks like this, and is detailed in the Asserter and Disputer rows within the diagram above. 1. An Asserter will post a bonded assertion about the state of the world. This assertion will : * **identifier:** price identifier being requested. * **timestamp:** timestamp of the fact being asserted. * **claim:** ancillary data containing additional information about the assertion * **currency:** ERC20 token used for payment of rewards and fees. Must be approved for use with the DVM. * **bond:** a bond size that represents the stake the asserter is putting on their statement being correct. 2. Disputers can refute a piece of data submitted by an Asserter within the assertion liveness period by referencing their own off-chain price feeds and determination methodologies. The liveness period is a pre-defined amount of time a that an assertion can be disputed. 3. If Disputers do not refute the price submitted by the Asserter within the proposal liveness period, the assertion is optimistically treated as being correct. 4. If an assertion is disputed, the assertion will be submitted to UMA’s DVM for dispute arbitration. ### [](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) UMA's Data Verification Mechanism The Data Verification Mechanism (DVM) provides a backstop to the UMA OO by resolving disputes that happen when a proposed/asserted piece of data is disputed. 1. In the event of a dispute, a price request is submitted to the DVM which proposes a vote to UMA tokenholders to report the price of the asset at a specific timestamp. 2. The vote will conclude after a 48-96 hour voting period. 3. UMA tokenholders will reference the price identifier's [UMIP](https://docs.uma.xyz/community/governance/the-umip-process) to determine how to arrive at a vote result via off-chain price feeds and methodologies. 4. The DVM will aggregate votes from UMA tokenholders to determine the final price of the asset for a given timestamp. The DVM is powerful because it encompasses an element of human judgment to ensure contracts are securely and correctly managed when issues arise from volatile (and sometimes manipulatable) markets. UMA's oracle system is constructed with economic guarantees around the cost of corrupting the DVM to ensure it will cost more to corrupt the oracle (i.e., obtain 65% or more UMA tokens) than the amount someone could profit from corrupting the oracle (i.e. stealing funds within contracts on UMA). [PreviousSetting Custom Bond and Liveness Parameters](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters) [NextExample Projects](https://docs.uma.xyz/protocol-overview/example-projects) Last updated 26 days ago Was this helpful? * [Optimistic Oracle](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#optimistic-oracle) * [UMA's Data Verification Mechanism](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) Was this helpful? --- # The UMIP Process | UMA Documentation UMA Improvement Proposals (UMIPs) are design documents used to propose changes to the UMA ecosystem. UMIPs are intended to be the primary mechanism for proposing new features, collecting community input on an issue, and for documenting the design decisions that have gone into the UMA protocol. UMIPs are a convenient way to track the progress of an implementation. Examples of common UMIPS include adding a new [price identifier](https://docs.uma.xyz/resources/approved-price-identifiers) or [collateral currency](https://docs.uma.xyz/resources/approved-collateral-types) to be supported by the DVM. UMIPs are presented to UMA tokenholders for voting through the voting dapp to determine whether they will be accepted or rejected. UMIPs need to provide a concise technical specification of the feature and a rationale for the feature. They are modeled after [EIPs](https://eips.ethereum.org/) and [ZEIPs](https://blog.0xproject.com/0x-protocol-governance-voting-walkthrough-and-faq-3becfd57a370) . See here for an [EIP template](https://blog.0xproject.com/0x-protocol-governance-voting-walkthrough-and-faq-3becfd57a370) and [ZEIP template](https://github.com/0xProject/ZEIPs/blob/master/ISSUE_TEMPLATE.md) . [PreviousGovernance](https://docs.uma.xyz/community/governance) [NextDAO Proposals](https://docs.uma.xyz/community/governance/dao-proposals) Last updated 3 years ago Was this helpful? Was this helpful? --- # Resolving Disputes | UMA Documentation If the dispute is on a live network, it will be resolved by the [DVM](https://docs.umaproject.org/protocol-overview/how-does-umas-oracle-work) on Ethereum, and the results returned within 48-72 hours (depending on when the dispute was raised during the DVM voting cycle). If you are testing the dispute flow on Görli, you will need to manually resolve the dispute through the [Mock Oracle](https://goerli.etherscan.io/address/0x20570e9e27920ac5e2601e0bef7244deff7f0b28#code) . This contract stands in for the DVM on Görli and allows you to manually return your own values for testing purposes. 1. Go to the [Mock Oracle contract](https://goerli.etherscan.io/address/0x20570e9e27920ac5e2601e0bef7244deff7f0b28#code) on Görli Etherscan. 2. Click 'Write Contract.' 3. Click 'Connect to Web3' to connect your wallet. 4. Click 'OK' on the pop-up that warns you that writing to contracts on Etherscan is a beta test feature. 5. Connect through your wallet interface, and switch networks to Görli if necessary. 6. Click `pushPrice` to see the parameters you will need to enter. 7. Enter the original request's `identifier`, `time`, and `ancillaryData`, and enter the value you want to return for `price`. 8. Click 'Write' and submit the transaction. 9. Depending on how the contract you are testing was written, you may need to call `settleAndGetPrice` from your contract to the Optimistic Oracle contract to get the value returned from the mock oracle, or you may be able to call `settle` on the Optimistic Oracle and have your contract automatically receive and handle the return value with a `priceSettled` callback function. [PreviousDisputing Oracle Data](https://docs.uma.xyz/using-uma/disputing-oracle-data) [NextVerification System](https://docs.uma.xyz/verification-guide/verification-system) Last updated 3 years ago Was this helpful? Was this helpful? --- # Disputing Oracle Data | UMA Documentation 1. Go to the [Optimistic Oracle dApp](https://oracle.umaproject.org/) , if you are disputing proposals on a live network like Ethereum, Optimism, or Polygon, or go to the [Testnet dApp](https://testnet.oracle.umaproject.org/) if you are disputing test data on Görli. Disputes will be resolved by the [DVM](https://docs.umaproject.org/protocol-overview/how-does-umas-oracle-work) if you are on a live network, or by a mock oracle if you are on Görli (see Resolving Disputes). 2. Locate proposals under the Proposals tab for outstanding proposals that are within the challenge window and can be disputed. 3. Click on the proposal you want to dispute. 4. Click the 'Connect wallet' button in the top right corner and go through the steps to connect your wallet. Confirm you are on the same network as the proposal. 5. Before disputing, confirm the details of the request and ancillary data to ensure the proposal is actually incorrect. You may also want to check the instructions in the [UMIP](https://docs.umaproject.org/resources/approved-price-identifiers) for the identifier. 6. Click the 'Dispute Proposal' button. 7. Confirm the transaction details through your wallet provider. After confirming, the proposal will be disputed. 8. If you are on a live network, the dispute will escalate to the DVM on Ethereum for resolution. If you are on Görli, you will need to manually resolve the dispute through the [Mock Oracle](https://goerli.etherscan.io/address/0x20570e9e27920ac5e2601e0bef7244deff7f0b28#code) . [PreviousProposing Oracle Data](https://docs.uma.xyz/using-uma/providing-oracle-data) [NextResolving Disputes](https://docs.uma.xyz/using-uma/resolving-disputes) Last updated 3 years ago Was this helpful? Was this helpful? --- # Governance | UMA Documentation The UMA token is primarily a governance token used to contribute to UMA protocol decisions, such as voting on UMA Improvement Proposals (UMIPs), price requests, and disputes made to UMA's Data Verification Mechanism (DVM). ### [](https://docs.uma.xyz/community/governance#governing-the-uma-ecosystem) Governing the UMA ecosystem The UMA token is an integral part of the UMA ecosystem as it guarantees the economic security of UMA smart contracts and its oracle system. The objective of the UMA token is to enable the optimistic oracle to remain secure utilizing a fully decentralized and permissionless method. UMA's DVM is designed with an economic guarantee around the cost it would take to corrupt the oracle and the profit someone would receive. The DVM ensures the price to obtain 65% of UMA tokens is greater than the profit from corrupting the DVM, as measured by the collateral stored in UMA's financial contracts. This is achieved through an inflationary reward (currently 0.05% of total network token supply), distributed pro-rata by stake to voters who participate and vote correctly. As long as there is an honest majority, voters will vote correctly. As the total value of collateral locked in UMA grows, the UMA token is required to increase in value to ensure the security of the DVM. To ensure this inequality holds, the DVM may charge fees to financial contracts which the DVM would use to buy UMA tokens. ### [](https://docs.uma.xyz/community/governance#voting) Voting The UMA voting process requires tokenholders to commit and reveal their votes in two separate stages. Each stage is open for 24 hours, so each voting period is 48 hours. * UMA Tokenholders can discuss their votes in the #voting channel of the [UMA Discord](https://discord.umaproject.org/) before voting * UMA tokenholders can use the [Voter dApp](https://vote.umaproject.org/) to vote on protocol decisions Examples of governance proposals include: * Approving new [price identifiers](https://docs.uma.xyz/resources/approved-price-identifiers) and [collateral currencies](https://docs.uma.xyz/resources/approved-collateral-types) * Price requests and disputes * Upgrading the core DVM protocol and / or modify DVM parameters * Registering and de-registering contract templates * Shutting down contract instantiations (in rare circumstances) [PreviousDVM 2.0 FAQ](https://docs.uma.xyz/protocol-overview/dvm-2.0-faq) [NextThe UMIP Process](https://docs.uma.xyz/community/governance/the-umip-process) Last updated 26 days ago Was this helpful? * [Governing the UMA ecosystem](https://docs.uma.xyz/community/governance#governing-the-uma-ecosystem) * [Voting](https://docs.uma.xyz/community/governance#voting) Was this helpful? --- # Optimistic Oracle v3 | UMA Documentation This section showcases different design patterns for building contracts that integrate with the UMA Optimistic Oracle v3. These include: * A [quick start tutorial](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start) showcasing the simplest possible OOv3 integration contract. * Building example contracts: * [Prediction market](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market) * [Insurance contract](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance) * [A generic data assertion framework](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter) * A description of [Escalation Managers](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers) and how they can be used. * Deploying [sandboxed oracle environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment) for testing the dispute flow. [PreviousDefault Proposer Whitelist](https://docs.uma.xyz/developers/managedoptimisticoraclev2/default-proposer-whitelist) [NextASSERT\_TRUTH Deprecation](https://docs.uma.xyz/developers/optimistic-oracle-v3/assert_truth-deprecation) Last updated 1 month ago Was this helpful? Was this helpful? --- # Quick start | UMA Documentation The primary integration point into the UMA ecosystem is the Optimistic Oracle V3 (OOV3). The OOV3 is an _**oracle for arbitrary off-chain data**_ which leverages an interactive escalation game between _asserters_ and _disputers_ and is secured by _economic incentives_. It differs from the Optimistic Oracle V2 (getting started can be found [here](https://docs.uma.xyz/developers/optimistic-oracle/getting-started) ) by being easier to reason about and simpler in integration points. This getting started tutorial will show you how to go from 0 to 1 with the OOV3 by executing the simplest possible assertion flow. Later in the docs you can find more information on how the OOV3 works and dig deeper into its mechanism and more sophisticated code examples. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#a-minimum-viable-oov3-integration) **A minimum viable OOV3 integration** The OOV3 works by making a truth claim about the world, stating that something has happened or is true. Once asserted, the assertion enters a challenge period wherein someone can disagree with the assertion, by disputing it. If no one disputes it during the challenge window the statement is taken as true. If disputed, the outcome is arbitrated using the UMA DVM (more info on how this works here). In this tutorial you will be working through a simple smart contract that asserts the following truth: `Statement: Argentina won the 2022 Fifa world cup in Qatar.` Once through the challenge window, you will use the assertion in your resolution contract. This shows the full non-dispute lifecycle of an OOV3 data assertion. It will give you the basic intuition as to how the Optimistic Asserter works without much overhead and is a great starting point before digging deeper. Let's get started! ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#prerequisites) **Prerequisites** To complete this tutorial you will need**:** 1. Metamask installed in a Chromium based browser (such as [Google Chrome](https://www.google.com/chrome/) ) If you don't have it already, you can get Metamask [here](https://metamask.io/) . 2. A wallet set up in Metamask. 3. [Görli](https://goerli.net/) test ETH to send test transactions. You can get GETH from [Alchemy's faucet](https://goerlifaucet.com/) . ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#asserting-a-truth) Asserting a truth First, we will work through the basic flow for _asserting a truth to the oracle_. In this example, we are making a statement about the outcome of a sports event, but the statement could be much more complex; it could power any kind of smart contract system requiring data. The contract used in this tutorial is meant to be a simple data assertion flow. The contract exposes a simple `assertTruth` function which asserts the truth to the OA about the outcome of the world cup. 1. [Go to this example contract on Remix](https://remix.ethereum.org/#activate=solidity,fileManager&version=soljson-v0.8.16+commit.07a7930e.js&optimize=false&runs=200&gist=17a8a29b2f8ae432e8bac0b88cff8bb1&call=fileManager//open//gist-17a8a29b2f8ae432e8bac0b88cff8bb1/OOV3_GettingStarted.sol) . This gives you the minimum assertion flow. Read the contract and the comments listed within. 2. In the far left hand menu, click the link to deploy and run transactions (which looks like the Ethereum logo and a right arrow). 3. In the "Environment" dropdown, choose "Injected Provider," and connect to your wallet. **Make sure you are connected to Görli within your metamask wallet, that has Görli test ETH!** You don't want to deploy to a real network and spend real gas, and the Görli Optimistic Oracle address hardcoded into the contract will not work on other networks. 4. Under the "Contract" dropdown, select `OOV3_GettingStarted`. 5. Click "Deploy" and confirm the transaction with your wallet. 6. You should now see the `OOV3_GettingStarted` contract under "Deployed Contracts". Clicking the dropdown carrot will reveal buttons for each of the functions in the contract. 7. Click `assertTruth` to request the data specified in the contract's ancillary data, asserting the truth about the outcome of the Fifa world cup. This will submit a data assertion to the Optimistic Asserter and the assertion will enter the challenge period. What we've done in the above steps is: a) deploy a smart contract and b) submit a "data assertion" to the Optimistic Oracle V3 through the call to the Optimistic Oracle V3's `assertTruthWithDefaults` function. Now, the assertion has entered the challenge window and can be disputed by someone who disagrees with the assertion. If you click the `getAssertion` you can see some of the fields that are associated with the assertion. For more details on what these fields mean you can look at the OOV3 interface [here](https://github.com/UMAprotocol/protocol/blob/7a93650a7494eaee83756382a18ecf11314499cf/packages/core/contracts/optimistic-oracle-v3/interfaces/OptimisticOracleV3Interface.sol) . The default liveness for an assertion is 120 seconds (2 minutes). Wait this time before going to the next step. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#settling-the-assertion) Settling the assertion Once the assertion has settled, and assuming no one has disputed it, we can settle it! Do the following: 1. Click `settleAndGetAssertionResult` in remix. This will send a transaction to settle the assertion and return the settlement value. 2. Wait for the transaction to mine. 3. Once mined you can expand the transaction output block inline with the green tick arrow. If you scroll down here you can find some information about the assertion, such as the settlement value (which should be `true` as it was not disputed). ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FwPbkrbi8ELF1vHSIXmIO%252F2023-02-02%2520at%252014.39.21%25402x.png%3Falt%3Dmedia%26token%3D4622c905-8f26-49a0-8adf-ffd1230ec350&width=768&dpr=4&quality=100&sign=5edfca47&sv=2) 1. Now, you can call `getAssertion` and `getAssertionResult` from remix and see the outputs. `getAssertion` has changed such the `settled` value is `true` and `getAssertionResult` now returns `true` as the assertion was deemed valid as it was not disputed. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#next-steps) Next Steps Hopefully you got a basic understanding of the Optimistic Oracle V3 request flow from this getting started guide. Note that this kind of example would not really work on mainnet as: a) there were no bonds for the asserter (and therefore no rewards for disputers) b) the challenge window was too short. The Optimistic Oracle V3 works due to economic incentives between the asserter and disputers, which was absent in this example to keep things simple. For some incentive compatible examples check out some of the example tutorials where we walk through more details on the functions discussed in this guide. Those can be found [here](https://docs.uma.xyz/developers/optimistic-oracle-v3) . [PreviousUsing Blacklisting Tokens as Currency](https://docs.uma.xyz/developers/optimistic-oracle-v3/using-blacklisting-tokens-as-currency) [NextData Asserter](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter) Last updated 7 months ago Was this helpful? * [A minimum viable OOV3 integration](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#a-minimum-viable-oov3-integration) * [Prerequisites](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#prerequisites) * [Asserting a truth](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#asserting-a-truth) * [Settling the assertion](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#settling-the-assertion) * [Next Steps](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start#next-steps) Was this helpful? --- # Polymarket | UMA Documentation #### [](https://docs.uma.xyz/verification-guide/yes_or_no#what-is-the-yes_or_no_query) What is the YES\_OR\_NO\_QUERY? The YES\_OR\_NO\_QUERY (UMIP can be read [here](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-107.md) ) is a price identifier intended for plaintext binary questions. Requesters encode their questions in ancillary data. For a full overview of how ancillary data is formatted, refer [here](https://github.com/UMAprotocol/UMIPs/blob/master/price-identifier-template.md#ancillary-data-specifications) . The YES\_OR\_NO\_QUERY is most typically used by Polymarket today to resolve the outcome of information markets. This can come in the form of asking for the outcome of sports games, a crypto or nft price at a specific point in time or world events among many other things. Note that this price identifier is often in the form of YES or NO, but could also be in the form of THIS or THAT - ie “did the Lakers or Clippers win the game last night” can work even though it is not really a YES or NO question. The example used in the rest of this document will illustrate how this can be done. #### [](https://docs.uma.xyz/verification-guide/yes_or_no#components-of-ancillary-data) Components of Ancillary Data From the UMIP: When converted from bytes to UTF-8, the ancillary data should be a dictionary object containing q (question), p1, p2, p3 and p4 keys and values. p4 is optional and will only apply in certain situations. Example: q: title: French Open Final: Djokovic vs. Ruud, description: This market will resolve to "Djokovic" if Novak Djokovic wins the final, or to "Ruud" if Casper Ruud wins the final. res\_data: p1: 0, p2: 1, p3: 0.5. Where p1 corresponds to Ruud, p2 to Djokovic, p3 to unknown/50-50,initializer:91430cad2d3975766499717fa0d66a78d814e5c5 The UMIP goes on to note default values for p1, p2, p3 and p4. * p1 is usually used for “NO” values and defaults to \`0\` if not explicitly assigned * p2 is used for “YES” values and defaults to \`1\` if not explicitly assigned * p3 is for “UNKNOWN” or “CANNOT BE DETERMINED” and defaults to \`0.5\` if not explicitly assigned. * p4 is for situations where the question is expected to eventually be able to be evaluated, but cannot be at this time. An example would be if the outcome to a sports game was asked for, but the game has not yet happened or finished. This will be referred to as the “magic number” and defaults to the minimum int256 value or before e18 scaling: -57896044618658097711785492504343953926634992332820282019728.792003956564819968 Important Note: Polymarket currently uses OptimisticOracleV2. Therefore, the early request should only be used if a proposed value is proposed earlier than the expected event resolution time noted in ancillary data. For additional context on when the magic number or p3 are expected to be returned, from the UMIP: p4 is intended to be used for situations where it is not a given that the price request (or contract settlement) should even occur yet. An example of this would be the UMA event-based expiry LSP. A request to settle an event-based expiry LSP can be submitted at any time but if the question can not be resolved yet it should be ignored. The default p4 value is the minimum int256 value and is used as a "magic number" to indicate that an event-based expiry request is invalid and the contract should continue as normal. For example, if the question is related to a basketball game on January 6th and a settlement request comes in on January 5th, the question can not be resolved yet, and voters should return the p4 value with the magic number to reject the settlement request. This value also moves the decimal place 18 spaces to the left, due to the default behavior of the UMA voting interface to scale input values to 18 decimals. After scaling by the interface, the value will be -57896044618658097711785492504343953926634992332820282019728792003956564819968 Notice that a p3 value would never be returned earlier than the final price request time noted in the ancillary data or the requesting contract's expiration timestamp and a p4 value would never be returned after that point. Consider an unresolvable question like, "Was the weather nice on January 6th, 2022?" If the question was asked on January 7th, 2022, you would return the p3 value. If the same question was asked on January 5th, 2022, you would return the p4 value. #### [](https://docs.uma.xyz/verification-guide/yes_or_no#scaling-values) Scaling values Also noted in the UMIP is the fact that return values are not scaled when referred to in the UMIP or present in ancillary data. This simply means that if the ancillary data contains “p2:1”, this should really be returned on-chain as 1e18 (not 1 wei). So 1000000000000000000 instead of 1. All price identifier values are treated this way in the UMA system. The UMA voter dapp and Optimistic Oracle proposer interface both perform this scaling automatically for UMA voters or proposers. #### [](https://docs.uma.xyz/verification-guide/yes_or_no#understanding-question-data) Understanding Question Data When verifying a proposal, it is important to assess the question data and arrive at their own conclusion for what the return value should be. Here is the example above in the oracle UI: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh5.googleusercontent.com%2FCvtvs57QTWYnrutclqexZHRvZZXiwn1_mIS8cB8mg87x_mTZ98YJQh2F0E1vxJZd23bB-e0jqyzyvuqCrRfOM1MKEga8MNLFUKTahQ8QQC3ON2UWdlWRceoeyu47_gG0BWreae9KF1OhDdLMb9HKHaU&width=300&dpr=4&quality=100&sign=e6bc9bb9&sv=2) Key data in the proposal is the identifier, timestamp, and the ancillaryData. The YES\_OR\_NO\_QUERY identifier tells us which “pricing methodology” we should be referring to. This is best understood by reading the corresponding UMIP. For all price identifiers, the UMIP can be looked up [here](https://docs.umaproject.org/uma-tokenholders/approved-price-identifiers) by price identifier name. The proposed time tells us the timestamp a value was proposed and therefore should be evaluated. The Additional Text Data above represents the ancillary data and contains the plaintext version of the binary question that a proposer should be evaluating. It is important to read the full text data as it could also contain pricing specifications or data sources that should be used. In the example, I can see that the question is asking if Novak Djokovic or Casper Ruud wins the French Open Final. It does not specify a data source so I can use a wide array of publicly available information to determine what I think the correct answer should be. Referring to ESPN scores: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh5.googleusercontent.com%2FlHC2mPmAO3JmIBQKSa9NHcVK5aWrpKjqYiwUzZUn1QGRULH2Xo6sZ_EgUKj0vcNyTZcofkYKGNP1WTyXUInmOB0ZNUMhQcVzo-TztwR3iwaLsv1znssum3KYrVZo8N_OKA6X5t38ZicXM4EAh8Rz0Ds&width=300&dpr=4&quality=100&sign=e2a770eb&sv=2) I see that Djokovic won and I should continue to read the ancillary data to determine which return value should be used in this scenario. Ancillary data question: This market will resolve to "Djokovic" if Novak Djokovic wins the final, or to "Ruud" if Casper Ruud wins the final. Resolution key: res\_data: p1: 0, p2: 1, p3: 0.5. Where p1 corresponds to Ruud, p2 to Djokovic, p3 to unknown/50-50 Since Djokovic won and p2 corresponds to 1, the proposed value should be p2:1. Voters/proposers should typically evaluate all price requests independent of the party that has requested the data. But as a validation tool, the requestor can sometimes provide information that will help us verify the values that we are about to propose. As an example, this question was from [https://polymarket.com/](https://polymarket.com/) . This is one simple example of evaluating a YES\_OR\_NO\_QUERY, but almost all questions follow the same format. [PreviousVerification System](https://docs.uma.xyz/verification-guide/verification-system) [NextAcross](https://docs.uma.xyz/verification-guide/across) Last updated 8 months ago Was this helpful? Was this helpful? --- # Proposing Oracle Data | UMA Documentation This tutorial describes how to propose answers to data requests. The data could be anything from token prices, to who won a basketball game, to whether an optimistic governance action is valid. **Step 1:** Go to the [Optimistic Oracle dApp](https://oracle.umaproject.org/) , if you are answering requests on a live network like Ethereum, Optimism, or Polygon, or go to the [Testnet dApp](https://testnet.oracle.umaproject.org/) if you are answering requests (probably your own) on Goerli. **Step 2:** Locate requests under the Requests tab for outstanding requests. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FwgzCkFTRyXPwu78Rz0K1%252Fimage.png%3Falt%3Dmedia%26token%3D6607d007-d491-4911-a07c-06c26fb1f0e6&width=768&dpr=4&quality=100&sign=46f8effc&sv=2) **Step 3:** Click on the request you are interested in proposing data for. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FRkoeFgWRmdAb8EC4f9Bk%252Fimage.png%3Falt%3Dmedia%26token%3D975034f8-a01d-4441-8909-190d2ca834bf&width=768&dpr=4&quality=100&sign=b32a4c44&sv=2) **Step 4:** Click the 'Connect wallet' button in the top right corner and go through the steps to connect your wallet. Confirm you are on the same network as the data request. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FG3pIWbXmw21bYSbsdrxO%252Fimage.png%3Falt%3Dmedia%26token%3De090959a-d137-400f-8098-f2cdd98f1469&width=768&dpr=4&quality=100&sign=a7a93fbc&sv=2) **Step 5:** Before proposing, confirm the details of the request and ancillary data to ensure you are proposing accurate data. You may also want to check the instructions in the [UMIP](https://docs.umaproject.org/resources/approved-price-identifiers) for the identifier. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FsUigtCHNFbfT1SMyz0qV%252Fimage.png%3Falt%3Dmedia%26token%3Db31a0b94-894f-4e25-98d2-23c11cf1a1eb&width=768&dpr=4&quality=100&sign=e6aa1964&sv=2) **Step 6:** Once you are sure of the proposed value and connected to your wallet, input the value and click the 'Submit Proposal' button. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F48jV33OFdiYaH57FHLht%252Fimage.png%3Falt%3Dmedia%26token%3D1c79467f-4bd4-4c6b-a3e5-33aed1914be3&width=768&dpr=4&quality=100&sign=febe8356&sv=2) **Step 7:** Confirm the transaction details through your wallet provider. After confirming, the proposal will be sent! [PreviousDiscord Summaries](https://docs.uma.xyz/using-uma/voting-walkthrough/discord-summaries) [NextDisputing Oracle Data](https://docs.uma.xyz/using-uma/disputing-oracle-data) Last updated 5 months ago Was this helpful? Was this helpful? --- # New Network Requests | UMA Documentation The following are the evaluation criteria UMA considers when adding Optimistic Oracle support for a new network. UMA aims to support as many networks as possible to deliver the best experience for our integrating protocols and users. However, integrating a new network requires a significant investment. Therefore, the evaluation criteria were established to ensure that the benefits to UMA's integrating protocols and users outweigh the development, security, and operational costs of adding a new network. Please note that these requirements are subject to change as the EVM (Ethereum Virtual Machine) and Layer 2 ecosystem continue to evolve. Meeting these requirements is the initial step in our evaluation process and does not guarantee support. ### [](https://docs.uma.xyz/resources/network-addresses/new-network-requests#non-negotiable-criteria) Non-Negotiable Criteria: **The below are a pre-requisite to any consideration:** * EVM-Compatible Network a canonical token and message bridge to mainnet * ≥ 2 or more Independent RPC Node Providers (without block range limits for log queries) * 30-Day Moving Average TVL on the network > $75M * Block Explorer with Etherscan-Compatible API, contract verification and ABI fetching * Availability of token mappings data source with Ethereum mainnet * Dedicated support channel containing technical members of the network with priority support commitment to advise on contract development and debug data quality * Subgraph support for testnet and mainnet * Wallet connector libraries support for testnet and mainnet ### [](https://docs.uma.xyz/resources/network-addresses/new-network-requests#get-in-touch-with-uma) Get in Touch with UMA * Drop a message in the [UMA Discord Server](https://discord.com/invite/jsb9XQJ) * Send an email to [\[email protected\]](https://docs.uma.xyz/cdn-cgi/l/email-protection) [PreviousNetwork Information](https://docs.uma.xyz/resources/network-addresses) [NextAudit & Bug Bounty Programs](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs) Last updated 1 month ago Was this helpful? * [Non-Negotiable Criteria:](https://docs.uma.xyz/resources/network-addresses/new-network-requests#non-negotiable-criteria) * [Get in Touch with UMA](https://docs.uma.xyz/resources/network-addresses/new-network-requests#get-in-touch-with-uma) Was this helpful? --- # Voting Walkthrough | UMA Documentation This tutorial describes how to vote using the [UMA voter dApp](https://vote.uma.xyz/) . For context, each voting period is 48hrs. Voting takes 3 steps: * Commit Vote: the first 24hrs of a voting period allows you to encrypt and commit your vote * Reveal vote: the second 24hrs of a voting period allows you to decrypt and reveal your vote. Votes are tallied by a DVM smart contract at the end of the reveal period. * Claim rewards: staking rewards are constantly accrued. You can claim + restake or just claim them to your wallet whenever you like. The purpose behind using the [Commit/Reveal scheme](https://www.gitcoin.co/blog/commit-reveal-scheme-on-ethereum) is that it allows votes to remain private. ### [](https://docs.uma.xyz/using-uma/voting-walkthrough#instructions) Instructions: 1. Go to [http://vote.uma.xyz](http://vote.uma.xyz/) . 2. Connect your wallet. 3. In order to vote, you must stake your tokens. Click "Stake/Unstake" then follow the instructions in the module. Staking your tokens does three things: * Your tokens will immediately start to earn a prorated portion of the $UMA token emissions, which is reflected as an APY on the dapp. * You will be able to vote with those tokens * You will have a 7-day cooldown period in order to unstake those tokens. During that period, your tokens will not be earning any rewards or be eligible for voting. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FAfTELLrL3j1TlgddUWQQ%252Fimage.png%3Falt%3Dmedia%26token%3D4a4277ba-91b2-441d-bab4-dfea03b682eb&width=768&dpr=4&quality=100&sign=d55e3eb4&sv=2) Indicate that you understand the cooldown period, approve, then stake your $UMA 1. You can only vote when there is a live vote(s), and during the **Commit period.** 2. Choose your vote(s) from the dropdown menu, then click "Commit vote" and send the transaction. 3. Each voting round consists of a 24-hour commit period, followed by a 24-hour reveal period. **In order for your vote(s) to count, you need to return and reveal your vote(s) during the reveal period.** 4. During the reveal period, return to the Dapp and choose "Reveal" to reveal your vote(s). Once the dapp shows your vote as "Revealed," you are done with the voting process. The vote(s) will be finalized when the reveal period ends, at which point you will be able to see if you voted correctly. If you did, you will receive a bonus. If you voted inaccurately or failed to vote, you will have a penalty applied to your stake. This penalty amount is redistributed to accurate voters. **Protocol Parameters (adjustable by governance)** Emissions: .18 $UMA/second Missed vote penalty: 0.1% of staked balance Withdraw cooldown period: 7 days ### [](https://docs.uma.xyz/using-uma/voting-walkthrough#claim-rewards) Claim rewards Emission rewards begin to accrue automatically when you stake $UMA. You may claim these rewards to your wallet, or claim-and-stake to your staked balance. Rewards associated with voting successfully are automatically added to your staked balance after the voting period ends. [PreviousDAO Proposals](https://docs.uma.xyz/community/governance/dao-proposals) [NextVoter Guide](https://docs.uma.xyz/using-uma/voting-walkthrough/voter-guide) Last updated 5 months ago Was this helpful? * [Instructions:](https://docs.uma.xyz/using-uma/voting-walkthrough#instructions) * [Claim rewards](https://docs.uma.xyz/using-uma/voting-walkthrough#claim-rewards) Was this helpful? --- # Unsupported Contracts | UMA Documentation Risk Labs/UMA protocol no longer actively supports or improves: * The [Expiring Multi-Party (EMP)](https://github.com/UMAprotocol/launch-emp) * The [Perpetual Multi-Party](https://github.com/UMAprotocol/protocol/tree/master/packages/core/contracts/financial-templates/perpetual-multiparty) These contracts are open-source code, and anyone is free to use, improve, or fork the code. However note that for these contracts to be safe, it requires a robust system of well capitalized off-chain watchers (liquidator & disputer bots) to continually check that positions are appropriately collateralized, or that positions are not being liquidated unfairly. Anyone using this code in production must ensure that there are well-capitalized liquidators and disputers running at all times; failure to do so could result in a loss of all locked funds. Risk Labs does not and will not run liquidators for these contracts, nor does it give any security assurances about any EMP or Perp contracts. As always, UMA protocol and Risk Labs will continue to support proposed addition or request of price identifiers for general use including within EMP/Perp contracts. [PreviousVoting with a 2-Key Contract](https://docs.uma.xyz/resources/voting-with-a-2-key-contract) [NextoSnap (Deprecated)](https://docs.uma.xyz/resources/osnap) Last updated 1 year ago Was this helpful? Was this helpful? --- # Approved Price Identifiers | UMA Documentation This table includes identifiers that could be useful for new contracts and are likely to be encountered by proposers, disputers, and voters. It does not include identifiers that have been deprecated, identifiers that have fallen out of use, or specific token pairs. If you need an identifier that is not included in this list, you can [submit a new UMIP](https://docs.umaproject.org/community/governance/the-umip-process) for approval. If a price request is made with an identifier that is not on this table, please refer to the canonical [UMIP directory](https://github.com/UMAprotocol/UMIPs/tree/master/UMIPs) on GitHub. The absence of an identifier from this table does _not_ necessarily mean the identifier is not approved, it just means it is not recommended for new contracts. If you want to use an approved identifier that is not on this list, let us know and we can add the identifier back to this table for easier voter/disputer reference. ACROSS-V2 Verification of whether a bundle of Across bridge transactions submitted to mainnet is valid. [UMIP-179](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-179.md) ASSERT\_TRUTH (DEPRECATED as of Dec 15, 2025) Former default price identifier for Optimistic Oracle V3 [UMIP-170](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-170.md) ASSERT\_TRUTH2 (as of Dec 8, 2025) New intended default price identifier for Optimistic Oracle V3 [UMIP-191](https://github.com/UMAprotocol/UMIPs/pull/629/files) MULTIPLE\_CHOICE\_QUERY Allows requests with a predefined set of valid responses. [UMIP-181](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-181.md) NUMERICAL Returns a number value based on a question asked in the ancillary data. [UMIP-165](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-165.md) ROPU\_ETHx Reflects violations of the MEV-policy committed by validators of the ETHx staking protocol [UMIP-177](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-177.md) YES\_OR\_NO\_QUERY Returns an answer to a "yes or no" question. [UMIP-107](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-107.md) [PreviousAudit & Bug Bounty Programs](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs) [NextApproved Collateral Types](https://docs.uma.xyz/resources/approved-collateral-types) Last updated 1 month ago Was this helpful? Was this helpful? --- # Disabling oSnap | UMA Documentation Requirements: * The below steps propose a Safe transaction to disable oSnap. Transactions can only be proposed to a Safe by that Safe's Signers or Proposers. You can view these roles on your Safe's settings page. * Executing the proposed Safe transaction requires your minimum number of Signers to sign the transaction and one Signer to execute the transaction. Steps: 1. Connect a Snapshot space admin wallet and navigate to your Snapshot space Settings page. If you do not have an admin wallet connected, you can also access this page by pasting in this URL with your DAO's ENS inserted: https://snapshot.box/#/.eth/settings/execution 2. Click "Execution" on the left side menu and the pencil icon inside the "oSnap by UMA" box to show oSnap enabled Treasuries. 3. If your space has oSnap configured, Treasuries will display below the "oSnap by UMA" box with their status displayed as "Active". ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FvPJXqIyXHtA1vcw9ri2Q%252Fimage.png%3Falt%3Dmedia%26token%3Dc0c6984b-4da8-448d-b85c-1ddffd6ce22e&width=768&dpr=4&quality=100&sign=6f8cf19&sv=2) 1. To disable oSnap on a active oSnap treasury, hover over "Active", to show the "Disable" button and click it to open the oSnap Safe app. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252Fa3LJbt2ejTBguCmwS1CT%252Fimage.png%3Falt%3Dmedia%26token%3D93145763-83c2-46e4-8133-a2e032bb9b9a&width=768&dpr=4&quality=100&sign=6dd41afe&sv=2) 1. Opening up the oSnap Safe app may bring up the following Safe warnings depending on your browser's stored cookies: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F2aS6Ic1bcYleAPR73y0v%252Fimage.png%3Falt%3Dmedia%26token%3D5eaec03a-36ce-490f-9ada-213d6b14f7cb&width=768&dpr=4&quality=100&sign=cc71d8bc&sv=2) ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FyRJLdtJsxV6rpVCdKALY%252Fimage.png%3Falt%3Dmedia%26token%3Dfbcff8b5-79c8-40c2-b01c-554e46d1497e&width=768&dpr=4&quality=100&sign=a82cc456&sv=2) 1. In the oSnap Safe app, click "Deactive oSnap" ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FPVVpKbUzYwMKPJBst2DG%252Fimage.png%3Falt%3Dmedia%26token%3D799bccc4-7d45-4d1a-8868-eff8ca0a7af0&width=768&dpr=4&quality=100&sign=ca99ee95&sv=2) 1. This will propose a "disableModule" transaction in the Safe(Wallet) dapp. This transaction can be proposed, reviewed, signed, and executed as per the typical Safe(Wallet) transaction flow. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FwdUhRYfqEXQLufjiWeih%252Fimage.png%3Falt%3Dmedia%26token%3Da53656f4-8f69-4a8b-a3cd-f3dffe666ec5&width=768&dpr=4&quality=100&sign=9397c9ca&sv=2) 1. After this transaction is executed, oSnap is disabled from your Safe treasury. Treasuries without oSnap enabled will display with an "Enable" button in Snapshot's Execution settings page (note, it may take some time after the executed transaction for the Snapshot UI to update). ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252Feysf6QrXRKZzME6YMnfs%252Fimage.png%3Falt%3Dmedia%26token%3D574a23bb-8fb4-4dde-a297-10a1983a0f56&width=768&dpr=4&quality=100&sign=17026656&sv=2) [PreviousoSnap (Deprecated)](https://docs.uma.xyz/resources/osnap) [NextoSnap Proposal Verification](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification) Last updated 20 days ago Was this helpful? Was this helpful? --- # Glossary | UMA Documentation #### [](https://docs.uma.xyz/resources/glossary#optimistic-oracle) Optimistic Oracle The "Optimistic Oracle" (OO) allows contracts to quickly request and receive price information. Unlike mechanically restrictive price feed oracles, an optimistic oracle can serve any arbitrary data on-chain. #### [](https://docs.uma.xyz/resources/glossary#dvm) DVM The “Data Verification Mechanism” (DVM) is the name of the oracle service provided by UMA. The DVM does not provide an on-chain price feed. Instead, it is only used to resolve disputes of liquidations and to settle synthetic token contracts upon expiration. ### [](https://docs.uma.xyz/resources/glossary#parameters-of-a-long-short-pair-lsp-smart-contract) Parameters of a Long Short Pair (LSP) smart contract: #### [](https://docs.uma.xyz/resources/glossary#financial-product-library-fpl) Financial Product Library (FPL) The financial product libraries are used to transform the value returned by the price identifier into a final settlement value. Financial product libraries can be applied to create different types of financial contracts and payout functions. Refer to [github](https://github.com/UMAprotocol/protocol/tree/master/packages/core/networks) for a list of deployed financial product libraries for each network. If your desired financial product library is not already deployed, refer [here](https://github.com/UMAprotocol/launch-emp#deploying-financial-product-libraries) for instructions on deploying and verifying your own financial product library contract. #### [](https://docs.uma.xyz/resources/glossary#collateralperpair) collateralPerPair The collateralPerPair parameter determines the amount of collateral required to mint each pair of long and short tokens. * Example: If a contract uses WETH as collateral and the collateralPerPair parameter is set to 0.25 on deployment, each long and short token that is minted would require 0.25 WETH as collateral. #### [](https://docs.uma.xyz/resources/glossary#expirypercentlong) expiryPercentLong ExpiryPercentLong is used to determine the redemption rate between long and short tokens. ExpiryPercentLong is a number between 0 and 1, where 0 assigns all collateral to the short tokens and 1 assigns all collateral to the long tokens. ### [](https://docs.uma.xyz/resources/glossary#uma-product-types) UMA Product Types: #### [](https://docs.uma.xyz/resources/glossary#range-tokens) Range Tokens Range tokens enable a DAO to use its native token as collateral to borrow funds. At maturity, if the debt is not paid, the range token holder is instead compensated with an amount of the collateral (the native token) using the settlement price of the native token to determine the number of tokens. This is similar to a tokenized convertible debt structure. #### [](https://docs.uma.xyz/resources/glossary#success-tokens) Success Tokens Success tokens offer an alternative way for DAOs to diversify their treasury and sell tokens to investors in an incentive-aligned way. Success tokens are two financial products wrapped into one token: a set amount of a project token which is combined with a covered call option on that token backed by a set amount of the same token. #### [](https://docs.uma.xyz/resources/glossary#kpi-options) KPI Options Key Performance Indicator (KPI) Options are synthetic tokens that will pay out more rewards if a project’s KPI reaches predetermined targets before a given expiry date. Every KPI Option holder has an incentive to improve that KPI because their option will be worth more. This is intended to align individual token holder interests with the collective interests of the protocol. [PreviousAdditional Resources](https://docs.uma.xyz/resources/additional-resources) [NextLinks](https://docs.uma.xyz/resources/links) Last updated 1 year ago Was this helpful? * [Parameters of a Long Short Pair (LSP) smart contract:](https://docs.uma.xyz/resources/glossary#parameters-of-a-long-short-pair-lsp-smart-contract) * [UMA Product Types:](https://docs.uma.xyz/resources/glossary#uma-product-types) Was this helpful? --- # Sandboxed Oracle Environment | UMA Documentation Whenever the assertion is disputed on a production network this triggers DVM request to be resolved by UMA voters. This might be impractical to fully simulate this in a testing environment, hence, developers can use [mocked oracle contract](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/test/MockOracleAncillary.sol) to resolve requests as they had been returned by DVM. Interacting with Optimistic Oracle requires having whitelisted price identifier and bonding currency. In production networks these are approved by UMA token holders as part of governance voting. When testing, it might be easier for developers to use their own set of UMA ecosystem contracts where they have full control over such whitelisting process. Follow the written tutorial below or check out the video tutorial on [Youtube](https://www.youtube.com/watch?v=1sW8vcqTRCE) . ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#deploying-sandboxed-oracle-environment) Deploying sandboxed Oracle environment A set of sandboxed UMA ecosystem contracts can be deployed using forge script from [Optimistic Oracle V3 developers quick-start repository](https://github.com/UMAprotocol/dev-quickstart-oov3) . After cloning the repository make sure you have the latest Foundry version by running `foundryup` command (see more installation details on [Foundry book](https://book.getfoundry.sh/getting-started/installation.html) ). From the root of the repository install dependencies with: Copy forge install All script parameters are controlled through environment variables that should be exported before running the script: * `ETH_RPC_URL`: URL of the RPC node to use for broadcasting deployment transactions on the desired test network. * `MNEMONIC`: Mnemonic of the account to use for deployment (derived account with 0 index will be used by default). * `ETHERSCAN_API_KEY`: API key for Etherscan, used for verifying deployed contracts. * `DEFAULT_IDENTIFIER`: Default identifier used by Optimistic Oracle V3 when resolving disputes. If not provided, this defaults to `ASSERT_TRUTH` identifier. The script will also whitelist this identifier. * `DEFAULT_LIVENESS`: Default liveness in seconds used by Optimistic Oracle V3 when settling assertions. If not provided, this defaults to `7200` seconds. * `DEFAULT_CURRENCY`: Default currency used by Optimistic Oracle V3 when bonding assertions and disputes. The script will also whitelist this currency. If not provided, the script would also deploy a [mintable ERC20 token](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/common/implementation/TestnetERC20.sol) and use it as the default currency based on following parameters: * `DEFAULT_CURRENCY_NAME`: Name of the new token. If not provided, this defaults to `Default Bond Token`. * `DEFAULT_CURRENCY_SYMBOL`: Symbol of the new token. If not provided, this defaults to `DBT`. * `DEFAULT_CURRENCY_DECIMALS`: Number of decimals of the new token. If not provided, this defaults to `18`. * `MINIMUM_BOND`: Minimum bond amount in Wei of default currency required by Optimistic Oracle V3 when accepting new assertions. If not provided, this defaults to `100e18` Wei. Once all required environment variables are setup, deploy and verify the set of sandboxed UMA ecosystem contracts with: At the top of the script output the addresses of the deployed contracts should be logged: * `Finder`: Used to locate other UMA ecosystem contract addresses. Deployment script will have added new `Store`, `AddressWhitelist`, `IdentifierWhitelist`, `MockOracleAncillary` and `OptimisticOracleV3` implementations. * `Store`: Stores final fees of bonding currencies. The script will have set the final fee of default currency to half of provided minimum bond amount since Optimistic Oracle V3 calculates minimum bond twice the value of this final fee. * `AddressWhitelist`: Stores approved currency addresses that can be used for bonding assertions and disputes. The script will have already whitelisted the default currency. * `IdentifierWhitelist`: Stores approved identifiers that can be used to resolve disputes at DVM. The script will have already whitelisted the default identifier. * `MockOracleAncillary`: Optimistic Oracle will use this contract to resolve disputes equivalent to DVM voting on mainnet. Once requested, anyone can push desired test price through this mock oracle contract. * `TestnetERC20`: Unless existing default currency was provided the script will have deployed this new token that is whitelisted as a bonding currency. Anyone can mint new tokens by calling its `allocateTo(address ownerAddress, uint256 value)` method. * `OptimisticOracleV3`: Optimistic Oracle that resolves assertions made by integrating contracts. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#resolving-dispute-requests) Resolving dispute requests Whenever the assertion is disputed, Optimistic Oracle V3 calls `requestPrice` method on the Oracle that triggers DVM vote on mainnet. In the sandboxed environment this would resolve to `MockOracleAncillary` contract instead. The disputed request is uniquely identified by its identifier, timestamp and ancillary data that should be referenced by the testing developer pushing resolved price to the mocked oracle. The `MockOracleAncillary` contract will emit `PriceRequestAdded` event with following parameters: * `address indexed requester`: Address of the calling contract (Optimistic Oracle V3 in the sandboxed setup). * `bytes32 indexed identifier`: Identifier referencing the rules on how the request should be resolved. By default Optimistic Oracle V3 uses `ASSERT_TRUTH` identifier unless the integrating contract provided other value. * `uint256 time`: Optimistic Oracle V3 will set this to timestamp when the original assertion was made. * `bytes ancillaryData`: Optimistic Oracle V3 will put the `assertionId` and address of the asserter referencing the disputed assertion. * `bytes32 indexed requestId`: This is hashed value of identifier, time and ancillary data provided by the `MockOracleAncillary` contract just as convenient method to resolve request by one parameter instead of three separate parameters. Note that production voting contract on mainnet emits this differently and above `PriceRequestAdded` is provided only as a convenience for developers when interacting with the `MockOracleAncillary` contract in their testing environment. `MockOracleAncillary` contract provides two alternative methods for testing developers to resolve request: * `pushPrice(bytes32 identifier, uint256 time, bytes memory ancillaryData, int256 price)` where request is referenced by its individual parameters. * `pushPriceByRequestId(bytes32 requestId, int256 price)` where request is referenced by the hashed value of its identifying parameters. While testing developer can pass any `int256` price value, Optimistic Oracle V3 can only interpret value of `1e18` to represent truthful assertion. Any other value would settle assertion as being false. Also note that `MockOracleAncillary` contract will only accept the first pushed price to resolve a given request. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#example-dispute-flow) Example dispute flow As an illustration to the section above this example walks through resolving disputed assertion with `cast` tool from Foundry. This also requires `jq` being installed for parsing returned values. Just for the sake of simplicity set `MINIMUM_BOND` environment variable to `0` when running `forge script` command as discussed in the [sandbox deployment section](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#deploying-sandboxed-oracle-environment) . This would allow to skip minting and approving assertion/dispute bonds. Take a note of deployed contracts log and export Optimistic Oracle V3 address to `OOV3_ADDRESS` and `MockOracleAncillary` address to `MOCK_ORACLE_ADDRESS` environment variables. Also to keep this simple perform all steps from the same address: Start with generating test assertion and grab the resulting `assertionId` emitted by Optimistic Oracle V3 (corresponds to topic index `1` in the `AssertionMade` event): Dispute the above assertion and grab the resulting `requestId` emitted by `MockOracleAncillary` (corresponds to topic index `3` in the `PriceRequestAdded` event): Now resolve the disputed assertion as truthful by pushing `1e18` as price to `MockOracleAncillary` contract: This allows us to settle the assertion at Optimistic Oracle V3: Finally, you can verify that Optimistic Oracle V3 has correctly settled the assertion (this should return `true`): ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#further-sandbox-configuration) Further sandbox configuration The deployment script documented in the [section above](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#deploying-sandboxed-oracle-environment) covers most common use cases and should be sufficient to test example contracts from the [Optimistic Oracle V3 integration quickstart repository](https://github.com/UMAprotocol/dev-quickstart-oov3) . Though, when developing your own integrating contracts it might be required to further configure the sandboxed oracle environment. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#whitelisting-of-bonding-currencies) Whitelisting of bonding currencies In case the integrating contract requires handling assertion bonds in multiple currencies all of them should be approved at the `AddressWhitelist` contract. On production this should go through UMA governance while in the sandboxed environment the deployer owns this contract and can call `addToWhitelist` method directly. Assuming the address of `AddressWhitelist` contract is exported to `ADDRESS_WHITELIST` and required bonding currency is exported to `BONDING_CURRENCY` environment variables, this can be done by: In order to test the scenario on how the integrating contracts would behave if UMA governance removed support for a particular bonding currency, you can test this by calling `removeFromWhitelist` method on the `AddressWhitelist` contract: Note that Optimistic Oracle V3 is caching whitelisted bonding currencies. Hence, before testing impact on the integrating contracts somebody should sync the contract cache (anyone has authority to do this): #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#changing-the-final-fee) Changing the final fee In case the UMA governance was to change the configured final fee for a particular bonding currency this would also change the minimum assertion bond required by Optimistic Oracle V3. In order to test such impact on integrating contracts in the testing environment, the deployer would need to call `setFinalFee` on the `Store` contract (exported as `STORE_ADDRESS`). E.g. to set final fee to `1000e18`, you would call: Again, before testing impact on integrating contracts someone would need to sync new final fee at the Optimistic Oracle V3: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#whitelisting-of-identifiers) Whitelisting of identifiers If the integrating contract plans to make assertions with multiple identifiers, the developer would need to add them to `IdentifierWhitelist` contract (exported as `IDENTIFIER_ADDRESS`) in the sandboxed environment, e.g. adding `CUSTOM_IDENTIFIER`: In order to test the scenario on how the integrating contracts would behave if UMA governance removed support for a particular identifier, you can test this by calling `removeSupportedIdentifier` method on the `IdentifierWhitelist` contract: Note that Optimistic Oracle V3 is caching whitelisted identifiers. Hence, before testing impact on the integrating contracts somebody should sync the contract cache (anyone has authority to do this): [PreviousEscalation Managers](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers) [NextSetting Custom Bond and Liveness Parameters](https://docs.uma.xyz/developers/setting-custom-bond-and-liveness-parameters) Last updated 1 year ago Was this helpful? * [Deploying sandboxed Oracle environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#deploying-sandboxed-oracle-environment) * [Resolving dispute requests](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#resolving-dispute-requests) * [Example dispute flow](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#example-dispute-flow) * [Further sandbox configuration](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment#further-sandbox-configuration) Was this helpful? Copy forge script \ --broadcast \ --fork-url $ETH_RPC_URL \ --mnemonics "$MNEMONIC" \ --sender $(cast wallet address --mnemonic "$MNEMONIC") \ --verify \ script/OracleSandbox.s.sol Copy export USER_ADDRESS=$(cast wallet address --mnemonic "$MNEMONIC") Copy export ASSERTION_TX=$(cast send --mnemonic "$MNEMONIC" --json $OOV3_ADDRESS "assertTruthWithDefaults(bytes,address)" $(cast --from-utf8 "test claim") $USER_ADDRESS | jq -r '.transactionHash') export ASSERTION_ID=$(cast receipt --json $ASSERTION_TX | jq -r --arg OOV3_LOWERCASE $(echo $OOV3_ADDRESS | tr [:upper:] [:lower:]) '.logs[] | select(.address==$OOV3_LOWERCASE).topics[1]') Copy export DISPUTE_TX=$(cast send --mnemonic "$MNEMONIC" --json $OOV3_ADDRESS "disputeAssertion(bytes32,address)" $ASSERTION_ID $USER_ADDRESS | jq -r '.transactionHash') export REQUEST_ID=$(cast receipt --json $DISPUTE_TX | jq -r --arg MOCK_LOWERCASE $(echo $MOCK_ORACLE_ADDRESS | tr [:upper:] [:lower:]) '.logs[] | select(.address==$MOCK_LOWERCASE).topics[3]') Copy cast send --mnemonic "$MNEMONIC" $MOCK_ORACLE_ADDRESS "pushPriceByRequestId(bytes32,int256)" $REQUEST_ID $(cast --to-wei 1) Copy cast send --mnemonic "$MNEMONIC" $OOV3_ADDRESS "settleAssertion(bytes32)" $ASSERTION_ID Copy cast call $OOV3_ADDRESS "getAssertionResult(bytes32)(bool)" $ASSERTION_ID Copy cast send --mnemonic "$MNEMONIC" $ADDRESS_WHITELIST "addToWhitelist(address)" $BONDING_CURRENCY Copy cast send --mnemonic "$MNEMONIC" $ADDRESS_WHITELIST "removeFromWhitelist(address)" $BONDING_CURRENCY Copy cast send --mnemonic "$MNEMONIC" $OOV3_ADDRESS "syncUmaParams(bytes32,address)" $(cast --format-bytes32-string "") $BONDING_CURRENCY Copy cast send --mnemonic "$MNEMONIC" $STORE_ADDRESS "setFinalFee(address,(uint256))" $BONDING_CURRENCY "($(cast --to-wei 1000))" Copy cast send --mnemonic "$MNEMONIC" $OOV3_ADDRESS "syncUmaParams(bytes32,address)" $(cast --format-bytes32-string "") $BONDING_CURRENCY Copy cast send --mnemonic "$MNEMONIC" $IDENTIFIER_ADDRESS "addSupportedIdentifier(bytes32)" $(cast --format-bytes32-string "CUSTOM_IDENTIFIER") Copy cast send --mnemonic "$MNEMONIC" $IDENTIFIER_ADDRESS "removeSupportedIdentifier(bytes32)" $(cast --format-bytes32-string "CUSTOM_IDENTIFIER") Copy cast send --mnemonic "$MNEMONIC" $OOV3_ADDRESS "syncUmaParams(bytes32,address)" $(cast --format-bytes32-string "CUSTOM_IDENTIFIER") 0x0000000000000000000000000000000000000000 --- # Additional Resources | UMA Documentation **Internal Learning Sessions** * [Validating an Across v2 Dispute](https://www.youtube.com/watch?v=OjwzNlCwUsY&ab_channel=UMAProtocol) * [Across v2 Architecture](https://www.youtube.com/watch?v=iuxf6Crv8MI&ab_channel=UMAProtocol) * [Optimistic Distributor](https://www.youtube.com/watch?v=-N8UNHDxzYg&ab_channel=UMAProtocol) * [L2 Bridge Architecture](https://www.youtube.com/watch?v=G6tIiJUXIMg&ab_channel=UMAProtocol) * [How to use Storybook](https://www.youtube.com/watch?v=sS_FT-2_u-8&ab_channel=UMAProtocol) * [LM 2.0](https://www.youtube.com/watch?v=I8wDrvms_BI&ab_channel=UMAProtocol) * [Protected Tokens](https://www.youtube.com/watch?v=3h5SJVXw9pA&ab_channel=UMAProtocol) * [KPI Options 2.0](https://www.youtube.com/watch?v=cnIfqOvWpZ4&ab_channel=UMAProtocol) * [Optimistic Governance](https://www.youtube.com/watch?v=ohIHd1Ll-1U&ab_channel=UMAProtocol) * [Introduction to using UMA's Optimistic Oracle](https://www.youtube.com/watch?v=GhMfzKvA9Qk&ab_channel=UMAProtocol) * [Introduction to Merkle Roots](https://www.youtube.com/watch?v=JXn4GqyS7Gg&t=1s&ab_channel=UMAProtocol) * [UMA Call Options](https://www.youtube.com/watch?v=3wQUnTHl8jw&ab_channel=UMAProtocol) * [Introduction to the LSP](https://www.youtube.com/watch?v=KNKSNKdUVl4&t=2407s&ab_channel=UMAProtocol) * [Range Tokens](https://www.youtube.com/watch?v=l3WsUsRjzBk&ab_channel=UMAProtocol) [PreviousoSnap Proposal Verification](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification) [NextGlossary](https://docs.uma.xyz/resources/glossary) Last updated 1 year ago Was this helpful? Was this helpful? --- # Links | UMA Documentation #### [](https://docs.uma.xyz/resources/links#links) Links You can keep up to date with what is happening with UMA across our various social media platforms and community resources: * [Discord](https://discord.umaproject.org/) * [Twitter](https://twitter.com/UMAprotocol) * [Discourse](https://discourse.umaproject.org/) * [Medium](https://medium.com/uma-project) * [YouTube](https://www.youtube.com/channel/UC-3qS7FXxCd7gBMLttmTirw/playlists) * [UMAverse](https://projects.umaproject.org/) * [UMA Protocol Calendar](http://calendar.umaproject.org/) * [UMA Press Kit](https://github.com/UMAprotocol/website/tree/master/documents/press-kit) #### [](https://docs.uma.xyz/resources/links#employment-at-uma) Employment at UMA If you are interested in working at UMA, please see our vacancies below. If you know someone that might be a good fit, check out our “talent referral options” program that offers up to 1000 $UMA to anyone who refers suitably qualified candidates for any of our open positions. * [Risk Labs Job Postings](https://jobs.lever.co/risklabs) * ["Talent Referral Options" Program](https://medium.com/uma-project/talent-referral-options-program-170bc347542a) [PreviousGlossary](https://docs.uma.xyz/resources/glossary) Last updated 8 months ago Was this helpful? Was this helpful? --- # oSnap | UMA Documentation #### [](https://docs.uma.xyz/verification-guide/osnap#what-is-the-assert_truth-identifier) What is the ASSERT\_TRUTH identifier? oSnap uses the `ASSERT_TRUTH` identifier can be found [here](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-170.md) . `ASSERT_TRUTH` is intended to be used as a default price identifier for UMA's [Optimistic Oracle V3 contract](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol) that allows asserters to make claims about the state of the world. Price settlement can happen only in one of two ways: * Return the 1 value if the claim is true. * Return the 0 value if the claim is false or cannot be resolved. **Part 1: Snapshot Proposal Created** When a Snapshot proposal is created, a Discord ticket is created with a Tenderly simulation of the transaction payload. Here is an example: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FMFBN4aoDRiq565knXu9I%252Fimage.png%3Falt%3Dmedia%26token%3D402242b8-bbcc-4b87-a0f7-f7fed3df18a0&width=768&dpr=4&quality=100&sign=41b767ee&sv=2) The main objective of verifying the Snapshot proposal before voting is to ensure: * The transaction payload can be executed * Comparing the intent of the proposal against the transaction payload * The transaction payload doesn't have any unintended consequences or malicious intent In the Tenderly simulation, if the `Status` value is not `Success`, that is an indicator the transaction payload is unable to be executed and requires further review. The input shows the transactions array that will be executed if the Snapshot proposal passes: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FVMb7VbFO27pq3KO0tGIf%252Fimage.png%3Falt%3Dmedia%26token%3D9c0c6855-669f-4729-b006-3210ce4449b3&width=768&dpr=4&quality=100&sign=2453bf35&sv=2) **Verifying the transaction data** 1. Go to [https://lab.miguelmota.com/ethereum-input-data-decoder/example/](https://lab.miguelmota.com/ethereum-input-data-decoder/example/) . 2. Input the contract ABI into the ABI section 1. Take the ‘to’ value from the transaction object and input it into etherscan (or the block explorer based on the chainID. For etherscan, you would go to [https://etherscan.io/address/{to](https://etherscan.io/address/%7Bto) }. 2. Click the ‘contract’ tab 3. Scroll down to the ‘Contract ABI’ section and copy everything 4. Paste it into the ABI section Here is what the example would look like: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh6.googleusercontent.com%2FX6YmY3KqrdHNzD7PO3dvNWOSFl374VguSZsXs0xZv_-L9npKaa7AcxgrzzUwXQveeJzyeILCIdX2f1FPvyhOIHlMkIfncnZStgrTe-lF85PU2woo3XfH3taxibvPDrh0HHL4pgBJK8ctGUOyZOd7MRg&width=300&dpr=4&quality=100&sign=d89994f9&sv=2) The ‘Output’ for a Transfer should look as the below: Verify the following: * For any BigNumber values, go to [https://playground.ethers.org/](https://playground.ethers.org/) and input `BigNumber.from("{INPUT_VALUE}").toString()`. For example, `BigNumber.from("0x14adf4b7320334b9000000").toString()` would be `25000000000000000000000000`. To scale this value, go to the token contract address and check decimals. For the ACX token, the decimals are 18 so the scaled value is `25000000`. You can use [https://eth-converter.com/](https://eth-converter.com/) if the decimals are 18. * Confirm that the above value is mentioned in the actual Snapshot proposal. * Search for the token in coingecko.com with the token address and confirm there is liquidity. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh4.googleusercontent.com%2FXQTD64G3zp1doTkN_-u_pmsuIEHsV-f6ODkyvXLvJD7veH2Q85S4FEYAQFnZwW00PcjzEFFITi0E4plYWownM2iqxM2V_NHct720eOqfSE_4Cksj5dxFfJ_i353cm0eL8zhGCkDG2HHaW0u8YKAQCsE&width=300&dpr=4&quality=100&sign=cbde221f&sv=2) **Part 2: oSnap Transactions Proposed** After a Snapshot proposal is completed, if the proposal is valid the transactions are proposed which creates another Discord ticket. [Here](https://discord.com/channels/718590743446290492/1133220903728189460) is an example thread in the UMA Discord. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh4.googleusercontent.com%2Fp4P55O8VFf_1HLBZCG50Vrrj-78M92Uz4y1KtGMjgKtvO8WaFEdmIgh9Sdh5MZkzOdSd0wiZRMJ5BlDwu9Kvd9IJ6g2SjWyLwUr4KK2R5m_cjtX2Qotft0i-B-CxCT1_E5psYixzpEHnY-OIMD4XsM8&width=300&dpr=4&quality=100&sign=1548897a&sv=2) The first objective is to verify the oSnap rules against Snapshot Proposal. Click the Snapshot space URL, in the above example that is [https://snapshot.org/#/acrossprotocol.eth](https://snapshot.org/#/acrossprotocol.eth) . Go through the list of proposals and confirm the explanation from the Discord message matches the Snapshot space. Validators should do the following to verify the oSnap proposal: * Check the Snapshot space referenced in the rules string. * Check that the IPFS hash passed as the explanation lines up with an actual vote in that Snapshot space. They should be able to cross-reference the value with a link from a specific Snapshot proposal. * Check the Snapshot proposal tied to the IPFS explanation value met the minimum voting period and quorum. * Check that the Snapshot proposal passed according to the Snapshot strategy. **Compare Snapshot IPFS Transaction data against Proposed Transactions** 1. Go to the Snapshot proposal and click the ‘View Details’ link in the Transactions container: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh3.googleusercontent.com%2Fd7Pzv8pFjEhTtBKVHjhr12HL8ZhJ034va1Z03jEip7UAYYlKxwNKLKEeFTaKfHONDxnMnHDdCrVFwLk71nsP901VvEjiDP99Ms2Sv7gdEBqetZsZDViU_E7UbF7n60eT7mhw6wA7vKiAGUkzhpxX0eo&width=300&dpr=4&quality=100&sign=81e5b9f&sv=2) 1. Copy the “transactions” array into [https://jsonformatter.org/](https://jsonformatter.org/) . You should use Firefox or Brave so that backslashes “\\” aren’t included in the array which will give you an error message when trying to parse: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh6.googleusercontent.com%2F18HVGLKM_PbypT61kEVmo5kFFm9FMn5WMm27TeWe7YlmhAAJ49c-62tkyPMpKCc-l4kcv893PjL-KXFYYK7p9DTj8LYzbAsRIUjloqvwN3A4vfkkTjZ4X8od9W6qzCJpYXlrdjas7iEqcOiRLjKqPoQ&width=300&dpr=4&quality=100&sign=1ffe262d&sv=2) 3\. In the Discord post, click the transaction:’ ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh6.googleusercontent.com%2FaEUx5sRSrWj3KsjwW0N96jkssfv0kXGu8xbN8Q_9iVBLr0bsWa1nH_64NslFmKx0hRTs1RYlAonI6Bk93birxHPgULuzZD9wzNclr9rDigm215x0g1qkzXEoKwcJFZcCij2osytYbOMF1dwC8ImLZ90&width=300&dpr=4&quality=100&sign=4960e113&sv=2) Then copy the ‘Transaction Hash’: ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh3.googleusercontent.com%2F0suGhWmXC8Xyo1zVkH-g7rtAr519ochAJlsA4rVrUlfsVdiIcuGJxMgMFNyAQLWYODtVM7TWjF5JIT3RF3UyE3WQ-KyXkIdcWlZ2McnOFSL8U22J22uE7k7skb7ONFZ1VwWN8mGae7Suwlhyv5z-ewk&width=300&dpr=4&quality=100&sign=60891928&sv=2) Go to [https://dashboard.tenderly.co/](https://dashboard.tenderly.co/) and paste the ‘Transaction Hash’. Then click ‘Show’ to check the input data. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2Flh3.googleusercontent.com%2FTSrHDZePeo_v_ZbjAyuA4EkKjD3bYjf57fL7WlCVX6E7cdTYTayuthJfbTHTjx9c70_CRLhbz5s_pMezclorNTYLSdL7KF2xObANrin1OTXu0_i9veszCebY2SnHBSw4LUOkzOm1VUMlctA8oO4_h7k&width=300&dpr=4&quality=100&sign=e8520ba0&sv=2) In the Discord Ticket, paste the screenshots of Tenderly and json formatter and also paste the transaction data into another thread message as below: The following should be verified: * ‘data’ from Tenderly matches the transaction data from Snapshot. * ‘value’ from Tenderly matches the transaction data from Snapshot. * ‘to’ from Tenderly matches the transaction data from Snapshot. * Verify the explanation: * Go to [https://playground.ethers.org/](https://playground.ethers.org/) and input the following explanation to ethers.utils.toUtf8String(“[{explanation](https://snapshot.4everland.link/ipfs/%7Bexplanation) }”).toString() * Take the returned value and input it into the following url ‘[https://snapshot.4everland.link/ipfs/{explanation](https://snapshot.4everland.link/ipfs/%7Bexplanation) } and verify that the data matches from Snapshot [PreviousAcross](https://docs.uma.xyz/verification-guide/across) [NextNetwork Information](https://docs.uma.xyz/resources/network-addresses) Last updated 1 year ago Was this helpful? Was this helpful? Copy { "method": "transfer", "types": [\ "address",\ "uint256"\ ], "inputs": [\ "9040e41eF5E8b281535a96D9a48aCb8cfaBD9a48",\ {\ "type": "BigNumber",\ "hex": "0x14adf4b7320334b9000000"\ }\ ], "names": [\ "to",\ "amount"\ ] } Copy Tenderly: [\ {\ "to": "0x44108f0223a3c3028f5fe7aec7f9bb2e66bef82f",\ "operation": 0,\ "value": "0",\ "data": "0xa9059cbb0000000000000000000000009040e41ef5e8b281535a96d9a48acb8cfabd9a4800000000000000000000000000000000000000000014adf4b7320334b9000000"\ }\ ] Snapshot IPFS: [\ {\ "operation": "0",\ "data": "0xa9059cbb0000000000000000000000009040e41ef5e8b281535a96d9a48acb8cfabd9a4800000000000000000000000000000000000000000014adf4b7320334b9000000",\ "to": "0x44108f0223A3C3028F5Fe7AEC7f9bb2E66beF82F",\ "value": "0"\ }\ ] --- # Across | UMA Documentation **Step 1: Install Required Dependencies:** git: * Documentation: [https://github.com/git-guides/install-git](https://github.com/git-guides/install-git) yarn: * Documentation: [https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable) node.js * Documentation: [https://nodejs.org/en/download](https://nodejs.org/en/download) * Run the following command to check what version of node you are running: `node -v` Make sure it is greater than 16.18.0. redis: * Documentation: [https://redis.io/docs/getting-started/installation/](https://redis.io/docs/getting-started/installation/) * Note: Follow the [relayer-v2 README](https://github.com/across-protocol/relayer-v2/tree/master) instructions ts-node * You can use the following to install globally: `npm install -g ts-node` Nvm (optional) * Documentation: [https://github.com/nvm-sh/nvm#installing-and-updating](https://github.com/nvm-sh/nvm#installing-and-updating) * Note: Optional, but nvm allows you to easily install and switch between node versions VS Code (optional) * Highly recommend using a code editor like VS code. **Step 2: Clone the relayer-v2 repo:** * If using VS code, open the terminal and run the following command: **Step 3: Run Redis** Open a terminal window and run: **Step 4: Environment Variables** * Change the .env.example file to .env * In line 8 and 9, uncomment either the MNEMONIC or PRIVATE\_KEY and input a private key that has no money on it. * I used [https://vanity-eth.tk/](https://vanity-eth.tk/) to create a private key to use for the demo but again, do not use one that has any money on it as it is an unnecessary risk. * Sign up for an Infura account [https://www.infura.io/](https://www.infura.io/) and click ‘Create New API Key’. After you create the key, you should see a list of endpoints for each network. * In the .env file, update the following env variables to the URL for your infura account. The underscore number at the end of the variable represents the chain ID. So RPC\_PROVIDER\_ALCHEMY\_1 is mainnet. * You can use [https://chainlist.org/](https://chainlist.org/) to find the ID by network. * Include the NODE\_URL\_324 for zksync below even though it hasn’t been added to the .env.example file yet: **Step 5: Run the script** The below is an example, however the two changes that need to be made based on the request are: * REQUEST\_TIME=CHANGE\_THIS\_TO\_THE\_TIMESTAMP * I used privateKey for the below, however, if you used mnemonic in your env variables, it should be changed to –wallet mnemonic Note: The first time you run this, it is going to take a long time. REQUEST\_TIME=1692110627 ts-node ./src/scripts/validateRootBundle.ts --wallet privateKey When the script finishes running, check the Validation results as shown below. The below shows an example of an invalid bundle as it shows “valid”: false: **Appendix** For additional documentation on Across root bundles, visit: [https://docs.across.to/v/developer-docs/how-across-works/overview/disputing-root-bundles](https://docs.across.to/v/developer-docs/how-across-works/overview/disputing-root-bundles) [https://docs.across.to/v/developer-docs/how-across-works/overview/validating-root-bundles](https://docs.across.to/v/developer-docs/how-across-works/overview/validating-root-bundles) [PreviousPolymarket](https://docs.uma.xyz/verification-guide/yes_or_no) [NextoSnap](https://docs.uma.xyz/verification-guide/osnap) Last updated 8 months ago Was this helpful? Was this helpful? Copy git clone https://github.com/across-protocol/relayer-v2 Copy redis-server From the README, run the three commands: cd relayer-v2 yarn install yarn build Copy RPC_PROVIDER_ALCHEMY_1=https://eth-mainnet.g.alchemy.com/v2/{API_KEY} RPC_PROVIDER_ALCHEMY_10=https://opt-mainnet.g.alchemy.com/v2/{API_KEY} RPC_PROVIDER_ALCHEMY_137=https://polygon-mainnet.g.alchemy.com/v2/{API_KEY} RPC_PROVIDER_ALCHEMY_42161=https://arb-mainnet.g.alchemy.com/v2/{API_KEY} NODE_URL_324=https://mainnet.era.zksync.io Copy { "at": "RootBundleValidator", "message": "Validation results", "rootBundle": { "poolRebalanceRoot": "0x7005c47a8e476a2551d5325a6c53cd5b71f308b2ac670742ad7cceb8078a193f", "relayerRefundRoot": "0x9edefc2fc000e71fa1ea1c6ce666a0f8cb2d6da422c45a372585da5e3b738713", "slowRelayRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", "proposer": "0xf7bAc63fc7CEaCf0589F25454Ecf5C2ce904997c", "unclaimedPoolRebalanceLeafCount": 5, "challengePeriodEndTimestamp": 1692117191, "bundleEvaluationBlockNumbers": [\ 17920824,\ 108255396,\ 46338509,\ 977154,\ 121659934,\ 11305323\ ], "proposalBlockNumber": 17920860 }, "valid": false, "invalidReason": "Disputed pending root bundle:\n..... // removed the rest of the invalidReason for the example --- # Subgraphs | UMA Documentation This section explains the UMA subgraph and how to interact with it. The UMA subgraph indexes data from UMA contracts over time. It organizes data about tokenholders, contracts, DVM requests, voting, and more. The subgraph updates for each UMA contract interaction. The subgraph runs on [The Graph](https://thegraph.com/) protocol’s hosted service and can be openly queried. UMA has a GraphQL API Endpoint hosted by [The Graph](https://thegraph.com/docs/about/introduction#what-the-graph-is) called a subgraph for indexing and organizing data from the smart contracts. The schema of GraphQL elements available is defined in [`the subgraphs repo`](https://github.com/UMAprotocol/subgraphs/) . [](https://docs.uma.xyz/resources/subgraph-data#ethereum-mainnet) Ethereum Mainnet --------------------------------------------------------------------------------------- [Creating an API Key Video Tutorial](https://www.youtube.com/watch?v=UrfIpm-Vlgs) * [Explorer Page](https://thegraph.com/explorer/subgraph?id=41LCrgtCNBQyDiVVyZEuPxbvkBH9BxxLU3nEZst77V8o&view=Overview) * Graphql Endpoint: https://gateway.thegraph.com/api/\[api-key\]/subgraphs/id//41LCrgtCNBQyDiVVyZEuPxbvkBH9BxxLU3nEZst77V8o * [Code Repo](https://github.com/UMAprotocol/subgraphs) [](https://docs.uma.xyz/resources/subgraph-data#helpful-links) Helpful Links --------------------------------------------------------------------------------- [Querying from an Application](https://thegraph.com/docs/en/developer/querying-from-your-app/) [Managing your API Key & Setting your indexer preferences](https://thegraph.com/docs/en/studio/managing-api-keys/) [](https://docs.uma.xyz/resources/subgraph-data#resources) Resources ------------------------------------------------------------------------- LSP Subgraphs * [Mainnet Subgraph](https://thegraph.com/hosted-service/subgraph/umaprotocol/mainnet-lsp) * [Polygon Subgraph](https://thegraph.com/hosted-service/subgraph/umaprotocol/polygon-lsp) * [Kovan Subgraph](https://thegraph.com/hosted-service/subgraph/umaprotocol/kovan-lsp) EMP Subgraphs (includes query for whitelisted collateral) * [Mainnet Subgraph](https://thegraph.com/explorer/subgraph/umaprotocol/mainnet-contracts) * [Kovan Subgraph](https://thegraph.com/explorer/subgraph/umaprotocol/kovan-contracts) Voting Subgraphs * [Mainnet Subgraph](https://thegraph.com/explorer/subgraph/umaprotocol/mainnet-voting) * [Kovan Subgraph](https://thegraph.com/explorer/subgraph/umaprotocol/kovan-voting) Here is the [source code](https://github.com/UMAprotocol/subgraphs) for deployed subgraphs. [](https://docs.uma.xyz/resources/subgraph-data#making-queries) Making Queries ----------------------------------------------------------------------------------- To learn more about querying a subgraph refer to [The Graph’s documentation](https://thegraph.com/docs/about/introduction) . [PreviousApproved Collateral Types](https://docs.uma.xyz/resources/approved-collateral-types) [NextMainnet Voting Entities](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities) Last updated 3 years ago Was this helpful? * [Ethereum Mainnet](https://docs.uma.xyz/resources/subgraph-data#ethereum-mainnet) * [Helpful Links](https://docs.uma.xyz/resources/subgraph-data#helpful-links) * [Resources](https://docs.uma.xyz/resources/subgraph-data#resources) * [Making Queries](https://docs.uma.xyz/resources/subgraph-data#making-queries) Was this helpful? --- # Approved Collateral Types | UMA Documentation Collateral Currency Final Fee UMIP Chains ABT 0.055 [UMIP-178](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-178.md) [Ethereum](https://etherscan.io/address/0xee1DC6BCF1Ee967a350e9aC6CaaAA236109002ea) USDB 250 [UMIP-182](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-182.md) [Blast](https://blastscan.io/address/0x4300000000000000000000000000000000000003) USDC 250 [UMIP-18](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-18.md) [Arbitrum](https://arbiscan.io/address/0xaf88d065e77c8cC2239327C5EDb3A432268e5831) , [Arbitrum (USDC.e)](https://arbiscan.io/address/0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8) , [Base](https://basescan.org/address/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913) , [Core](https://scan.coredao.org/address/0xa4151B2B3e269645181dCcF2D426cE75fcbDeca9) , [Ethereum](https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) , [Optimism](https://optimistic.etherscan.io/address/0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85) , [Optimism (USDC.e)](https://optimistic.etherscan.io/address/0x7F5c764cBc14f9669B88837ca1490cCa17c31607) , [Polygon](https://polygonscan.com/address/0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) , [Polygon (USDC.e)](https://polygonscan.com/address/0x2791bca1f2de4661ed88a30c99a7a9449aa84174) WETH 0.055 [UMIP-10](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-10.md) [Arbitrum](https://arbiscan.io/address/0x82aF49447D8a07e3bd95BD0d56f35241523fBab1) , [Base](https://basescan.org/address/0x4200000000000000000000000000000000000006) , [Blast](https://blastscan.io/address/0x4300000000000000000000000000000000000004) , [Core](https://scan.coredao.org/address/0xeAB3aC417c4d6dF6b143346a46fEe1B847B50296) , [Ethereum](https://etherscan.io/token/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) , [Optimism](https://optimistic.etherscan.io/address/0x4200000000000000000000000000000000000006) , [Polygon](https://polygonscan.com/address/0x7ceb23fd6bc0add59e62ac25578270cff1b9f619) , WIP 50 [Story](https://www.storyscan.io/address/0x1514000000000000000000000000000000000000) [PreviousApproved Price Identifiers](https://docs.uma.xyz/resources/approved-price-identifiers) [NextSubgraphs](https://docs.uma.xyz/resources/subgraph-data) Last updated 4 months ago Was this helpful? Was this helpful? --- # Queries | UMA Documentation Below are some sample queries you can use to gather information from UMA contracts. You can build your own queries using a [GraphQL Explorer](https://graphiql-online.com/graphiql) and enter your endpoint to limit the data to exactly what you need. [](https://docs.uma.xyz/resources/subgraph-data/queries#financial-contracts) Financial Contracts ----------------------------------------------------------------------------------------------------- Copy { financialContracts { id creator { id isRemoved manager } deployer { id } address collateralToken { id name } collateralRequirement expirationTimestamp totalSyntheticTokensBurned totalSyntheticTokensCreated totalTokensOutstanding cumulativeFeeMultiplier globalCollateralizationRatio rawTotalPositionCollateral totalCollateralDeposited totalCollateralWithdrawn totalPositionCollateral rawLiquidationCollateral positions { id rawCollateral collateral tokensOutstanding isEnded } liquidations { id status amountWithdrawn } } } [](https://docs.uma.xyz/resources/subgraph-data/queries#liquidations) Liquidations --------------------------------------------------------------------------------------- [](https://docs.uma.xyz/resources/subgraph-data/queries#price-requests) Price Requests ------------------------------------------------------------------------------------------- [PreviousMainnet Voting Entities](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities) [NextVoting with a 2-Key Contract](https://docs.uma.xyz/resources/voting-with-a-2-key-contract) Last updated 3 years ago Was this helpful? * [Financial Contracts](https://docs.uma.xyz/resources/subgraph-data/queries#financial-contracts) * [Liquidations](https://docs.uma.xyz/resources/subgraph-data/queries#liquidations) * [Price Requests](https://docs.uma.xyz/resources/subgraph-data/queries#price-requests) Was this helpful? Copy { liquidations { id status sponsor { id } liquidator { id } disputer { id } liquidationId tokensLiquidated lockedCollateral liquidatedCollateral disputeBondAmount disputeSucceeded amountWithdrawn events { __typename } } } Copy { priceRequests { id isResolved price latestRound { roundId snapshotId totalVotesRevealed totalRewardsClaimed totalSupplyAtSnapshot votersAmount votersClaimedAmount tokenVoteParticipationRatio tokenVoteParticipationPercentage votersEligibleForRewardsRatio votersEligibleForRewardsPercentage votersClaimedRatio votersClaimedPercentage tokensClaimedRatio tokensClaimedPercentage winnerGroup { votersAmount totalVoteAmount } groups { price totalVoteAmount won votersAmount } } time identifier { id isSupported } committedVotes(first: 2) { time } revealedVotes(first: 2) { price time } } } --- # oSnap (Deprecated) | UMA Documentation Support for oSnap will be deprecated on December 15th, 2025. After this date, oSnap will not be able to execute transactions from your DAO’s Safe treasury. oSnap integrations should take the following steps to prepare: * Ensure their Safe signers are prepared to sign and execute any necessary DAO transactions * Disable oSnap on all DAO treasuries by following these steps: [https://docs.uma.xyz/developers/osnap/disabling-osnap](https://docs.uma.xyz/developers/osnap/disabling-osnap) [PreviousUnsupported Contracts](https://docs.uma.xyz/resources/unsupported-contracts) [NextDisabling oSnap](https://docs.uma.xyz/resources/osnap/disabling-osnap) Last updated 21 days ago Was this helpful? Was this helpful? --- # Verification System | UMA Documentation ### [](https://docs.uma.xyz/verification-guide/verification-system#prerequisites) Prerequisites Before getting into the specifics of how to verify proposals from the Optimistic Oracle, please make sure to go through the following resources to understand how UMA works: * [Understanding UMA](https://docs.umaproject.org/getting-started/oracle) * [Understanding oSnap](https://docs.uma.xyz/developers/osnap) ### [](https://docs.uma.xyz/verification-guide/verification-system#why-verification-matters) **Why Verification Matters:** When a project integrates with UMA, they do so with the understanding that someone is always watching for the opportunity to dispute bad proposals. The Verification Team is one form of defence against these bad proposals, and an important one at that. This team is responsible for bringing the human element to proposal resolution. Sometimes the truth can only be discovered through intensive research and lengthy discussion. Our job is to highlight those moments and provide the best source of truth available for UMA voters to consider. By joining our team, you become a key contributor to our shared goal of maintaining the integrity of our oracle. Join the Verification Team here --> [https://discord.gg/muN6tBaG4d](https://discord.gg/muN6tBaG4d) [PreviousResolving Disputes](https://docs.uma.xyz/using-uma/resolving-disputes) [NextPolymarket](https://docs.uma.xyz/verification-guide/yes_or_no) Last updated 8 months ago Was this helpful? * [Prerequisites](https://docs.uma.xyz/verification-guide/verification-system#prerequisites) * [Why Verification Matters:](https://docs.uma.xyz/verification-guide/verification-system#why-verification-matters) Was this helpful? --- # oSnap Proposal Verification | UMA Documentation [](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#verifying-proposals) Verifying Proposals ----------------------------------------------------------------------------------------------------------------- After transactions have been requested for execution, the challenge period begins. The challenge period length is set by the oSnap Safe module advanced settings. Invalid requests must be disputed within the challenge period. oSnap requests can be reviewed in the [Optimistic Oracle dApp](https://oracle.umaproject.org/) 's Verify tab. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252F4JND8ZFsj4kuHLV5SxLm%252Fimage.png%3Falt%3Dmedia%26token%3Daa40d1e1-a854-4920-ace6-ba926433307f&width=768&dpr=4&quality=100&sign=acba7e9e&sv=2) After selecting a request, a sidebar will show additional request details including the bond amount, when the challenge period ends, a dispute button (when a wallet is connected), a link to the corresponding Snapshot proposal, the oSnap rules that the request should be reviewed against (including minimum quorum and voting period for the Snapshot proposal), and links to relevant block explorer pages. The explanation includes an IPFS hash that is a unique identifier for the Snapshot proposal and can be used to retrieve details of the proposal. For example, [https://ipfs.io/ipfs/bafkreie2hujdeenwz7dcbqcvwq37vjgu6g3alvkk5ysxbm4yqpeahm37xa](https://ipfs.io/ipfs/bafkreie2hujdeenwz7dcbqcvwq37vjgu6g3alvkk5ysxbm4yqpeahm37xa) . ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FPuVsJkfCoX8rANe8KUVQ%252Fimage.png%3Falt%3Dmedia%26token%3Dcac03f6c-5f73-4a1b-990c-18d746f4333f&width=768&dpr=4&quality=100&sign=d1c292b9&sv=2) [](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#osnap-proposal-pass-criteria) oSnap Proposal Pass Criteria ----------------------------------------------------------------------------------------------------------------------------------- An oSnap proposal's voting results must meet both criteria below to be considered passed: 1. Quorum: FOR + AGAINST + ABSTAIN ≥ Required Quorum 2. 'FOR' majority: FOR > 50% \* (FOR + AGAINST + ABSTAIN) [](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#disputing-proposals) Disputing Proposals ----------------------------------------------------------------------------------------------------------------- If the oSnap request does not meet the Rules, it should be disputed. Disputed requests can not be executed no matter how UMA resolves the dispute. This [section](https://docs.uma.xyz/using-uma/disputing-oracle-data) outlines the steps to dispute an invalid oSnap request, or any other invalid assertions to UMA's Optimistic Oracle. [PreviousDisabling oSnap](https://docs.uma.xyz/resources/osnap/disabling-osnap) [NextAdditional Resources](https://docs.uma.xyz/resources/additional-resources) Last updated 20 days ago Was this helpful? * [Verifying Proposals](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#verifying-proposals) * [oSnap Proposal Pass Criteria](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#osnap-proposal-pass-criteria) * [Disputing Proposals](https://docs.uma.xyz/resources/osnap/osnap-proposal-verification#disputing-proposals) Was this helpful? --- # Voting with a 2-Key Contract | UMA Documentation The UMA DVM two-key contract enables you to actively engage in voting using hot keys (private keys stored on machine and used often), but protect your funds with the stronger, and preferable, use of cold keys (private keys stored offline and used rarely). Another way this contract can be used is to delegate voting rights to an EOA, while still maintaining token ownership with a multisig or other ownership structure. Each two-key contract is a unique smart contract that you deploy. It keeps track of: * The number of UMA tokens you have deposited into the two-key contract * The address of your hot wallet; the hot wallet is permissioned to sign transactions and vote in DVM governance * The address of your cold wallet; only the cold wallet (and importantly, not the voting wallet or any other address) is permissioned to withdraw UMA tokens from the two-key contract > **DANGER** > > If you do not know exactly why you are setting up a 2-Key contract, then you likely do not need one. Deploying the contract is expensive and unnecessary unless you need to vote with separate hot and cold keys. > > Voting with a hardware wallet is not a reason that necessitates needing to set up a 2-Key contract. You can likely vote by connecting your hardware wallet to MetaMask or another wallet provider. > > If you have any doubt about your need for a 2-Key contract, please ask in the UMA Discord before proceeding. ### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#prerequisites) Prerequisites * You need ETH in your hot wallet for the initial deployment of the 2-key contract and for submitting all subsequent votes. * You need ETH in your cold wallet to make the initial UMA token deposit, and also if you ever want to withdraw tokens from the 2-key contract. ### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#instructions-to-deploy-your-own-2-key-contract) Instructions to deploy your own 2-key contract #### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#connect) Connect Navigate to the UMA voter dApp (vote.umaproject.org) and connect your MetaMask hot wallet. This will be your voting wallet going forward. #### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#deploy) Deploy Click on the gear icon on the far right. In the modal, click `Add Cold Wallet Address` Input your cold wallet address and click `Save`. #### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#verify-your-deployment-was-correct) Verify your deployment was correct The following steps help you verify that your two-key contract was deployed correctly and check that the permissions are held by the correct address. * Copy the 2-key smart contract address (i.e., DesignatedVoting Escrow Account) from the voter dApp and view it on Etherscan * Under `Read Contract` input roleID `0` in function `1. getMember`, and click query. Check that the address output matches your cold wallet address. * Input roleID `1` in function `1. getMember`, and click query. Check that the address output matches your hot wallet address. #### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#voting) Voting To vote with the 2-key contract, you will need to send UMA tokens to it. After sending UMA tokens to the two-key contract address, you can immediately start voting with your hot keys at the voter dApp. This will exclude you from voting with any additional UMA tokens that are in your hot wallet through the voter dApp. #### [](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#withdraw-tokens) Withdraw tokens The following steps let you withdraw UMA tokens from the two-key contract using your cold keys. You will have to withdraw and deploy a new two-key contract if you want to designate a new hot key for voting. * Navigate to your DesignatedVotingContract on Etherscan * Connect your cold wallet by clicking the “Connect to web3” button * Use function `11. withdrawErc20` * Input erc20Address: `0x04fa0d235c4abf4bcf4787af4cf447de572ef828` * Input the number of tokens that you want to withdraw \* 10^18 (for example, if you want to withdraw 1.1 tokens, you should input `1100000000000000000`) * Click “Write” * Confirm the transaction with your cold keys and wait for the transaction to finish mining **Changing the voter address** To change the voter address for a DesignatedVotingContract, you just need to call `resetMember(newAddress)` with your cold keys (owner address) and pass in the new address that you wish to use as the voter. [PreviousQueries](https://docs.uma.xyz/resources/subgraph-data/queries) [NextUnsupported Contracts](https://docs.uma.xyz/resources/unsupported-contracts) Last updated 1 year ago Was this helpful? * [Prerequisites](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#prerequisites) * [Instructions to deploy your own 2-key contract](https://docs.uma.xyz/resources/voting-with-a-2-key-contract#instructions-to-deploy-your-own-2-key-contract) Was this helpful? --- # Audit & Bug Bounty Programs | UMA Documentation Security of the platform is our highest priority. All contract code and balances are publicly verifiable, and security researchers are eligible for a bug bounty for reporting undiscovered vulnerabilities. ### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#audits) Audits OpenZeppelin has performed the following audits on UMA contracts: * [Common and oracle directory contracts: April 28, 2020](https://blog.openzeppelin.com/uma-audit-phase-1/) * [Financial-templates directory contracts: May 12, 2020](https://blog.openzeppelin.com/uma-audit-phase-2/) * [Updates to the Expiring Multiparty contracts and flash loan mitigations for the voting contracts: September 9, 2020](https://blog.openzeppelin.com/uma-audit-phase-3/) * [Perpetual Multiparty template contracts: February 2, 2021](https://blog.openzeppelin.com/uma-audit-phase-4/) * [Insured Bridge contracts: December 1, 2021](https://blog.openzeppelin.com/uma-audit-l2-bridges/) * [Governance, cross-chain oracle, and optimistic rewarder contracts: January 7, 2022](https://blog.openzeppelin.com/uma-audit-phase-6/) * [UMA Optimistic Governor Audit: July 21, 2022](https://blog.openzeppelin.com/uma-optimistic-governor-audit/) * [Across Token and Token Distributor Audit: July 21, 2022](https://blog.openzeppelin.com/across-token-and-token-distributor-audit/) Additionally, OpenZeppelin audits incremental upgrades to UMA's contracts on a continuous basis. The continuous audit report can be found [here](https://blog.openzeppelin.com/uma-continuous-audit/) . ### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#bug-bounty-rewards) Bug Bounty Rewards UMA encourages the community to audit our contracts and security; we also encourage the responsible disclosure of any issues. The bug bounty program is intended to recognize the value of working with the community of independent security researchers and sets out our definition of good faith in the context of finding and reporting vulnerabilities, as well as what you can expect from us in return. UMA offers substantial rewards for discoveries that can prevent the loss of assets, the freezing of assets, or harm to users. All rewards will be paid in $UMA, and the amount of compensation will vary depending on bug severity. Reward amounts typically correspond to severity in the following manner. Severity Reward amount in USD Low $250 Medium $3,000 High $10,000 Critical up to $1,000,000 Severity is calculated according to the [OWASP](https://owasp.org/www-project-risk-assessment-framework/) risk rating model based on Impact and Likelihood. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FxqbuiId1IQafAqPVA5z6%252Fseverity.png%3Falt%3Dmedia%26token%3D2a4aa2dc-f650-49bf-9a63-bccf8a46de84&width=768&dpr=4&quality=100&sign=c70b2d08&sv=2) ### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#scope) Scope The scope of our bug bounty program includes any and all of UMA's production smart contracts. It does not include known issues with the intended behavior. #### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#in-scope) In scope * All UMA, Oval, or Across smart contracts that are deployed to mainnet or are otherwise noted as being applicable. * Bot or other offchain code to support deployed smart contracts. #### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#examples-of-whats-in-scope) Examples of what’s in scope: * Being able to steal funds * Being able to freeze funds or render them inaccessible by their owners #### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#out-of-scope) Out of scope: * Issues that have already been submitted by another user or are already known to the UMA team * Note: this includes bugs known to the UMA team, but have not been disclosed due to active mitigation efforts. * Vulnerabilities in contracts built on top of the protocol by third-party developers (such as smart contract wallets) * Vulnerabilities that require ownership of an admin key * Any files, modules or libraries other than the ones mentioned above * More efficient gas solutions (although these suggestions are appreciated) * Any points listed as an already known weaknesses * Any points listed in an audit report ### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#submissions) Submissions Please email your submissions to [\[email protected\]](https://docs.uma.xyz/cdn-cgi/l/email-protection#3d5f485a4e7d48505c4d4f5257585e4913524f5a) . The submission must include clear and concise steps to reproduce the discovered vulnerability. ### [](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#terms--conditions) Terms & Conditions If you comply with the policies below when reporting a security issue to us, we will not initiate a lawsuit or law enforcement investigation against you in response to your report. We ask that you: * Report any vulnerability you’ve discovered promptly. * Avoid violating the privacy of others, disrupting our systems, destroying data, or harming user experience. * Use only [\[email protected\]](https://docs.uma.xyz/cdn-cgi/l/email-protection#cba9beacb88bbea6aabbb9a4a1aea8bfe5a4b9ac) to discuss vulnerabilities with us. * Keep the details of any discovered vulnerabilities confidential until they are publicly announced by Risk Labs. * Perform testing only on in-scope systems, and respect systems and activities which are out-of-scope. * Not engage in blackmail, extortion, or any other unlawful conduct. * Not be a current or former UMA Foundation employee, vendor, contractor, or the employee of an UMA vendor or contractor. Public disclosure of the bug or the indication of an intention to exploit it on Mainnet will make the report ineligible for a bounty. If in doubt about other aspects of the bounty, most of the [Ethereum Foundation bug bounty program rules](https://bounty.ethereum.org/) will apply. Any questions? Reach us via email ([\[email protected\]](https://docs.uma.xyz/cdn-cgi/l/email-protection#afcddac8dcefdac2cedfddc0c5caccdb81c0ddc8) ). For more information on the UMA platform, check out our [website](http://www.umaproject.org/) and [Github](https://github.com/UMAprotocol/) . All reward determinations, including eligibility and payment amount, are made at UMA’s sole discretion. UMA reserves the right to reject submissions and alter the terms and conditions of this program without notice. [PreviousNew Network Requests](https://docs.uma.xyz/resources/network-addresses/new-network-requests) [NextApproved Price Identifiers](https://docs.uma.xyz/resources/approved-price-identifiers) Last updated 1 year ago Was this helpful? * [Audits](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#audits) * [Bug Bounty Rewards](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#bug-bounty-rewards) * [Scope](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#scope) * [Submissions](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#submissions) * [Terms & Conditions](https://docs.uma.xyz/resources/audit-and-bug-bounty-programs#terms--conditions) Was this helpful? --- # Data Asserter | UMA Documentation This section covers the [Data Asserter contract](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/DataAsserter.sol) , which is available in the Optimistic Oracle V3 [quick-start repo](https://github.com/UMAprotocol/dev-quickstart-oov3) . This tutorial shows an example of how to build an arbitrary data asserter contract, using the UMA [Optimistic Oracle V3 (OOV3)](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol) contract. This enables you to assert to the correctness of some off-chain process and store the output on-chain. This tutorial acts as a starting point to show how the OOV3 can be flexibility used in a sample integration. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#data-asserter) Data Asserter This smart contract allows data providers to assert the correctness of a data point, within any arbitrary data set, and bring the result on-chain. This contract is designed to be maximally open ended, enabling any kind of data to be asserted. For example, and for illustrative purposes of this tutorial, we will assert weather data on-chain. Note, though, that this kind of assertion flow and the associated OOV3 integration could build a wide range of assertions with arbitrary complexity. For example you could use the same structure to bring on-chain complex data associated with Beacon chain validator set to build a Liquid staking derivative, enable complex off-chain computation with on-chain outputs or anything that has a defined deterministic input output relationship. Anyone can assert a data point against the Data Asserter contract, with a known dataId and datapoint. Independent 3rd parties can then verify the correctness of this data against the dataId. For our example we will be asserting the output of a very simple numerical computation: `69+420`. This is meant to show the basic idea without overcomplicating the off-chain part. Note, though, that the `dataId` prop used here could represent any kind of unique data identifier (a row in a database table, a validator address or a complex structure used to associate any kind of data to a given value. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#development-environment) Development environment This project uses [forge](https://github.com/foundry-rs/foundry/tree/master/forge) as the Ethereum testing framework. You will also need to install Foundry, refer to [Foundry installation documentation](https://book.getfoundry.sh/getting-started/installation) if you don’t have it already. You will also need `git` for cloning the repository, as well as `bash` shell and `jq` tool in order to parse transaction outputs when interacting with deployed contracts. Clone the UMA [Optimistic Oracle V3 quick-start repository](https://github.com/UMAprotocol/dev-quickstart-oov3) and install the dependencies: Copy git clone https://github.com/UMAprotocol/dev-quickstart-oov3.git cd dev-quickstart-oov3 forge install ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#contract-implementation) Contract implementation The contract discussed in this tutorial can be found at `dev-quickstart-oov3/src/DataAsserter.sol` ([here](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/DataAsserter.sol) ) within the repo. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#contract-creation-and-initialization) Contract creation and initialization To initialize the state variables of the contract, the constructor takes two parameters: 1. `_defaultCurrency` parameter in the constructor identifies the token used for bonds of data assertions. This token should be approved as whitelisted UMA collateral. Please check [Approved Collateral Types](https://docs.uma.xyz/resources/approved-collateral-types) for production networks or call `getWhitelist()` on the [Address Whitelist](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/common/implementation/AddressWhitelist.sol) contract for any of the test networks. Note that the deployed Optimistic Oracle V3 instance already has its `defaultCurrency` added to the whitelist, so it can also be used by the Data Asserter contract. Alternatively, you can approve a new token address with `addToWhitelist` method in the Address Whitelist contract if working in a sandboxed UMA environment. 2. `_optimisticOracleV3` is used to locate the address of UMA Optimistic Oracle V3. Address of `OptimisticOracleV3` contact can be fetched from the relevant [networks](https://github.com/UMAprotocol/protocol/tree/master/packages/core/networks) file, if you are on a live network, or you can provide your own contract instance if deploying UMA Oracle contracts in your own sandboxed testing environment. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#asserting-data) Asserting data `assertDataFor` method allows any data provider to assert some value of `data` for the associated `dataId`. The caller sets the `asserter` as the address that will receive bonds at resolution of the data assertion (this could be their address as well). Internally, this function pulls the associated assertion bond (global for all assertions within the DataAssertion contract) from the caller, makes an assertion call to the Optimistic Oracle V3 and stores the assertion within the contracts internal `assertionsData` mapping. Lastly, an event is emitted. For the context of this example we will be considering the `dataId` simply as the URL that would be called to fetch the weather data from `wttr.in` and the `data` value as the result from this call. Both are bytes32 encoded. The call to the Optimistic Oracle V3 looks as follows: Lets break this down step by step: * First, the value for the `claim` filed is constructed to be a human readable string as the concatenation of a number of different data points. This is meant to be parsable by the validation network and enable both Humans and software verifiers alike to assess the correctness of the claim. Note that within the Optimistic Oracle V3 the `claim` field (this prop in this function call) is _not_ stored on-chain; it is simply emitted and is used by off-chain actors to verify the correctness of the claim. * Next, the `asserter` field is passed in from this function call. This is who will receive the bonds back at resolution of the assertion, assuming the asserter was correct. * Next, we have the callback recipient set to `address(this)`. The OOV3 has the concept of callbacks wherein at the settlement of an assertion the asserter can choose to optionally call out from the OO into another contract. In this context, we want the OOV3 to call _back_ into the Data Asserter contract when the assertion is settled (this will become clearer in the following section). * We have no Sovereign security enabled here (this is an advanced topic and does not need to be covered here). * Default liveness, bond and identifier are set. * No domain is set (this is an external concept that helps 3rd parties identify assertions). #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#resolving-and-subsequently-fetching-data-assertions) Resolving and subsequently fetching data assertions Once data has been asserted, the act of verifying it is passed over to the Optimistic Oracle V3 and the associated network of data verifiers. Due to the presence of a bond (reward for catching invalid assertions), we can be confident that in real world someone would verify this assertion (if the bond is high enough, and the liveness is long enough we have high guarantees of this). If the assertion passes the `assertionLiveness` without dispute then it can be settled. The data assertion contract showcases the OOV3's concept of `assertionResolvedCallback` which enables the OOV3 to settle downstream contracts that are dependent on the resolution of an assertion. Once an assertion is settleable (it has: a) passed liveness and b) not been disputed) anyone can call [`settleAssertion`](https://github.com/UMAprotocol/protocol/blob/922e5da60d1e71f64de50acdf9bf83a07be9449e/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol#L250) on the OOV3. This function acts to settle the assertion within the OO and call into the callback recipient, set during the `assertDataFor` function call. Looking within the Data Asserter contract, we can see what happens when the `assertionResolvedCallback` is hit from the OOV3 on settlement: This function effectively: * enforce the inbound caller is the OOV3. Else, revert * If the assertion was resolved as truthful (it would not be if it was disputed and the dispute proved to be correct) then: * set the data assertion status to true, * remove the data from the temporary `dataAssertion` structure * if it was resolved as not truthful (deleted) then simply delete it from the temp structure `assertionsData` Once settled, we can now call the `getData` function with the `assertionId.`This will return the data value and the accompanying resolution status (was it resolved truthfully, or not). #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#disputing-data-assertions) Disputing data assertions If we want to dispute an asserted data point one must simply call the [`disputeAssertion(bytes32 assertionId, address disputer)`](https://github.com/UMAprotocol/protocol/blob/922e5da60d1e71f64de50acdf9bf83a07be9449e/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol#L220) method on the OOV3. In here, you provide the associated `assertionId` (the same field that was returned when calling `assertData`and the `disputer` address (the address that will receive the bonds back at the resolution of the dispute). ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#tests-and-deployment) Tests and deployment All the unit tests covering the functionality described above are available [here](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/test/DataAsserter.t.sol) . To execute all of them, run: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#deployment) Deployment Before deploying and interacting with the contracts export the required environment variables. Note that there are a number of ways to interact with these contracts. The simplest setup is to fork Goerli testnet into a local development environment, using Anvil, and run the steps against the fork. To create an Anvil fork run the following: Replacing `xxx` with your infura key. This will create a local fork of the Goerli testnet, running on `127.0.0.1:8545`. It will also expose a test mnemonic that you can use which has pre-loaded Eth within the fork. (**Note:** to set environment variables, as those listed below, use the `export` syntax in your shell. for example `export ETH_RPC_URL=XXX` * `ETHERSCAN_API_KEY`: your secret API key used for contract verification on Etherscan if deploying on a public network (not required if you want to do this against a local testnet). * `ETH_RPC_URL`: your RPC node used to interact with the selected network. For this tutorial it will be easiest to do this against the Goerli fork by setting `ETH_RPC_URL=http://127.0.0.1:8545` * `MNEMONIC`: your passphrase used to derive private keys of deployer (index 0) and any other addresses interacting with the contracts. The simplest setup with this is to re-use the Anvil default unlocked accounts, if you are using the local testnet environment, you can have: * `FINDER_ADDRESS`: address of the [Finder](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/implementation/Finder.sol) contract used to locate other UMA ecosystem contracts (in order to resolve disputes you would need to use the one from a sandboxed environment). For Goerli, you can use: Use `cast` command from Foundry to locate the address of Optimistic Oracle V3 and its default bonding token: You should be able to see both of these values set in your env with `echo $OOV3_ADDRESS` and `echo $DEFAULT_CURRENCY_ADDRESS` To deploy the Data Asserter contract, run `forge create` command. (**Note** if you hit an error like `Error accessing local wallet. Did you set a private key, mnemonic or keystore?` then you might be hitting a foundry related issue that should be resolved by updating your foundry installation with `foundryup`. Finally, we can verify the deployed (if deployed to a public network) contract with `forge verify-contract`: ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#interacting-with-deployed-contract) Interacting with deployed contract The following section provides instructions on how to interact with the deployed contract from the foundry `cast` tool, though one can also use it for guidance for interacting through another interface (e.g. Remix or Etherscan). #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#initial-setup) Initial setup Export derivation index for the asserting user that will be needed when signing transactions: Make sure the user address above have sufficient funding for the gas to execute the transactions. Next, set up the bytes32 encoding for the `dataId` and `data`, as discussed in the [Asserting Data](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#asserting-data) section. The `dataId` field will be the simplest command that can be re-produced by independent verifiers. We use `bc` (arbitrary-precision arithmetic language and calculator) that should be available on most operating systems: The `data` field will be the asserted output of the above `bc` command: Note that at any point you can look at your env by running `printenv` within your console to see the things we've set up to this point. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#asserting-the-data-point) Asserting the data point Next, we will call the Data Asserter contract and assert the data point and data ID that we set within our environment. Note that on the Goerli testnet the default bond for the default currency is set to 0. This is done to somewhat simplify the interactions: you don't need to mint yourself any USDC and you don't need to approve the Data Asserter to pull it from your account. Clearly, this is different to how this would be structured in reality but for demonstration purposes it keeps thing easier. What we are doing here is calling the `assertDataFor(bytes32,bytes32,address)`with the props `DATA_ID`, `DATA` and `DATA_ASSERTER`, that we set earlier. We are taking the output of the transaction and storing the `transactionHash` within the `ASSERTION_TX` variable. We can fetch the associated `assertionId` from the `DataAssertionResolved` event that should be the last event in the assertion transaction. The emitted event has the structure: We can fetch indexed props from cast by using the `receipt` function in conjunction with `jq`. To fetch the 3rd indexed prop (`assertionId`) from the last event, we would run: Next, we can view the data asserted object using the `--abi-decode` call. This will return the props in the `assertionData` mapping, relating to this structure: The last prop in the output (`resolved`) should be `false` at this moment. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#settling-the-assertion) Settling the assertion Now, let's move forward 2 hours to go pass the challenge window of the assertion: Now, we can submit the settlement transaction to the OOV3 as we've passed liveness: If we call the `assertionData` mapping again, we'll see that the assertion has settled. The last prop in the output (`resolved`) should be `true`: We can now call the `getData` method directly and store output in `IS_RESOLVED` and `RESOLVED_DATA` variables: `IS_RESOLVED` should now be `true`: The decoded value of `RESOLVED_DATA` should be `489` as originally asserted: ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#conclusion) Conclusion This tutorial has shown you how to use the Data Asserter sample tutorial, along with the Optimistic Oracle V3. This is meant to act as a starting point for further contracts to be built on. Next steps should be looking at the other OOV3 tutorials or trying to build your own integration! If you have questions please message us on Discord or create a Github issue and we'll happily help you with your integration. [PreviousQuick start](https://docs.uma.xyz/developers/optimistic-oracle-v3/quick-start) [NextEscalation Managers](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers) Last updated 8 months ago Was this helpful? * [Data Asserter](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#data-asserter) * [Development environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#development-environment) * [Contract implementation](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#contract-implementation) * [Tests and deployment](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#tests-and-deployment) * [Interacting with deployed contract](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#interacting-with-deployed-contract) * [Conclusion](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter#conclusion) Was this helpful? Copy constructor(address _defaultCurrency, address _optimisticOracleV3) { defaultCurrency = IERC20(_defaultCurrency); oo = OptimisticOracleV3Interface(_optimisticOracleV3); defaultIdentifier = oo.defaultIdentifier(); } Copy function assertDataFor( bytes32 dataId, bytes32 data, address asserter ) public returns (bytes32 assertionId) { ... } Copy assertionId = oo.assertTruth( abi.encodePacked( "Data asserted: 0x", // in the example data is type bytes32 so we add the hex prefix 0x. ClaimData.toUtf8Bytes(data), " for dataId: 0x", ClaimData.toUtf8Bytes(dataId), " and asserter: 0x", ClaimData.toUtf8BytesAddress(asserter), " at timestamp: ", ClaimData.toUtf8BytesUint(block.timestamp), " in the DataAsserter contract at 0x", ClaimData.toUtf8BytesAddress(address(this)), " is valid." ), asserter, address(this), // Callback recipient address(0), // No sovereign security. assertionLiveness, defaultCurrency, bond, defaultIdentifier, bytes32(0) // No domain. ); Copy // OptimisticOracleV3 resolve callback. function assertionResolvedCallback(bytes32 assertionId, bool assertedTruthfully) public { require(msg.sender == address(oo)); // If the assertion was true, then the data assertion is resolved. if (assertedTruthfully) { assertionsData[assertionId].resolved = true; DataAssertion memory dataAssertion = assertionsData[assertionId]; emit DataAssertionResolved(dataAssertion.dataId, dataAssertion.data, dataAssertion.asserter, assertionId); // Else delete the data assertion if it was false to save gas. } else delete assertionsData[assertionId]; } Copy forge test --match-path *DataAsserter* Copy anvil --fork-url https://goerli.infura.io/v3/xxx Copy export MNEMONIC="test test test test test test test test test test test junk" Copy export FINDER_ADDRESS=0xE60dBa66B85E10E7Fd18a67a6859E241A243950e Copy export OOV3_ADDRESS=$(cast call $FINDER_ADDRESS "getImplementationAddress(bytes32)(address)" \ $(cast --format-bytes32-string "OptimisticOracleV3")) export DEFAULT_CURRENCY_ADDRESS=$(cast call $OOV3_ADDRESS "defaultCurrency()(address)") Copy export DATA_ASSERTER=$(forge create --json src/DataAsserter.sol:DataAsserter \ --mnemonic "$MNEMONIC" \ --constructor-args $DEFAULT_CURRENCY_ADDRESS $OOV3_ADDRESS \ | jq -r .deployedTo) Copy forge verify-contract \ --chain-id $(cast chain-id) \ --constructor-args $(cast abi-encode "constructor(address,address)" \ $DEFAULT_CURRENCY_ADDRESS $OOV3_ADDRESS) $DATA_ASSERTER DataAsserter Copy export ASSERTER_ID=1 Copy export DATA_ID=$(cast --format-bytes32-string "echo '69+420' | bc") echo "DATA_ID=$(echo $DATA_ID)" Copy export DATA=$(cast --format-bytes32-string $(echo '69+420' | bc)) echo "DATA=$(echo $DATA)" Copy export ASSERTION_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $ASSERTER_ID \ $DATA_ASSERTER \ "assertDataFor(bytes32,bytes32,address)" $DATA_ID $DATA $DATA_ASSERTER \ | jq -r .transactionHash) Copy event DataAssertionResolved( bytes32 indexed dataId, bytes32 data, address indexed asserter, bytes32 indexed assertionId ); Copy export ASSERTION_ID=$(cast receipt --json $ASSERTION_TX | jq -r .logs[-1].topics[3]) Copy struct DataAssertion { bytes32 dataId; // The dataId that was asserted. bytes32 data; // This could be an arbitrary data type. address asserter; // The address that made the assertion. bool resolved; // Whether the assertion has been resolved. } Copy cast --abi-decode "assertionsData(bytes32)(bytes32,bytes32,address,bool)" \ $(cast call $DATA_ASSERTER "assertionsData(bytes32)" $ASSERTION_ID) Copy cast rpc evm_increaseTime 7200 cast rpc evm_mine Copy cast send --mnemonic "$MNEMONIC" $OOV3_ADDRESS "settleAssertion(bytes32)" $ASSERTION_ID Copy cast --abi-decode "assertionsData(bytes32)(bytes32,bytes32,address,bool)" \ $(cast call $DATA_ASSERTER "assertionsData(bytes32)" $ASSERTION_ID) Copy read -r IS_RESOLVED RESOLVED_DATA \ < <(cast --abi-decode "getData(bytes32)(bool,bytes32)" \ $(cast call $DATA_ASSERTER "getData(bytes32)" $ASSERTION_ID) \ | awk '{s=(NR==1?s:s " ")$0}END{print s}') Copy echo $IS_RESOLVED Copy cast --parse-bytes32-string $RESOLVED_DATA --- # Network Information | UMA Documentation #### [](https://docs.uma.xyz/resources/network-addresses#monitored) Monitored Risk Labs operates monitoring bots for the following networks and integrations for additional resiliency. UMA Contract Addresses Chain ID Fully Permissionless Settlement DVM Support Oracle UI [Ethereum Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/1.json) _(Across only)_ 1 Yes Yes [Yes](https://oracle.uma.xyz/) [Polygon Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/137.json) _(Polymarket only)_ 137 Yes Yes [Yes](https://oracle.uma.xyz/) #### [](https://docs.uma.xyz/resources/network-addresses#unmonitored) Unmonitored The following networks are supported, but Risk Labs does not provide additional monitoring If you plan to integrate UMA's optimistic oracle, we recommend you run your own monitoring bots to provide additional resiliency. UMA's data verification mechanism (DVM), which is used to resolve disputes, is on Ethereum mainnet. Where possible, UMA uses a chain's native messaging bridge to relay dispute and governance information between that chain and Ethereum. On chains where no such native messaging bridge exists, UMA uses a multi-sig controlled by UMA core engineers at Risk Labs to relay disputes to the DVM, to return data from the DVM to requesters on that chain, and to execute governance actions (for instance, adding new identifiers). UMA Contract Addresses Chain ID Fully Permissionless Settlement DVM Support Oracle UI [Ethereum Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/1.json) 1 Yes Yes [Yes](https://oracle.uma.xyz/) [Ethereum Sepolia](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/11155111.json) _(testnet)_ 11155111 Yes No [Yes](https://testnet.oracle.uma.xyz/) [Polygon Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/137.json) 137 Yes Yes [Yes](https://oracle.uma.xyz/) [Polygon Amoy](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/80002.json) _(testnet)_ 80002 Yes No [Yes](https://testnet.oracle.uma.xyz/) [Optimism Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/10.json) 10 Yes Yes [Yes](https://oracle.uma.xyz/) [Arbitrum Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/42161.json) 42161 Yes Yes [Yes](https://oracle.uma.xyz/) [Base Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/8453.json) 8453 Yes Yes [Yes](https://oracle.uma.xyz/) [Base Sepolia](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/84532.json) _(testnet)_ 84532 Yes No No [Blast Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/81457.json) 81457 Yes Yes [Yes](https://oracle.uma.xyz/) [Blast Sepolia](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/168587773.json) _(testnet)_ 168587773 Yes No No [Story Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/1514.json) 1514 Multi-sig relay Yes [Yes](https://oracle.uma.xyz/) [Avalanche C-Chain](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/43114.json) 43114 Multi-sig relay Yes No #### [](https://docs.uma.xyz/resources/network-addresses#deprecated) Deprecated UMA Contract Addresses Chain ID Fully Permissionless Settlement DVM Support Oracle UI [Story Odyssey](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/1516.json) _(testnet)(deprecated)_ 1516 Yes No [Yes](https://testnet.oracle.uma.xyz/) [Boba Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/288.json) (_Deprecated)_ 288 n/a No No [Core Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/1116.json) (_Deprecated)_ 1116 n/a No No [Ethereum Kovan](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/42.json) (_(testnet)(deprecated)_ 42 n/a No No [Ethereum Rinkeby](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/4.json) _(testnet)(deprecated)_ 4 n/a No No [Ethereum Göerli](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/5.json) (_(testnet)(deprecated)_ 5 Yes No No [Polygon Mumbai](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/80001.json) _(testnet)(deprecated)_ 80001 Yes No [Yes](https://testnet.oracle.uma.xyz/) [Arbitrum Rinkeby](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/421611.json) _(testnet)(deprecated)_ 421611 Yes No No [Gnosis Chain Mainnet](https://github.com/UMAprotocol/protocol/blob/master/packages/core/networks/100.json) (_Deprecated)_ 100 n/a No No [PreviousoSnap](https://docs.uma.xyz/verification-guide/osnap) [NextNew Network Requests](https://docs.uma.xyz/resources/network-addresses/new-network-requests) Last updated 1 month ago Was this helpful? Was this helpful? --- # Escalation Managers | UMA Documentation ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#table-of-contents) Table of Contents 1. [Introduction](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#introduction) 2. [Use Cases](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#use-cases) 3. [Events](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#events) 4. [Functions](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#functions) 5. [Getting Started](https://chat.openai.com/chat/9433ce54-7882-46cc-975a-4877b66aaf8c#getting-started) ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#introduction) Introduction The [Full Policy Escalation Manager](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/escalation-manager/FullPolicyEscalationManager.sol) [](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/escalation-manager/FullPolicyEscalationManager.sol#L6) is an example implementation of [Escalation Manager](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/escalation-manager/BaseEscalationManager.sol) that allows for a high level of control over the arbitration process in the [Optimistic Oracle V3](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol) . It can be used to set various policy parameters such as who is able to assert truths, who is able to file disputes, and whether disputes should be arbitrated via the escalation manager or the [UMA Data Verification Mechanism (DVM)](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) . By using the Escalation Managers, such as the Full Policy Escalation Manager, users can better tailor the arbitration process to suit their specific needs and security requirements. An Escalation Manager is a smart contract that is used in the Optimistic Oracle V3 to handle the escalation policy for assertions and can also be used to arbitrate disputes. When one party makes an assertion, it might be challenged by another, known as the disputer. In the event of a dispute, the Escalation Manager is used to decide how the dispute should be handled and how the Optimistic Oracle V3 should respond to it. The Full Policy Escalation Manager is an Escalation Manager implementation that allows the contract owner to set all policy parameters and store arbitration resolutions for the Escalation Manager. Some of the key functionality that the Full Policy Escalation Manager allows are: * Enabling a whitelist of asserting callers, asserters and disputers. This allows the owner to limit who can assert truths, and who can dispute assertions. * Determining whether disputes should be arbitrated by the Escalation Manager or by the Data Verification Mechanism (DVM). * Determining whether the resolution of a potential dispute arbitrated by the Oracle should be disregarded (i.e a disputed assertion defaults to false outcome). * Storing and managing the arbitration resolutions for a given identifier, time and ancillary data. This smart contract is ideal for use cases where a high degree of control over the behaviour of the Escalation Manager is needed, and where the owner wants to have a say in how disputes are handled and acts as a good starting point for projects that want to build their own escalation managers that implement custom logic. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#use-cases) Use Cases The FullPolicyEscalationManager can be used in a variety of ways depending on the specific needs of the project. Below are a few examples of possible use cases and how to configure the escalation manager for each: * **Blocking assertions by untrusted parties**: In this case, the project may want to prevent assertions from being made by certain parties that are not trusted. To accomplish this, the `blockByAssertingCaller` and/or `blockByAsserter` parameters can be set to `true` and the corresponding whitelists can be populated with trusted parties using the `setAssertingCallerWhitelist` and `setAsserterWhitelist` functions. * **Validation of disputers**: In some cases, the project may want to prevent disputes from being filed by untrusted parties. To accomplish this, the `validateDisputers` parameter can be set to `true` and the `whitelistedDisputeCallers` whitelist can be populated with trusted parties using the `setDisputeCallerWhitelist` function. * **Allowing arbitration via the escalation manager**: By default, disputes are arbitrated via the UMA DVM. However, in some cases, the project may want to use the escalation manager to arbitrate disputes instead. To accomplish this, the `arbitrateViaEscalationManager` parameter can be set to `true`. * **Discarding the oracle resolution**: In some cases, the project may want to disregard the oracle's resolution when arbitrating disputes. To accomplish this, the `discardOracle` parameter can be set to `true`. * **Custom arbitration resolution**: If the project wants to define a custom resolution for a given identifier, time, and ancillary data, it can be set using the `setArbitrationResolution` function. * **Mixing different options**: The FullPolicyEscalationManager can be customized to mix different options, such as allowing arbitration via the escalation manager, but also blocking assertions by untrusted parties, or validating disputers but also allowing custom arbitration resolution. It's important to note that the values of `blockByAssertingCaller`, `blockByAsserter`, `validateDisputers`, `arbitrateViaEscalationManager`, `discardOracle` are set to false by default. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#events) Events * `EscalationManagerConfigured`: Emitted when the escalation manager is configured using the `configureEscalationManager` function. The event contains the following parameters: * `blockByAssertingCaller`: A boolean indicating whether assertions are allowed only by whitelisted asserting callers. * `blockByAsserter`: A boolean indicating whether assertions are allowed only by whitelisted asserters. * `validateDisputers`: A boolean indicating whether the escalation managershould validate disputers via the whitelistedDisputeCallers mapping. * `arbitrateViaEscalationManager`: A boolean indicating whether it is determined that the escalation manager should arbitrate disputes. * `discardOracle`: A boolean indicating whether the escalation manager should disregard the Oracle’s resolution of disputes. * `ArbitrationResolutionSet`: Emitted when an arbitration resolution is set using the `setArbitrationResolution` function. The event contains the following parameters: * `identifier`: The identifier of the assertion. * `time`: The time of the assertion. * `ancillaryData`: The ancillary data of the assertion. * `resolution`: The resolution of the arbitration. * `DisputeCallerWhitelistSet`: Emitted when a dispute caller is added or removed from the whitelistedDisputeCallers mapping using the `addDisputeCallerToWhitelist` and `removeDisputeCallerFromWhitelist` functions. The event contains the following parameters: * `disputeCaller`: The address of the dispute caller that was added or removed from the whitelist. * `whitelisted`: A boolean indicating whether the dispute caller was added (true) or removed (false) from the whitelist. * `AssertingCallerWhitelistSet`: Emitted when an asserting caller is added or removed from the whitelistedAssertingCallers mapping using the `addAssertingCallerToWhitelist` and `removeAssertingCallerFromWhitelist` functions. The event contains the following parameters: * `assertingCaller`: The address of the asserting caller that was added or removed from the whitelist. * `whitelisted`: A boolean indicating whether the asserting caller was added (true) or removed (false) from the whitelist. * `AsserterWhitelistSet`: Emitted when an asserter is added or removed from the whitelistedAsserters mapping using the `addAsserterToWhitelist` and `removeAsserterFromWhitelist` functions. The event contains the following parameters: * `asserter`: The address of the asserter to add. * `whitelisted`: true represents adding and false represents removing the asserter from the whitelist. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#functions) Functions ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getassertionpolicy) `**getAssertionPolicy**` This function returns the Assertion Policy defined by the contract's parameters and functions. **Parameters** * `assertionId`: the ID of the assertion to get the policy for. **Returns** * `AssertionPolicy memory`: an object that contains the following properties: * `blockAssertion`: a boolean indicating whether the assertion is blocked or not. * `arbitrateViaEscalationManager`: a boolean indicating whether the arbitration should be done via the escalation manager if it is configured. * `discardOracle`: a boolean indicating whether to ignore the Oracle (DVM or EM) resolution if it is configured. * `validateDisputers`: a boolean indicating whether to validate disputers if it is configured. **Notes** If no configuration is done after deployment, this function returns an all false default policy. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getprice) `**getPrice**` The `getPrice` function allows developers to retrieve the resolved price for a given identifier and timestamp. It replicates the interface of the corresponding DVM function to allow the user to use his own dispute arbitration system when arbitrating via the escalation manager in a DVM-compatible manner. It is useful when you want to get the resolved price for a specific request. **Parameters** * `identifier`: A unique identifier that identifies the price requested. * `time`: A unix timestamp of the price request. * `ancillaryData`: Arbitrary data appended to a price request to give the voters more info from the caller. **Returns** * `int256`: representing the resolved price for the given identifier and timestamp. **Notes** If the price is not available, the method reverts. Also, the function requires that the arbitration resolution has been set before calling it. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#isdisputeallowed) `**isDisputeAllowed**` This function returns whether a given disputerCaller is authorized to dispute a given assertionId or not. **Parameters** * `assertionId`: The ID of the assertion to check the disputerCaller for. * `disputeCaller`: The address of the disputeCaller to check. **Returns** * `bool`: true if the disputerCaller is authorized to dispute the assertion, false otherwise. **Notes** * In order for this function to be used by the Optimistic Oracle V3, validateDisputers must be set to true. * The whitelistedDisputeCallers is a mapping that contains the addresses of the authorized disputers, which are set through the setDisputeCallerInWhitelist function. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#configureescalationmanager) `**configureEscalationManager**` This function is used to configure the escalation manager and define the assertion policy for each configuration's rules. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#parameters) Parameters * `_blockByAssertingCaller`: A boolean value that indicates if assertions are allowed only by whitelisted asserting callers. * `_blockByAsserter`: A boolean value that indicates if assertions are allowed only by whitelisted asserters. * `_validateDisputers`: A boolean value that indicates if the escalation manager should validate disputers via whitelistedDisputeCallers. * `_arbitrateViaEscalationManager`: A boolean value that indicates if the escalation manager should arbitrate instead of the DVM. * `_discardOracle`: A boolean value that indicates if the escalation manager should disregard the Oracle's (DVM or EM) resolution. **Notes** * This function can only be called by the contract's owner. * It is important to note that this function only activates the rules that will be executed, each rule must additionally be defined using the other functions. * The \_blockByAsserter must be true if \_blockByAssertingCaller is true. * When this function is called, an event `EscalationManagerConfigured` is emitted with the parameters of the function call. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setarbitrationresolution) `**setArbitrationResolution**` This function is used to set the arbitration resolution for a given identifier, time, and ancillary data. This function should be used by the contract owner whenever a dispute arises and it should be arbitrated by the Escalation Manager. The owner of the contract is responsible for determining how to resolve the dispute. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#parameters-1) Parameters * **identifier**: A unique identifier that represents the price requested. This is used to identify the price request in question. * **time**: A unix timestamp of the price request. * **ancillaryData**: Arbitrary data that is appended to a price request to give the voters more information from the caller. * **arbitrationResolution**: A boolean value that indicates if the assertion should be resolved as true (true) or false (false). #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#notes) Notes * This function is only callable by the owner of the contract. * This function requires that the `arbitrationResolutions[requestId].valueSet` is equal to false, otherwise the function will revert with the error message "Arbitration already resolved". * A `ArbitrationResolutionSet` event is emitted with the parameters `identifier`, `time`, `ancillaryData`, and `arbitrationResolution` when this function is called. * The `getRequestId` function is used to generate a requestId to uniquely identify the price request. The requestId is generated from the identifier, time, and ancillaryData parameters. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setdisputecallerinwhitelist) `**setDisputeCallerInWhitelist**` The `setDisputeCallerInWhitelist` function allows the owner of the `FullPolicyEscalationManager` contract to add or remove a given address (`disputeCaller`) to the whitelist of addresses that are able to file disputes. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#parameters-2) Parameters * `disputeCaller`: The address of the dispute caller to add or remove from the whitelist. * `value`: A boolean value that represents whether the `disputeCaller` is being added (`true`) or removed (`false`) from the whitelist. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#notes-1) Notes This function is only used if the `validateDisputers` parameter is set to `true`. When a dispute caller is added or removed from the whitelist, the `DisputeCallerWhitelistSet` event is emitted with the `disputeCaller` and `value` as the arguments. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setwhitelistedassertingcallers) `**setWhitelistedAssertingCallers**` This function allows the owner of the contract to add or remove an address from the whitelist of asserting callers that are authorized to make assertions. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#parameters-3) Parameters * `assertingCaller`: The address of the asserting caller to add or remove from the whitelist. * `value`: A boolean value that represents whether the asserting caller is being added (`true`) or removed (`false`) from the whitelist. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#notes-2) Notes * This function can only be called by the owner of the contract. * An event `AssertingCallerWhitelistSet` is emitted upon the successful execution of this function, which includes the `assertingCaller` and the `value` as the arguments. * The whitelist of asserting callers is used when the `blockByAssertingCaller` configuration is set to `true`. In this case, only addresses in the whitelist are allowed to make assertions. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setwhitelistedasserters) `**setWhitelistedAsserters**` This function allows an owner to add or remove an address from the whitelist of authorized asserters. **Parameters** * `asserter`: The address of the asserter to add or remove from the whitelist. * `value`: A boolean value that determines whether the asserter is added or removed from the whitelist. `true` represents adding the asserter to the whitelist and `false` represents removing the asserter from the whitelist. **Notes** * This function can only be called by the contract owner. * This function must be used in conjunction with `setWhitelistedAssertingCallers` in order to have an effect. This means that if `setWhitelistedAssertingCallers` is set to true, the assertion will only be made by an address that is in both whitelists `whitelistedAssertingCallers` and `whitelistedAsserters`. * When an asserter is added or removed from the whitelist, an event `AsserterWhitelistSet` is emitted with the `asserter` and `value` as the arguments. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getting-started) Getting started To get started with the Full Policy Escalation Manager, the first step is to deploy the contract on the EVM network. This can be done using hardhat and a library such as `ethers.js`. Here is an example of how to deploy the contract: Once the contract is deployed, it can be configured to handle disputes in different ways, depending on the use case. The `configureEscalationManager` function can be used to set the rules for how disputes should be handled. Here are some examples of how to configure the contract for different use cases: Example 1: Example 2: Example 3: The Full Policy Escalation Manager can be configured for a variety of use cases depending on the requirements. The examples above show how to deploy the contract, configure it for different use cases and whitelist asserting callers, asserters and disputers. Keep in mind that the contract can only be configured by the owner and that the parameters of configureEscalationManager function must be set according to the desired use case. [PreviousData Asserter](https://docs.uma.xyz/developers/optimistic-oracle-v3/data-asserter) [NextSandboxed Oracle Environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/sandboxed-oracle-environment) Last updated 8 months ago Was this helpful? * [Table of Contents](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#table-of-contents) * [Introduction](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#introduction) * [Use Cases](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#use-cases) * [Events](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#events) * [Functions](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#functions) * [getAssertionPolicy](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getassertionpolicy) * [getPrice](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getprice) * [isDisputeAllowed](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#isdisputeallowed) * [configureEscalationManager](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#configureescalationmanager) * [setArbitrationResolution](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setarbitrationresolution) * [setDisputeCallerInWhitelist](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setdisputecallerinwhitelist) * [setWhitelistedAssertingCallers](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setwhitelistedassertingcallers) * [setWhitelistedAsserters](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#setwhitelistedasserters) * [Getting started](https://docs.uma.xyz/developers/optimistic-oracle-v3/escalation-managers#getting-started) Was this helpful? Copy const hre = require("hardhat"); import { FullPolicyEscalationManagerEthers__factory } from "@uma/contracts-node"; const { getContractFactory } = hre.ethers; const { getAddress } = require("@uma/contracts-node"); async function main() { console.log("Running FullPolicyEscalationManager Deployments🔥"); const networkId = Number(await hre.getChainId()); const optimisticOracleV3 = getAddress("OptimisticOracleV3", networkId); const fullPolicyEscalationManagerFactory: FullPolicyEscalationManagerEthers__factory = await getContractFactory( "FullPolicyEscalationManager" ); const fullPolicyEscalationManager = await fullPolicyEscalationManagerFactory.deploy(optimisticOracleV3); console.log("Deployed FullPolicyEscalationManager: ", fullPolicyEscalationManager.address); } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); }); Copy //Configure the contract to block assertions by asserting callers that are not whitelisted await fullPolicyEscalationManager.configureEscalationManager(true, false, false, false, false); //Whitelist an asserting caller and asserter await fullPolicyEscalationManager.setWhitelistedAssertingCallers("0x123456789abcdef0123456789abcdef0123456789", true); Copy //Configure the contract to validate disputers and arbitrate via the escalation manager await fullPolicyEscalationManager.configureEscalationManager(false, false, true, true, false); //Whitelist a dispute caller await fullPolicyEscalationManager.setDisputeCallerInWhitelist("0x123456789abcdef0123456789abcdef0123456789", true); Copy //Configure the contract to disregard the oracle's resolution await fullPolicyEscalationManager.configureEscalationManager(false, false, false, false, true); --- # FAQs | UMA Documentation [](https://docs.uma.xyz/faqs#general-questions) General Questions ---------------------------------------------------------------------- **What is UMA?**[](https://docs.uma.xyz/faqs#what-is-uma) UMA is a decentralized protocol designed to verify real-world information onchain in a trustless and secure manner. It consists of an **optimistic oracle (OO)** and a **data verification mechanism (DVM)** to help apps trustlessly verify real-world data using economic guarantees and community resolution. **Why does UMA matter?**[](https://docs.uma.xyz/faqs#why-does-uma-matter) Decentralized applications need trustworthy data to function. However, blockchains and smart contracts are inherently disconnected from real-world data. UMA bridges this gap by providing a scalable, secure, and cost-effective way to verify offchain (and onchain) information without relying on a centralized oracle. **How does UMA compare to Chainlink?**[](https://docs.uma.xyz/faqs#how-does-uma-compare-to-chainlink) Chainlink streams data onchain at regular intervals. UMA is a request-based, dispute-driven system that verifies data only when needed, offering cost savings and support for broader data types. **What makes UMA different from other oracles?**[](https://docs.uma.xyz/faqs#what-makes-uma-different-from-other-oracles) Most oracles can only process purely objective data (e.g. price feeds). UMA is uniquely built to process and verify objective _and_ intersubjective data (e.g. sports scores, election outcomes, cultural events, etc.). UMA’s OO enables smart contracts to verify intersubjective claims such as “Did the Eagles win the Super Bowl?”, “Did Donald Trump say ‘Tesla’ in the debate last night?” or “Did xyz proposal pass?" All these claims are verified using a decentralized dispute resolution system backed by economic guarantees. Additionally, rather than pushing data onchain by default, UMA uses an optimistic system where proposed data is assumed correct unless challenged. This design allows for fast verification through the OO, while still enabling secure dispute resolution through the DVM. If a dispute is raised, a decentralized network of UMA token stakers vote on the correct answer using offchain information. This layered structure is fast when there’s consensus and robust when there’s conflict, making UMA more flexible, cost-effective, and secure than traditional oracles. **Can UMA verify data about real-world events?**[](https://docs.uma.xyz/faqs#can-uma-verify-data-about-real-world-events) Yes. UMA can verify outcomes of real-world events like elections, sports results, weather outcomes, or legal rulings inasmuch as there's public, credible evidence that voters can independently verify. **What types of projects are best suited to use UMA?**[](https://docs.uma.xyz/faqs#what-types-of-projects-are-best-suited-to-use-uma) Any project that requires robust, onchain data verification. The most popular use cases in production include prediction markets (e.g. [Polymarket](https://polymarket.com/) ), crosschain bridges (e.g. [Across Protocol](https://across.to/) ), DAO governance (e.g. oSnap integrations with Developer DAO, Everclear, Nexus Mutual, etc.), and IP ownership protocols (e.g. [Story Protocol](https://www.story.foundation/) ). **Is UMA only for DeFi?**[](https://docs.uma.xyz/faqs#is-uma-only-for-defi) No. UMA can be used anywhere trustless verification is needed. While its roots are in DeFi, UMA supports use cases across prediction markets, DAO governance, crosschain interop, insurance, gaming, and much more. * * * [](https://docs.uma.xyz/faqs#how-uma-works) How UMA Works -------------------------------------------------------------- **What is the optimistic oracle?**[](https://docs.uma.xyz/faqs#what-is-the-optimistic-oracle) UMA’s [optimistic oracle (OO)](https://blog.uma.xyz/articles/what-is-umas-optimistic-oracle) is a decentralized verification protocol that lets anyone propose data onchain. If no one disputes the data within a predefined liveness period, it's considered verified. If disputed, the claim goes to a community vote via the DVM. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FCtL0JhxcqDpoWrhlOAlM%252Fimage.png%3Falt%3Dmedia%26token%3Ddaf38ae0-d507-4185-8d99-a77080a47512&width=768&dpr=4&quality=100&sign=178d036e&sv=2) **What is the DVM?**[](https://docs.uma.xyz/faqs#what-is-the-dvm) The [Data Verification Mechanism (DVM)](https://docs.uma.xyz/protocol-overview/dvm-2.0) is UMA’s dispute resolution system. It uses a commit-reveal voting process where UMA tokenholders vote on the correct answer to a disputed data request. Honest voters earn rewards; incorrect or absent voters are penalized. **How long does it take to verify data with UMA’s system?**[](https://docs.uma.xyz/faqs#how-long-does-it-take-to-verify-data-with-umas-system) If undisputed, data is verified after the liveness period, which is configurable and should be set based on your use case. Currently, integrations set their liveness period between 2 hours to 2 days. If undisputed, the data is verified after the liveness period. In the rare case of a dispute, the DVM vote resolves the case within 2-4 days. **What is the economic model behind UMA?**[](https://docs.uma.xyz/faqs#what-is-the-economic-model-behind-uma) UMA relies on the principle of economic guarantees. Economic incentives are in place for every participant, from proposers, disputers, and voters—to ensure that everyone behaves honestly. This economic model ensures that corrupting the protocol (e.g., by submitting false data or voting dishonestly) is more expensive than the potential profit from doing so. **Can I trust UMA without understanding how it works?**[](https://docs.uma.xyz/faqs#can-i-trust-uma-without-understanding-how-it-works) Yes, UMA is designed to be trustless. The economic game theory ensures that data is highly likely to be accurate, even if you don’t personally verify each step. * * * [](https://docs.uma.xyz/faqs#osnap-and-dao-tooling) oSnap and DAO Tooling ------------------------------------------------------------------------------ **What is oSnap?**[](https://docs.uma.xyz/faqs#what-is-osnap) [oSnap](https://docs.uma.xyz/developers/osnap) is UMA’s governance automation tool. It connects Snapshot votes with onchain execution, letting DAOs run offchain votes and trustlessly execute them onchain with UMA’s OO securing the results. Notable users include Across, Developer DAO, Nexus Mutual, and many more. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252Fs3RJYIYHzBVRKa61NjCr%252Fimage.png%3Falt%3Dmedia%26token%3D3c96cf26-f670-44c4-8687-b6aaa76feddc&width=768&dpr=4&quality=100&sign=3b6b2de5&sv=2) **Does oSnap ensure the integrity of governance execution?**[](https://docs.uma.xyz/faqs#does-osnap-ensure-the-integrity-of-governance-execution) Yes. By anchoring Snapshot votes to UMA’s decentralized verification process, oSnap ensures that governance outcomes cannot be tampered with between voting and execution. **How does oSnap ensure secure governance execution?**[](https://docs.uma.xyz/faqs#how-does-osnap-ensure-secure-governance-execution) oSnap posts a bond-backed proposal to the OO after a Snapshot vote concludes. If no one disputes the validity of the vote outcome, the proposal is executed onchain automatically. If disputed, the DVM resolves it through tokenholder voting. * * * [](https://docs.uma.xyz/faqs#uma-participants-proposers-disputers-and-voters) UMA Participants (Proposers, Disputers, and Voters) -------------------------------------------------------------------------------------------------------------------------------------- ### [](https://docs.uma.xyz/faqs#proposing-data) Proposing Data **What kinds of data can be proposed?**[](https://docs.uma.xyz/faqs#what-kinds-of-data-can-be-proposed) Any peice of information that can be verified with public evidence or consensus: asset prices, sporting event outcomes, governance results, hack confirmations, crosschain transfers, and more. **How do I propose data?**[](https://docs.uma.xyz/faqs#how-do-i-propose-data) Use the [UMA OO dApp](https://oracle.uma.xyz/propose) to submit data to the OO. Under the “Propose” tab, you can view the full list of live queries and choose which one you want to propose an answer to. You’ll need to post a bond and specify details for the request. If undisputed during the liveness window, the data is finalized and published onchain. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FFQ3Fc6cT3zczgREBW26V%252Fimage.png%3Falt%3Dmedia%26token%3D06014c5b-3af5-4d1c-9c70-a74ad8d1c17b&width=768&dpr=4&quality=100&sign=d21e6ba8&sv=2) **What are the incentives for honest behavior as a proposer?**[](https://docs.uma.xyz/faqs#what-are-the-incentives-for-honest-behavior-as-a-proposer) When a proposer is correct, they receive a posted financial reward. However, when a proposer is incorrect, they lose their bond. This encourages honest participation. Dishonest participation can result in financial losses. **What are the risks of participating as a proposer?**[](https://docs.uma.xyz/faqs#what-are-the-risks-of-participating-as-a-proposer) If you propose incorrectly or too early, you risk losing your bond. **Can I automate participation as a proposer?**[](https://docs.uma.xyz/faqs#can-i-automate-participation-as-a-proposer) Yes. Bots can be written to monitor for proposals based on predefined logic. UMA encourages automation for higher participation, but does not provide these services. ### [](https://docs.uma.xyz/faqs#disputing-data) Disputing Data **How do I dispute incorrect data?**[](https://docs.uma.xyz/faqs#how-do-i-dispute-incorrect-data) Submit a dispute through the [UMA OO dApp](https://oracle.uma.xyz/) within the liveness period. Under the “Verify” tab, you can view the full list of live proposals currently in their challenge period and choose which one you want to dispute. You'll need to post a bond and the request will escalate to the DVM for resolution. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FLWVOwiwILI5tHeOYJ4Zq%252Fimage.png%3Falt%3Dmedia%26token%3D083ab384-c0b7-46e7-88db-e8e27f966525&width=768&dpr=4&quality=100&sign=6effb8ec&sv=2) **What are the incentives for honest behavior as a disputer?**[](https://docs.uma.xyz/faqs#what-are-the-incentives-for-honest-behavior-as-a-disputer) When a disputer is correct, they receive half of the proposer’s bond. However, when a disputer is incorrect, they lose their bond. This encourages honest participation. Dishonest participation can result in financial losses. **What are the risks of participating as a disputer?**[](https://docs.uma.xyz/faqs#what-are-the-risks-of-participating-as-a-disputer) If you dispute incorrectly, you risk losing your bond. **Can I automate participation as a disputer?**[](https://docs.uma.xyz/faqs#can-i-automate-participation-as-a-disputer) Yes. Bots can be written to monitor for proposals and auto-dispute based on predefined logic. UMA encourages automation for higher participation, but does not provide these services. ### [](https://docs.uma.xyz/faqs#voting) Voting **How do I vote on disputes?**[](https://docs.uma.xyz/faqs#how-do-i-vote-on-disputes) To vote on disputes and earn rewards, you must stake $UMA in the [UMA Voter dApp](https://vote.uma.xyz/) . From there, you can commit and reveal your votes. You cal also view upcoming votes, your $UMA rewards, and voting history. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FK9TFw51vtWfAEQmEDpEF%252Fimage.png%3Falt%3Dmedia%26token%3D0b4fdae4-12f3-4938-980a-6250969cda1f&width=768&dpr=4&quality=100&sign=64ff2b7f&sv=2) **What is the minimum UMA token amount needed to vote?**[](https://docs.uma.xyz/faqs#what-is-the-minimum-uma-token-amount-needed-to-vote) There is no minimum. Your influence is proportional to the amount of tokens staked, but participation is open and inclusive. You need to stake a minimum of 1000 $UMA to receive voting gas rebates. **How does DVM voting work?**[](https://docs.uma.xyz/faqs#how-does-dvm-voting-work) DVM voting uses a commit-reveal system: 1. **Commit**: Submit a hashed vote (24 hour window). 2. **Reveal**: Later, reveal your vote to show your answer (24 hour window). 3. **Resolve**: Rewards and slashing is based on voting accuracy. Votes are shielded, meaning that voters cannot see each other's votes until after the reveal phase starts. **How do voting rewards work?**[](https://docs.uma.xyz/faqs#how-do-voting-rewards-work) Rewards are paid in $UMA tokens. When you stake $UMA in the [UMA Voter dApp](https://vote.uma.xyz/) , you start earning rewards automatically. Your staked tokens receive a share of UMA emissions, displayed as an APY in the dApp (~17%). Disputes come through the dApp in voting rounds, in which you are responsible for participating. If you vote incorrectly or miss a vote, you lose 0.1% of your staked $UMA per incorrect vote. If you vote accurately, you earn extra rewards in proportion to your staked $UMA. These rewards are collected from inaccurate and absent voters, and are redistributed to accurate voters at the end of each voting round. **Note**: You must successfully commit and reveal your vote on time in order for your vote to count. _For more info: read our full_ [_Voting FAQ_](https://blog.uma.xyz/articles/uma-voting-faq-vote-and-earn-like-a-pro) _._ **How is the correct answer decided in UMA’s voting system**[](https://docs.uma.xyz/faqs#how-is-the-correct-answer-decided-in-umas-voting-system) In UMA’s DVM, the correct vote is determined by majority consensus. During the voting process, $UMA token stakers participate in a shielded commit-reveal scheme to cast their votes on disputed assertions. After the reveal period, token-weighted votes are tallied, and if any single voting option reaches the consensus threshold (currently 65% of staked UMA), it is considered the correct outcome. This reflects the collective judgment of informed participants, incentivized to vote accurately through rewards and penalties. Note that UMA uses the **Schelling Point** principle: the assumption that rational, well-informed voters will independently converge on the same answer. There’s no single source of truth, just the consensus of honest participants acting in their own best interest. **How much can I earn for voting correctly?**[](https://docs.uma.xyz/faqs#how-much-can-i-earn-for-voting-correctly) Voter APYs typically range between 16% and 21%, depending on emissions and participation. If you restake your rewards, you can capitalize on compound interest. Additionally, $UMA penalties from inaccurate and absent voters are redistributed as extra rewards to accurate voters at the end of each round. **What happens if I vote incorrectly?**[](https://docs.uma.xyz/faqs#what-happens-if-i-vote-incorrectly) Your staked $UMA tokens are slashed whenever you vote incorrectly. You lose approximately 0.1% of your staked amount of $UMA per vote. **What happens if I miss a vote?**[](https://docs.uma.xyz/faqs#what-happens-if-i-miss-a-vote) Your staked $UMA tokens are slashed whenever you miss a vote. You lose approximately 0.1% of your staked amount of $UMA per vote **What is P4?**[](https://docs.uma.xyz/faqs#what-is-p4) P4 is the voting option for when a proposal is submitted too early. Many proposals get disputed for being too early. For example, someone may submit the Eagles as the winner of the Super Bowl five minutes _before_ the game ends. Even if the Eagles end up winning, they weren’t the winners at the time the proposal was submitted, therefore, the proposal is too early. In these situations, you should vote P4. Always make sure to check the proposal timestamp and take it into consideration when voting. _Learn more about P4_ [_here_](https://blog.uma.xyz/articles/what-is-p4) _._ ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FCe3czPNvfR3QbzZjvbfd%252Fimage.png%3Falt%3Dmedia%26token%3Dad0614a7-c2e4-4487-9364-3248619c70de&width=768&dpr=4&quality=100&sign=1060e3c8&sv=2) **Voting gas is expensive. Do I get a refund?**[](https://docs.uma.xyz/faqs#voting-gas-is-expensive.-do-i-get-a-refund) Yes! As long as you are staking a minimum of 1000 $UMA, you will receive an ETH gas rebate at the end of each month paid in full, gwei for gwei. See more details [here](https://docs.uma.xyz/using-uma/voting-walkthrough/voting-gas-rebates) . **Are there community discussions when voting on disputes?**[](https://docs.uma.xyz/faqs#are-there-community-discussions-when-voting-on-disputes) Yes! You can find live discussions in the [UMA Voter dApp](https://vote.uma.xyz/) and in the [UMA Discord server](https://discord.com/invite/39GFUAk5bA) in the #evidence-rationale channel. **What are the incentives for honest behavior as a voter?**[](https://docs.uma.xyz/faqs#what-are-the-incentives-for-honest-behavior-as-a-voter) Incorrect voters are slashed, losing 0.1% of their staked $UMA per incorrect vote. Correct voters receive the slashed $UMA as a reward (in addition to their emissions APY). Therefore voters are incentivized to vote with the majority. Since votes are committed in secret, voters cannot copy other voters, and instead vote for the best answer where other voters will congregate. **What prevents a consensus of stakers corrupting an oracle result?**[](https://docs.uma.xyz/faqs#what-prevents-a-consensus-of-stakers-corrupting-an-oracle-result) Simply put, economic incentives. All voters have staked $UMA with a one week lock up. If they corrupt an oracle result, the value of their staked $UMA will fall drastically before the can unstake and sell. This aligns voters with the long-term success of UMA and the integrity of the Optimistic Oracle. **What are the risks of voting?**[](https://docs.uma.xyz/faqs#what-are-the-risks-of-voting) If you vote incorrectly or miss voting rounds, you lose approximately 0.1% of your staked amount of $UMA per vote. **Can I automate participation as a voter?**[](https://docs.uma.xyz/faqs#can-i-automate-participation-as-a-voter) Yes. Bots can be written to cast votes based on predefined logic. UMA encourages automation for higher participation, but does not provide these services. * * * [](https://docs.uma.xyz/faqs#technical-questions) Technical Questions -------------------------------------------------------------------------- **What is intersubjective data**[](https://docs.uma.xyz/faqs#what-is-intersubjective-data) Intersubjective data is information that may not be purely objective, but is still publicly verifiable and widely agreed upon by informed observers. It’s the sweet spot between “hard facts” and “personal opinion.” Things like election outcomes, sports results, or whether a protocol got hacked fall into this category. **What is a liveness period, and how is it determined?**[](https://docs.uma.xyz/faqs#what-is-a-liveness-period-and-how-is-it-determined) The liveness period, also known as the “challenge period”, is a window of time after a data proposal during which someone can raise a dispute. This duration is configurable and often depends on the use case’s sensitivity or urgency. The most common liveness period ranges from **2 hours to 2 days**. Many prediction markets, like Polymarket, use this configuration. Across Protocol also uses a 2-hour liveness period because it best suits its crosschain interop use case. **What chains does UMA support?**[](https://docs.uma.xyz/faqs#what-chains-does-uma-support) UMA is currently deployed and fully supported (including Oracle UI, DVM support, and oSnap functionality) on the following mainnets: * Ethereum Mainnet * Polygon Mainnet * Optimism Mainnet * Arbitrum Mainnet * Base Mainnet * Blast Mainnet * Core Mainnet * Story Mainnet For the most up-to-date list of supported networks, including testnets and partially supported chains, you can find UMA's [network information here](https://docs.uma.xyz/resources/network-addresses) . * * * [](https://docs.uma.xyz/faqs#recent-optimistic-oracle-upgrades) Recent Optimistic Oracle Upgrades ------------------------------------------------------------------------------------------------------ **What does UMIP-183 do, and why is it useful?**[](https://docs.uma.xyz/faqs#what-does-umip-183-do-and-why-is-it-useful) [UMIP-183](https://blog.uma.xyz/articles/what-is-umas-optimistic-oracle) introduced the MULTIPLE\_VALUES price identifier, allowing a single data request to return up to **seven values**. This is a major win for prediction markets, sports betting apps, and any protocol resolving multiple outcomes at once. By batching outcomes into one transaction, protocols can: * Drastically reduce gas costs. * Simplify resolution logic. * Settle multiple events faster and more efficiently. Use cases like Polymarket and sports betting platforms directly benefit from this added scale and flexibility. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FwYE3i1cOdazZmA4xN66g%252Fimage.png%3Falt%3Dmedia%26token%3D62749f30-bfd6-4945-80c1-f1ddb9f0cfc0&width=768&dpr=4&quality=100&sign=a7529308&sv=2) **What is UMIP-185, and how does it improve performance?**[](https://docs.uma.xyz/faqs#what-is-umip-185-and-how-does-it-improve-performance) [UMIP-185](https://x.com/UMAprotocol/status/1914819386369573070) allows proposers to submit **hashed or offchain-referenced data** instead of full ancillary strings. This reduces the size of onchain transactions, which: * Lowers gas fees. * Speeds up proposal submissions. * Makes oracle usage more cost-effective in congested markets. This is especially helpful for integrations that involve complex or large datasets. **What is the “slow proposer penalty,” and why was it added?**[](https://docs.uma.xyz/faqs#what-is-the-slow-proposer-penalty-and-why-was-it-added) To discourage latency in oracle activity, UMA introduced a **penalty for proposers who wait until the end of the liveness window** to submit data. This incentivizes faster responses and ensures that applications relying on the oracle don’t get bottlenecked by late proposals. Faster proposers = faster oracle = better UX for users. **How do these improvements affect the developer experience?**[](https://docs.uma.xyz/faqs#how-do-these-improvements-affect-the-developer-experience) All of these upgrades are designed to make UMA’s oracle more composable, efficient, and scalable. Whether you're resolving crosschain messages, prediction markets, or governance proposals, these tools help reduce cost and complexity while preserving trustlessness. * * * [](https://docs.uma.xyz/faqs#security) Security ---------------------------------------------------- **How secure is UMA’s economic model?**[](https://docs.uma.xyz/faqs#how-secure-is-umas-economic-model) UMA’s security comes from game theory, not just code. The protocol is designed so that honest behavior is always the most profitable strategy and dishonest actions are economically irrational. At the core of this is UMA’s use of the **Schelling Point principle**: rational voters, acting independently, are incentivized to report the truth because they know others will too. Those who vote correctly earn rewards. Those who vote incorrectly or don’t vote at all are penalized via slashing. For an attacker to corrupt UMA’s oracle, they’d need to acquire **65% of all UMA tokens**, then convince a majority of that voting power to agree on a false outcome. Not only would this be prohibitively expensive, but it would also damage the value of the token they control. This structure creates a powerful economic feedback loop: * Truthful participation is rewarded. * Dishonesty is costly. * Corruption is uneconomical. That’s how UMA turns incentive design into a security system at scale. **How secure is the DVM?**[](https://docs.uma.xyz/faqs#how-secure-is-the-dvm) To corrupt the DVM, an attacker would need to acquire 65% of all UMA tokens and convince a majority of voting power to support a dishonest resolution. This would be extremely costly, and would cost far more than the potential upside of submitting incorrect data. **What security audits has UMA undergone?**[](https://docs.uma.xyz/faqs#what-security-audits-has-uma-undergone) At UMA, we take security seriously. The protocol has undergone multiple audits by reputable firms. Notably, OpenZeppelin conducted a comprehensive audit of UMA's Across V2 contracts, providing insights and recommendations to enhance security. Additionally, UMA maintains a bug bounty program to encourage responsible disclosure of vulnerabilities. Detailed information about UMA's security audits and bug bounty program can be found in the. **How does UMA handle potential oracle manipulations or attacks?**[](https://docs.uma.xyz/faqs#how-does-uma-handle-potential-oracle-manipulations-or-attacks) UMA employs a combination of economic incentives and community consensus to mitigate the risk of oracle manipulation: * Participants proposing data are required to post bonds, which they forfeit if their data is successfully disputed. On the other hand, they earn rewards for proposing accurate data. * Disputers must also post bonds, which they forfeit if their dispute is deemed inaccurate by the DVM. On the other hand, they earn rewards for disputing inaccurate proposals. * Voters stake $UMA, which can be slashed if they vote inaccurately or are absent for voting rounds. On the other hand, they earn staking rewards for participating and voting accurately. * $UMA stakers participate in securing the DVM by voting on oracle resolutions. While small slashing and reward mechanisms exist (~0.1% of stake), the real security comes from the economic incentive to protect the system. If the DVM were corrupted, UMA’s value would likely collapse, meaning attackers would lose far more than they could gain. This economic structure creates a financial deterrent against dishonest behavior. The system is built in such a way where honesty is profitable and lying is expensive. * * * [](https://docs.uma.xyz/faqs#compatibility-and-limitations) Compatibility and Limitations ---------------------------------------------------------------------------------------------- **Are there any limitations on the types of data UMA can verify?**[](https://docs.uma.xyz/faqs#are-there-any-limitations-on-the-types-of-data-uma-can-verify) UMA's oracle is designed to verify any data that is publicly available and independently verifiable. In particular, the OO and DVM are best built to process objective and intersubjective data. This includes a wide range of data types, such as asset prices, event outcomes, and real-world occurrences. However, the OO is not suitable for data that is purely subjective or lacks a clear, verifiable source. For instance, personal opinions or unverifiable claims fall outside the scope of what UMA can accurately verify.​ **Is UMA compatible with other oracle systems?**[](https://docs.uma.xyz/faqs#is-uma-compatible-with-other-oracle-systems) Yes, UMA is designed to be complementary to other oracle systems. It can function alongside traditional oracles, providing an additional layer of verification or serving as a fallback mechanism. * * * [](https://docs.uma.xyz/faqs#operational-edge-cases) Operational Edge Cases -------------------------------------------------------------------------------- **What happens if a vote in the DVM is inconclusive or tied?**[](https://docs.uma.xyz/faqs#what-happens-if-a-vote-in-the-dvm-is-inconclusive-or-tied) In the rare event of an inconclusive or tied vote within the DVM, the dispute is rolled over into the next voting round. A rolled vote happens when a dispute doesn’t get resolved in the current voting round and gets pushed to the next one. This only happens if the vote doesn’t meet two quorum thresholds: **GAT** and **SPAT**. * **GAT (God Awful Threshold)** is a fixed minimum amount of UMA that must vote for the result to count. In DVM 2.0, that number is 5 million UMA. * **SPAT (Schelling Point Activation Threshold)** is a new rule in DVM 2.0. It requires at least 65% of staked $UMA to vote _and_ agree on the same outcome. If either threshold isn’t met, the vote rolls into the next round. It's designed this way to make sure there's both broad participation and meaningful agreement before a dispute is finalized.​ **How does UMA handle network congestion or high gas periods?**[](https://docs.uma.xyz/faqs#how-does-uma-handle-network-congestion-or-high-gas-periods) UMA is built to handle network congestion by operating across multiple L2s like Arbitrum and Optimism, reducing gas fees. On top of that, upgrades like **UMIP-185** improve efficiency by letting proposers use hashes or pointers instead of submitting full data onchain, cutting gas costs further. UMA also offers gas rebates for voters, so participation stays affordable even in high-fee environments. * * * [](https://docs.uma.xyz/faqs#building-and-integrating-with-uma) Building and Integrating with UMA ------------------------------------------------------------------------------------------------------ **What developer resources are available to get started?**[](https://docs.uma.xyz/faqs#what-developer-resources-are-available-to-get-started) Visit [docs.uma.xyz](https://docs.uma.xyz/) for integration guides, tutorials, contract templates, and walkthroughs. [UMA’s Discord](https://discord.com/invite/39GFUAk5bA) is also active for dev support. **How do I integrate UMA’s optimistic oracle into my project?**[](https://docs.uma.xyz/faqs#how-do-i-integrate-umas-optimistic-oracle-into-my-project) You can use UMA's OOV3 smart contracts to submit and verify data. Integration info and quick-start guides are available on UMA's [developer docs](https://docs.uma.xyz/developers/quick-start) . **Are there different versions of the optimistic oracle?**[](https://docs.uma.xyz/faqs#are-there-different-versions-of-the-optimistic-oracle) Yes. UMA’s OO is constantly being improved to evolve and serve in-demand use cases over time. Currently, there are two versions of the OO available: 1. **OOV2**: Implements the use of data requests. Integrations must submit data requests that can then be answered by third-party proposers. Rules must be included in the request to establish the specific parameters for proposers and disputers to follow. 2. **OOV3**: Unlike OOV2, OOV3 doesn’t implement data requests. Instead, integrations skip that step and submit their own data proposals along with the rules. The challenge period and dispute process remains the same. **Which version of UMA’s optimistic oracle should I use?**[](https://docs.uma.xyz/faqs#which-version-of-umas-optimistic-oracle-should-i-use) The primary use cases for **OOV2** include prediction markets, sports betting applications, and insurance protocols. The primary use cases for **OOV3** include crosschain infrastructure, content moderation, transaction verification, governance, and insurance protocols. **How customizable is the UMA oracle’s logic for unique applications?**[](https://docs.uma.xyz/faqs#how-customizable-is-the-uma-oracles-logic-for-unique-applications) Very. UMA was built with flexibility in mind. You can customize nearly every parameter of a request to fit your specific use case, including: * **Question format:** You decide what you're asking and how it's phrased. * **Liveness period:** Set how long others have to challenge your data. * **Bond size:** Increase the required stake for proposers or disputers to raise the cost of dishonest participation. * **Resolution criteria:** Add detailed instructions or requirements to help voters resolve disputes clearly and accurately. * **Data format:** You define the format of the data to be verified (e.g. booleans, multiple-choice, integers, or encoded data using upgrades like UMIP-185). **Can I test UMA locally or on testnet?**[](https://docs.uma.xyz/faqs#can-i-test-uma-locally-or-on-testnet) Yes. UMA offers contracts on major Ethereum testnets. Developers can simulate oracle requests, disputes, bonding, and DVM voting in staging environments. Here is the full list of supported testnet chains: * Ethereum Sepolia * Arbitrum Sepolia * Optimism Sepolia * Polygon Mumbai * Polygon Amoy * Base Sepolia * Blast Sepolia * Core Testnet * Story Odyssey You can view the full list of supported chains [here](https://docs.uma.xyz/resources/network-addresses) . **What are common use cases for UMA?**[](https://docs.uma.xyz/faqs#what-are-common-use-cases-for-uma) * Prediction markets (e.g. Polymarket) * Crosschain bridges (e.g. Across Protocol) * DAO governance (e.g. oSnap with Nexus Mutual, Developer DAO) * IP dispute verification (e.g. Story Protocol) * AI agent verification (e.g. Axal) * Insurance protocol **Why would I use UMA instead of a traditional price feed oracle?**[](https://docs.uma.xyz/faqs#why-would-i-use-uma-instead-of-a-traditional-price-feed-oracle) Price feed oracles can only handle one type of data: prices. UMA is built to handle any publicly verifiable information. That’s why UMA is the go-to oracle for onchain applications such as prediction markets, crosschain interop protocols, IP ownership layers, and many more—because each of these rely on access to verified **intersubjective data**. Price feed oracles simply can’t provide that. UMA can. Additionally, most traditional price feed oracles constantly push data onchain, even when it isn’t needed. This wastes gas and introduces attack vectors. UMA’s OO only verifies data when requested, making it more gas-efficient and censorship-resistant. It also supports **any** type of data, not just prices, allowing for use cases like governance execution, crosschain messages, and real-world event verification. There’s also a major cost advantage. Setting up and maintaining a price feed on traditional oracles is expensive. It often requires upfront coordination, whitelisting, and ongoing fees. UMA is **fully permissionless and free to use**. There are no fees to access the oracle. You only pay for gas and bonding if you interact with it directly. **How does Polymarket use UMA?**[](https://docs.uma.xyz/faqs#how-does-polymarket-use-uma) Polymarket leverages UMA's OOV2 to resolve the outcomes of its prediction markets in a decentralized and trustless manner. When Polymarket creates a prediction market, a data query is sent to the OO. Anyone can then propose the outcome to UMA's OO, which assumes the proposed result is correct unless challenged within a 48-hour predefined dispute window. If a dispute arises, it is escalated to UMA's DVM, where $UMA token holders vote to determine the accurate outcome. This system allows Polymarket to handle a wide range of markets, including those based on natural language and intersubjective data, which traditional oracles cannot process. ![](https://docs.uma.xyz/~gitbook/image?url=https%3A%2F%2F2020722513-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FKdaoNjf9AzgWFNHyPo5b%252Fuploads%252FlNkQDpizeY05fzWVs2UC%252Fimage.png%3Falt%3Dmedia%26token%3D7d6fff45-1efc-42fd-8c5a-d8fe253eb7f9&width=768&dpr=4&quality=100&sign=7bda855f&sv=2) **How does Across use UMA?**[](https://docs.uma.xyz/faqs#how-does-across-use-uma) Across is a [crosschain bridge](https://across.to/) that uses a unique variation of UMA’s OOV3 to verify crosschain Intents, which are statements of a user’s bridging transaction, before relayers are repaid. This gives Across security guarantees without needing to validate every transaction in real-time. * * * [](https://docs.uma.xyz/faqs#governance) Governance -------------------------------------------------------- **How is UMA governed?**[](https://docs.uma.xyz/faqs#how-is-uma-governed) UMA is governed by its community of $UMA tokenholders. Major protocol upgrades, parameter changes, and funding decisions are proposed, discussed, and voted on by the UMA community, primarily through offchain Snapshot votes and confirmed onchain when needed. Proposal discussions are hosted on [UMA’s Discourse page](https://discourse.uma.xyz/top?period=all) . **How can I participate in UMA governance?**[](https://docs.uma.xyz/faqs#how-can-i-participate-in-uma-governance) To participate, hold $UMA, stake it to vote, and take part in governance proposals through the [UMA Voter dApp](https://vote.uma.xyz/) and [UMA’s Snapshot Space](https://snapshot.box/#/s:uma.eth) . Important proposals are discussed in the UMA Discord and forum before voting begins. **What kinds of decisions are made through governance?**[](https://docs.uma.xyz/faqs#what-kinds-of-decisions-are-made-through-governance) Governance decisions include protocol upgrades, parameter changes (such as inflation rates or bond sizes), budget allocations, grants, and strategic initiatives for UMA’s growth and development. **How does UMA handle proposals to change protocol parameters?**[](https://docs.uma.xyz/faqs#how-does-uma-handle-proposals-to-change-protocol-parameters) Changes to UMA’s core protocol, such as inflation rates, contract upgrades, or bond sizes, are governed directly by $UMA tokenholders. Proposals are typically discussed in the community forum and Discord, then voted on through the [UMA Voter dApp](https://vote.uma.xyz/) , which uses the same secure commit-reveal process as oracle dispute resolution. While Snapshot can be used for informal temperature checks, it is **not** where binding decisions happen. Final decisions are made through onchain voting via the DVM, ensuring that changes are trustlessly approved by the UMA community. **What is the difference between dispute resolutions and governance votes on the Voter Dapp?**[](https://docs.uma.xyz/faqs#what-is-the-difference-between-dispute-resolutions-and-governance-votes-on-the-voter-dapp) Unlike dispute resolutions, voters who vote against the consensus on governance votes are not slashed. If a voter does not submit a vote on a governance vote, they are still slashed. This allows voters to vote their personal opinions without the economic disincentive of slashing. **What is the difference between protocol governance and oSnap execution?**[](https://docs.uma.xyz/faqs#what-is-the-difference-between-protocol-governance-and-osnap-execution) Protocol governance refers to changing the UMA protocol itself (e.g. inflation rate, contract upgrades, etc.). oSnap is a tool built with the OO and used to execute DAO votes trustlessly. oSnap can be used by any DAO; the UMA DAO and many other notable DAOs currently uses oSnap. **What is the role of the DVM in UMA governance?**[](https://docs.uma.xyz/faqs#what-is-the-role-of-the-dvm-in-uma-governance) The DVM is the venue where **all binding governance votes take place**. It’s the same secure, commit-reveal voting system used to resolve oracle disputes, except instead of resolving data proposals, it’s used to approve or reject protocol upgrades, parameter changes, and funding decisions. In UMA, the DVM is more than a dispute resolution system. It’s the foundation of onchain governance. Every major decision made by the DAO goes through the DVM, giving $UMA tokenholders full control over the protocol’s future. * * * [](https://docs.uma.xyz/faqs#tokenomics) Tokenomics -------------------------------------------------------- **What is the $UMA token used for?**[](https://docs.uma.xyz/faqs#what-is-the-usduma-token-used-for) $UMA is the core utility and governance token of the protocol. It’s used to stake, vote, and secure the oracle. Tokenholders help verify data, resolve disputes, and steer the protocol’s direction by participating in governance. In short: UMA aligns incentives around truth. The value of the $UMA token is directly tied to its role in maintaining honest oracle outcomes and decentralized governance. **What is the total supply and inflation schedule of the UMA token?**[](https://docs.uma.xyz/faqs#what-is-the-total-supply-and-inflation-schedule-of-the-uma-token) The supply of $UMA isn’t fixed. It’s dynamic and governed by the DAO. The protocol uses controlled inflation to incentivize participation and long-term security. The current inflation rate is set at **0.05% of the total token supply**, distributed to active, correct voters in the DVM. _Learn more about the $UMA token supply_ [_here_](https://blog.uma.xyz/articles/uma-token-supply-disclosure) _._ **How are new UMA tokens distributed?**[](https://docs.uma.xyz/faqs#how-are-new-uma-tokens-distributed) Token emissions are controlled by governance. UMA emissions are used to provide staking rewards to stakers who vote on disputes to secure the protocol. **Where can I track UMA's token metrics?**[](https://docs.uma.xyz/faqs#where-can-i-track-umas-token-metrics) The current supply of $UMA and emission rates are defined onchain and can be found [here](https://etherscan.io/address/0x7b292034084A41B9D441B71b6E3557Edd0463fa8#code) **.** * * * [](https://docs.uma.xyz/faqs#community-and-ecosystem) Community and Ecosystem ---------------------------------------------------------------------------------- **How can I contribute to UMA beyond voting?**[](https://docs.uma.xyz/faqs#how-can-i-contribute-to-uma-beyond-voting) There are tons of ways to get involved! You can build integrations, write code, create content, improve the docs, join governance discussions, or just hang out in the [UMA Discord](https://discord.gg/uma) and vibe with the community. Whether you're technical or not, there's space for you to contribute. **Are there developer grants available?**[](https://docs.uma.xyz/faqs#are-there-developer-grants-available) Yes. UMA offers grants to developers and teams building tools, integrations, or initiatives that advance the ecosystem. To apply, you’ll start by posting a proposal in the [Funding Proposals](https://discourse.uma.xyz/c/uma-protocol/funding-proposals/41) category of UMA’s governance forum. From there, the community will review and provide feedback. If the proposal gains traction, it can proceed to a Snapshot vote, and if successful, be submitted onchain with help from Risk Labs or directly by the proposer. All grant proposals are evaluated based on their technical feasibility, ecosystem impact, and funding requirements. If you have any questions about our grant program, please reach out to us in our [Discord](https://discord.gg/uma) . Yes. UMA offers grants to support developers and teams building tools, integrations, or infrastructure that strengthens the ecosystem. To apply, start by posting your idea in the [Funding Proposals](https://discourse.uma.xyz/c/uma-protocol/funding-proposals/41) category in the UMA governance forum. The community will review and provide feedback. If your proposal gains traction, it can move to a Snapshot vote, and if approved, it’ll execute onchain with help from Risk Labs or directly by the proposer. Grants are evaluated based on: * Technical feasibility * Ecosystem impact * Budget/funding needs Have questions? Come chat with us in [Discord](https://discord.gg/uma) . **What community resources exist?**[](https://docs.uma.xyz/faqs#what-community-resources-exist) Here’s where you can plug into UMA’s community and stay up to date: * [UMA Discord](https://discord.gg/uma) – Join conversations, ask questions, or just vibe. * [UMA Discourse](https://discourse.uma.xyz/) – Home of governance discussions and funding proposals. * [UMA Snapshot Space](https://snapshot.box/#/s:uma.eth) – Where tokenholders vote on proposals. * [UMA Docs](https://docs.uma.xyz/) – Developer documentation, guides, and protocol deep dives. * [UMA Blog](https://blog.uma.xyz/) – Insights, announcements, and ecosystem updates. [PreviousWhat's New!](https://docs.uma.xyz/whats-new) [NextOptimistic Oracle v2](https://docs.uma.xyz/developers/optimistic-oracle) Last updated 26 days ago Was this helpful? * [General Questions](https://docs.uma.xyz/faqs#general-questions) * [How UMA Works](https://docs.uma.xyz/faqs#how-uma-works) * [oSnap and DAO Tooling](https://docs.uma.xyz/faqs#osnap-and-dao-tooling) * [UMA Participants (Proposers, Disputers, and Voters)](https://docs.uma.xyz/faqs#uma-participants-proposers-disputers-and-voters) * [Proposing Data](https://docs.uma.xyz/faqs#proposing-data) * [Disputing Data](https://docs.uma.xyz/faqs#disputing-data) * [Voting](https://docs.uma.xyz/faqs#voting) * [Technical Questions](https://docs.uma.xyz/faqs#technical-questions) * [Recent Optimistic Oracle Upgrades](https://docs.uma.xyz/faqs#recent-optimistic-oracle-upgrades) * [Security](https://docs.uma.xyz/faqs#security) * [Compatibility and Limitations](https://docs.uma.xyz/faqs#compatibility-and-limitations) * [Operational Edge Cases](https://docs.uma.xyz/faqs#operational-edge-cases) * [Building and Integrating with UMA](https://docs.uma.xyz/faqs#building-and-integrating-with-uma) * [Governance](https://docs.uma.xyz/faqs#governance) * [Tokenomics](https://docs.uma.xyz/faqs#tokenomics) * [Community and Ecosystem](https://docs.uma.xyz/faqs#community-and-ecosystem) Was this helpful? --- # Mainnet Voting Entities | UMA Documentation ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#entities) Entities * [`User`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#user) * [`Collateral`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#collateral) * [`PriceIdentifier`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#priceidentifier) * [`PriceRequest`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequest) * [`PriceRequestRound`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequestround) * [`VoterGroup`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#votergroup) * [`CommittedVote`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#committedvote) * [`RevealedVote`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) * [`RewardsClaimed`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#rewardsclaimed) * [`FinancialContract`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#financialcontract) ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#user) User Description: Field Type Description id ID! Utility entity that links data from a single Ethereum address. Id of the entity is the Ethereum address itself address Bytes! countReveals BigInt Number of price requests that this user has revealed a vote for, and therefore participated in as a voter countRetrievals BigInt Provides a lower bound on the number of votes a user has correctly voted for. Users may not have retrieved rewards for all of their correct votes votesCommited Int! ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#collateral) Collateral Description: Field Type Description id ID! Represents approved collateral that is whitelisted in the AddressWhitelist and whose fees are set in the Store. Id of the entity is its address decimals Int! name String! symbol String! isOnWhitelist Boolean! Is token currently whitelisted as collateral finalFee BigDecimal ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#priceidentifier) PriceIdentifier Description: Field Type Description id ID! isSupported Boolean! Depicts whether this PriceIdentifier is currently among the identifiers supported on the whitelist. It will only be false if it was removed from the whitelist priceRequests [`PriceRequest!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequest) List of all the PriceRequest entities related to this particular PriceIdentifier ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequest) PriceRequest Description: Field Type Description id ID! ID is the PriceIdentifier ID + the timestamp isResolved Boolean! Depicts whether the request has been resolved price BigInt Price resolved for this request latestRound PriceRequestRound PriceRequestRound entity corresponding to the last round of voting time BigInt! identifier PriceIdentifier! PriceIdentifier for the request ancillaryData String resolutionTransaction Bytes Transaction where the resolution of the request took place resolutionTimestamp Bigint Timestamp when the resolution of the request took place resolutionBlock BigInt Block number when the resolution of the request took place rounds [`PriceRequestRound!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequestround) List of all the rounds involved in this PriceRequest committedVotes [`CommittedVote!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#committedvote) List of all the votes committed on this request revealedVotes [`RevealedVote!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) List of all the votes revealed on this request rewardsClaimed [`RewardsClaimed!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#rewardsclaimed) List of all the rewards claimed events for this request ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequestround) PriceRequestRound Description: Field Type Description id ID! ID is the PriceIdentifier ID + the timestamp + the roundId + ancillaryData (if available) request PriceRequest! identifier PriceIdentifier! ancillaryData String time BigInt! snapshotId BigInt votersAmount BigDecimal! Total amount of users who voted on this round votersClaimedAmount BigDecimal! Total amount of users who claimed rewards on this round totalVotesRevealed BigDecimal! totaRewardsClaimed BigDecimal! totalSupplyAtSnapshot BigDecimal tokenVoteParticipationRatio BigDecimal Ratio of the total supply of tokens that were weighted on this vote tokenVoteParticipationPercentage BigDecimal Ratio of correct voters over total voters on this price request votersEligibleForRewardRatio BigDecimal Ratio of correct voters over total voters on this price request votersEligibleForRewardsPercentage BigDecimal Percentage of correct voters over total voters on this price request votersClaimRatio BigDecimal Ratio of correct voters who claimed their rewards votersClaimedPercentage BigDecimal Percentage of correct voters who claimed their rewards tokensClaimedRatio BigDecimal Ratio of rewards claimed over total supply of voting token tokensClaimedPercentage BigDecimal Percentage of rewards claimed over total supply of voting token getPercentageRaw BigDecimal getPercentage expressed exactly as in the contract. 1 = 100% getPercentage BigDecimal getPercentage expressed as a percentage value inflationRateRaw BigDecimal inflationRate expressed exactly as in the contract. 1 = 100% inflationRate BigDecimal inflationRate expressed as a percentage value winnerGroup VoterGroup committedVotes [`CommittedVote!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#committedvote) revealedVotes [`RevealedVote!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) groups [`VoterGroup!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#votergroup) rewardsClaimed [`RewardsClaimed!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#rewardsclaimed) ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#votergroup) VoterGroup Description: Field Type Description id ID! Just a helper entity to group voters who voted the same price result. ID is composed of round ID + voted price price BigInt! round PriceRequestRound! votes [`RevealedVote!`](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) totalVoteAmount BigDecimal! totalVoteAmount BigInt votersAmount BigDecimal! won Boolean! ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#committedvote) CommittedVote Description: Field Type Description id ID! Committed votes won't show the price until a reveal happens and a RevealedVote is created identifier PriceIdentifier! ancillaryData String request PriceRequest! time BigInt! round PriceRequestRound! voter User! ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) RevealedVote Description: Field Type Description id ID! identifier PriceIdentifier! ancillaryData String request PriceRequest! time BigInt! round PriceRequestRound! price BigInt! voter User! numTokens BigInt! group VoterGroup! ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#rewardsclaimed) RewardsClaimed Description: Field Type Description id ID! identifier PriceIdentifier! ancillaryData String request PriceRequest! time BigInt! round PriceRequestRound! claimer User! numTokens BigInt! NumTokens will be 0 if the claim is not 'valid'. This can happen if the function was called for a voter who didn't get the correct vote for example group VoterGroup! ### [](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#financialcontract) FinancialContract Description: Field Type Description id ID! This entity represents a contract that can make price requests to the DVM. ID is the address of the contract creator Bytes! registrationTimestamp BigInt! [PreviousSubgraphs](https://docs.uma.xyz/resources/subgraph-data) [NextQueries](https://docs.uma.xyz/resources/subgraph-data/queries) Last updated 3 years ago Was this helpful? * [Entities](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#entities) * [User](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#user) * [Collateral](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#collateral) * [PriceIdentifier](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#priceidentifier) * [PriceRequest](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequest) * [PriceRequestRound](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#pricerequestround) * [VoterGroup](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#votergroup) * [CommittedVote](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#committedvote) * [RevealedVote](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#revealedvote) * [RewardsClaimed](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#rewardsclaimed) * [FinancialContract](https://docs.uma.xyz/resources/subgraph-data/mainnet-voting-entities#financialcontract) Was this helpful? --- # Internal Optimistic Oracle | UMA Documentation ### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#the-internal-optimistic-oracle) The Internal Optimistic Oracle The Internal Optimistic Oracle (IOO) implements the Optimistic Oracle's (OO) internal escalation game logic for price requests and price proposals within another contract. The disputes are escalated through the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) to [UMA's Data Verification Mechanism](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) . The IOO contract is meant to be utilized as a type of OO that permits customized escalation game logic and custom data structures. This pattern provides the most gas efficient route to building an OO integration by removing the need to perform cross-contract calls in all cases except for when a dispute is raised via the internal escalation game. The IOO is intended to be the simplest implementation possible, allowing it to serve as a starting point for any project that can benefit from these functionalities. The following table shows how the Internal Optimistic Oracle differs from the [Optimistic Oracle V2](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v2/implementation/OptimisticOracleV2.sol) and why using the Internal Optimistic Oracle could be useful: Optimistic Oracle V2 (OO) Internal Optimistic Oracle (IOO) Using the OO from an external contract incurs gas costs that, while not excessive, might be reduced with customized implementations like the IOO. Lower gas costs because price requests are processed locally. The requested data types from the OO are always `int256`. Customized data structures: the data requested from the oracle can be of any type (`uint256` in this IOO implementation). The OO design is agnostic and adaptable to every use case, but adding more advanced functionality to price requests, such as defining who can propose values, requires some extra work. Additional customization is allowed: in the example implementation, a price request is coupled with the `msg.sender`, requiring the requester and proposer to be same. Disputes are resolved in the [DVM](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) through a vote of UMA token holders. Disputes are resolved in the [DVM](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) through a vote of UMA token holders. In this simple implementation, we highlight these functionalities, however, if you wish to go further, consider the following: * The data type of the "price" (`proposedPrice`) could be any: structs, arrays, bytes. In the example, we chose `uint256`, but you can modify it to suit your requirements. _(Note: For historical reasons, the data is referred to as a "price" throughout UMA's code, but can be any type of data, not just data related to asset prices.)_ * Any further logic could be added to the requests and proposals, such as permitting only addresses on a whitelist to submit answers (`proposePrice` function). ### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#development-environment-and-tests) Development environment and tests #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#clone-repository-and-install-dependencies) Clone repository and Install dependencies Clone the [UMA dev-quickstart](https://github.com/UMAprotocol/dev-quickstart) repository and install the dependencies. To install dependencies, you will need to install the long-term support version of Nodejs, currently Nodejs v16, and yarn. You can then install dependencies by running yarn with no arguments: Copy git clone [email protected]:UMAprotocol/dev-quickstart.git cd dev-quickstart yarn #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#compiling-your-contracts) Compiling your contracts We will need to run the following command to compile the contracts and make the Typescript interfaces so that they are easy to work with: ### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#contract-implementation) Contract Implementation The contract discussed in this tutorial can be found at `dev-quickstart/contracts/InternalOptimisticOracle.sol` ([here](https://github.com/UMAprotocol/dev-quickstart/blob/main/contracts/InternalOptimisticOracle.sol) ) within the repo. #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#contract-creation-and-initialization) Contract creation and initialization The constructor of the Internal Optimistic Oracle contract takes three parameters: `_finderAddress` finder contract used to get addresses of other UMA contracts. `_currency` the collateral token used to pay fees. `_timerAddress` is used only when running unit tests locally to simulate advancement of time. For all the public networks (including testnets) zero address should be used. As part of initialization, the `oo` variable is set to the address of the `OptimisticOracleV2` implementation as discovered through the `getImplementationAddress` method in the [Finder](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/implementation/Finder.sol) contract. This address will vary depending on which chain this contract is deployed to. #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#requesting-a-price) Requesting a price The following function allows you to request a price internally in the IOO. For simplicity the [price identifier](https://docs.uma.xyz/resources/approved-price-identifiers) has been hardcoded to `YES_OR_NO_QUERY`. This imposes a set of rules on how the assertion is formulated and formatted, which are specified in [UMIP-107](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-107.md) . The `requestPrice` function takes the following arguments: * `timestamp` timestamp used to identify the request, usually the current timestamp. * `ancillaryData` the byte-converted question that we want to ask (e.g. '`q: "What uint256 are we looking for?"'`) * `reward` the amount of the `currency` defined in the constructor to pay to the proposer on settlement * `bond` the bond in the `currency` defined in the constructor that we want to require on top of the [`finalFee`](https://docs.uma.xyz/resources/approved-collateral-types) (~1500 USD worth of the currency). The [`finalFee`](https://docs.uma.xyz/resources/approved-collateral-types) can be viewed as the minimum bond required by the system to process a dispute, and the bond is any additional amount we to require on top. * `liveness` time period during which the proposal can be disputed Note: The `requestPrice` function requires the caller to approve the IOO to spend the `reward` amount of the `currency`. #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#proposing-a-price) Proposing a price Once a price has been requested, it can be proposed. These are the arguments that `proposePrice` receives: * `timestamp` timestamp used to identify the priceRequest, usually the current timestamp. * `ancillaryData` the byte-converted question that we want to ask. * `proposedPrice` the price proposed to the request Note: The `proposePrice` function requires the caller to approve the IOO to spend the `bond + finalFee` amount of the `currency`. Note: Because of the `_getId` function definition, the requester and the proposer must be the same person. #### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#disputing-a-price) Disputing a price Once a price has been proposed it can be disputed by calling `disputePrice`, this function takes the following parameters: * `timestamp` timestamp used to identify the price request, usually the current timestamp. * `ancillaryData` the byte-converted question that has been asked initially and already answered by the proposer Note: The `disputePrice` function requires the caller to approve the IOO to spend the `bond + finalFee` amount of the `currency`. Note: Because of the `_getId` function definition, the requester, proposer and disputer must be the same person. ### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#tests-and-deployment) Tests and deployment All the unit tests covering the functionality described above are available [here](https://github.com/UMAprotocol/dev-quickstart/tree/main/test/OptimisticArbitrator) . To execute all of them, run: Before deploying the contract check the comments on available environment variables in [the deployment script](https://github.com/UMAprotocol/dev-quickstart/tree/main/deploy) . In the case of the Görli testnet, the defaults would use the Finder instance that references the [Mock Oracle](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/oracle/test/MockOracleAncillary.sol) implementation for resolving DVM requests. This exposes a `pushPrice` method to be used for simulating a resolved answer in case of disputed proposals. Also, the default Görli deployment would use the already whitelisted `TestnetERC20` currency that can be minted by anyone using its `allocateTo` method. To deploy the Internal Optimistic Oracle contract on Görli, run: Optionally, you can verify the deployed contract on Etherscan: ### [](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#interacting-with-deployed-contract) Interacting with deployed contract The following section provide instructions on how to interact with the deployed contract from the Hardhat console, though one can also use it for guidance for interacting through another interface (e.g. Remix or Etherscan). Start Hardhat console with: **Initial setup** Get the libraries and connect to the necessary contracts that we are going to use. In this tutorial we are using `TestnetERC20` as the `currency` as described in the deployment script. **Request a price and propose a price without disputes** First we need to mint the `reward` amount and approve the IOO to pull them. This amount of `currency` tokens will be used to pay the proposer of the price request we are going to create. Request the price: Then we can propose a price to answer the question. The proposer needs to post a bond equal to the `request.bond + finalFee` in order to do this so let's mint and approve the tokens as before: And propose the price: Now we need to wait 10 seconds for the liveness period to be over and settle and get the price to verify the correct answer: **Request a price and propose a price with a dispute** After requesting and proposing a price we can dispute the price to escalate it to the DVM to be resolved by UMA voters. In this example we will be proposing a correct answer and disputing it, asking the DVM to determine the answer. The first steps are the same as before where we request a price and propose an answer: Then we can dispute the price: As we are in a test environment, we can simulate the vote that would normally occur by pushing a price to the mockOracle: At this point, we can call `settleAndGetPrice` to settle the accepted price request and then confirm that the result matches the proposed price: Last updated 1 year ago Was this helpful? * [The Internal Optimistic Oracle](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#the-internal-optimistic-oracle) * [Development environment and tests](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#development-environment-and-tests) * [Contract Implementation](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#contract-implementation) * [Tests and deployment](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#tests-and-deployment) * [Interacting with deployed contract](https://docs.uma.xyz/developers/optimistic-oracle/internal-optimistic-oracle#interacting-with-deployed-contract) Was this helpful? Copy yarn hardhat compile Copy constructor( address _finderAddress, address _currency, address _timerAddress ) Testable(_timerAddress) { finder = FinderInterface(_finderAddress); currency = IERC20(_currency); oo = OptimisticOracleV2Interface(finder.getImplementationAddress(OracleInterfaces.OptimisticOracleV2)); } Copy function requestPrice( uint256 timestamp, bytes memory ancillaryData, uint256 reward, uint256 bond, uint64 liveness ) public { bytes32 requestId = _getId(msg.sender, timestamp, ancillaryData); require(address(requests[requestId].currency) == address(0), "Request already initialized"); require(_getIdentifierWhitelist().isIdentifierSupported(priceIdentifier), "Unsupported identifier"); require(_getCollateralWhitelist().isOnWhitelist(address(currency)), "Unsupported currency"); require(timestamp <= getCurrentTime(), "Timestamp in future"); requests[requestId] = Request({ proposer: address(0), disputer: address(0), currency: currency, settled: false, proposedPrice: 0, reward: reward, finalFee: _getFinalFee(), bond: bond, liveness: liveness, expirationTime: 0 }); if (reward > 0) currency.safeTransferFrom(msg.sender, address(this), reward); } Copy function proposePrice( uint256 timestamp, bytes memory ancillaryData, uint256 proposedPrice ) public { Request storage request = requests[_getId(msg.sender, timestamp, ancillaryData)]; require(address(request.currency) != address(0), "Price not requested"); require(request.proposer == address(0), "Price already proposed"); request.proposer = msg.sender; request.proposedPrice = proposedPrice; request.expirationTime = uint64(getCurrentTime()) + request.liveness; request.currency.safeTransferFrom(msg.sender, address(this), request.bond + request.finalFee); } Copy function disputePrice(uint256 timestamp, bytes memory ancillaryData) public { bytes32 requestId = _getId(msg.sender, timestamp, ancillaryData); Request storage request = requests[requestId]; require(request.proposer != address(0), "No proposed price to dispute"); require(request.disputer == address(0), "Proposal already disputed"); require(uint64(getCurrentTime()) < request.expirationTime, "Proposal past liveness"); request.disputer = msg.sender; // If the final fee gets updated between the time the request is made and the time the dispute is made, the // disputer will have to pay the final fee increase x2. This is a very rare edge case that we are willing to accept. uint256 finalFeeRise = _getFinalFeeRise(request); uint256 initialBalance = request.currency.balanceOf(address(this)); request.currency.safeTransferFrom( msg.sender, address(this), request.bond + request.finalFee + 2 * finalFeeRise ); request.currency.approve(address(oo), 2 * (request.bond + request.finalFee + finalFeeRise) + request.reward); bytes memory disputeAncillaryData = _getDisputeAncillaryData(requestId); oo.requestPrice(priceIdentifier, timestamp, disputeAncillaryData, request.currency, request.reward); oo.setBond(priceIdentifier, timestamp, disputeAncillaryData, request.bond); oo.proposePriceFor(request.proposer, address(this), priceIdentifier, timestamp, disputeAncillaryData, 1e18); oo.disputePriceFor(msg.sender, address(this), priceIdentifier, timestamp, disputeAncillaryData); // If the final fee has decreased, refund the excess to the disputer & proposer. uint256 balanceToRefund = request.currency.balanceOf(address(this)) > initialBalance ? request.currency.balanceOf(address(this)) - initialBalance : 0; if (balanceToRefund > 0) request.currency.safeTransfer(msg.sender, balanceToRefund); } Copy yarn test test/InternalOptimisticOracle/* Copy NODE_URL_5=YOUR_GOERLI_NODE MNEMONIC=YOUR_MNEMONIC yarn hardhat deploy --network goerli --tags InternalOptimisticOracle Copy ETHERSCAN_API_KEY=YOUR_API_KEY yarn hardhat etherscan-verify --network goerli --license AGPL-3.0 --force-license --solc-input Copy NODE_URL_5=YOUR_GOERLI_NODE MNEMONIC=YOUR_MNEMONIC yarn hardhat console --network goerli Copy const { getAbi, getAddress } = require("@uma/contracts-node"); const { ethers } = require("hardhat"); const signer = (await ethers.getSigners())[0]; const iooDeployment = await deployments.get("InternalOptimisticOracle"); const ioo = new ethers.Contract( iooDeployment.address, iooDeployment.abi, ethers.provider ); const finder = new hre.ethers.Contract( "0xDC6b80D38004F495861E081e249213836a2F3217", // Finder address used in the deployment getAbi("Finder"), ethers.provider ); const store = new hre.ethers.Contract( await finder.getImplementationAddress( ethers.utils.formatBytes32String("Store") ), getAbi("Store"), ethers.provider ); const currency = new hre.ethers.Contract( await ioo.currency(), getAbi("TestnetERC20"), ethers.provider ); const mockOracle = new hre.ethers.Contract( await finder.getImplementationAddress( ethers.utils.formatBytes32String("Oracle") ), getAbi("MockOracleAncillary"), ethers.provider ); Copy const reward = ethers.utils.parseUnits("100", 18); await (await currency.connect(signer).allocateTo(signer.address, reward)).wait(); await (await currency.connect(signer).approve(ioo.address, reward)).wait(); Copy let requestTimestamp = await( await ethers.provider.getBlock("latest") ).timestamp; const bond = ethers.utils.parseUnits("500", 18); const liveness = 10; // 10 seconds for testing purposes const ancillaryData = ethers.utils.toUtf8Bytes( `q: "What uint256 are we looking for?"` ); await( await ioo.connect(signer).requestPrice( requestTimestamp, ancillaryData, reward, bond, liveness ) ).wait(); Copy const finalFee = await store.computeFinalFee(currency.address); const totalAmount = bond.add(finalFee.rawValue); await (await currency.connect(signer).allocateTo(signer.address, totalAmount)).wait(); await (await currency.connect(signer).approve(ioo.address, totalAmount)).wait(); Copy const correctAnswer = ethers.utils.parseEther("1"); await( await ioo .connect(signer) .proposePrice(requestTimestamp, ancillaryData, correctAnswer) ).wait(); Copy await( await ioo.connect(signer).settleAndGetPrice(requestTimestamp, ancillaryData) ).wait(); console.log( "Price is the correct answer: ", (await ioo.getPrice(requestTimestamp, ancillaryData)).eq(correctAnswer) ); Copy // get a new request timestamp requestTimestamp = await(await ethers.provider.getBlock("latest")).timestamp; // mint and approve the reward await(await currency.connect(signer).allocateTo(signer.address, reward)).wait(); await(await currency.connect(signer).approve(ioo.address, reward)).wait(); // request a new price const longerLiveness = 3600; await( await ioo .connect(signer) .requestPrice(requestTimestamp, ancillaryData, reward, bond, longerLiveness) ).wait(); // mint and approve the bond await( await currency.connect(signer).allocateTo(signer.address, totalAmount) ).wait(); await(await currency.connect(signer).approve(ioo.address, totalAmount)).wait(); // propose a price await( await ioo .connect(signer) .proposePrice(requestTimestamp, ancillaryData, correctAnswer) ).wait(); Copy // mint and approve the bond for the disputer await( await currency.connect(signer).allocateTo(signer.address, totalAmount) ).wait(); await(await currency.connect(signer).approve(ioo.address, totalAmount)).wait(); // dispute the price const receipt = await( await ioo.connect(signer).disputePrice(requestTimestamp, ancillaryData) ).wait(); Copy const disputedPriceRequest = ( await mockOracle.queryFilter(mockOracle.filters.PriceRequestAdded(), receipt.blockNumber, receipt.blockNumber) )[0]; await mockOracle.connect(signer).pushPrice( disputedPriceRequest.args.identifier, disputedPriceRequest.args.time, disputedPriceRequest.args.ancillaryData, correctAnswer // The original price is accepted ); Copy await( await ioo.connect(signer).settleAndGetPrice(requestTimestamp, ancillaryData) ).wait(); console.log( "Price is the correct answer: ", (await ioo.getPrice(requestTimestamp, ancillaryData)).eq(correctAnswer) ); --- # Email Protection | Cloudflare Please enable cookies. Email Protection ================ You are unable to access this email address docs.uma.xyz -------------------------------------------------------- The website from which you got to this page is protected by Cloudflare. Email addresses on that page have been hidden in order to keep them from being accessed by malicious bots. **You must enable Javascript in your browser in order to decode the e-mail address**. If you have a website and are interested in protecting it in a similar way, you can [sign up for Cloudflare](https://www.cloudflare.com/sign-up?utm_source=email_protection) . * [How does Cloudflare protect email addresses on website from spammers?](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) * [Can I sign up for Cloudflare?](https://developers.cloudflare.com/fundamentals/setup/account/create-account/) Cloudflare Ray ID: **9ba164118d844b11** • Your IP: Click to reveal 54.237.218.47 • Performance & security by [Cloudflare](https://www.cloudflare.com/5xx-error-landing) --- # Prediction Market | UMA Documentation This section covers the [Prediction Market contract](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/PredictionMarket.sol) , which is available in the Optimistic Oracle V3 [quick-start repo](https://github.com/UMAprotocol/dev-quickstart-oov3) and enables the creation of a binary prediction market using [Optimistic Oracle V3 (OOV3)](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol) assertions. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#prediction-market) Prediction Market A prediction market smart contract allows individuals to make predictions and place bets on the likelihood of different outcomes for a future event. These types of contracts can be used for any kind of events such as: 1. Sports games 2. Cryptocurrency price predictions 3. Product launches 4. Political policy decisions This smart contract enables the creation of prediction markets based on any off-chain event with three possible outcomes, two of which are chosen by the market creator and the third reflecting the remaining outcomes (i.e. tie or a draw in a sporting event). By participating in the prediction market, individuals can create outcome tokens (shares) and buy and sell them of the different outcomes based on their assessment of the likelihood of each outcome occurring. The market determines the price of each share based on supply and demand, and individuals can profit by purchasing shares whose value grows as the likelihood of a certain event increases. Nevertheless, this contract does not cover the selling of outcome tokens; only their creation is covered. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#development-environment) Development environment This project uses [forge](https://github.com/foundry-rs/foundry/tree/master/forge) as the Ethereum testing framework. You will also need to install Foundry, refer to [Foundry installation documentation](https://book.getfoundry.sh/getting-started/installation) if you don’t have it already. You will also need `git` for cloning the repository, as well as `bash` shell and `jq` tool in order to parse transaction outputs when interacting with deployed contracts. Clone the UMA [Optimistic Oracle V3 quick-start repository](https://github.com/UMAprotocol/dev-quickstart-oov3) and install the dependencies: Copy git clone https://github.com/UMAprotocol/dev-quickstart-oov3.git cd dev-quickstart-oov3 forge install ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#contract-implementation) Contract implementation The contract discussed in this tutorial can be found at `dev-quickstart-oov3/src/PredictionMarket.sol` ([here](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/PredictionMarket.sol) ) within the repo. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#contract-creation-and-initialization) Contract creation and initialization To initialize the state variables of the contract, the constructor takes three parameters: 1. `_finder`: address that represents the Finder contract, which is used to locate and retrieve other contracts within the system. 2. `_currency`: address that represents the currency that will be used for trading in the markets created by this contract. 3. `_optimisticOracleV3`: address that represents the OptimisticOracleV3, contract to assert truths about the world which are verified using an optimistic escalation game. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#market-creation) Market creation The `initializeMarket()` function is used to create a new market in the Prediction Market contract. Once the contract has been deployed, anyone can call `initializeMarket()` after approving the optional `reward` amount to be paid to the wallet that runs the assertion. To create a new market, the `initializeMarket()` function is called with the following parameters: * `outcome1`: A short name for the first outcome (i.e., "yes"). * `outcome2`: A short name for the second outcome (i.e., "no"). * `description`: A description of the market and the event being predicted. * `reward`: The amount of currency (in Wei) that will be available as a reward for the user that runs that creates the assertion in the OOV3, necessary to settle the market once it's ready. * `requiredBond`: The amount of currency (in Wei) that users must bond to assert the outcome of the event. Once the input checks are passed, the function creates two new ERC20 tokens (one for each outcome) using the `ExpandedERC20` contract, which extends the standard ERC20 contract by adding the ability to mint and burn tokens. The Prediction Market is assigned the minter and burner roles to simplify how the outcome tokens handled when creating, redeeming or settling the tokens. The `Market` is then created and stored internally associated to a `marketId` returned by the `initializeMarket()` and emitted in the `MarketInitialized` event at the end of the process together with the parameters defining the market. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#create-outcome-tokens) Create outcome tokens The `createOutcomeTokens` function mints a pair of tokens representing the value of outcome1 and outcome2 for a given market identified by `marketId`. This allows participants to trade on the outcome of the market by exchanging these tokens with each other outside of the scope of the Prediction Market contract. The `createOutcomeTokens` function takes two parameters: * `tokensToCreate`: an unsigned integer (`uint256`) value representing the number of tokens to be created for each outcome. The total number of tokens created will be twice this value, as two outcome tokens are created for each market. * `marketId`: a `bytes32` value representing the unique identifier of the market for which the outcome tokens are being created. The function first checks if the market exists. If the market exists, it transfers the specified amount of currency tokens from the caller to the contract using `safeTransferFrom` function from `currency` contract instance. Then, the function mints `tokensToCreate` amount of both outcome1 and outcome2 tokens to the caller using the `mint` function of the respective `ExpandedERC20` token instances. Finally, it emits an event to notify that tokens have been created. It is important to note that before calling this function, the caller must approve the contract to spend the required amount of currency tokens by calling the `approve` function on the `currency` contract instance. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#redeem-outcome-tokens) Redeem outcome tokens The `redeemOutcomeTokens` function burns an equal amount of `outcome1Token` and `outcome2Token` tokens for a given market and transfers the corresponding settlement currency tokens to the caller's account. The function takes two parameters: * `marketId`: a `bytes32` value representing the unique identifier of the market for which the tokens are being redeemed. * `tokensToRedeem`: an unsigned integer (`uint256`) value representing the number of tokens of each outcome to be redeemed. The total number of tokens redeemed will be twice this value, as two outcome tokens are burned for each market. Both parameters are passed to the function as arguments when it is called. The function first retrieves the Market data from the storage using the provided marketId. Then, it checks if the outcome1Token is not equal to the zero address, which indicates the market exists. Next, it burns the specified number of tokens for both outcome1Token and outcome2Token tokens using the `burnFrom()` function of their respective contracts, which decreases the balance of the caller's account. Finally, it transfers the specified number of settlement currency tokens from the contract's account to the caller's account using the `safeTransfer()` function. The function emits a `TokensRedeemed` event, which includes the marketId, the caller's address, and the number of tokens redeemed. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#settle-outcome-tokens) Settle outcome tokens The `settleOutcomeTokens` function allows a user to settle their outcome tokens for a given market and receive a payout in the settlement currency. The payout depends on the resolved market outcome and the number of tokens burned for each outcome. The function takes one parameter: * `marketId`: a `bytes32` value representing the unique identifier of the market for which the outcome tokens are being settled. The `marketId` parameter is passed to the function as an argument when it is called. The function first retrieves the Market data from the storage using the provided `marketId`. It then checks if the market has been resolved by verifying that the `resolved` flag in the market struct is set to `true`. If the market has not been resolved, the function throws an error. Next, the function determines how many `outcome1Token` and `outcome2Token` tokens the caller has by calling the `balanceOf()` function of their respective contracts. The balances are stored in `outcome1Balance` and `outcome2Balance` variables. After that, the function calculates the payout based on the resolved market outcome and the number of tokens burned for each outcome. If the market was resolved to the first outcome, then the payout equals the balance of `outcome1Token` while `outcome2Token` provides nothing. If the market was resolved to the second outcome, then the payout equals the balance of `outcome2Token` while `outcome1Token` provides nothing. If the market was resolved to the split outcome, then both outcome tokens provide half of their balance as currency payout. Finally, the function burns the caller's outcome tokens using the `burnFrom()` function of their respective contracts, transfers the calculated payout from the contract's account to the caller's account using the `safeTransfer()` function, and emits a `TokensSettled` event, which includes the marketId, the caller's address, the payout amount, and the number of `outcome1Token` and `outcome2Token` tokens burned. The calculated payout is returned by the function. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#assert-market) Assert market The function `assertMarket` is used to assert a market with any of the three possible outcomes: outcome1, outcome2, or unresolvable. The function takes two arguments: * `marketId`, which is a unique identifier for the market * `assertedOutcome`, which is a string representing the asserted outcome. The function first checks that the market exists by verifying that the outcome1 token is not a null address. It then computes the hash of the asserted outcome using the `keccak256` function and checks that the market does not already have an active or resolved assertion. It also checks that the asserted outcome is one of the three allowed outcomes. If all checks pass, the function sets the `assertedOutcomeId` of the market to the hash of the asserted outcome and computes the bond required to make the assertion. If the bond required by the market is higher than the minimum bond required by the oracle, the market bond is used instead. The function then composes a claim with the asserted outcome and the market description, pulls the bond from the caller's account, approves it for the oracle, and makes the assertion using the `_assertTruthWithDefaults` function. Finally, the function stores information about the asserted market and emits a `MarketAsserted` event with the market ID, the asserted outcome, and the assertion ID. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#tests-and-deployment) Tests and deployment To run the contracts tests written in solidity with forge run the following command: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#deployment) Deployment Run a local node with anvil (included in foundry toolkit) in a console: In a second console continue running the rest of commands. Let's first export the environment variables for the wallets to use: Then Deploy the UMA Oracle Sandbox contracts to be used by running: Find in the logs the `FINDER_ADDRESS` and export it with: Then use the Finder to export rest of addresses by running the following commands: We are ready to deploy the Prediction Market contract with the following command: ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#interacting-with-deployed-contract) Interacting with deployed contract It's time to initialise a market. We can first export the market parameters to use. Here the description shows that it's a market based on the outcome of a match between two teams. The two possible outcomes are `yes` or `no.` We offer 100 units of `DEFAULT_CURRENCY` to the asserter of the claim and require a bond of 5,000 units of `DEFAULT_CURRENCY` to assert or dispute the assertion. We need to mint the amount of asserter rewards and approve them before creating the market: Then we are ready to initialise the market with the `DEPLOYER_WALLET` Then we can mint the necessary tokens to then create the outcome tokens: We can now create the outcome tokens. With an amount 10,000 units of `DEFAULT_CURRENCY` we get 10,000 `OUTCOME_TOKEN_ONE` and 10,000 `OUTCOME_TOKEN_TWO` tokens: At any point before the market is settled we can redeem outcome tokens. By redeeming an amount we are burning the same amount of `OUTCOME_TOKEN_ONE` and `OUTCOME_TOKEN_TWO` to receive that amount of `DEFAULT_CURRENCY`: After redeeming 5,000 tokens we can see how both balances of `OUTCOME_TOKEN_ONE` and `OUTCOME_TOKEN_TWO` have decreased by 5,000 and `DEFAULT_CURRENCY` has increased that same amount. Now, let's simulate how the `DEPLOYER_WALLET` would trade one position of the market by transferring the remaining 5,000 `OUTCOME_TOKEN_ONE` to another user. By doing this, `DEPLOYER_WALLET` is now only exposed to the outcome two ("no") because he only holds `OUTCOME_TOKEN_TWO`. On the other side, `USER_WALLET` is exposed to the outcome one ("yes") as he has traded some other currency against `OUTCOME_TOKEN_ONE`. This trade is out of the scope of this example, thats why we simulate it by running the following transfer: At this point, let's imagine that the match between The Glacial Storms and the Electric Titans has taken place and that The Glacial Storms won. Then anyone can now `assert` that this has occurred by calling `assertMarket` with outcome `"yes"` as the claim defined in `DESCRIPTION` is true. We can do it, from the `ASSERTER_WALLET`, by running the following command: Now, let's move forward 2 hours to go pass the challenge window of the assertion: Now the assertion can be settled in the `OptimisticOracleV3`. We can do it by running the following command: We can now check how the `ASSERTER_WALLET` has received back the assertion bond plus the reward: Now, both the `DEPLOYER_WALLET` and `USER_WALLET` can settle their outcome tokens: Finally we can see how the `USER_WALLET` won the bet, as he got `OUTCOME_TOKEN_ONE` so he now has 5,000 `DEFAULT_CURRENCY` and the deployer wallet only has 5,000 `DEFAULT_CURRENCY` from his initial 10,000: Last updated 1 year ago Was this helpful? * [Prediction Market](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#prediction-market) * [Development environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#development-environment) * [Contract implementation](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#contract-implementation) * [Tests and deployment](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#tests-and-deployment) * [Interacting with deployed contract](https://docs.uma.xyz/developers/optimistic-oracle-v3/prediction-market#interacting-with-deployed-contract) Was this helpful? Copy constructor( address _finder, address _currency, address _optimisticOracleV3 ) { finder = FinderInterface(_finder); require(_getCollateralWhitelist().isOnWhitelist(_currency), "Unsupported currency"); currency = IERC20(_currency); oo = OptimisticOracleV3Interface(_optimisticOracleV3); defaultIdentifier = oo.defaultIdentifier(); } Copy function initializeMarket( string memory outcome1, // Short name of the first outcome. string memory outcome2, // Short name of the second outcome. string memory description, // Description of the market. uint256 reward, // Reward available for asserting true market outcome. uint256 requiredBond // Expected bond to assert market outcome (OOv3 can require higher bond). ) public returns (bytes32 marketId) { ... } Copy forge test --match-path *PredictionMarket* Copy anvil Copy export MNEMONIC="test test test test test test test test test test test junk" export USER_ID=1 export ASSERTER_ID=2 export DEPLOYER_WALLET=$(cast wallet address --mnemonic "$MNEMONIC") export USER_WALLET=$(cast wallet address --mnemonic "$MNEMONIC" --mnemonic-index $USER_ID) export ASSERTER_WALLET=$(cast wallet address --mnemonic "$MNEMONIC" --mnemonic-index $ASSERTER_ID) export ETH_RPC_URL="http://127.0.0.1:8545" Copy forge script script/OracleSandbox.s.sol \ --fork-url $ETH_RPC_URL \ --mnemonics "$MNEMONIC" \ --sender $DEPLOYER_WALLET \ --broadcast Copy export FINDER_ADDRESS= Copy export OOV3_ADDRESS=$(cast call $FINDER_ADDRESS "getImplementationAddress(bytes32)(address)" \ $(cast --format-bytes32-string "OptimisticOracleV3")) export DEFAULT_CURRENCY_ADDRESS=$(cast call $OOV3_ADDRESS "defaultCurrency()(address)") Copy export PREDICTION_MARKET_ADDRESS=$(forge create src/PredictionMarket.sol:PredictionMarket \ --json \ --mnemonic "$MNEMONIC" \ --constructor-args $FINDER_ADDRESS $DEFAULT_CURRENCY_ADDRESS $OOV3_ADDRESS \ | jq -r .deployedTo) echo "PREDICTION MARKET DEPLOYED TO" $PREDICTION_MARKET_ADDRESS Copy export DESCRIPTION="The Glacial Storms beat the Electric Titans on March 8, 2023 at 3:00 PM UTC, \ which is equivalent to the Unix timestamp 1686258000 seconds." export OUTCOME_ONE="yes" export OUTCOME_TWO="no" export REWARD=$(cast --to-wei 100) export REQUIRED_BOND=$(cast --to-wei 5000) Copy cast send --mnemonic "$MNEMONIC" \ $DEFAULT_CURRENCY_ADDRESS "allocateTo(address,uint256)" $DEPLOYER_WALLET $REWARD cast send --mnemonic "$MNEMONIC" \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" $PREDICTION_MARKET_ADDRESS $REWARD Copy export MARKET_ID_TX=$(cast send --json \ --mnemonic "$MNEMONIC" \ $PREDICTION_MARKET_ADDRESS \ "initializeMarket(string,string,string,uint256,uint256)(bytes32)" \ $OUTCOME_ONE $OUTCOME_TWO "$DESCRIPTION" $REWARD $REQUIRED_BOND \ | jq -r .transactionHash) export MARKET_ID=$(cast receipt --json $MARKET_ID_TX | jq -r .logs[-1].topics[1]) export OUTCOME_TOKEN_ONE_ADDRESS=$(cast --abi-decode \ "MarketInitializedNonIndexed()(string,string,string,address,address,uint256,uint256)" \ $(cast receipt --json $MARKET_ID_TX | jq -r .logs[-1].data) | awk 'NR==4 {print $1}') export OUTCOME_TOKEN_TWO_ADDRESS=$(cast --abi-decode \ "MarketInitializedNonIndexed()(string,string,string,address,address,uint256,uint256)" \ $(cast receipt --json $MARKET_ID_TX | jq -r .logs[-1].data) | awk 'NR==5 {print $1}') Copy export AMOUNT=$(cast --to-wei 10000) cast send --mnemonic "$MNEMONIC" \ $DEFAULT_CURRENCY_ADDRESS "allocateTo(address,uint256)" $DEPLOYER_WALLET $AMOUNT cast send --mnemonic "$MNEMONIC" \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" $PREDICTION_MARKET_ADDRESS $AMOUNT Copy cast send --mnemonic "$MNEMONIC" \ $PREDICTION_MARKET_ADDRESS "createOutcomeTokens(bytes32,uint256)" $MARKET_ID $AMOUNT Copy echo "BALANCE OUTCOME TOKEN ONE" $(cast call $OUTCOME_TOKEN_ONE_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "BALANCE OUTCOME TOKEN TWO" $(cast call $OUTCOME_TOKEN_TWO_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "BALANCE DEFAULT_CURRENCY" $(cast call $DEFAULT_CURRENCY_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) Copy cast send --mnemonic "$MNEMONIC" \ $PREDICTION_MARKET_ADDRESS "redeemOutcomeTokens(bytes32,uint256)" \ $MARKET_ID $(cast --to-wei 5000) Copy echo "BALANCE OUTCOME TOKEN ONE" $(cast call $OUTCOME_TOKEN_ONE_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "BALANCE OUTCOME TOKEN TWO" $(cast call $OUTCOME_TOKEN_TWO_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "BALANCE DEFAULT_CURRENCY" $(cast call $DEFAULT_CURRENCY_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) Copy cast send --mnemonic "$MNEMONIC" \ $OUTCOME_TOKEN_ONE_ADDRESS "transfer(address,uint256)" $USER_WALLET $(cast --to-wei 5000) Copy cast send --mnemonic "$MNEMONIC" \ $DEFAULT_CURRENCY_ADDRESS "allocateTo(address,uint256)" \ $ASSERTER_WALLET $REQUIRED_BOND cast send --mnemonic "$MNEMONIC" --mnemonic-index $ASSERTER_ID \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" \ $PREDICTION_MARKET_ADDRESS $REQUIRED_BOND export ASSERTION_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $ASSERTER_ID \ $PREDICTION_MARKET_ADDRESS "assertMarket(bytes32,string)" $MARKET_ID "yes" \ | jq -r .transactionHash) export ASSERTION_ID=$(cast receipt --json $ASSERTION_TX | jq -r .logs[-1].topics[2]) Copy cast rpc evm_increaseTime 7200 cast rpc evm_mine Copy cast send --mnemonic "$MNEMONIC" \ $OOV3_ADDRESS "settleAssertion(bytes32)" $ASSERTION_ID Copy echo "ASSERTER WALLET BALANCE DEFAULT_CURRENCY" \ $(cast call $DEFAULT_CURRENCY_ADDRESS "balanceOf(address)(uint256)" $ASSERTER_WALLET) Copy cast send --mnemonic "$MNEMONIC" \ $PREDICTION_MARKET_ADDRESS "settleOutcomeTokens(bytes32)" $MARKET_ID cast send --mnemonic "$MNEMONIC" --mnemonic-index $USER_ID \ $PREDICTION_MARKET_ADDRESS "settleOutcomeTokens(bytes32)" $MARKET_ID Copy echo "DEPLOYER WALLET BALANCE OUTCOME TOKEN ONE" $(cast call $OUTCOME_TOKEN_ONE_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "DEPLOYER WALLET BALANCE OUTCOME TOKEN TWO" $(cast call $OUTCOME_TOKEN_TWO_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "DEPLOYER WALLET BALANCE DEFAULT_CURRENCY" $(cast call $DEFAULT_CURRENCY_ADDRESS \ "balanceOf(address)(uint256)" $DEPLOYER_WALLET) echo "USER WALLET BALANCE OUTCOME TOKEN ONE" $(cast call $OUTCOME_TOKEN_ONE_ADDRESS \ "balanceOf(address)(uint256)" $USER_WALLET) echo "USER WALLET BALANCE OUTCOME TOKEN TWO" $(cast call $OUTCOME_TOKEN_TWO_ADDRESS \ "balanceOf(address)(uint256)" $USER_WALLET) echo "USER WALLET BALANCE DEFAULT_CURRENCY" $(cast call $DEFAULT_CURRENCY_ADDRESS \ "balanceOf(address)(uint256)" $USER_WALLET) --- # Insurance | UMA Documentation This section covers the [Insurance contract](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/Insurance.sol) , which is available in the Optimistic Oracle V3 [quick-start repo](https://github.com/UMAprotocol/dev-quickstart-oov3) . This tutorial shows an example of how insurance claims can be resolved and settled through the [Optimistic Oracle V3 (OOV3)](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/optimistic-oracle-v3/implementation/OptimisticOracleV3.sol) contract. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#insurance-contract) Insurance Contract This smart contract allows insurers to issue insurance policies by depositing the insured amount, designating the insured beneficiary, and describing the insured event. Anyone can request payout to the insured beneficiary at any time. The Insurance contract resolves the claim through the Optimistic Oracle V3 by asserting that the insured event has occurred as of request time using the default identifier `ASSERT_TRUTH` specified in [UMIP-170](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-170.md) . If the claim is confirmed and settled through the Optimistic Oracle V3, this contract automatically pays out insurance coverage to the beneficiary. If the claim is rejected, the policy continues to be active and ready for subsequent claim attempts. There is no limit to the number of payout requests that can be made of the same policy, however, only the first truthfully resolved request will settle the insurance payment, whereas the Optimistic Oracle V3 will settle bonds for all requests. ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#development-environment) Development environment This project uses [forge](https://github.com/foundry-rs/foundry/tree/master/forge) as the Ethereum testing framework. You will also need to install Foundry, refer to [Foundry installation documentation](https://book.getfoundry.sh/getting-started/installation) if you don’t have it already. You will also need `git` for cloning the repository, as well as `bash` shell and `jq` tool in order to parse transaction outputs when interacting with deployed contracts. Clone the UMA [Optimistic Oracle V3 quick-start repository](https://github.com/UMAprotocol/dev-quickstart-oov3) and install the dependencies: Copy git clone https://github.com/UMAprotocol/dev-quickstart-oov3.git cd dev-quickstart-oov3 forge install ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#contract-implementation) Contract implementation The contract discussed in this tutorial can be found at `dev-quickstart-oov3/src/Insurance.sol` ([here](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/src/Insurance.sol) ) within the repo. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#contract-creation-and-initialization) Contract creation and initialization To initialize the state variables of the contract, the constructor takes two parameters: 1. `_defaultCurrency` identifies the token used for settlement of insurance claims, as well as the bond currency for assertions and disputes. This token should be approved as whitelisted UMA collateral. Please check [Approved Collateral Types](https://docs.uma.xyz/resources/approved-collateral-types) for production networks or call `getWhitelist()` on the [Address Whitelist](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/common/implementation/AddressWhitelist.sol) contract for any of the test networks. Note that the deployed Optimistic Oracle V3 instance already has its `defaultCurrency` added to the whitelist, so it can also be used by the Insurance contract. Alternatively, you can approve a new token address with `addToWhitelist` method in the Address Whitelist contract if working in a sandboxed UMA environment. 2. `_optimisticOracleV3` is used to locate the address of UMA Optimistic Oracle V3. Address of `OptimisticOracleV3` contact can be fetched from the relevant [networks](https://github.com/UMAprotocol/protocol/tree/master/packages/core/networks) file, if you are on a live network, or you can provide your own contract instance if deploying UMA Oracle contracts in your own sandboxed testing environment. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#issuing-insurance) Issuing insurance `issueInsurance` method allows any insurer to deposit `insuranceAmount` of `defaultCurrency` tokens by designating an insurance beneficiary (`payoutAddress`) and defining the insured event (`insuredEvent`). Before calling this method, the insurer should have approved this contract to spend the required amount of `defaultCurrency` tokens. Internally, the issued policy is stored in the `policies` mapping using the calculated `policyId` key that is generated by hashing the insured event and beneficiary address. After pulling `insuranceAmount` from the caller in the `issueInsurance` method, the contract emits a `InsuranceIssued` event including the `policyId` parameter that should be used when claiming insurance. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#submitting-insurance-claim) Submitting insurance claim Anyone can submit an insurance claim on the issued policy by calling the `requestPayout` method with the relevant `policyId` parameter. This method will make an assertion with the Optimistic Oracle V3. An assertion bond is required, hence the caller should have approved this contract to spend the required minimum amount of `defaultCurrency` tokens for the proposal bond (call `getMinimumBond` method on the Optimistic Oracle V3). After checking that the `policyId` represents a valid insurance policy, the contract gets the current `timestamp` and composes claim that the insured event has occurred as of request time, that is passed to the Optimistic Oracle V3 when making the assertion with the `assertTruth` method: Optimistic Oracle V3 pulls the required bond and returns `assertionId` that is used as a key when storing the linked `policyId` in the `assertedPolicies` mapping. This information will be required when receiving a callback from the Optimistic Oracle V3. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#disputing-insurance-claim) Disputing insurance claim For the sake of simplicity this contract does not implement a dispute method, but the disputer can dispute the submitted claim directly through Optimistic Oracle V3 before the liveness passes by calling its `disputeAssertion` method: The disputer should pass the `assertionId` from the request above, as well as the address for receiving back bond and rewards if the disputer was right. If the claim is disputed, the request is escalated to the UMA DVM and it can be settled only after UMA voters have resolved it. To learn more about the DVM, see the docs section on the DVM: [how does UMA's Oracle work](https://docs.uma.xyz/protocol-overview/how-does-umas-oracle-work#umas-data-verification-mechanism) . #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#settling-insurance-claim) Settling insurance claim Similar to disputes, claim settlement should be initiated through the Optimistic Oracle V3 contract by calling its `settleAssertion` method with the same `assertionId` parameter: In case the liveness has expired or a dispute has been resolved by the UMA DVM, this call would initiate a `assertionResolvedCallback` callback in the Insurance contract: Importantly, all callbacks should be restricted to accept calls only from the Optimistic Oracle V3 to avoid someone spoofing a resolved answer: Depending on the resolved answer received in the `assertedTruthfully` callback parameter, this contract would either pay out the insured beneficiary if this was the first successful claim (in case of `true` representing that insurance claim was valid) or reject the payout: ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#tests-and-deployment) Tests and deployment All the unit tests covering the functionality described above are available [here](https://github.com/UMAprotocol/dev-quickstart-oov3/blob/master/test/Insurance.t.sol) . To execute all of them, run: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#deployment) Deployment Before deploying and interacting with the contracts export the required environment variables: * `ETHERSCAN_API_KEY`: your secret API key used for contract verification on Etherscan if deploying on a public network * `ETH_RPC_URL`: your RPC node used to interact with the selected network * `MNEMONIC`: your passphrase used to derive private keys of deployer (index 0) and any other addresses interacting with the contracts * `FINDER_ADDRESS`: address of the [Finder](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/implementation/Finder.sol) contract used to locate other UMA ecosystem contracts (in order to resolve disputes you would need to use the one from a sandboxed environment). For Goerli, you can use: * `DEFAULT_CURRENCY_ADDRESS`: address of the token used for insurance claim settlement. This is also used as oracle bonding currency, thus, needs to be added to whitelist either by UMA governance (production networks) or testnet administrator. On Goerli you can use [`0xe9448D94C9b033Ff50d3B14089043bD976fC1394`](https://goerli.etherscan.io/address/0xe9448d94c9b033ff50d3b14089043bd976fc1394) that is already whitelisted and can be minted by anyone using its `allocateTo` method Use `cast` command from Foundry to locate the address of Optimistic Oracle V3: To deploy the Insurance contract, run `forge create` command. Finally, we can verify the deployed (if deployed to a public network) contract with `forge verify-contract`: ### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#interacting-with-deployed-contract) Interacting with deployed contract The following section provides instructions on how to interact with the deployed contract from the foundry `cast` tool, though one can also use it for guidance for interacting through another interface (e.g. Remix or Etherscan). #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#initial-setup) Initial setup Export required user addresses and their derivation indices: Make sure the user addresses above have sufficient funding for the gas to execute the transactions. #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#issue-insurance) Issue insurance Make sure to have some amount of `DEFAULT_CURRENCY_ADDRESS` tokens to back potential insurance claim. If [`0xe9448D94C9b033Ff50d3B14089043bD976fC1394`](https://goerli.etherscan.io/address/0xe9448d94c9b033ff50d3b14089043bd976fc1394) was used on Goerli you can mint 10,000 DBT tokens to insurance issuer account: Approve `DEFAULT_CURRENCY_ADDRESS` to be pulled by the Insurance contract: Issue the insurance policy and grab the resulting `policyId` from the emitted `InsuranceIssued` event (it should be the last emitted event in the transaction and indexed `policyId` is at topic index `1`): If in doubt on the parsing of transaction receipt you can manually view full logs from tracing: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#submit-insurance-claim) Submit insurance claim Get the expected oracle bond: This should be zero for [`0xe9448D94C9b033Ff50d3B14089043bD976fC1394`](https://goerli.etherscan.io/address/0xe9448d94c9b033ff50d3b14089043bd976fc1394) on Goerli, but in case of other currencies make sure to have this amount of `DEFAULT_CURRENCY_ADDRESS` both on the insured account (for submitting the claim) and on the insurer's account (for disputing the claim). If bond amount is non-zero, also make sure to add approval: Now initiate the insurance claim and grab the resulting `assertionId` from the emitted `InsurancePayoutRequested` event (it should be the last emitted event and indexed `assertionId` is at topic index `2`): If in doubt on the parsing of transaction receipt you can manually view full logs from tracing: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#dispute-insurance-claim) Dispute insurance claim Before liveness passes, anyone (e.g. insurer) can dispute the claim through the Optimistic Oracle V3. In case of non-zero bond amount, they must add approval for Optimistic Oracle V3 to pull the bond: Now initiate the dispute and export related transaction hash that we will need to collect additional request parameters for resolving the dispute: #### [](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#settle-insurance-claim) Settle insurance claim Resolving disputes in production environment involves UMA token holders to vote on the request. Thus, testing is possible only in a sandboxed UMA ecosystem environment where the [Mock Oracle](https://github.com/UMAprotocol/protocol/blob/master/packages/core/contracts/data-verification-mechanism/test/MockOracleAncillary.sol) is used to resolve requests: In order to resolve request Mock Oracle expects the following parameters: * `identifier`: identifier that references instructions to resolve the request (Optimistic Oracle V3 and Insurance contract uses default identifier `ASSERT_TRUTH` specified in [UMIP-170](https://github.com/UMAprotocol/UMIPs/blob/master/UMIPs/umip-170.md) .) * `time`: timestamp when the disputed assertion was made * `ancillaryData`: bytes encoded additional data required to resolve the request (Optimistic Oracle V3 includes `assertionId` and the address of the claiming asserter) * `price`: numerical value to decide the outcome of the request (Optimistic Oracle V3 requires this to be `1e18` in order to resolve assertion as truthful) The commands below export the required parameters and resolves the request at the Mock Oracle: Note that the syntax above for getting ancillary data involves stripping `0x` and transforming `assertionId` and `ooAsserter` to lowercase to replicate the logic how Optimistic Oracle V3 contract is composing the ancillary data. If in doubt, you can always check the emitted `PriceRequestAdded` event parameters from the Mock Oracle contract in the dispute transaction traces: Now we can settle the request through the Optimistic Oracle V3 and observe the emitted `InsurancePayoutSettled` from our Insurance contract: The above settlement transaction should also transfer `INSURANCE_AMOUNT` tokens to the insured beneficiary as well as return the assertion bond plus half of disputer's bond to the claim initiator. Alternatively, if `0` value was resolved in `PRICE` (representing the asserted claim was not true), the settlement transaction should only return the bond plus half of claim initiator's bond to the disputer. Last updated 1 year ago Was this helpful? * [Insurance Contract](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#insurance-contract) * [Development environment](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#development-environment) * [Contract implementation](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#contract-implementation) * [Tests and deployment](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#tests-and-deployment) * [Interacting with deployed contract](https://docs.uma.xyz/developers/optimistic-oracle-v3/in-depth-tutorial-insurance#interacting-with-deployed-contract) Was this helpful? Copy constructor(address _defaultCurrency, address _optimisticOracleV3) { defaultCurrency = IERC20(_defaultCurrency); oo = OptimisticOracleV3Interface(_optimisticOracleV3); defaultIdentifier = oo.defaultIdentifier(); } Copy function issueInsurance( uint256 insuranceAmount, address payoutAddress, bytes memory insuredEvent ) public returns (bytes32 policyId) { ... } Copy function requestPayout(bytes32 policyId) public returns (bytes32 assertionId) { ... } Copy assertionId = oo.assertTruth( abi.encodePacked( "Insurance contract is claiming that insurance event ", policies[policyId].insuredEvent, " had occurred as of ", ClaimData.toUtf8BytesUint(block.timestamp), "." ), msg.sender, // asserter address(this), // callbackRecipient (the contract) address(0), // No sovereign security. assertionLiveness, defaultCurrency, bond, defaultIdentifier, bytes32(0) // No domain. ); assertedPolicies[assertionId] = policyId; Copy function disputeAssertion(bytes32 assertionId, address disputer) external nonReentrant { ... } Copy function settleAssertion(bytes32 assertionId) public nonReentrant { ... } Copy function assertionResolvedCallback(bytes32 assertionId, bool assertedTruthfully) public { ... } Copy require(msg.sender == address(oo)); Copy if (assertedTruthfully) _settlePayout(assertionId); ... function _settlePayout(bytes32 assertionId) internal { bytes32 policyId = assertedPolicies[assertionId]; Policy storage policy = policies[policyId]; if (policy.settled) return; policy.settled = true; defaultCurrency.safeTransfer(policy.payoutAddress, policy.insuranceAmount); emit InsurancePayoutSettled(policyId, assertionId); } Copy forge test --match-path *Insurance* Copy export FINDER_ADDRESS=0xE60dBa66B85E10E7Fd18a67a6859E241A243950e Copy export OOV3_ADDRESS=$(cast call $FINDER_ADDRESS "getImplementationAddress(bytes32)(address)" \ $(cast --format-bytes32-string "OptimisticOracleV3")) Copy export INSURANCE_ADDRESS=$(forge create --json src/Insurance.sol:Insurance \ --mnemonic "$MNEMONIC" \ --constructor-args $DEFAULT_CURRENCY_ADDRESS $OOV3_ADDRESS \ | jq -r .deployedTo) Copy forge verify-contract \ --chain-id $(cast chain-id) \ --constructor-args $(cast abi-encode "constructor(address,address)" \ $DEFAULT_CURRENCY_ADDRESS $OOV3_ADDRESS) \ $INSURANCE_ADDRESS Insurance Copy export INSURER_ID=1 export INSURED_ID=2 export INSURER_ADDRESS=$(cast wallet address --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID) export INSURED_ADDRESS=$(cast wallet address --mnemonic "$MNEMONIC" --mnemonic-index $INSURED_ID) Copy export INSURANCE_AMOUNT=$(cast --to-wei 10000) cast send --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID \ $DEFAULT_CURRENCY_ADDRESS "allocateTo(address,uint256)" $INSURER_ADDRESS $INSURANCE_AMOUNT Copy cast send --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" $INSURANCE_ADDRESS $INSURANCE_AMOUNT Copy export ISSUE_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID \ $INSURANCE_ADDRESS \ "issueInsurance(uint256,address,bytes)" \ $INSURANCE_AMOUNT $INSURED_ADDRESS $(cast --from-utf8 "Bad things have happened") \ | jq -r .transactionHash) export POLICY_ID=$(cast receipt --json $ISSUE_TX | jq -r .logs[-1].topics[1]) Copy cast run $ISSUE_TX Copy export BOND_AMOUNT=$(cast call $OOV3_ADDRESS \ "getMinimumBond(address)(uint256)" $DEFAULT_CURRENCY_ADDRESS) Copy cast send --mnemonic "$MNEMONIC" --mnemonic-index $INSURED_ID \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" $INSURANCE_ADDRESS $BOND_AMOUNT Copy export ASSERTION_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $INSURED_ID \ $INSURANCE_ADDRESS \ "requestPayout(bytes32)" $POLICY_ID | jq -r .transactionHash) export ASSERTION_ID=$(cast receipt --json $ASSERTION_TX | jq -r .logs[-1].topics[2]) Copy cast run $ASSERTION_TX Copy cast send --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID \ $DEFAULT_CURRENCY_ADDRESS "approve(address,uint256)" $OOV3_ADDRESS $BOND_AMOUNT Copy export DISPUTE_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $INSURER_ID \ $OOV3_ADDRESS "disputeAssertion(bytes32,address)" $ASSERTION_ID $INSURER_ADDRESS \ | jq -r .transactionHash) Copy export MOCK_ORACLE_ADDRESS=$(cast call \ $FINDER_ADDRESS "getImplementationAddress(bytes32)(address)" \ $(cast --format-bytes32-string "Oracle")) Copy export IDENTIFIER=$(cast call $INSURANCE_ADDRESS "defaultIdentifier()(bytes32)") export ASSERTION_TIME=$(cast block --json \ $(cast tx --json $ASSERTION_TX | jq -r .blockNumber) | jq -r .timestamp) export ANCILLARY_DATA=$(cast --from-utf8 $(echo assertionId:$(echo $ASSERTION_ID | sed 's/0x//' | tr [:upper:] [:lower:]),ooAsserter:$(echo $INSURED_ADDRESS | sed 's/0x//' | tr [:upper:] [:lower:]))) export PRICE=$(cast --to-wei 1) cast send --mnemonic "$MNEMONIC" --mnemonic-index $INSURED_ID \ $MOCK_ORACLE_ADDRESS \ "pushPrice(bytes32,uint256,bytes,int256)" \ $IDENTIFIER $ASSERTION_TIME $ANCILLARY_DATA $PRICE Copy cast run $DISPUTE_TX Copy export SETTLE_TX=$(cast send --json \ --mnemonic "$MNEMONIC" --mnemonic-index $INSURED_ID \ $OOV3_ADDRESS "settleAssertion(bytes32)" $ASSERTION_ID \ | jq -r .transactionHash) cast run $SETTLE_TX ---