A decentralized prediction market smart contract built on Stacks blockchain using Clarity. Users can create binary outcome markets, place bets, and claim winnings based on resolved outcomes.
- Market Creation: Create prediction markets with custom questions and timeframes
- Binary Betting: Place bets on YES or NO outcomes
- Automated Resolution: Authorized resolvers determine winning outcomes
- Proportional Payouts: Winners receive proportional share of the total pool
- Dynamic Odds: Real-time probability calculation based on bet distribution
- Authorization checks for market creators and resolvers
- Time-based market controls (end-time, resolution-time)
- Double-claim prevention
- Platform fee mechanism (2% default, max 10%)
- Emergency withdrawal for contract owner
Markets Map
{
creator: principal,
question: string-ascii,
end-time: uint,
resolution-time: uint,
total-yes: uint,
total-no: uint,
status: uint,
winning-outcome: optional bool,
resolver: principal
}User Positions Map
{
yes-amount: uint,
no-amount: uint,
claimed: bool
}- Open (1): Accepting bets
- Closed (2): No longer accepting bets
- Resolved (3): Outcome determined, winnings claimable
(create-market
"Will Bitcoin reach $100k by end of 2025?"
u1000000 ;; end-time block height
u1100000) ;; resolution-time block heightRequirements:
- End-time must be in the future
- Resolution-time must be after end-time
(place-bet u0 true u1000000) ;; market-id, outcome (true=YES), amount in microSTXRequirements:
- Market must be open
- Current block must be before end-time
- Amount must be greater than 0
- User must have sufficient STX balance
(close-market u0) ;; market-idAuthorization: Market creator or contract owner only
(resolve-market u0 true) ;; market-id, winning-outcomeRequirements:
- Must be called by the designated resolver
- Current block must be at or after resolution-time
- Market must not already be resolved
(claim-winnings u0) ;; market-idPayout Formula:
payout = (user_bet / winning_pool) × total_pool
net_payout = payout - (payout × platform_fee%)
Requirements:
- Market must be resolved
- User must have winning position
- Cannot claim twice
(get-market u0) ;; Returns market details(get-user-position u0 tx-sender) ;; market-id, user(calculate-payout u0 tx-sender) ;; Before claiming(get-odds u0) ;; Returns {yes-odds: uint, no-odds: uint}| Code | Error | Description |
|---|---|---|
| u100 | err-owner-only | Action restricted to contract owner |
| u101 | err-not-found | Market or position not found |
| u102 | err-already-exists | Resource already exists |
| u103 | err-market-closed | Market is closed for betting |
| u104 | err-market-resolved | Market already resolved |
| u105 | err-invalid-outcome | Invalid outcome specified |
| u106 | err-insufficient-balance | Insufficient STX balance |
| u107 | err-already-claimed | Winnings already claimed |
| u108 | err-not-resolved | Market not yet resolved |
| u109 | err-unauthorized | User not authorized |
| u110 | err-invalid-amount | Invalid amount specified |
(set-platform-fee u3) ;; Set to 3% (max 10%)Authorization: Contract owner only
(emergency-withdraw u0) ;; market-idAuthorization: Contract owner only
Purpose: Safety mechanism for critical situations
;; 1. Alice creates a market
(create-market "Will it rain tomorrow?" u1050000 u1060000)
;; Returns: (ok u0)
;; 2. Bob bets 100 STX on YES
(place-bet u0 true u100000000)
;; 3. Charlie bets 200 STX on NO
(place-bet u0 false u200000000)
;; 4. Check current odds
(get-odds u0)
;; Returns: {yes-odds: u33, no-odds: u66}
;; 5. After resolution time, Alice resolves
(resolve-market u0 true) ;; YES wins
;; 6. Bob claims his winnings
(claim-winnings u0)
;; Bob receives: (100/100) × 300 = 300 STX - 2% fee = 294 STX
;; 7. Charlie gets nothing (bet on losing outcome)- Time Manipulation: Markets use block heights to prevent time-based attacks
- Front-running: Consider using commit-reveal scheme for high-value markets
- Oracle Risk: Resolution depends on trusted resolver (consider decentralized oracle)
- Liquidity: No guaranteed liquidity; payouts depend on opposing bets
- Deploy contract to Stacks blockchain
- Contract owner is set to deployer's address
- Platform fee defaults to 2%
- Market nonce starts at 0
- ✅ Market creation with various parameters
- ✅ Betting on both outcomes
- ✅ Time-based restrictions (end-time, resolution-time)
- ✅ Authorization checks
- ✅ Payout calculations
- ✅ Double-claim prevention
- ✅ Edge cases (zero bets, one-sided markets)