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
За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3
Security Insights

За пределами смарт-контракта: операционная безопасность доменов и DNS в Web3

Аудит контрактов не проверяет сам контракт. Мы провели 800 SEAL-проверок DNS и регистраторов для 100 доменов из TVL Top 100 DefiLlama — лишь один домен прошёл все. Каких четырёх мер защиты не хватает большинству и почему это критично для пользователя.

Поверхности атаки Web3: обзор тестирования на проникновение

Поверхности атаки Web3: обзор тестирования на проникновение

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

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly
Security Insights

Потеряно ~23 млн $: эксплойты Cosmos EVM и Moonwell | BlockSec Weekly

За период (22.08.2026–30.08.2026): 5 инцидентов, ~$22,7 млн убытков; Tectonic — $74–119,5 млн, откачены на Cronos. Взлом Cosmos EVM (~$5,7 млн) на TAC Chain, Moonwell, Ajna, Rain Card Exploit (Ed25519) на Solana.

Best Security Auditor for Web3

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

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