Разбор Uniswap V2: mint() & burn()
А теперь поговорим о функции минта, которая представлена на скрине выше.
Некоторый функционал в ней схож с функцией burn(), поэтому некоторые моменты можно посмотреть в предыдущем посте.
В пуле может быть, как бы, два состояние: без ликвидности и с ликвидность. Оба этих случая учитываются в коде (отмечены желтым маркером). В данном разборе мы коснёмся второго случая, а именно того, как рассчитывается объем минта при депозите токенов в пул.
Посмотрите на эту строку:
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
именно тут происходит вся магия. Здесь выбирается минимальное значение из двух возможных, которые будут сминчены пользователю.
Например, у нас есть 10 токенов_1 и 10 токенов_2. Если пользователь добавит 10 токенов_1 и 0 токенов_2, то он получит 0 LP токенов - (10/10, 0/10)! Или другой пример: если пользователь отправит 5% токена_1 и 10% токена_2, он получит всего 5% LP токенов!
Причина такому подсчёту проста: таким образом протокол мотивирует своих пользователей добавлять оба токена в пул, сохраняя его ратио. Зачем? Давайте разбираться.
Представим, что пул содержит в себе 10 токенов_1 и всего 1 токен_2, а также количество LP равно 1. Также допустим, что цена каждого токена 100$ (за каждый), т.е. общая стоимость пула равна 200$.
Если мы будет минтить по максимальному ратио, хакер может добавить всего 1 токен_2 (стоимостью 100$) и увеличить общую стоимость пула до 300$, т.е. увеличение на 50%. Также он получит 1 LP токен, что фактически равно 50% от общего количества LP токенов. В итоге получается, что он теперь контролирует 50% от пула стоимостью 300$, вложив всего 100$! А это вполне может считаться воровством у других поставщиков ликвидности.
Также как и в случае работы burn() функции, общее количество LP токенов и баланс пула может быть изменен прямо перед нашей транзакцией, поэтому тут также требуется писать дополнительные проверки на проскальзывание (slippage).
#unoswap #v2 #mint
Post #1029
890
- 👍 5
- 🔥 2