-Advertisement-
El ataque de préstamo flash del 13 de marzo contra Euler Finance se saldó con más de 195 millones de dólares en pérdidas. Provocó un contagio a través de múltiples protocolos de finanzas descentralizadas (DeFi), y al menos 11 protocolos distintos de Euler sufrieron pérdidas debido al ataque.
En los 23 días siguientes, y para gran alivio de muchos usuarios de Euler, el atacante devolvió todos los fondos explotados.
Pero aunque la comunidad de criptomonedas puede celebrar la devolución de los fondos, la pregunta sigue siendo si ataques similares pueden causar pérdidas masivas en el futuro.
Puede ser útil un análisis de cómo se produjo el ataque y si los desarrolladores y usuarios pueden hacer algo para ayudar a prevenir este tipo de ataques en el futuro.
Por suerte, los documentos para desarrolladores de Euler explican claramente cómo funciona el protocolo, y la propia blockchain ha conservado un registro completo del ataque.
Cómo funciona Euler Finance
Según según los documentos oficiales del protocolo, Euler es una plataforma de préstamos similar a Compound o Aave. Los usuarios pueden depositar cripto y permitir que el protocolo lo preste a otros, o pueden utilizar un depósito como garantía para pedir cripto prestado.
El valor de la garantía de un usuario debe ser siempre superior a lo que pide prestado. Supongamos que la garantía de un usuario cae por debajo de un ratio específico entre el valor de la garantía y el valor de la deuda. En ese caso, la plataforma le permitirá ser “liquidado”, lo que significa que su garantía será vendida para pagar sus deudas. La cantidad exacta de garantía que necesita un usuario depende del activo depositado frente al activo prestado.
Los eTokens son activos, mientras que los dTokens son deudas.
Cuando los usuarios depositan en Euler, ellos reciben eTokens que representan las monedas depositadas. Por ejemplo, si un usuario deposita 1.000 USD Coin (USDC), recibirá a cambio la misma cantidad de eUSDC.
Dado que adquieren un valor superior al de las monedas subyacentes a medida que el depósito devenga intereses, los eTokens no tienen una correspondencia 1:1 con el activo subyacente en términos de valor.
Euler también permite a los usuarios ganar apalancamiento mediante acuñando eTokens. Pero si lo hacen, el protocolo les enviará tokens de deuda (dTokens) para equilibrar los activos creados.
Por ejemplo, los documentos dicen que si un usuario deposita 1.000 USDC, puede acuñar 5.000 eUSDC. Sin embargo, si hacen esto, el protocolo también les enviará 5.000 de un token de deuda llamado “dUSDC”.
La función de transferencia de un dToken está escrita de forma diferente a la de un token ERC-20 estándar. Si posees un token de deuda, no puedes transferirlo a otra persona, pero cualquiera puede quitarte un dToken si quiere.
Relacionado: Protocolo de liquidez Sentimiento explotado por más de $ 500K
Según la documentación de Euler, un usuario sólo puede acuñar tantos eTokens como hubiera podido depositando y pidiendo prestados una y otra vez, ya que afirma: “La función Mint imita lo que sucedería si un usuario depositara 1.000 USDC, luego pidiera prestados 900 USDC, volviera a depositar esos 900 USDC, para pedir prestados 810 USDC más, y así sucesivamente.”
Usuarios liquidados si la puntuación de salud baja a 1 o menos
Según una entrada del blog de Euler, cada usuario tiene una “puntuación de salud” basada en en el valor de los eTokens que tienen en sus carteras frente al valor de los dTokens que tienen. Un usuario necesita tener un mayor valor en dólares de eTokens que de dTokens, pero cuánto más depende de las monedas concretas que esté tomando prestadas o depositando. En cualquier caso, un usuario con suficientes eTokens tendrá una puntuación de salud superior a 1.
Si el usuario apenas llega al número requerido de eTokens, tendrá una puntuación de salud de exactamente 1. Esto le someterá a una “liquidación suave”. Los bots liquidadores pueden llamar a una función para transferirse a sí mismos algunos de los eTokens y dTokens del usuario hasta que la puntuación de salud del prestatario vuelva a 1,25. Dado que un usuario que está apenas por debajo de los requisitos de garantía todavía tendrá más garantía que deuda, el liquidador debería beneficiarse de esta transacción.
Si la puntuación de salud de un usuario cae por debajo de 1, el liquidador recibe un descuento creciente en función de lo mala que sea la puntuación de salud. Cuanto peor sea la puntuación, mayor será el descuento para el liquidador. Con esto se pretende asegurar que siempre haya alguien que liquide una cuenta antes de que acumule demasiadas deudas.
El post de Euler afirma que otros protocolos ofrecen un “descuento fijo” por liquidación y argumenta por qué cree que los descuentos variables son superiores.
Cómo se produjo el ataque de Euler
Los datos de Blockchain revelan que el atacante llevó a cabo una serie de ataques que drenaron varios tokens del protocolo. El primer ataque drenó alrededor de 8,9 millones de dólares en Dai (DAI) del depósito de Dai. A continuación, se repitió una y otra vez en otros depósitos hasta que se agotó la cantidad total.
El atacante utilizó tres direcciones Ethereum diferentes para realizar el ataque. La primera fue un contrato inteligente, que Etherscan ha etiquetado como “Euler Exploit Contract 1”, utilizado para pedir prestado a Aave. La segunda dirección se utilizó para depositar y pedir prestado a Euler, y la tercera se utilizó para realizar una liquidación.
Para evitar tener que indicar repetidamente las direcciones que Etherscan no ha etiquetado, se hará referencia a la segunda cuenta como “Prestatario” y a la tercera como “Liquidador”, tal y como se muestra a continuación:
El primer ataque consistió en de 20 transacciones en el mismo bloque.
En primer lugar, Euler Exploit Contract 1 tomó prestados 30 millones de DAI de Aave en un préstamo flash. A continuación, envió este préstamo a la cuenta del prestatario.
Tras recibir los 30 millones de DAI, el prestatario depositó 20 millones de ellos a Euler. Euler respondió entonces acuñando aproximadamente 19,6 millones de eDAI y enviándolos al prestatario.
Estas monedas eDAI eran un recibo por el depósito, por lo que no se acuñó una cantidad correspondiente de dDai en el proceso. Y como cada eDAI puede canjearse por algo más de un dDai, el prestatario sólo recibió 19,6 millones en lugar de los 20 millones completos.
Tras realizar este depósito inicial, el prestatario acuñó aproximadamente 195,7 millones de eDAI. En respuesta, Euler acuñó 200 millones de dDAI y los envió al prestatario.
En este punto, el prestatario estaba cerca de su límite de acuñación de eDAI, ya que ahora había pedido prestado unas 10 veces la cantidad de DAI que había depositado. Así que su siguiente paso fue pagar algunas de las deudas. Depositaron los otros 10 millones de AID que tenían retenidos, devolviendo así 10 millones del préstamo. En respuesta, Euler sacó 10 millones de AID de la cartera del prestatario y los quemó, reduciendo la deuda del prestatario en 10 millones de dólares.
Relacionado: Allbridge ofrece una recompensa por el exploit que robó 573.000 dólares en un ataque a un préstamo flash
El atacante pudo entonces acuñar más eDAI. El prestatario acuñó otros 195,7 millones de eDAI, con lo que su total de eDAI acuñados ascendió a unos 391,4 millones. Los 19,6 millones de eDAI en ingresos de depósitos elevaron el total de eDAI del prestatario a unos 411 millones.
En respuesta, Euler acuñó otros 200 millones de dDai y los envió al prestatario, con lo que la deuda total del prestatario ascendía a 400 millones.
Una vez que el prestatario hubo maximizado su capacidad de acuñación de eDAI, envió 100 millones de eDai a la dirección nula, destruyéndola de hecho.
Esto empujó su puntuación de salud muy por debajo de 1, ya que ahora tenían 400 millones de dólares en deuda frente a aproximadamente 320 millones de dólares en activos.
Aquí es donde entra en juego la cuenta liquidadora. Llamó a la función liquidar, introduciendo la dirección del prestatario como la cuenta a liquidar.
-Advertisement-
En respuesta, Euler inició el proceso de liquidación. Primero tomó unos 254 millones de dDAI del prestatario y los destruyó, después acuñó 254 millones de nuevos dDai y los transfirió al liquidador. Estos dos pasos transfirieron 254 millones de dólares de deuda del prestatario al liquidador.
A continuación, Euler acuñó otros 5,08 millones de dDAI y los envió al liquidador. Esto elevó la deuda del liquidador a 260 millones de dólares. Por último, Euler transfirió aproximadamente 310,9 millones de eDAI del prestatario al liquidador, completando así el proceso de liquidación.
Al final, el prestatario se quedó sin eDAI, sin DAI y con 146 millones de dDAI. Esto significaba que la cuenta no tenía activos y 146 millones de dólares de deuda.
Por otro lado, el liquidador tenía aproximadamente 310,9 millones de eDAI y sólo 260 millones de dDAI.
Una vez finalizada la liquidación, el liquidador reembolsó 38 millones de eDAI (38,9 millones de dólares), recibiendo a cambio 38,9 millones de DAI. A continuación, devolvió 30 millones de DAI más intereses a Euler Exploiter Contract 1, que el contrato utilizó para devolver el préstamo de Aave.
Al final, el liquidador se quedó con unos 8,9 millones de dólares de beneficios que habían sido explotados de otros usuarios del protocolo.
Este ataque se repitió para otros múltiples tokens, incluyendo Wrapped Bitcoin (WBTC), Staked Ether (stETH) y USDC, sumando 197 millones de dólares en criptodivisas explotadas.
Qué falló en el ataque Euler
Las empresas de seguridad de blockchain Omniscia y SlowMist han analizado el ataque para tratar de determinar qué podría haberlo evitado.
Según un informe de Omniscia del 13 de marzo, el principal problema de Euler era su función “donateToReserves”. Esta función permitía al atacante donar sus eDAI a las reservas de Euler, eliminando activos de su monedero sin eliminar una cantidad correspondiente de deuda. Omnisica afirma que esta función no estaba en la versión original de Euler, sino que se introdujo en la Propuesta de Mejora 14 de Euler (eIP-14).
El código de la eIP-14 revela que creó una función llamada donateToReserves, que permite al usuario transferir tokens de su propio saldo a una variable de protocolo llamada “assetStorage.reserveBalance.” Cada vez que se llama a esta función, el contrato emite un evento “RequestDonate” que proporciona información sobre la transacción.
Los datos de Blockchain muestran que este evento RequestDonate se emitió por un valor de 100 millones de tokens. Esta es la cantidad exacta que Etherscan muestra que se quemaron, empujando la cuenta a la insolvencia.
En su análisis del 15 de marzo, SlowMist acordó con Omniscia sobre la importancia de la función donateToReserve, declarando:
“El hecho de no comprobar si el usuario se encontraba en estado de liquidación tras donar fondos a la dirección de reserva provocaba la activación directa del mecanismo de liquidación suave”.
El atacante también podría haber sido capaz de llevar a cabo el ataque incluso si la función donar no hubiera existido. El código del contrato Euler “EToken.sol” en GitHub contiene una función estándar de “transferencia” ERC-20. Esto parece implicar que el atacante podría haber transferido sus eTokens a otro usuario aleatorio o a la dirección nula en lugar de donar, empujándose a sí mismo a la insolvencia de todos modos.
-Advertisement-
Sin embargo, el atacante optó por donar los fondos en lugar de transferirlos, lo que sugiere que la transferencia no habría funcionado.
Cointelegraph se ha puesto en contacto con Omniscia, SlowMist y el equipo de Euler para aclarar si la función donateToReserves era esencial para el ataque. Sin embargo, no ha recibido respuesta al cierre de esta edición.
Relacionado: El equipo de Euler niega que el detective de la cadena fuera sospechoso del hackeo
Las dos empresas coincidieron en que otra de las principales vulnerabilidades de Euler eran los elevados descuentos ofrecidos a los liquidadores. Según SlowMist, cuando un protocolo de préstamo tiene un “mecanismo de liquidación que actualiza dinámicamente los descuentos”, “crea oportunidades de arbitraje lucrativas para que los atacantes desvíen una gran cantidad de garantías sin necesidad de garantías o de reembolso de la deuda”. Omniscia hizo observaciones similares, declarando:
“Cuando el infractor se liquida, se aplica un descuento porcentual […] garantizando que estarán ‘a flote’ e incurrirán sólo en la deuda que corresponda a las garantías que adquieran”.
Cómo prevenir un futuro ataque de Euler
En su análisis, SlowMist aconsejaba a los desarrolladores cómo prevenir otro ataque del tipo Euler en el futuro. Argumentaba que los protocolos de préstamo no deberían permitir a los usuarios quemar activos si ello les va a generar una deuda incobrable, y afirmaba que los desarrolladores deberían tener cuidado al utilizar múltiples módulos que puedan interactuar entre sí de forma inesperada:
“El equipo de seguridad de SlowMist recomienda que los protocolos de préstamo incorporen las comprobaciones de salud necesarias en las funciones que implican fondos de los usuarios, al tiempo que consideran los riesgos de seguridad que pueden surgir de la combinación de diferentes módulos. Esto permitirá diseñar modelos económicos seguros y viables que mitiguen eficazmente tales ataques en el futuro.”
Un representante del desarrollador de DeFi, Spool, dijo a Cointelegraph que el riesgo tecnológico es una característica intrínseca del ecosistema DeFi. Aunque no se puede eliminar, se puede mitigar mediante modelos que califiquen adecuadamente los riesgos de los protocolos.
Según el libro blanco de gestión de riesgos de Spool utiliza una “matriz de riesgo” para determinar el grado de riesgo de los protocolos. Esta matriz tiene en cuenta factores como el rendimiento porcentual anual (APY) del protocolo, las auditorías realizadas sobre sus contratos, el tiempo transcurrido desde su despliegue, el valor total bloqueado (TVL) y otros para crear una calificación de riesgo. Los usuarios de Spool pueden emplear esta matriz para diversificar las inversiones DeFi y limitar los riesgos.
El representante dijo a Cointelegraph que la matriz de Spool redujo significativamente las pérdidas de los inversores por el incidente de Euler.
“En este incidente, las bóvedas inteligentes más afectadas, aquellas diseñadas por los usuarios para buscar rendimientos más altos (y más arriesgados), solo se vieron afectadas hasta en un 35%. La cámara acorazada menos afectada con exposición a estrategias Euler (a través de Harvest o Idle), en comparación, sólo se vio afectada en un 6%. Algunas bóvedas tenían exposición cero y, por tanto, no se vieron afectadas”, declararon.
Spool continuó: “Aunque esto no es lo ideal, demuestra claramente la capacidad de las cámaras acorazadas inteligentes para proporcionar modelos de riesgo a medida y distribuir los fondos de los usuarios entre múltiples fuentes de rendimiento.”
Cointelegraph obtuvo una respuesta similar de SwissBorg, otro protocolo DeFi que pretende ayudar a los usuarios a limitar el riesgo mediante la diversificación. El CEO de SwissBorg, Cyrus Fazel, declaró que la app de SwissBorg tiene “diferentes estrategias de rendimiento basadas en riesgo/tiempoAPY.”
Algunas estrategias aparecen como “1: núcleo = bajo”, mientras que otras aparecen como “2: aventurero = arriesgado”. Debido a que Euler recibió una calificación “2”, las pérdidas del protocolo se limitaron a sólo una pequeña parte del valor total bloqueado de SwissBorg, declaró Fazel.
El jefe de ingeniería de SwissBorg, Nicolas Rémond, aclaró además que el equipo emplea criterios sofisticados para determinar qué protocolos pueden figurar en la aplicación SwissBorg.
“Tenemos un proceso de diligencia debida para todas las plataformas DeFi antes de entrar en cualquier posición. Y luego, una vez que estamos allí, tenemos procedimientos de operación”, dijo, y añadió: “La diligencia debida tiene que ver con TVL, equipo, auditorías, código fuente abierto, TVL, ataque de manipulación de oráculo, etc.”. […] El procedimiento operativo trata de la supervisión de la plataforma, la supervisión de las redes sociales y algunas medidas de emergencia. Algunas siguen siendo manuales, pero estamos invirtiendo para automatizarlo todo a base de poder ser extremadamente reactivos.”
En un hilo de Twitter del 13 de marzo, el equipo de SwissBorg declaró que aunque el protocolo había perdido el 2,2% de los fondos de un pool y el 29,52% de otro, todos los usuarios serían compensados por SwissBorg en caso de que los fondos no fueran recuperables de Euler.
El ataque a Euler fue el peor exploit DeFi del primer trimestre de 2023. Afortunadamente, el atacante devolvió la mayor parte de los fondos, y la mayoría de los usuarios no deberían sufrir pérdidas. Pero el ataque plantea preguntas sobre cómo los desarrolladores y los usuarios pueden limitar el riesgo a medida que el ecosistema DeFi continúa expandiéndose.
Una combinación de diligencia por parte de los desarrolladores y diversificación de los inversores puede ser la solución al problema. En cualquier caso, es posible que se siga hablando del ataque de Euler en el futuro, aunque sólo sea por su magnitud y por ilustrar los riesgos de los exploits DeFi.
Source: COIN TELEGRAPH