« Back to Glossary Index

Delegate Call Attack (Ataque Delegate Call)

⚡ Definición Rápida

Un Delegate Call Attack (Ataque de Llamada Delegada) es una vulnerabilidad de seguridad en contratos inteligentes de Ethereum donde un atacante explota la instrucción delegatecall para ejecutar código malicioso en el contexto de almacenamiento y balance de otro contrato. A diferencia de una llamada normal (call), delegatecall preserva el contexto del contrato que llama, permitiendo que el código de un contrato externo modifique el estado del contrato víctima. Un ataque exitoso puede resultar en el robo total de fondos, la toma de control de la propiedad del contrato o la corrupción irreversible de su estado.

Términos relacionados: sandwich attackReentrancy AttackSmart ContractProxy ContractEVM


❓ ¿Qué es un Delegate Call Attack y por qué es peligroso?

Un Delegate Call Attack explota una de las características más potentes y peligrosas de la Máquina Virtual de Ethereum (EVM): la instrucción delegatecall. Esta instrucción permite que un contrato ejecute el código de otro contrato, pero en su propio contexto. Esto significa que el código ejecutado puede leer y modificar el almacenamiento del contrato que llama, usar su balance de Ether y heredar su msg.sender y msg.value.

Esta funcionalidad es esencial para patrones de diseño avanzados como los contratos proxy upgradeables (que permiten actualizar la lógica de un contrato sin cambiar su dirección) y las bibliotecas reutilizables. Sin embargo, si no se implementa con sumo cuidado, un atacante puede engañar a un contrato para que ejecute delegatecall hacia un contrato malicioso que él mismo ha desplegado. Al hacerlo, el atacante obtiene el control total del estado del contrato víctima, pudiendo robar fondos, cambiar la propiedad o autodestruir el contrato.

El peligro radica en que la víctima no se da cuenta de que está ejecutando código externo. Es como si un banco le diera a un extraño las llaves de su caja fuerte, permitiéndole actuar como si fuera el gerente. El extraño puede cambiar los registros, vaciar la caja y cerrar la puerta, todo con la autoridad del banco.

📖 Definición Técnica

Técnicamente, un Delegate Call Attack ocurre cuando un contrato inteligente (el «contrato llamante») utiliza la instrucción de bajo nivel delegatecall para ejecutar el código de otro contrato (el «contrato objetivo») en su propio contexto de ejecución. La instrucción delegatecall carga el código del contrato objetivo y lo ejecuta utilizando el almacenamiento, el balance y la dirección del contrato llamante. Esto significa que cualquier modificación de variables de estado o transferencia de Ether realizada por el código objetivo afecta directamente al contrato llamante, no al objetivo.

Un ataque típico implica que el atacante despliega un contrato malicioso que contiene código diseñado para manipular el almacenamiento del contrato llamante. Luego, el atacante encuentra una manera de hacer que el contrato llamante ejecute delegatecall hacia su contrato malicioso. Esto puede suceder si el contrato llamante tiene una función que permite cambiar la dirección de la implementación (como en un proxy mal configurado) o si tiene una función que acepta una dirección de biblioteca como argumento sin validarla adecuadamente.


🏛️ Mecánica del Ataque: Cómo se ejecuta

Para entender cómo se ejecuta un Delegate Call Attack, es crucial comprender la diferencia entre delegatecall y call. La siguiente tabla lo resume:

Aspectocalldelegatecall
Contexto de ejecuciónDel contrato objetivo (el que recibe la llamada).Del contrato llamante (el que hace la llamada).
Almacenamiento modificadoAlmacenamiento del contrato objetivo.Almacenamiento del contrato llamante.
Balance de EtherEl balance del contrato objetivo se usa para pagar el gas y puede ser transferido.El balance del contrato llamante se usa y puede ser transferido.
msg.sender y msg.valueSe refieren al contrato llamante y al valor enviado en la transacción original.Se preservan de la transacción original, como si el código objetivo fuera parte del llamante.
Uso comúnInteractuar con otros contratos, enviar Ether.Patrones de biblioteca y contratos proxy upgradeables.
Riesgo de seguridadMenor, ya que el contrato llamante no expone su estado directamente.Alto, ya que el código externo tiene acceso completo al estado del llamante.

