¡Creo que Uniswap v4 estará disponible para todos pronto!

Esta vez, el equipo de Uniswap tiene objetivos ambiciosos y planea introducir muchas características nuevas [1], incluido el soporte para un número ilimitado de fondos de liquidez y tarifas dinámicas para cada par comercial, diseño singleton, contabilidad relámpago, Hooks y soporte para el token ERC1155. estándar. Aprovechando el almacenamiento transitorio introducido por EIP-1153, se espera que Uniswap v4 se lance después de la actualización de Ethereum Cancún.

Entre muchas innovaciones, el mecanismo Hook ha atraído una gran atención debido a su poderoso potencial. El mecanismo Hook admite la ejecución de código específico en puntos específicos del ciclo de vida del fondo de liquidez, lo que mejora en gran medida la escalabilidad y flexibilidad del fondo.

Sin embargo, el mecanismo de gancho también puede ser un arma de doble filo. Aunque es potente y flexible, utilizar Hook de forma segura también supone un gran desafío. La complejidad de los ganchos trae inevitablemente nuevos vectores de ataque potenciales. Por lo tanto, esperamos escribir una serie de artículos para presentar sistemáticamente los problemas de seguridad y los riesgos potenciales relacionados con el mecanismo Hook, a fin de promover el desarrollo de la seguridad de la comunidad. Creemos que estos conocimientos ayudarán a construir un Hook Uniswap v4 seguro.

Como comienzo de esta serie de artículos, este artículo presenta conceptos relacionados con el mecanismo Hook en Uniswap v4 y describe los riesgos de seguridad del mecanismo Hook.

El mecanismo de Uniswap V4

Antes de profundizar, debemos tener un conocimiento básico de la mecánica de Uniswap v4. Según el anuncio oficial [1] y el documento técnico [2], los Hooks, la arquitectura singleton y la contabilidad relámpago son tres funciones importantes para implementar fondos de liquidez personalizados y lograr un enrutamiento eficiente entre múltiples fondos.

1.1 Gancho

Los ganchos se refieren a contratos que se ejecutan en diferentes etapas del ciclo de vida del fondo de liquidez. El equipo de Uniswap espera permitir que cualquiera pueda tomar decisiones de compensación mediante la introducción de ganchos. De esta manera, es posible admitir de forma nativa tarifas dinámicas, agregar órdenes de límite de precio en cadena o distribuir órdenes grandes a través de un creador de mercado promedio ponderado en el tiempo (TWAMM).

Actualmente hay ocho devoluciones de llamada de Hook, divididas en cuatro grupos (cada grupo contiene un par de devoluciones de llamada):

  • antes de inicializar/después de inicializar

  • antes de modificar posición/después de modificar posición

  • antes del intercambio/después del intercambio

  • antes de donar/después de donar

El siguiente es el proceso de intercambio de Hooks presentado en el documento técnico [2].

Figura 1: Proceso de Exchange Hook

El equipo de Uniswap presentó cómo hacerlo con algunos ejemplos (como TWAMM Hook[3]), y los participantes de la comunidad también hicieron algunas contribuciones. La documentación oficial[4] también enlaza con el repositorio Awesome Uniswap v4 Hooks[5], que recopila más ejemplos de Hook.

1.2 Mecanismo de bloqueo, contabilidad de rayos y singleton

La arquitectura Singleton y la contabilidad flash están diseñadas para mejorar el rendimiento al reducir los costos y garantizar la eficiencia. Introduce un nuevo contrato singleton, donde todos los fondos de liquidez se mantienen en el mismo contrato inteligente. Este diseño singleton se basa en un PoolManager para almacenar y administrar el estado de todos los grupos.

En versiones anteriores del protocolo Uniswap, operaciones como el intercambio o la adición de liquidez implicaban transferencias directas de tokens. La versión v4 se diferencia en que introduce una contabilidad relámpago y un mecanismo de bloqueo.

El mecanismo de bloqueo funciona de la siguiente manera:

1. Un contrato de casillero solicita un bloqueo en PoolManager.

2. PoolManager agrega la dirección del contrato del casillero a la cola lockData y llama a su devolución de llamada lockAcquired.

3. El contrato de casillero ejecuta su lógica en la devolución de llamada. Durante la ejecución, la interacción del contrato de casillero con el grupo puede resultar en incrementos de moneda distintos de cero. Sin embargo, al final de la ejecución, todos los deltas deben llegar a cero. Además, si la cola lockData no está vacía, solo el último contrato de casillero puede realizar operaciones.

4. PoolManager verifica el estado de la cola lockData y el incremento de moneda. Después de la verificación, PoolManager eliminará el contrato del casillero.

En resumen, el mecanismo de bloqueo evita el acceso simultáneo y garantiza que todas las transacciones puedan borrarse. El contrato de casillero se aplica a los bloqueos en secuencia y luego ejecuta transacciones a través de la devolución de llamada lockAcquired. La devolución de llamada de Hook correspondiente se activará antes y después de cada operación del grupo. Finalmente, el PoolManager comprueba el estado.

