Explorando los mecanismos centrales de UniswapV4

AvanzadoDec 24, 2023
Este artículo interpreta tres características innovadoras de UniswapV4 (Contabilidad Flash, Contrato Singleton y Arquitectura Hooks) desde una perspectiva de código e implementación.
Explorando los mecanismos centrales de UniswapV4

Introducción

Desde el anuncio de UniswapV4, esta plataforma de intercambio ha experimentado una transformación significativa, pasando de una simple plataforma de intercambio a un proveedor de servicios de infraestructura. En particular, la función Hooks de V4 ha ganado una amplia atención. Después de una investigación en profundidad, he recopilado contenido para ayudar a todos a comprender mejor esta transformación y su implementación.

El objetivo de la innovación de UniswapV4 no es solo mejorar la tecnología AMM sino también expandir el ecosistema. En concreto, esta innovación incluye las siguientes características clave:

  • Contabilidad flash
  • Contrato singleton
  • Arquitectura de ganchos

En las siguientes secciones, explicaré en detalle la importancia de estas características y sus principios de implementación.

fuente: https://twitter.com/jermywkh/status/1670779830621851650

Contabilidad flash

Contabilidad de doble entrada

UniswapV4 adopta un método de mantenimiento de registros similar a la contabilidad de doble entrada para realizar un seguimiento de los cambios de saldo de los tokens correspondientes a cada operación. Este método de contabilidad por partida doble requiere registrar cada transacción en varias cuentas simultáneamente y garantizar que el saldo de activos entre estas cuentas permanezca equilibrado. Por ejemplo, supongamos que un usuario intercambia 100 TokenA por 50 TokenB del grupo. El registro en el libro mayor sería el siguiente:

  • USUARIO: TokenA disminuyó en 100 unidades (-100), mientras que TokenB aumentó en 50 unidades (+50).
  • GRUPO: TokenA aumentó en 100 unidades (+100), mientras que TokenB disminuyó en 50 unidades (-50).

Token Delta y operaciones relacionadas

En UniswapV4, este método de mantenimiento de registros se utiliza principalmente para operaciones importantes y una variable de almacenamiento denominada lockState.currencyDelta[moneda] se utiliza en el código para registrar la cantidad de cambios en el saldo del token. Si el valor de este delta es positivo, representa el aumento esperado en la cantidad de tokens en el grupo, mientras que un valor negativo representa la disminución esperada en la cantidad de tokens. Alternativamente, si el valor es positivo, indica la cantidad de token faltante en el grupo (la cantidad esperada a recibir), mientras que un valor negativo indica el exceso de token en el grupo (la cantidad esperada que los usuarios retiren). La siguiente lista muestra los efectos de varias operaciones en Token Delta:

  • modificarPosition: Representa la operación Agregar/Quitar liquidez. Para Agregar liquidez, TokenDelta se actualiza mediante la suma (que representa la cantidad esperada de TokenA que se agregará al grupo). Para Eliminar liquidez, TokenDelta se actualiza mediante resta (que representa la cantidad esperada de TokenB que se retirará del grupo).
  • swap: Representa la operación Swap. Tomando el ejemplo del intercambio de TokenA por TokenB, TokenADelta se actualiza mediante suma, mientras que TokenBDelta se actualiza mediante resta.
  • liquidar: Acompaña la transferencia de tokens al pool. El grupo calcula el aumento en la cantidad de tokens antes y después y actualiza TokenDelta mediante resta. Si el grupo recibe la cantidad esperada de tokens, la resta pondrá a cero TokenDelta.
  • tomar: Acompaña el retiro de tokens del pool. TokenDelta se actualiza mediante suma, lo que indica que los tokens se han eliminado del grupo.
  • mint: El comportamiento de actualizar TokenDelta es similar a "tomar", pero en lugar de retirar tokens del grupo, se emiten tokens ERC1155 como prueba de retiro, mientras los tokens permanecen en el grupo. Más tarde, los usuarios pueden recuperar los tokens del grupo quemando los tokens ERC1155. El propósito de este enfoque puede ser doble: 1. Ahorrar costos de gasolina para las transferencias de tokens ERC20 (llamada de contrato + una escritura de almacenamiento menos) y utilizar la quema de tokens ERC1155 en el futuro para actualizar TokenDelta para las transacciones. 2. Preservar la liquidez en el fondo común para mantener un fondo de liquidez profundo para una mejor experiencia de intercambio de usuarios.
  • donar: esta operación declara la donación de tokens al grupo, pero en realidad, los tokens aún deben transferirse al grupo mediante "liquidar". Por lo tanto, TokenDelta se actualiza mediante la suma en este caso.

