Module 08: Prediction Markets

Prerequisites

Next steps after a market action

  • Bet on an outcome? Track shares with getUserShares(); redeem after resolution
  • Bought a Predict+ token? Borrow against it (→05) and deploy elsewhere
  • Created a market? Build the full creator stack via Module 13; compare to token creation
  • Want to resolve markets for bounty? See the deep dive in Module 14

1. Why Prediction Markets on BASIS

BASIS prediction markets are structurally different from platforms like Polymarket. Three differences define the edge:

Uncapped payouts. On Polymarket, winning shares always pay exactly $1 — volume affects liquidity, not your return. On BASIS, all pools (every outcome, plus the general pot) merge into one big pot on resolution. Your payout is (your winning shares / total winning shares) × entire merged pot. A share bought at 5c can pay $4+ if the pot is large enough. The economics are better on trade one, at any volume level, because the structure is different.

Instant AMM liquidity. Traditional platforms need a counterparty for every trade. BASIS uses a one-directional AMM — buys go through the AMM, sells go through the order book. Because the AMM only handles buys, virtual liquidity can be set arbitrarily high without real capital backing it. Every market has instant fills from creation, including niche topics and off-peak hours.

Multiple independent income streams. Traditional platforms give you one role: bettor. BASIS opens at minimum three independent profit paths from a single market simultaneously — see Module 13 for full role breakdowns.

The Two Assets Every Market Creates

Every prediction market creates two completely separate assets:

AssetWhat It IsHow It Profits
Predict+ tokenA Stable+ subtype. Market token. Price can only go up, driven by trading volume.Volume play — appreciates regardless of which outcome wins. Trade on the DEX like any token.
Outcome sharesWhat you buy to bet on a specific result. One set per outcome.Conviction play — proportional share of the merged pot on resolution.

These are not the same thing. Buying the Predict+ token is not a bet. Buying outcome shares is not token trading. They have different mechanics, different flows, and different risk profiles.

Who Benefits

RoleHowWhat You Need
Creator20% of net trading fees forever (0.1% of trade volume)A compelling question
BettorUncapped payout from winning outcome sharesConviction on an outcome
TraderPredict+ token appreciates from market volumeRead on activity levels
ResolverBounty pool for proposing and finalizing correct outcomesAccurate information
Leveraged playerCollateralise Predict+ tokens → borrow USDB → buy outcome sharesAny of the above

2. How It Works

Market Structure

  • A market has a question, up to 150 outcomes (creative market designs in Module 13), an end time (0 = open-ended, or a future timestamp ≥ now + 60s), and a seed amount in $10 increments. Seed minimums vary by market type: Basis-managed public markets = 50 USDB, creator-created public markets = 10 USDB, creator-created private markets = 0 USDB (no minimum). The seed funds the resolution bounty and the general pot — it is not liquidity for the outcome pools.
  • At creation, each outcome gets its own AMM pool seeded with virtual liquidity at launch — creator pays nothing for it. Real liquidity accumulates as users buy into outcomes.
  • Trading fees are 1.5% gross (compare to Floor+ fee structure). Of that: 1% feeds back into the prediction ecosystem (0.95% → general pot, 0.05% → bounty pool). The remaining 0.5% is the net platform fee, split: creator 20%, staking vault 16%, platform 60%, reward-phase buyers 4%. Creator ends up with 0.1% of all trade volume.

Buying Shares

Shares are bought via AMM — instant fill, no counterparty. Price per share reflects implied probability. As more capital flows into one outcome, shares become more expensive (lower potential upside) and other outcomes become relatively cheaper.

Selling Shares

Selling goes through the P2P order book. You list at your chosen price. Because resolution value can far exceed the AMM buy price (e.g., bought at 5c, resolution value $4+), both sides of an order book trade can be genuinely profitable — a dynamic fixed-payout platforms cannot produce.

On Resolution: The Merged Pot

