Back to Blog

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

Code Auditing
4 августа 2021 г.
4 min read

4 августа 2021 года проект Popsicle Finance понес огромные финансовые потери (более 20 млн долларов) в результате атаки [1]. После ручного анализа мы подтверждаем, что это была атака типа double-claiming («двойное получение»), то есть лазейка в системе вознаграждений позволила злоумышленнику многократно запрашивать награды. Ниже мы на примере транзакции атаки проиллюстрируем процесс атаки и основную причину уязвимости.

Предыстория

Popsicle Finance — это платформа для оптимизации доходности, поддерживающая множество хранилищ (vaults) для различных сетей (например, Ethereum и BSC).

В частности, пользователь сначала вызывает функцию deposit для предоставления ликвидности и получает токен ликвидности Popsicle (сокращенно PLP). После этого Popsicle Finance управляет ликвидностью пользователя (взаимодействуя с такими платформами, как Uniswap) для получения прибыли. Пользователь может вызвать функцию withdraw, чтобы забрать ликвидность из Popsicle Finance, которая рассчитывает сумму на основе токенов PLP. Стимулирующее вознаграждение поступает от ликвидности и накапливается с течением времени. Пользователь может вызвать функцию collectFees для получения наград, которая и является ключевым звеном этой атаки.

Анализ уязвимости

В функции collectFees для пользователя рассчитываются token0Reward и token1Reward (награды за соответствующие пары LP-токенов). Вся логика расчета проста. Однако функция использует модификатор updateVault, который применяется для соответствующего обновления наград.

Кратко говоря, updateVault выполняет следующие действия:

  1. сначала вызывает функцию _earnFees для получения накопленной комиссии из пула;
  2. затем вызывает функцию _tokenPerShare для обновления token0PerShareStored и token1PerShareStored, которые представляют собой количество токенов token0 и token1 в пуле на каждую долю;
  3. наконец, вызывает функции _fee0Earned и _fee1Earned для обновления наград пользователя (т.е. token0Rewards и token1Rewards соответственно).

Функции _fee0Earned и _fee1Earned используют одну и ту же логику, а именно реализуют следующую формулу (на примере token0):

user.token0Rewards += PLP.balanceOf(account) * (fee0PerShare - user.token0PerSharePaid) / 1e18

Обратите внимание, что расчет является инкрементальным, что означает: даже если у пользователя НЕТ токенов PLP, рассчитанная награда остается значением, сохраненным в token0Rewards.

Следовательно, мы можем сделать два вывода:

  1. награды пользователя хранятся в token0Rewards и token1Rewards, которые не привязаны ни к одному токену PLP;
  2. функция collectFees зависит только от состояния token0Rewards и token1Rewards, что означает, что награды можно вывести, не владея токенами PLP.

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

Ход атаки

Кратко, для осуществления атаки злоумышленник выполнил следующие шаги:

  1. создал три контракта. Один из них использовался для проведения атаки, в то время как два других использовались для вызова функции collectFees и получения наград;
  2. использовал Flash Loan (флэш-кредит), то есть занял большой объем ликвидности у платформы AAVE;
  3. запустил цикл Deposit-Withdraw-CollectFees для выполнения атаки (всего было 8 циклов, и из различных хранилищ Popsicle Finance было выведено большое количество ликвидности);
  4. вернул флэш-кредит обратно в AAVE и отмыл прибыль через Tornado.Cash.

В частности, цикл Deposit-Withdraw-CollectFees состоит из нескольких шагов, которые можно легко пометить и четко резюмировать с помощью нашего онлайн-инструмента [2]:

Анализ прибыли

В общей сложности злоумышленник получил от Popsicle Finance 20 млн долларов, включая 2.56 тыс. WETH, 96.2 WBTC, 160 тыс. DAI, 5.39 млн USDC, 4.98 млн USDT и 10.5 тыс. UNI. После этого эксплойта злоумышленник сначала обменял все остальные токены на ETH через Uniswap и WETH, а затем отмыл деньги с помощью Tornado.Cash.

Авторы

Юфэн Ху, Зилинг Лин, Джунджи Фей, Лей Ву, Яджин Чжоу @BlockSec

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

https://www.blocksecteam.com

Medium: https://blocksecteam.medium.com/

Twitter: https://twitter.com/BlockSecTeam

Контакт: [email protected]

Ссылки

[1] https://twitter.com/defiprime/status/1422708265423556611

[2] https://tx.blocksecteam.com/

Sign up for the latest updates
За пределами безопасного хранения, часть 1: проектирование безопасных процессов проведения платежей и подписания транзакций
Security Insights

За пределами безопасного хранения, часть 1: проектирование безопасных процессов проведения платежей и подписания транзакций

Как несанкционированная операция может получить действительную подпись, если злоумышленник не похитил закрытый ключ? В части 1 материала «За пределами безопасного хранения» на примере инцидентов, в том числе связанных с Bitget, Bybit и Binance, рассматриваются сбои авторизации на этапах подачи платёжных запросов, формирования транзакций, подписания, исполнения и расчётов. На этой основе выводятся принципы проектирования, направленные на предотвращение несанкционированных операций и ограничение потерь, а затем объясняется, как проверки, аудиты, тесты на проникновение и учения могут помочь проверить эти меры защиты.

Потери около 5,57 млн USD: атаки на X100 Freezer и NEM | Еженедельный обзор BlockSec
Security Insights

Потери около 5,57 млн USD: атаки на X100 Freezer и NEM | Еженедельный обзор BlockSec

Этот еженедельный отчёт охватывает два инцидента безопасности в сетях Ethereum и BNB Chain за период 19.10.2026–25.10.2026. В нём рассматриваются захват управления X100 Freezer, профинансированный с помощью флеш-кредита, и ошибка при расчёте налога, затронувшая пул ликвидности токена NEM в сети BNB Chain. Оценочные потери в рамках отчёта составляют в общей сложности около 5,57 млн USD: ~4,75 млн USD по рассматриваемой транзакции X100 и ~820 тыс. USD в результате инцидента с пулом NEM. В эту сумму не входят отдельно опубликованные данные о последующих выводах средств из X100.

Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec
Security Insights

Потери на сумму около 3,87 млн USD: взломы Autheo Network и UNCX | Еженедельный обзор BlockSec

В этом еженедельном отчёте рассматриваются 3 инцидента безопасности за период 12.10.2026–18.10.2026. Общий оценочный ущерб составил около 3,87 млн USD. Ущерб Autheo Network от компрометации закрытого ключа составил примерно 1,76 млн USD, Qubic Wallet потерял примерно 1,30 млн USD из-за ненадёжной генерации seed, а ошибка учёта в контрактах Smart Token Vesting V2 сети UNCX Network на Ethereum, BNB Chain, Base и Robinhood Chain привела к ущербу примерно в 807 тыс. USD. В подробном анализе инцидента UNCX объясняется, как некорректный расчёт совокупного количества долей смешивал транши вестинга, созданные при разных соотношениях токенов и долей, и позволял выводить из общих пулов больше положенного.

Best Security Auditor for Web3

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

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