Skip to main content
The Gnosis / Polymarket conditional token framework, ported by PredictStreet and used as the settlement substrate. Condition, collection and position ids are computed with the upstream formulas, but the event signatures differ from upstream (see Events), so do not decode logs with an upstream or Polymarket ABI.

Key concepts

  • Condition — an (oracle, questionId, outcomeSlotCount) tuple.
  • Position — an ERC-1155 balance of a specific outcome slot within a condition.
  • Redemption — once the oracle reports payouts, holders call redeemPositions to exchange winning tokens for USDC.

Prepare a condition

Called by the platform as part of market deployment.

Redeem winning positions

Redeeming your positions

Your outcome tokens sit in your vault, not in your EOA. ConditionalTokens.redeemPositions pays out only the caller’s own balance, so calling it from your EOA burns nothing and pays nothing. Redeem in one of these ways instead:
  • Automatic — auto-redeem is on by default. Within a few minutes of a market’s final status the platform redeems for you, and pays the gas for, the refund on a voided market and your winnings on a resolved market when they pay at least 1 USDC on that market. Smaller winnings are left for you to claim, so check redeemable on GET /api/me/positions?status=redeemable and use one of the paths below for anything still redeemable. Read or change the setting with GET / PUT /api/me/auto-redeem (body { "enabled": true | false }); details in Auto-redeem.
  • Gasless API — POST /api/me/positions/redeem (vault:write scope) with the position’s { "marketId", "outcomeIndex" } as returned by GET /api/me/positions (0 = YES, 1 = NO). API-key callers must also send auth: { deadline, v, r, s }: an EIP-712 RedeemAuthorization(address owner, string marketId, uint8 outcomeIndex, uint256 deadline) signed by the wallet owner under the domain { name: "PredictStreetRedeem", version: "1", chainId } (no verifyingContract). The response is { jobId, status }; poll GET /api/me/positions/redeem/{jobId} until status is confirmed (or failed_permanent / expired).
  • On-chain, from the vault-owner EOA — vault.redeemPositions(conditionId, indexSets) for binary markets, or vault.redeemPositionsNegRisk(marketId, questionIndex, amount) for neg-risk markets. No backend co-signature is needed; only the vault owner (or the platform) may call them, anyone else gets NotOwner(). See Positions → Redeeming a resolved position for which fields to pass.
Every path credits the USDC payout to your vault, where it shows up in the USDC row of GET /api/me/balances. There is no separate “claim” step.

Events

seq is a counter that increases by one with each of these five events, across the whole contract, so a gap means you missed a log.

Source

0x66Ed938E9Dec9A1df6033d66560d5fe6117EE744 on Blockscout (testnet). Based on Gnosis ConditionalTokens via Polymarket’s fork. Differences from upstream: every event above starts with uint64 seq, PayoutRedemption indexes conditionId instead of parentCollectionId, and redeemPositions returns the total payout.