When a market resolves:

  1. All outcome pools (winners and losers) + the accumulated general pot merge into one big pot.
  2. Winning outcome share holders receive proportional payouts: (your shares / total winning shares) × total pot.
  3. If your outcome lost: no shares to redeem.

Special resolution outcomes (see Module 14 for edge cases):

  • INVALID (254): Proportional refund to all participants.
  • EARLY (253): Market resets — round increments, fresh proposal cycle. Only the disputer can propose EARLY.

Resolution Lifecycle

Market end time passes ↓ Anyone calls proposeOutcome(marketToken, outcomeId) — posts 5 USDB bond ↓ Challenge period (PROPOSAL_PERIOD — target: 2 hours*) ├── No dispute → finalizeUncontested() → Proposer: bond back + 100% bounty → Winners redeem └── Disputed (5 USDB bond) → Voting period (DISPUTE_PERIOD — target: 24 hours*) ↓ Staked voters vote (≥ 5 tokens staked, one-staker-one-vote, 70% supermajority) ↓ finalizeMarket() → Winners redeem → Correct side claims bonds + bounty

Current testing values are 30 minutes for all periods (Phase 1 only — production targets in later phases: 2h proposal, 24h dispute/voting, 1h veto). Read values from the contract at runtime — do not hardcode. See Resolver Read Methods.


3. Actions

3a. Create a Market

client.predictionMarkets.createMarketWithMetadata(options) — creates the market and registers metadata on IPFS in one call. Requires SIWE authentication.

JS:

const market = await client.predictionMarkets.createMarketWithMetadata({
  marketName: "Will ETH reach $10k this month?",
  symbol: "ETH10K",                                     // MUST BE CAPITALISED
  endTime: BigInt(Math.floor(Date.now() / 1000) + 86400 * 30),
  optionNames: ["Yes", "No"],
  maintoken: client.mainTokenAddress,
  seedAmount: parseUnits("10", 18),                     // $10 increments. Min: 50 USDB (Basis-managed public), 10 USDB (creator public), 0 (creator private)
  description: "ETH price prediction.",
  imageUrl: "https://example.com/eth.jpg",
});
const marketToken = market.marketTokenAddress;

Python:

import time
market = client.prediction_markets.create_market_with_metadata(
    market_name="Will ETH reach $10k this month?",
    symbol="ETH10K",
    end_time=int(time.time()) + 86400 * 30,
    option_names=["Yes", "No"],
    maintoken=client.main_token_address,
    seed_amount=10 * 10**18,  # $10 increments. Min: 50 (Basis-managed public), 10 (creator public), 0 (creator private)
)
market_token = market["market_token_address"]
ParameterRequiredNotes
marketNameyesQuestion/title
symbolyesMust be CAPITALISED (e.g., "ETH10K", not "eth10k")
endTimeyesUnix timestamp. 0 = open-ended. If set, must be ≥ now + 60s
optionNamesyesArray of outcome names, up to 150
maintokenyesclient.mainTokenAddress
seedAmountnoUSDB seed in 18 decimals. Must be in $10 increments across all tiers. Minimums by market type: Basis-managed public = 50 USDB, creator public = 10 USDB, creator private = 0 (no minimum). Funds the resolution bounty + general pot — not outcome-pool liquidity (pools are virtual at launch)
description, imageUrl, website, telegram, twitterxnoMetadata
frozennotrue = only whitelisted wallets can buy until unfrozen (see whitelist pattern)
bondingnoReward-phase allocation in USDB (same mechanic as usdbForBonding on token creation; see reward-phase pricing)

Returns: { hash, receipt, marketTokenAddress, imageUrl, metadata }

For private markets (creator-managed resolution), use client.privateMarkets.createMarketWithMetadata() instead — same parameters plus privateEvent: true to restrict buying to whitelisted addresses. See Section 4.


3b. Bet (Buy Outcome Shares)

