Back to Blog

№9: MEV-бот 0xd61492: от хищника к добыче в результате гениального эксплойта

Phalcon Security
February 21, 2024
6 min read

3 августа 2023 года MEV-бот в сети Arbitrum подвергся атаке, в результате которой было потеряно 800 000 долларов США. Первопричиной этой атаки стала недостаточная проверка пользовательского ввода.

Учитывая сложные взаимодействия между MEV-ботами и их непроверенными контрактами, становится ясно, что отсутствие открытого исходного кода не гарантирует безопасность, особенно для DeFi-протоколов.

Предыстория

MEV-бот

MEV-бот (Maximum Extractable Value Bot) предназначен для обнаружения и реализации выгодных возможностей в блокчейне. Он работает путем анализа ожидающих транзакций (то есть тех, что находятся в мемпуле) или состояний внутри сети для получения прибыли через арбитраж.

В отличие от типичных MEV-ботов, использующих фронтраннинг и сэндвич-атаки, MEV-бот, ставший целью этой атаки, был сосредоточен на выполнении таких стратегий, как треугольный арбитраж и ликвидация задолженности. Сами по себе эти боты помогают стабилизировать цены для AMM и способствуют ликвидации активов в протоколах кредитования для обеспечения бесперебойной работы, составляя важную часть здорового функционирования DeFi-экосистемы.

Флеш-кредит (Flashloan)

Флеш-кредит представляет собой уникальную инновацию в DeFi-экосистеме – форму беззалогового кредитования. Вы можете взять взаймы до миллиарда долларов через Flashloan без какого-либо обеспечения при условии, что кредит будет погашен в рамках той же транзакции. Если кредит не будет возвращен в течение этой же транзакции, она будет отменена, как будто ее никогда не существовало.

Этот механизм обычно используется для арбитража или использования других DeFi-стратегий для извлечения выгоды из временных рыночных неэффективностей.

Уязвимость

Краткая версия

Недостаточная проверка параметров пользовательского ввода позволила злоумышленнику внедрить FakeFlashloanProvider. Контракт хранилища (Vault) использовал этого провайдера для инициирования флеш-кредита. Впоследствии, возможно, для погашения флеш-кредита, контракт хранилища одобрил передачу токенов FakeFlashloanProvider, что привело к несанкционированному выводу активов из хранилища.

Подробная версия

Эксплуатируемые контракты:

  • Vault: Контракт-жертва 0xd614927acfb9744441180c2525faf4cedb70207f выступает в роли «Хранилища», предоставляя резервы и обеспечивая флеш-кредиты от других протоколов, таких как AAVE и Balancer.
  • Arbitrage Bot: Уязвимый контракт 0x8db0efee6a7622cd9f46a2cf1aedc8505341a1a7, функционирующий как «Арбитражный бот», обладающий ролью заемщика в контракте «Хранилище».

Функция 0x0582f20f() в «Арбитражном боте» является основной точкой входа для запуска арбитражных сделок. Сначала она вызывает borrow() в «Хранилище» для получения первоначального капитала, а затем выполняет логику арбитража через delegatecall к внешнему контракту, указанному в calldata, без какой-либо проверки.

function 0x0582f20f(...) {
  ...
  v67, /* uint256 */ v68 = address(0xd614927acfb9744441180c2525faf4cedb70207f).borrow(address(v39), address(v9[0]), v29).gas(msg.gas);
  ...
  // 0x4da91757 = swap(address,address,address,uint256,uint256,uint256,address)
  MEM[MEM[64] + 32] = uint224(address(MEM[0 + v4[v69]])) | 0x4da9175700000000000000000000000000000000000000000000000000000000;
  v82 = address(v76 >> 96).delegatecall(MEM[(MEM[64]) len 228], MEM[(MEM[64]) len 0]).gas(msg.gas);
  ...
  v189 = v170.refund(0x410085df, address(v9[0]), address(v39), v68, address(v9[0]), v29, v186, 4 + MEM[64] + (varg2.length << 5) - (4 + MEM[64]) + 192).gas(msg.gas);
  ...
}

Впоследствии он вызывает 0x512b7351() в «Хранилище», запуская флеш-кредит к контракту злоумышленника FakeFlashloanProvider.

Функция 0x512b7351() требует, чтобы msg.sender находился в списке разрешенных (allowlist), но проверка была успешно обойдена предыдущим вызовом delegatecall. Это критически важный этап.

