После статей про AMM vs order book, routing, price discovery и liquidity pools полезно разобрать следующий практический слой: что именно происходит в момент, когда пользователь нажимает Swap. Не в абстрактном смысле «контракт что-то считает», а буквально по шагам: от получения quote и approval до router, calldata, исполнения в блоке и возможного revert.
Это важная тема, потому что в DEX-продукте качество определяется не только тем, какая цена нарисована на экране. Пользователь на самом деле покупает качественное исполнение:
- чтобы swap прошёл без лишних approvals и лишнего риска;
- чтобы quote не оказался красивой, но бесполезной картинкой;
- чтобы slippage guard реально защищал, а не просто стоял для галочки;
- чтобы команда могла объяснить, почему сделка прошла, ухудшилась или откатилась.
Если смотреть на инженерные обсуждения в HN и шире по продуктовой инфраструктуре, там постоянно всплывает один и тот же мотив: ценность всё чаще находится в execution path, observability и guardrails, а не только в интерфейсе. Для DEX это особенно правда.
Что именно разбираем
Сегодня разбираем:
- что происходит между нажатием кнопки Swap и реальным изменением баланса;
- зачем нужны
approve,permit,routerиminAmountOut; - как двигаются деньги между кошельком пользователя, router и пулами;
- кто платит fees, gas и hidden execution costs;
- где рождаются revert, failed swaps и плохой fill;
- как собрать похожий MVP: swap simulator, execution dashboard, policy checks и automation layer.
Главный практический вопрос статьи можно сформулировать так:
как устроить swap flow так, чтобы он был не просто рабочим, а понятным, безопасным и наблюдаемым с инженерной точки зрения?
Как это работает простыми словами
У пользователя есть токен A, и он хочет получить токен B.
Снаружи это выглядит как три поля:
- что продаём;
- что покупаем;
- сколько меняем.
Но под капотом swap почти всегда состоит из нескольких стадий:
- UI получает quote.
- Система считает expected output и price impact.
- Пользователь даёт право потратить входной токен.
- Router формирует execution path.
- Транзакция отправляется в сеть.
- Контракт последовательно проходит через один или несколько пулов.
- Проверяется итоговый
minAmountOut. - Пользователь получает выходной токен — или вся транзакция откатывается.
Если совсем упростить, DEX swap — это не «обмен одной монеты на другую», а контролируемый сценарий исполнения, в котором контракт временно получает право распоряжаться входным активом пользователя и обязан вернуть ожидаемый результат в допустимых границах риска.
Что происходит до onchain-исполнения
1. Quote
Первое, что видит пользователь, — quote.
Обычно UI или backend показывает:
- estimated output;
- exchange rate;
- price impact;
- gas estimate;
- route;
- warning по slippage или token risk.
Но quote — это ещё не сделка. Это всего лишь модель ожидаемого исполнения на текущем состоянии рынка.
Quote может устареть из-за:
- других swap в тех же пулах;
- движения рынка;
- смены маршрута;
- изменения gas;
- MEV и публичного мемпула.
Поэтому грамотный продукт не обещает пользователю «ты точно получишь именно это число», а показывает границы и условия исполнения.
2. Approval
Чтобы router мог потратить входной токен пользователя, ему обычно нужен approve.
Простая модель такая:
- токен лежит в кошельке пользователя;
- router не может сам его забрать;
- пользователь отдельно разрешает контракту потратить до определённого объёма.
То есть swap почти всегда опирается на две сущности:
- баланс;
- allowance.
Если allowance не хватает, swap не исполнится.
Почему approval — это отдельный риск
Потому что approval — это не сама сделка, а право на расходование актива.
Если пользователь дал:
- слишком большой unlimited approval;
- approval подозрительному router;
- approval не тому контракту;
то он увеличил свою поверхность риска даже без немедленного swap.
Именно поэтому в зрелом DEX-продукте полезно поддерживать:
- точечные approvals на конкретную сумму;
permit, где это возможно;- понятный UI, кому и сколько прав выдаётся;
- allowance monitoring и revoke hints.
3. Permit вместо approve
Некоторые токены и протоколы умеют permit.
Это позволяет:
- не делать отдельную approval-транзакцию заранее;
- подписать разрешение offchain;
- использовать его внутри самого swap flow.
Для пользователя это часто лучше по UX:
- меньше шагов;
- меньше шансов забыть про allowance;
- меньше лишних gas-операций.
Но для команды это требует аккуратной реализации:
- правильной валидации подписей;
- контроля deadline;
- проверки replay risk;
- корректной поддержки сетей и token-specific edge cases.
Как деньги двигаются во время swap
Возьмём типичный сценарий: пользователь меняет USDC на ETH.
Сценарий через один пул
- Пользователь подписывает транзакцию router’у.
- Router вызывает
transferFromи забираетUSDCиз кошелька пользователя. - Router передаёт
USDCв целевой пул. - Пул рассчитывает output по своей внутренней логике.
- Пул отдаёт
ETHобратно router’у или напрямую пользователю. - Router проверяет, что итог не хуже
minAmountOut. - Если условие соблюдено, swap завершается.
- Если нет — весь flow откатывается.
Сценарий через несколько пулов
Если маршрут multi-hop, картина такая:
USDC -> WETH -> ETH-like assetили другой промежуточный путь;- router прогоняет входной актив через несколько pool interactions;
- промежуточные токены могут даже не попасть в кошелёк пользователя;
- всё проходит внутри одной транзакции.
Для пользователя это выглядит как один swap. Для execution engine — это уже цепочка зависимых преобразований состояния.
Что делает router
Router — это оркестратор исполнения.
Он не обязательно сам формирует цену, но он:
- принимает параметры swap;
- знает маршрут;
- вызывает нужные пулы или adapters;
- проверяет ограничения по slippage;
- возвращает результат пользователю.
Если упростить до аналогии, router в DEX — это что-то между:
- API gateway;
- orchestrator;
- transaction builder.
Он держит логику того, как именно провести сделку через инфраструктуру ликвидности.
Зачем нужен minAmountOut
Это один из самых важных guardrail-элементов.
Когда пользователь подписывает swap, ему нужно зафиксировать не точное идеальное число, а минимально приемлемый результат.
Например:
- quote обещал 1.0 ETH;
- пользователь готов согласиться минимум на 0.992 ETH;
- если на момент включения в блок результат ниже — транзакция должна откатиться.
Это и есть minAmountOut.
Он защищает от:
- устаревшего quote;
- слишком сильного движения цены;
- sandwich и другого execution degradation;
- ошибки в route planning.
Важно: minAmountOut не делает цену хорошей. Он просто не позволяет исполнить сделку хуже заранее принятой границы.
Откуда берутся fees и hidden costs
Когда пользователь делает swap, он платит не одну абстрактную комиссию, а сразу несколько типов издержек.
1. Pool fee
Это комиссия самого пула или набора пулов.
Её получают:
- LP;
- иногда частично протокол.
2. Gas
Платится за:
- approval или permit-related path;
- вызовы router;
- взаимодействие с каждым пулом;
- вычисления в контракте.
Чем сложнее маршрут, тем выше gas.
3. Slippage
Это не отдельный fee в интерфейсе, но вполне реальная стоимость исполнения.
Пользователь платит её, когда:
- размер сделки двигает цену;
- ликвидность тонкая;
- состояние пула меняется между quote и settlement.
4. MEV / execution loss
Если маршрут публичный и заметный, часть value может быть потеряна через:
- sandwich;
- frontrun;
- ухудшение fill из-за order flow visibility.
5. Aggregator / protocol fee
Если поверх swap стоит агрегатор или другой execution layer, он может брать свою fee-компоненту.
Поэтому для пользователя полезная формула такая:
real swap cost = pool fees + gas + slippage + execution degradation + optional protocol fee
Почему swap может откатиться
Это очень практический вопрос, потому что с точки зрения продукта failed swap — одна из самых неприятных вещей.
Частые причины revert
- недостаточный allowance;
- quote устарел и итог ниже
minAmountOut; - deadline истёк;
- один из intermediate pool больше не даёт ожидаемый output;
- токен ведёт себя нестандартно;
- слишком маленький остаток ликвидности;
- policy engine запретил путь;
- транзакция попала в слишком токсичное окно исполнения.
Почему это важно не только для UX
Каждый failed swap — это сигнал про качество execution layer.
Нужно понимать:
- проблема в рынке;
- проблема в маршруте;
- проблема в allowance/UX;
- проблема в контрактной совместимости;
- проблема в risk rules.
Без нормальной телеметрии команда видит просто “swap failed”. С телеметрией команда видит конкретный класс сбоя.
Где реальные trade-offs
1. Tight slippage guard vs success rate
Чем жёстче граница minAmountOut, тем лучше защита пользователя.
Но тем выше вероятность revert, особенно на волатильном рынке.
2. Simple route vs best theoretical route
Прямой swap через один пул:
- проще;
- дешевле по gas;
- менее хрупкий.
Но не всегда лучший по цене.
Сложный route:
- может дать лучший output;
- но добавляет gas, состояние зависимостей и вероятность fail.
3. Unlimited approval vs precise approval
Unlimited approval:
- удобнее;
- меньше трения в UX.
Но:
- хуже по security posture;
- сложнее объяснить пользователю;
- выше риск при инциденте в интеграции.
4. Public mempool vs protected order flow
Публичная отправка транзакции проще и совместимее.
Но она повышает exposure к:
- MEV;
- sandwich;
- копированию намерения сделки.
5. Quote speed vs quote quality
Можно показать quote очень быстро, но на грубой модели.
Можно считать аккуратнее:
- симулировать route;
- оценивать gas;
- штрафовать risky paths.
Но это сложнее и медленнее.
Основные компоненты архитектуры swap execution-продукта
Если строить DEX helper, execution dashboard или swap-oriented MVP, архитектура обычно делится на несколько слоёв.
1. Wallet / signing layer
Отвечает за:
- подключение кошелька;
- chain detection;
- balance fetch;
- allowance fetch;
- подписи approve или permit;
- отправку транзакции.
2. Quote and simulation layer
Должен уметь:
- считать expected output;
- строить route;
- оценивать price impact;
- проверять liquidity depth;
- выдавать
minAmountOut; - отмечать risky scenarios.
3. Router / execution layer
Это onchain или hybrid-слой, который:
- получает calldata;
- вызывает нужные pools или adapters;
- проверяет deadline;
- контролирует slippage guard;
- возвращает output пользователю.
4. Indexer и state cache
Нужны для свежего состояния:
- reserves;
- pool metadata;
- fee tiers;
- recent swaps;
- token behavior flags;
- historical execution results.
Если этот слой отстаёт, quote engine начинает принимать решения по старому миру.
5. Policy / risk engine
Здесь живут правила вроде:
- max allowed slippage;
- denylist токенов;
- allowlist router/contracts;
- max hops;
- min liquidity thresholds;
- stale quote timeout;
- special handling для нестандартных ERC-20.
6. Observability и analytics
Нужно видеть:
- success rate swaps;
- failed swaps by reason;
- quoted vs realized output;
- average gas by route type;
- allowance issues;
- токсичные токены и пулы;
- аномалии в execution quality.
Реальные сценарии использования
1. Swap helper для кошелька или DEX-фронта
Самый очевидный use-case.
Нужно:
- показать quote;
- подсветить route;
- объяснить allowance;
- безопасно провести пользователя до результата.
2. Treasury execution tool
Когда проект или DAO делает конвертацию активов, важна не только цена, но и контроль исполнения:
- какой router использовать;
- какой max slippage допустим;
- когда дробить сделку;
- когда лучше отложить исполнение.
3. Execution quality dashboard
Очень полезный продукт сам по себе.
Он показывает:
- где quotes чаще всего устаревают;
- какие tokens ломают swaps;
- какие pools дают худшее фактическое исполнение;
- где allowance friction портит funnel.
4. Risk-aware automation layer
Поверх swap flow можно строить автоматизацию:
- alarms по failed swap rate;
- policy-based execution windows;
- routing disable rules;
- keeper logic для повторной попытки или эскалации оператору.
Как собрать похожий MVP
Если цель — не production-grade DEX, а рабочий prototype, разумный scope такой.
Шаг 1. Ограничить universe
Для MVP достаточно:
- одной сети;
- 5–15 ликвидных токенов;
- 1–3 router-compatible DEX;
- max 2–3 hops;
- только blue-chip активов без экзотики.
Это резко упрощает risk surface.
Шаг 2. Поднять state indexer
Минимальные таблицы:
tokensbalancesallowancespoolspool_snapshotsquotesroutesexecutionsexecution_failuresrisk_flags
Нужно хранить:
- свежие reserves;
- supported routers;
- quote history;
- фактические результаты swap;
- причины revert.
Шаг 3. Сделать quote + slippage module
MVP-логика:
- Получить balance и allowance пользователя.
- Построить candidate route.
- Рассчитать expected output.
- Добавить gas estimate.
- Вычислить рекомендованный
minAmountOut. - Проверить risk rules.
- Вернуть готовый execution plan.
Псевдоструктура:
load_wallet_state()
check_allowance()
build_route(tokenIn, tokenOut, amountIn)
simulate_output()
estimate_gas()
compute_min_amount_out(slippage_bps)
apply_policy_checks()
return execution_plan
Шаг 4. Собрать execution dashboard
Минимальный интерфейс должен показывать:
- token in / token out;
- amount;
- route;
- expected output;
minAmountOut;- gas;
- approval required или not required;
- risk warnings.
Отдельно полезен блок Why this swap may fail:
- allowance too low;
- slippage too tight;
- liquidity too thin;
- token behavior risk;
- stale quote.
Шаг 5. Добавить execution reports
После каждой попытки swap полезно логировать:
- tx hash;
- route used;
- quote time;
- expected output;
- realized output;
- gas used;
- success/failure;
- failure reason class.
Это превращает продукт из «UI с кнопкой» в инженерный инструмент.
Что можно автоматизировать поверх
Здесь как раз рождается отдельная ценность.
1. Allowance monitoring
Автоматические проверки:
- слишком широкие approvals;
- старые unused approvals;
- approvals на risky routers;
- токены без удобного permit path.
2. Failed swap alerts
Можно слать alerts, если:
- резко вырос revert rate;
- конкретный router начал ломаться;
- появился всплеск stale quotes;
- один token стабильно ведёт к failed execution.
3. Execution quality monitoring
Сравнивать:
- quoted vs realized output;
- route family vs gas;
- success rate по времени суток;
- protected order flow vs public path;
- slippage setting vs fail rate.
4. Treasury guardrails
Для автоматизированных swap-процессов полезны правила:
- не исполнять swap выше определённого price impact;
- запрещать unknown routers;
- требовать fresh quote;
- дробить объём по policy;
- эскалировать оператору при нестабильном route.
5. Anomaly detection
Можно ловить:
- необычно высокий gas на знакомом path;
- скачок failed approvals;
- токен с нестандартным поведением transfer;
- деградацию quote-to-fill ratio;
- массовые отклонения по
minAmountOut.
6. Retry / fallback logic
Для semi-automated execution layer можно добавлять:
- повторную попытку с новым quote;
- fallback router;
- более простой путь без split;
- временную заморозку risky token pair.
Как выглядит здравый roadmap
Phase 1 — visibility
- quote history;
- allowance checks;
- execution reports;
- dashboard по failed swaps.
Phase 2 — safer UX
- permit support;
- slippage recommendations;
- route explanation;
- token risk warnings.
Phase 3 — smarter execution
- path simulation;
- risk-aware route scoring;
- protected order flow options;
- fallback logic.
Phase 4 — automation layer
- treasury policies;
- alerts;
- anomaly detection;
- operator workflows;
- retry orchestration.
Главное, что стоит запомнить
Если убрать лишний шум, картина такая:
- DEX swap — это не одна магическая операция, а execution pipeline;
approveилиpermitоткрывают доступ к расходованию входного токена;routerоркестрирует движение денег через один или несколько пулов;minAmountOut— ключевой guardrail против плохого исполнения;- пользователь платит не только pool fee, но и gas, slippage и execution degradation;
- failed swap — это не просто UX-ошибка, а наблюдаемый технический сигнал;
- полезный MVP можно собрать как quote engine + allowance checks + route simulator + execution reports + dashboard;
- automation layer особенно силён вокруг allowance monitoring, failed swap alerts, execution quality и treasury guardrails.
По сути, хороший DEX-продукт строится не вокруг кнопки Swap, а вокруг управляемого и наблюдаемого исполнения сделки. Интерфейс можно повторить быстро. А вот прозрачный execution stack с нормальными risk checks, отчётностью и автоматизацией — уже нет.