Анализ уязвимостей балансировщика

фон

22 августа Balancer официально объявил, что получил серьезные сообщения об уязвимостях, затрагивающих несколько пулов V2 Boost. Пострадало только 1,4% TVL. Несколько пулов были приостановлены, а пользователи были уведомлены о необходимости как можно скорее вывести ликвидность LP. [1] [2]

27 августа система SlowMist MistEye обнаружила атакующую транзакцию, предположительно использующую уязвимость Balancer. [3]

Поскольку пул не может быть приостановлен, а некоторые средства по-прежнему затронуты атакой, представители Balancer еще раз напоминают пользователям о необходимости восстановить LP в пострадавшем пуле. [4] Впоследствии Balancer официально опубликовал на Medium подробности об уязвимости, обнаруженной в августе. [5] , команда безопасности SlowMist проверила его, подробности следующие:

Введение

Представители Balancer просто указали в своем сообщении, что проблема на этот раз заключается в том, что округление линейного пула вниз и виртуальное предложение комбинируемого пула привели к тому, что bptSupply стал равным 0. Для начала давайте кратко разберемся в содержимом протокола Balancer, связанного с этой уязвимостью.

Хранилище балансировщика V2

Балансир V2 [6] Протокол представляет собой протокол децентрализованного автоматизированного маркет-мейкера (AMM), основанный на Ethereum, который представляет собой гибкий строительный блок для программируемой ликвидности. Его основным компонентом является контракт Vault, который ведет учет всех пулов и управляет учетом и передачей токенов, включая упаковку и распаковку собственного ETH. Другими словами, Vault реализован для отделения учета и управления токенами от логики пула.

В Vault имеется четыре интерфейса, а именно joinPool, exitPool, swap и patchSwap (присоединение, выход и обмен — это отдельные вызовы, и в одном вызове их комбинация невозможна). Одной из выдающихся функций является пакетный обмен, который может реализовать несколько атомарных обменов между несколькими пулами и соединить выход одного обмена пула со входом другого пула (GiveIn и GiveOut). В системе также реализованы молниеносные свопы. [7] , аналогично внутреннему флэш-кредиту.

Линейные бассейны Линейный бассейн

Чтобы повысить эффективность использования капитала LP и решить проблему высоких накладных расходов на деформацию и деформацию, Balancer запустил линейный пул в качестве решения в V2, представив таким образом токен BPT (ERC20 Balancer Pool Token).

линейный бассейн [8] Включая основной токен (базовый актив), обернутый токен (обернутый токен) и токен BPT, активы и их обернутые аналоги с доходами обмениваются по известным обменным курсам. Чем выше доля завернутых токенов, тем выше доходность и эффективность использования капитала пула. В процессе деформации обычно используются коэффициенты масштабирования, чтобы гарантировать, что разные токены рассчитываются с одинаковой точностью.

Составные пулы Составной пул

Все пулы Balancer являются составными пулами, которые содержат другие токены, а сам пул также имеет свои собственные токены. Среди них валюта BPT относится к токену сбалансированного пула ERC20, который является основой всех пулов. Пользователи могут свободно комбинировать токены BPT в других пулах для погашения. Погашение всегда включает в себя пул и два токена: GiveIn и GiveOut. In означает отправку токенов компонентов и получение BPT, а Out означает отправку BPT и получение токенов компонентов. Если бы BPT сам по себе был токеном компонента, его можно было бы обменивать, как и другие токены. Такая реализация представляет собой простой путь пакетного обмена между базовыми активами и токенами во внешнем пуле.Пользователи могут использовать BPT для обмена на базовые активы линейного пула.Это также пул Balancer Boosted. [9] Фундамент.

За счет вышеуказанной комбинации формируется комбинируемый пул Balancer. Составной стабильный пул bb-a-USD состоит из трех линейных пулов, при этом простаивающая ликвидность отправляется на внешний протокол (Aave). Например, bb-a-DAI — это линейный пул, содержащий DAI и waDAI (обернутый aDAI). Когда пользователю необходимо выполнить пакетный обмен (например, изменить USDT на DAI), пример пути обмена выглядит следующим образом:

  1. В линейном пуле USDT обменять USDT на bb-a-USDT (войти в линейный пул USDT);

  2. В bb-a-USD bb-a-USDT обменивается на bb-a-DAI (обмен между линейными BPT);

  3. В линейном пуле DAI bb-a-DAI обменивается на DAI (выход из линейного пула DAI).

После краткого понимания вышеуказанных необходимых знаний мы входим в ссылку анализа уязвимостей.

анализировать

27 августа группа безопасности SlowMist получила от системы MistEye подтверждение того, что предполагаемая уязвимость Balancer была использована в реальных условиях. торговля [3] следующее:

Злоумышленник сначала взял взаймы 300 000 долларов США у AAVE посредством срочного кредита. Затем вызывается операция BatchSwap Vault, и расчет обмена токенов BPT осуществляется через объединяемый стабильный пул bb-a-USD.Наконец, 94 508 USDC обмениваются на 59 964 bb-a-USDC, 68 201 bb-a-DAI. и 74 280 bb-a-USDT. Наконец, полученные токены BPT выйдут из пула через контракт exitPool of the Vault в обмен на базовые активы, погасят мгновенный кредит и покинут рынок с прибылью в размере примерно 108 843,7 долларов США.

Видно, что ключ к этой атаке лежит в пакетном обмене, а что именно произошло в пакетном обмене? Давайте посмотрим поближе.

