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.
| Type | Outcomes | Oracle | When to Use |
|---|---|---|---|
| Binary market | 2 (YES / NO) | UMA | Standalone discretionary questions |
| Market group | N (2–50) mutually exclusive | UMA + NegRisk | "Who wins?" / "Which of N?" |
| Price market | 2 (YES / NO) | Pyth | Up / 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
noCountdifferent markets,amounteach - Output: YES tokens for the remaining
N - noCountmarkets +(noCount - 1) * amountcollateral
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
strikePriceat 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
| Binary | Market Group | Price Market | |
|---|---|---|---|
| Question style | Yes/No | Which one of N? | Will the price go Up/Down? |
| Outcomes | 2 (YES/NO) | N mutually exclusive | 2 (YES/NO) |
| Resolution | UMA assertion | UMA + cascade | Pyth auto-resolution |
| Bond / dispute | Required | Required | None |
| Position conversion | N/A | NegRisk conversion | N/A |
| Max outcomes | 2 | 50 per group | 2 |
| 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
- Creating Markets → — step-by-step creation for each type
- Resolution → — how markets resolve, including cascade and Pyth paths
- Token Mechanics → — how outcome tokens and NegRisk conversion work
- Price Markets → — deep dive into the Pyth-powered path