We develop decentralized betting systems on the blockchain: from simple totalizators to full-fledged CLOB markets with conditional tokens. Polymarket already processes hundreds of millions of dollars in betting volume on political events via Polygon with USDC as settlement currency—and the entire system relies on smart contracts with conditional outcomes. The key challenge in building any such platform isn't the betting mechanism, but the deterministic and secure resolution of outcomes. Our experience encompasses over 30 contracts deployed in production on Ethereum, Polygon, and Arbitrum. Our team has 5+ years of experience in blockchain development and has been delivering DeFi solutions since 2019.
The Oracle Question — Central Engineering Challenge
The outcome of an event like "Biden wins the election" cannot be obtained from a Chainlink Price Feed. It's not a numeric value with decentralized consensus—it's a judgment. For prediction systems, this means choosing among several resolution approaches.
UMA Optimistic Oracle
UMA uses an optimistic model: anyone can propose an outcome, another participant can dispute it. Disputing triggers a dispute resolution through a vote by UMA holders. Economic security relies on a bond: the proposer posts a bond in USDC or UMA, which is lost if the resolution is incorrect. UMA Optimistic Oracle ensures security through economic incentives—as described in official documentation.
Integration with UMA:
import "@uma/core/contracts/optimistic-oracle-v3/interfaces/OptimisticOracleV3Interface.sol";
contract EventBettingMarket {
OptimisticOracleV3Interface immutable oracle;
bytes32 public assertionId;
function resolveMarket(bytes memory claim) external {
assertionId = oracle.assertTruth(
claim,
address(this),
address(0),
address(0),
7200,
IERC20(currency),
bond,
identifier,
bytes32(0)
);
}
function assertionResolvedCallback(bytes32 _assertionId, bool assertedTruthfully) external {
require(msg.sender == address(oracle));
if (assertedTruthfully) {
_settleWinners();
} else {
_refundBettors();
}
}
}
Advantage of UMA: cheap for most markets (no voting when there's no dispute), but when there is a dispute, it is 10 times slower than Chainlink.
Chainlink for Numeric Outcomes
Note: when the outcome is numeric, Chainlink AggregatorV3Interface is the right choice: deterministic, no dispute window.
function resolveNumericMarket() external {
(, int256 price, , uint256 updatedAt, ) = priceFeed.latestRoundData();
require(updatedAt >= marketEndTime, "Price data too old");
require(block.timestamp >= marketEndTime, "Market not ended");
bool outcomeA = price >= int256(targetPrice);
_settleMarket(outcomeA);
}
Critical issue: Chainlink updates data based on deviation threshold or heartbeat—not at a specific second. You must explicitly check updatedAt and have a fallback to Pyth or UMA.
Multi-Oracle Approach for Production
For critical markets with volumes over $1M—aggregate multiple sources:
| Oracle | Outcome Type | Latency | Cost |
|---|---|---|---|
| Chainlink | Numeric (price) | ~1 hour | Low |
| Pyth Network | Numeric (price) | Seconds | Low |
| UMA Optimistic | Arbitrary | 2+ hours | Medium |
| API3 dAPI | Numeric (first-class data) | Minutes | Low |
| Custom multisig | Any | Instant | 0 (trust) |
For sports results, UMA + a reserve multisig with timelock is optimal—as a last line.
How to Choose the Winning Distribution Model?
Fixed Odds — Outdated for DeFi
Odds are fixed at market creation. The bookmaker bears risk if the assessment is wrong. Hard to implement on-chain without centralized re-pricing.
Parimutuel — Standard for Blockchain Betting
All bets go into a pool. Winners split the pool proportionally. The odds are determined by the final distribution. Parimutuel is 2–3 times cheaper in gas per operation than CLOB. On Ethereum, a typical parimutuel bet costs ~50,000 gas, while a CLOB bet costs ~150,000 gas.
mapping(uint8 => uint256) public totalBets;
mapping(address => mapping(uint8 => uint256)) public userBets;
function claimWinnings(uint8 outcome) external {
require(resolvedOutcome == outcome, "Wrong outcome");
uint256 userBet = userBets[msg.sender][outcome];
require(userBet > 0, "No bet");
uint256 totalPool = totalBets[0] + totalBets[1];
uint256 protocolFee = totalPool * feeBps / 10000;
uint256 winnerPool = totalPool - protocolFee;
uint256 payout = (userBet * winnerPool) / totalBets[outcome];
userBets[msg.sender][outcome] = 0;
IERC20(currency).transfer(msg.sender, payout);
}
CLOB — Advanced Approach
Polymarket uses conditional tokens (ERC-1155). Each outcome is a token, and the market trades via a CLOB with limit orders. Advantage: real price discovery, aggregated liquidity. Complexity: off-chain orderbook + on-chain settlement.
| Feature | Parimutuel | CLOB |
|---|---|---|
| Price discovery | No (odds after pool) | Yes (real market) |
| Liquidity | Single pool | Order aggregation |
| Contract complexity | Low | High (matching engine) |
| Gas per bet | 50k–100k gas | 150k–300k gas |
Protecting Bets from Front-Running
To protect bets from front-running, we use a commit-reveal scheme: first the hash of the bet, then disclosure after N blocks. For sports bets, we lock betting 5 minutes before the event via endBettingTime = eventStartTime - 5 minutes. This prevents last-second manipulation.
Why UMA Optimistic Oracle is Better for Sports Outcomes?
UMA supports arbitrary assertions, which is ideal for sports and politics. Chainlink Price Feed only provides numeric data. UMA is cheaper for markets without disputes, and the bond protects against dishonest resolutions. Average resolution cost is $50–$200 when there is no dispute.
Creating and Managing Markets: Factory Pattern
Each market is a separate contract deployed via a factory. This isolates risks.
contract MarketFactory {
mapping(bytes32 => address) public markets;
function createMarket(
string calldata question,
uint256 endTime,
address oracle,
bytes calldata oracleData
) external returns (address marketAddress) {
bytes32 marketId = keccak256(abi.encode(question, endTime, oracle));
require(markets[marketId] == address(0), "Market exists");
BettingMarket market = new BettingMarket(
question, endTime, oracle, oracleData, feeBps
);
markets[marketId] = address(market);
emit MarketCreated(marketId, address(market), question, endTime);
return address(market);
}
}
Emergency Pause and Refund
If the oracle cannot resolve the outcome (event canceled), emergency admin (multisig) calls cancelMarket(), all participants withdraw deposits. Timelock on cancellation—minimum 24 hours.
Development Stack
Contracts: Solidity 0.8.24 + OpenZeppelin (AccessControl, Pausable, ReentrancyGuard) + Foundry for testing. Tests include fork tests with real UMA and Chainlink on Polygon mainnet. For conditional tokens—Gnosis Conditional Tokens Framework. Off-chain: The Graph subgraph, GraphQL API.
Process of Work
- Analytics (2–3 days). Event types, winning model, oracles, compliance, chains.
- Design (3–5 days). Contract architecture, integration, resolution, emergency.
- Development (3–8 weeks). From parimutuel MVP to CLOB with conditional tokens.
- Audit. Betting contracts are high-priority audit due to money management. Audit cost starts at $15,000 depending on complexity.
Timeline and Costs
- Parimutuel with Chainlink — 1–2 weeks (cost from $5,000).
- UMA + Factory + The Graph — 6–10 weeks (cost from $15,000).
- CLOB with conditional tokens — 3–5 months (cost from $50,000).
Deliverables
- Source code of contracts with full test coverage (Foundry).
- Integration with chosen oracles (Chainlink, UMA, Pyth).
- API documentation and The Graph subgraph.
- Audit report from partners (HashEx or CertiK).
- Training for your team and 3 months of technical support.
- Access to private Git repository and deployment scripts.
We guarantee a fully audited smart contract with a multi-oracle approach combining Chainlink (numeric data) and UMA (outcomes). This reduces the probability of erroneous resolution to 0.01%. Our team has over 5 years of experience and has delivered more than 30 production contracts. Contact us for a consultation—we'll assess your project within 2 days. Order development of a blockchain betting system and get demo access to our contracts.







