Skip to main content
Polymarket outcome balances live in one of two ERC-1155 contracts. Use the market version returned by Gamma to select the correct section below. Field presence is not a reliable discriminator because a CTF market can also appear as a leg in a PositionManager workflow. See Discover Markets for the discovery workflow and Contracts for Polygon addresses.

CTF

Derive CTF Identifiers

Conditional Tokens derives each identifier from the condition and collateral path. Use the deployed contract helpers when possible. A CTF position can contain more than one condition through its parent collection. The indexSet selects the represented outcomes. For a binary condition, the two singleton collections use index sets 1 and 2. Conditional Tokens does not define a platform-wide event identifier. Negative risk grouping is maintained by the Neg Risk Adapter. Gamma provides the event and market identifiers used by application integrations.

Index CTF Balances and Lifecycle Events

Build balances from TransferSingle and TransferBatch events emitted by Conditional Tokens. Build operator approvals from ApprovalForAll. Conditional Tokens does not expose a general total-supply read for every outcome token. Start from the deployment block or another verified checkpoint if your indexer needs complete historical balances or supply. Use these lifecycle events as transaction context around the ERC-1155 balance changes: ERC-1155 transfer events remain the canonical input for balances, minting, burning, and supply. Do not count a lifecycle event and its underlying transfer as two balance changes.

Attribute CTF Exchange Fills

The CTF exchanges emit OrderFilled, OrdersMatched, and FeeCharged. The signed order field is named tokenId and contains the CTF outcome token ID selected during market discovery. OrderFilled includes the signed builder value and metadata. Record the exchange address or EIP-712 domain version "2" with each order. This keeps fills attributable to the correct position system when both systems use the same order shape.

Track CTF Resolution and Redemptions

Conditional Tokens stores payoutNumerators and payoutDenominator. The payout fraction for one outcome is its numerator divided by the condition denominator. AutoRedeemer identifies the source of an automated CTF redemption with one of these events: The ledger also emits its normal redemption, burn, and transfer events. Use the AutoRedeemer event to attribute the automated action and the ledger events to update balances and supply.

Polymarket Protocol V2

Decode Polymarket Protocol V2 Position IDs

A Polymarket Protocol V2 Position ID encodes its module, event, condition, and outcome. The same value can be reduced to a Condition ID or Event ID by clearing its lower fields.
Current module IDs are: The native Polymarket Protocol V2 identifier helpers derive identifiers in this order: Migration uses precomputed legacy identifiers instead of the native base-hash derivation. Binary migration passes the legacy CTF Condition ID directly as the base-hash input. Negative risk migration passes the legacy event ID directly as the Event ID base-hash input, then derives its Condition IDs by index. Do not hash either legacy identifier again. Treat MigrationConditionRegistered as the authoritative CTF-to-Polymarket Protocol V2 Condition ID mapping and EventPrepared as the authoritative legacy-to-Polymarket Protocol V2 Event ID mapping. Polymarket Protocol V2 represents a Condition ID as bytes31 and an Event ID as bytes29. Compatibility boundaries that accept or return bytes32 use the same values right-padded with zero bytes. Preserve the native widths when decoding typed ABI values, and pad only when the target ABI requires bytes32. Binary conditions have arity 0 and condition index 0, so their Condition ID is bit-equivalent to their Event ID. Use these masks when decoding a Position ID:
The other binary outcome is derived by replacing outcomeIndex with 0 for YES or 1 for NO. A canonical Condition ID has a zero outcome byte. A canonical Event ID has zero condition and outcome fields.

Index PositionManager Balances and Lifecycle Events

Build balances from TransferSingle and TransferBatch events emitted by PositionManager. Build operator approvals from ApprovalForAll. PositionManager does not expose a general total-supply read for every outcome token. Start from the deployment block or another verified checkpoint if your indexer needs complete historical balances or supply. Use these lifecycle events as transaction context around the ERC-1155 balance changes: Native BinaryModule and NegRiskModule identifiers have no preparation event. CombinatorialModule has its own operation-specific conversion events in addition to those summarized above, and Combo positions are not bridgeable. The Router also emits events for routed splits, merges, conversions, redemptions, and collateral returns. Store these events as call context if needed. Do not apply their amounts as additional ERC-1155 balance updates. CombinatorialModule emits operation-specific events for changes within a Combo, including splits, merges, conversions, extraction, injection, compression, and wrapping. Index the deployed module ABI when those changes must be reconstructed. ERC-1155 transfer events remain the canonical input for balances, minting, burning, and supply. Do not count a lifecycle event and its underlying transfer as two balance changes.

Attribute Polymarket Protocol V2 Exchange Fills

The Polymarket Protocol V2 Exchange emits OrderFilled, OrdersMatched, and FeeCharged. The signed order field is named tokenId and contains the Position ID selected during market discovery. OrderFilled includes the signed builder value and metadata. Record the exchange address or EIP-712 domain version "3" with each order. This keeps fills attributable to the correct position system when both systems use the same order shape.

Track Polymarket Protocol V2 Resolution and Redemptions

BinaryModule and NegRiskModule store result vectors in parts per million. The result denominator is 1,000,000. OracleAggregator events describe reporter consensus and disputes. A ConditionResolved event from BinaryModule or NegRiskModule records the result that controls redemption. CombinatorialModule stores each Combo condition’s BinaryModule and NegRiskModule legs, not a separate result vector. Determine a Combo position’s payout from the stored legs and their underlying module results. CombinatorialModule does not emit ConditionResolved. For native Polymarket Protocol V2 negative risk events, not every result needs a separate stored value:
  • RemainingConditionsDerivableAsNo means the remaining real conditions can be derived as NO after a YES result reaches the full denominator.
  • SyntheticConditionDerivableAsYes means the synthetic Other condition can be derived as YES after every real condition resolves NO.
An indexer that displays all outcomes must apply these derivation rules instead of waiting for one ConditionResolved event per derived result. Do not derive a sibling-NO result for a registered negative risk migration condition. Even if RemainingConditionsDerivableAsNo is emitted for its event, NegRiskModule.getResult excludes registered migration conditions from that derivation. Wait for each migrated real condition’s stored CTF-backed result, recorded by ConditionResolved and MigrationResolved. The synthetic Other condition has no CTF mapping and remains derivable after all real conditions resolve NO. AutoRedeemer emits Redemption for an automated PositionManager redemption. The ledger also emits its normal redemption, burn, and transfer events. Use the AutoRedeemer event to attribute the automated action and the ledger events to update balances and supply.

Track Migration from CTF

Migration moves a registered CTF balance into the corresponding PositionManager balance. Index these events from BinaryModule and NegRiskModule: A migrated condition resolves from the registered CTF payout. A Polymarket Protocol V2 resolver cannot replace that result. A bridge report first derives the result from CTF and must match it. The synthetic Other condition in a negative risk event has no CTF mapping and is derived by NegRiskModule. Migration also emits CTF transfers and PositionManager mint events. Use the ERC-1155 events to update balances, then use PositionMigrated to connect the old and new identifiers.