client.predictionMarkets.buy(marketToken, outcomeId, inputToken, inputAmount, minUsdb, minShares) — buys shares for a specific outcome. Auto-approves input token (see approval patterns in Module 02).

JS:

// Preview current prices first
const outcomes = await client.marketReader.getAllOutcomes(
  "0x396216fc9d2c220afD227B59097cf97B7dEaCb57", // MarketTrading contract
  marketToken
);
const yesPrice = outcomes[0].pricePerShare;
const fiveUsdb = parseUnits("5", 18);
const expectedShares = fiveUsdb * BigInt(1e18) / yesPrice;
const minShares = expectedShares * 98n / 100n; // 2% slippage tolerance

const result = await client.predictionMarkets.buy(
  marketToken,
  0,          // outcomeId (0-based)
  USDB,
  fiveUsdb,
  0n,         // minUsdb (for non-USDB inputs only)
  minShares
);

Python:

outcomes = client.market_reader.get_all_outcomes(
    "0x396216fc9d2c220afD227B59097cf97B7dEaCb57", market_token
)
yes_price = int(outcomes[0]["pricePerShare"])
five_usdb = 5 * 10**18
expected_shares = five_usdb * 10**18 // yes_price
min_shares = expected_shares * 98 // 100  # 2% slippage
result = client.prediction_markets.buy(market_token, 0, USDB, five_usdb, 0, min_shares)
ParamDescription
marketTokenMarket token address
outcomeIdOutcome index, 0-based
inputTokenToken to pay with (typically USDB address)
inputAmountAmount to spend (18 decimals)
minUsdbMin USDB equivalent — use for non-USDB inputs, else 0
minSharesMin shares to receive — always set in production (see slippage tolerance →04)

Pre-flight checks: verify outcomeId is within range (getNumOutcomes()), verify market is not resolved (getMarketData().resolved).


3c. Order Book (Sell / P2P Trade)

The order book handles peer-to-peer limit orders for outcome shares. Use it to sell shares before resolution or to buy shares at a specific price. (Advanced order book strategies for traders → Module 13.)

List a Sell Order

client.orderBook.listOrder(marketToken, outcomeId, amount, pricePerShare)

// List 100 shares of outcome 0 at 0.60 USDB per share
const result = await client.orderBook.listOrder(
  marketToken, 0, parseUnits("100", 18), parseUnits("0.6", 18)
);
result = client.order_book.list_order(
    market_token, 0, 100 * 10**18, 600_000_000_000_000_000  # 0.60 USDB
)

Fill an Order

client.orderBook.buyOrder(marketToken, orderId, fill)fill is the USDB amount to spend.

client.orderBook.buyMultipleOrders(marketToken, orderIds, usdbAmount) — fill several orders in one tx.

Cancel an Order

client.orderBook.cancelOrder(marketToken, orderId)

Hybrid Fill (Order Book + AMM)

client.predictionMarkets.buyOrdersAndContract(marketToken, outcomeId, orderIds, inputToken, totalInput, minShares) — fills the listed orders first, then buys remaining from AMM, all in one transaction.

Order Book Reads

MethodReturns
client.orderBook.getBuyOrderCost(marketToken, orderId, fill){ baseUsdb, buyerTax, totalCostToBuyer, netToSeller }
client.orderBook.getBuyOrderAmountsOut(marketToken, orderId, usdbAmount){ fill, baseUsdb, buyerTax, totalCostToBuyer }
client.predictionMarkets.getBuyOrderAmountsOut(marketToken, orderId, usdbAmount)Preview order fill from prediction module

3d. Redeem (Collect Winnings)

client.predictionMarkets.redeem(marketToken) — after resolution, winning share holders call this to claim their proportional share of the merged pot. Free.

const receipt = await client.predictionMarkets.redeem(marketToken);
// Parse redeemed USDB from transfer logs:
const redeemed = parseEventLogs({ abi: erc20Abi, logs: receipt.logs })
  .find(e => e.eventName === 'Transfer' && e.args.to === wallet)?.args.value;
