Every prediction market smart contract has the same fundamental problem: the blockchain cannot see the outside world. Your contract knows the current block number, the balances in its liquidity pool, and the history of trades placed against it. It does not know whether Bitcoin closed above $100,000 on December 31st, who won the election, or what the Fed funds rate is. Chainlink is the dominant oracle network for prediction market deployments in 2026, securing over $28 trillion in transaction value and powering Polymarket’s 5-minute and 15-minute crypto markets which have surpassed $3.4 billion in trading volume. This guide covers how to integrate Chainlink into your prediction market script correctly — stale data detection, oracle manipulation prevention, permissionless settlement triggering, and chain-portable oracle wrapper architecture.
Which Chainlink Product for Which Market Type
| Market Type | Duration | Chainlink Product | Settlement Pattern | Notes |
|---|---|---|---|---|
| Crypto price markets (BTC, ETH) | Any | Data Streams | Pull-based, CRE-automated | Best for precise timestamp |
| Daily/weekly price threshold | >4 hours | Data Feeds | Heartbeat + deviation | Free to consume |
| Sub-4-hour / 5-minute markets | <4 hours | Data Streams | Pull on-demand | Sub-second latency |
| Custom API markets (sports, weather) | Any | Functions | Keeper-triggered | ~0.1–0.2 LINK/call |
| Subjective / event markets | Any | UMA Optimistic Oracle | Dispute window | 12–24hr challenge period |
Step 1: Choose the Right Chainlink Product for Your Market Type
Before writing a single line of integration code, the market type determines the Chainlink product. Getting this wrong is the most common integration mistake.
Chainlink Data Feeds are heartbeat-based price oracles. A network of independent node operators fetches price data from multiple sources, aggregates off-chain, and pushes an on-chain update either when price deviates by a threshold (e.g., 0.5%) or on a scheduled heartbeat (e.g., every hour). Data Feeds are deployed on every major EVM chain including Polygon, Arbitrum, and Base, and are the right choice for prediction markets with resolution windows longer than four hours. The limitation: if your market resolves on “BTC price at exactly 23:00 UTC” and the nearest heartbeat was at 22:47, you’re settling on a 13-minute-old price — an arbitrage window that informed traders will exploit.
Chainlink Data Streams use a pull-based model: your contract requests a cryptographically signed price report for a specific timestamp on demand. Latency is sub-second. There is no manipulation window because the price is cryptographically tied to the precise settlement timestamp. Polymarket uses Data Streams for its 5-minute and 15-minute crypto markets precisely because these need timestamped, verifiable price snapshots rather than periodic heartbeat updates.
Chainlink Functions connect your contract to any external API by running JavaScript in a decentralized compute environment. This is the right tool for markets where the outcome is a real-world event result — sports scores, election results, weather data — rather than a continuously published price series.
Chainlink Automation provides the settlement trigger. It monitors on-chain conditions and calls your contract’s finalize() function when conditions are met, without requiring any admin key or manual intervention.
For how these oracle products fit into the broader build architecture, see the full guide to building a prediction market platform like Polymarket.
Step 2: Integrate Chainlink Data Feeds (Price-Based Markets)
Data Feeds integration in Solidity uses the AggregatorV3Interface. Your Market contract stores the oracle address, calls latestRoundData() on the aggregator, reads the returned price and timestamp, validates both, and uses the price to determine the market outcome.
The latestRoundData() function returns five values: roundId, answer (the price), startedAt, updatedAt, and answeredInRound. Most integration guides only use answer. The updatedAt timestamp is equally important — if updatedAt is more than your configured staleness threshold ago, revert with "OracleDataStale" rather than resolving on outdated prices. Your settlement should revert or emit a stale data alert rather than proceeding with an old price.
The oracle wrapper pattern is the second critical detail. Instead of hard-coding the Chainlink aggregator address directly into your Market contract, deploy a separate OracleWrapper contract that your Market calls. The wrapper has a single owner-updateable address pointing at the current aggregator. When you migrate chains, change feed addresses, or upgrade to Data Streams, you update one address in the wrapper rather than redeploying and re-auditing all your market contracts. This costs zero additional gas at runtime and saves thousands in audit costs during inevitable oracle configuration changes.
LINK token cost for Data Feeds: free to consume on-chain. You pay gas to call latestRoundData() (minimal on Polygon and Arbitrum), but no LINK payment is required. Chainlink node operators are compensated by the protocols that sponsor each feed’s operation.
Step 3: Upgrade to Chainlink Data Streams (High-Frequency Markets)
Data Streams have a different integration model from Data Feeds. Your off-chain Node.js backend requests a signed report from the Chainlink Data Streams REST API for a specific feedId and timestamp. The API returns a signed report containing the price, timestamp, and a cryptographic proof that the designated Chainlink node network produced this exact report. Your backend submits this report to your smart contract’s settlement function. The contract calls the StreamsVerifier contract (deployed by Chainlink on your chain) to verify the cryptographic signature. If valid, the contract uses the embedded price to resolve the market.
The key property this achieves: the settlement price is cryptographically tied to the exact resolution timestamp specified in the market. There is no manipulation window because you can’t submit a report for a different timestamp than the one requested. An attacker who moves the asset price in the seconds before settlement cannot substitute a different price because the report for the correct timestamp is already signed by the oracle network.
The feedId format for Data Streams is different from Data Feed contract addresses. Each asset has a unique bytes32 feedId. The BTC/USD Data Streams feedId on Polygon is different from the Data Feeds aggregator address for the same asset on the same chain. Confirm your feedId before deploying to mainnet — using the wrong identifier silently calls a different feed or reverts.
LINK token cost for Data Streams: approximately 0.001 to 0.01 LINK per report verification. For a platform running 100 markets with daily settlements, this is $1 to $10 per day in LINK at current prices.
Step 4: Automate Settlement with Chainlink Automation