Entre estas operaciones, sólo "liquidar" y "tomar" implican la transferencia real de tokens, mientras que otras operaciones son las únicas responsables de actualizar el valor de TokenDelta.

Ejemplo de delta de token

Aquí usamos un ejemplo simple para ilustrar cómo actualizar TokenDelta. Supongamos que hoy cambiamos 100 TokenA por 50 TokenB:

  1. Antes de que comience la transacción, tanto TokenADelta como TokenBDelta son 0.
  2. swap: Calcule cuánto TokenA necesita recibir el Pool y cuánto TokenB recibirá el usuario. En este punto, TokenADelta = 100, TokenBDelta = -50.
  3. liquidar: envíe 100 TokenA al grupo y actualice TokenADelta = 100 - 100 = 0.
  4. tomar: Transfiera 50 TokenB del Pool a la cuenta del usuario y actualice TokenBDelta = -50 + 50 = 0.
  5. Una vez completada la transacción, tanto TokenADelta como TokenBDelta son 0.

Cuando se completa toda la operación de intercambio, tanto TokenADelta como TokenBDelta se restablecen a 0. Esto significa que la operación se ha equilibrado por completo, garantizando así la coherencia de los saldos de las cuentas.

EIP-1153: códigos de operación de almacenamiento transitorio

Anteriormente, se mencionó que UniswapV4 utiliza variables de almacenamiento para registrar TokenDelta. Sin embargo, dentro del contrato, leer y escribir en variables de almacenamiento es bastante costoso. Esto nos lleva a otro EIP presentado por Uniswap: EIP1153 - Códigos de operación de almacenamiento transitorio.

UniswapV4 planea utilizar los códigos de operación TSTORE y TLOAD proporcionados por EIP1153 para actualizar TokenDelta. Las variables de almacenamiento que adoptan códigos de operación de almacenamiento transitorio se descartarán una vez finalizada la transacción (similar a las variables de memoria), lo que reduce las tarifas de gas.

Se ha confirmado que EIP1153 se incluirá en la próxima actualización de Cancún, y UniswapV4 también ha declarado que entrará en funcionamiento después de la actualización de Cancún, como se informa aquí.

fuente: https://etherworld.co/2022/12/13/transient-storage-for-beginners/

Contabilidad flash: bloquear

UniswapV4 introduce un mecanismo de bloqueo, lo que significa que antes de realizar cualquier operación del Pool, primero debe llamar a PoolManager.lock() para adquirir un bloqueo. Durante la ejecución de lock(), verifica si el valor de TokenDelta es 0; de lo contrario, se revertirá. Una vez que PoolManager.lock() se adquiere con éxito, llama a la función lockAcquired() de msg.sender. Dentro de la función lockAcquired() se realizan las operaciones relacionadas con el Pool, como swap y modificarPosition.

El proceso se ilustra a continuación. Cuando un usuario necesita realizar una operación de intercambio de tokens, debe llamar a un contrato inteligente con la función lockAcquired() (conocido como contrato de devolución de llamada). El contrato de devolución de llamada primero llama a PoolManager.lock(), y luego PoolManager llama a la función lockAcquired() del Contrato de devolución de llamada. Dentro de la función lockAcquired(), se define la lógica relacionada con las operaciones del Pool, como swap, liquidación y toma. Finalmente, cuando lock() está a punto de finalizar, PoolManager verifica si el TokenDelta asociado con esta operación se ha restablecido a 0, asegurando que el saldo de activos en el Pool permanezca intacto.

Contrato singleton

El contrato Singleton significa que UniswapV4 ha abandonado el modelo Factory-Pool anterior. Cada grupo ya no es un contrato inteligente independiente, sino que todos los grupos comparten un único contrato único. Este diseño, combinado con el mecanismo de Contabilidad Flash, solo requiere actualizar las Variables de Almacenamiento necesarias, reduciendo aún más la complejidad y el costo de las operaciones.