Este enfoque significa que la operación ajusta el saldo neto interno (es decir, delta) en lugar de realizar una transferencia instantánea. Cualquier modificación se registrará en el saldo interno del pool y la transferencia real se realizará al final de la operación (es decir, bloqueo). Este proceso garantiza que no queden tokens pendientes, manteniendo así la integridad de los fondos.

Debido al mecanismo de bloqueo, las Cuentas de propiedad externa (EOA) no pueden interactuar directamente con PoolManager. En cambio, cualquier interacción debe ocurrir a través de un contrato. Este contrato actúa como un casillero intermedio y debe solicitar un candado antes de realizar cualquier operación en la piscina.

Hay dos escenarios principales de interacción contractual:

  • Un determinado contrato de casillero proviene del código base oficial o lo implementan los usuarios. En este caso, podemos pensar que la interacción se realiza a través del enrutador.

  • Un contrato de casillero y Hook están integrados en el mismo contrato o controlados por una entidad de terceros. En este caso, podemos pensar que la interacción se produce a través de Hooks. En este caso, Hook desempeña el papel de contrato de casillero y es responsable de manejar las devoluciones de llamada.

Modelo de amenaza

Antes de discutir cuestiones de seguridad relacionadas, debemos identificar el modelo de amenaza. Consideramos principalmente las siguientes dos situaciones:

  • Modelo de amenaza I: los ganchos en sí son benignos, pero tienen vulnerabilidades.

  • Modelo de amenaza II: los ganchos son inherentemente maliciosos.

En las siguientes secciones, analizamos posibles problemas de seguridad basados ​​en estos dos modelos de amenazas.

2.1 Problemas de seguridad en el modelo de amenaza I

El modelo de amenazas I se centra en las vulnerabilidades relacionadas con el propio Hook. Este modelo de amenaza supone que los desarrolladores y sus Hooks son inofensivos. Sin embargo, las vulnerabilidades conocidas existentes en los contratos inteligentes también pueden aparecer en Hooks. Por ejemplo, si un Hook se implementa como un contrato actualizable, puede encontrar problemas relacionados con la vulnerabilidad UUPSUpgradeable de OpenZeppelin.

En vista de los factores anteriores, decidimos centrarnos en las posibles vulnerabilidades exclusivas de la versión v4. En Uniswap v4, los Hooks son contratos inteligentes capaces de ejecutar lógica personalizada antes o después de las operaciones del grupo central, incluida la inicialización, la modificación de la posición, el intercambio y la recopilación. Si bien se espera que los Hooks implementen interfaces estándar, también permiten la inclusión de lógica personalizada. Por lo tanto, nuestra discusión se limitará a la lógica que involucra la interfaz Hook estándar. Luego intentaremos identificar posibles fuentes de vulnerabilidades, por ejemplo, cómo los Hooks podrían abusar de estas funciones estándar de Hook.

Específicamente, nos centraremos en los siguientes dos tipos de Hooks:

  • El primer gancho es conservar los fondos de los usuarios. En este caso, un atacante puede atacar este gancho para transferir fondos, provocando la pérdida de activos.

  • El segundo tipo de gancho almacena datos de estado clave en los que confían los usuarios u otros protocolos. En este caso, el atacante puede intentar cambiar el estado crítico. Pueden surgir riesgos potenciales cuando otros usuarios o protocolos utilizan un estado incorrecto.

Tenga en cuenta que los ganchos fuera de estos dos ámbitos están fuera del alcance de nuestra discusión.

Dado que no existen casos de uso reales para Hooks al momento de escribir este artículo, extraeremos información del repositorio de Awesome Uniswap v4 Hooks.

Después de una inmersión profunda en el repositorio Awesome Uniswap v4 Hooks (commit hash 3a0a444922f26605ec27a41929f3ced924af6075), descubrimos varias vulnerabilidades críticas. Estas vulnerabilidades se originan principalmente en interacciones riesgosas entre ganchos, PoolManager y terceros externos, y se pueden dividir principalmente en dos categorías: problemas de control de acceso y problemas de validación de entradas. Consulte la siguiente tabla para conocer hallazgos específicos:

En total, encontramos 22 proyectos relevantes (excluyendo proyectos no relacionados con Uniswap v4). Entre estos proyectos, creemos que 8 (36%) proyectos son vulnerables. De los ocho proyectos vulnerables, seis tenían problemas de control de acceso y dos eran vulnerables a llamadas externas no confiables.

2.1.1 Problemas de control de acceso

En esta parte de la discusión, nos centramos principalmente en los problemas que pueden ser causados ​​por las funciones de devolución de llamada en v4, incluidas las devoluciones de llamada de 8 ganchos y las devoluciones de llamada de bloqueo. Por supuesto, hay otras situaciones que deben verificarse, pero estas situaciones varían según el diseño y están más allá del alcance de nuestra discusión.

