Разработка системы маршрутизации ордеров через несколько DEX

Агрегатор 1inch показал простую идею: если ты ищешь лучшую цену только на одном DEX — ты оставляешь деньги на столе. С тех пор системы маршрутизации ордеров выросли до сложных решений с split routing, multi-hop и специализированными алгоритмами. Мы проектируем и внедряем такие системы под ключ — с н

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

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1309
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1003
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1269
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    719
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1009

Агрегатор 1inch показал простую идею: если ты ищешь лучшую цену только на одном DEX — ты оставляешь деньги на столе. С тех пор системы маршрутизации ордеров выросли до сложных решений с split routing, multi-hop и специализированными алгоритмами. Мы проектируем и внедряем такие системы под ключ — с нуля или как расширение существующей инфраструктуры.

Собственная система маршрутизации ордеров нужна, когда стандартные агрегаторы (1inch, Paraswap, 0x) не поддерживают нужный чейн; требуется интеграция кастомных протоколов; нужен контроль над источниками ликвидности; или существующие API слишком медленны для торгового бота. Наш опыт — 5+ лет в блокчейн-разработке и 30+ проектов в DeFi.

Как работает система маршрутизации ордеров через несколько DEX?

Маршрутизация — это задача поиска пути в взвешенном направленном графе. Вершины — токены. Рёбра — пулы (каждый пул создаёт два направленных ребра: A→B и B→A с ценой в данном направлении).

Для поиска лучшего пути при фиксированном amountIn — задача поиска пути с максимальным произведением обменных курсов (или эквивалентно — минимальной суммой отрицательных логарифмов). Это модификация алгоритма Беллмана-Форда или Дейкстры.

Но есть нюанс, который делает задачу сложнее: цена в пуле зависит от объёма. Для amountIn = 100 USDC лучший маршрут может быть Uniswap V3 пул 0.05%. Для amountIn = 1 000 000 USDC тот же пул даст 3% slippage, а split между несколькими пулами даст 0.3%. Это превращает задачу из поиска пути в граф с фиксированными весами в оптимизационную задачу с объёмо-зависимыми весами.

Как split routing снижает проскальзывание на крупных ордерах?

Для крупных ордеров оптимальное решение — не единый маршрут, а распределение объёма по нескольким путям. Подход через бинарный поиск оптимального split для двух маршрутов:

function findOptimalSplit( routeA: Route, routeB: Route, totalAmount: bigint, steps: number = 20 ): { splitA: bigint; splitB: bigint; totalOut: bigint } { let bestSplit = { splitA: 0n, splitB: totalAmount, totalOut: 0n } for (let i = 0; i <= steps; i++) { const fraction = i / steps const amountA = BigInt(Math.floor(Number(totalAmount) * fraction)) const amountB = totalAmount - amountA const outA = amountA > 0n ? simulateRoute(routeA, amountA) : 0n const outB = amountB > 0n ? simulateRoute(routeB, amountB) : 0n const totalOut = outA + outB if (totalOut > bestSplit.totalOut) { bestSplit = { splitA: amountA, splitB: amountB, totalOut } } } return bestSplit } 

Для N маршрутов задача становится N-мерной оптимизацией — применяют gradient descent или Nelder-Mead с ограничениями (сумма долей = 1, все доли ≥ 0).

Симуляция пулов: точность vs скорость

Uniswap V2: точная формула — разработка системы маршрутизации

function getAmountOutV2(amountIn: bigint, reserveIn: bigint, reserveOut: bigint): bigint { const amountInWithFee = amountIn * 997n const numerator = amountInWithFee * reserveOut const denominator = reserveIn * 1000n + amountInWithFee return numerator / denominator } 

Uniswap V2 Whitepaper

Uniswap V3: tick traversal

V3 требует итерации по tick bitmap для нахождения ближайших активных tick-ов. Полная симуляция точна, но медленна — несколько миллисекунд на крупный своп с traversal через множество tick-ов.

Для быстрой оценки (при скриннинге маршрутов) используем приближение через текущий sqrtPriceX96 и liquidity без tick traversal — точно для малых объёмов, с погрешностью для крупных. Точную симуляцию запускаем только для финальных кандидатов.

Curve StableSwap: итерационная формула

