Почему «одобрение токена» — худшая идея в DeFi.
ERC-20 правильно стандартизировал балансы и переводы, но ошибся в самой сложной части — он так и не предоставил чистого способа для контракта реально использовать ваши токены. Простой перевод на контракт даже не сообщает ему, что что-то пришло. Поэтому к нему прикрутили горячую заплатку: approve + transferFrom.
Посмотрите, что эта заплатка навязывает вам. Чтобы позволить контракту тратить ваши токены, вы либо:
- одобряете его один раз на огромную или бесконечную сумму, и теперь он может беспрепятственно обращаться к вашему кошельку в любое время, навсегда, пока вы не вспомните отозвать это одобрение. Вы доверяете контракту, который, скорее всего, никогда не читали.
- ИЛИ одобряете точную сумму прямо перед каждой операцией, что требует второй транзакции и второй комиссии за газ на каждое действие.
Доверять незнакомцу или платить налог за каждое движение. Вот два варианта, и стандарт не предлагает ничего лучшего. Поэтому все выбирают первый вариант и кликают «бесконечно», и цепь заполняется кошельками, направленными на себя, как на заряженные пистолеты.
Не теоретически. MEV-бот JaredFromSubway только что потерял миллионы именно таким образом. Ничего не было взломано. Он выдал одобрения, гоняясь за фейковыми сделками, и кто-то использовал transferFrom, чтобы вывести средства.
Самое худшее: лучший дизайн существовал всё это время. Transfer-and-call (ERC-223, ERC-1363) перемещает точную сумму и уведомляет получателя в одной транзакции. Нет постоянного одобрения, нет дополнительной транзакции, никто не держит ключ от вашего аккаунта. Он проиграл из-за первоначального преимущества ERC-20, и теперь бесконечные одобрения стали несущей конструкцией всего DeFi. Permit, Permit2, абстракция аккаунта — каждое «исправление» — это заплата на примитиве, который никогда не должен был быть выпущен.
Мы не получили безопасный вариант. Мы получили удобный — и с тех пор платим за него.