Your Market contract implements the AutomationCompatibleInterface, which requires two functions. checkUpkeep(bytes calldata checkData) is called off-chain by the Chainlink Automation network and returns upkeepNeeded = true when the market’s resolution conditions are met: block.timestamp >= resolutionTimestamp, the oracle has a valid report, and the dispute window has passed. performUpkeep(bytes calldata performData) is called on-chain when checkUpkeep returns true — it executes your finalize() logic: reads the oracle price, determines the winning outcome, and enables redemptions.
The 64-block Polygon finality recommendation applies here. On Polygon PoS, deep chain reorganizations are possible for approximately the first 64 blocks (around 2 minutes) after a transaction. For high-value prediction market settlements, configure your checkUpkeep to require block.number > oracle_report_block + 64 before triggering performUpkeep. This ensures you’re settling on a price from a confirmed, reorg-resistant block.
LINK token cost for Automation: approximately 0.005 to 0.05 LINK per upkeep trigger depending on gas costs and your chain. For a platform with 50 markets each settling once per day, budget 0.25 to 2.5 LINK per day — under $25 at current prices.
For a full explanation of the finalize() pattern and the contract-level settlement lifecycle, see smart contracts for prediction markets: how they work.
Step 5: Stale Data Detection and the Circuit Breaker Pattern
Stale data detection in your OracleWrapper: after calling latestRoundData(), check block.timestamp - updatedAt > stalenessThreshold. If true, revert with "OracleDataStale" rather than proceeding with outdated prices. Set stalenessThreshold to 1.5x the feed’s expected heartbeat interval: 5,400 seconds (90 minutes) for an hourly feed, 129,600 seconds (36 hours) for a daily feed. Log stale data events so your monitoring system (Alchemy webhooks, custom dashboards) alerts your ops team before the settlement window passes.
The circuit breaker pattern handles the case where oracle data is available but potentially manipulated — for example, a flash loan spiked the BTC price 15% in the 30 seconds before your settlement timestamp. The circuit breaker compares the settlement price to a time-weighted average price (TWAP) from the same feed. If the settlement price deviates from the TWAP by more than your configured threshold (typically 10%), settlement is paused and a SettlementPaused event is emitted. A 24 to 48 hour time-lock gives the community time to review the price anomaly. One platform in 2025 settled a $7 million pool on a flash loan-manipulated price — a 10% TWAP circuit breaker would have caught it before payouts executed.
Step 6: Custom Market Types with Chainlink Functions
Not every prediction market can resolve on a Chainlink price feed. “Will the Lakers win tonight?” requires querying the NBA API. “What will the US CPI reading be?” requires a government data source. Chainlink Functions handles both by running JavaScript in a decentralized off-chain compute environment. Your JavaScript makes HTTPS calls to any API, parses the response, and returns a bytes32 result. The result is delivered to your contract’s fulfillRequest callback along with a cryptographic proof that the computation was performed correctly.
For ambiguous results (game postponed, API unavailable), your JavaScript returns a sentinel value (e.g., 2) that your contract maps to a “no resolution — refund all positions” state. Always define the ambiguous result handling before deployment — leaving it undefined means a postponed game could lock market funds permanently.
LINK token cost for Functions: approximately 0.1 to 0.2 LINK per request. A market with a 0.5% trading fee on $10,000 in volume generates $50 in revenue — a $1 to $2 Functions call is under 4% of that revenue.
Chainlink vs Pyth vs UMA: When to Use Each
Chainlink is the default for price-based markets with any resolution window. Use Data Feeds for markets resolving in hours or days, Data Streams for markets resolving in minutes, and Automation for permissionless settlement triggering on all market types.
Pyth Network publishes prices every 400 milliseconds — significantly faster than Chainlink’s standard heartbeat-based Data Feeds. For markets with resolution windows under 4 hours where Chainlink Data Streams is not yet available on your target chain, Pyth closes the arbitrage window that a slower heartbeat update would leave open. Use Pyth as a complement to Chainlink, not a replacement.
UMA’s Optimistic Oracle handles everything that no price feed can resolve: election outcomes, sports results, regulatory decisions, research questions. The dispute mechanism provides a human-verification layer via DVM when automated resolution is ambiguous. Use UMA for all event-based and subjective markets in your prediction market platform.
The three-oracle strategy: Data Streams for sub-4-hour price markets, Data Feeds for longer-duration price markets, UMA for event markets. This covers every market category a general-purpose prediction market platform needs without building custom oracle infrastructure from scratch.
Frequently Asked Questions
Q1: What is the difference between Chainlink Data Feeds and Data Streams for prediction markets?
Data Feeds are push-based: node operators push an on-chain price update on a heartbeat schedule or when price deviates. Data Streams are pull-based: your contract requests a cryptographically signed price report for a specific timestamp on demand. For prediction markets, Data Streams are superior for any market with a precise resolution timestamp because the settlement price is cryptographically tied to the exact moment specified, eliminating the manipulation window that exists between heartbeat updates.
Q2: Do I need to pay LINK tokens to use Chainlink in my prediction market?
For Data Feeds: no LINK payment required. For Data Streams: approximately 0.001 to 0.01 LINK per report verification. For Chainlink Automation: approximately 0.005 to 0.05 LINK per upkeep trigger. For Chainlink Functions: approximately 0.1 to 0.2 LINK per request. For a platform running 50 markets with daily settlements, total Chainlink operating costs are typically under $50 per day at current LINK prices.
Q3: What is the oracle wrapper pattern and why does it matter?
An oracle wrapper is a separate contract between your Market contracts and the Chainlink aggregator. The wrapper has an owner-updateable aggregator address. When you migrate chains, upgrade from Data Feeds to Data Streams, or change feed addresses, you update one variable in the wrapper rather than redeploying and re-auditing all your market contracts. This adds zero gas overhead at runtime and saves thousands in audit costs during oracle configuration changes.
Q4: What is stale data and how do I detect it in my smart contract?
Stale data is an oracle report where updatedAt (returned by latestRoundData()) is significantly older than the current block.timestamp. This happens when oracle nodes are offline or during network congestion. In your oracle wrapper, check block.timestamp - updatedAt > stalenessThreshold after calling latestRoundData() and revert with "OracleDataStale" if true. Set the threshold to 1.5x the feed’s expected heartbeat interval.
Q5: What is the 64-block Polygon finality recommendation?
On Polygon PoS, deep chain reorganizations are possible for approximately the first 64 blocks (around 2 minutes) after a transaction. For high-value prediction market settlements, configure your Chainlink Automation upkeep to require block.number > oracle_report_block + 64 before triggering performUpkeep. This ensures you’re settling on a price from a confirmed, reorg-resistant block rather than one that could be reorganized away.
Q6: What is the circuit breaker pattern for oracle manipulation prevention?
The circuit breaker compares your settlement price to a time-weighted average price (TWAP) from the same feed. If the settlement price deviates from the TWAP by more than your configured threshold (typically 10%), settlement is paused and a SettlementPaused event is emitted. A 24 to 48 hour time-lock gives the community time to review the anomaly. If the price spike was flash loan manipulation, it typically reverts within hours, allowing normal settlement to proceed with the post-spike price.
Q7: When should I use Pyth Network instead of Chainlink?
Use Pyth for prediction markets with resolution windows under 4 hours where you don’t yet have access to Chainlink Data Streams on your target chain. Pyth publishes prices every 400 milliseconds — faster than Chainlink’s standard heartbeat feeds — which closes the arbitrage window that a slower heartbeat update would leave open on short-duration markets. Use Pyth as a complement to Chainlink, not a replacement for it.

