Back to Blog

#9 Incidente 1inch: De la Corrupción de Calldata a la Liquidación Falsificada: La Explotación Binaria Llega a la Cadena de Bloques

Code Auditing
February 13, 2026
8 min read

El 5 de marzo de 2025, un contrato resolvedor de terceros integrado con el protocolo Fusion V1 de 1inch sufrió un exploit coordinado que resultó en pérdidas totales de más de $5 millones. La causa raíz fue una reconstrucción insegura de calldata en el flujo de liquidación, donde una longitud de interacción controlada por el atacante desencadenó un desbordamiento inferior de puntero durante el ensamblaje del sufijo, permitiendo que se inyectaran datos de liquidación falsificados. El exploit fue habilitado además por un límite de confianza mal ubicado: los contratos resolutores confiaban implícitamente en todos los calldata reenviados por el contrato de liquidación basándose únicamente en msg.sender, lo que causó que los datos controlados por el atacante heredaran autoridad a nivel de liquidación a pesar de pasar todas las verificaciones de control de acceso.

Este incidente se destaca como uno de los exploits de DeFi más sofisticados de 2025, no por tratarse de un primitivo financiero novedoso, sino por su explotación de suposiciones de bajo nivel sobre ABI y diseño de memoria, difuminando la línea entre las vulnerabilidades de contratos inteligentes y las técnicas clásicas de explotación binaria.

Contexto

El protocolo Fusion V1 de 1inch

1inch es un agregador de intercambio descentralizado (DEX) que obtiene liquidez de múltiples DEXs para proporcionar a los usuarios una ejecución de intercambio optimizada. Construido sobre la infraestructura de órdenes limitadas del agregador, 1inch Fusion introduce un modelo de emparejamiento de órdenes basado en subasta holandesa, que permite a los usuarios especificar parámetros de ejecución flexibles como rangos de precios y ventanas de tiempo de intercambio.

En el modelo Fusion, las órdenes de los usuarios no son completadas directamente por el propio protocolo. En cambio, son ejecutadas por actores especializados conocidos como resolutores. Los resolutores pueden verse como participantes privilegiados y aprobados: para ser elegibles, deben apostar tokens para obtener suficiente Unicorn Power, que sirve como mecanismo de control económico de acceso.

Operacionalmente, los resolutores ejecutan su propia infraestructura fuera de la cadena que interactúa con las APIs del backend de 1inch para descubrir órdenes de usuarios y determinar si y cuándo completarlas. Una vez que un resolutor decide ejecutar una orden, envía una transacción en cadena a través de una cuenta dedicada al contrato Settlement, que realiza el intercambio real. (Si bien Fusion involucra una subasta holandesa competitiva entre resolutores, este mecanismo no es esencial para entender el ataque y por lo tanto se omite aquí; por simplicidad, asumimos que el resolutor puede satisfacer directamente las condiciones de la orden del usuario.)

Al ejecutar un intercambio, un resolutor puede obtener liquidez de mercados externos para ofrecer una mejor ejecución que los requisitos mínimos del usuario, o liquidar directamente la operación usando sus propios activos. Cualquier valor excedente generado en el proceso se acumula para el resolutor como ganancia. El ataque discutido en este blog apunta a dicho contrato resolutor. Específicamente, un contrato utilizado para la creación de mercado en cadena que tenía activos y había otorgado aprobaciones al contrato Settlement, lo que en última instancia condujo a la pérdida de esos activos.

Procesamiento y Cumplimiento de Órdenes

La ejecución de órdenes en 1inch Fusion es coordinada por el contrato Settlement y sigue un modelo de liquidación recursiva impulsado por datos de interacción en lugar de un flujo de ejecución lineal.

El proceso comienza cuando un resolutor llama a la función settleOrders(), pasando calldata que codifica la primera orden junto con un payload de interacción. En lugar de intentar liquidar todas las órdenes a la vez, Settlement las procesa de forma incremental mediante invocaciones repetidas de la función interna _settleOrder().

