Back to Blog

Анализ инцидента безопасности Array Finance

Code Auditing
July 19, 2021
5 min read

18 июля наша система DeFiRanger сообщила о нескольких подозрительных транзакциях. После ручного анализа мы подтвердили, что эти транзакции являются атаками на Array Finance. Далее мы будем использовать одну атакующую транзакцию, чтобы проиллюстрировать процесс атаки и первопричину уязвимости.

Атакующая транзакция

Атакующая транзакция, используемая в этом блоге: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

Ход атаки

Рисунок 1
Рисунок 1

Как показано на Рисунке 1, мы обнаружили, что атакующий получил прибыль в размере 186,62 WETH (в этом блоге мы не будем явно различать WETH и ETH) после получения флэш-займа от AAVE.

Рисунок 2
Рисунок 2

Подробный процесс атаки показан на Рисунке 2.

  • Сначала атакующий вызвал функцию buy контракта Array Finance. Атакующий получил 430 токенов ARRAY, выпущенных Array Finance, используя 45,91 WETH.
  • Затем атакующий пять раз вызвал функцию joinPool контракта с закрытым исходным кодом (Array Collater - 0xa800cda5). Он/она внёс 676 410,58 DAI + 679 080,46 USDC + 901,82 WETH + 20 WBTC + 20 renBTC и получил 726,38 токенов aBPT, выпущенных Array Collater.
  • Атакующий вызвал функцию sell, чтобы сжечь 430 токенов ARRAY, и получил 77,17 токенов aBPT.
  • Наконец, атакующий вызвал функцию exitPool контракта Array Collater. Он/она сжёг 804,55 токенов aBPT, полученных на предыдущих двух шагах, и получил 748 271,55 DAI + 751 225,08 USDC + 997,62 WETH + 22,63 WBTC + 22,74 renBTC.

Из Рисунка 2 видно, что атакующий получает прибыль на шаге 5 (Рисунок 2: Вызов функции sell). Это происходит потому, что полученные 77,17 токенов aBPT более ценны, чем 49,9142 WETH, депонированных на шаге 3 (Рисунок 2: Вызов функции buy). Далее мы проанализируем код, чтобы понять, почему возможна эта атака.

Уязвимость в коде

Следующий код показывает функцию sell контракта Array Finance. В этой функции Array Finance использует баланс токена ARRAY, принадлежащего атакующему, и вызывает внутреннюю функцию _sell для расчёта количества токенов aBPT, которые можно получить, продав токен ARRAY.

Далее представлена реализация функции _sell. Она вызывает функцию calculateLPtokensGivenArrayTokens, чтобы получить количество токенов aBPT, которые можно получить за определённое количество токенов ARRAY. Затем эта функция сжигает токен ARRAY и возвращает токен aBPT.

Далее показана реализация функции calculateLPtokensGivenArrayTokens.

Обратите внимание, что есть четыре аргумента, которые могут влиять на расчёт amountLPToken. После изучения saleTargetAmount мы предполагаем, что формула следующая:

arraySmartPool.totalSupply() * (1 - (1 - amount / ARRAY.totalSupply()) ^ (1000000 / reseveRatio))
 

arraySmartPool — это адрес смарт-контракта Array Collater (0xa800cda5f3416a6fb64ef93d84d6298a685d190d). Значение arraySmartPool.totalSupply() увеличивается, когда атакующий вносит средства, заимствованные с помощью флэш-займа, в Array Collater (показано в следующей таблице).

TxnIndex: 64 arraySmartPool.totalSupply():  110162296218708026400
TxnIndex: 107 arraySmartPool.totalSupply():  165243444328062039600
TxnIndex: 150 arraySmartPool.totalSupply():  247865166492093059400
TxnIndex: 193 arraySmartPool.totalSupply():  371797749738139589100
TxnIndex: 236 arraySmartPool.totalSupply():  557696624607209383650
TxnIndex: 280 arraySmartPool.totalSupply():  836544936910814075475

Мы можем подтвердить эту логику после изучения кода arraySmartPool. Ниже показана функция joinPool контракта arraySmartPool.

Эта функция сначала вызывает функцию SmartPoolManager.joinPool для расчёта количества токенов (actualAmountsIn), которые нужно получить от msg.sender. Затем для каждого токена она вызывает функцию _pullUnderlying, чтобы депонировать токен в arraySmartPool. Наконец, она вызывает _mintPoolShare и _pushPoolShare для выпуска токена aBPT и передачи выпущенного токена aBPT msg.sender.