receipt = client.prediction_markets.redeem(market_token)

If your outcome did not win, there is nothing to redeem. "No winning shares" error = your bet lost.


3e. Basic Resolution

Full resolution strategy is covered in Module 14. Here is the mechanical flow.

Step 1 — Discover Markets Needing Resolution

const markets = await client.api.getTokens({ isPrediction: true, limit: 100 });
const needsProposal = markets.data.filter(m => m.predictionStatus === "awaiting_proposal");
const inDispute = markets.data.filter(m => m.predictionStatus === "disputed");

predictionStatus values: "active" | "awaiting_proposal" | "proposed" | "disputed" | "resolved"

Step 2 — Propose an Outcome

client.resolver.proposeOutcome(marketToken, outcomeId) — posts 5 USDB bond automatically. If uncontested after the challenge period, the proposer calls finalizeUncontested() and receives bond back + 100% of the bounty pool.

Also available as client.resolver.propose() — identical behavior.

Step 3 — Finalize (Uncontested)

client.resolver.finalizeUncontested(marketToken) — anyone can call after the challenge period expires with no dispute.

Step 4 — If Disputed

client.resolver.dispute(marketToken, newOutcomeId) — dispute the current proposal with an alternative outcome. Posts 5 USDB bond. Triggers the voting period.

Self-dispute is allowed — you can dispute your own proposal to correct a mistake (cost: one extra bond).

Step 5 — Vote

To vote you must first stake: client.resolver.stake(token) — pass any active ecosystem token address. The SDK auto-reads MIN_STAKE_AMOUNT (currently 5 tokens) and approves. One vote per staker regardless of stake size above minimum.

Then: client.resolver.vote(marketToken, outcomeId)

After voting, staked tokens are locked for 24 hours (VOTE_LOCK_DURATION). Check all loan expiry dates before voting — you cannot unstake to repay a loan during the lock window.

Finalize after voting: client.resolver.finalizeMarket(marketToken) — requires quorum met and 70% supermajority.

Step 6 — Claim Bounty

client.resolver.claimBounty(marketToken) — claim if you were the uncontested proposer or voted on the winning side.

Complete Example (JS)

// 1. Discover and propose
const markets = await client.api.getTokens({ isPrediction: true, limit: 100 });
const market = markets.data.find(m => m.predictionStatus === "awaiting_proposal");
await client.resolver.proposeOutcome(market.address, 0); // 0 = "Yes"

// 2. Wait for challenge period, then try to finalize
try {
  await client.resolver.finalizeUncontested(market.address);
  // Bond returned + 100% bounty
} catch (e) {
  // Was disputed — stake and vote
  await client.resolver.stake("0xEcosystemTokenAddress");
  await client.resolver.vote(market.address, 0);
  // Wait for voting period, then finalize
  await client.resolver.finalizeMarket(market.address);
}

// 3. Claim bounty
await client.resolver.claimBounty(market.address);

Resolver Read Methods

MethodReturns
isResolved(marketToken)boolean
getFinalOutcome(marketToken)number — winning outcome index
isInDispute(marketToken)boolean
isInVeto(marketToken)boolean
getCurrentRound(marketToken)number
getDisputeData(marketToken)Dispute details including proposalEndTime
getUserStake(marketToken, user)string
isVoter(marketToken, user)boolean
getVoteCount(marketToken, outcomeId)number
hasVoted(marketToken, user)boolean
getVoterChoice(marketToken, user)number
getBountyPerVote(marketToken)string
hasClaimed(marketToken, user)boolean

4. Private Markets

Private markets use creator-managed resolution (skipping the public dispute/vote flow). The creator and their designated voters resolve the market directly.

Create: client.privateMarkets.createMarketWithMetadata(options) — same parameters as public plus:

  • privateEvent: true — restricts buying to whitelisted addresses only (same whitelist pattern as gated tokens)