💰 Ejemplo de un Ataque Delegate Call

Imagina un contrato proxy simple que permite actualizar su lógica:

Un atacante despliega un contrato malicioso que se hace pasar por una nueva implementación:

Si el atacante logra llamar a upgradeTo (por ejemplo, si la función no está protegida o si roba la clave privada del propietario), puede establecer la dirección de su contrato malicioso. Luego, cualquier llamada al proxy (a través de fallback) ejecutará el código malicioso. Si el atacante llama a la función pwn() a través del proxy, el código de pwn() se ejecutará en el contexto del proxy, sobrescribiendo la variable owner del proxy con la dirección del atacante.


📈 Principales vectores de ataque y cómo prevenirlos

  • Contratos Proxy mal configurados: La causa más común. Si la función de actualización (upgradeTo) no está protegida adecuadamente o si el proxy permite llamadas directas a funciones de inicialización, un atacante puede tomar el control. Prevención: Usar patrones de proxy estándar como Transparent Proxy o UUPS, y proteger las funciones de administración con controles de acceso robustos (multisig, timelocks).
  • Bibliotecas con estado: Si una biblioteca utilizada vía delegatecall tiene sus propias variables de estado, puede haber colisiones de almacenamiento con el contrato llamante. Prevención: Las bibliotecas deben ser sin estado (stateless). Toda la información debe pasarse como argumentos.
  • Funciones de inicialización no protegidas: En los contratos proxy, la inicialización debe ocurrir una sola vez. Si una función initialize es pública y no tiene un modificador initializer, cualquiera puede llamarla y reescribir el estado. Prevención: Usar el modificador initializer de OpenZeppelin.
  • Llamadas delegatecall a direcciones arbitrarias: Si un contrato permite a los usuarios especificar la dirección de destino de un delegatecall (por ejemplo, para flexibilidad), es una puerta abierta a ataques. Prevención: No permitir direcciones arbitrarias. Si es necesario, usar una lista blanca de direcciones confiables y auditadas.
  • Falta de verificación de la dirección de implementación: En el fallback de un proxy, es crucial verificar que la dirección de implementación no sea cero y que contenga código. Prevención: Usar extcodesize para verificar que la dirección tenga código asociado.

🆚 Delegate Call Attack vs. Reentrancy Attack vs. Storage Collision Attack

Para entender mejor el Delegate Call Attack, es útil compararlo con otros ataques famosos de contratos inteligentes.

AspectoDelegate Call AttackReentrancy AttackStorage Collision Attack
Vulnerabilidad PrincipalUso inseguro de la instrucción delegatecall.Llamadas externas antes de actualizar el estado interno.Mala alineación del diseño de almacenamiento entre contratos.
Contexto ExplotadoEl contexto (almacenamiento, balance, msg.sender) del contrato llamante.La posibilidad de que un contrato receptor llame de vuelta al remitente antes de que se complete la transacción.La determinística asignación de slots de almacenamiento en la EVM.
Objetivo del AtacanteTomar control del estado del contrato víctima (robar fondos, cambiar propiedad).Drenar los fondos de un contrato llamando repetidamente a una función de retiro.Sobrescribir variables de estado críticas del contrato llamante.
Prevención ClavePatrones de proxy seguros (UUPS/Transparent), bibliotecas sin estado, control estricto de direcciones de implementación.Patrón Checks-Effects-Interactions, guardias de reentrada (nonReentrant).Uso de slots de almacenamiento estandarizados (ERC-1967), contratos de almacenamiento base compartido.
Ejemplo HistóricoParity Multisig Hack (Congelación – Nov 2017).The DAO Hack (2016).Parity Multisig Hack (Robo – Jul 2017).