Para cada orden, la función _settleOrder() reconstruye en memoria una llamada al Protocolo de Órdenes Limitadas (AggregationRouterV5.fillOrderTo()). Durante esta reconstrucción, Settlement agrega contexto adicional relacionado con el resolutor a los datos de interacción en forma de un sufijo dinámico. Este sufijo lleva metadatos de ejecución como la identidad del resolutor y las comisiones acumuladas, y es tratado como opaco por el Protocolo de Órdenes Limitadas. Se reenvía sin cambios y luego es decodificado por el propio Settlement durante la devolución de llamada de interacción.

Después de que la orden es completada, el control regresa a Settlement a través de la función fillOrderInteraction(). Según los datos de interacción, Settlement continúa la liquidación invocando recursivamente la función _settleOrder() con el payload de interacción restante, o pasa a una etapa de finalización. En la etapa final, Settlement transfiere el control al contrato resolutor invocando su función resolveOrders(), pasando el contexto de ejecución acumulado.

Este diseño permite que múltiples órdenes se liquiden secuencialmente dentro de una sola transacción mientras se difiere la lógica específica del resolutor hasta que todos los pasos de ejecución a nivel de protocolo se hayan completado.

Análisis de la Vulnerabilidad

La vulnerabilidad surge de una lógica de reconstrucción de calldata insegura en la función interna _settleOrder(), específicamente durante la colocación del sufijo dinámico que se agrega a los datos de interacción.

Los contratos resolutores están protegidos por control de acceso explícito: requieren que las llamadas se originen desde el contrato Settlement y que la dirección del resolutor suministrada durante la resolución coincida con el propio contrato resolutor. Estas verificaciones asumen que la identidad del resolutor propagada a través del proceso de liquidación se construye correctamente y permanece intacta. Esta suposición depende de la corrección de cómo los datos relacionados con el resolutor se codifican y se agregan durante la reconstrucción del calldata.

Concretamente, la función resolveOrders() del resolutor aplica dos guardas:

require(msg.sender == _settlement, OnlySettlement());
require(this == resolver, NotTaker());

La primera verificación confirma que la llamada se origina desde el contrato Settlement. La segunda confirma que el parámetro resolver (decodificado del sufijo) coincide con la propia dirección del contrato resolutor. En condiciones normales, ambos campos son establecidos correctamente por _settleOrder(). Durante el ataque, ambas verificaciones siguen pasando: el atacante opera dentro del flujo de liquidación (no fuera de él), por lo que msg.sender es genuinamente el contrato Settlement; y el campo resolver se decodifica del sufijo falsificado, donde el atacante ha escrito la dirección del resolutor víctima.

Durante la liquidación, _settleOrder() reconstruye calldata en memoria y agrega un sufijo dinámico que lleva el contexto de ejecución específico del resolutor. Este sufijo incluye no solo la dirección del resolutor, sino también información relacionada con la orden en la que el resolutor se basa para interpretar la liquidación como legítima. El sufijo se escribe en una ubicación de memoria calculada como ptr + interactionOffset + interactionLength, donde interactionLength se lee directamente del calldata como un valor de 32 bytes completo.

Dado que este cálculo de desplazamiento se realiza sin verificación de límites, un atacante puede controlar interactionLength para inducir un desbordamiento aritmético y manipular dónde se escribe el sufijo en memoria. Al hacerlo, el atacante puede reemplazar el sufijo previsto con uno falsificado, proporcionando una dirección de resolutor arbitraria junto con contexto de orden controlado por el atacante.

Como resultado, cuando el flujo de liquidación decodifica posteriormente el sufijo, puede interpretar la ejecución como originada por un resolutor legítimo e involucrando datos de orden válidos, aunque ninguna de las dos suposiciones sea correcta. El atacante puede efectivamente inyectar su propia versión del sufijo de la orden mientras finge ser el resolutor para intercambiar unos pocos wei por millones.

Análisis del Ataque

Tomando la transacción 0x74bc como ejemplo. El ataque comienza con la creación de cinco órdenes válidas que intercambian una cantidad insignificante de tokens (unos pocos wei) por una cantidad de salida desproporcionadamente grande. Estas órdenes son sintácticamente válidas y pasan las verificaciones a nivel de protocolo.

