Developing Prediction Smart Contract (Polymarket Style)
Polymarket is a prediction market with $500M+ trading volume monthly at its 2024 peak. Under the hood — binary outcome contract built on AMM/CLOB hybrid with Chainlink oracle for resolution. This isn't a "simple betting contract" — it's a full-fledged financial protocol with non-trivial mathematics and several attack vectors that must be closed before deployment.
How Blockchain Prediction Markets Work
Each market is a pair of conditional tokens: YES and NO. User deposits 1 USDC and receives 1 YES + 1 NO token (via Gnosis Conditional Tokens Framework). Then they sell the undesired outcome on AMM or CLOB. After resolution, the winning token exchanges for 1 USDC, the losing one for 0.
CTF (Conditional Tokens Framework) is ERC-1155 standard for conditional tokens. Each outcome is represented as a position with unique positionId. On resolution, CTF allows redeeming winning positions.
// Gnosis CTF interface
interface IConditionalTokens {
function prepareCondition(
address oracle,
bytes32 questionId,
uint outcomeSlotCount
) external;
function reportPayouts(
bytes32 questionId,
uint[] calldata payouts
) external;
function redeemPositions(
IERC20 collateralToken,
bytes32 parentCollectionId,
bytes32 conditionId,
uint[] calldata indexSets
) external;
}
AMM vs CLOB: Choosing Price Mechanism
Polymarket uses CLOB (Central Limit Order Book) — order book on MATIC with matching on Polymarket's side. Fast and CEX-like, but requires centralized matcher. For fully decentralized market — AMM.
LMSR (Logarithmic Market Scoring Rule) is the classic AMM for prediction markets. Price depends on current YES and NO token quantities:
price_yes = e^(q_yes/b) / (e^(q_yes/b) + e^(q_no/b))
where b is the liquidity parameter, q_yes, q_no are sold token quantities.
LMSR guarantees market maker (market creator) always accepts bets, and max loss is capped at b * ln(2). Mathematically elegant but expensive on gas due to fixed-point exponent calculations.
Constant Product AMM (Uniswap v2 style). Cheaper on gas, but less accurate prices at extreme probabilities (close to 0% or 100%). Good for balanced-liquidity markets.
We build on modified constant product with price range restrictions [0.02, 0.98] — to avoid infinite losses at extreme positions.
Oracle and Resolution: Where Main Complexity Hides
A prediction market without reliable oracle is a market with manual arbitration, always under question. Three approaches:
Chainlink Data Feeds. For financial data markets (ETH price above $5000 by Dec 31?). Deterministic, decentralized, but covers only financial assets.
UMA Optimistic Oracle. For subjective questions (Biden wins the election?). Answer proposal + dispute period + dispute via UMA token holders. 2-48 hour delay, but works for any question.
Custom multisig oracle. Set of respected parties (5/9 multisig) votes on outcome. Centralized but transparent and fast. For closed or niche markets.
contract PredictionMarket {
struct Market {
bytes32 conditionId;
address oracle;
uint256 endTime;
uint256 resolutionTime;
MarketStatus status;
uint128 yesReserve;
uint128 noReserve;
uint256 totalVolume;
}
enum MarketStatus { Open, Closed, Resolved, Disputed }
mapping(bytes32 => Market) public markets;
// AMM pricing
function getPrice(bytes32 marketId, bool isYes) public view returns (uint256) {
Market storage m = markets[marketId];
uint256 yesR = m.yesReserve;
uint256 noR = m.noReserve;
// constant product: price_yes = noR / (yesR + noR) in fixed point
return (noR * 1e18) / (yesR + noR);
}
}
Attack Vectors to Close
Oracle manipulation. If market resolves by on-chain price at specific moment — flash loan attack possible: borrow funds, manipulate price via DEX, get winning outcome. Protection: TWAP (time-weighted average price) over 24-48 hours instead of spot. Or require multiple independent oracle sources.
Front-running resolution. Someone knows the outcome before official resolution (e.g., Biden lost but oracle hasn't updated) and buys NO tokens at 0.8 before price updates to 1.0. Partial solution — close trading X hours before resolution.
Griefing via spam dispute. In optimistic oracle systems an attacker can dispute every resolution, blocking payouts. Protection: bond requirement for disputes (collateral lost if dispute fails).
Reentrancy on redeem. CTF.redeemPositions transfers tokens before updating state. Standard pattern — Check-Effects-Interactions + ReentrancyGuard on all withdrawal functions.
Wrong conditionId. CTF uses keccak256(oracle, questionId, outcomeSlotCount) as conditionId. If oracle address or questionId differs from expected — users can't redeem winnings. Verify conditionId twice before market deployment.
Governance and Market Creation
Who can create markets? Options:
- Permissioned. Only whitelisted operators. Centralized but protects from junk markets.
- Permissionless with bond. Anyone paying a bond. Returned on correct resolution, burned on manipulation.
- DAO governance. Vote on each market. Slow but maximally decentralized.
For MVP — permissioned with DAO roadmap.
Development Stack
- Foundry — primary tool. Fuzz tests especially important for AMM math: random inputs find numerical errors in fixed-point arithmetic.
- Gnosis CTF — use ready implementation, don't write conditional tokens from scratch.
- Chainlink — oracle for financial markets.
- OpenZeppelin — AccessControl, ReentrancyGuard, Pausable.
- Slither + Echidna — static analysis and property-based testing.
Development Process
Design (3-5 days). Choose AMM/CLOB mechanism, oracle strategy, governance model. Whitepaper with AMM math and no-arbitrage proof.
Contract development (7-10 days). Market factory, AMM logic, oracle integration, CTF integration. Each module separately with unit tests.
Audit and fuzzing (3-5 days). Foundry fuzzer on AMM functions, Echidna for invariant testing (sum of YES+NO reserve constant, price always in [0,1]). Slither on entire codebase.
Frontend and The Graph (5-7 days). Subgraph for market event indexing, TypeScript SDK, React interface with price charts.
Testnet testing (3-5 days). Simulate full cycle: market creation → trading → resolution → redeem.
Total timeline — 1-2 weeks for basic protocol without frontend. Full platform with interface — 4-6 weeks.
Regulatory Context
Prediction markets are in a gray zone in most jurisdictions. US CFTC considers some prediction markets unregistered swap platforms. Perion Markets got Wells Notice from SEC in 2024. Recommend legal consultation before launch, especially for US users.
Technically — geoblocking via frontend and terms of service. Smart contract address restrictions are impractical: easy to bypass through another contract.







