Swap del mismo token en MonoX
$31 M drenados de los pools de MonoX cuando el atacante intercambió un token consigo mismo, inflando MONO en el oráculo hasta vaciar los pools.
- Fecha
- Víctima
- MonoX Finance
- Estado
- Fondos robados
El 30 de noviembre de 2021, el AMM de pool único MonoX Finance perdió aproximadamente $31 millones en sus despliegues en Ethereum y Polygon. El bug era casi demasiado simple para ser real: el contrato de swap no verificaba si el token de entrada y el token de salida eran el mismo.
Qué ocurrió
MonoX usaba un novedoso diseño de AMM de "pool único" donde cada token estaba emparejado contra el token de gobernanza MONO del protocolo internamente, en lugar de contra otros tokens directamente. Un swap del token A al token B se implementaba como A → MONO → B en dos pasos internos, cada uno actualizando los precios relevantes de los tokens.
La omisión fatal: la función de swap no validaba que tokenIn ≠ tokenOut. Cuando un usuario intercambiaba MONO por MONO, la lógica de actualización de precios se ejecutaba en ambas patas:
- La pata de "venta" del swap empujaba el precio de MONO hacia abajo (comportamiento típico de AMM).
- La pata de "compra" empujaba el precio de MONO hacia arriba.
- Crucialmente, las funciones de actualización de precios se ejecutaban secuencialmente, y la actualización del precio
tokenOutocurría al final — así que el protocolo terminaba la transacción con el precio de MONO masivamente inflado.
El ciclo de ataque:
- Intercambiar MONO por MONO repetidamente, inflando el precio registrado de MONO.
- Intercambiar el MONO artificialmente caro por activos reales — WETH, WMATIC, WBTC, USDC, USDT, LINK, GHST, DUCK, MIM, IMX.
- Repetir hasta vaciar cada pool.
Pérdidas totales en Polygon + Ethereum: ~2.100 WETH, 1,9 M WMATIC, 36 WBTC, $8,2 M USDC, $9,1 M USDT y una larga cola de otros tokens, sumando ~$31 M.
Consecuencias
- MonoX pausó ambos despliegues y anunció un plan de recuperación.
- El atacante blanqueó a través de Tornado Cash; sin recuperación pública.
- MonoX nunca volvió a su posición previa al incidente.
Por qué importa
MonoX es el caso de libro de texto de cómo una sola comprobación de igualdad faltante puede ser un primitivo de exploit totalmente cargado. El bug — require(tokenIn != tokenOut) — es exactamente una línea de código. Su ausencia costó $31 M.
La lección más profunda es la recurrente para diseños novedosos de AMM: cada invariante reclamado del AMM debe ser probado en todo el espacio de entradas, incluidos casos obviamente degenerados. El caso "intercambiar un token por sí mismo" es degenerado desde la perspectiva del usuario — nadie querría hacerlo. Desde la perspectiva del protocolo, es una ruta de actualización de estado que produce deriva de precio no restringida. Los frameworks modernos de pruebas de AMM (Echidna, invariantes de Foundry) generan específicamente entradas degeneradas para sacar a la luz exactamente esta clase de bug.
Fuentes y evidencia on-chain
- [01]slowmist.medium.comhttps://slowmist.medium.com/detailed-analysis-of-the-31-million-monox-protocol-hack-574d8c44a9c8
- [02]cryptobriefing.comhttps://cryptobriefing.com/monox-finance-drained-of-31m-in-latest-defi-hack/
- [03]immunebytes.comhttps://immunebytes.com/blog/monox-hack-incident-nov-30-2021-detailed-analysis/