Строительные блоки: токены, AMM и пулы ликвидности

Как программа меняет один токен на другой без стакана заявок — и откуда берётся цена.

AMM (Automated Market Maker) — алгоритмическая биржа, где цену задаёт математическая формула на основе запасов токенов в пуле, а не встречные заявки покупателей и продавцов.

Токен как баланс в таблице

Токен ERC-20 — это не «монета», а запись в смарт-контракте: внутренний mapping(address => uint256), который хранит, сколько токенов у каждого адреса. Перевод — это уменьшение одной строки и увеличение другой. Понимание этого важно для безопасности: «деньги» здесь — просто число в storage, и тот, кто может его изменить, контролирует средства.

contract Token {
    mapping(address => uint256) public balanceOf;

    function transfer(address to, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "not enough");
        balanceOf[msg.sender] -= amount;
        balanceOf[to]        += amount;
        return true;
    }
}

Пул ликвидности и формула x*y=k

В классическом AMM (Uniswap v2) пул держит два токена — скажем, X и Y. Биржа поддерживает инвариант x · y = k: произведение запасов постоянно. Когда вы покупаете токен Y за токен X, вы добавляете X в пул и забираете Y так, чтобы произведение осталось прежним. Цена определяется соотношением запасов: чем меньше Y осталось, тем он дороже.

Смоделируем сделку на чистом Python (без библиотек):

x = 1000.0   # запас токена X в пуле
y = 1000.0   # запас токена Y
k = x * y    # инвариант

dx = 100.0   # вносим 100 X
# новый x, из инварианта находим новый y:
new_x = x + dx
new_y = k / new_x
dy = y - new_y   # сколько Y получим

print("Получено Y:", round(dy, 4))
print("Эффективная цена за 1 Y:", round(dx / dy, 4))
print("Инвариант сохранён:", round(new_x * new_y, 2))

Вывод:

Получено Y: 90.9091
Эффективная цена за 1 Y: 1.1
Инвариант сохранён: 1000000.0

Как работает под капотом: проскальзывание

Обратите внимание: за 100 X мы получили не 100 Y, а ~90.9. Это проскальзывание (slippage) — чем крупнее сделка относительно пула, тем сильнее она двигает цену против вас. Это не баг, а свойство формулы, и оно станет ключевым, когда мы дойдём до манипуляции ценой через большие сделки.

Поставщики ликвидности (LP) вносят оба токена в пул и получают долю комиссий с каждого обмена. Но они несут непостоянные потери (impermanent loss): если цена сильно меняется, выгоднее было бы просто держать токены.

Частые ошибки

  • Считать цену AMM «истинной». Цена в пуле — это лишь отражение его запасов, и крупный игрок может её временно сдвинуть. Брать её напрямую как оракул — классическая уязвимость.
  • Игнорировать slippage в коде интеграции. Без проверки минимального выхода пользователь получит меньше, чем ждал.

Итоги

  • Токен ERC-20 — это mapping баланса в контракте; «деньги» = число в storage.
  • AMM задаёт цену формулой x·y=k, без стакана заявок.
  • Проскальзывание — встроенное свойство: крупная сделка двигает цену.
  • Цена в пуле управляема и не должна слепо использоваться как источник истины.
Проверьте себя
1. Что хранит токен ERC-20 «под капотом»?
AФизические монеты
Bmapping адрес → баланс в смарт-контракте
CЗаписи в банке
DФайлы на диске пользователя
2. Какой инвариант поддерживает классический AMM (Uniswap v2)?
Ax + y = k
Bx * y = k
Cx / y = k
Dx − y = k
3. Почему за крупную сделку в AMM вы получаете заметно меньше «по номиналу»?
AИз-за налога
BИз-за проскальзывания: сделка двигает цену против вас
CИз-за задержки сети
DИз-за комиссии валидатора