Сфера DeFi покорила мир благодаря своим безграничным возможностям и приложениям. В этом отчёте рассматриваются несколько распространённых векторов атак DeFi и меры по их устранению, в том числе манипулирование ценовыми оракулами, повторная атака и манипулирование ковриком.
Основные тезисы
Введение
Децентрализованные финансы (DeFi) вызвали ажиотаж в криптопространстве в 2020 г. и стали самым популярным применением ведущих блокчейнов, таких как Эфириум. В отличие от традиционных финансов, в обработке транзакций всецело полагающихся на посредников, таких как банки, открытый и децентрализованный характер DeFi предложил пользователям способ осуществлять финансовые действия, такие как торговля, кредитование и т. д., без посредников – используя смарт-контракты. Общая зарезервированная стоимость (Total Value Locked, TVL) – показатель стоимости DeFi-транзакций – за год выросла в 14 раз и состоянием на июнь 2021 г. составила $57 млрд.
Тогда как DeFi становятся всё более популярными и ликвидными, их открытость также привела к частым нарушениям безопасности, таким как взломы и эксплойты, из-за чего участники каждый раз теряют средства. В 2020-21 гг. с DeFi-платформ было похищено активов примерно на $500 млн, причём темпы и суммы краж растут.
В настоящем отчёте мы рассмотрим основные векторы атак на DeFi. Вам следует знать о них и понимать, как такие атаки могут вывести из протоколов миллионы долларов.
Типы атак
Манипуляция ценовыми оракулами
Манипуляция оракулами – самая распространённая атака в DeFi-пространстве. В данном случае злоумышленники манипулируют данными о ценах активов на децентрализованных биржах (DEX), таких как Uniswap. Если подверженная манипуляции биржа используется DeFi-платформой как единственный источник цен, злоумышленники могут купить или продать определённый актив на этой платформе дешевле или дороже справедливой рыночной цены.
Поскольку для такой атаки требуется много капитала, для атаки на уязвимые контракты всё чаще используются флэш-займы, так как они позволяют любому получить доступ к огромным суммам капитала с очень низкими издержками. Например, в мае 2021 г. протокол PancakeBunny на Binance Smart Chain потерял больше 700 000 токенов BUNNY и 114 000 BNB из-за атаки с использованием флэш-займов, вследствие чего токен проекта обвалился больше чем на 95% и общие потери превысили $200 млн.
Прежде чем углубиться в подробности подобных атак, необходимо узнать кое-какие основы ценовых оракулов и децентрализованного кредитования.
Ценовой оракул
В мире DeFi ценовые оракулы – это сервисы третьих сторон, позволяющие смарт-контрактам получать данные о ценах извне их экосистемы. Многие DeFi-протоколы используют централизованные ценовые оракулы, которые получают цены непосредственно с пар активов на какой-то одной децентрализованной бирже (DEX), такой как Uniswap. Разработчики просто инструктируют смарт-контракт отправлять запрос оракулу, который выдаёт текущую стоимость токена в указанной валюте, такой как USD или ETH. Если DeFi-протокол полагается на ценовые данные единственной DEX, любые изменения ценовых данных этой DEX – будь то справедливая рыночная цена или нет – считаются смарт-контрактами протокола истинными и точными. Следовательно, если злоумышленник может манипулировать ценами активов на этой единственной DEX, во все протоколы, полагающиеся на эту DEX в качестве ценового оракула, могут поступать неточные данные о цене, что делает их уязвимыми к эксплуатации.
Что такое децентрализованное кредитование (лендинг)?
В традиционном кредитовании в случае дефолта изымается залог. Сумма, которую можно взять взаймы, зависит от справедливой рыночной стоимости залога, которая известна или оценивается кредитором.
Похожий процесс происходит в децентрализованном кредитовании, только здесь кредитор – это смарт-контракт, изолированный от внешнего мира. Чтобы получить справедливую рыночную стоимость токенов, используемых в качестве залога, смарт-контракт отправляет запрос оракулу. Если оракул выдаст искажённые данные о цене, можно получить кредит, превышающий стоимость залога, и извлечь прибыль.
Манипуляция оракулом с использованием флэш-займов
Флэш-займы – это новый тип необеспеченных займов, разработанный кредитным DeFi-протоколом AAVE и реализуемый с помощью смарт-контрактов. Необеспеченный заём – это такой, где не требуется залог. Например, когда можно взять деньги в банке, если у вас хороший кредитный рейтинг. Однако если сумма займа слишком большая, банк потребует предоставить залог, такой как дом или машина, чтобы смягчить риски.
С другой стороны, флэш-заём позволяет пользователям получить любую сумму без залога, при условии, что они смогут вернуть деньги после того, как проведут с ними какие-то действия, такие как арбитраж. В противном случае транзакция будет отменена. Благодаря низким рискам, низким издержкам и высокому возможному вознаграждению флэш-займы часто используются злоумышленниками.
Как происходит атака
Атака на кредитный DeFi-протокол с помощью флэш-займа и источника цен на основе DEX происходит в следующей последовательности:
- Берётся взаймы большая сумма токенов A у протокола, поддерживающего флэш-займы.
- Токены A обмениваются на токены B на DEX (что снижает цену токенов A и повышает цену токенов B на DEX).
- Приобретённые токены B вносятся в качестве залога в DeFi-протокол, использующий ту же DEX как единственный источник цен, и, благодаря манипуляции ценами, берётся взаймы больше токенов A, что в нормальных условиях было бы невозможно.
- Часть взятых взаймы токенов A используется, чтобы погасить изначальный флэш-заём, а с остальных токенов получается прибыль благодаря манипуляции источником цен протокола.
- Когда цены токенов A и B на DEX благодаря арбитражу возвращаются к истинным рыночным уровням, у DeFi-протокола остаётся недостаточно обеспеченная позиция (сумма долга больше, чем стоимость залога), что непосредственно вредит пользователям, обеспечивающим пул ликвидности.
Предотвращение
Из вышеприведённого примера можно увидеть, что протоколы, использующие централизованные ценовые ончейн-оракулы, такие как единственная DEX, уязвимы к эксплойтам с помощью флэш-займов. При использовании в качестве источника цен единственной ончейн-биржи данные об активе сильно ограничены, так как они отражают лишь рыночный статус одной биржи. Использование децентрализованных сетей оракулов вроде Chainlink поможет снизить риски, так как они получают данные о ценах из нескольких источников, таких как CoinGecko, BraveNewCoin и др., что даёт полный охват рынка. Так единственный флэш-заём не повлияет на данные о ценах.
Uniswap V2 также имеет ряд улучшений, касающихся поддержки оракула, устойчивого к манипуляции. Вместо хранения всех рыночных цен в блоке, ценовой оракул будет лишь измерять рыночную цену актива в начале каждого блока перед любой сделкой. Так ценой сложнее манипулировать, потому что она предварительно задана предыдущим блоком. Таким образом, злоумышленникам нужно манипулировать ценой в конце предыдущего блока и убедиться, что им удастся обойти арбитражёров, что очень сложно.
Кроме того, на основе последней цены каждого блока будет рассчитываться взвешенная по времени средняя цена (time-weighted average price, TWAP) для любого желаемого интервала. TWAP можно использовать напрямую или при необходимости как основу для скользящих средних (экспоненциальных (EMA) и простых (SMA)).
Атака повторного входа
Повторный вход, или реентерабельность, – одна из самых известных и разрушительных атак, с которыми из года в год сталкиваются разработчики смарт-контрактов. При проведении хакерами этой атаки баланс смарт-контракта может быть полностью стёрт. По определению процедура считается реентерабельной, если её «исполнение можно прервать посередине и запустить заново (осуществить повторный вход), причём оба запуска могут завершиться без каких-либо ошибок исполнения». Следовательно, это ставит смарт-контракт в «непоследовательное состояние» и ведёт к уязвимостям.
Что такое реентерабельность?
Представьте себе плохо запрограммированный банкомат, который проверяет баланс вашего счёта, только когда вы заберёте карту. Что будет, если вы будете снова и снова запрашивать снятие средств? Вы рано или поздно заберёте из банкомата все деньги, так как он не поймёт, что снимаемая сумма потенциально превышает баланс вашего счёта, пока вы не заберёте карту. Это основной механизм эксплойта реентерабельности, который использовался в известном взломе The DAO в 2016 г.
Взаимодействие между смарт-контрактами
Смарт-контракты не должны отправлять больше денег, чем в них заключено. Однако, воспользовавшись реентерабельностью, хакеры фактически могут превратить смарт-контракт в плохо запрограммированный банкомат. Прежде чем углубиться в то, как можно эксплуатировать смарт-контракты посредством реентерабельности, нужно сначала узнать кое-какие основы взаимодействия смарт-контрактов друг с другом.
Для простоты мы рассмотрим в этом разделе лишь некоторые базовые действия смарт-контракта. При разработке смарт-контрактов на языке Solidity в основном вызываются два типа функций для выполнения базовых задач:
Функции внешнего вызова позволяют контрактам взаимодействовать друг с другом и вызывать другие функции из того же или другого контракта, например:
- Запрос вывода средств из другого контракта.
- Получение эфира от других контрактов (payable).
- Перевод эфира в другие контракты (send (), transfer () и call.value ()).
Функции внутреннего вызова:
1. Внутренний аудит (т. е. проверка баланса).
Все смарт-контракты на Эфириуме по умолчанию содержат функцию fallback, которая полностью кастомизируема и которую разработчик может заменить произвольным кодом. Например, если её заменить функцией payable, смарт-контракт сможет получать эфир и функция будет выполняться каждый раз, когда это происходит. Можно запрограммировать её на запрос вывода средств из целевого контракта после получения эфира.
Представим себе контракты A и B, где A – уязвимый контракт, а B – контракт, используемый злоумышленником. Последовательность действий будет следующей:
- Контракт B запрашивает у контракта A вывод средств, вызывая функцию атаки.
- A вызывает функцию вывода (withdraw) и отправляет B 1 эфир, убедившись, что в контракте B есть больше 0 эфира.
- Перевод от A к B запускает функцию fallback.
- Функция fallback запрашивает у A ещё один вывод.
- Перевод от A к B снова запускает функцию fallback.
- Функция fallback запрашивает у A ещё один вывод… (процесс повторяется).
Поскольку реальный баланс B в контракте A не будет обновляться, пока цикл вывода не завершится, хакер может рекурсивно вызывать функцию вывода, пока контракт A не будет полностью опустошён.
Взлом The DAO
The DAO – популярный децентрализованный инвестиционный фонд на основе смарт-контрактов. В 2016 г. смарт-контракты The DAO накопили эфира на $150 млн (по тогдашнему курсу). 17 июня 2016 г. его взломали и похитили 3,6 млн эфира ($50 млн) с помощью кросс-функциональной атаки повторного входа. Ethereum Foundation выпустил критическое обновление, чтобы откатить взлом. Это привело к разделению Эфириума на Ethereum и Ethereum Classic. Для проведения атаки хакер воспользовался функцией fallback Эфириума.
Как предотвратить
Существует ряд общих способов избежать атаки повторного входа. Solidity поддерживает три способа перевода эфира между кошельками и смарт-контрактами: send (), transfer () и call.value (). Эти методы отличаются только лимитом газа при исполнении функции. Если использовать функцию send () или transfer () вместо call.value (), рекурсивные вызовы вывода не будут допущены из-за низкого лимита газа. Кроме того, чтобы избежать рекурсивного вывода, контракт должен обновлять своё внутреннее состояние (например, пользовательский баланс) перед проведением любой транзакции.
Ещё один возможный подход – добавить в белый список определённые внешние контракты, чтобы ограничить взаимодействие с неизвестными контрактами.
Rug pull
Rug pull или «раг-пулл» (букв. «кидок», «выбивание почвы из-под ног») – популярная мошенническая схема в DeFi-экосистеме, широко используемая недобросовестными разработчиками, так как это технически очень простой, но чрезвычайно прибыльный тип атаки. Rug pull – это когда недобросовестная команда внезапно удаляет все следы в соцсетях, забросив проект, и исчезает со средствами инвесторов. Например, команда может забрать всю поддержку покупок из пула ликвидности на децентрализованной бирже (DEX). Мошенники полностью контролируют протокол проекта, поэтому они могут создавать и выставлять на биржу токены без аудита и даже имеют право забирать ликвидность.
Что такое rug pull
Мошенники могут создать токен на DEX, такой как Uniswap или SushiSwap, и спарить его с ведущей криптовалютой, такой как эфир. Затем они обычно обещают розничным инвесторам, таким как «доходные фермеры», смехотворно большую годовую процентную доходность. Когда инвесторы обменяют свой эфир на новые токены и в смарт-контракте будет зарезервировано достаточно средств, разработчики могут опустошить пул ликвидности и исчезнуть со средствами. Внезапная потеря ликвидности приведёт к массовой распродаже токенов, так как их держатели захотят спасти свою прибыль.
Случай 1: Meerkat Finance
Meerkat Finance – протокол доходного фермерства на Binance Smart Chain (BSC), разработчики которого исчезли через день после запуска в марте 2021 г. с примерно 13 млн BUSD и 73 000 BNB, на общую сумму около $31 млн. После инцидента сайт Meerkat и аккаунт в Твиттере были удалены. Оказалось, что незадолго до атаки разработчики обновили контракт, присвоив себе право выводить активы из пула.
Случай 2: токен TruAmpl (TMPL)
Ещё один пример – известный rug pull TMPL, случившийся в августе 2020 г., когда создатель контракта вывел всю ликвидность, включавшую 154 ETH и 2 926 099 токенов TMPL, всего через 40 минут после начала публичной продажи токенов.
Последовательность событий можно резюмировать так:
- Мошенники (0x5d64a2b59328c1e387806ebefaebcf57a45a298e) создали контракт пула токенов TMPL (0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) на Uniswap и предоставили ликвидность в виде 150 ETH и 3 000 000 TMPL для раскрутки.
- Пользователи обменивали свои ценные токены, такие как ETH, на TMPL, увеличивая уровень участия в пуле и цену TMPL.
- Мошенники вывели ликвидность с платформы и получили прибыль с ценных токенов.
Как предотвратить
Чтобы защититься от атаки rug pull, следует изучить проект, прежде чем вкладывать в него деньги. Следует убедиться в надёжности команды, выяснив цели и изнанку проекта. В частности, можно проверить послужной список разработчиков, их следы в соцсетях, опыт и т. д. Также можно использовать блокчейн-эксплореры, такие как Etherscan, чтобы проверить число держателей токенов. Если у токенов очень мало держателей и они котируются только на децентрализованных биржах, высока вероятность мошенничества.