En el siguiente ejemplo, utilizando UniswapV3 como ejemplo, el intercambio de ETH por DAI requeriría al menos cuatro transferencias de tokens (operaciones de escritura de almacenamiento). Esto incluye múltiples cambios registrados para los tokens USDC, USDT y DAI. Sin embargo, con las mejoras en UniswapV4, junto con el mecanismo de Contabilidad Flash, solo se necesita una transferencia de Token (mover DAI del Pool al usuario), lo que reduce significativamente la cantidad de operaciones y costos.

fuente: https://twitter.com/Uniswap/status/1671208668304486404

Arquitectura de ganchos

En la última actualización de UniswapV4, la característica más notable es la arquitectura Hooks. Esta actualización aporta una gran flexibilidad en términos de disponibilidad del Pool. Los Hooks son acciones adicionales que se activan a través del Contrato de Hooks al realizar operaciones específicas en el Pool. Estas acciones se clasifican en inicializar (crear grupo), modificar posición (agregar/eliminar liquidez), intercambiar y donar. Cada categoría tiene acciones previas y posteriores a la ejecución.

  • 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

Este diseño permite a los usuarios ejecutar lógica personalizada antes y después de operaciones específicas, lo que la hace más flexible y amplía la funcionalidad de UniswapV4.

fuente: https://github.com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf

Ejemplo de gancho: gancho de orden limitada

A continuación, usaremos un ejemplo de orden limitada para explicar el proceso de operación real de Hooks en UniswapV4. Antes de comenzar, expliquemos brevemente el principio de implementación de órdenes limitadas en UniswapV4.

Mecanismo de orden límite UniswapV4

La implementación UniswapV4 de la orden límite funciona agregando liquidez a un rango de precios específico y luego ejecutando la operación de eliminación de liquidez si se intercambia la liquidez en ese rango.

Por ejemplo, digamos que agregamos liquidez en el rango de precios de 1900-2000 para ETH, y luego el precio de ETH aumenta de 1800 a 2100. En este punto, toda la liquidez de ETH que agregamos anteriormente en el rango de precios 1900-2000 se ha intercambiado por USDC (suponiendo que sea en el grupo ETH-USDC). Al eliminar la liquidez en este momento, podemos lograr un efecto similar al de ejecutar una orden de mercado de ETH en el rango de precios actual de 1900-2000.

Contrato de gancho de orden limitada

Este ejemplo está tomado de GitHub de UniswapV4. En este ejemplo, el contrato de enlace de orden limitada proporciona dos enlaces, a saber, afterInitialize y afterSwap. El gancho afterInitialize se utiliza para registrar el rango de precios (tick) al crear un grupo, con el fin de determinar qué órdenes límite se han igualado después de que alguien realiza un intercambio.

Hacer un pedido

Cuando el usuario necesita realizar una orden, el contrato Hook ejecuta la operación de adición de liquidez en función del rango de precios y la cantidad especificados por el usuario. En el contrato Hook para órdenes limitadas, puede ver la función place() . La lógica principal es llamar a la función lockAcquiredPlace() después de adquirir el bloqueo para ejecutar la operación de adición de liquidez, lo que equivale a colocar una orden limitada.

fuente: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L246

gancho afterSwap

Después de que el usuario complete un token de intercambio dentro de este grupo, el grupo invocará la función afterSwap() del contrato Hook. La lógica principal de afterSwap es eliminar la liquidez de las órdenes realizadas previamente que se han ejecutado entre el rango de precios anterior y el rango de precios actual. Este comportamiento es equivalente a que se complete el pedido.

fuente: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L192

Limitar el flujo de órdenes

A continuación se muestra un diagrama de flujo que ilustra el proceso de ejecución de una orden limitada:

  1. El colocador del pedido envía el pedido al contrato Hook.
  2. El contrato Hook ejecuta operaciones de adición de liquidez basadas en la información de la orden.
  3. Los usuarios habituales realizan operaciones de intercambio de tokens en el grupo.
  4. Una vez completada la operación de intercambio de token, el grupo llama a la función afterSwap () del contrato Hook.
  5. El contrato Hook ejecuta operaciones de eliminación de liquidez para órdenes límite ejecutadas en función de la variación del rango de precios de los tokens intercambiados.

Lo anterior es todo el proceso de implementación de Limit-Order utilizando el mecanismo Hook.

Gancho: Otras características

Los ganchos tienen varios puntos interesantes que creo que vale la pena compartir.

Bit de dirección de contrato de ganchos

