All packages

polymarket

PaulieB14
v0.3.0/18 downloads/Repository

Package ref

polymarket@v0.3.0

Run package

CLI

Run db_out from the command line.

substreams run polymarket@v0.3.0 db_out -e polygon
Authenticate by running substreams auth or directly on thegraph.market (see docs).

README

Polymarket Substreams

Polymarket

Comprehensive event archive for Polymarket prediction markets on Polygon — CLOB v1 + v2, Conditional Tokens lifecycle, USDC.e and pUSD collateral flows.

Substreams CLOB v1+v2 Polygon PostgreSQL ClickHouse


What this package is for

This is the comprehensive event archive in the Polymarket substreams family — designed to capture every on-chain event that touches Polymarket markets, not just trade fills.

It's complementary to two more focused packages:

PackageScopeUse when
polymarket-orderbook-substreamsOrder flow, market analytics, trader leaderboardsYou want clean orderbook trade analytics with foundational stores
polymarket-pnlTrader P&L, cost basis, position trackingYou want per-user realized/unrealized P&L
polymarket (this)Raw event archive: Exchange + Conditional Tokens lifecycle + collateral transfersYou need market creation/resolution, mint/redeem flows, raw collateral movements, or a full audit trail

If you only need order flow, use orderbook. If you only need P&L, use pnl. If you need market lifecycle (when conditions are prepared/resolved), user mint/redeem flows (PositionSplit/PositionsMerge/PayoutRedemption), or raw USDC.e + pUSD collateral movements, use this package.


CLOB v2 ready (since v0.3.0)

Polymarket migrated to CLOB v2 at the 2026-04-28 ~11:00 UTC cutover. v2 ships fresh Exchange contracts at new addresses, a redesigned OrderFilled event, a new fee model, and a new wallet-facing collateral wrapper (pUSD). This package indexes both contract generations and the new collateral wrapper alongside the unchanged Conditional Tokens layer.

What changed in CLOB v2

ConceptCLOB v1CLOB v2
Exchange contracts0x4bfb…982e (CTF) / 0xC5d5…f80a (NegRisk)0xE111…996B (CTF) / 0xe222…0F59 (NegRisk) — fresh deploys
Order uniquenessnonce per makertimestamp (ms) — nonces removed
Order sideInferred from makerAssetId == 0Explicit side enum on the event (BUY=0, SELL=1)
OrderFilled event8 fields, including makerAssetId + takerAssetId10 fields: single tokenId + side + new builder (bytes32) + metadata (bytes32)
OrdersMatched eventmakerAssetId + takerAssetId + amountstakerOrderHash + takerOrderMaker + side + tokenId + amounts
FeesEmbedded in order (feeRateBps), maker + takerProtocol-determined at match time, taker only, dynamic per market
Collateral (wallet)USDC.e directlypUSD — 1:1-backed ERC-20 wrapper. USDC.e wraps via CollateralOnramp.wrap()
Collateral (CTF level)USDC.eUSDC.e (unchanged — pUSD is purely wallet-facing)
CancellationsOrderCancelled eventOrderPreapprovalInvalidated (operator-driven pauseUser replaces onchain cancel)
Builder attributionHMAC headers on API ordersSingle builderCode (bytes32) on the order, surfaced as builder on the event
EIP-712 domain version"1""2" for exchange signing (L1 API auth still "1")
Open orders at cutoverAll wiped during the maintenance window

How this package handles it

  1. CLOB v1 + v2 dual coverage. map_ctf_exchange_events (v1) extracts events from CTF Exchange 0x4bfb… and NegRisk Exchange 0xC5d5… (the v0.2.0 release was missing NegRisk — fixed in v0.3.0). Two new modules — map_ctf_exchange_v2_events and map_neg_risk_exchange_v2_events — extract the v2 OrderFilled (with single tokenId + explicit side + builder + metadata), v2 OrdersMatched, OrderPreapprovalInvalidated, FeeCharged, TradingPaused/Unpaused. Each v2 row is tagged with source_contract (ctf_v2 / neg_risk_v2).
  2. Conditional Tokens layer is unchanged. map_ctf_events decodes ConditionPreparation, ConditionResolution, PositionSplit, PositionsMerge, and PayoutRedemption from 0x4D97…6045 — these contracts are unchanged in v2, so this module covers both eras with a single configuration. (v0.2.0 had this as a stub; v0.3.0 actually implements it.)
  3. Both collateral tokens. map_usdc_events continues to track USDC.e Transfer/Approval events (still the CTF-level collateral). map_pusd_events is new — it tracks the wallet-facing pUSD wrapper (0xC011…2DFB) introduced in v2. (USDC was also a stub in v0.2.0; now implemented.)
  4. V4 protocol + S2 compression. Built against substreams-sink-database-changes v4 and the latest substreams CLI; benefits from V4 Blocks Streams batching and S2 compression auto-negotiated by StreamingFast endpoints.
  5. No schema migration on existing tables. All v0.2.0 tables (order_fills, orders_matched, order_cancellations, fee_charges, token_registrations, etc.) keep their schema. New v2 tables (order_fills_v2, orders_matched_v2, order_cancellations_v2, fee_charges_v2) sit alongside. New CTF lifecycle tables (condition_preparations, condition_resolutions, position_splits, position_merges, position_redemptions) and collateral tables (usdc_transfers, pusd_transfers) are also new.

