LPsLux Proposals
Consensus Systems
LP-101

lp-0101-prediction-markets-framework

LP-0101: Prediction Markets Framework

FieldValue
LP0101
TitlePrediction Markets Framework
AuthorLux Core Team
StatusDraft
Created2025-12-31
CategoryDeFi Infrastructure

Abstract

This proposal introduces the Conditional Tokens Framework (CTF) to Lux, enabling prediction markets with UMA oracle resolution. The system allows creation of binary and multi-outcome markets where users can split collateral into outcome tokens, trade positions, and redeem winnings after resolution.

Motivation

Prediction markets provide:

  1. Price Discovery - Aggregate information about future events
  2. Hedging - Protect against uncertain outcomes
  3. Speculation - Trade on beliefs about future events
  4. Governance - Futarchy-style decision making

The CTF + UMA combination (used by Polymarket) is the most battle-tested prediction market infrastructure.

Specification

Core Contracts

ContractLocationPurpose
ConditionalTokenscontracts/prediction/ctf/ERC-1155 outcome tokens
CTHelperscontracts/prediction/ctf/ID generation helpers
UmaCtfAdaptercontracts/prediction/adapters/UMA oracle bridge
NegRiskAdaptercontracts/prediction/adapters/Multi-outcome markets

Market Lifecycle

┌─────────────────────────────────────────────────────────────────────────┐
│                     PREDICTION MARKET LIFECYCLE                          │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                          │
│  1. CREATION                                                             │
│     Admin calls adapter.initialize(ancillaryData, reward, bond, liveness)│
│     → Creates questionID                                                 │
│     → Prepares CTF condition (2 outcomes: YES/NO)                       │
│     → Requests price from UMA OO                                         │
│                                                                          │
│  2. TRADING                                                              │
│     Users call ctf.splitPosition(collateral, amount)                    │
│     → Receives 1 YES + 1 NO token per collateral unit                   │
│     → Trade on DEX or via CLOB                                          │
│     Users call ctf.mergePositions()                                      │
│     → Return YES + NO tokens → receive collateral                        │
│                                                                          │
│  3. RESOLUTION                                                           │
│     UMA proposer submits outcome (0=NO, 0.5=UNKNOWN, 1=YES)             │
│     → If undisputed after liveness: settles                             │
│     → If disputed: escalates to DVM voting                              │
│     Admin calls adapter.resolve(questionID)                              │
│     → Fetches price from OO                                              │
│     → Calls ctf.reportPayouts()                                          │
│                                                                          │
│  4. REDEMPTION                                                           │
│     Winners call ctf.redeemPositions()                                   │
│     → Burn winning tokens → receive collateral                           │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────┘

Conditional Tokens (ERC-1155)

Position tokens are ERC-1155 with deterministic IDs:

// Condition ID
conditionId = keccak256(oracle, questionId, outcomeSlotCount)

// Collection ID (uses BN254 curve math)
collectionId = ecAdd(point(keccak256(conditionId, indexSet)), parentCollectionId)

// Position ID (ERC-1155 token ID)
positionId = keccak256(collateralToken, collectionId)

Configurable Bond Amounts

Per user requirement, bonds are configurable per market:

struct BondConfig {
    uint256 minBond;
    uint256 maxBond;
    bool customBondEnabled;
}

// Global default
mapping(bytes32 => BondConfig) public marketBondConfigs;

// Market creators can set custom bonds
function setMarketBondConfig(bytes32 questionID, uint256 minBond, uint256 maxBond) external;

Multi-Outcome Markets (NegRiskAdapter)

For markets with >2 outcomes (elections, sports):

Market: "Who will win the 2024 election?"
├── Question 1: "Will Candidate A win?"YES/NO tokens
├── Question 2: "Will Candidate B win?"YES/NO tokens
└── Question 3: "Will Candidate C win?"YES/NO tokens

Invariant: Only ONE question can resolve to YES
Conversion: 1 NO(A) + 1 NO(B) ≡ 1 USDC + 1 YES(C)

Parameters

ParameterValueNotes
Outcome Slots2-256Binary markets use 2
Default Liveness7200s2 hours
Bond CurrencyLUSDStablecoin
Min Bond100 LUSDConfigurable
Max Bond100,000 LUSDConfigurable

Security Considerations

  1. Conditional Token Audit: Based on Gnosis CTF (audited)
  2. Position ID Collision: CTHelpers uses elliptic curve math to prevent
  3. Oracle Trust: Only designated adapter can report payouts
  4. Reentrancy: Split/merge use checks-effects-interactions pattern

Cross-Chain Support

Markets can be created on Zoo/Hanzo chains via Warp messaging (see LP-0103):

C-Chain (Hub)              Zoo Chain (Spoke)
┌─────────────┐            ┌─────────────┐
│ WarpMarket  │◄──Warp────►│ WarpMarket  │
│ Hub         │  Messaging │ Spoke       │
└─────────────┘            └─────────────┘

Implementation

Contracts in ~/work/lux/standard/contracts/prediction/:

  • ctf/ConditionalTokens.sol - ERC-1155 outcome tokens
  • ctf/CTHelpers.sol - Helper library
  • adapters/UmaCtfAdapter.sol - UMA bridge
  • libraries/AncillaryDataLib.sol - Data encoding
  • libraries/PayoutHelperLib.sol - Payout validation

References