Розробка смарт-контракту передбачень (стиль Polymarket)

Ви запускаєте DeFi-протокол, де користувачі роблять ставки на результат подій — від спортивних матчів до курсу ETH. Перша версія контракту на JavaScript з Web3 провалюється під навантаженням: reentrancy в redeem, oracle manipulation призводить до loss of funds, а gas cost на AMM перевищує ліміт у 15

Напрямки блокчейн-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1452
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1005
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1270
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1011

Ви запускаєте DeFi-протокол, де користувачі роблять ставки на результат подій — від спортивних матчів до курсу ETH. Перша версія контракту на JavaScript з Web3 провалюється під навантаженням: reentrancy в redeem, oracle manipulation призводить до loss of funds, а gas cost на AMM перевищує ліміт у 15 млн. Знайома ситуація? Ми переписуємо такі контракти з нуля.

Як працюють ринки передбачень на блокчейні?

Кожен ринок — пара умовних токенів: YES і NO. Користувач вносить 1 USDC і отримує 1 YES + 1 NO токен через Conditional Tokens Framework (CTF) від Gnosis. Далі він продає небажаний результат на AMM або CLOB. Після резолюції виграшний токен обмінюється на 1 USDC, програшний — на 0.

Conditional Tokens Framework (CTF) — стандарт 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: що обрати для вашого ринку?

Параметр AMM (LMSR або Constant Product) CLOB (Central Limit Order Book)
Децентралізація Повна (on-chain матчинг) Потребує off-chain матчера
Швидкість торгів Залежить від газу блоку Мілісекунди (матчинг на стороні)
Ліквідність Автоматична від LP Залежить від спреду та глибини книги
Gas cost Високий (експонента в LMSR) Низький (тільки settlement)
Підходить для Повністю децентралізованих платформ Високочастотної торгівлі

Polymarket використовує CLOB для швидкості. Для повністю децентралізованого ринку краще AMM. LMSR математично елегантний, але Constant Product AMM приблизно в 3 рази дешевший по газу — хороший вибір для ринків зі збалансованою ліквідністю.

Чому AMM вигідніший для повністю децентралізованого ринку?

LMSR (Logarithmic Market Scoring Rule) — класичний AMM для передбачувальних ринків. Ціна залежить від кількості проданих YES і NO токенів:

price_yes = e^(q_yes/b) / (e^(q_yes/b) + e^(q_no/b)) 

де b — параметр ліквідності. LMSR гарантує, що маркетмейкер завжди приймає ставки, і максимальний збиток обмежений b * ln(2). Constant Product AMM (як в Uniswap v2) простіший по газу, але ціни менш точні поблизу 0% або 100%. Ми використовуємо модифікований constant product з обмеженням діапазону цін [0.02, 0.98] — це захищає від нескінченних втрат при крайніх результатах.

Oracle і резолюція: де ховається головна складність

Ринок передбачень без надійного oracle — це ринок з мануальним арбітражем, який завжди під загрозою. Три підходи:

  • Chainlink Data Feeds — для фінансових ринків (ціна ETH вище $5000?). Детермінований, децентралізований, але охоплює тільки фінанси.
  • 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 TWAP за 24-48 годин + кілька джерел
Front-running резолюції Закриття торгів за X годин до резолюції
Griefing через spam dispute Bond-вимога для диспутів
Reentrancy при redeem Check-Effects-Interactions + ReentrancyGuard
Неправильний conditionId Подвійна перевірка перед деплоєм
  • Oracle manipulation. Якщо ринок резолвиться по on-chain ціні в конкретний момент — flash loan атака можлива. Захист: TWAP за 24-48 годин замість spot price, кілька незалежних джерел.
  • Front-running резолюції. Хтось дізнається результат до офіційної резолюції і купує токени за старою ціною. Рішення: закриття торгів за X годин до резолюції.
  • Griefing через spam dispute. В optimistic oracle системах зловмисник оскаржує кожну резолюцію. Захист: bond-вимога для диспутів (застава втрачається при програші).
  • Reentrancy при redeem. CTF.redeemPositions переводить токени до оновлення state. Використовуємо Check-Effects-Interactions + ReentrancyGuard.
  • Неправильний conditionId. CTF використовує keccak256(oracle, questionId, outcomeSlotCount). Перевіряємо conditionId двічі перед деплоєм.

Governance і створення ринків

Хто може створювати ринки? Варіанти:

  • Permissioned. Тільки whitelist операторів. Централізовано, але захищає від сміттєвих ринків.
  • Permissionless з bond. Будь-хто, хто заплатить заставу. Застава повертається при коректній резолюції.
  • DAO governance. Голосування за кожен ринок. Повільно, але децентралізовано.

Для MVP — permissioned з roadmap до DAO.

Стек розробки

  • Foundry — основний інструмент. Fuzz-тести для AMM математики.
  • Gnosis CTF — використовуємо готову імплементацію.
  • Chainlink — oracle для фінансових ринків.
  • OpenZeppelin — AccessControl, ReentrancyGuard, Pausable.
  • Slither + Echidna — статичний аналіз і property-based testing.
Повний список етапів робіт
  1. Проектування (3-5 днів). Вибір AMM/CLOB, oracle стратегії, governance моделі. White paper з математикою.
  2. Розробка контрактів (7-10 днів). Market factory, AMM логіка, CTF інтеграція. У кожного модуля unit-тести.
  3. Аудит і fuzzing (3-5 днів). Foundry fuzzer, Echidna для invariant testing, Slither на весь код.
  4. Фронтенд і The Graph (5-7 днів). Subgraph, TypeScript SDK, React-інтерфейс.
  5. Тестування на testnet (3-5 днів). Повний цикл: створення → торги → резолюція → redeem.

Загальний термін — від 1-2 тижнів (тільки контракти) до 4-6 тижнів (повноцінна платформа).\n

Що входить в роботу

  • Документація: технічне завдання, white paper, API-специфікації.
  • Вихідний код смарт-контрактів з відкритою ліцензією.
  • Розгортання на обраній мережі (Ethereum, Polygon, Arbitrum, BNB Chain).
  • Аудит безпеки зі звітом.
  • Інтеграція з фронтендом (опціонально) та The Graph subgraph.
  • Технічна підтримка на 3 місяці після деплою.

Оцінимо ваш проект за 1-2 дні. Зв'яжіться з нами для обговорення деталей. Отримайте консультацію по вашому протоколу.