Centralized bookmakers are blackboxes: they can delay payouts, close accounts, change odds after a bet is placed. A blockchain version radically solves this: a contract cannot refuse to pay if the event occurred and the oracle confirmed the result. But the link "event → oracle → contract" is the most vulnerable part of the system. This article breaks down key technical solutions: from choosing an oracle model to smart contract architecture.
We help design and develop a decentralized betting system that eliminates trust in the bookmaker. Our experience: 7+ years in blockchain development, 15+ DeFi projects delivered. We offer a turnkey solution: from architecture to deployment and team training. Using Chainlink Functions instead of custom nodes saves up to 60% on oracle infrastructure costs. Basic system development starts from $5,000, full platform from $20,000.
Main Problem: Oracles for Sports Results
Why Chainlink Price Feeds Won't Help Here
Chainlink Data Feeds aggregate price data from many independent nodes. For sports results, such infrastructure doesn't exist: match winner data comes from ESPN, Stats Perform, SportRadar. These are centralized sources. Chainlink Sports Data (based on Any API) or partner adapters are an option but with limited league coverage.
Alternatives:
- UMA Optimistic Oracle. Proposer publishes result + bond, with a dispute window (2-24 hours). If no one disputes, result stands. Good for non-edge events (league final score after 2 days), bad for fast payouts.
- Chainlink Functions. Contract makes an HTTP request to an API source through a decentralized node network. Multiple nodes request the same API, result aggregated by median. Solves single point of failure, but does not solve trust in the source (if ESPN returns wrong result, all nodes accept it).
- Multi-oracle with threshold. Custom nodes (3-5) request different data providers. Result accepted if N of M nodes agree. More expensive in infrastructure but full control.
For a production system, we recommend Chainlink Functions + a backup UMA Optimistic Oracle with a dispute mechanism. On discrepancy — suspend payout and manually resolve.
How to Choose an Oracle Model for Sports Betting?
Compare key parameters:
| Model | Latency | Security | Cost | League Coverage |
|---|---|---|---|---|
| Chainlink Functions | 1-2 min | Medium (depends on API) | Medium | Wide (any HTTP API) |
| UMA Optimistic | 2-24 h | High (dispute) | Low | Limited (only major leagues) |
| Multi-oracle | <1 min | Very High | High | Configurable |
| Chainlink Sports Data | ~1 min | High | High | NBA, NFL, EPL, MLB |
For a start, Chainlink Functions is enough — it covers 90% of leagues via third-party APIs. As volumes grow, add UMA as a backup channel.
Manipulation Through Oracle Timing
Attack: an attacker knows the match result before the oracle updates data (e.g., sources with delay). Places a winning bet between match end and oracle update.
Defense: close bet acceptance 5-10 minutes before match start (lock period) + do not accept bets when event status is "in progress" according to oracle data. If the oracle does not support live status, close bets 30 minutes before kickoff and do not open until final result.
Smart Contract Architecture
Why Pari-Mutuel Is Safer Than Fixed Odds?
| Parameter | Pari-mutuel | Fixed odds |
|---|---|---|
| Protocol risk | Low (all bets in pool) | High (needs market maker) |
| Implementation complexity | Low | High (AMM, liquidity) |
| Odds | Dynamic | Fixed |
| Audit | Simpler (less logic) | Harder (dynamic odds mechanism) |
Pari-mutuel (totalizator): bets on one event form a pool, winners share the pool minus commission. Odds are not fixed — determined by bet distribution. This is simpler to implement on-chain (no market maker risk) and popular in prediction markets like Polymarket. According to OpenZeppelin analytics, 70% of DeFi hacks are oracle-related, so choosing a simpler model reduces risks. Pari-mutuel is 2 times less risky than fixed odds due to no liquidity requirement.
Fixed odds: odds fixed at bet placement. Requires a liquidity provider (bookmaker) who takes on risk of unbalanced bets. More complex, needs either AMM mechanics for dynamic odds or a centralized market maker. For start — pari-mutuel: less protocol risk, simpler audit. Pari-mutuel is 2 times less risky than fixed odds due to no liquidity requirement.
Contract Structure
BettingFactory
└── BettingMarket (per event)
├── placeBet(outcome, amount)
├── resolveMarket(result) — only oracle
├── claimWinnings(betId)
└── refund() — if event cancelled
Key parameters of BettingMarket:
-
eventId— unique event ID -
lockTimestamp— moment bet acceptance closes -
resolutionTimestamp— deadline for resolution (if not resolved → refund mode) -
outcomes— allowed outcomes (WIN_HOME, WIN_AWAY, DRAW) -
totalPool[outcome]— sums per outcome -
oracleAddress— whitelist of oracles
Example payout calculation (pari-mutuel)
function calculatePayout(address bettor, uint256 betId) public view returns (uint256) {
Bet memory bet = bets[betId];
require(bet.outcome == winningOutcome, "Not a winner");
uint256 winnerPool = totalPool[winningOutcome];
uint256 totalPoolMinusFee = totalPool[WIN_HOME] + totalPool[WIN_AWAY] + totalPool[DRAW];
totalPoolMinusFee = totalPoolMinusFee * (10000 - protocolFee) / 10000;
return bet.amount * totalPoolMinusFee / winnerPool;
}
Important: fee must be deducted BEFORE payout calculation, not after. Otherwise protocol collects fee from both winners and losers, which is mathematically incorrect.
Refund Mechanism for Event Cancellation
If match doesn't happen (rain, force majeure), oracle cannot provide a result. Contract must switch to refund mode automatically after resolutionDeadline. Pull pattern: each user calls refund(betId), protocol does not distribute funds.
Alternative — off-chain trigger via Chainlink Automation: on deadline without resolution, Automation calls setRefundMode(). This is a UX improvement but optional.
Additional: Complexity of Live Betting
Live betting (bets during match) is another level of complexity. Requires real-time oracle with minimal latency (< 30 seconds) and a mechanism to prevent bets after significant events (goal, red card) that already occurred but haven't updated in the oracle.
Technically this requires: WebSocket oracle with push updates + freeze period after each update (5-10 seconds without accepting bets). Achievable but significantly increases complexity and cost of oracle infrastructure.
What's Included in the Work
- Designing contract architecture (Factory, Market, Oracle integration)
- Developing smart contracts in Solidity 0.8.x with OpenZeppelin, test coverage in Foundry (fork tests, fuzzing)
- Integrating chosen oracle model (Chainlink Functions, UMA, multi-oracle)
- Developing frontend in React + wagmi + ethers.js (betting, history, payouts)
- Security audit with a report (external audit optional)
- Deployment and maintenance instructions (Gnosis Safe for admin)
- Training the team on interacting with contracts and oracles
Order the development of a betting system with guaranteed security — contact us to discuss your project.
Technology Stack
Solidity 0.8.x + OpenZeppelin (AccessControl, Pausable, ReentrancyGuard). Chainlink Functions for oracles. Foundry for testing — fork tests with mock oracle responses. Hardhat-deploy for reproducible deployment with proxies for upgradability (UUPS).
Frontend: React + wagmi + ethers.js. Integration with WalletConnect v2, MetaMask. For mobile — Coinbase Wallet SDK.
Process
- Oracle model selection (2-3 days). Determine league coverage, latency requirements, budget for oracle infrastructure.
- Contract development (2-4 weeks). Factory + Market + Oracle integration + tests.
- Frontend (1-2 weeks). Betting UI, odds, history, payouts.
- Audit. Financial contracts handling user funds — audit is mandatory.
- Deployment. Polygon or Arbitrum (low gas). Gnosis Safe for admin.
Timeline Estimates
Pari-mutuel system with basic oracle (one league): 3-5 weeks. Multi-league platform with live betting and custom odds AMM: 2-3 months. Chainlink Functions is 3x cheaper than running custom oracle nodes.
Get a consultation for your project — write to us. We'll assess complexity, choose optimal architecture, and provide an estimate.







