Розробка intent-based торгового протоколу
Класична модель DEX: користувач підписує транзакцію, яка точно описує що робити (обміняти 1 ETH на мінімум 3450 USDC через пул Uniswap V3 X). Якщо ринкові умови змінилися — транзакція скасується або виконується за невигідною ціною. Intent-based модель інвертує це: користувач підписує намір («хочу продати 1 ETH за найкращу можливу ціну USDC до 15:00 UTC»), а виконання делегується спеціалізованим solver-ам, які конкурують за право його виконати.
Це архітектурний зсув, порівнянний з переходом від limit order books до AMM. CoW Protocol, UniswapX, 1inch Fusion — реалізації цієї ідеї з різними компромісами.
Ключові компоненти системи
Структура ордера та підпис
Intent — це структурована сповіщення, яке користувач підписує через EIP-712. Мінімальна структура:
struct Order {
address maker; // хто створює ордер
address inputToken;
address outputToken;
uint256 inputAmount;
uint256 minOutputAmount; // мінімально прийнятно
uint256 deadline; // дійсний до
uint256 nonce; // захист від replay
bytes32 partialFillable; // дозволено чи часткове заповнення
}
EIP-712 типізована підпис: користувач бачить читаних даних у MetaMask, не raw hex. Це критично для UX та захисту від фішингу (користувач розуміє що підписує).
Важливий нюанс з nonce: класичний інкрементальний nonce не дозволяє мати кілька активних ордерів одночасно. UniswapX використовує схему word + bit: 256 ордерів можуть бути активні паралельно, кожен біт у uint256 word — один nonce. Скасування ордера = інвалідація біта в on-chain маппінгу без окремої транзакції для кожного ордера.
Мережа solver та конкуренція
Solver — off-chain агент, який моніторить orderbook (зазвичай off-chain orderbook з on-chain settlement), знаходить оптимальне виконання та виконує його on-chain. Прибуток solver-а — різниця між реальною ціною виконання та minOutputAmount ордера (так звана surplus).
Архітектурно можливі дві моделі:
On-chain аукціон (CoW Protocol): batch аукціон, всі ордери за період збираються разом, один переможний solver виконує весь batch. Uniform clearing price — всі ордери в batch виконуються за однією ціною. Це усуває front-running всередину batch.
Off-chain перший solver перемагає (UniswapX спрощено): перший solver, який виконав ордер on-chain до deadline — отримує винагороду. Простіше, але можлива MEV гонка між solver-ами.
Для користувацького протоколу: вибір моделі залежить від обсягу. При низькому обсязі batch аукціон не наповнюється — немає сенсу чекати. При високому — batch економить користувачам газ та дає краще ціни.
Settlement контракт
Центральний контракт, який:
- Верифікує підпис ордера (EIP-712 recovery)
- Перевіряє nonce (чи не був ордер уже виконаний)
- Перевіряє deadline
- Перевіряє що solver передає не менше
minOutputAmount - Атомарно переводить inputToken від maker до solver та outputToken від solver до maker
function fill(Order calldata order, bytes calldata signature, uint256 fillAmount) external {
// 1. Recover signer
address signer = ECDSA.recover(_hashTypedData(order), signature);
require(signer == order.maker, "Invalid signature");
// 2. Check nonce
require(!_usedNonces[order.maker][order.nonce], "Nonce used");
_usedNonces[order.maker][order.nonce] = true;
// 3. Check deadline
require(block.timestamp <= order.deadline, "Expired");
// 4. Transfer tokens atomically
IERC20(order.inputToken).safeTransferFrom(order.maker, msg.sender, fillAmount);
IERC20(order.outputToken).safeTransferFrom(msg.sender, order.maker, outputAmount);
emit OrderFilled(orderHash, msg.sender, fillAmount, outputAmount);
}
Атомарність досягається через safeTransferFrom в обидва боки в одній транзакції. Якщо solver не одобрив outputToken — другий transferFrom скасується, перший теж (атомарність EVM).
Permit2 інтеграція
Користувач повинен approve settlement контракт для inputToken. Класичний approve — окремої транзакції до першого ордера. З Permit2 (Uniswap) — дозвіл підписується off-chain разом з ордером, без попередньої on-chain транзакції. Це значне поліпшення UX.
Permit2 підтримує batch permit — дозволити кілька токенів однією підписью. Для протоколу з кількома парами — користувач одного разу approves Permit2 для кожного токена (one per token, not per protocol), далі всі dApps використовують Permit2.
Реалізація solver
Пошук оптимального виконання
Solver повинен знайти найкращий маршрут виконання ордера: через AMM пули (Uniswap, Curve, Balancer), через CEX (Binance через API, якщо є арбітраж), через on-chain orderbooks (Seaport для NFT, clob-based DEX), або через inventory solver-а (якщо у нього є outputToken).
Алгоритм: запит котирування від всіх джерел → вибір найкращої ціни → розрахунок прибутковості (outputAmount - minOutputAmount - gas cost - будь-які збори протоколу → прибуток).
Якщо profit < газ * gasPrice * safetyMultiplier — ордер не беремо. Помилка починаючих solver-ів: брати збиткові ордери сподіваючись на MEV — це не працює стійко.
Захист solver-а від shady ордерів
Зловмисник може створити ордер з inputToken, який при transferFrom викликає reentrancy у settlement контракті. Або inputToken може бути дефляційним (transfer fee) — solver отримує менше ніж очікував.
Захист settlement контракту: nonReentrant на fill. Захист solver-а: перевіряє inputToken на whitelist відомих токенів або проводить simulated fill через eth_call перед реальним виконанням.
Оптимізація газу
Кожен fill — мінімум 2 трансфери + signature recovery + nonce check. На mainnet при $50 газ — це $5-15 за транзакцію. При малих ордерах (100 USDC) — неприйнятно.
Рішення:
- L2 розгортування: Arbitrum One знижує газ 10-50x, Optimism аналогічно
-
Batch fill: solver виконує кілька ордерів в одному
batchFillвиклику, амортизуючи base gas cost - Calldata оптимізація: abi-encoding ордера оптимізується під нульові байти (нульові байти дешевше, 4 газ vs 16 газ). Компактне кодування зменшує calldata газ на 20-40%
Стек розробки
Solidity 0.8.x + Foundry + OpenZeppelin 5.x. EIP-712 через OpenZeppelin EIP712 abstract contract. Permit2 інтеграція через репозиторій Uniswap/permit2. Off-chain solver: Node.js + TypeScript + ethers.js v6 + viem. Orderbook: власний сервер або інтеграція з існуючим (CoW Orderbook API).
| Компонент | Технологія | Складність |
|---|---|---|
| Order structure | EIP-712 + Solidity | Середня |
| Settlement | Solidity + Permit2 | Висока |
| Nonce management | Bit-packed mapping | Середня |
| Solver logic | Node.js + 1inch/Jupiter API | Висока |
| Orderbook | REST API + WebSocket | Середня |
| Frontend | wagmi + viem + React | Середня |
Процес роботи
Аналітика (3-5 днів). Вибір моделі (batch auction vs first-solver), цільові токени та ланцюги, вимоги до solver network (відкрита чи дозволена), інтеграція з існуючими джерелами ліквідності.
Проектування (5-7 днів). EIP-712 схема ордера, механізм nonce, архітектура settlement контракту, механізм винагороди solver.
Розробка (6-10 тижнів). Settlement контракт → Permit2 інтеграція → off-chain orderbook → базовий solver → frontend. Кожен компонент тестується незалежно.
Аудит. Settlement контракт керує користувацькими коштами напрямку. Зовнішній аудит обов'язковий. Особлива увага: EIP-712 signature malleability, reentrancy у fill, коректність nonce invalidation.
Орієнтири за часовими рамками
MVP з базовим settlement та одним solver — 4-6 тижнів. Production-ready протокол з batch аукціоном, відкритою solver мережею та оптимізацією газу — 2-3 місяці.
Вартість розраховується після визначення моделі та scope.