Manage voters: client.privateMarkets.manageVoter(marketToken, voter, add)add=true adds, add=false removes.

Resolution flow: After end time, eligible voters call client.privateMarkets.vote(marketToken, outcomeId). Voting window is 15 minutes from the first vote. Majority wins. Anyone calls client.privateMarkets.finalize(marketToken) after the window.

Important: Private markets do NOT show predictionStatus === "awaiting_proposal". To detect: check isPrivate in the API response. Private markets waiting for resolution will show an end time in the past with no finalized outcome.

MethodDescription
vote(marketToken, outcomeId)Cast resolution vote (creator + whitelisted voters)
finalize(marketToken)Finalize after voting window ends
claimBounty(marketToken)Claim resolver bounty
manageVoter(marketToken, voter, add)Add/remove voter
togglePrivateEventBuyers(marketToken, buyers, status)Whitelist/unwhitelist buyer addresses
disableFreeze(marketToken)Open frozen market to public
manageWhitelist(marketToken, wallets, amount, tag, status)Manage frozen market whitelist

Private markets share all prediction market and order book read methods.


5. Read Methods

Prediction Markets (client.predictionMarkets)

MethodReturnsNotes
getMarketData(marketToken)MarketData structIncludes resolved, finalOutcome, generalPot, isPrivate, endTime
getOutcome(marketToken, outcomeId)Outcome struct{ virtualReserve, totalCost, circulatingShares }
getUserShares(marketToken, user, outcomeId)bigintShares held, 18 decimals
getNumOutcomes(marketToken)bigintTotal outcome count
getOptionNames(marketToken)string[]Outcome names array
hasBettedOnMarket(marketToken, user)boolean
getBountyPool(marketToken)bigintUSDB in bounty pool, 18 decimals
getGeneralPot(marketToken)bigintUSDB accumulated in general pot
getInitialReserves(numOutcomes)[bigint, bigint][perOutcomeReserve, totalReserve]
getBuyOrderAmountsOut(marketToken, orderId, usdbAmount){ fill, baseUsdb, buyerTax, totalCostToBuyer }Preview order book fill

Market Reader (client.marketReader)

MethodReturnsNotes
getAllOutcomes(routerAddress, marketToken)OutcomeInfo[]Full outcome data including pricePerShare, probability, hasWon. Router = 0x396216fc9d2c220afD227B59097cf97B7dEaCb57
estimateSharesOut(routerAddress, marketToken, outcomeId, usdbAmount, orderIds, user)bigintEstimated shares from combined AMM + order book fill
getPotentialPayout(routerAddress, marketToken, outcomeId, sharesAmount, estimatedUsdbToPool)[bigint, bigint][holdPayout, simulatedAmmPayout]

Implied probability from getAllOutcomes: Number(outcome.probability) / 1e18 * 100 gives percentage.

Market Reader Aggregates (client.api)

// All prediction markets
const all = await client.api.getTokens({ isPrediction: true, limit: 100 });
// Filter by status
const active = all.data.filter(m => m.predictionStatus === "active");

6. Fees

ActionCostGoes To
Market creationSeed amount (USDB, $10 increments)Bounty pool + general pot (outcome pools are virtual at launch — no liquidity deposit required)
Buy outcome shares1.5% gross1% → prediction ecosystem (0.95% general pot, 0.05% bounty); 0.5% net fee (creator 20%, staking →06 16%, platform 60%, reward buyers 4%)
Predict+ token trading1.5% gross (same structure)Same as above
List order / cancel orderFree
Fill orderBuyer tax (included in buyerTax field)Platform
Resolution proposal5 USDB bondReturned if uncontested. Winner gets both bonds if disputed
Dispute5 USDB bondWinner of dispute gets both bonds
Veto5 USDB bondOne per market, post-voting window only
Stake to vote5 tokens minimum (any active ecosystem token)Staked, returned on unstake (after 24h lock post-vote)
RedeemFree

