← Workspace Index

Prediction Market Models Explained

CTF Multi-Outcome vs NegRisk Adapter - A Complete Guide

Market Model Comparison (시장 모델 비교)

구분 그룹형 바이너리
Grouped Binary (Nostra 현재)
CTF 다중 결과
CTF Multi-Outcome
그룹형 바이너리 + NegRisk
Polymarket
초기 확률
Initial Probability
자유 설정
(50% 또는 100/N% 등)
자유 설정
(100/N% 또는 외부 데이터)
자유 설정
(시장 결정)
YES 총합
Sum of YES prices
자유 (연동 없음)
(차익거래 가능)
항상 100%
(기계적 보장)
~100%
(경제적 수렴)
시장 연동
Market Linkage
독립적
(연동 없음)
기계적 연동
(분할/병합)
어댑터 연동
(NegRisk)
재고 문제
Stuck Inventory
발생함
(전환 불가)
발생하지 않음
(병합 가능)
발생하지 않음
(전환 가능)
구현 난이도
Implementation
간단함 복잡함
(커스텀 거래소 필요)
복잡함
(6-10주)
conditionId
Condition ID
각 outcome별 다름 모두 동일 (공유) 각 outcome별 다름
+ negRiskMarketId 공유
포지션 전환
Position Conversion
불가능 가능 (merge) 가능 (adapter)

Key Takeaway

Nostra 현재: 그룹형 바이너리 (Grouped Binary) - 간단하지만 포지션 전환 불가

Polymarket: 그룹형 바이너리 + NegRisk - 포지션 전환 가능

핵심 차이: 시장 연동 메커니즘 (없음 vs 분할/병합 vs NegRisk 어댑터)

PART A: CTF Multi-Outcome Model Pure Multi-Outcome using Conditional Tokens Framework

A1. What is CTF Multi-Outcome? (CTF 다중 결과란?)

The CTF Multi-Outcome model is the "pure" way to handle multiple mutually exclusive outcomes using the Conditional Tokens Framework. Unlike Grouped Binary where each outcome is a separate market, CTF Multi-Outcome uses a single condition with multiple outcome slots.

작동 방식 (How It Works)

🟢 CTF 다중 결과 모델 단일 컨디션, 다중 결과
하나의 conditionId (모든 결과가 공유)
🇪🇸 스페인
슬롯 0
🇫🇷 프랑스
슬롯 1
🇧🇷 브라질
슬롯 2
🇦🇷 아르헨티나
슬롯 3
🏴󠁧󠁢󠁥󠁮󠁧󠁿 잉글랜드
슬롯 4
prepareCondition(oracle, questionId, outcomeSlotCount=5)
⚡ vs ⚡
🟠 그룹형 바이너리 모델 결과별 개별 컨디션
condId_1
🇪🇸 스페인
YES NO
condId_2
🇫🇷 프랑스
YES NO
condId_3
🇧🇷 브라질
YES NO
condId_4
🇦🇷 아르헨티나
YES NO
condId_5
🏴󠁧󠁢󠁥󠁮󠁧󠁿 잉글랜드
YES NO
각 결과마다 prepareCondition(oracle, questionId_N, 2) 호출
구분 🟢 CTF 다중 결과 🟠 그룹형 바이너리
conditionId 1개 (공유) N개 (결과별 개별)
토큰 구조 결과당 1개 토큰
(스페인, 프랑스, 브라질...)
결과당 YES/NO 쌍
(스페인 YES/NO, 프랑스 YES/NO...)
분할/병합 네이티브 CTF 기능 불가능
가격 총합 항상 = 100% N × 50% = 250% (5팀)

A1.1 Split and Merge Operations

CTF Multi-Outcome enables mechanical split/merge operations that are impossible in Grouped Binary:

Split: USDC → All Outcome Tokens

$1 USDC
1 Spain 1 France 1 Brazil 1 Argentina 1 England

Exactly ONE will be worth $1, others worth $0

Merge: All Outcome Tokens → USDC

1 Spain 1 France 1 Brazil 1 Argentina 1 England
$1 USDC

Guaranteed $1 regardless of outcome

A1.2 Position Conversion via Merge

Example: Convert Spain to France

You have: 100 Spain tokens @ 20¢ = $20 value

You want: France tokens

// Step 1: Buy all OTHER tokens to complete a set Buy: 100 France @ 15¢ = $15 Buy: 100 Brazil @ 25¢ = $25 Buy: 100 Argentina @ 30¢ = $30 Buy: 100 England @ 10¢ = $10 Total spent: $80 // Step 2: Merge complete sets 100 Spain + 100 France + 100 Brazil + 100 Argentina + 100 England = 100 complete sets = $100 USDC // Step 3: Use $100 to buy France tokens $100 / 15¢ = ~666 France tokens // Net result: Started: 100 Spain tokens (worth $20) Spent: $80 on other tokens Got back: $100 from merge Bought: 666 France tokens (worth $100) Profit from arbitrage: $0 (prices were fair)

A1.3 Why Sum Always = 100%