Обратите внимание, что arraySmartPool наследуется от PCToken. Функция _mintPoolShare вызывает функцию _mint, которая показана ниже.

Функция _mint увеличивает переменную varTotalSupply, которая напрямую возвращается функцией totalSupply(). Таким образом, это значение увеличивается при каждом вызове joinPool.

Оценка прибыли

Адрес атакующего Атакующая транзакция Прибыль (ETH)
0x1337 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa 186.62073907323577
0x1b4fb735b51a25b280499710d02f50e4f772949664f9eb088e9d968b41ca2a1c 59.338842936817095
0x356ae8a278754551d9d2ae7dc0ea876b37c342ff2d010bee14aa253bb0b6030b 18.827787420260467
0x388fd59eab65b6034c96c01a21197eb2889d6507f84ff07e553749c541563962 5.880854505948256
0xf4227ca3c8e8b5c8a0b10f034c6dee6556788c618e4cd289dc343b3247e85add 0.4327422187881
Всего 271.1009661550497
0x80d2 0xf061f8fc19c894ec37310ff59977ec97de55fd1494f1b1e66ae89188552d5c60 1.8414029470248867
Всего 1.8414029470248867
Всего 272.9423691020746

Резюме

В итоге, атакующий использует уязвимость, заключающуюся в том, что ценовой механизм Array Finance зависит от totalSupply токена aBPT, который можно манипулировать. Эта уязвимость обсуждается в нашей исследовательской статье DeFiRanger: Detecting Price Manipulation Attacks on DeFi Applications.

Благодарности

Junjie Fei, Yufeng Hu, Ziling Lin, Siwei Wu, Lei Wu, Yajin Zhou @BlockSec

(В алфавитном порядке по фамилии)

О компании BlockSec

BlockSec — новаторская компания в сфере блокчейн-безопасности, основанная в 2021 году группой всемирно известных экспертов по безопасности. Компания стремится повышать безопасность и удобство использования для развивающегося мира Web3, чтобы способствовать его массовому внедрению. Для этого BlockSec предоставляет услуги по аудиту безопасности смарт-контрактов и EVM-цепочек, платформу Phalcon для разработки в области безопасности и проактивного блокирования угроз, платформу MetaSleuth для отслеживания и расследования движения средств, а также расширение MetaDock для разработчиков web3, позволяющее эффективно работать в криптомире.

На сегодняшний день компания обслужила более 300 уважаемых клиентов, таких как MetaMask, Uniswap Foundation, Compound, Forta и PancakeSwap, и привлекла десятки миллионов долларов США в рамках двух раундов финансирования от ведущих инвесторов, включая Matrix Partners, Vitalbridge Capital и Fenbushi Capital.

Официальный сайт: https://blocksec.com/

Официальный аккаунт в Twitter: https://twitter.com/BlockSecTeam

Sign up for the latest updates
Мост Harmony Cross-Shard ONE Mint + потеря ключей на ~$47М | BlockSec
Security Insights

Мост Harmony Cross-Shard ONE Mint + потеря ключей на ~$47М | BlockSec

10-16 авг 2026: 5 инцидентов, ~$47М убытков. Анализ — уязвимость Harmony: replay чеков между шардами создал 3.01Т ONE (не учтено в убытках). $47М — кражи ключей (Whale ~$25М, Kite ~$14М, Coinsbuy ~$7.9М) и ошибка Fox (~$117K).

~$1.6M потеряно: эксплойты токена Moke и LpdFi | BlockSec Weekly
Security Insights

~$1.6M потеряно: эксплойты токена Moke и LpdFi | BlockSec Weekly

За неделю 3-9 августа 2026 года в BNB Chain произошло 2 инцидента с общими потерями ~$1,6 млн из-за манипуляций с ценами. LpdFi (~$697K): атакующий использовал резервы PancakeSwap для завышения позиции. Moke Token (~$906K): манипуляция ценой и дублирование дивидендов LP.

Инцидент с COLDCARD: когда «случайная» сид-фраза кошелька оказалась не случайной
Security Insights

Инцидент с COLDCARD: когда «случайная» сид-фраза кошелька оказалась не случайной

Ошибка в прошивке COLDCARD направляла генерацию seed на слабый программный ГСЧ, делая кошельки восстановимыми офлайн. Обновление не устраняет проблему. К 7 августа 2026 г. подтверждённые потери — 1 405 BTC (~$91 млн), оценки до 2 055 BTC.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit
Анализ инцидента безопасности Array Finance