What is Polymarket Merge Arbitrage?
Between April 2024 and April 2025, on-chain arbitrageurs extracted $39.6 million from Polymarket. The top arbitrageur made $2,009,632 from 4,049 trades — an average of $496 profit per trade. They weren't predicting outcomes. They were exploiting a simple mathematical inefficiency that exists in the protocol itself.
This is how it works.
The Core Mechanic
Every Polymarket condition issues two ERC-1155 tokens on the Polygon blockchain:
- YES token — redeemable for $1.00 USDC if the event resolves YES
- NO token — redeemable for $1.00 USDC if the event resolves NO
Since exactly one of these must happen, in a perfectly efficient market: YES_price + NO_price = $1.00.
Markets are not perfectly efficient.
When YES + NO < $1.00, the Conditional Token Framework has a function called mergePositions() that lets you combine 1 YES token + 1 NO token and receive exactly 1.00 USDC instantly.
YES = $0.47 · NO = $0.51 · Total cost = $0.98
Call mergePositions() → receive $1.00 USDC
Profit: $0.02 per share. Zero risk. Settlement: ~3 seconds.
There is no prediction involved. You don't care whether the event resolves YES or NO. You hold both sides. The outcome doesn't matter — you've already been made whole by the merge.
Why the Gap Exists
Four structural reasons keep this inefficiency alive:
- Liquidity fragmentation — YES and NO are traded on separate order books. Prices drift independently.
- Market maker latency — Automated market makers don't reprice instantaneously. Windows open and close in seconds.
- Fear/greed asymmetry — In breaking news, one side gets hammered while the other lags. The gap widens.
- Retail fee confusion — Most traders don't calculate the net cost including fees. This creates gaps that survive even with fees.
41% of all active Polymarket conditions have shown this gap at some point. The inefficiency is structural, not random. It will persist as long as Polymarket has retail participants.
The Fee Structure
This is the most important thing most people get wrong. Polymarket has two fee regimes:
| Market Type | Trading Fees | Threshold for Profit |
|---|---|---|
| Politics, culture, science | ZERO | Any gap where YES + NO < $1.00 |
| Crypto, sports | Variable (max ~1.56%) | YES + NO < ~$0.984 at the 50¢ midpoint |
Target non-crypto, non-sports markets first. Every gap you find there is pure profit with no fee haircut. This is the most important sentence in this article.
The crypto/sports fee formula:
fee = C × price × 0.25 × (price × (1 - price))² // C ≈ 0.02, max fee ≈ 1.56% at price = 0.50 // At extremes (5¢ or 95¢), fees approach zero
Executing On-Chain
The merge happens on the Conditional Token Framework (CTF) contract deployed on Polygon:
Contract: 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045 mergePositions( collateralToken, // USDC: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 parentCollectionId, // 0x0 conditionId, // the market's condition ID partition, // [1, 2] for YES/NO amount // number of tokens to merge )
Gas cost on Polygon: approximately $0.002–$0.01 per merge. Negligible. Settlement: 3–5 seconds (one block).
Crucially, after the merge your USDC is immediately available. Capital velocity — how fast you can recycle the same dollar — is your true edge at scale.
Finding the Gap: The Scanner
Polymarket's Gamma API exposes all active markets and current prices. A basic scanner in Python:
import requests
def scan_merge_arb(min_profit=0.003):
markets = requests.get(
"https://gamma-api.polymarket.com/markets",
params={"active": True, "limit": 500}
).json()
opportunities = []
for market in markets:
yes_ask = market.get("bestAsk")
no_ask = 1 - market.get("bestBid")
if yes_ask and no_ask:
profit = 1.0 - (yes_ask + no_ask)
if profit >= min_profit:
opportunities.append({
"question": market["question"],
"profit_per_share": profit,
"condition_id": market["conditionId"]
})
return sorted(opportunities, key=lambda x: x["profit_per_share"], reverse=True)
print(scan_merge_arb())
This scans 500 markets in seconds. Run it on a cron job every 30 seconds and you'll catch most opportunities. The pros use the CLOB API for real-time order book depth and fire in milliseconds.
Capital Sizing: Quarter-Kelly
Never bet everything on one trade. The Kelly Criterion tells you the optimal fraction to risk:
edge = profit_per_share / cost_of_trade kelly = (edge / (1 + edge)) × 0.25 # quarter-kelly # Example: YES=$0.47, NO=$0.51, profit=$0.02 # edge = 0.02 / 0.98 = 2.04% # quarter-kelly = 0.5% of capital per trade
Quarter-Kelly (25% of full Kelly) has 87% of the long-run growth rate with 25% of the variance. For a small account where survival matters more than optimization, this is the correct sizing.
The Numbers
| Metric | Value |
|---|---|
| Markets showing arb opportunity | 41% of all active conditions |
| Total extracted (Apr 2024–Apr 2025) | $39,600,000 |
| Top arbitrageur P&L | $2,009,632 |
| Top arbitrageur trade count | 4,049 trades |
| Average profit per trade (top arber) | $496 |
| Gas cost per merge (Polygon) | $0.002–$0.01 |
| Settlement time | 3–5 seconds |
What This Is Not
Merge arb is not:
- Prediction — you have no market view
- Speculation — there is no outcome risk once both sides are held
- Front-running — you're not racing other traders' orders
- A glitch or exploit —
mergePositions()is a documented, intended protocol function
It is mechanical edge extraction from a structurally inefficient market. The inefficiency is the spread between two correlated assets that should always sum to $1.00 but sometimes don't.
The Full Playbook
8 chapters. All the code. The fee math. Kelly sizing for small accounts. The $300 → $300K roadmap.
GET THE PLAYBOOK — $9 →