Uniswap V2 и децентрализованные биржи. Всё, что нужно знать (deep dive)
По результатам опроса в канале я решил написать эту статью. Хоть протокол уже довольно старый (три года в крипте равны пятнадцати в остальном мире), механизм его работы следует знать каждому. Ведь всё же когда-то это была самая популярная децентрализованная биржа с почти десятью миллиардами долларов в ликвидности. Да и сейчас именно на Uniswap v2 запускаются большинство мемкоинов (особенно с комиссиями на покупку/продажу, так как третья версия не позволяет этого делать).
Понимание работы второй версии протокола будет очень полезно для понимания третьей (Uniswap V3), о которой я тоже как-нибудь напишу статью.
В данном материале я предполагаю, что вы уже на обывательском уровне знаете, что такое децентрализованная биржа, и умеете ей пользоваться (например, менять один токен на другой). Больше никаких знаний не требуется.
Начнём разбор с небольшого введения.
Введение
Как вы уже знаете, децентрализованные биржи (DEX) в своем большинстве работают не так, как централизованные (CEX). На CEX используется так называемая книга ордеров (order book) — система создания и исполнения заявок на покупку/продажу актива по определённой цене. DEX'ы же в силу дороговизны и медленной скорости отправки ордеров в блокчейн и сохранения их там вместо этого предпринимают другой подход. Представьте, если бы вы заплатили за размещение запроса на покупку актива несколько долларов в комиссиях сети, а потом этот запрос не исполнился! Такая система никуда не годится, особенно на волатильных парах.
Поэтому придумали решение: механизм автоматизированного маркет-мейкера (automated market maker или AMM). Простыми словами, это алгоритм, рассчитывает стоимость активов относительно друг друга без необходимости иметь постоянные запросы в книге ордеров. Как это работает? В следующем, математическом, разделе я всё объясню. Не бойтесь, никаких заоблачных формул здесь не будет, а весь текст я буду подкреплять картинками, чтобы точно было понятно.
Математика Uniswap V2
Итак, Uniswap V2 работает на принципе автоматизированного маркет-мейкера (AMM). Далее в статье будем считать, что мы рассматриваем пару ETH/USDT, если явно не указано другое.
Для того, чтобы пользователи биржи могли торговать активами какой-то пары в любой момент, в протоколе должны храниться резервы этих токенов, причём сразу обоих из них. То есть в резервах должны содержаться одновременно и эфиры, и токены USDT. Такие резервы называют пулом ликвидности (или просто пулом).
Пусть, скажем, в пуле протокола хранится x эфиров и y USDT. Тогда цена одного эфира в USDT считается по волшебной формуле:
Разберём конкретный пример: пусть в резервах находится 10 эфиров и, скажем, 5000 USDT. Тогда цена одного эфира равна:
USDT. Как мы увидели, этой формулой пользоваться очень просто. Можно сделать такой вывод: текущая цена актива на Uniswap V2 зависит лишь от соотношения резервов двух активов в протоколе.
Теперь введём такую, очень важную для визуализации, формулу:
Её называют формулой постоянного произведения (constant product formula). График этой формулы выглядит так:
Это гипербола. Точнее, одна её ветка. Этот график очень полезен для дальнейшего понимания происходящего.
По горизонтальной оси X на графике происходит изменение резервов одного токена (эфира), а по вертикальной оси Y - изменение резервов другого токена (USDT). Например, вот так может выглядеть состояние резервов протокола при наличии в пуле 0.5 эфира и 2 USDT (напоминаю, что в таком случае цена равна 2/0.5=4 USDT за 1 эфир):
Как работает покупка/продажа?
Когда вы покупаете токены через Uniswap, на самом деле вы просто забираете их из пула протокола. Взамен них вы должны отправить в пул другие токены, которые вы обмениваете на эти. Причём в результате обмена новая точка состояния резервов должна оказаться снова на графике. Рассмотрим на примере покупки USDT за ETH. Визуально будет понятнее:
Перед вашей покупкой состояние резервов таково: 1 эфир и 4 USDT. Фиолетовая точка на графике обозначает это начальное состояние резервов. Покупая USDT, вы отправляете в пул эфиры. Состояние резервов переходит в оранжевую точку. Обратите внимание: количество эфиров на оси X увеличилось, так как вы отправили их в пул. Количество USDT на оси Y наоборот уменьшилось, так как вы получили их из пула.
Продажа это та же покупка, но только наоборот. В рассуждениях можно поменять ETH и USDT местами, и вот вы уже проводите продажу USDT за ETH (иными словами, покупку ETH).
Теперь мы можем понять, почему происходит "проскальзывание". Так называют ситуацию, когда в результате сделки вы получаете меньше токенов, чем должны были по текущей цене. На примере: при покупке одного эфира вы платите за него 1000 USDT, а при покупке десяти эфиров — уже не 10000, а, например, 11000. Вот эта переплата в 10% и называется проскальзыванием.
Рассмотрим такую ситуацию на графике:
Мы всё так же начинаем действие из фиолетовой точки. Состояние резервов в ней: 4 USDT и 1 ETH. В начале математической секции мы считали цену так: p=y/x=4/1=4 (USDT за один эфир). Но, как видно на графике, отправив в пул целых 5 эфиров, мы получили всего 3,31 USDT! Хотя должны были получить 5*4=20 USDT. Средняя цена сделки в таком случае составила 0.66 USDT за один эфир. В шесть раз меньше, чем было заявлено.
Если изобразить среднюю цену сделки на графике, то она оказывается равна тангенсу угла наклона прямой, проходящей через точки состояния резервов в начале обмена и после него. Это серая пунктирная прямая, проведённая через фиолетовую и оранжевую точки.
Чем больше эфира мы продаем, тем меньше USDT мы получаем за каждый из них. Например, при продаже аж 24 эфиров средняя цена продажи за каждый из них будет всего чуть более 0.15 USDT. То есть получим мы за это всего лишь 3.82 USDT.
Как мы видим, чем больше эфира мы продаём, тем менее крутой становится серая линия. И тем меньше становится тангенс угла её наклона. Следовательно, тем худшую цену за продажу эфира мы получаем. Это и есть проскальзывание.
Для борьбы с проскальзыванием существуют сервисы агрегации DEX'ов (например, 1inch), которые покупают понемногу токенов из резервов разных децентрализованных бирж, тем самым уменьшая проскальзывание.
Ликвидность
Но что же такое k в формуле постоянного произведения? Напомню, эта формула выглядит так:
Есть ещё одна формула, которая позволит нам это понять:
Здесь L - это ликвидность. Преобразованиями можем получить её удобное восприятие:
То есть ликвидностью считается среднее геометрическое значение обоих резервов в пуле. Давайте посмотрим, как изменяется график x*y=k и условия сделок при изменении ликвидности. Для начала рассмотрим ситуацию с L=1
Как видим, при продаже пяти эфиров по стартовой цене 15.84 (USDT за эфир) со значением ликвидности L=1, мы получили за это всего 3.78 USDT. Таким образом, средняя цена продажи составила всего 0.75 (USDT за эфир). В 21 раз меньше, чем стартовая цена продажи!
Теперь посмотрим на продажу тех же пяти эфиров по той же стартовой цене 15.84 (USDT за эфир), но со значением ликвидности L=3:
При таком раскладе мы получили уже 10.37 USDT со средней ценой продажи 2.07 (USDT за эфир). Это почти три раза лучше, чем в предыдущем примере.
Чтобы полностью осознать смысл ликвидности, посмотрим на случай при L=100. Масштаб графика изменился настолько сильно, что уже не почти видно, сколько эфиров мы продали:
За пять эфиров мы выручили 66.1 USDT со средней ценой продажи 13.2 (USDT за эфир). В шесть раз больше, чем при L=3.
Какой можно сделать вывод? Чем больше значение ликвидности, тем более близкую к стартовой цене (в нашем случае, 15.84 (USDT за эфир)) среднюю цену продажи мы получаем.
И тем мéньшее влияние на цену имеет любая сделка (так как она осуществляет мéньшее движение по графику гиперболы).
Вот анимация того, как на график гиперболы влияют различные значения L:
Ликвидность (резервы) пополняется за счёт поставщиков ликвидности. За это им полагается часть от комиссий, уплаченных пользователями за торги на конкретной паре. Сейчас расскажу, какие условия там предлагаются и как не потерять всё на непостоянной потере.
Поставление ликвидности и его риски
Чтобы получать комиссии с торгов пользователей, поставщик ликвидности (liquidity provider) должен внести в пул ликвидности какой-либо пары равное по стоимости количество обоих активов. Например, если 1 ETH = 1000 USDT, то он может внести одновременно 0.5 эфира и 500 USDT или 10 эфиров и 10000 USDT и так далее.
За отправку своих средств в пул ликвидности, поставщик получает так называемые LP-токены (liquidity pool tokens, токены пула ликвидности), которые представляют собой долю от всех активов пула.
Пусть, например, в пуле ликвидности было 99 эфиров и 9900 USDT (тогда цена 1 ETH = 100 USDT), и новый поставщик внёс в него 1 эфир и 100 USDT. Количество активов в пуле увеличилось до 100 ETH и 10000 USDT. За это поставщик получил 1% от всего существующего объёма LP-токенов этого пула, за которые он может в любой момент вывести из него свою часть.
Когда пользователи торгуют на Uniswap, с их сделок взимается комиссия. Эта комиссия отправляется в пул ликвидности. То есть при активных торгах количество активов в пуле увеличивается. Если, например, за год пользователи уплатили в качестве комиссий 10 эфиров и 1000 USDT, то количество активов в резервах стало 110 ETH и 11000 USDT. Тогда за свой 1% всех токенов ликвидности наш поставщик сможет вывести уже 1,1 ETH и 110 USDT (он увеличил свой портфель на 10%).
Так и зарабатывают поставщики ликвидности с уплаченных пользователями комиссий. Но может произойти неприятность.
Отмотаем время назад. В пуле 100 ETH и 10000 USDT. Пренебрегая комиссиями за торги, рассмотрим такую ситуацию: пусть цена эфира резко выросла до 120 USDT (со 100). Арбитражеры начнут скупать эфир из пула, пока не установится равновесие цены на Uniswap с текущей ценой эфира. Тогда в пуле станет примерно 91.28 ETH и 10954 USDT. Это можно проверить так: p=y/x=10954/91.28≈120 USDT за эфир и k=y*x=10954*91.28≈1000000. Формула для вычисления новых резервов активов в пуле при изменении цены (можно вывести, решив систему уравнений, указанную выше):
Здесь
x', y' — новые количества резервов x и y соответственно в пуле после изменения цены,
k=xy — постоянная произведения,
p' — новая цена.
Итак, после роста эфира до 120 USDT, в пуле стало 91.28 ETH и 10954.5 USDT. Если поставщик решит забрать свою долю в 1%, он получит 0.9128 ETH и 109.5 USDT, что равно (по текущему курсу 1 ETH = 120 USDT) всего лишь 219 USDT.
Если же поставщик воздержался бы от отправки средств в пул ликвидности, он остался бы при своих изначальных 1 ETH и 100 USDT, что по выросшему курсу равняется 220 USDT.
То есть, отправив средства в пул ликвидности, поставщик потерял 1 USDT по сравнению со стратегией простого удержания активов. Этот феномен, а точнее процент упущенной выгоды (1/220 = 0.45%) и называется непостоянной потерей (impermanent loss/divergence loss).
Конечно, если цена эфира вернётся на исходные значения (1 ETH = 100 USDT), то непостоянная потеря пропадёт.
Как мы видим, непостоянная потеря сама по себе не является "потерей" в прямом смысле этого слова. Мы ничего не теряем, просто получаем меньше, чем если бы придерживались стратегии удержания активов.
Из формул выше можно вывести формулу подсчёта непостоянной потери:
Где x — изменение цены от изначальных значений (количество "иксов" цены). Например, при росте цены на 100%, x=2 ("2 икса").
Вот значения IL(x) для различных иксов:
- Изменение цены в 1,25 раза приводит к потере в 0,6% по сравнению с простым удержанием активов (aka HODL)
- Изменение цены в 1,50 раза приводит к потере в 2,0% по сравнению с HODL
- Изменение цены в 1,75 раза приводит к потере в 3,8% по сравнению с HODL
- Изменение цены в 2 раза приводит к потере в 5,7% по сравнению с HODL
- Изменение цены в 3 раза приводит к потере в 13,4% по сравнению с HODL
- Изменение цены в 4 раза приводит к потере в 20,0% по сравнению с HODL
- Изменение цены в 5 раз приводит к потере в 25,5% по сравнению с HODL
Это можно удобно визуализировать на графике:
Здесь ось X представляет собой изменение отношения цен с момента поставки ликвидности (100% означает исходную цену при поставке ликвидности). Ось Y показывает изменение стоимости позиции.
Стоит заметить, что impermanent loss работает одинаково в обе стороны изменения цены. То есть независимо от того, произошёл ли, например, рост в два раза или падение в два раза. Непостоянная потеря в обоих случаях будет равна IL(2)=IL(1/2)=-5.7% Говоря более формально, IL(x)=IL(1/x) для всех x.
Также важно то, что, например, на парах стейблкоинов (если считать, что они придерживаются стабильного курса 1 к 1), нет непостоянных потерь.
"Убытки" за счёт непостоянных потерь могут перекрываться прибылью от комиссий. Точнее говоря, чтобы получить прибыль от поставки ликвидности, вы должны быть уверены в том, что так и будет.
Как защититься от непостоянных потерь
Как мы уже поняли, непостоянные потери появляются при поставке ликвидности на парах, в которых активы очень волатильны друг относительно друга. Поэтому чтобы избежать непостоянных потерь, можно, например, поставлять ликвидность в пары между стейблкоинами или между другими активами, цены которых сильно коррелируют. Но из-за того, что это низкорисковая стратегия, на ней выходит маленький заработок (~2.75% APY на паре USDT/USDC). Здесь также нужно учитывать возможный депег (отвязку) одного из стейблкоинов, из-за которой можно потерять чуть ли не всё. Привет, UST!
К слову, раз зашла речь об отвязках стейблкоинов, я недавно также написал статью о набравшем популярность "децентрализованном" стейблкоине Ethena USDe в своём телеграм канале. Почему "децентрализованном" в кавычках? Там всё описано! Вернёмся к Uniswap v2.
Очень важная вещь, которую стоит подчерпнуть из этой статьи, заключается в том, что поставлять ликвидность на малоизвестные и волатильные токены очень рискованно. Если такой токен соскамится (упадёт до нуля), то из-за непостоянной потери вы потеряете весь не только его, но и почти весь второй токен в паре (например, эфир).
P.S. Прочитать про более продвинутые способы вычисления прибыли с LP можно в пятом источнике ниже. С интерактивным графиком x*y=k можно поиграть во втором.
Заключение
С помощью информации в этой статье вы сможете теперь принимать более взвешенные решения, если захотите купить какой-то низколиквидный токен на Uniswap или даже поставить ликвидность в его пару.
Теперь вы обладаете знаниями о том, как работает самая популярная децентрализованная биржа изнутри и имеете отличную основу для дальнейшего изучения глубин DeFi. А делать это легко вы сможете, подписавшись на мой телеграм канал. Там будет ещё много продвинутых статей.
Источники
- Uniswap v2 Core whitepaper https://uniswap.org/whitepaper.pdf
- Desmos graphing calculator Uniswap (v2) Math https://www.desmos.com/calculator/j8eppi5vvu
- Uniswap v2 docs. Understanding liquidity provision returns https://docs.uniswap.org/contracts/v2/concepts/advanced-topics/understanding-returns
- Uniswap: A Good Deal for Liquidity Providers? https://medium.com/@pintail/uniswap-a-good-deal-for-liquidity-providers-104c0b6816f2
- Understanding Uniswap returns https://pintail.medium.com/understanding-uniswap-returns-cc593f3499ef