El atacante luego rellena el calldata de la orden con una gran región de bytes nulos. Este relleno sirve como un área de memoria controlada que luego será sobrescrita debido a la colocación incorrecta del sufijo.

De manera crucial, el atacante especifica un valor interactionLength inválido para la orden final. El valor se elige como 0xffff…fe00, que corresponde a -512 cuando se interpreta como un entero con signo. Dado que interactionLength se trata como un valor de 256 bits sin signo y se usa directamente en aritmética de punteros, esto provoca un desbordamiento aritmético al calcular el desplazamiento de escritura del sufijo.

La estructura de interacción maliciosa que se muestra a continuación se trata como un sufijo:

Del Sufijo Falsificado a la Extracción de Activos

Cuando Settlement procesa la orden final, el desbordamiento hace que el sufijo legítimo se escriba en la región rellena con nulos, sobrescribiendo ceros de manera inofensiva. El sufijo falsificado colocado por el atacante en la posición de lectura real se interpreta entonces como contexto de liquidación legítimo.

El sufijo falsificado establece el indicador de finalización, lo que hace que Settlement pase del procesamiento recursivo de órdenes a la etapa de finalización. Settlement llama a resolveOrders() en la dirección decodificada del sufijo, que es el resolutor víctima. Como se describe en el Análisis de la Vulnerabilidad, ambas verificaciones de control de acceso pasan: msg.sender es el contrato Settlement (la llamada fluye a través del camino de liquidación legítimo), y resolver coincide con la dirección de la víctima (escrita en el sufijo falsificado por el atacante).

El resolutor víctima luego procesa el array tokensAndAmounts, que incluye las direcciones de activos y los montos elegidos por el atacante. Dado que el resolutor había otorgado previamente aprobaciones de tokens al contrato Settlement para su operación normal, la transferencia se ejecuta. El resolutor envía sus activos retenidos para cumplir órdenes que solo requerían unos pocos wei de entrada, resultando en pérdidas de más de $5 millones.

Resumen

Este incidente apuntó a un contrato resolutor de terceros integrado con el protocolo Fusion V1 obsoleto de 1inch, resultando en pérdidas sustanciales, lo que pone de relieve varias lecciones importantes.

  • Suposiciones de Datos Inseguras: Los sistemas que dependen de datos de entrada construidos dinámicamente no deben asumir la integridad de longitudes, desplazamientos o estructuras cuando cualquier parte está influenciada por el usuario.
  • Cadenas de Confianza Implícitas: Las verificaciones de seguridad pueden verse comprometidas cuando los contratos dependen de componentes ascendentes para preservar el contexto crítico, en lugar de validarlo en cada límite.
  • Superficie de Ataque Heredada: Mantener componentes obsoletos aumenta la superficie de ataque y hace que los protocolos sean más vulnerables a técnicas de explotación novedosas.
  • Patrones de Explotación entre Dominios: Las vulnerabilidades comunes en el software tradicional pueden reaparecer en cadena cuando se involucra lógica de memoria o diseño de datos de bajo nivel.

Referencia

  1. https://blog.decurity.io/yul-calldata-corruption-1inch-postmortem-a7ea7a53bfd9

  2. https://paragraph.com/@cookies-research/1inch-fusion-cost-efficient-mev-resistant-swaps

  3. https://blog-zh.1inch.com/fusion-swap-resolving-onchain-component/#steps-5-6


Acerca de BlockSec

BlockSec es un proveedor integral de seguridad blockchain y cumplimiento de criptomonedas. Desarrollamos productos y servicios que ayudan a los clientes a realizar auditorías de código (incluyendo contratos inteligentes, blockchain y billeteras), interceptar ataques en tiempo real, analizar incidentes, rastrear fondos ilícitos y cumplir con las obligaciones AML/CFT, a lo largo del ciclo de vida completo de protocolos y plataformas.

BlockSec ha publicado múltiples artículos de seguridad blockchain en conferencias de prestigio, ha reportado varios ataques de día cero en aplicaciones DeFi, ha bloqueado múltiples hackeos para rescatar más de 20 millones de dólares y ha asegurado miles de millones en criptomonedas.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit