0️⃣1️⃣ A Detailed Look at Polymarket’s Outcome Tokens

Tl;dr:

  • Polymarket outcome tokens are represented using the Gnosis Conditional Tokens Framework’s ERC1155 tokens.

  • Outcome tokens are derived from a shared conditionId unique indexSets and a reference to the underlying ERC20 collateral token.

  • Full outcome sets can be created from one unit of collateral in an operation called “splitting”.

  • Full outcome sets can be exchanged for the underlying unit of collateral in an operation called “merging”.

Introduction:

All outcomes on Polymarket are tokenized and exchanged non-custodially and atomically via the Polygon network. In this brief article, we detail the outcome token primitive that underlies all Polymarket markets with specific focus on the binary case.

Binary Tokens Detailed:

Binary outcomes (ie “YES” and “NO”) on Polymarket are represented using Gnosis’ Conditional Token Framework (CTF). They are distinct ERC1155 tokens related to a parent condition and backed by some collateral. More technically, the binary outcome tokens are referred to as “positionIds” in Gnosis’s documentation. “PositionIds” are derived from a collateral token and distinct “collectionIds”. “CollectionIds” are derived from a “parentCollectionId”, (always bytes32(0) in our case) a “conditionId”, and a unique “indexSet”. The “indexSet” is a 256 bit array denoting which outcome slots are in an outcome collection; it must be a nonempty proper subset of a condition’s outcome slots. In the binary case, which we are interested in, there are two “indexSets”, one for the first outcome and one for the second. The first outcome’s “indexSet” is 0b01 == 1 and the second’s is 0b10 == 2. The parent “conditionId” (shared by both “collectionIds” and therefore “positionIds”) is derived from a “questionId” (an IPFS hash of market details), an “oracle” address (the UMA adapter V2) and an “outcomeSlotCount” (always 2 in the binary case). Below we summarize the steps for calculating “positionIds”.

Calculating PositionIds:

  1. Get the conditionId

    • Function:

      • getConditionId(oracle, questionId, outcomeSlotCount
    • Inputs:

      • oracle: address - UMA adapter V2

      • questionId: bytes32 - an IPFS hash of market details

      • outcomeSlotCount: uint - 2 for binary markets

  2. Get the two collectionIds

    • Function:

      • getCollectionId(parentCollectionId, conditionId, indexSet)
    • Inputs:

      • parentCollectionId: bytes32 - bytes32(0)

      • conditionId: bytes32 - the conditionId derived from (1)

      • indexSet: uint - 1 (0b01) for the first and 2 (0b10) for the second.

  3. Get the two positionIds

    • Function:

      • getPositionId(collateralToken, collectionId)
    • Inputs:

      • collateralToken: IERC20 - address of ERC20 token collateral (USDC)

      • collectionId: bytes32 - the two collectionIds derived from (3)

See this gist for typescript implementations of the above functions which mirror the solidity function implementations here.

Splitting & Merging

Leveraging the relations above, specifically “conditionIds” → “positionIds” the Gnosis CTF contract allows for “splitting” and “merging” full outcome sets. This means, for prepared conditions (markets), any user can, at any time, split one unit of collateral (USDC) for 1 of each binary outcome token and can, at any time, merge one of each outcome token into one unit of collateral. This means in correctly structured marketplace, the market price of these tokens should always be somewhere between (0, 1) unit of collateral and should sum to 1.

Subscribe to Polymarket
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.