Volver al blog

El Análisis del Incidente de Seguridad de Array Finance

Code Auditing
19 de julio de 2021
5 min de lectura

El 18 de julio, nuestro sistema DeFiRanger reportó un par de transacciones sospechosas. Tras el análisis manual, confirmamos que estas transacciones son ataques a Array Finance. A continuación, utilizaremos una transacción de ataque para ilustrar el proceso del ataque y la causa raíz de la vulnerabilidad.

Transacción de Ataque

La transacción de ataque utilizada en este blog es: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

Flujo del Ataque

Figura 1
Figura 1

Como se muestra en la Figura 1, encontramos que el atacante obtuvo una ganancia de 186,62 WETH (no distinguimos explícitamente entre WETH y ETH en este blog.) tras pedir prestado el préstamo flash de AAVE.

Figura 2
Figura 2

El proceso detallado del ataque se muestra en la Figura 2.

  • Primero, el atacante invocó la función buy de Array Finance. El atacante obtuvo 430 tokens ARRAY acuñados por Array Finance usando 45,91 WETH.
  • Luego, el atacante invocó la función joinPool de un contrato de código cerrado (Array Collater - 0xa800cda5) cinco veces. Depositó 676.410,58 DAI + 679.080,46 USDC + 901,82 WETH + 20 WBTC + 20 renBTC y obtuvo 726,38 tokens aBPT acuñados por Array Collater.
  • El atacante invocó la función sell para quemar 430 tokens ARRAY y obtuvo 77,17 tokens aBPT.
  • Por último, el atacante invocó la función exitPool de Array Collater. Quemó 804,55 tokens aBPT obtenidos en los dos pasos anteriores y obtuvo 748.271,55 DAI + 751.225,08 USDC + 997,62 WETH + 22,63 WBTC + 22,74 renBTC.

A partir de la Figura 2, podemos encontrar que el atacante obtiene ganancias en el paso 5 (Figura 2: Invocar la función sell). Esto se debe a que los 77,17 tokens aBPT obtenidos son más valiosos que los 49,9142 WETH depositados en el paso 3 (Figura 2: Invocar la función buy). A continuación, analizaremos el código para entender por qué este ataque puede ocurrir.

Vulnerabilidad del Código

El siguiente código muestra la función sell de Array Finance. En esta función, Array Finance utiliza el saldo del token ARRAY que posee el atacante e invoca la función interna _sell para calcular el número de tokens aBPT que se pueden obtener al vender el token ARRAY.

A continuación se muestra la implementación de la función _sell. Invoca calculateLPtokensGivenArrayTokens para obtener el número de tokens aBPT que se pueden obtener dado un cierto número de tokens ARRAY. Luego, esta función quema el token ARRAY y devuelve el token aBPT.

A continuación se muestra la implementación de la función calculateLPtokensGivenArrayTokens.

Nótese que hay cuatro argumentos que pueden afectar el cálculo de amountLPToken. Tras leer saleTargetAmount, inferimos que la fórmula es la siguiente:

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

El arraySmartPool es la dirección del contrato inteligente de Array Collater (0xa800cda5f3416a6fb64ef93d84d6298a685d190d). El valor de arraySmartPool.totalSupply() aumentará cuando el atacante deposite los fondos prestados del préstamo flash en el Array Collater (mostrado en la siguiente tabla).

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

Podemos confirmar esta lógica tras leer el código del arraySmartPool. A continuación se muestra la función joinPool del arraySmartPool.

Esta función primero invoca la función SmartPoolManager.joinPool para calcular el número de tokens (actualAmountsIn) que necesitan obtenerse del msg.sender. Luego, para cada token, invoca la función _pullUnderlying para depositar el token en arraySmartPool. Por último, invoca _mintPoolShare y _pushPoolShare para acuñar el token aBPT y transferir el token aBPT acuñado al msg.sender.

Nótese que el arraySmartPool hereda de PCToken. La función _mintPoolShare invoca la función _mint, que se muestra a continuación.

La función _mint aumentará la variable varTotalSupply, que es devuelta directamente por totalSupply(). Por lo tanto, este valor se incrementa con cada invocación de joinPool.

Estimación de Ganancias

Resumen

En resumen, el atacante explota la vulnerabilidad de que el mecanismo de precios de Array Finance depende del totalSupply del token aBPT, el cual es manipulable. La vulnerabilidad ha sido discutida en nuestro artículo de investigación DeFiRanger: Detecting Price Manipulation Attacks on DeFi Applications.

Créditos

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

(En orden alfabético por apellido)

Acerca de BlockSec

BlockSec es una empresa pionera en seguridad blockchain establecida en 2021 por un grupo de expertos en seguridad de renombre mundial. La empresa está comprometida a mejorar la seguridad y la usabilidad para el emergente mundo Web3 con el fin de facilitar su adopción masiva. Con este fin, BlockSec ofrece servicios de auditoría de seguridad para contratos inteligentes y cadenas EVM, la plataforma Phalcon para el desarrollo de seguridad y el bloqueo proactivo de amenazas, la plataforma MetaSleuth para el seguimiento e investigación de fondos, y la extensión MetaDock para que los constructores de web3 naveguen eficientemente en el mundo cripto.

Hasta la fecha, la empresa ha prestado servicios a más de 300 clientes destacados como MetaMask, Uniswap Foundation, Compound, Forta y PancakeSwap, y ha recibido decenas de millones de dólares estadounidenses en dos rondas de financiamiento de inversores prominentes, incluyendo Matrix Partners, Vitalbridge Capital y Fenbushi Capital.

Sitio web oficial: https://blocksec.com/

Cuenta oficial de Twitter: https://twitter.com/BlockSecTeam

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