La decisión de realizar operaciones específicas antes/después está determinada por el byte más a la izquierda de la dirección del contrato Hook. 1 byte equivale a 8 bits, lo que corresponde a 8 acciones adicionales. El grupo comprobará si el bit de esa acción es 1 para determinar si se debe invocar la función de enlace correspondiente del contrato de enlace. Esto también significa que la dirección del contrato Hook debe diseñarse de una manera específica y no puede elegirse arbitrariamente como el contrato Hook. Este diseño tiene como objetivo principal reducir el consumo de gas y trasladar el costo al despliegue por contrato para lograr operaciones más eficientes. (PD: en la práctica, se pueden usar diferentes sales CREATE2 para calcular por fuerza bruta las direcciones del contrato que cumplen con las condiciones)

Tarifa dinámica

Además de poder realizar operaciones adicionales antes y después de cada acción, Hooks también admite la implementación de tarifas dinámicas. Al crear un grupo, puede especificar si desea habilitar tarifas dinámicas. Si las tarifas dinámicas están habilitadas, se llama a la función getFee() del contrato Hook al intercambiar tokens. El contrato Hook puede determinar el monto de las tarifas a cobrar en función del estado actual del Pool. Este diseño permite un cálculo de tarifas flexible en función de las circunstancias reales, lo que aumenta la flexibilidad del sistema.

Creación de piscinas

Cada Pool necesita determinar el contrato Hook durante su creación, y no se puede cambiar después (aunque diferentes Pools pueden compartir el mismo contrato Hook). Esto se debe principalmente a que los Hooks se consideran parte de PoolKey y PoolManager usa PoolKey para identificar en qué grupo operar. Incluso si los activos son los mismos, si el contrato Hook es diferente, se considerará un Pool diferente. Este diseño garantiza que el estado y las operaciones de diferentes Pools se puedan gestionar de forma independiente, garantizando la coherencia de los Pools. Sin embargo, también aumenta la complejidad del enrutamiento a medida que aumenta el número de Pools (quizás UniswapX esté diseñado para resolver este problema).

TL;DR

  • Flash Accounting se utiliza para rastrear los cambios en la cantidad de cada token para garantizar que todos los cambios se pongan a cero después de completar una transacción. Para ahorrar en tarifas de gas, Flash Accounting utiliza un método de almacenamiento especial proporcionado por EIP1153.
  • El diseño del contrato Singleton ayuda a reducir el consumo de gas al evitar actualizaciones de múltiples variables de almacenamiento.
  • La arquitectura Hooks proporciona operaciones adicionales, divididas en etapas previas a la ejecución y posteriores a la ejecución. Esto permite una mayor flexibilidad en cada operación del Pool pero también hace que el enrutamiento de los Pools sea más complejo.

UniswapV4 claramente enfatiza la expansión de todo el ecosistema Uniswap, convirtiéndolo en infraestructura para permitir que se construyan más servicios sobre la base de Uniswap Pools. Esto ayuda a mejorar la competitividad de Uniswap y reduce el riesgo de servicios alternativos. Sin embargo, aún está por verse si logrará el éxito esperado. Algunos aspectos destacados incluyen la combinación de Flash Accounting y EIP1153, y creemos que más servicios adoptarán estas características en el futuro, lo que dará lugar a varios escenarios de aplicación. Este es el concepto central de UniswapV4 y esperamos que proporcione una comprensión más profunda de cómo funciona UniswapV4. Si hay algún error en el artículo, no dude en señalarlo. También damos la bienvenida a discusiones y comentarios.

Finalmente, nos gustaría agradecer a Anton Cheng y Ping Chen por revisar el artículo y brindar comentarios valiosos.

Descargo de responsabilidad:

  1. Este artículo se reimprime de [medio]. Todos los derechos de autor pertenecen al autor original [林瑋宸 Albert Lin]. Si hay objeciones a esta reimpresión, comuníquese con el equipo de Gate Learn ( gatelearn@gate.io ) y ellos lo manejarán de inmediato.
  2. Descargo de responsabilidad: los puntos de vista y opiniones expresados en este artículo son únicamente los del autor y no constituyen ningún consejo de inversión.
  3. Las traducciones del artículo a otros idiomas están a cargo del equipo de Gate Learn. A menos que se mencione, está prohibido copiar, distribuir o plagiar los artículos traducidos.
learn.articles.copyrightNoticeOne
learn.articles.copyrightNoticeTwo
learn.articles.start.now
learn.articles.start.now.voucher
learn.articles.create.account