Estas funciones solo deben ser invocadas por PoolManager y no pueden ser invocadas por otras direcciones (incluidos EOA y contratos). Por ejemplo, en el caso de que las recompensas se distribuyan mediante claves de grupo, las recompensas pueden reclamarse incorrectamente si cualquier cuenta puede llamar a la función correspondiente.

Por lo tanto, es crucial establecer mecanismos sólidos de control de acceso para los ganchos, especialmente porque pueden ser invocados por partes distintas al propio grupo. Al gestionar estrictamente los derechos de acceso, los fondos de liquidez pueden reducir significativamente el riesgo de interacciones no autorizadas o maliciosas con los ganchos.

2.1.2 Problemas de verificación de entrada

En Uniswap v4, debido al mecanismo de bloqueo, los usuarios deben obtener un bloqueo a través del contrato antes de realizar cualquier operación del fondo común. Esto garantiza que el contrato que participa actualmente en la interacción sea el último contrato de casillero.

No obstante, todavía existe un posible escenario de ataque, concretamente llamadas externas que no son de confianza debido a una validación de entrada incorrecta en algunas implementaciones de Hook vulnerables:

  • En primer lugar, el gancho no verifica el conjunto de fondos con el que el usuario pretende interactuar. Podría tratarse de un grupo malicioso que contenga tokens falsos y ejecute lógica dañina.

  • En segundo lugar, algunas funciones de enlace clave permiten llamadas externas arbitrarias.

Las llamadas externas que no son de confianza son extremadamente peligrosas porque pueden provocar varios tipos de ataques, incluido lo que conocemos como ataques de reentrada.

Para atacar estos ganchos vulnerables, un atacante puede registrar un fondo de fondos malicioso para sus propios tokens falsos y luego llamar al gancho para realizar operaciones en el fondo de fondos. Al interactuar con el grupo, la lógica del token malicioso secuestra el flujo de control para realizar un comportamiento no deseado.

2.1.3 Medidas preventivas frente a amenazas modelo I

Para evitar estos problemas de seguridad relacionados con los ganchos, es crucial autenticar las interacciones aplicando adecuadamente los controles de acceso necesarios a funciones públicas/externas sensibles y validando los parámetros de entrada. Además, la protección de reentrada puede ayudar a garantizar que el enlace no se ejecute repetidamente en el flujo lógico estándar. Al implementar salvaguardas de seguridad adecuadas, los pools pueden reducir los riesgos asociados con tales amenazas.

2.2 Problemas de seguridad en el modelo de amenazas II

En este modelo de amenaza, asumimos que el desarrollador y su gancho son maliciosos. Debido al amplio alcance, sólo nos centramos en cuestiones de seguridad relacionadas con la versión v4. Por lo tanto, la clave es si el enlace proporcionado puede manejar los criptoactivos transferidos o autorizados por el usuario.

Dado que el método de acceso al gancho determina los permisos que se le pueden otorgar, dividimos el gancho en dos categorías:

  • Ganchos administrados: los ganchos no son puntos de entrada. Los usuarios deben interactuar con el gancho a través de un enrutador (posiblemente proporcionado por Uniswap).

  • Ganchos independientes: los ganchos son puntos de entrada que permiten a los usuarios interactuar con ellos directamente.

Figura 2: Ejemplo de un gancho malicioso

2.2.1 Gancho administrado

En este caso, los criptoactivos del usuario (incluidos los tokens nativos y otros tokens) se transfieren o autorizan al enrutador. Dado que PoolManager realiza comprobaciones de saldo, no es fácil para los ganchos maliciosos robar directamente estos activos. Sin embargo, todavía existe una posible superficie de ataque. Por ejemplo, los atacantes pueden manipular el mecanismo de gestión de gastos de la versión v4 mediante ganchos.

2.2.2 Gancho independiente

La situación es aún más complicada cuando se utilizan ganchos como puntos de entrada. En este caso, el gancho gana más potencia ya que el usuario puede interactuar con él directamente. En teoría, un gancho puede hacer lo que quiera con esta interacción.

En la versión v4, la verificación de la lógica del código es muy crítica. La cuestión principal es si se puede manipular la lógica del código. Si un gancho se puede actualizar, esto significa que un gancho aparentemente seguro puede volverse malicioso después de actualizarse, lo que representa un riesgo significativo. Estos riesgos incluyen:

  • Agentes actualizables (pueden ser atacados directamente);

  • Con lógica de autodestrucción. Puede ser atacado cuando se llaman conjuntamente selfdestruct y create2.

2.2.3 Medidas preventivas frente a amenazas modelo II

Es fundamental evaluar si el gancho es malicioso. Específicamente, para los ganchos administrados, debemos centrarnos en el comportamiento de la gestión de tarifas, mientras que para los ganchos independientes, el foco principal es si son actualizables;

en conclusión

En este artículo, primero brindamos una breve descripción general de los mecanismos principales relacionados con los problemas de seguridad del Hook de Uniswap v4. Posteriormente, proponemos dos modelos de amenazas y describimos brevemente los riesgos de seguridad asociados.

En artículos posteriores, realizaremos un análisis en profundidad de los problemas de seguridad de cada modelo de amenaza.