Trading Polymarket Resolution Disputes as a Bot Edge
Polymarket resolution dispute trading: detect UMA disputes on-chain early and position the mispriced 99c/1c legs before the DVM vote finalizes.
A UMA dispute on a Polymarket market almost always leaves one leg of a binary trading somewhere between 92c and 99c while the "wrong" outcome sits at 8c to 1c. That gap is not efficiency. It is the market pricing in a small tail probability that the Optimistic Oracle's proposed answer gets overturned by UMA token holders during the Data Verification Mechanism vote. Most of those disputes resolve exactly the way the first proposal said they would. If you can flag the dispute in the first few minutes and you have a defensible read on how the DVM will vote, the mispriced leg is a real, repeatable edge — one that has nothing to do with the order-book price arbitrage everyone else is chasing.
This is resolution-risk trading. You are not betting on the underlying event anymore. That question is already settled in reality. You are betting on how a decentralized oracle process adjudicates it.
Why the dispute window even exists
When a Polymarket market closes, a proposer posts an outcome to UMA's Optimistic Oracle with a bond. Anyone can dispute that proposal by posting an equal bond within the liveness window (usually two hours on Polymarket's OO deployment). If nobody disputes, the proposed price is accepted and the market resolves. If someone disputes, the question escalates to the DVM, where UMA token holders commit-reveal a vote over roughly a two-to-three day cycle before the price is finalized on-chain.
That escalation is where the pricing dislocation lives. The moment a dispute lands, a market that was about to settle at $1.00 for YES can gap down to 90c because the crowd now sees a non-zero chance of the DVM landing on NO. If you already know the dispute is frivolous — a bond-grief attempt, a fat-fingered proposal, a genuine ambiguity that the UMA voter base has a clear historical bias on — you buy the discounted leg and hold to finalization. If you think the dispute is legitimate and the original proposal was wrong, you position the other side while everyone else is still anchored to the pre-dispute price.
I wrote up the underlying mechanics in more detail in our breakdown of how UMA's optimistic oracle actually resolves Polymarket markets; read that first if the proposer/disputer bond flow is fuzzy, because the rest of this assumes it.
Detecting the dispute before the price fully repriced
The whole edge collapses if you find out about the dispute from the Polymarket UI. By then the leg has already moved. You need to be watching the chain.
Disputes surface as DisputePrice events emitted by the Optimistic Oracle contract (and ProposePrice before them). Subscribe to those logs directly rather than polling an API. A minimal watcher against a websocket RPC looks like this:
from web3 import Web3
w3 = Web3(Web3.LegacyWebSocketProvider("wss://polygon-rpc.example/ws"))
oo = w3.eth.contract(address=OO_V2_ADDRESS, abi=OO_ABI)
dispute_filter = oo.events.DisputePrice.create_filter(from_block="latest")
while True:
for ev in dispute_filter.get_new_entries():
ident = ev["args"]["identifier"] # usually YES_OR_NO_QUERY
ts = ev["args"]["timestamp"]
ancillary = ev["args"]["ancillaryData"] # hex-encoded question text
# map ancillaryData -> Polymarket conditionId -> the two token ids
handle_dispute(ident, ts, ancillary)
The mapping step is the annoying part. ancillaryData is a bytes blob containing the question, the resolution source, and a reference to the Polymarket market. You decode it, hash it the way the CTF adapter does, and recover the conditionId so you know which two ERC-1155 outcome tokens to trade on the CLOB. Cache that mapping ahead of time by indexing QuestionInitialized events from Polymarket's UMA CTF adapter, so at dispute time it's an O(1) lookup instead of a decode-and-hash scramble while the price is running away from you.
Latency budget: from the DisputePrice log hitting your node to a signed order sitting in the book, you want to be under two seconds. Order signing is the piece people underestimate — if you haven't already got a warm signer and pre-approved allowances, you're not competing. The order-signing deep dive covers the EIP-712 flow and the allowance gotchas that will otherwise cost you the first hundred milliseconds.
Reading the DVM vote, not the news
Here's the opinionated part. The DVM does not re-litigate reality. UMA voters vote with the perceived majority because the mechanism punishes minority voters, and they lean heavily on the literal resolution criteria in the ancillary data. That produces a few patterns worth trading:
- Literalist bias. If the ancillary text says "resolves YES if X is officially announced by source Y," and X happened but Y never announced it, the DVM tends to go NO even when everyone knows X is true. The crowd often mispriced this on the "obvious" side.
- Ambiguity defaults. Genuinely ambiguous questions frequently resolve to the 50/50 UMA "unresolvable" split (0.5 / 0.5), which prints if you're holding both legs cheap.
- Bond-grief disputes. A disputer with no case, poking at a correct proposal to extract the proposer's bond or stall. These almost always confirm the original proposal. The disputed leg is a near-free discount.
Build a small classifier over historical DVM outcomes keyed on identifier type, resolution-source category, and whether the dispute was self-serving. You do not need a fancy model; a decently labeled dataset of past disputes and their final DVM prices gets you a base rate per category, and the base rate is the whole game.
A worked example
Say an election-adjacent market is proposed YES and, 40 minutes later, gets disputed. YES gaps from 99c to 91c. Your watcher fires, maps the conditionId, and your classifier flags it: resolution source is an official body that already published the result, and the disputer holds a large NO position — a textbook self-serving dispute. Your historical base rate for this category confirming the proposal is around 94%.
Expected value on buying YES at 91c:
EV = 0.94 * (1.00 - 0.91) + 0.06 * (0.00 - 0.91)
= 0.94 * 0.09 - 0.06 * 0.91
= 0.0846 - 0.0546
= +0.030 per share (~3.3% over ~2.5 days, before fees)
Size it by Kelly against your real confidence, not the headline base rate, and cap exposure per market because the tail here is a total loss of the position, not a drawdown. Fund the position across several concurrent disputes so no single DVM surprise wrecks the book.
Gotchas that will cost you money
Finalization takes days, so your capital is locked and the position is illiquid — you often can't exit at a fair price mid-vote if new information arrives. Bonds and gas on Polygon are trivial, but the opportunity cost isn't. Watch for re-disputes and multi-round escalation on the same identifier, which extends the lock. And know that UMA governance can, rarely, intervene on a bad DVM outcome, which is a tail you can't hedge.
This strategy pairs well with inventory-style approaches — the same event feed that flags disputes feeds a Polymarket news bot for faster reaction, and the leftover legs are natural inventory for a passive market-making book. If you'd rather run it as pure directional resolution-risk capture, that's closer to how a Polymarket arbitrage bot is architected: fast detection, tight signing, disciplined sizing. For the market-making mechanics that make holding disputed inventory cheap, the CLOB market-making guide is the companion piece.
If you want this detection-and-signing pipeline built and battle-tested against live disputes, that's the kind of system our arbitrage bot work is built to ship.
Need a bot like this built?
We design, build and run trading bots on Solana, Hyperliquid and Polymarket.
Start a projectMore from the blog
Public vs Paid RPC: How to Run a Fair Benchmark
A fair comparison of public and paid RPC endpoints must account for quotas, workload, freshness and support guarantees.
Read articleRPC Benchmark Percentiles Explained: p50, p95 and p99
Why averages hide the latency spikes that break trading bots, wallets and production blockchain applications.
Read articleHyperliquid REST vs WebSocket Benchmark: What to Measure
A benchmark plan for Hyperliquid market data that separates request latency from streaming freshness and recovery.
Read article