✅ Buenas prácticas para prevenir ataques Delegate Call

  • Usar patrones de proxy estándar: Implementa patrones como Transparent Proxy o UUPS (EIP-1822). Estos patrones han sido auditados y probados extensamente, y manejan correctamente la separación de responsabilidades y la prevención de colisiones de almacenamiento.
  • Utilizar bibliotecas de código probadas: Usa bibliotecas como las de OpenZeppelin para implementar proxies, control de acceso y funciones de inicialización. No reinventes la rueda.
  • Mantener las bibliotecas sin estado: Las bibliotecas diseñadas para ser usadas con delegatecall no deben tener variables de estado propias. Toda la información debe pasarse como argumentos de función.
  • Proteger las funciones de actualización: Las funciones que permiten cambiar la dirección de implementación deben estar protegidas con controles de acceso robustos, como un multisig o un timelock, para evitar cambios maliciosos repentinos.
  • Realizar auditorías de seguridad exhaustivas: Cualquier contrato que utilice delegatecall debe ser auditado por profesionales de seguridad especializados en contratos inteligentes. Las auditorías deben centrarse en el diseño de almacenamiento y los permisos de actualización.
  • Usar herramientas de verificación de almacenamiento: Herramientas como el plugin de OpenZeppelin Upgrades para Hardhat verifican automáticamente que no haya colisiones de almacenamiento al desplegar contratos upgradeables.

⚠️ Críticas y desafíos

  • Complejidad técnica: El uso de delegatecall añade una capa significativa de complejidad al desarrollo de contratos inteligentes. Los desarrolladores deben comprender profundamente cómo funciona la EVM y el almacenamiento para evitar errores.
  • Riesgo de errores humanos: Incluso con patrones estándar, un pequeño error en la configuración (como olvidar un modificador onlyOwner) puede tener consecuencias catastróficas.
  • Dependencia de bibliotecas externas: Si bien las bibliotecas como OpenZeppelin son ampliamente confiables, también pueden contener vulnerabilidades. Es importante mantenerlas actualizadas y revisar los cambios.
  • Falsa sensación de seguridad: El hecho de que un contrato use un patrón de proxy estándar no lo hace inmune a todos los ataques. La lógica de la implementación también debe ser segura.
  • Irreversibilidad de los ataques: Debido a la naturaleza inmutable de la blockchain, un ataque exitoso de delegatecall suele ser irreversible. Los fondos robados no se pueden recuperar y el estado del contrato no se puede restaurar.

🧠 Guía práctica: Cómo protegerte como desarrollador y usuario

  • Si eres desarrollador: Nunca implementes tu propio patrón de proxy desde cero. Usa las bibliotecas estandarizadas de OpenZeppelin. Aprende a usar el plugin de Upgrades para Hardhat. Siempre verifica que tus contratos de implementación no tengan variables de estado que puedan colisionar con el proxy.
  • Si eres usuario o inversor: Antes de interactuar con un protocolo DeFi que sea «upgradeable», investiga si ha sido auditado por firmas de seguridad reputadas. Busca información sobre si el equipo tiene un multisig o un timelock para controlar las actualizaciones. Desconfía de proyectos que puedan cambiar su lógica sin previo aviso.
  • Si eres auditor: Presta especial atención a cualquier uso de delegatecall en el código. Verifica que la dirección de destino esté controlada y que no se puedan inyectar direcciones arbitrarias. Revisa el diseño de almacenamiento de los contratos proxy y de implementación para detectar posibles colisiones.
  • Si formas parte de una DAO: Asegúrate de que los contratos que gestionan el tesoro de la DAO sigan las mejores prácticas de seguridad. Considera la posibilidad de utilizar un contrato proxy con un timelock y un multisig para las actualizaciones.

🔮 El futuro de la seguridad contra Delegate Call Attacks

