Разработка смарт-контракта предсказаний (Polymarket-стиль)
Polymarket — это рынок предсказаний с объёмом торгов $500M+ в месяц на пике 2024 года. Под капотом — контракт бинарных исходов поверх AMM/CLOB гибрида с Chainlink oracle для резолюции. Это не «простой betting-контракт» — это полноценный финансовый протокол с нетривиальной математикой и несколькими векторами атак, которые нужно закрыть до деплоя.
Как работает рынок предсказаний на блокчейне
Каждый рынок — пара условных токенов: YES и NO. Пользователь вносит 1 USDC и получает 1 YES + 1 NO токен (через Conditional Tokens Framework от Gnosis). Дальше он продаёт нежелательный исход на AMM или CLOB. После резолюции выигравший токен обменивается на 1 USDC, проигравший — на 0.
CTF (Conditional Tokens Framework) — стандарт ERC-1155 для условных токенов. Каждый исход представлен как позиция с уникальным positionId. При резолюции CTF разрешает redeem выигравших позиций.
// 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: выбор механизма ценообразования
Polymarket использует CLOB (Central Limit Order Book) — книгу ордеров на MATIC с матчингом на стороне Polymarket. Это быстро и похоже на CEX, но требует централизованного матчера. Для полностью децентрализованного рынка — AMM.
LMSR (Logarithmic Market Scoring Rule) — классический AMM для предсказательных рынков. Цена зависит от текущего количества токенов YES и NO:
price_yes = e^(q_yes/b) / (e^(q_yes/b) + e^(q_no/b))
где b — ликвидность параметр, q_yes, q_no — количество проданных токенов.
LMSR гарантирует, что market maker (создатель рынка) всегда принимает ставки, и максимальный убыток ограничен b * ln(2). Это математически элегантно, но дорого по газу из-за вычислений с fixed-point экспонентой.
Constant Product AMM (Uniswap v2 стиль). Проще по газу, но цены менее точные в экстремальных вероятностях (близко к 0% или 100%). Хорошо для рынков со сбалансированной ликвидностью.
Мы строим на модифицированном constant product с ограничениями на диапазон цен [0.02, 0.98] — чтобы избежать бесконечных потерь при крайних позициях.
Oracle и резолюция: где прячется главная сложность
Рынок предсказаний без надёжного oracle — это рынок с мануальным арбитражем, который всегда под вопросом. Три подхода:
Chainlink Data Feeds. Для рынков на финансовые данные (ETH цена выше $5000 31 декабря?). Детерминированный, decentralized, но охватывает только финансовые активы.
UMA Optimistic Oracle. Для субъективных вопросов (Байден выиграет выборы?). Предложение ответа + период оспаривания + диспут через UMA token holders. Задержка 2-48 часов, но работает для любых вопросов.
Кастомный мультисиг oracle. Набор уважаемых сторон (5/9 multisig) голосует за исход. Централизовано, но прозрачно и быстро. Для закрытых или нишевых рынков.
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) в fixed point
return (noR * 1e18) / (yesR + noR);
}
}
Векторы атак, которые нужно закрыть
Oracle manipulation. Если рынок резолюится по onchain цене в конкретный момент — возможен flash loan attack: занять средства, манипулировать ценой через DEX, получить выигрышный исход. Защита: TWAP (time-weighted average price) за 24-48 часов вместо spot price. Или требование нескольких независимых oracle источников.
Front-running резолюции. Кто-то знает исход раньше официальной резолюции (например, Байден проиграл выборы, но oracle ещё не обновился) и покупает NO токены по 0.8 перед тем, как цена обновится до 1.0. Частичное решение — закрытие торгов за X часов до резолюции.
Griefing через spam dispute. В optimistic oracle системах злоумышленник может оспаривать каждую резолюцию, блокируя выплаты. Защита: bond-requirement для диспутов (залог, который теряется при проигрыше в диспуте).
Reentrancy при redeem. CTF.redeemPositions переводит токены до обновления state. Стандартный паттерн — Check-Effects-Interactions + ReentrancyGuard на всех функциях вывода средств.
Неправильный conditionId. CTF использует keccak256(oracle, questionId, outcomeSlotCount) как conditionId. Если oracle адрес или questionId отличается от ожидаемого — пользователи не смогут redeem выигрыш. Проверяем conditionId дважды перед деплоем рынка.
Governance и создание рынков
Кто может создавать рынки? Варианты:
- Permissioned. Только whitelist операторов. Централизованно, но защищает от мусорных рынков.
- Permissionless с bond. Любой, кто заплатит залог. Залог возвращается при корректной резолюции, сжигается при манипуляции.
- DAO governance. Голосование за каждый рынок. Медленно, но максимально децентрализованно.
Для MVP — permissioned с roadmap к DAO.
Стек разработки
- Foundry — основной инструмент. Fuzz-тесты особенно важны для AMM математики: случайные входные данные позволяют найти численные ошибки в fixed-point арифметике.
- Gnosis CTF — используем готовую имплементацию, не пишем conditional tokens с нуля.
- Chainlink — oracle для финансовых рынков.
- OpenZeppelin — AccessControl, ReentrancyGuard, Pausable.
- Slither + Echidna — статический анализ и property-based testing.
Процесс разработки
Проектирование (3-5 дней). Выбор механизма AMM/CLOB, oracle стратегии, governance модели. Whitepaper с математикой AMM и proof of no-arbitrage.
Разработка контрактов (7-10 дней). Market factory, AMM логика, oracle интеграция, CTF integration. Каждый модуль отдельно с unit-тестами.
Аудит и fuzzing (3-5 дней). Foundry fuzzer на AMM функциях, Echidna для invariant testing (сумма YES+NO reserve постоянна, цена в [0,1] всегда). Slither на весь кодbase.
Фронтенд и The Graph (5-7 дней). Subgraph для индексации событий рынка, TypeScript SDK, React-интерфейс с графиками цен.
Тестирование на testnet (3-5 дней). Симуляция полного цикла: создание рынка → торги → резолюция → redeem.
Общий срок — 1-2 недели для базового протокола без фронтенда. Полноценная платформа с интерфейсом — 4-6 недель.
Регуляторный контекст
Рынки предсказаний находятся в серой зоне в большинстве юрисдикций. CFTC США считает некоторые предсказательные рынки незарегистрированными swap-платформами. Perion Markets получил Wells Notice от SEC в 2024. Рекомендуем юридическую консультацию до запуска, особенно если планируете работать с US пользователями.
Технически — geoblocking через фронтенд и terms of service. На уровне смарт-контракта ограничения нецелесообразны: блокировать адреса через контракт легко обходится через другой контракт.