function 0x512b7351(...) public nonPayable { 
    ...
    if (_borrow[msg.sender] >= 1) {
        v0 = !_refund;
    }
    require(v0, Error('BBVault: FORBIDDEN'));
    ...
    v38 = v23.length;
    v39 = v23.data;
    _refund = keccak256(v23);
    ...
    <FakeFalshloanProvider>.flashloan(...);
    ...
}

Во время обратного вызова (callback) флеш-кредита, функция executeOperation() в «Хранилище» сначала переводит заемные активы в «Арбитражный бот» 0x8db0ef, а затем вызывает его 0x7fe3ba8b().

function executeOperation(...) {
  ...
  require(_refund == keccak256(v3.data), Error('BBVault: STATUS'));

  Token.transfer(ArbitrageBot, amountBorrowed);
  <ArbitrageBot>.call(0x7fe3ba8b...);
  
}

«Арбитражный бот», доверяя этому внешнему вызову, переводит полученные активы обратно в FakeFlashloanProvider. Однако «Хранилище» не распознает этого и все равно предоставляет одобрение (approval) на перевод средств для FakeFlashloanProvider для погашения флеш-кредита в конце выполнения executeOperation().

Процесс атаки

Транзакция атаки: 0x864c8cfb8c54d3439613e6bd0d81a5ea2c5d0ad25c9af11afd190e5ea4dcfc1f

Злоумышленник вызывает 0x0582f20f() «Арбитражного бота», который, в свою очередь, выполняет delegatecall к контракту злоумышленника.

Контракт hack_contract_2 затем вызывает функцию victim 0x512b7351(). Функция 0x512b7351() требует, чтобы msg.sender был в списке разрешенных, но эта проверка была успешно проигнорирована из-за предыдущего delegatecall.

Затем victim (жертва) вызывает контракт злоумышленника FakeFlashloanProvider, переводя все активы флеш-кредита в victim и вызывая функцию executeOperation() жертвы.

Функция 0x7fe3ba8b() «Арбитражного бота» снова выполняет delegatecall к контракту злоумышленника, в этот раз переводя все активы обратно злоумышленнику. На этом этапе активы, предоставленные провайдером флеш-кредита злоумышленника, были погашены.

Жертва («Хранилище») одобряет токены для FakeFlashloanProvider, вероятно, с намерением погасить флеш-кредит.

Злоумышленник использует это одобрение для получения прибыли, применяя transferFrom для вывода средств из хранилища жертвы.

Рекомендации по безопасности

Неоткрытый исходный код не гарантирует безопасность

Мнение о том, что закрытый и запутанный код гарантирует безопасность — это заблуждение. Этот инцидент с MEV-ботом показывает, что секретность не защищает от эксплойтов и может дать разработчикам ложное чувство защищенности.

Тщательная проверка входных данных

Крайне важно тщательно проверять все взаимодействия с контрактами и calldata, особенно при работе со стандартными интерфейсами, такими как флеш-кредиты и колбэки обмена токенов. Обеспечение целостности данных и безопасности должно быть приоритетом при проектировании и реализации контрактов.

Читайте другие статьи из этой серии:

Sign up for the latest updates
Информационный бюллетень — март 2026 г.
Security Insights

Информационный бюллетень — март 2026 г.

В марте 2026 г. в DeFi произошли 3 инцидента: взлом Resolv Protocol (~$80М), ошибка минтинга в BitcoinReserveOffering (~$2,7М) и атака на Venus Protocol (~$2,15М) из-за манипуляций рынком. Общий ущерб составил более $84,85 млн.

Отчет о преступлениях в сфере криптовалют за 2025 год: ключевые тренды и ончейн-данные
Security Insights

Отчет о преступлениях в сфере криптовалют за 2025 год: ключевые тренды и ончейн-данные

Этот 67-страничный отчет, основанный на анализе данных и блокчейн-доказательствах, раскрывает картину криптопреступности 2025 года, включая основные кейсы, структуру, особенности и актуальные тренды этой сферы.

Инцидент с Cetus №1: одна непроверенная операция привела к потере 223 млн долларов в крупнейшем DeFi-взломе 2025 года
Case Studies

Инцидент с Cetus №1: одна непроверенная операция привела к потере 223 млн долларов в крупнейшем DeFi-взломе 2025 года

22 мая 2025 г. Cetus Protocol на Sui был взломан на ~$223 млн из-за ошибки в функции checked_shlw(). Уязвимость позволила хакеру обойти проверку ликвидности, создать фиктивные позиции и вывести реальные резервы пулов через манипуляцию сдвигами битов.

Get Real-Time Protection with Phalcon Security

Audits alone are not enough. Phalcon Security detects attacks in real time and blocks threats mid-flight.

phalcon security