В течение всего процесса пакетного обмена злоумышленник сначала выкупал USDC в пуле bb-a-USDC, а затем обменивал токены BPT, обменивая bb-a-USDC на bb-a-DAI, bb-a-USDT и USDC. Наконец, базовый основной токен USDC обменивается на bb-a-USDT. Другими словами, bb-a-USDC, как ключевой токен BPT, служит токеном компонента GiveOut и GiveIn.

На первом этапе злоумышленник обменивает токены BPT на основные токены USDC в линейном пуле bb-a-USDC с фиксированным коэффициентом масштабирования, а увеличенная сумма фиксируется в bptBalance в пуле. Но после второго обмена onSwap мы обнаружили, что значение sumOut обмениваемых USDC было равно 0 во время того же процесса обмена. Почему это?

Копнув глубже в функцию onSwap, мы обнаружим, что в этом процессе точность будет обработана до номинальной и будет рассчитан коэффициент масштабирования соответствующего токена. При следующем вызове функции _downscaleDown значение sumOut округляется в меньшую сторону. Если sumOut и scalingFactors [indexOut] Разница между значениями большая, а вычисленное значение _downscaleDown равно нулю.

То есть, когда мы используем токены BPT для выкупа основных токенов, если sumOut слишком мал, возвращаемое значение будет округлено до нуля, и это значение меньше 1e12, рассчитанное с помощью scalingFactors. Однако сумма bb-a-USDC, поступающая из sumIn, все равно будет добавлена к виртуальной сумме bptBalance, и эта операция увеличит баланс в пуле bb-a-USDC, что можно расценивать как одностороннее добавление bb -a-USDC ликвидность.

Затем, используя характеристики комбинируемого стабильного пула, посредством взаимной конвертации между токенами BPT, сначала обменяйте bb-a-USDC на другие токены BPT. Чтобы следовать этому процессу обмена, вы можете объединить следующий путь вызова стабильного пула: bb-a-DAI onSwap -> _swapGivenIn -> _onSwapGivenIn. Сначала замените bb-a-USDC на bb-a-DAI и bb- a-USDT последовательно. В отличие от онлайн-линейных пулов, составные стабильные пулы требуют обновления кэша обменного курса перед операциями onSwap. Из кода мы видим, что в пуле комбинаций onSwap сначала определит, нужно ли обновлять курс обмена кэшированных токенов.

После предыдущего обмена количество bb-a-USDC изменилось, и реальная общая сумма после номинализации через _toNominal составляет totalBalance 994 010 000 000, а виртуальный запас токенов BPT составляет 20 000 000 000. Можно подсчитать, что обновленный курс обмена почти в 45 раз превышает исходный курс обмена кэша предыдущего линейного пула, равный 1 100 443 876 587 504 549, что составляет 49 700 500 000 000 000 000.

Впоследствии bb-a-USDC обменивается на USDC в линейном пуле. Однако этот обмен аналогичен второму обмену, который снова приводит к округлению суммы Out до 0, а путь обмена такой же, как и раньше.

Следующий обмен — это обратный обмен USDC на bb-a-USDC, путь обмена — onSwap -> onSwapGivenIn -> _swapGivenMainIn. В ходе этого процесса мы обнаружили, что при расчете суммы Out, которую необходимо выкупить, расчет виртуального предложения основан на разнице между общим количеством выкупленного токена BPT и оставшейся суммой в пуле, равной 0.

Это связано с тем, что bptSupply равен 0, а функция _toNominal вызывается напрямую при расчете BPT Out, и вызов этого пути делает соотношение обмена USDC к bb-a-USDC близким к 1:1.

Подведем итог

BatchSwap соединяет выходные данные обмена одного пула с входными данными другого пула (tokenIn и tokenOut) посредством нескольких атомарных свопов между несколькими пулами и конвертирует USDC в токены BPT. При этом пакетном обмене фактической передачи токенов не происходит, но окончательная сумма обмена подтверждается путем записи суммы, переведенной внутрь и наружу. А поскольку обмен линейного пула осуществляется через токен базового актива, метод обмена заключается в расчете ставки с помощью виртуального предложения и фиксированного алгоритма. Таким образом, в пакетном обмене есть две дыры в безопасности:

Первая — это проблема округления в меньшую сторону линейных пулов: злоумышленник в одностороннем порядке добавляет в пул основные токены посредством округления, чтобы увеличить долю кэшированных токенов, тем самым манипулируя курсом обмена токенов в соответствующем составном пуле;

Во-вторых, из-за характеристик виртуального предложения комбинируемого пула, виртуальное предложение рассчитывается путем вычитания остатка в пуле из токена BPT. Если GiveIn является токеном BPT на момент погашения, эта часть будет вычтена из последующего Злоумышленнику нужно только обменять BPT на GiveIn и сначала манипулировать его запасом до 0, а затем выполнить обратный обмен, то есть BPT затем используется в качестве стороны GiveOut. В это время, поскольку запас равен 0, алгоритм будет близок к 1: коэффициент 1 ниже, чем коэффициент погашения линейного пула для фактического погашения, что приводит к косвенному манипулированию количеством токенов BPT GiveOut.

Мы можем обнаружить, что первая уязвимость увеличивает обменный курс, а вторая снижает обменный курс в обратном направлении. Злоумышленник воспользовался двойным баффом, чтобы получить прибыль и уйти.

Справочная ссылка:

[1]

[2]

[3]

[4]

[5]

[6]

[7]

[8]

[9]

Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • комментарий
  • Поделиться
комментарий
0/400
Нет комментариев
  • Закрепить