Ви запускаєте 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.
Повний список етапів робіт
- Проектування (3-5 днів). Вибір AMM/CLOB, oracle стратегії, governance моделі. White paper з математикою.
- Розробка контрактів (7-10 днів). Market factory, AMM логіка, CTF інтеграція. У кожного модуля unit-тести.
- Аудит і fuzzing (3-5 днів). Foundry fuzzer, Echidna для invariant testing, Slither на весь код.
- Фронтенд і The Graph (5-7 днів). Subgraph, TypeScript SDK, React-інтерфейс.
- Тестування на testnet (3-5 днів). Повний цикл: створення → торги → резолюція → redeem.
Загальний термін — від 1-2 тижнів (тільки контракти) до 4-6 тижнів (повноцінна платформа).\n
Що входить в роботу
- Документація: технічне завдання, white paper, API-специфікації.
- Вихідний код смарт-контрактів з відкритою ліцензією.
- Розгортання на обраній мережі (Ethereum, Polygon, Arbitrum, BNB Chain).
- Аудит безпеки зі звітом.
- Інтеграція з фронтендом (опціонально) та The Graph subgraph.
- Технічна підтримка на 3 місяці після деплою.
Оцінимо ваш проект за 1-2 дні. Зв'яжіться з нами для обговорення деталей. Отримайте консультацію по вашому протоколу.