Mathematical Guarantee

In CTF Multi-Outcome, the split/merge mechanism creates a mechanical arbitrage that forces prices to sum to 100%:

  • If sum > 100%: Arbitrageurs split $1 → sell all tokens → profit from excess
  • If sum < 100%: Arbitrageurs buy all tokens cheap → merge → profit from $1

This is why CTF Multi-Outcome markets always sum to ~100%, unlike Grouped Binary which can have any sum.

A2. Polymarket이 순수 CTF Multi-Outcome을 사용하지 않는 이유

Polymarket chose Grouped Binary + NegRisk instead of pure CTF Multi-Outcome for several reasons:

  • Flexibility: Can add/remove outcomes after market creation
  • Familiar UX: YES/NO trading is more intuitive for users
  • Existing Infrastructure: Binary market exchange was already built
  • Liquidity: Easier to provide liquidity on YES/NO pairs
  • Modularity: NegRisk adapter can be upgraded separately

Trade-off: More complex architecture, but more operational flexibility

A3. Nostra의 createMultipleChoiceMarket()

Nostra's MarketFactory actually has a createMultipleChoiceMarket() function that creates pure CTF Multi-Outcome markets:

// In MarketFactory.sol function createMultipleChoiceMarket( bytes32 questionId, string[] calldata outcomeLabels, // ["Spain", "France", "Brazil", ...] ... ) { // Creates ONE condition with multiple outcomes ctf.prepareCondition(oracle, questionId, outcomeLabels.length); // All outcomes share the SAME conditionId bytes32 conditionId = getConditionId(oracle, questionId, outcomeLabels.length); } // vs createBinaryMarket() used currently: function createBinaryMarket(...) { ctf.prepareCondition(oracle, questionId, 2); // Always 2 outcomes }

Current Status: Nostra has the capability but uses createBinaryMarket() in a loop instead, creating Grouped Binary markets.

