A decentralized prediction market platform built on Stacks blockchain using Clarity, enabling users to create and participate in harvest outcome predictions.
This smart contract allows users to create prediction markets for agricultural harvest outcomes and place bets using STX tokens. Markets can predict yield levels (high, medium, low) or crop failure, with winners receiving proportional rewards from the total pool.
- Market Creation: Create time-bound prediction markets with custom descriptions
- Four Outcome Types: High yield, Medium yield, Low yield, Crop failure
- Proportional Rewards: Winners share the total pool based on their contribution
- Platform Fees: Configurable 2% fee on total pools
- Market Lifecycle: Open → Closed → Resolved states with validation
- Duplicate Prevention: Users can only predict once per market
- Input Validation: All user inputs are validated to prevent errors
(create-market (description (string-ascii 256)) (duration-blocks uint))
Creates a new prediction market. Duration must be between 144 blocks (~1 day) and 52,560 blocks (~1 year).
Returns: Market ID (uint)
(place-prediction (market-id uint) (outcome uint) (amount uint))
Place a prediction on a market outcome (1-4). Minimum bet: 1,000,000 micro-STX (1 STX).
Outcomes:
- 1: High yield
- 2: Medium yield
- 3: Low yield
- 4: Crop failure
(close-market (market-id uint))
Closes a market after end-block is reached. Only callable by contract owner.
(resolve-market (market-id uint) (winning-outcome uint))
Resolves a closed market with the winning outcome. Only callable by contract owner.
(claim-reward (market-id uint))
Winners claim their proportional share of the total pool minus platform fee.
Reward Formula: (user-amount * total-pool * 98) / (winning-pool * 100)
(get-market (market-id uint))
Returns complete market details including all pool amounts and state.
(get-prediction (market-id uint) (predictor principal))
Returns a user's prediction details for a specific market.
(calculate-potential-reward (market-id uint) (predictor principal))
Calculates potential reward if the user's prediction wins.
(get-platform-fee-rate)
Returns current platform fee rate (default: 200 = 2%).
{
creator: principal,
description: (string-ascii 256),
end-block: uint,
total-pool: uint,
outcome-1-pool: uint,
outcome-2-pool: uint,
outcome-3-pool: uint,
outcome-4-pool: uint,
is-resolved: bool,
winning-outcome: (optional uint),
state: uint ;; 1=open, 2=closed, 3=resolved
}
{
outcome: uint,
amount: uint,
claimed: bool
}
| Code | Constant | Description |
|---|---|---|
| 100 | ERR-NOT-AUTHORIZED | Caller not authorized |
| 101 | ERR-MARKET-NOT-FOUND | Market doesn't exist |
| 102 | ERR-MARKET-CLOSED | Market already closed |
| 103 | ERR-MARKET-NOT-CLOSED | Market still open |
| 104 | ERR-INVALID-OUTCOME | Invalid outcome (must be 1-4) |
| 105 | ERR-ALREADY-PREDICTED | User already predicted |
| 106 | ERR-INSUFFICIENT-AMOUNT | Amount below minimum |
| 107 | ERR-MARKET-NOT-RESOLVED | Market not resolved yet |
| 108 | ERR-REWARD-CLAIMED | Reward already claimed |
| 109 | ERR-NOT-WINNER | User didn't predict winning outcome |
| 110 | ERR-INVALID-DURATION | Duration outside valid range |
| 111 | ERR-INVALID-DESCRIPTION | Description too short |
;; 1. Create a market (as contract owner)
(contract-call? .harvest-prediction-market create-market
"Will corn yield exceed 180 bushels/acre in Iowa 2024?"
u10000) ;; ~70 days
;; 2. Place predictions (as users)
(contract-call? .harvest-prediction-market place-prediction
u1 ;; market-id
u1 ;; outcome: high yield
u5000000) ;; 5 STX
;; 3. Close market after end-block (as owner)
(contract-call? .harvest-prediction-market close-market u1)
;; 4. Resolve with winning outcome (as owner)
(contract-call? .harvest-prediction-market resolve-market u1 u1)
;; 5. Winners claim rewards
(contract-call? .harvest-prediction-market claim-reward u1)
- Install Clarinet:
npm install -g @hirosystems/clarinet - Create new project:
clarinet new harvest-market - Add contract to
contracts/directory - Test:
clarinet test - Deploy:
clarinet deploy --testnetor--mainnet
- Owner Privileges: Market resolution requires trusted owner/oracle
- No Refunds: Predictions are final once placed
- Block Timing: Market duration based on block height, not timestamps
- Fee Collection: Platform fees accumulate in contract balance
- Reentrancy Safe: Uses Clarity's built-in transfer functions
- Create market with valid/invalid durations
- Place predictions on all outcomes
- Attempt duplicate predictions
- Close market before/after end-block
- Resolve with each outcome type
- Claim rewards as winner/loser
- Verify fee calculations
- Test edge cases (zero pool, single predictor)