Incidentes Asociados
La trágica combinación de errores inevitables y código inmutable
La semana pasada fue testigo de un evento catastrófico en el ecosistema Ethereum, cuando The DAO, un contrato inteligente de menos de dos meses, comenzó a filtrar fondos rápidamente a una parte desconocida. Mirando el conjunto actual de contratos de Ethereum, llenos de casinos y esquemas Ponzi autodeclarados, esto podría no parecer un gran problema. Es decir, hasta que te enteras de que casi 20 000 personas habían invertido más de 12 millones de unidades de ether, la criptomoneda Ethereum, en The DAO. Eso es alrededor del 15% de todo el ether existente, valorado en más de $250 millones el 17 de junio.
Dos días después, los activos de la DAO cayeron por debajo de los 100 millones de dólares. Dos cosas contribuyeron a esta precipitada caída. Primero, ya se había tomado un tercio de sus fondos (como se denominan en éter). Y segundo, el pánico resultante hizo que el precio de mercado del éter se desplomara desde su pico de más de $21 a $10,67 más aleccionadores. (En el momento de la publicación, el precio se había recuperado a alrededor de $ 14). Este segundo efecto fue una consecuencia natural del primero, ya que gran parte del aumento reciente en el valor de ether fue impulsado por personas que lo compraron para invertir en The DAO.
La DAO había prometido actuar como un nuevo tipo de vehículo de crowdsourcing descentralizado, como Kickstarter o Indiegogo, pero sin intermediarios ni regulación. Fue diseñado para permitir que los participantes agruparan sus criptomonedas, votaran colectivamente proyectos en busca de financiamiento, luego invirtieran y obtuvieran las recompensas futuras. Antes de que ocurriera la catástrofe, ya se habían propuesto más de 100 proyectos, la mayoría de los cuales estaban relacionados con el propio Ethereum. Además, la DAO permitió a los participantes retirar sus fondos no invertidos en cualquier momento, posicionándose como una inversión de bajo riesgo.
Irónicamente, el individuo o grupo que vació The DAO lo hizo explotando errores sutiles en este mecanismo de retiro. Como todos los contratos inteligentes en Ethereum, el DAO es solo una pieza de código de computadora, que está "inmutablemente" (es decir, permanente e irreversiblemente) incrustado en la cadena de bloques y ejecutado por cada nodo en respuesta a las transacciones entrantes. Y como cualquier contrato inteligente que se precie, The DAO brinda total transparencia al hacer que su código fuente sea fácilmente accesible en línea. Esto significa que cualquiera puede verificar de forma independiente su funcionalidad pero también, lo que es más importante, buscar vulnerabilidades. Y, sin embargo, la naturaleza inmutable de las cadenas de bloques evita que se solucionen tales problemas.
A fines de mayo, se destacaron varios problemas críticos en el destacado blog Hacking Distributed, junto con un llamado a una moratoria en las propuestas de proyectos para The DAO. Esto es lo que podríamos llamar el enfoque de "sombrero blanco", en el que se denuncian los exploits por el bien de la comunidad. No obstante, nadie parecía demasiado preocupado, ya que los problemas se relacionaban con incentivos económicos sesgados más que con un riesgo de robo total. Sin embargo, al mismo tiempo, parece que otros estaban estudiando detenidamente el código de The DAO con mayor interés propio, es decir, para buscar una manera de ganar mucho dinero. Y el 17 de junio, alguien lo logró.
Drenando el DAO
En un sentido general, el ataque surgió de la interacción entre vulnerabilidades en el código de The DAO y otro código diseñado para explotarlas. Verá, cuando se miró de forma aislada, la DAO no contenía ningún error obvio y, de hecho, solo se publicó después de una extensa auditoría de seguridad. Pero con el beneficio de la retrospectiva y muchos más ojos, desde entonces se ha encontrado una cantidad significativa de errores.
No proporcionaré una descripción técnica completa del mecanismo del exploit aquí, ya que otros ya han publicado autopsias magníficas y detalladas (ver aquí, aquí y aquí). Pero explicaré una vulnerabilidad particular que estaba presente, porque se ha descubierto en muchos otros contratos inteligentes y sirve como ejemplo instructivo.
Digamos que un contrato inteligente retiene fondos en nombre de varios usuarios y les permite retirar sus fondos a pedido. La lógica del proceso podría verse así:
Espere a que un usuario solicite un retiro. Compruebe si el saldo de ese usuario es suficiente. En caso afirmativo, envíe la cantidad solicitada a la dirección del usuario. Comprueba que el pago se ha realizado correctamente. De ser así, descontar la cantidad del saldo del usuario.
Todo esto parece eminentemente sensato, y más bien como un cajero automático que le da algo de efectivo y deduce la cantidad apropiada de su saldo bancario.
Entonces, ¿cómo puede salir mal este simple proceso? Bueno, resulta que si una dirección de Ethereum pertenece a un contrato en lugar de a un usuario regular, entonces este contrato puede ejecutar algún código en respuesta a la recepción de fondos. Y este código puede, a su vez, activar otras piezas de código en la cadena de bloques de Ethereum. De manera crucial, incluso puede activar el mismo código que hizo que se pagara en primer lugar.
Esto significa que, durante el paso 3 anterior, la dirección receptora puede enviar una nueva solicitud de retiro, comenzando un nuevo proceso en el paso 1 antes de que se complete el proceso anterior. Dado que el saldo del usuario solo se reduce en el paso 5, se realizará un nuevo retiro.