Curve использует инвариант A * n^n * sum(x_i) + D = A * D * n^n + D^(n+1) / (n^n * prod(x_i)). Расчёт amountOut — итерационный (Newton's method). Для JavaScript/TypeScript — BigInt арифметика с 18-decimal precision.

Balancer WeightedPool

Balancer с весовыми пулами (например, 80/20 BAL/ETH) использует другой инвариант. getAmountOut зависит от весов токенов в пуле — более сложная формула, чем V2.

On-chain vs off-chain маршрутизация

Маршрутизация может происходить полностью on-chain (смарт-контракт находит маршрут прямо в транзакции) или off-chain (вычисления вне чейна, результат передаётся в контракт).

On-chain маршрутизация: полная прозрачность, невозможность манипуляции со стороны aggregator-а. Проблема: ограниченный gas, нельзя перебрать все маршруты. Применяется для простых случаев (2–3 пула maximum).

Off-chain маршрутизация (подход 1inch, Paraswap): вычисления в backend, контракту передаётся готовый маршрут. Контракт только исполняет. Gas эффективнее, маршрут сложнее. Риск: backend может вернуть субоптимальный маршрут. Защита через slippage protection: minAmountOut в транзакции гарантирует пользователю минимум.

Как устроен router контракт?

Контракт должен поддерживать гетерогенные маршруты: часть через Uniswap V2, часть через V3, часть через Curve.

struct SwapStep { address pool; address tokenIn; address tokenOut; uint24 fee; // Для V3 uint8 dexType; // 0=V2, 1=V3, 2=Curve, 3=Balancer bytes extraData; // Дополнительные параметры под тип DEX } function multiSwap( SwapStep[] calldata steps, uint256 amountIn, uint256 minAmountOut, address recipient ) external returns (uint256 amountOut) { IERC20(steps[0].tokenIn).transferFrom(msg.sender, address(this), amountIn); uint256 currentAmount = amountIn; for (uint256 i = 0; i < steps.length; i++) { currentAmount = _executeStep(steps[i], currentAmount); } require(currentAmount >= minAmountOut, "Slippage exceeded"); IERC20(steps[steps.length-1].tokenOut).transfer(recipient, currentAmount); return currentAmount; } 

_executeStep диспатчит к конкретной DEX-реализации по dexType. Каждая реализация — отдельная библиотека (Solidity library pattern) для экономии bytecode size.

Почему кэш пулов критичен для скорости?

Для быстрой маршрутизации без RPC-вызовов на каждый запрос нужен кэш актуального состояния пулов: WebSocket subscriptions на события Sync (V2 пулы) и Swap (V3 пулы) через eth_subscribe("logs"). При каждом событии обновляем reserves/sqrtPrice в памяти.

Для 500–1000 активных пулов это ~50–100 событий/блок на Ethereum mainnet. Обработка через event-driven архитектуру (Node.js EventEmitter или Rust tokio channel) с ≤1ms задержкой обновления.

Cold start: при запуске сервиса нужно загрузить текущее состояние всех пулов через multicall. Для 1000 пулов — 5–10 multicall транзакций (до 200 calls каждый), занимает 1–3 секунды.

Сравнение архитектурных подходов

Подход Когда подходит Сложность Latency
Простой multi-hop 3–5 чейнов, топ-5 DEX Низкая 200–500ms
Split routing Крупные ордера ($50K+) Средняя 500ms–1s
С кэшем пулов Торговый бот, < 50ms Высокая 10–50ms
On-chain router Максимальная прозрачность Средняя 1 блок

Ориентировочные сроки разработки

Этап Время
Аналитика (список DEX, требования к latency) 1–2 дня
Разработка routing engine (граф, алгоритм, симуляция) 5–7 дней
Router контракт (multi-step, fork-тесты) 3–5 дней
Кэш пулов (WebSocket + in-memory) 3–5 дней
Интеграция, тестирование, документация 2–3 дня

Этапы разработки в виде пошаговой инструкции

  1. Анализ пулов и графа ликвидности — составляем карту токенов и пулов для ваших чейнов.
  2. Разработка алгоритма поиска пути — реализация модифицированного Дейкстры с учётом объёмной зависимости.
  3. Интеграция симуляций — пишем симуляторы для Uniswap V2/V3, Curve, Balancer.
  4. Тестирование на mainnet fork — прогоняем ордера разных объёмов, сверяем с эталоном.
  5. Развёртывание и мониторинг — запуск в тестовой сети и mainnet, настройка алертов.

Что входит в работу

  • Архитектурная документация: описание графа пулов, схема кэширования, спецификация контракта.
  • Routing engine: реализация поиска пути и split routing с поддержкой V2/V3/Curve/Balancer.
  • Router контракт: multi-step исполнение с защитой от slippage.
  • Кэш пулов (опционально): WebSocket подписки + in-memory хранилище.
  • Тестирование: fork-тесты Foundry, фаззинг Echidna.
  • Интеграция: развёртывание в тестовой сети и mainnet, настройка мониторинга.
  • Обучение команды: внутренняя документация, code review.

Закажите консультацию — пришлём технико-коммерческое предложение через 1 день после брифа. Получите детальный анализ вашей текущей инфраструктуры и рекомендации по оптимизации маршрутизации. Свяжитесь с нами, чтобы обсудить ваш проект.