Creator earnings: 20% of net trading fees = 0.1% of all trade volume on Predict+ tokens (vs 0.3% on Floor+ tokens, because 2/3 of the gross fee on Predict+ goes back into the prediction ecosystem).

No surge tax on Predict+ tokens.


7. Errors

ErrorCauseFix
Seed must be in $10 incrementsseedAmount not divisible by 10 USDBRound seed to nearest $10
Seed below minimumSeed < minimum for market type (50 USDB Basis-managed public / 10 USDB creator public / 0 creator private)Increase seed to match your tier
Invalid outcome IDoutcomeIdgetNumOutcomes()Check getNumOutcomes() before buy
Market already resolvedBuying shares on a resolved marketCheck getMarketData().resolved
Slippage exceededminShares not metIncrease tolerance or re-preview price
Market not endedProposing before endTimeWait for end time
Already proposedAnother proposal already activeCheck getDisputeData() for existing proposal
Challenge period activeCalling finalizeUncontested before period expiresWait for PROPOSAL_PERIOD to elapse
Not in disputeCalling vote/finalize before a dispute is filedFile dispute first
Voting period not endedCalling finalizeMarket before DISPUTE_PERIOD expiresWait for voting period
Tie - vote moreNo 70% supermajority reachedMore voters needed
Quorum not metInsufficient votersWait for more votes
Already votedVoting twice on same marketOne vote per staker
Insufficient stakeVoting without ≥ 5 tokens stakedCall stake(token) first
Cannot fill own orderTrying to fill your own order book listingUse a different wallet
No winning sharesCalling redeem with shares in a losing outcomeOutcome lost — nothing to redeem
Symbol must be capitalisedLowercase symbol in createMarketWithMetadataUse "ETH10K" not "eth10k"

8. Strategy Context

Stacking: Paths C and D

Prediction markets fit into two stacking paths. Use these as building blocks inside multi-stack strategies (full stacking reference → Module 12).

Path C — Predict+ Token Path:

USDB → buy Predict+ token → borrow USDB against it
  • Position held: Predict+ token (appreciates from market volume regardless of outcome)
  • USDB recovered: ~96.5% of input (1.5% buy tax + 2% loan origination)
  • Risk: loan expiry + market must stay active
  • Points: Trade + Prediction + Lending categories (airdrop scoring)

Path D — Outcome Bet Path:

USDB → buy outcome shares → [wait for resolution] → USDB (if correct)
  • Position held: outcome shares
  • USDB recovered: only on correct outcome — but payout is uncapped
  • Risk: you lose if the outcome is wrong
  • Points: Prediction category (airdrop scoring)

Combining C and D (the Quick Stack — see also Module 12 §5):

  1. Buy Predict+ tokens → borrow USDB
  2. Use borrowed USDB to buy outcome shares on the same market
  3. Two positions from one bag: token appreciating from volume, shares waiting on resolution
  4. Win the bet → collect winnings → repay loan → still own the Predict+ tokens

Three-stack fee reality check: After Path A (wSTASIS →06) → Path C (Predict+) → Path D (bet), you've deployed ~91-92 cents of every dollar across three positions with ~8-9 cents total in fees. Three stacks is the sweet spot before fees bite meaningfully.

Creator vs Bettor vs Trader

Three independent roles, each profitable standalone. Combining them is the real edge.

Creator (passive): Earn 20% of net fees from all trading forever. Create questions that generate genuine disagreement. A dead market costs gas with zero return.

Bettor (conviction): Uncapped payouts reward early conviction. Buy before consensus forms. Use the order book to exit if conviction changes — you can list shares at your own price, and both sides of the trade can genuinely profit because of the uncapped resolution value.

Trader (volume): Buy Predict+ tokens on high-activity markets. You're betting on controversy and volume, not outcomes. Predict+ tokens are a Stable+ subtype — price can only go up. Hold through the market lifecycle and sell after resolution for maximum appreciation.

