OddMaki
Configuration

Market Types

Binary markets, market groups with NegRisk, and Pyth-powered price markets — when to use each and how they work.

OddMaki supports three market types. All three use the same ERC-1155 outcome token pair (YES / NO) and the same CLOB — they differ in how many outcomes they represent and how they resolve.

TypeOutcomesOracleWhen to Use
Binary market2 (YES / NO)UMAStandalone discretionary questions
Market groupN (2–50) mutually exclusiveUMA + NegRisk"Who wins?" / "Which of N?"
Price market2 (YES / NO)PythUp / Down on a price feed, auto-resolved

Binary Markets

A standalone binary market is a single YES/NO question. Created via createMarket(), it goes live immediately.

  • Two outcome tokens (YES and NO) minted by the Gnosis CTF
  • Price discovery through an on-chain CLOB
  • Each tick represents a price increment (e.g., $0.01 with a 1% tick size)
  • Resolved independently through UMA
const tx = await client.market.createMarket({
  venueId: 1n,
  question: {
    title: 'Will ETH hit $5000 by Dec 31?',
    description: 'Resolves YES if ETH/USD >= $5000 on any major exchange.',
  },
  outcomes: ['Yes', 'No'],
  tickSize: parseEther('0.01'),
  collateralToken: USDC_ADDRESS,
  additionalReward: 0n,
  liveness: 0n,  // defaults to 2 hours
});

Market Groups

A market group contains N mutually exclusive binary markets where exactly one resolves YES. All share the same collateral, tick size, and oracle parameters.

Lifecycle: Create group → Add outcomes → Activate → Trade

// 1. Create the group
await client.market.createMarketGroup({
  venueId: 1n,
  question: 'Who will win the championship?',
  description: 'Resolves YES for the winning team.',
  collateralToken: USDC_ADDRESS,
  tickSize: parseEther('0.01'),
  additionalReward: 0n,
  liveness: 0n,
});

// 2. Add outcomes
await client.market.addMarketToGroup({
  marketGroupId: 1n,
  marketName: 'Team A',
  marketQuestion: 'Will Team A win?',
});

// 3. Activate (locks totalMarkets, enables trading)
await client.market.activateMarketGroup({ marketGroupId: 1n });

Groups support placeholder markets — reserve slots for outcomes added later. Add placeholders before activation, then activate them individually once the outcome is known.

NegRisk

NegRisk ensures mutual exclusivity through two mechanisms:

Cascade resolution — When one market resolves YES, all sibling markets automatically resolve NO in the same transaction. No separate assertion needed for siblings.

Position conversion — Holders of NO positions across multiple markets in a group can convert them into YES positions in the complementary markets, plus collateral returned. This keeps pricing consistent across the group.

Conversion math (for a group with N total markets):

  • Input: NO tokens from noCount different markets, amount each
  • Output: YES tokens for the remaining N - noCount markets + (noCount - 1) * amount collateral

Price Markets

Price markets are binary markets that resolve automatically from a Pyth price feed at a fixed close time. No UMA bond, no liveness, no assertions — the feed's historical price at the close timestamp determines the outcome.

Modes:

  • Up/Down — YES resolves if the final price is higher than the captured open price
  • Strike — YES resolves if the final price is ≥ strikePrice (specify strikePrice at creation)
const tx = await client.priceMarket.createPyth({
  venueId: 1n,
  pythFeedId: '0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43', // BTC/USD
  closeTime: BigInt(Math.floor(Date.now() / 1000) + 86400), // +24h
  tickSize: parseEther('0.01'),
  collateralToken: USDC_ADDRESS,
  question: {
    title: 'Will BTC close above its open price in 24h?',
    description: 'Resolves from the Pyth BTC/USD feed at the close timestamp.',
  },
  // strikePrice: 0n  // omit or 0 → Up/Down mode using captured open
});

// Anyone can trigger resolution once closeTime has passed
await client.priceMarket.resolvePyth(marketId);

See Price Markets for the full details on feeds, resolution windows, and on-chain mechanics.

Choosing the Right Type

BinaryMarket GroupPrice Market
Question styleYes/NoWhich one of N?Will the price go Up/Down?
Outcomes2 (YES/NO)N mutually exclusive2 (YES/NO)
ResolutionUMA assertionUMA + cascadePyth auto-resolution
Bond / disputeRequiredRequiredNone
Position conversionN/ANegRisk conversionN/A
Max outcomes250 per group2
Examples"Will X happen?""Who will win?""BTC Up or Down today?"

Use binary for simple yes/no questions with discretionary resolution. Use market groups when outcomes are mutually exclusive and you need consistent pricing across them. Use price markets for high-frequency predictions on asset prices where automation matters.

Examples

Binary: "Will BTC reach $100k by end of 2026?" — Two outcomes, independent UMA resolution.

Market Group: "Where will Giannis be traded?" — Add each team as an outcome. When one team acquires him, that market resolves YES and all others cascade to NO.

Market Group with placeholders: "Who will win the election?" — Start with known candidates, reserve placeholder slots for late entrants. Activate placeholders as new candidates emerge.

Price Market (Up/Down): "ETH 24h close above open?" — Create at 00:00 UTC, closeTime at 24:00 UTC. Resolves automatically from Pyth at 24:00.

Price Market (Strike): "BTC ≥ $100,000 on Jan 1?" — Set strikePrice = 100_000e8, closeTime at the target timestamp.

What's Next