Skip to content

Prediction Markets - sybil-resistant, 1 human = 1 position #31

@het4rk

Description

@het4rk

Product Requirements (PRD)

Problem

Existing prediction markets (Polymarket, Kalshi) are dominated by whales and can be manipulated by wealthy actors. The "wisdom of the crowd" only works when each voice has equal weight.

Solution

Sybil-resistant prediction markets where each World ID-verified human gets exactly one position per market. No whales, no bots, no manipulation. The purest crowd wisdom signal possible.

User Stories

  1. As a user, I want to predict outcomes on topics I care about and earn WLD if I'm right.
  2. As a data consumer, I want access to prediction data where each data point represents a unique verified human.
  3. As a community, we want to collectively forecast events with each person having equal voice.

Features

Market Creation

  • Binary markets: "Will X happen by Y date?" (Yes/No)
  • Created by verified humans with karma > threshold
  • Resolution date required
  • Categories/boards for organization

Positioning

  • Each human stakes 0.1-1 WLD on Yes or No
  • Exactly 1 position per human per market (enforced by World ID)
  • Can change position before market closes (but not add more)
  • Position changes tracked for transparency

Resolution

  • Community resolution: verified humans vote on outcome after resolution date
  • Oracle resolution: designated resolver (for factual outcomes)
  • Dispute mechanism: if resolution is contested, escalate to broader community vote

Leaderboard

  • Track record scores: accuracy percentage over time
  • "Superforecaster" badge for top predictors
  • Historical performance visible on profile

Revenue

  • 5% fee on winning payouts
  • Data licensing: prediction accuracy data for research
  • Premium markets: sponsored markets by brands/media

Technical Requirements (TRD)

New Schema

CREATE TABLE prediction_markets (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  creatorHash TEXT NOT NULL REFERENCES human_users(nullifier_hash),
  title TEXT NOT NULL,
  description TEXT,
  boardId TEXT,
  resolutionDate TIMESTAMP NOT NULL,
  resolvedAt TIMESTAMP,
  outcome TEXT, -- 'yes', 'no', 'void'
  resolverType TEXT DEFAULT 'community', -- 'community', 'oracle'
  resolverHash TEXT, -- for oracle resolution
  yesCount INTEGER DEFAULT 0,
  noCount INTEGER DEFAULT 0,
  totalStaked NUMERIC DEFAULT 0,
  status TEXT DEFAULT 'open', -- 'open', 'closed', 'resolved', 'disputed'
  createdAt TIMESTAMP DEFAULT NOW()
);

CREATE TABLE market_positions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  marketId UUID REFERENCES prediction_markets(id),
  nullifierHash TEXT NOT NULL,
  position TEXT NOT NULL, -- 'yes' or 'no'
  stakeWld NUMERIC NOT NULL,
  txId TEXT, -- WLD payment transaction
  createdAt TIMESTAMP DEFAULT NOW(),
  UNIQUE(marketId, nullifierHash) -- 1 human = 1 position
);

CREATE TABLE market_resolutions (
  marketId UUID REFERENCES prediction_markets(id),
  nullifierHash TEXT NOT NULL,
  vote TEXT NOT NULL, -- 'yes', 'no', 'void'
  createdAt TIMESTAMP DEFAULT NOW(),
  UNIQUE(marketId, nullifierHash)
);

Key Endpoints

  • POST /api/markets - create market
  • GET /api/markets - list markets (with filters)
  • POST /api/markets/{id}/position - take position (WLD payment)
  • POST /api/markets/{id}/resolve - vote on resolution
  • GET /api/markets/{id} - market detail + positions

Payout Logic

  • Total pool = sum of all stakes
  • Winners split pool proportionally (minus 5% fee)
  • If market voided, all stakes returned
  • Payouts via WLD on World Chain

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions