El 22 de agosto, Balancer anunció oficialmente que había recibido informes de vulnerabilidad graves que afectaban a varios grupos de V2 Boost. Solo el 1,4 % del TVL se vio afectado. Se suspendieron varios grupos y se notificó a los usuarios que retiraran LP de liquidez lo antes posible. [1] [2]
El 27 de agosto, el sistema SlowMist MistEye descubrió una transacción de ataque que se sospechaba que explotaba la vulnerabilidad Balancer. [3]
Dado que el grupo no se puede suspender y algunos fondos aún se ven afectados por el ataque, los funcionarios de Balancer recuerdan una vez más a los usuarios que recuperen el LP del grupo afectado. [4] Posteriormente, Balancer publicó oficialmente los detalles de la vulnerabilidad revelada en agosto en Medium. [5] , el equipo de seguridad de SlowMist lo revisó, los detalles son los siguientes:
Introducción
Los funcionarios de Balancer simplemente señalaron en su divulgación que el problema esta vez es que el redondeo a la baja del grupo lineal y el suministro virtual del grupo combinable causaron que bptSupply fuera 0. Primero, comprendamos brevemente el contenido del protocolo Balancer relacionado con esta vulnerabilidad.
Bóveda Balancer V2
Equilibrador V2 [6] El protocolo es un protocolo de creador de mercado automatizado (AMM) descentralizado basado en Ethereum que representa un componente flexible para la liquidez programable. Su componente principal es el contrato Vault, que mantiene registros de todos los grupos y gestiona la contabilidad y transferencia de tokens, incluido incluso el empaquetado y desembalaje de ETH nativo. En otras palabras, Vault se implementa para separar la contabilidad y la gestión de tokens de la lógica del grupo.
Hay cuatro interfaces en Vault, a saber, joinPool, exitPool, swap y batchSwap (unirse, salir e intercambiar son llamadas separadas y no hay combinación en una sola llamada). Una de las características destacadas es BatchSwap, que puede realizar múltiples intercambios atómicos entre múltiples grupos y conectar la salida de un intercambio de grupo a la entrada de otro grupo (GiveIn y GiveOut). El sistema también introduce intercambios relámpago. [7] , similar a un préstamo flash interno.
Piscinas lineales Piscina lineal
Para mejorar la eficiencia del capital de LP y el problema de los altos gastos generales de deformación y deformación, Balancer lanzó el grupo lineal como solución en V2, introduciendo así el token BPT (ERC20 Balancer Pool Token).
piscina lineal [8] Incluyendo el token principal (activo subyacente), el token envuelto (token envuelto) y el token BPT, los activos y sus contrapartes envueltas con rendimientos se intercambian mediante tipos de cambio conocidos. Cuanto mayor sea la proporción de tokens envueltos, mayor será el rendimiento y la eficiencia del capital del grupo. Durante el proceso de deformación, generalmente se utilizan factores de escala para garantizar que se calculen diferentes tokens con la misma precisión.
Grupos componibles Grupo componible
Todos los grupos de Balancer son grupos componibles que contienen otros tokens y el grupo en sí también tiene sus propios tokens. Entre ellos, la moneda BPT se refiere al token del grupo equilibrado ERC20, que es la base de todos los grupos. Los usuarios pueden combinar libremente tokens BPT en otros grupos para canjearlos. El canje siempre implica un fondo común y dos tokens: GiveIn y GiveOut. In significa enviar tokens de componentes y recibir BPT, mientras que Out significa enviar BPT y recibir tokens de componentes. Si el propio BPT fuera un token componente, podría intercambiarse como otros tokens. Esta implementación constituye una ruta de intercambio por lotes simple entre los activos subyacentes y los tokens en el grupo externo. Los usuarios pueden usar BPT para intercambiar por los activos subyacentes del grupo lineal. Este también es el grupo impulsado por Balancer. [9] Base.
A través de la combinación anterior, se forma el grupo combinable de Balancer. Un grupo estable componible de bb-a-USD consta de tres grupos lineales, mientras envía liquidez inactiva al protocolo externo (Aave). Por ejemplo, bb-a-DAI es un grupo lineal que contiene DAI y waDAI (aDAI envuelto). Cuando el usuario necesita realizar un intercambio por lotes (como cambiar USDT a DAI), el ejemplo de ruta de intercambio es el siguiente:
En el grupo lineal de USDT, intercambie USDT por bb-a-USDT (ingrese al grupo lineal de USDT);
En bb-a-USD, bb-a-USDT se intercambia por bb-a-DAI (intercambio entre BPT lineal);
En el grupo lineal DAI, bb-a-DAI se intercambia por DAI (salga del grupo lineal DAI).
Después de comprender brevemente los conocimientos previos anteriores, ingresamos al enlace de análisis de vulnerabilidad.
analizar
El 27 de agosto, el equipo de seguridad de SlowMist recibió la identificación del sistema MistEye de que una supuesta vulnerabilidad de Balancer había sido explotada en estado salvaje. comercio [3] como sigue:
El atacante primero pidió prestados 300.000 USDC a AAVE a través de un préstamo rápido. Luego se llama a la operación BatchSwap de Vault para realizar el cálculo de intercambio de tokens BPT a través del pool estable combinable bb-a-USD y finalmente se intercambian 94,508 USDC por 59,964 bb-a-USDC, 68,201 bb-a-DAI y 74,280. bb-a-USDT. Finalmente, los tokens BPT obtenidos saldrán del pool a través del exitPool del contrato Vault a cambio de activos subyacentes, reembolsarán el préstamo flash y saldrán del mercado con una ganancia de aproximadamente 108.843,7 dólares estadounidenses.
Se puede ver que la clave de este ataque está en BatchSwap, y ¿qué sucedió exactamente en BatchSwap? Miremos más de cerca.
Durante todo el proceso de intercambio por lotes, el atacante primero canjeó USDC en el grupo bb-a-USDC y luego intercambió tokens BPT, intercambiando bb-a-USDC por bb-a-DAI, bb-a-USDT y USDC. Finalmente, el token principal subyacente USDC se intercambia por bb-a-USDT. En otras palabras, bb-a-USDC, como token BPT clave, sirve como token componente de GiveOut y GiveIn.
En el primer paso, el atacante intercambia tokens BPT por tokens principales de USDC en el grupo lineal bb-a-USDC con un factor de escala fijo, y la cantidad aumentada se registra en el bptBalance del grupo. Pero después del segundo intercambio onSwap, descubrimos que el valor de cantidad de USDC intercambiado fue 0 durante el mismo proceso de intercambio. ¿Por qué es esto?
Profundizando en la función onSwap, encontramos que en este proceso, la precisión se procesará a nominal y se calculará el factor de escala del token correspondiente. Cuando se llama a continuación a la función _downscaleDown, cantidadOut se redondea hacia abajo. Si cantidad y factores de escala [indexOut] La diferencia entre los valores es grande y el valor calculado de _downscaleDown es cero.
Es decir, cuando usamos tokens BPT para canjear tokens principales, si cantidad es demasiado pequeña, el valor de retorno se redondeará a cero y este valor es menor que 1e12 calculado por scalingFactors. Sin embargo, la cantidad de bb-a-USDC proveniente de cantidadIn aún se agregará a la cantidad virtual de bptBalance, y esta operación aumentará el saldo en el grupo de bb-a-USDC, lo que puede considerarse como una adición unilateral de bb. -a-Liquidez del USDC.
Luego, utilizando las características del grupo estable combinable, mediante la conversión mutua entre tokens BPT, primero intercambie bb-a-USDC por otros tokens BPT. Para seguir este proceso de intercambio, puede combinar la siguiente ruta de llamada del grupo estable: bb-a-DAI onSwap -> _swapGivenIn -> _onSwapGivenIn. Primero, reemplace bb-a-USDC con bb-a-DAI y bb- a-USDT en secuencia. A diferencia de los pools lineales en línea, los pools estables componibles requieren actualizaciones de caché del tipo de cambio antes de las operaciones onSwap. Del código podemos ver que en el grupo de combinación, onSwap primero determinará si es necesario actualizar el tipo de cambio del token almacenado en caché.
Después del intercambio anterior, la cantidad de bb-a-USDC ha cambiado, y la cantidad total real después de la nominalización a través de _toNominal es totalBalance 994,010,000,000, y el suministro virtual de tokens BPT es 20,000,000,000. Se puede calcular que el tipo de cambio actualizado es casi 45 veces el tipo de cambio de caché original del grupo lineal anterior de 1.100.443.876.587.504.549, que es 49.700.500.000.000.000.000.
Posteriormente, bb-a-USDC se intercambia por USDC en el pool lineal. Sin embargo, este intercambio es el mismo que el segundo intercambio, lo que nuevamente hace que cantidadOut se redondee a la baja a 0 y la ruta de intercambio es la misma que antes.
El siguiente intercambio es revertir USDC a bb-a-USDC, y la ruta de intercambio es onSwap -> onSwapGivenIn -> _swapGivenMainIn. Durante este proceso, descubrimos que al calcular la cantidad que debe canjearse, el cálculo del suministro virtual se basa en la diferencia entre el suministro total del token BPT canjeado y la cantidad restante en el grupo, que es 0.
Esto se debe a que bptSupply es 0 y la función _toNominal se llama directamente al calcular BPT Out, y la llamada de esta ruta hace que la relación de cambio de USDC a bb-a-USDC se acerque a 1:1.
Resumir
BatchSwap conecta la salida del intercambio de un grupo con la entrada de otro grupo (tokenIn y tokenOut) a través de múltiples intercambios atómicos entre múltiples grupos y convierte USDC en tokens BPT. En este intercambio por lotes, no se produce ninguna transferencia de token real, pero el monto final del intercambio se confirma registrando el monto transferido hacia adentro y hacia afuera. Y debido a que el conjunto lineal se intercambia a través del token del activo subyacente, el método de intercambio consiste en calcular la Tasa a través de una oferta virtual y un algoritmo fijo. Por lo tanto, existen dos agujeros de seguridad en BatchSwap:
El primero es el problema de redondeo a la baja de los grupos lineales: el atacante agrega unilateralmente tokens principales al grupo mediante redondeo para aumentar la proporción de tokens almacenados en caché, manipulando así el tipo de cambio de tokens en el grupo componible correspondiente;
En segundo lugar, debido a las características de suministro virtual del grupo combinable, el suministro virtual se calcula restando el saldo del grupo del token BPT. Si GiveIn es un token BPT en el momento del canje, esta parte se deducirá de los tokens BPT posteriores. suministro., el atacante solo necesita intercambiar BPT como GiveIn, primero manipular su suministro a 0 y luego realizar un intercambio inverso, es decir, BPT se usa como el lado GiveOut. En este momento, dado que el suministro es 0, el El algoritmo estará cerca de 1: la proporción de 1 es menor que la proporción de canje del grupo lineal para el canje real, lo que hace que la cantidad de tokens BPT de GiveOut se manipule indirectamente.
Podemos encontrar que la vulnerabilidad uno aumenta el tipo de cambio, mientras que la vulnerabilidad dos reduce el tipo de cambio en la dirección inversa: el atacante aprovechó el doble beneficio para obtener ganancias y marcharse.
Link de referencia:
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
Ver originales
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
Análisis de vulnerabilidad del equilibrador.
fondo
El 22 de agosto, Balancer anunció oficialmente que había recibido informes de vulnerabilidad graves que afectaban a varios grupos de V2 Boost. Solo el 1,4 % del TVL se vio afectado. Se suspendieron varios grupos y se notificó a los usuarios que retiraran LP de liquidez lo antes posible. [1] [2]
El 27 de agosto, el sistema SlowMist MistEye descubrió una transacción de ataque que se sospechaba que explotaba la vulnerabilidad Balancer. [3]
Dado que el grupo no se puede suspender y algunos fondos aún se ven afectados por el ataque, los funcionarios de Balancer recuerdan una vez más a los usuarios que recuperen el LP del grupo afectado. [4] Posteriormente, Balancer publicó oficialmente los detalles de la vulnerabilidad revelada en agosto en Medium. [5] , el equipo de seguridad de SlowMist lo revisó, los detalles son los siguientes:
Introducción
Los funcionarios de Balancer simplemente señalaron en su divulgación que el problema esta vez es que el redondeo a la baja del grupo lineal y el suministro virtual del grupo combinable causaron que bptSupply fuera 0. Primero, comprendamos brevemente el contenido del protocolo Balancer relacionado con esta vulnerabilidad.
Bóveda Balancer V2
Equilibrador V2 [6] El protocolo es un protocolo de creador de mercado automatizado (AMM) descentralizado basado en Ethereum que representa un componente flexible para la liquidez programable. Su componente principal es el contrato Vault, que mantiene registros de todos los grupos y gestiona la contabilidad y transferencia de tokens, incluido incluso el empaquetado y desembalaje de ETH nativo. En otras palabras, Vault se implementa para separar la contabilidad y la gestión de tokens de la lógica del grupo.
Hay cuatro interfaces en Vault, a saber, joinPool, exitPool, swap y batchSwap (unirse, salir e intercambiar son llamadas separadas y no hay combinación en una sola llamada). Una de las características destacadas es BatchSwap, que puede realizar múltiples intercambios atómicos entre múltiples grupos y conectar la salida de un intercambio de grupo a la entrada de otro grupo (GiveIn y GiveOut). El sistema también introduce intercambios relámpago. [7] , similar a un préstamo flash interno.
Piscinas lineales Piscina lineal
Para mejorar la eficiencia del capital de LP y el problema de los altos gastos generales de deformación y deformación, Balancer lanzó el grupo lineal como solución en V2, introduciendo así el token BPT (ERC20 Balancer Pool Token).
piscina lineal [8] Incluyendo el token principal (activo subyacente), el token envuelto (token envuelto) y el token BPT, los activos y sus contrapartes envueltas con rendimientos se intercambian mediante tipos de cambio conocidos. Cuanto mayor sea la proporción de tokens envueltos, mayor será el rendimiento y la eficiencia del capital del grupo. Durante el proceso de deformación, generalmente se utilizan factores de escala para garantizar que se calculen diferentes tokens con la misma precisión.
Grupos componibles Grupo componible
Todos los grupos de Balancer son grupos componibles que contienen otros tokens y el grupo en sí también tiene sus propios tokens. Entre ellos, la moneda BPT se refiere al token del grupo equilibrado ERC20, que es la base de todos los grupos. Los usuarios pueden combinar libremente tokens BPT en otros grupos para canjearlos. El canje siempre implica un fondo común y dos tokens: GiveIn y GiveOut. In significa enviar tokens de componentes y recibir BPT, mientras que Out significa enviar BPT y recibir tokens de componentes. Si el propio BPT fuera un token componente, podría intercambiarse como otros tokens. Esta implementación constituye una ruta de intercambio por lotes simple entre los activos subyacentes y los tokens en el grupo externo. Los usuarios pueden usar BPT para intercambiar por los activos subyacentes del grupo lineal. Este también es el grupo impulsado por Balancer. [9] Base.
A través de la combinación anterior, se forma el grupo combinable de Balancer. Un grupo estable componible de bb-a-USD consta de tres grupos lineales, mientras envía liquidez inactiva al protocolo externo (Aave). Por ejemplo, bb-a-DAI es un grupo lineal que contiene DAI y waDAI (aDAI envuelto). Cuando el usuario necesita realizar un intercambio por lotes (como cambiar USDT a DAI), el ejemplo de ruta de intercambio es el siguiente:
En el grupo lineal de USDT, intercambie USDT por bb-a-USDT (ingrese al grupo lineal de USDT);
En bb-a-USD, bb-a-USDT se intercambia por bb-a-DAI (intercambio entre BPT lineal);
En el grupo lineal DAI, bb-a-DAI se intercambia por DAI (salga del grupo lineal DAI).
Después de comprender brevemente los conocimientos previos anteriores, ingresamos al enlace de análisis de vulnerabilidad.
analizar
El 27 de agosto, el equipo de seguridad de SlowMist recibió la identificación del sistema MistEye de que una supuesta vulnerabilidad de Balancer había sido explotada en estado salvaje. comercio [3] como sigue:
El atacante primero pidió prestados 300.000 USDC a AAVE a través de un préstamo rápido. Luego se llama a la operación BatchSwap de Vault para realizar el cálculo de intercambio de tokens BPT a través del pool estable combinable bb-a-USD y finalmente se intercambian 94,508 USDC por 59,964 bb-a-USDC, 68,201 bb-a-DAI y 74,280. bb-a-USDT. Finalmente, los tokens BPT obtenidos saldrán del pool a través del exitPool del contrato Vault a cambio de activos subyacentes, reembolsarán el préstamo flash y saldrán del mercado con una ganancia de aproximadamente 108.843,7 dólares estadounidenses.
Se puede ver que la clave de este ataque está en BatchSwap, y ¿qué sucedió exactamente en BatchSwap? Miremos más de cerca.
Durante todo el proceso de intercambio por lotes, el atacante primero canjeó USDC en el grupo bb-a-USDC y luego intercambió tokens BPT, intercambiando bb-a-USDC por bb-a-DAI, bb-a-USDT y USDC. Finalmente, el token principal subyacente USDC se intercambia por bb-a-USDT. En otras palabras, bb-a-USDC, como token BPT clave, sirve como token componente de GiveOut y GiveIn.
En el primer paso, el atacante intercambia tokens BPT por tokens principales de USDC en el grupo lineal bb-a-USDC con un factor de escala fijo, y la cantidad aumentada se registra en el bptBalance del grupo. Pero después del segundo intercambio onSwap, descubrimos que el valor de cantidad de USDC intercambiado fue 0 durante el mismo proceso de intercambio. ¿Por qué es esto?
Profundizando en la función onSwap, encontramos que en este proceso, la precisión se procesará a nominal y se calculará el factor de escala del token correspondiente. Cuando se llama a continuación a la función _downscaleDown, cantidadOut se redondea hacia abajo. Si cantidad y factores de escala [indexOut] La diferencia entre los valores es grande y el valor calculado de _downscaleDown es cero.
Es decir, cuando usamos tokens BPT para canjear tokens principales, si cantidad es demasiado pequeña, el valor de retorno se redondeará a cero y este valor es menor que 1e12 calculado por scalingFactors. Sin embargo, la cantidad de bb-a-USDC proveniente de cantidadIn aún se agregará a la cantidad virtual de bptBalance, y esta operación aumentará el saldo en el grupo de bb-a-USDC, lo que puede considerarse como una adición unilateral de bb. -a-Liquidez del USDC.
Luego, utilizando las características del grupo estable combinable, mediante la conversión mutua entre tokens BPT, primero intercambie bb-a-USDC por otros tokens BPT. Para seguir este proceso de intercambio, puede combinar la siguiente ruta de llamada del grupo estable: bb-a-DAI onSwap -> _swapGivenIn -> _onSwapGivenIn. Primero, reemplace bb-a-USDC con bb-a-DAI y bb- a-USDT en secuencia. A diferencia de los pools lineales en línea, los pools estables componibles requieren actualizaciones de caché del tipo de cambio antes de las operaciones onSwap. Del código podemos ver que en el grupo de combinación, onSwap primero determinará si es necesario actualizar el tipo de cambio del token almacenado en caché.
Después del intercambio anterior, la cantidad de bb-a-USDC ha cambiado, y la cantidad total real después de la nominalización a través de _toNominal es totalBalance 994,010,000,000, y el suministro virtual de tokens BPT es 20,000,000,000. Se puede calcular que el tipo de cambio actualizado es casi 45 veces el tipo de cambio de caché original del grupo lineal anterior de 1.100.443.876.587.504.549, que es 49.700.500.000.000.000.000.
Posteriormente, bb-a-USDC se intercambia por USDC en el pool lineal. Sin embargo, este intercambio es el mismo que el segundo intercambio, lo que nuevamente hace que cantidadOut se redondee a la baja a 0 y la ruta de intercambio es la misma que antes.
El siguiente intercambio es revertir USDC a bb-a-USDC, y la ruta de intercambio es onSwap -> onSwapGivenIn -> _swapGivenMainIn. Durante este proceso, descubrimos que al calcular la cantidad que debe canjearse, el cálculo del suministro virtual se basa en la diferencia entre el suministro total del token BPT canjeado y la cantidad restante en el grupo, que es 0.
Esto se debe a que bptSupply es 0 y la función _toNominal se llama directamente al calcular BPT Out, y la llamada de esta ruta hace que la relación de cambio de USDC a bb-a-USDC se acerque a 1:1.
Resumir
BatchSwap conecta la salida del intercambio de un grupo con la entrada de otro grupo (tokenIn y tokenOut) a través de múltiples intercambios atómicos entre múltiples grupos y convierte USDC en tokens BPT. En este intercambio por lotes, no se produce ninguna transferencia de token real, pero el monto final del intercambio se confirma registrando el monto transferido hacia adentro y hacia afuera. Y debido a que el conjunto lineal se intercambia a través del token del activo subyacente, el método de intercambio consiste en calcular la Tasa a través de una oferta virtual y un algoritmo fijo. Por lo tanto, existen dos agujeros de seguridad en BatchSwap:
El primero es el problema de redondeo a la baja de los grupos lineales: el atacante agrega unilateralmente tokens principales al grupo mediante redondeo para aumentar la proporción de tokens almacenados en caché, manipulando así el tipo de cambio de tokens en el grupo componible correspondiente;
En segundo lugar, debido a las características de suministro virtual del grupo combinable, el suministro virtual se calcula restando el saldo del grupo del token BPT. Si GiveIn es un token BPT en el momento del canje, esta parte se deducirá de los tokens BPT posteriores. suministro., el atacante solo necesita intercambiar BPT como GiveIn, primero manipular su suministro a 0 y luego realizar un intercambio inverso, es decir, BPT se usa como el lado GiveOut. En este momento, dado que el suministro es 0, el El algoritmo estará cerca de 1: la proporción de 1 es menor que la proporción de canje del grupo lineal para el canje real, lo que hace que la cantidad de tokens BPT de GiveOut se manipule indirectamente.
Podemos encontrar que la vulnerabilidad uno aumenta el tipo de cambio, mientras que la vulnerabilidad dos reduce el tipo de cambio en la dirección inversa: el atacante aprovechó el doble beneficio para obtener ganancias y marcharse.
Link de referencia:
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]