DEX изнутри: кто и как двигает цену
В прошлой статье я писал хайлевелно о том, как пришёл к разработке своего арбитражного бота на Solana — с использованием ликвидности децентрализованных бирж (DEX) и реализацией атомарных мультихоп-свопов.
В комментах под статьёй было много вопросов про одно конкретное место: откуда вообще берётся цена на DEX?Почему она двигается, кто её “ставит” и почему бывает слиппедж.
В этой статье хочу копнуть чуть глубже и разобрать именно механику ценообразования в децентрализованных пулах. Без воды, максимально простыми словами и на понятных примерах.
Если захочется углубиться в математику и механику под капотом — пишите в комменты, по возможности разложу подробнее.
Для начала быстро вспомним, как работает ценообразование на CEX, а потом на контрасте разберём DEX.
Ценообразование на CEX
На CEX вроде Binance, Bybit или OKX цена формируется через ордера. Один хочет купить, другой — продать, и биржа просто сводит их заявки между собой.
- Кто-то хочет купить 1 BTC по $85,000
- Кто-то готов продать по $85,100
- Биржа просто показывает, кто сколько готов дать или взять — и сделки происходят на этих условиях
Как это выглядит визуально
Представь себе ось Y (вертикальную), где сверху — высокая цена, снизу — низкая. Это и есть наша визуализация стакана.
- Продавцы всегда хотят продать дороже, поэтому в стакане продаж:
- Покупатели, наоборот, хотят купить дешевле, поэтому в стакане покупок:
Ниже — пример, как это выглядит на практике
Как это читать?
- Я хочу купить 4 BTC (смотрим в колонку Amount BTC),
- По цене $85 700 за 1 BTC (ячейка Price USDT),
- На общую сумму $342 800 (это Total USDT — 4 × 85 700).
В итоге каждая строка в обоих стаканах — это ордера подобные тому, что мы разобрали.
Визуализация стакана
Чтобы было нагляднее, давай представим, что мы разворачиваем BUY order book вверх ногами (зеркально)
и прикладываем его снизу к нижней части SELL order book.
Так мы получим классическую картинку со спредом посередине — и будет видно, как цена покупки и продажи сходятся.
Это всё складывается в ордербук — таблицу, где сверху стакан продавцов, снизу стакан покупателей. Они не совпадают идеально, между ними есть небольшой зазор — это называется спред.
Пример:
Ты заходишь на Binance, хочешь купить 1 SOL.
- В ордербуке пишут, что ближайший продавец готов отдать по $145.
- Ты жмёшь “купить по рынку” — биржа забирает этот ордер у продавца, и ты получаешь SOL по $145.
- А цена последней сделки (эта $145) становится “текущей рыночной ценой”.
Цена на CEX постоянно меняется — не потому что кто-то “рисует” цену, а потому что люди размещают ордера: кто-то продал, кто-то купил, и вот уже новая цена. Это как аукцион — сколько готовы дать, столько и будет стоить.
Биржа сама цену не устанавливает — она просто сводит заявки между участниками.
Как формируется цена на DEX: Order Book vs AMM 💥
В отличие от централизованных бирж, где цена формируется через ордера (один хочет купить, другой продать — биржа их сводит), на децентрализованных биржах (DEX) всё работает по-другому — через пулы ликвидности.
Пул ликвидности — это смарт-контракт, в котором лежат две монеты, например SOL и USDC.
Любой может прийти и обменять одну на другую — по тому курсу, который получается из текущего баланса токенов в этом пуле.
Какие вообще есть механики?
Если упростить до самого базового уровня, то под капотом почти всех DEX можно выделить две основные модели ценообразования:
1. Order Book (Ордера)
Пример: OpenBook (ранее Serum)
- Цена формируется через лимитные заявки (ордера)
- Есть покупатели и продавцы, каждый ставит свою цену
- Смарт-контракт сводит ордера, как обычная биржа
- Очень похоже на CEX, только всё в ончейне
2. AMM (Automated Market Maker)
А вот тут уже интереснее. Вместо ордеров — просто баланс токенов в пуле, и формула, по которой считается цена.
Сюда относятся разные вариации:
- CPMM (Constant Product Market Maker)
- CLMM (Concentrated Liquidity Market Maker)
- DLMM (Dynamic Liquidity Market Maker)
AMM (Automated Market Maker) 💥
В основе этой модели лежит простая, но мощная формула:
X * Y = K
- X — количество одного токена в пуле (например, SOL)
- Y — количество второго токена в пуле (например, USDC)
- K — постоянное значение произведения изначального количества SOL * USDC (оно сохраняется при каждом свопе)
Как работает обмен
Допустим, ты хочешь обменять SOL → USDC.
- Ты добавляешь немного SOL в пул — то есть X увеличивается.
- Чтобы K осталась постоянной, Y (кол-во USDC) должно уменьшиться.
- Ты получаешь эти USDC — по новому, менее выгодному курсу, потому что ты нарушил баланс пула.
Чем больше ты меняешь — тем сильнее нарушается баланс, тем хуже курс.
Пример 1 — маленький свап
Это означает, что K = 1000 * 100000 = 100,000,000
Ты хочешь обменять 1 SOL на USDC.
После обмена в пуле станет X = 1001.
Чтобы сохранить K, считаем новое Y:
Y = K / X = 100,000,000 / 1001 ≈ 99 900.1
Эффективный курс ≈ 1 SOL = 99.9 USDC
(вместо ровно 100 — есть маленький слиппедж)
Пример 2 — крупный свап (и сильный слиппедж)
Y = 100,000,000 / 1100 ≈ 90 909.1
Эффективный курс ≈ 1 SOL = 90.91 USDC
💥 Разница колоссальная: ты потерял почти 9% только из-за объёма — именно это и называется проскальзывание.
Практический пример на Meteora Devnet 💥
Чтобы показать, как всё работает на практике, я создал тестовый пул на девнете и покажу, как делается расчёт и насколько он совпадает с реальностью.
Я сам себе сминтил два тестовых токена, которые буду использовать в качестве парных активов в пуле.
Создаём пул
Для эксперимента я создал пул с ликвидностью по 100 токенов каждого типа — токен X и токен Y.
- Base Token (2no) - будем называть его токен X
- Quote Token (BaS) - соответственно, токен Y
- Initial Price - поставил 1, то есть 1 токен X = 1 токен Y.Это почти никогда не бывает так в реальности, но для примера — самое то.
- Base Fee - комиссия за своп, дефолт 10% на девнете
Делаем первый своп: меняем 10 X на Y 💥
Вспоминаем старую-добрую формулу AMM:
X * Y = K — должна оставаться постоянной
Без учёта комиссии:
Xnew = 100 + 10 = 110
Ynew = K / Xnew = 10,000 / 110 ≈ 90.91
AmountOut = Y - Ynew = 100 - 90.91 ≈ 9.09
🔸 То есть получаешь почти 9.1 токена Y, если бы не было комиссии вообще.
Учитываем комиссию 10%
По умолчанию в большинстве AMM комиссия берётся с входа.
В нашем случае: 10% с 10 X → 1 X в комиссию
10 * 0.9 = 9 X
Xnew = 100 + 9 = 109
Ynew = 10,000 / 109 ≈ 91.74
AmountOut = 100 - 91.74 = 8.26
🔺 Итого: ты получил 8.26 Y вместо 9.09.
Эта разница и есть “стоимость” комиссии в цифрах.
Важно:
Это не универсальное поведение — в разных DEX/пуловах логика бывает разной:
- В ExactIn комиссия снимается с входа (как у нас)
- В ExactOut — с выхода
- А иногда комиссия прибавляется сверх суммы свапа
- какая модель свапа используется (ExactIn, ExactOut, hybrid),
- и как реализована комиссия в конкретной DEX.
Что произошло с пулом после свопа?
Ты внёс X, пул получил больше X, но меньше Y → курс X упал, а Y подорожал.
Делаем второй своп — снова 10 X на Y 💥
После первого обмена баланс токенов в пуле уже изменился. Теперь повторим тот же свап — ещё 10 токенов X — и посмотрим, как изменится результат.
Исходные данные после первого свопа:
Сразу учитываем комиссию 10%
10 X → минус 10% комиссии → до пула доходит 9 X
Xnew = 109 + 9 = 118
Ynew = 10,000 / 118 ≈ 84.74
AmountOut = 91.74 - 84.74 = 7
🔻 Получаем только 7 токенов Y — меньше, чем в первом свопе.
Сравниваем с первым свопом
То есть за ту же сумму ты получил меньше.
И суммарно за 20X мы получили 15,25 Y
Почему так?
Потому что соотношение токенов в пуле изменилось, и цена токена X по отношению к Y стала ниже.
То есть твой X теперь “весит меньше”, чем в начале.
- Чем больше ликвидность в пуле — тем меньше ты влияешь на цену.
- Чем больше объём твоего свапа — тем сильнее цена уходит и больше слиппедж.
Как это выглядит визуально
Текущая цена в UI — это просто соотношение токенов в пуле, а не та цена, по которой произойдёт следующий свап.
Настоящая цена свапа рассчитывается в момент обмена, по формуле, с учётом:
Вывод 💥
- Формула X * Y = K — простая, но она не про фиксированные курсы.
- Любой обмен влияет на цену.
- Именно из-за этого возникает арбитраж между пулами: если в одном цена сильно сдвинулась, а в другом — ещё нет, то тут и появляется арбитражная возможность.
- Чем больше объём свопа — тем хуже курс.
- Лучше 1 своп на сумму X, чем 2 свопа по 0.5X.
- Если текущая цена в пуле, например 1.5, то это не значит что при обмене 10 USDT, ты получишь 15 SPL. Потому что эффективная цена и реальный выход считается через формулу X * Y = K каждый раз при каждом свопе.
- Соответственно, чем больше ликвидности в пуле (K) , тем объёмней свопы ты можешь делать без значимого влияния на цену.