Разработка системы batch-аукционов (CoW-стиль)
CoW Protocol решил задачу, которую AMM не решает: когда пользователь A хочет продать ETH за USDC, а пользователь B хочет продать USDC за ETH — зачем идти в пул и платить LP fees, если можно совместить ордера напрямую? Coincidence of Wants (CoW) — это прямой settlement без AMM hop. Batch auction — механизм, который агрегирует ордера за период времени и находит оптимальное исполнение. Реализовать такую систему сложнее, чем AMM, но механика защищает пользователей от front-running и MEV sandwich.
Как работает batch auction: механика изнутри
Batch период и uniform clearing price
Каждые N секунд (в CoW Protocol — ~30 секунд) закрывается batch. Все ордера, поданные в течение этого периода, исполняются по единой clearing price — одна цена для всех ордеров в batch.
Это принципиально отличается от continuous trading: нельзя front-run конкретный ордер, если все ордера исполняются одновременно по одной цене. MEV sandwich невозможен — нет до/после конкретной транзакции, есть единый момент settlement.
Uniform clearing price определяется как цена, максимизирующая торговый объём: максимальное количество ордеров на продажу и покупку, которые можно совместить при заданной цене.
Solver архитектура
Нахождение оптимального clearing price и маршрутизации — NP-hard задача при большом количестве ордеров. CoW Protocol решает это через открытую конкуренцию solver'ов: любой может запустить solver, который предлагает solution для текущего batch. Лучший solution (максимальный surplus для пользователей) побеждает.
Для собственной системы batch auction можно:
- Упрощённый on-chain solver — реализовать базовый алгоритм прямо в контракте. Работает для небольших batch (< 50 ордеров), ограничен gas limit.
- Off-chain solver + on-chain settlement — solver считает оффчейн, подаёт solution в контракт. Контракт верифицирует корректность (ордера исполнены по ценам не хуже лимитных) и выполняет transfers. Это подход CoW.
- Hybrid с AMM fallback — CoW matching для пересекающихся ордеров, остаток роутируется в Uniswap/Curve.
Order структура и signature
Off-chain limit order в стиле CoW: пользователь подписывает структуру (EIP-712), не платит газ за сам ордер. Settlement контракт исполняет пакет ордеров за один gas payment от solver'а.
struct Order {
address sellToken;
address buyToken;
address receiver;
uint256 sellAmount;
uint256 buyAmount; // минимальная сумма покупки (лимит)
uint32 validTo; // deadline
bytes32 appData; // metadata
uint256 feeAmount; // газ компенсация solver'у
bytes32 kind; // SELL или BUY order
bool partiallyFillable;
bytes32 sellTokenBalance; // erc20 / internal / external
bytes32 buyTokenBalance;
}
Подпись через EIP-712 + EIP-1271 (для контрактных кошельков). Settlement контракт проверяет подпись через isValidSignature при выполнении batch.
Surplus capture: как пользователи выигрывают
Если clearing price лучше, чем пользователь указал в лимит ордере — избыток (surplus) возвращается пользователю. Пример: пользователь хочет продать 1 ETH за минимум 3000 USDC. Clearing price — 3050 USDC. Пользователь получает 3050, не 3000. 50 USDC surplus.
В CoW Protocol часть surplus идёт solver'у как incentive. Это создаёт правильные стимулы: solver максимизирует user surplus, получает долю.
Реализация settlement контракта
On-chain верификация solution
Контракт получает от solver'а массив исполнений ордеров и список transfers. Верификация:
- Для каждого ордера:
executedSellAmount * buyPrice >= order.buyAmount(пользователь получил не меньше лимита) - Conservation law:
sum(sellAmounts) >= sum(buyAmounts)в базовом токене (баланс сохранён) - Подписи всех ордеров валидны
-
validToне истёк
Если верификация прошла — settlement: transfers всех токенов через GPv2SafeERC20.transfer (специальная safe обёртка CoW).
Flash accounting
CoW Protocol использует flash accounting для settlement: вместо последовательных transfers с промежуточным хранением, все балансы вычисляются как net flow. Settlement контракт должен знать только итоговые transfer суммы, не промежуточные состояния. Это снижает gas в 2-3 раза по сравнению с наивной реализацией.
Реализация: internal ledger в mapping(address token => mapping(address account => int256 balance)). Positive = должны выплатить, negative = должны принять. После всех net вычислений — финальные ERC-20 transfers только ненулевых балансов.
Стек разработки
Solidity 0.8.x для settlement контракта + OpenZeppelin для signature verification (ECDSA, EIP-1271). TypeScript для solver логики — npm пакет @cowprotocol/cow-sdk как reference. Foundry для тестирования с fuzz на корректность surplus расчётов.
Для off-chain orderbook хранения ордеров: PostgreSQL + REST API. WebSocket для real-time обновлений pending ордеров.
Процесс работы
Проектирование (3-5 дней). Order структура, solver архитектура (on-chain vs off-chain), fee модель.
Settlement контракт (2-3 недели). Order verification, flash accounting, AMM fallback интеграция.
Off-chain компоненты (1-2 недели). Orderbook API, базовый solver алгоритм, signature relay.
Тестирование (1 неделя). Fuzz тесты на solver outputs, integration тесты с Uniswap v3 fallback.
Ориентиры по срокам
Упрощённый batch auction с on-chain solver (малый объём): 2-3 недели. Полная система с off-chain solver конкуренцией и AMM fallback: 4-6 недель.