PART B: NegRisk Adapter (Polymarket's Approach) Linking Grouped Binary Markets with Position Conversion

B1. The Problem: Stuck Inventory

In Grouped Binary markets (like Nostra's current implementation), each outcome is an independent binary market. This creates a problem:

Example: 2026 FIFA World Cup Winner

You believe Spain will win, so you buy:

Spain YES @ 17¢ ($100 worth = 588 tokens)

Problem: If you change your mind and want to bet on France instead, you must:

  1. Sell Spain YES on the order book (might have slippage)
  2. Use the USDC to buy France YES

No direct conversion possible!

The Core Issue

Model Can Convert Positions? Stuck Inventory?
Grouped Binary (Nostra now) No Yes - Major Issue
CTF Multi-Outcome Yes (via merge) No
Grouped Binary + NegRisk Yes (via adapter) No

B2. The Key Insight: NO Token Equivalence (NegRisk = Negative Risk)

Mathematical Equivalence

In a mutually exclusive market (only ONE team can win), all NO tokens have a special property:

If Spain wins → Spain NO = $0, but France NO = $1, Brazil NO = $1, etc.

If France wins → France NO = $0, but Spain NO = $1, Brazil NO = $1, etc.

마법의 공식 (The Magic Formula)

N개 팀이 있는 상호 배타적 시장에서:

🎯 NO 토큰 보유 시나리오
🇪🇸 스페인 NO + 🇫🇷 프랑스 NO + 🇧🇷 브라질 NO + ... (모든 N개 팀)
누가 이기든 상관없이:
우승팀 NO
= $0
다른 팀들 NO
= 각 $1
총 가치
= $(N-1)
N개의 NO 토큰 (각 팀당 1개) = $(N-1) 보장

Concrete Example: 5 Teams

Setup: World Cup with 5 teams (Spain, France, Brazil, Argentina, England)

You hold: 1 NO token for each team (5 total)

// If Spain wins: Spain NO = $0 France NO = $1 Brazil NO = $1 Argentina NO = $1 England NO = $1 Total = $4 // If France wins: Spain NO = $1 France NO = $0 Brazil NO = $1 Argentina NO = $1 England NO = $1 Total = $4 // No matter who wins: Total = $4 (always!)

Insight: 5 NO tokens = $4 guaranteed = $(N-1)

B3. NegRisk 전환: 작동 원리

NegRisk는 수학적 등가성을 활용하여 포지션 전환을 가능하게 합니다:

전환 공식 (Conversion Formula)

🔄 NO → YES 전환
보유 중:
🇪🇸 스페인 NO + 🇫🇷 프랑스 NO + 🇧🇷 브라질 NO + 🇦🇷 아르헨 NO
원하는 것:
🏴󠁧󠁢󠁥󠁮󠁧󠁿 잉글랜드 YES
✨ 전환 로직:
4개의 NO 토큰 (잉글랜드 제외) = $3 보장 가치
= 1 잉글랜드 YES + 잔여 가치
결과:
🔥 소각: 스페인, 프랑스, 브라질, 아르헨티나 NO
✅ 수령: 잉글랜드 YES + USDC

Step-by-Step Example

Scenario: Convert Spain YES to France YES

Current prices: Spain 20%, France 15%, Brazil 25%, Argentina 30%, England 10%

Step 1: You have 100 Spain YES tokens

Step 2: Sell Spain YES, Buy all other NO tokens

// Sell Spain YES @ 20¢ 100 Spain YES → $20 USDC // Buy NO tokens for other teams // NO price = 1 - YES price France NO @ 85¢: $20 → 23.5 tokens Brazil NO @ 75¢: ... Argentina NO @ 70¢: ... England NO @ 90¢: ...

Step 3: NegRisk Converts NO tokens to YES

// You hold NO for: France, Brazil, Argentina, England // You want: France YES NegRisk Magic: Brazil NO + Argentina NO + England NO = $3 equivalent = France YES + USDC // Result: You get: France YES tokens + leftover USDC (France NO was already yours, separate)

왜 이것이 작동하는가 (Why This Works)

❌ NegRisk 없이

스페인 YES → 오더북에서 판매 → USDC → 프랑스 YES 구매

문제: 양쪽 거래에서 슬리피지, 유동성에 의존

✅ NegRisk 사용 시

스페인 YES → 어댑터로 전환 → 프랑스 YES

장점: 수학적 전환, 전환 단계에서 슬리피지 없음

B4. NegRisk 아키텍처

👤 사용자 인터페이스 (User Interface)
"내 스페인 YES를 프랑스 YES로 전환해줘"
⬇️
🔄 NegRisk 어댑터 (NegRisk Adapter)
splitPosition()
mergePositions()
convertPosition()
핵심 기능: USDC ↔ NO 토큰 ↔ YES 토큰 변환
Wrapped Collateral (wUSDC) - 원자적 변환 지원
⬇️
📊 그룹형 바이너리 마켓 (Grouped Binary Markets)
condId_1
🇪🇸 스페인
YES NO
condId_2
🇫🇷 프랑스
YES NO
condId_3
🇧🇷 브라질
YES NO
condId_4
🇦🇷 아르헨
YES NO
모든 마켓이 negRiskMarketId로 연결됨
⬇️
🔗 Conditional Tokens Framework (CTF)
모든 토큰 작업의 기반 레이어 (Base layer for all token operations)

핵심 컨트랙트 (Key Contracts)

컨트랙트 목적 Nostra 보유?
NegRiskAdapter Main conversion logic (NO → YES) No
NegRiskOperator Admin functions, oracle integration No
WrappedCollateral Wrapped USDC for atomic operations No
NegRiskFeeModule Fee collection on conversions No
ConditionalTokens (CTF) Base token framework Yes
MarketFactory Create binary markets Yes
CTFExchange Order book trading Yes

B5. NegRisk 구현을 위해 필요한 것

  • 1
    WrappedCollateral.sol

    ERC20 wrapper around USDC for internal accounting

    Easy
  • 2
    NegRiskAdapter.sol

    Core conversion logic: splitPosition, mergePositions, convertPosition

    Hard
  • 3
    NegRiskOperator.sol

    Market group management, links binary markets together

    Medium
  • 4
    Database: negRiskMarketId field

    Link markets in the same group

    Easy
  • 5
    API: /api/negrisk/convert endpoint

    Handle conversion requests from frontend

    Medium
  • 6
    Frontend: Convert Position UI

    Button to convert between outcomes in the same group

    Medium

Estimated Effort

Component Time Complexity
Smart Contracts (1-3) 2-3 weeks High (security critical)
Backend API (4-5) 3-5 days Medium
Frontend UI (6) 3-5 days Medium
Testing & Audit 2-4 weeks Critical
Total 6-10 weeks

B6. Alternative: Just Use Arbitrage Bots

Before implementing NegRisk, consider if you really need it:

NegRisk Adapter

  • Mechanical position conversion
  • No slippage on conversion
  • Complex implementation
  • 6-10 weeks development
  • Requires security audit

Arbitrage Bots (Current)

  • Economic position balancing
  • Some slippage possible
  • Simple implementation
  • Already working
  • No additional audit needed

When to Implement NegRisk?

  • High volume: When conversion demand justifies the complexity
  • User complaints: When stuck inventory becomes a major issue
  • Competitive pressure: When users demand Polymarket-level features
  • Capital efficiency: When large traders need atomic conversions

Summary

Key Comparisons

Implementation Options

Appendix: What is Gamma API?

gamma-api.polymarket.com is Polymarket's public REST API for market data.

// Example: Get World Cup market data GET https://gamma-api.polymarket.com/events?slug=2026-fifa-world-cup-winner-595 // Response includes: { "markets": [ { "question": "Will Spain win the 2026 FIFA World Cup?", "conditionId": "0x7976b8db...", "negRiskMarketId": "0xb5c32a9a...", // Shared! "tokens": [ { "outcome": "Yes", "tokenId": "439437288..." }, { "outcome": "No", "tokenId": "112680630..." } ] }, ... ] }

Nostra equivalent: /api/markets, /api/market-groups

Nostra Design Document | Created: December 2024