The maximum extraction play: create the market + buy Predict+ tokens + bet on an outcome + resolve it yourself. Four independent income streams from one market.

Full roles, combined strategies, and capital recycling loops → Module 13. Advanced resolution, bounty hunting, veto mechanics → Module 14.


Key Facts (Quick Reference)

ParameterValue
Max outcomes per market150
Seed increment$10 USDB
Min seed (Basis-managed public)50 USDB
Min seed (creator public)10 USDB
Min seed (creator private)0 (no minimum)
Creator fee share20% of net fee = 0.1% of trade volume
Proposal bond5 USDB
Dispute bond5 USDB (no escalation)
Min stake to vote5 tokens (any active ecosystem token)
Voting ruleOne-staker-one-vote, 70% supermajority
Vote lock duration24 hours after voting
Uncapped payoutsAll pools merge on resolution
No surge taxPredict+ tokens are exempt

Error Handling

Pre-Flight Checks

Before prediction market operations:

  • Seed in $10 increments across all tiers. Minimums: 50 USDB (Basis-managed public), 10 USDB (creator public), 0 (creator private)
  • End time: 0 (open-ended) or ≥ now + 60 seconds
  • Check outcome IDs exist before betting/proposing (use getMarketData())
  • For resolution: staked ≥ 5 tokens in resolver, market in correct phase, not in veto
  • Check USDB balance before seeding or betting
  • Simulate order book fills before large orders

Common Errors

ErrorWhenFix
"Seed below minimum" / "Seed low"createMarket()Increase seed to match tier min (50 Basis-managed public / 10 creator public / 0 creator private)
"Seed must be in increments of 10 USD"createMarket()Use multiples of 10 ($50, $100, not $55)
"End time error"createMarket()Set 0 (no end) or future timestamp ≥ now + 60s
"Bad outcome" / "Invalid outcome"Betting, proposing, votingCheck getMarketInfo() for valid outcome IDs
"min shares not met" / "min usdc not met"Prediction buy/sellIncrease slippage tolerance or reduce size. Note: "usdc" is a legacy contract string — it means USDB.
"market resolved"Trading on resolved marketRedeem winning shares or accept loss
"Already proposed"proposeResolution()Dispute it (5 USDB) or wait for quiet period
"Already in dispute"disputeResolution()Vote instead of filing another dispute
"No proposal to dispute"disputeResolution()Propose a resolution yourself first
"No winning shares" / "No payout"redeem()Your bet lost — nothing to claim
"Not voting"vote()Market not in dispute phase; wait for dispute
"Must stake 5 tokens to vote"vote()Stake ≥ 5 tokens in resolver first
"Stake locked due to recent vote"Unstake from resolverWait for cooldown to expire (24h after voting)
"cannot vote during veto"vote() during vetoWait for veto period to end
"Order inactive or market resolved"Filling limit orderBrowse active orders for this market
"Not your order"Cancelling limit orderOnly cancel your own orders
"Cannot fill own order"Filling own orderUse different wallet, or cancel and re-place
"Insufficient available shares"Selling/listing sharesCheck userShares balance first

Recovery Flow: Market Resolution Disputed

  1. Your proposal was disputed — you lose nothing (bond is at risk only if outcome is overturned)
  2. Wait for voting phase to begin
  3. If you have ≥ 5 staked tokens: vote for your proposed outcome
  4. Rally other stakers to vote (70% supermajority needed)
  5. If voting resolves in your favor: you earn the bounty. If not: bond is forfeited.

Recovery Flow: Shares Have No Value After Resolution

  1. Check which outcome won: getMarketData()finalOutcome
  2. If you hold winning shares: call redeem() — payout = your share of entire merged pool
  3. If you hold losing shares: nothing to claim. Learn from the loss.
  4. Check if you also hold Predict+ tokens: these may still have value (Stable+ mechanics — price only goes up; sell on the DEX →04)