Polymarket's CLOB and UMA Oracle: An Arb Bot's View
How Polymarket's off-chain CLOB and UMA's optimistic oracle create arb windows an AMM-arb bot's math can't see, with a worked EV example.
Two settlement layers, one mispricing engine
Polymarket looks like a DEX from the outside — connect a wallet, buy YES or NO, watch a price move between 0 and 1. Under the hood it's closer to a stock exchange bolted onto a dispute court. Order matching happens off-chain in Polymarket's own central limit order book (CLOB); settlement happens on-chain on Polygon through the CTFExchange contract, which mints and burns Gnosis Conditional Tokens Framework (CTF) outcome shares; and the answer to "what actually happened" comes from UMA's Optimistic Oracle, not from a price feed. Three systems, three different places for a market to be temporarily wrong, and each one behaves nothing like the constant-product curve most MEV bots are tuned for.
If you've built for Uniswap-style AMMs, your instinct is to think in terms of a bonding curve and price impact you can compute in closed form. Polymarket doesn't have that. It has resting limit orders signed off-chain via EIP-712, matched by Polymarket's engine, and submitted to the chain as a batch fill. Depth at a given price is whatever makers happened to post, not a formula. That changes what "arbitrage" even means here.
Where the CLOB creates windows
Two structural facts drive most of the exploitable mispricing:
- YES + NO should always sum to $1, since together they're a complete set of CTF outcome tokens redeemable 1:1 for the resolved side. When the book gets thin — low-liquidity markets, right after news breaks, or during a resolution event — the two legs can trade away from parity because they're matched independently, not priced off a single curve. A YES ask at 0.61 and a NO ask at 0.42 is a free 3 cents if you can buy both and hold to resolution or redemption.
- Off-chain matching lags on-chain settlement. The engine matches instantly, but the fill still needs a transaction landing on Polygon. Between "your order matched" and "your position is actually settled and tradeable again," there's real latency — enough for a fast bot watching the public order book feed to see a large taker order about to walk the book and front the resulting price move on a correlated market (e.g., a sister contract on the same event, or the same event listed with different strike thresholds).
Neither of these is novel MEV theory — it's the same cross-venue and complete-set arbitrage that's existed in prediction markets and options books for decades. What's new is doing it against an off-chain matching engine with on-chain finality, which means your bot needs a WebSocket feed for the book and a mempool/state feed for Polygon simultaneously, and it needs to reconcile the two without racing its own fills.
UMA's optimistic oracle: the real edge
This is the part generic AMM-arb infra completely misses, because there's no equivalent on Uniswap. When a Polymarket market needs resolving, someone (often Polymarket's own UMA adapter, sometimes any bonded proposer) calls proposePrice on UMA's OptimisticOracleV2 with a bond — historically 750 USDC — asserting the outcome. That starts a liveness window, typically two hours for standard Polymarket markets, during which anyone can dispute by posting a matching bond. No dispute, the proposed answer finalizes automatically and shares become redeemable at 0 or 1. A dispute sends it to UMA's DVM, where UMA token holders vote — a process that can take days.
That two-hour window is where a mispricing sits in plain sight. A market's UI price will usually snap toward the proposed outcome fast, since anyone watching ProposePrice events can front-run the crowd, but it rarely snaps all the way to 0.99+ immediately. Traders who don't want to eat dispute risk — the proposed answer being wrong, or getting overturned in the DVM — leave a discount on the table. If you can price that dispute risk correctly, the discount is close to free money.
A worked example
Say a market proposes YES at $0.94 immediately after ProposePrice fires, versus a pre-proposal price of $0.80. The bond is 750 USDC, the dispute bond matches it, and historically well over 90% of Polymarket UMA proposals go unchallenged (obviously correct outcomes, sports scores, on-chain-verifiable events). Rough expected value for buying at $0.94:
EV = P(no dispute) * (1.00 - 0.94)
+ P(dispute) * P(DVM sides with proposer) * (1.00 - 0.94)
+ P(dispute) * P(DVM overturns) * (0.00 - 0.94)
Plug in P(no dispute) = 0.92, P(dispute & upheld) = 0.06, P(dispute & overturned) = 0.02:
EV = 0.92*0.06 + 0.06*0.06 + 0.02*(-0.94)
= 0.0552 + 0.0036 - 0.0188
= 0.04 (~4 cents on a 6-cent-wide gap)
That's a real edge on capital tied up for roughly two hours to two days, and it's an edge you can only compute if you're actually decoding UMA events and tracking historical dispute rates per market category — sports resolve almost mechanically, ambiguous political or "will X happen by date Y" markets get disputed far more often and deserve a fatter discount before you touch them.
Building the bot: what you actually watch
A working setup needs three concurrent feeds, not one:
- Polymarket's CLOB WebSocket for book depth and fills across correlated markets.
- Polygon state/logs for CTFExchange settlement and for UMA's OptimisticOracleV2
ProposePrice/DisputePriceevents, filtered to Polymarket's adapter address. - A resolution-risk model per market category, since dispute probability is not uniform and treating it as a constant will blow up your EV math on the markets that matter most.
This is the same category of problem our EVM MEV bot and EVM arbitrage bot builds solve elsewhere on Polygon and other EVM chains — event-driven strategies that live or die on how fast and how cleanly you can decode chain state, not on clever math alone. The complete-set and cross-market legs of this strategy in particular are close cousins of the parity-arb patterns we cover in our breakdown of Jito bundles versus Flashbots bundles for MEV auctions, just without an auction layer to bid into — Polymarket's matching is FIFO within price levels, so speed to the book substitutes for bid strategy.
The infra problem nobody budgets for
The failure mode isn't strategy design, it's plumbing. Public RPC endpoints rate-limit you exactly when a proposal event fires and everyone else's bot wakes up at once, and a missed or delayed DisputePrice event means you're holding a position you thought was settled and isn't. The latency discipline that matters for Yellowstone gRPC versus Solana RPC in MEV work or for understanding Jito's block-engine auction applies just as hard here, even though Polymarket sits on an entirely different stack — dedicated node infra and clean event decoding across CLOB, CTF, and UMA are non-negotiable, which is exactly the layer our data and infra work is built to handle.
If you're trying to run this strategy and keep getting beaten to the proposal events, that's an infrastructure gap, not a strategy gap — talk to us about an EVM arbitrage bot built for Polymarket's specific settlement path.
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