Volver al blog

El Análisis del Incidente de Seguridad de Popsicle Finance

Code Auditing
4 de agosto de 2021
4 min de lectura

El 4 de agosto de 2021, Popsicle Finance sufrió una enorme pérdida financiera (más de $20M) a causa de un ataque [1]. Tras un análisis manual, confirmamos que se trata de un ataque de reclamación doble (double-claiming), es decir, una laguna en su sistema de recompensas permite al atacante reclamar recompensas repetidamente. A continuación, utilizaremos una transacción del ataque para ilustrar el proceso del ataque y la causa raíz de la vulnerabilidad.

Contexto

Popsicle Finance es una plataforma de optimización de rendimiento que soporta múltiples bóvedas para diferentes cadenas (p. ej., Ethereum y BSC).

Específicamente, un usuario primero invoca la función deposit para proporcionar liquidez y obtiene el token LP de Popsicle (PLP, por sus siglas). Después de eso, Popsicle Finance gestionará la liquidez (interactuando con plataformas como Uniswap) para generar ganancias al usuario. El usuario puede invocar la función withdraw para recuperar la liquidez de Popsicle Finance, que calculará el monto en función de los tokens PLP. La recompensa de incentivo proviene de la liquidez, que se irá acumulando con el paso del tiempo. El usuario puede invocar la función collectFees para reclamar las recompensas, que es la clave de este ataque.

Análisis de la Vulnerabilidad

En la función collectFees, se calculan token0Reward y token1Reward (recompensas del par de tokens LP correspondiente) para el usuario. Toda la lógica de cálculo es sencilla. Sin embargo, la función utiliza un modificador llamado updateVault, que se usa para actualizar las recompensas en consecuencia.

En resumen, updateVault realizará lo siguiente:

  1. primero invoca la función _earnFees para obtener la tarifa acumulada del pool;
  2. luego invoca la función _tokenPerShare para actualizar token0PerShareStored y token1PerShareStored, que representan las cantidades de token0 y token1 en el pool por cada participación;
  3. finalmente invoca las funciones _fee0Earned y _fee1Earned para actualizar las recompensas del usuario (es decir, token0Rewards y token1Rewards respectivamente).

Las funciones _fee0Earned y _fee1Earned comparten la misma lógica, es decir, implementan la siguiente fórmula (usando token0 como ejemplo):

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

Nótese que el cálculo es incremental, lo que significa que incluso si el usuario NO posee el token PLP, la recompensa calculada mantiene el valor almacenado en token0Rewards.

Por lo tanto, podemos concluir las siguientes dos observaciones:

  1. las recompensas del usuario se almacenan en token0Rewards y token1Rewards, las cuales no están asociadas a ningún token PLP;
  2. la función collectFees solo depende del estado de token0Rewards y token1Rewards, lo que significa que las recompensas pueden retirarse sin poseer el token PLP.

En un escenario del mundo real, esto significa que un usuario deposita dinero en un banco y el banco le entrega un certificado de depósito. Desafortunadamente, este certificado no es ni anti-falsificación, ni está asociado al usuario. En tal caso, es posible hacer duplicados y distribuirlos a otros para obtener ganancias del banco.

Flujo del Ataque

En resumen, el atacante siguió los siguientes pasos para lanzar el ataque:

  1. creó tres contratos. Uno de ellos se utilizó para lanzar el ataque, mientras que los otros dos se usaron para invocar la función collectFees y obtener las recompensas;
  2. utilizó el Flash Loan, es decir, tomó prestada una gran cantidad de liquidez de AAVE;
  3. lanzó el ciclo Depositar-Retirar-ReclamarTarifas (Deposit-Withdraw-CollectFees) para realizar el ataque (hay 8 ciclos en total, y se retiró mucha liquidez de múltiples bóvedas de Popsicle Finance);
  4. devolvió el Flash Loan a AAVE y blanqueó las ganancias a través de Tornado.Cash.

Específicamente, el ciclo Depositar-Retirar-ReclamarTarifas consta de varios pasos, que pueden etiquetarse fácilmente y resumirse claramente usando nuestra herramienta en línea [2]:

Análisis de Ganancias

En total, el atacante obtuvo $20M de Popsicle Finance, incluyendo 2,56K WETH, 96,2 WBTC, 160K DAI, 5,39M USDC, 4,98M USDT y 10,5K UNI. Tras esa explotación, el atacante primero intercambió todos los demás tokens por ETH a través de Uniswap y WETH, y luego realizó el blanqueo de dinero utilizando Tornado.Cash.

Créditos

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

(En orden alfabético por apellido)

https://www.blocksecteam.com

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

Twitter: https://twitter.com/BlockSecTeam

Contacto: [email protected]

Referencia

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

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

Apúntate para recibir las novedades
Pérdidas de ~5,57 millones USD: exploits de X100 Freezer y NEM | Resumen semanal de BlockSec
Security Insights

Pérdidas de ~5,57 millones USD: exploits de X100 Freezer y NEM | Resumen semanal de BlockSec

Este informe semanal cubre dos incidentes de seguridad ocurridos en Ethereum y BNB Chain durante el período 19/10/2026–25/10/2026. Examina una toma de control de la gobernanza de X100 Freezer financiada mediante un préstamo flash y un fallo en la liquidación de impuestos que afectó a un pool de liquidez de un token NEM en BNB Chain. Las pérdidas estimadas dentro del alcance del informe suman aproximadamente 5,57 millones USD: ~4,75 millones USD de la transacción representativa de X100 y ~820 mil USD del incidente del pool de NEM. El total excluye las extracciones posteriores de X100 reportadas por separado.

Pérdidas de aproximadamente 3,87 millones USD: hackeos de Autheo Network y UNCX | Resumen semanal de BlockSec
Security Insights

Pérdidas de aproximadamente 3,87 millones USD: hackeos de Autheo Network y UNCX | Resumen semanal de BlockSec

Este informe semanal cubre 3 incidentes de seguridad correspondientes al período 12/10/2026–18/10/2026, con pérdidas totales estimadas en aproximadamente 3,87 millones USD. Autheo Network sufrió una vulneración de clave privada con pérdidas de aproximadamente 1,76 millones USD; Qubic Wallet perdió aproximadamente 1,30 millones USD debido a la generación de una semilla débil; y los contratos Smart Token Vesting V2 de UNCX Network sufrieron un error contable con pérdidas de aproximadamente 807 mil USD en Ethereum, BNB Chain, Base y Robinhood Chain. El análisis destacado de UNCX explica cómo un cálculo agregado de participaciones defectuoso mezcló tramos de adquisición de derechos creados con distintas proporciones entre tokens y participaciones, lo que permitió retiros excesivos de pools compartidos.

Pérdidas de ~542.000 dólares: explotación de MakerDaoBot | Resumen semanal de BlockSec
Security Insights

Pérdidas de ~542.000 dólares: explotación de MakerDaoBot | Resumen semanal de BlockSec

Ethereum (05–11/10/2026): 1 incidente; pérdida estimada de $542 mil. MakerDaoBot, sin control de acceso, dio a un adaptador malicioso acceso a sus saldos MakerDAO. Este cerró 4 subastas ETH-A y convirtió 200 ETH-A en WETH; el atacante los cambió por 200 ETH y se los envió.

El mejor auditor de seguridad para Web3

Valida el diseño, el código y la lógica de negocio antes del lanzamiento, siguiendo los estándares de seguridad más exigentes del sector.

Auditoría de BlockSec