"트럼프가 대선에서 이길 확률은?" — 이 질문에 돈을 거는 시장이 어떻게 블록체인 위에서 동작하는가. Conditional Tokens, CLOB, UMA Oracle까지 컨트랙트 수준으로 해부한다.

예측 시장(Prediction Market)은 미래 사건의 결과에 돈을 베팅하는 금융 시장이다. 핵심 아이디어는 "집단 지성(Wisdom of Crowds)": 시장 참여자들이 자신의 정보와 믿음을 가격에 반영하면, 그 가격이 실제 확률의 최선 추정치가 된다는 것이다.
Polymarket의 모든 마켓은 Gnosis가 설계한 Conditional Tokens Framework 위에서 동작한다. CTF는 ERC-1155 기반이며, 담보 토큰(USDC)을 조건부 결과 토큰으로 분할하고 결과 확정 후 승리 토큰을 담보로 교환하는 구조다.
// 1 USDC → 1 YES token + 1 NO token CTF.splitPosition( collateralToken: USDC, parentCollectionId: bytes32(0), conditionId: conditionId, partition: [0b01, 0b10], // YES=index0, NO=index1 amount: 1_000_000 // 1 USDC (6 decimals) ) // 결과: YES positionId로 1e6 토큰, NO positionId로 1e6 토큰 발행
1 USDC를 분할하면 항상 YES 1개 + NO 1개. 두 토큰의 합은 항상 1 USDC.
// CTFExchange CLOB에서 주문 제출 (EIP-712 서명)
Order {
maker: 0xUser,
tokenId: YES_positionId,
makerAmount: 620_000, // 0.62 USDC (지불)
takerAmount: 1_000_000, // 1 YES token (수취)
side: BUY,
expiration: timestamp,
nonce: nonce,
signature: eip712sig
}
// YES @ $0.62 = "시장이 62% 확률로 판단"YES 토큰 가격이 0.62 USDC면 시장 참여자들이 집합적으로 62% 확률로 평가한다는 의미.
// 오라클이 YES 승리로 결과 보고 후 CTF.redeemPositions( collateralToken: USDC, parentCollectionId: bytes32(0), conditionId: conditionId, indexSets: [0b01] // YES position ) // 1 YES token → 1 USDC (payout = 1) // 1 NO token → 0 USDC (payout = 0)
결과 발표 후 승리 토큰 1개 = USDC 1개. 패배 토큰은 가치 없음. 자동 정산, 중개자 없음.
Polymarket는 AMM이 아니라 CLOB(Central Limit Order Book)을 사용한다. 주문 매칭은 Polymarket 서버에서 오프체인으로 처리하지만, 실제 토큰 이동은 CTFExchange 컨트랙트를 통해 온체인에서 발생한다. 이 구조로 AMM의 슬리피지 없이 CEX 수준의 UX를 구현한다.
function matchOrders(
Order calldata takerOrder,
Order[] calldata makerOrders,
uint256 takerFillAmount,
uint256[] calldata makerFillAmounts
) external onlyOperator {
// 1. 서명 검증 (EIP-712)
_validateOrder(takerOrder);
for (Order o in makerOrders) _validateOrder(o);
// 2. 가격 조건 검증 (taker price >= maker price)
_validateMatch(takerOrder, makerOrders[i]);
// 3. CTF를 통한 실제 토큰 이전
CTF.safeTransferFrom(maker, taker, tokenId, fillAmount, "");
CTF.safeTransferFrom(taker, maker, oppositeTokenId, fillAmount, "");
emit OrderFilled(orderHash, maker, taker, ...);
}마켓 결과를 누가, 어떻게 판정하는가? Polymarket는 UMA의 Optimistic Oracle v2를 사용한다. "낙관적(Optimistic)" 이란, 제안된 답이 이의 없이 유효하면 그대로 확정하고, 이의 제기 시에만 분쟁 해결 메커니즘을 작동시킨다는 의미다.
누구나 결과를 제안할 수 있다. 제안 시 UMA 토큰(bond)을 스테이킹. 틀리면 몰수.
제안된 결과에 이의 없으면 자동 확정. 이의 제기자도 bond를 스테이킹해야 함.
Proposer의 bond 반환 + 수수료 수취. CTF.reportPayouts() 호출 → 결과 기록.
UMA의 Data Verification Mechanism 작동. UMA 토큰 홀더가 2일간 투표. 다수결 확정 → 패자 bond 승자에게 전달.
// 1. Proposer가 결과 제안
OptimisticOracleV2.proposePrice(
requester: CTF_address,
identifier: bytes32("YES_OR_NO_QUERY"),
timestamp: market_expiry,
ancillaryData: "q: 트럼프 당선? res data: p1:0, p2:1",
proposedPrice: 1e18 // YES = 1
)
// 2. 챌린지 기간 후 결과 확정
OptimisticOracleV2.settle(requester, identifier, timestamp, ancData)
// 3. CTF에 결과 기록 (reportPayouts 호출)
ConditionalTokens.reportPayouts(
questionId: questionId,
payouts: [1, 0] // YES wins, NO loses
)
// 이후 YES 토큰 보유자 → redeemPositions() 가능| 항목 | Polymarket | Augur v2 | Kalshi | Manifold |
|---|---|---|---|---|
| 체인 | Polygon | Ethereum | 없음 (중앙화) | 없음 |
| 담보 | USDC | DAI / ETH | USD | 플레이머니 |
| 주문 방식 | CLOB (Off-chain) | AMM (Augur Turbo) | CLOB | AMM |
| 오라클 | UMA OO v2 | REP 홀더 투표 | 내부 + 데이터 파트너 | 관리자 |
| 분쟁 해결 | UMA DVM | Augur REP 포크 | 내부 | N/A |
| 탈중앙화 | 부분 (오더북 중앙화) | 높음 | 낮음 | 낮음 |
| 규제 | 비규제 (미국인 제한) | 비규제 | CFTC 규제 | 비규제 |
| 거래량 | $10B+ (2024) | ~$50M | ~$1B | 소액 |
Polymarket는 공개 REST API와 Python/JS SDK를 제공한다. 마켓 조회, 주문 제출, 포지션 관리를 코드로 할 수 있다.
// 활성 마켓 목록
GET https://clob.polymarket.com/markets
?active=true&closed=false
// 특정 마켓 오더북
GET https://clob.polymarket.com/book
?token_id=<YES_positionId>
// 응답 예시
{
"market": "0xabc...",
"question": "트럼프 당선?",
"conditionId": "0x123...",
"tokens": [
{ "token_id": "...", "outcome": "Yes", "price": 0.62 },
{ "token_id": "...", "outcome": "No", "price": 0.38 }
],
"volume": "3300000000"
}from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType
client = ClobClient(
host="https://clob.polymarket.com",
key=PRIVATE_KEY,
chain_id=137 # Polygon
)
# GTC 지정가 매수: YES 토큰 @0.62
order = client.create_order(
OrderArgs(
token_id=YES_TOKEN_ID,
price=0.62,
size=100, # 100 shares
side="BUY",
order_type=OrderType.GTC
)
)
resp = client.post_order(order)
print(resp["orderID"]) # 오더북에 등록됨const CTF_ADDRESS = "0x4D97DCd97eC945f40cF65F87097ACe5EA0476045";
const ctf = new ethers.Contract(CTF_ADDRESS, CTF_ABI, signer);
// 1. USDC approve
await usdc.approve(CTF_ADDRESS, parseUnits("10", 6));
// 2. USDC → YES + NO 분할
await ctf.splitPosition(
USDC_ADDRESS,
ethers.ZeroHash, // parentCollectionId
conditionId,
[1, 2], // partition (indexSets)
parseUnits("10", 6) // 10 USDC
);
// 3. 결과 확정 후 YES 토큰 → USDC 환매
await ctf.redeemPositions(
USDC_ADDRESS,
ethers.ZeroHash,
conditionId,
[1] // YES indexSet
);UMA DVM도 대규모 자본으로 REP/UMA 토큰 다수를 확보하면 결과를 조작할 수 있다. 현실적으로 비용이 크지만 이론적 위험은 존재.
Polymarket 서버가 특정 주문을 거부하거나 사용자를 차단할 수 있다. 미국 사용자가 VPN 없이 접근 제한된 이유가 이것.
"트럼프가 이길 것인가"처럼 명확한 질문은 쉽지만, 모호한 조건의 질문은 오라클 분쟁이 많다. 언어적 모호성이 기술적 취약점이 된다.
대형 마켓(대선, 월드컵)에는 유동성이 몰리지만, 틈새 마켓은 스프레드가 넓고 유동성이 얕다. LP 인센티브 구조 개선이 과제.
Polymarket에서 포지션을 대기하는 USDC도 walits Idle Time Detector가 자동으로 수익화한다.
walits 시작하기 →