Polymarket’s multi-outcome markets - “Who wins the 2028 election?”, “Which team takes the championship?” - hide a clever portfolio operation that almost no retail trader ever sees: the PositionsConverted event. It lets a holder of NO tokens across several outcomes collapse them into YES tokens plus a guaranteed collateral payout, in a single transaction.
We just turned on indexing for the polymarket.positions_converted table in our ClickHouse cluster, capturing every emission of this event since the NegRiskAdapter contract launched. Here’s what’s inside.
What is a NegRisk market?
A “negative risk” (neg-risk) market is Polymarket’s structure for events with N mutually exclusive outcomes, where exactly one outcome happens. Each outcome i has its own pair of conditional tokens: YES_i (pays 1 USDC if outcome i wins) and NO_i (pays 1 USDC if any other outcome wins).
Across the whole market, prices must satisfy:
sum(price(YES_i)) = 1.00 USDC
price(NO_i) = 1.00 - price(YES_i)
Holding NO_i is a bet against a specific outcome. Holding it for many outcomes simultaneously means you’re betting against most of the field - which is a position the protocol can simplify.
The conversion mechanism
Suppose you hold k NO tokens, one each for outcomes in some set S (with |S| = k), and a market with N total outcomes. Whichever outcome wins:
- Winner is in S (probability you’re “wrong” on): one of your NO tokens pays 0, the other
k-1pay 1 USDC each → you get(k-1)USDC. - Winner is outside S: all
kof your NO tokens pay 1 USDC each → you getkUSDC.
The minimum value of this basket is (k-1) USDC, guaranteed. The remaining “upside” - the extra 1 USDC if the winner falls outside S - is exactly equivalent to holding 1 YES token for each outcome not in S.
The NegRiskAdapter contract lets you cash this insight directly. Calling convertPositions(marketId, indexSet, amount):
- Burns
amountof each NO token for outcomes inS. - Pays out
(k - 1) × amountUSDC of collateral. - Mints
amountof each YES token for outcomes not inS.
This is one-way. You cannot go from YES back to NO this way - the protocol won’t increase your collateral exposure on demand.
Why it matters
Without this operation, a trader who accumulated NO positions across many outcomes would need to sell each one individually on the order book, paying spread and price impact at every step. Conversion is a direct contract call against the protocol’s invariants, free of order-book slippage. Market makers use it constantly to rebalance inventory and free collateral that’s implicitly tied up in “long the field minus one” positions.
Reading the event
The PositionsConverted event carries four logical fields plus standard blockchain context. In the ClickHouse table polymarket.positions_converted:
| Column | Type | Meaning |
|---|---|---|
stakeholder | String | The wallet performing the conversion |
market_id | String | The neg-risk market identifier (not a single outcome’s CLOB token id) |
index_set | UInt256 (string) | Bitmask of which outcomes’ NO tokens are supplied |
amount | UInt256 (string) | Tokens converted, 6 decimals (USDC scale) |
contract_address | String | Always 0xd91e80cf2e7be2e162c6513ced06f1dd0da35296 (NegRiskAdapter on Polygon) |
block_timestamp, transaction_hash, log_index, … | Standard event-location columns |
The index_set bitmask
index_set is a uint256 where bit i indicates that outcome i’s NO token is included in the conversion input. So:
index_set = 1(binary0001) → only outcome 0’s NO is supplied. You get YES tokens for outcomes 1, 2, …, and0 × amountcollateral.index_set = 6(binary0110) → outcomes 1 and 2’s NOs supplied (k=2). You get YES for outcomes 0, 3, 4, … and1 × amountcollateral.index_set = 127(binary1111111) in a 7-outcome market → all seven NOs supplied (k=7), returning6 × amountUSDC and no tokens. This is just a structured exit.
In SQL, recover k cheaply:
SELECT bitCount(toUInt256(index_set)) AS num_no_tokens_supplied
FROM polymarket.positions_converted
What the on-chain data shows
The NegRiskAdapter has emitted 3,167,335 PositionsConverted events between 2023-12-07 and the time of writing, across 27,792 unique markets and 12,906 unique stakeholder wallets. The footprint is much narrower than retail trading (the order-filled table covers ~600K wallets) - this is a tool used by a small, sophisticated cohort.
Most conversions are small basket rebalances
Distribution of k (number of NO tokens supplied per call) for 2025+ events:
| k | Events | Avg amount (USDC) |
|---|---|---|
| 1 | 751,061 | 926 |
| 2 | 363,561 | 352 |
| 3 | 308,819 | 240 |
| 4 | 257,533 | 215 |
| 5 | 223,769 | 90 |
| 6-10 | 586,218 | ~60 |
| 11-20 | 220,367 | ~55 |
| 20+ | 235,180 | mostly < 40 |
The k=1 case is interesting: it releases zero collateral (because k-1 = 0), so the call is purely a token swap - “trade my NO for outcome i into a bundle of YES for everything else.” The high average size (~$926) suggests these are large directional flips by market makers, not retail.
As k grows the average amount shrinks - long-tail markets with many outcomes have thinner liquidity per token, so traders convert in smaller chunks.
A few wallets dominate
Top 5 stakeholders by total amount converted in 2025+:
| Wallet | Events | Volume converted (USDC) | Markets |
|---|---|---|---|
0xada2...eaab | 460,678 | $82.1M | 7,120 |
0xd218...b5c9 | 84,752 | $78.0M | 3,247 |
0xa027...e1d5 | 166 | $45.6M | 42 |
0xe8dd...ec86 | 393,408 | $37.8M | 5,439 |
0xa9d1...a399 | 87 | $36.7M | 10 |
Two distinct profiles jump out:
- Bots (
0xada2...,0xe8dd...): hundreds of thousands of small conversions across thousands of markets - automated inventory management. - Discretionary whales (
0xa027...,0xa9d1...): under 200 calls each but tens of millions in volume - large rebalances on a small number of conviction markets.
Monthly trend
| Month | Events | Volume (USDC) | Unique wallets |
|---|---|---|---|
| 2026-06 (partial) | 149,556 | $30.1M | 132 |
| 2026-05 | 417,677 | $59.3M | 318 |
| 2026-04 | 442,050 | $64.1M | 2,271 |
| 2026-03 | 404,953 | $78.3M | 5,263 |
| 2026-02 | 264,601 | $62.8M | 1,251 |
| 2026-01 | 264,913 | $105.5M | 1,251 |
| 2025-12 | 179,817 | $73.0M | 1,113 |
| 2025-11 | 144,804 | $59.2M | 998 |
January 2026 was the peak so far - $105M of NO baskets converted into YES + collateral in a single month. The recent rise in unique wallets per month (5,263 in March 2026) suggests the tooling for these conversions has become more accessible.
Querying it yourself
from core.clickhouse import PolymarketAccessor
with PolymarketAccessor() as db:
df = db.query_df("""
SELECT
block_timestamp,
stakeholder,
market_id,
bitCount(toUInt256(index_set)) AS k,
toFloat64(amount) / 1e6 AS amount_usdc,
(bitCount(toUInt256(index_set)) - 1) * toFloat64(amount) / 1e6 AS collateral_released_usdc,
transaction_hash
FROM polymarket.positions_converted
WHERE block_timestamp >= '2026-06-01'
ORDER BY amount_usdc DESC
LIMIT 20
""")
To join with market metadata, the market_id in positions_converted corresponds to the parent neg-risk market - not the per-outcome clob_token_id. Joining with polymarket.raw_market_meta requires the neg-risk market id field there (or grouping that table’s rows by their common parent).
What to do with it
A few research angles this table unlocks:
- Market-maker inventory cycles. Track conversions alongside
polymarket_order_filledfor the same wallet to see how MMs rebalance after directional flow. - Implied probability snapshots. Every conversion is a revealed-preference signal that the stakeholder considers
(k-1)/kUSDC immediately better than holding the full basket - i.e., they believeP(winner ∈ S) > 1/k. - Crowd sentiment shifts. A spike in conversions concentrated on a particular
index_setfor one market means a cohort of traders has collectively given up on certain outcomes. - Liquidity quality signal. Markets with high conversion activity have active arbitrageurs enforcing price consistency across outcomes - usually a sign of healthy quoting on the order book too.
The NegRiskAdapter is one of the most under-analyzed surfaces of Polymarket because its activity doesn’t show up in standard trade feeds. With the table now indexed end-to-end, it’s a good time to start looking.
Background reading: Decoding Polymarket covers the broader CTF + NegRisk architecture in depth. The NegRiskAdapter contract on Polygon: 0xd91e80cf2e7be2e162c6513ced06f1dd0da35296.