Price Markets
Pyth-powered price markets that resolve automatically from an on-chain price feed — no UMA bond, no assertion, no dispute path.
Price markets ask "is the price above X at time T?" and resolve deterministically from a price oracle. OddMaki integrates Pyth Network as the first feed provider; the architecture is provider-agnostic and reserves room for additional providers (e.g., Chainlink) as separate resolution facets.
Why Price Markets
The UMA path is ideal for discretionary questions ("Will Team A win?") but overkill when the answer is already on-chain. Price markets use the PriceMarketFacet + PythResolutionFacet pair to:
- Skip the UMA bond, liveness window, and dispute flow entirely
- Resolve at the known close time — no waiting for a human asserter
- Let anyone permissionlessly trigger resolution with a single call
Two Modes
| Mode | Strike | Resolves YES When |
|---|---|---|
| Up/Down | strikePrice = 0 | finalPrice > capturedOpenPrice |
| Strike | strikePrice > 0 | finalPrice >= strikePrice |
In Up/Down mode, the protocol captures the current Pyth price at creation and stores it as openTime / openPrice. In Strike mode, the creator picks the target and no opening snapshot is needed.
Creating a Price Market
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 Pyth BTC/USD at the close timestamp.',
},
// strikePrice: 0n, // omit for Up/Down; set for Strike mode
// outcomes: ['Up', 'Down'], // default
// resolutionWindow: 60n, // Pyth publish-time tolerance (default 60s)
// tags: ['crypto', 'btc'],
});closeTime must be 300s – 86400s from now (5 minutes to 24 hours). For Up/Down mode the SDK fetches a current Pyth update from Hermes and pays the small ETH update fee; Strike mode skips both.
Resolution
Anyone can trigger resolution after closeTime:
const tx = await client.priceMarket.resolvePyth(marketId);The SDK fetches the historical Pyth price at exactly closeTime from the Hermes API, pays the update fee (ETH), and submits it to PythResolutionFacet.resolvePriceMarketPyth. The contract:
- Verifies the update timestamp is within
resolutionWindowofcloseTime - Compares
finalPriceagainst the captured open (or explicit strike) - Reports the payout vector directly to the CTF — no UMA assertion involved
Checking Resolvability
const canResolve = await client.priceMarket.canResolve(marketId);
const pm = await client.priceMarket.get(marketId);
console.log(pm.feedId); // Pyth feed hex id
console.log(pm.openTime); // captured open timestamp
console.log(pm.closeTime); // resolution time
console.log(pm.strikePrice); // 0n for Up/Down
console.log(pm.resolved); // true once resolvePyth succeedsData Model
struct PriceMarket {
bytes32 feedId; // Pyth feed id
FeedProvider feedProvider; // PYTH = 0, CHAINLINK = 1 (reserved)
uint256 openTime; // when opening price was captured
uint256 closeTime; // target resolution time
int32 priceExpo; // Pyth exponent (e.g., -8)
int64 finalPrice; // set on resolution
uint256 resolutionWindow; // publish-time tolerance around closeTime
bool resolved;
int64 strikePrice; // 0 → Up/Down; >0 → Strike
}Storage lives in LibPriceMarketStorage under its own namespaced slot, separate from the UMA resolution storage used by binary markets.
Trading
Price markets trade exactly like binary markets — same orderbook, same settlement paths, same outcome tokens. Outcomes default to ["Up", "Down"] but can be overridden (e.g., ["Above", "Below"] for Strike mode).
Holders of the winning side redeem through the CTF after resolution, just like UMA-resolved markets.
Interplay With UMA
Price markets have no UMA assertion, no oracle lock, and no dispute window. ResolutionFacet.assertMarketOutcome reverts for price markets — the only resolution path is resolvePriceMarketPyth. Conversely, binary and grouped markets cannot be resolved via Pyth.
What's Next
- Creating Markets → — full parameter reference, including Pyth
- Resolution → — how both resolution paths end in a CTF payout vector
- Orderbook → — CLOB mechanics shared across all market types