La seguridad en el espacio de los contratos inteligentes es un campo en constante evolución. Las perspectivas para el futuro incluyen:

  • Herramientas de análisis estático más avanzadas: Surgirán herramientas que puedan detectar automáticamente vulnerabilidades relacionadas con delegatecall en el código fuente, incluso en patrones complejos.
  • Lenguajes de contratos inteligentes más seguros: Lenguajes como Vyper y Fe están diseñados para ser más seguros que Solidity, limitando o eliminando el uso de características peligrosas como delegatecall.
  • Estandarización de patrones de proxy: La comunidad de Ethereum continuará estandarizando y mejorando los patrones de proxy (como el ERC-1967) para hacerlos más seguros y fáciles de usar.
  • Verificación formal: La verificación formal, que utiliza métodos matemáticos para probar la corrección del código, se volverá más accesible y se aplicará a contratos que utilicen delegatecall para garantizar su seguridad.
  • Educación y concienciación: A medida que la comunidad de desarrolladores de Ethereum crezca, también lo hará la educación sobre los peligros de delegatecall. Las mejores prácticas se difundirán más ampliamente.

🎯 Conclusión: El poder de delegatecall debe ser respetado

El Delegate Call Attack es uno de los vectores de ataque más peligrosos en el ecosistema de contratos inteligentes de Ethereum. Explota una característica poderosa pero intrínsecamente riesgosa, y sus consecuencias pueden ser catastróficas, como lo demostró el infame hack de Parity Multisig que congeló cientos de millones de dólares en Ether.

La lección principal es que el poder de delegatecall debe ser tratado con el máximo respeto. No es una herramienta para ser utilizada a la ligera. Su implementación requiere un profundo conocimiento de la EVM, un diseño cuidadoso y una adhesión rigurosa a patrones de seguridad probados. Para los desarrolladores, la regla de oro es simple: no implementes tu propio patrón de proxy. Usa bibliotecas estandarizadas, realiza auditorías exhaustivas y nunca confíes en direcciones arbitrarias.

Para los usuarios, la conclusión es ser conscientes de los riesgos asociados con los contratos upgradeables. Investiga los proyectos en los que inviertes y prefiere aquellos que demuestren un compromiso serio con la seguridad, mediante auditorías, timelocks y equipos transparentes. La seguridad en DeFi es una responsabilidad compartida, y entender estos ataques es el primer paso para protegerse.

❓ Preguntas Frecuentes sobre Delegate Call Attack


📚 ¿Quieres profundizar en seguridad de contratos inteligentes?

Explora más recursos de La Cryptoguía sobre seguridad y desarrollo en blockchain:

🛡️ Reentrancy Attack - Otro de los ataques más famosos en Ethereum.

🏗️ Storage Collision Attack - Un vector de ataque relacionado y a menudo combinado.

🔷 ¿Qué es Blockchain? - La base tecnológica para entender los contratos inteligentes.

💡 ¿Cómo auditar un token? - Aprende a identificar vulnerabilidades técnicas complejas.


🚀 ¿Empezando en Crypto?

Si eres nuevo, empieza con nuestra guía completa para principiantes para entender los fundamentos antes de adentrarte en la seguridad de contratos inteligentes.


📋 ¿Por qué confiar en esta definición? Cada término de la Cryptopedia sigue una metodología de verificación con fuentes primarias, whitepapers y legislación oficial. Conoce nuestro proceso →


⚠️ Disclaimer: Este artículo es informativo y educativo. No constituye asesoramiento de seguridad, de desarrollo de software o financiero. Los ataques por Delegate Call son un vector técnico avanzado con consecuencias potencialmente catastróficas. La seguridad de los contratos inteligentes es un campo complejo. Siempre busca auditorías profesionales de múltiples firmas, utiliza bibliotecas estandarizadas y probadas, y prueba exhaustivamente en entornos de testnet antes de cualquier despliegue en mainnet. La Cryptoguía no se responsabiliza de pérdidas o daños derivados de la aplicación de este contenido.

📅 Actualizado: Marzo 2026
📖 Categoría: Seguridad y Riesgos / Auditoría y Smart Contracts

« Volver al Glosario
Scroll al inicio