What stays the same

  • Same chain (Polygon), same Firehose source.
  • Same module names for v1 modules — additive only, map_ctf_exchange_events now also covers NegRisk.
  • Existing v0.2.0 SQL tables and indexes continue working unchanged.

Modules

CLOB v1 (legacy — historical fills only after the 2026-04-28 cutover)

ModuleInitial BlockDescription
map_ctf_exchange_events33,605,403All v1 events from CTF Exchange + NegRisk Exchange (OrderFilled, OrdersMatched, OrderCancelled, FeeCharged, NewAdmin/RemovedAdmin, NewOperator/RemovedOperator, ProxyFactoryUpdated, SafeFactoryUpdated, TokenRegistered, TradingPaused/Unpaused)

CLOB v2 (deployed 2026-03-31, cutover 2026-04-28)

ModuleInitial BlockDescription
map_ctf_exchange_v2_events84,902,353CTF Exchange V2 events with single tokenId + side + builder + metadata
map_neg_risk_exchange_v2_events84,902,353NegRisk CTF Exchange V2 events

Conditional Tokens (unchanged across v1/v2)

ModuleInitial BlockDescription
map_ctf_events33,605,403Market creation (ConditionPreparation), resolution (ConditionResolution), and user mint/redeem flows (PositionSplit, PositionsMerge, PayoutRedemption)

Collateral

ModuleContractInitial BlockDescription
map_usdc_eventsUSDC.e (0x2791…84174)33,605,403ERC-20 Transfer + Approval. CTF-level collateral, unchanged in v2
map_pusd_eventspUSD (0xC011…2DFB)84,902,353ERC-20 Transfer + Approval. New wallet-facing collateral wrapper introduced in v2

Aggregations

ModuleDescription
map_trading_dataCombined trading data view across CTF + NegRisk v1 fills
store_total_order_countCumulative order fill count per market
store_total_volumeCumulative trading volume per market
db_outDatabaseChanges output combining all maps + store deltas

Contract Addresses

CLOB v1 (legacy)

ContractAddress
CTF Exchange v10x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e
NegRisk Exchange v10xC5d563A36AE78145C45a50134d48A1215220f80a

CLOB v2 (deployed 2026-03-31)

ContractAddress
CTF Exchange V20xE111180000d2663C0091e4f400237545B87B996B
NegRisk CTF Exchange V20xe2222d279d744050d28e00520010520000310F59

Always-on infrastructure

ContractAddress
Conditional Tokens0x4D97DCd97eC945f40cF65F87097ACe5EA0476045
USDC.e (CTF collateral)0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
pUSD (v2 wallet collateral)0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB

V2 Exchange deploy block: 84,902,353 · Cutover: 2026-04-28 ~11:00 UTC


Quick Start

# Install Substreams CLI
brew install streamingfast/tap/substreams

# Authenticate
substreams auth

# Stream all v1 + v2 fills (v1 module covers CTF + NegRisk)
substreams run https://spkg.io/PaulieB14/polymarket-v0.3.0.spkg \
  map_ctf_exchange_events \
  -e polygon.substreams.pinax.network:443 \
  -s 33605403 -t +1000

# Stream market lifecycle (creations/resolutions/splits/merges/redemptions)
substreams run https://spkg.io/PaulieB14/polymarket-v0.3.0.spkg \
  map_ctf_events \
  -e polygon.substreams.pinax.network:443 \
  -s 33605403 -t +1000

# Stream pUSD transfers (post-cutover)
substreams run https://spkg.io/PaulieB14/polymarket-v0.3.0.spkg \
  map_pusd_events \
  -e polygon.substreams.pinax.network:443 \
  -s 84902353 -t +1000

SQL Sink

# Create database and apply schema
createdb polymarket
psql -d polymarket -f schema.sql

# Setup sink
substreams-sink-sql setup \
  "psql://localhost:5432/polymarket?sslmode=disable" \
  https://spkg.io/PaulieB14/polymarket-v0.3.0.spkg

# Run sink
substreams-sink-sql run \
  "psql://localhost:5432/polymarket?sslmode=disable" \
  https://spkg.io/PaulieB14/polymarket-v0.3.0.spkg \
  -e polygon.substreams.pinax.network:443

Sample queries

-- All v1 + v2 fills in chronological order
SELECT 'v1' AS gen, evt_block_number, evt_tx_hash, maker, taker, maker_amount_filled
FROM order_fills
UNION ALL
SELECT source_contract AS gen, evt_block_number, evt_tx_hash, maker, taker, maker_amount_filled
FROM order_fills_v2
ORDER BY evt_block_number DESC LIMIT 100;

-- Markets created vs resolved
SELECT
  COUNT(DISTINCT cp.condition_id) AS markets_created,
  COUNT(DISTINCT cr.condition_id) AS markets_resolved
FROM condition_preparations cp
LEFT JOIN condition_resolutions cr USING (condition_id);

-- Top stakeholders by mint volume (PositionSplit)
SELECT stakeholder, COUNT(*) AS splits, SUM(amount::numeric) AS total_minted
FROM position_splits
GROUP BY stakeholder
ORDER BY total_minted DESC LIMIT 50;

-- Builder attribution (v2 only)
SELECT builder, COUNT(*) AS fills, SUM(taker_amount_filled::numeric) AS volume
FROM order_fills_v2
WHERE builder <> '0000000000000000000000000000000000000000000000000000000000000000'
GROUP BY builder
ORDER BY volume DESC;

-- pUSD vs USDC.e flow comparison post-cutover
SELECT 'usdc.e' AS token, SUM(value::numeric) AS volume FROM usdc_transfers WHERE evt_block_number > 84902353
UNION ALL
SELECT 'pusd' AS token, SUM(value::numeric) AS volume FROM pusd_transfers;

Architecture

                                Polygon Blockchain
                                       │
                                       ▼
                              ┌─────────────────┐
                              │ Firehose Blocks │
                              └────────┬────────┘
                                       │
        ┌────────────┬─────────────────┼─────────────────┬─────────────┐
        ▼            ▼                 ▼                 ▼             ▼
   ┌─────────┐  ┌──────────┐    ┌────────────┐    ┌──────────┐  ┌──────────┐
   │ CTF v1  │  │ CTF v2   │    │ NegRisk v2 │    │ CTF      │  │ USDC.e + │
   │ + NegRisk│  │ Exchange │    │ Exchange   │    │ Cond.Toks│  │ pUSD     │
   └─────┬───┘  └─────┬────┘    └─────┬──────┘    └────┬─────┘  └────┬─────┘
         │            │                │                │             │
         └────────────┴────────┬───────┴────────────────┴─────────────┘
                               ▼
                       ┌──────────────┐
                       │   db_out     │
                       │ (SQL/CH)     │
                       └──────┬───────┘
                              │
                    ┌─────────┴────────┐
                    ▼                  ▼
              PostgreSQL          ClickHouse

Build from Source

git clone https://github.com/PaulieB14/Polymarket-Substreams
cd Polymarket-Substreams

substreams build
substreams pack

# Stream locally
substreams run substreams.yaml map_ctf_exchange_v2_events \
  -e polygon.substreams.pinax.network:443 \
  -s 84902353 -t +100

License

MIT — see LICENSE.

Modules

Execution graph

12 modules
map

map_ctf_events

Extracts ConditionPreparation, ConditionResolution, PositionSplit, PositionsMerge, and PayoutRedemption from the Gnosis Conditional Tokens contract.

from #33605403
map

map_ctf_exchange_events

Extracts all CTF Exchange + NegRisk Exchange v1 events: OrderFilled, OrdersMatched, OrderCancelled, FeeCharged, NewAdmin/RemovedAdmin, NewOperator/RemovedOperator, ProxyFactoryUpdated, SafeFactoryUpdated, TokenRegistered, TradingPaused/Unpaused.

from #33605403
Show 2 dependencies
map

ethcommon:all_events

`all_events` gives you all the events in a block (from successful transactions), with basic block hash/number/timestamp and transaction hash

Output

sf.substreams.ethereum.v1.Events

blockIndex

ethcommon:index_events

`index_events` sets the following keys on the block: * Event signatures evt_sig:0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef (signature in hex, prefixed by 0x) * Event address evt_addr:0x0123456789abcdef0123456789abcdef01234567 (address in hex, prefixed by 0x)

Output

sf.substreams.index.v1.Keys