Explorando os mecanismos principais do UniswapV4

AvançadoDec 24, 2023
Este artigo interpreta três recursos inovadores do UniswapV4 – Flash Accounting, Singleton Contract e Hooks Architecture – de uma perspectiva de código e implementação.
Explorando os mecanismos principais do UniswapV4

Introdução:

Desde o anúncio do UniswapV4, esta plataforma de swap passou por uma transformação significativa, evoluindo de uma simples plataforma de swap para um provedor de serviços de infraestrutura. Em particular, o recurso Hooks do V4 ganhou ampla atenção. Após uma pesquisa aprofundada, compilei alguns conteúdos para ajudar todos a entender melhor essa transformação e sua implementação.

O foco da inovação do UniswapV4 não é apenas melhorar a tecnologia AMM, mas também expandir o ecossistema. Especificamente, esta inovação inclui os seguintes recursos principais:

  • Contabilidade Flash
  • Contrato Singleton
  • Arquitetura de Ganchos

Nas seções seguintes, explicarei detalhadamente a importância desses recursos e seus princípios de implementação.

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

Contabilidade Flash

Escrituração de dupla entrada

O UniswapV4 adota um método de manutenção de registros semelhante à Escrituração de Dupla Entrada para rastrear as alterações de saldo dos tokens correspondentes a cada operação. Este método de contabilidade por partidas dobradas exige o registro de cada transação em várias contas simultaneamente e a garantia de que o saldo dos ativos entre essas contas permaneça equilibrado. Por exemplo, suponha que um usuário troque 100 TokenA por 50 TokenB do pool. O registro no livro razão seria o seguinte:

  • USUÁRIO: TokenA diminuiu em 100 unidades (-100), enquanto TokenB aumentou em 50 unidades (+50).
  • POOL: TokenA aumentou em 100 unidades (+100), enquanto TokenB diminuiu em 50 unidades (-50).

Token Delta e operações relacionadas

No UniswapV4, esse método de manutenção de registros é usado principalmente para operações importantes e uma variável de armazenamento chamada lockState.currencyDelta[currency] é usado no código para registrar a quantidade de alterações no saldo do token. Se o valor deste delta for positivo, ele representa o aumento esperado na quantidade de tokens no pool, enquanto um valor negativo representa a diminuição esperada na quantidade de tokens. Alternativamente, se o valor for positivo, indica a quantidade de tokens em falta no pool (o valor esperado a ser recebido), enquanto um valor negativo indica o excesso de tokens no pool (o valor esperado para os usuários retirarem). A lista a seguir mostra os efeitos de várias operações no Token Delta:

  • modificarPosition: Representa a operação Adicionar/Remover liquidez. Para Adicionar liquidez, TokenDelta é atualizado usando adição (representando a quantidade esperada de TokenA a ser adicionada ao pool). Para Remover liquidez, o TokenDelta é atualizado usando subtração (representando a quantidade esperada de TokenB a ser retirada do pool).
  • swap: Representa a operação Swap. Tomando o exemplo da troca de TokenA por TokenB, TokenADelta é atualizado usando adição, enquanto TokenBDelta é atualizado usando subtração.
  • liquidar: Acompanha a transferência de tokens para o pool. O pool calcula o aumento na quantidade de token antes e depois e atualiza o TokenDelta usando subtração. Se o pool receber a quantidade esperada de tokens, a subtração zerará o TokenDelta.
  • take: Acompanha a retirada de tokens do pool. TokenDelta é atualizado usando adição, indicando que os tokens foram removidos do pool.
  • mint: O comportamento de atualização do TokenDelta é semelhante ao “take”, mas em vez de realmente retirar os tokens do pool, os tokens ERC1155 são emitidos como prova de retirada, enquanto os tokens permanecem no pool. Posteriormente, os usuários podem recuperar os tokens do pool queimando os tokens ERC1155. O objetivo desta abordagem pode ser duplo: 1. Economizar custos de gás para transferências de token ERC20 (chamada de contrato + menos uma gravação de armazenamento) e usar a queima de token ERC1155 no futuro para atualizar o TokenDelta para transações. 2. Preservar a liquidez no pool para manter um pool de liquidez profundo para uma melhor experiência de troca de usuário.
  • doar: Esta operação declara a doação de tokens para o pool, mas na verdade, os tokens ainda precisam ser transferidos para o pool usando “settle”. Portanto, TokenDelta é atualizado usando adição neste caso.

Dentre essas operações, apenas “settle” e “take” envolvem a transferência efetiva de tokens, enquanto as demais operações são as únicas responsáveis pela atualização do valor do TokenDelta.

Exemplo de token delta

Aqui usamos um exemplo simples para ilustrar como atualizar o TokenDelta. Vamos supor que hoje trocamos 100 TokenA por 50 TokenB:

  1. Antes do início da transação, tanto TokenADelta quanto TokenBDelta são 0.
  2. swap: Calcule quanto TokenA o Pool precisa receber e quanto TokenB o usuário receberá. Neste ponto, TokenADelta = 100, TokenBDelta = -50.
  3. liquidação: Envie 100 TokenA para o Pool e atualize TokenADelta = 100 - 100 = 0.
  4. take: Transfira 50 TokenB do Pool para a conta do usuário e atualize TokenBDelta = -50 + 50 = 0.
  5. Depois que a transação for concluída, tanto TokenADelta quanto TokenBDelta serão 0.

Quando toda a operação de câmbio é concluída, tanto TokenADelta quanto TokenBDelta são zerados. Isso significa que a operação foi totalmente balanceada, garantindo assim a consistência dos saldos das contas.

EIP-1153: Opcodes de armazenamento transitório

Anteriormente, foi mencionado que o UniswapV4 utiliza variáveis de armazenamento para registrar TokenDelta. Porém, dentro do contrato, a leitura e gravação em variáveis de armazenamento são bastante caras. Isso nos leva a outro EIP introduzido pelo Uniswap: EIP1153 - Transient Storage Opcodes.

O UniswapV4 planeja usar os opcodes TSTORE e TLOAD fornecidos pelo EIP1153 para atualizar o TokenDelta. Variáveis de armazenamento que adotam Opcodes de armazenamento transitório serão descartadas após o término da transação (semelhante às variáveis de memória), reduzindo assim as taxas de gás.

Foi confirmado que o EIP1153 será incluído na próxima atualização de Cancún, e o UniswapV4 também declarou que entrará em operação após a atualização de Cancún, conforme relatado aqui.

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

Contabilidade Flash – Bloqueio

UniswapV4 introduz um mecanismo de bloqueio, o que significa que antes de executar qualquer operação Pool, você deve primeiro chamar PoolManager.lock() para adquirir um bloqueio. Durante a execução de lock(), ele verifica se o valor de TokenDelta é 0, caso contrário será revertido. Depois que PoolManager.lock() for adquirido com sucesso, ele chama a função lockAcquired() de msg.sender. Dentro da função lockAcquired() são realizadas as operações relacionadas ao Pool, como swap e modificarPosition.

O processo é ilustrado abaixo. Quando um usuário precisa realizar uma operação de Token Swap, ele deve chamar um Contrato Inteligente com a função lockAcquired() (referida como Contrato de Retorno de Chamada). O contrato de retorno de chamada primeiro chama PoolManager.lock(), e então PoolManager chama a função lockAcquired() do contrato de retorno de chamada. Dentro da função lockAcquired(), é definida a lógica relacionada às operações do Pool, como swap, liquidação e take. Por fim, quando o lock() está prestes a terminar, o PoolManager verifica se o TokenDelta associado a esta operação foi zerado, garantindo que o saldo dos ativos no Pool permaneça intacto.

Contrato Singleton

Contrato Singleton significa que UniswapV4 abandonou o modelo Factory-Pool anterior. Cada Pool não é mais um Contrato Inteligente independente, mas todos os Pools compartilham um único contrato singleton. Este design, aliado ao mecanismo Flash Accounting, requer apenas a atualização das variáveis de armazenamento necessárias, reduzindo ainda mais a complexidade e o custo das operações.

No exemplo abaixo, usando UniswapV3 como exemplo, a troca de ETH por DAI exigiria pelo menos quatro transferências de Token (operações de gravação de armazenamento). Isso inclui várias alterações registradas para tokens USDC, USDT e DAI. Porém, com as melhorias no UniswapV4, aliadas ao mecanismo Flash Accounting, é necessária apenas uma transferência de Token (mover o DAI do Pool para o usuário), reduzindo significativamente o número de operações e custos.

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

Arquitetura de Ganchos

Na última atualização do UniswapV4, o recurso mais notável é a arquitetura Hooks. Esta atualização traz grande flexibilidade em termos de disponibilidade do Pool. Ganchos são ações adicionais que são acionadas através do Contrato de Ganchos ao realizar operações específicas no Pool. Essas ações são categorizadas em inicializar (criar pool), modificarPosition (adicionar/remover liquidez), trocar e doar. Cada categoria possui ações de pré e pós-execução.

  • antesInitialize / afterInitialize
  • beforeModifyPosition / afterModifyPosition
  • antesSwap / afterSwap
  • antesDoar / depoisDoar

Este design permite que os usuários executem lógica personalizada antes e depois de operações específicas, tornando-o mais flexível e expandindo a funcionalidade do UniswapV4.

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

Exemplo de gancho - Gancho de ordem limitada

A seguir, usaremos um exemplo de Ordem Limitada para explicar o processo real de operação de Hooks no UniswapV4. Antes de começarmos, vamos explicar brevemente o princípio de implementação de Ordens Limitadas no UniswapV4.

Mecanismo de ordem limite UniswapV4

A implementação UniswapV4 da ordem de limite funciona adicionando liquidez a uma faixa de preço específica e, em seguida, executando a operação de remoção de liquidez se a liquidez nessa faixa for trocada.

Por exemplo, digamos que adicionamos liquidez na faixa de preço de 1900-2000 para ETH, e então o preço da ETH sobe de 1800 para 2100. Neste ponto, toda a liquidez ETH que adicionamos anteriormente na faixa de preço 1900-2000 foi trocada por USDC (assumindo no pool ETH-USDC). Ao remover a liquidez neste momento, podemos obter um efeito semelhante à execução de uma ordem de mercado ETH na faixa de preço atual de 1900-2000.

Contrato de Gancho de Ordem Limitada

Este exemplo foi retirado do GitHub do UniswapV4. Neste exemplo, o contrato Limit Order Hook fornece dois ganchos, nomeadamente afterInitialize e afterSwap. O gancho afterInitialize é usado para registrar a faixa de preço (tick) ao criar um pool, a fim de determinar quais ordens de limite foram correspondidas após alguém trocar.

Efetuar ordem

Quando o usuário precisa fazer um pedido, o contrato Hook executa a operação de adição de liquidez com base na faixa de preço e quantidade especificada pelo usuário. No contrato Hook para pedidos com limite, você pode ver a função place() . A lógica principal é chamar a função lockAcquiredPlace() após adquirir o bloqueio para executar a operação de adição de liquidez, o que equivale a colocar uma ordem limite.

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

gancho afterSwap

Depois que o usuário concluir um Swap Token dentro deste Pool, o Pool invocará a função afterSwap() do contrato Hook. A principal lógica do afterSwap é remover a liquidez das ordens colocadas anteriormente que foram executadas entre a faixa de preço anterior e a faixa de preço atual. Esse comportamento equivale ao pedido sendo atendido.

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

Limitar fluxo de pedidos

Aqui está um fluxograma que ilustra o processo de execução de uma ordem com limite:

  1. O colocador do pedido envia o pedido para o contrato Hook.
  2. O contrato Hook executa operações de adição de liquidez com base nas informações do pedido.
  3. Usuários regulares realizam operações de Token Swap no Pool.
  4. Após a conclusão da operação Swap Token, o Pool chama a função afterSwap() do contrato Hook.
  5. O contrato Hook executa operações de retirada de liquidez para ordens limitadas preenchidas com base na variação da faixa de preço dos tokens trocados.

O texto acima é todo o processo de implementação da Ordem Limitada usando o mecanismo Hook.

Gancho: Outros recursos

Os ganchos têm vários pontos interessantes que acho que vale a pena compartilhar.

Bit de endereço de contrato de ganchos

A decisão de realizar operações específicas antes/depois é determinada pelo 1 byte mais à esquerda do endereço do contrato Hook. 1 byte é igual a 8 bits, o que corresponde a 8 ações adicionais. O Pool verificará se o bit dessa ação é 1 para determinar se deve invocar a função de gancho correspondente do contrato de gancho. Isso também significa que o endereço do contrato Hook precisa ser elaborado de forma específica e não pode ser escolhido arbitrariamente como contrato Hook. Este projeto visa principalmente reduzir o consumo de gás e transferir o custo para implantação contratual para alcançar operações mais eficientes. (PS: Na prática, diferentes sais CREATE2 podem ser usados para calcular com força bruta endereços de contrato que atendam às condições)

Taxa Dinâmica

Além de poder realizar operações adicionais antes e depois de cada ação, os Hooks também suportam a implementação de taxas dinâmicas. Ao criar um Pool, você pode especificar se deseja ativar taxas dinâmicas. Se as taxas dinâmicas estiverem habilitadas, a função getFee() do contrato Hook será chamada ao trocar tokens. O contrato Hook pode determinar o valor das taxas a serem cobradas com base no estado atual do Pool. Este design permite o cálculo flexível de taxas com base nas circunstâncias reais, aumentando a flexibilidade do sistema.

Criação de Piscina

Cada Pool precisa determinar o contrato Hook durante sua criação e ele não pode ser alterado posteriormente (embora Pools diferentes possam compartilhar o mesmo contrato Hook). Isso ocorre principalmente porque os Hooks são considerados parte do PoolKey, e o PoolManager usa o PoolKey para identificar em qual Pool operar. Mesmo que os ativos sejam iguais, se o contrato Hook for diferente, será considerado um Pool diferente. Este design garante que o estado e as operações de diferentes Pools possam ser gerenciados de forma independente, garantindo a consistência dos Pools. No entanto, também aumenta a complexidade do roteamento à medida que o número de Pools aumenta (talvez o UniswapX tenha sido projetado para resolver esse problema).

DR

  • Flash Accounting é usado para rastrear as alterações na quantidade de cada token para garantir que todas as alterações sejam zeradas após a conclusão de uma transação. Para economizar nas taxas de gás, a Flash Accounting usa um método de armazenamento especial fornecido pelo EIP1153.
  • O design do Singleton Contract ajuda a reduzir o consumo de gás, evitando atualizações em diversas variáveis de armazenamento.
  • A arquitetura Hooks fornece operações adicionais, divididas em estágios de pré-execução e pós-execução. Isso permite mais flexibilidade em cada operação do Pool, mas também torna o roteamento dos Pools mais complexo.

O UniswapV4 enfatiza claramente a expansão de todo o ecossistema Uniswap, transformando-o em infraestrutura para permitir a construção de mais serviços com base nos pools Uniswap. Isto ajuda a aumentar a competitividade do Uniswap e reduz o risco de serviços alternativos. No entanto, resta saber se alcançará o sucesso esperado. Alguns destaques incluem a combinação de Flash Accounting e EIP1153, e acreditamos que mais serviços adotarão esses recursos no futuro, levando a vários cenários de aplicação. Este é o conceito central do UniswapV4 e esperamos que forneça uma compreensão mais profunda de como o UniswapV4 funciona. Se houver algum erro no artigo, sinta-se à vontade para apontá-lo. Também acolhemos discussões e comentários.

Por fim, gostaríamos de agradecer a Anton Cheng e Ping Chen por revisarem o artigo e fornecerem comentários valiosos!

Isenção de responsabilidade:

  1. Este artigo foi reimpresso de [meio]. Todos os direitos autorais pertencem ao autor original [林瑋宸 Albert Lin]. Se houver objeções a esta reimpressão, entre em contato com a equipe do Gate Learn ( gatelearn@gate.io ) e eles cuidarão disso imediatamente.
  2. Isenção de responsabilidade: As opiniões e pontos de vista expressos neste artigo são exclusivamente do autor e não constituem qualquer conselho de investimento.
  3. As traduções do artigo para outros idiomas são feitas pela equipe do Gate Learn. A menos que mencionado, é proibido copiar, distribuir ou plagiar os artigos traduzidos.
* Đầu tư có rủi ro, phải thận trọng khi tham gia thị trường. Thông tin không nhằm mục đích và không cấu thành lời khuyên tài chính hay bất kỳ đề xuất nào khác thuộc bất kỳ hình thức nào được cung cấp hoặc xác nhận bởi Gate.io.
* Không được phép sao chép, truyền tải hoặc đạo nhái bài viết này mà không có sự cho phép của Gate.io. Vi phạm là hành vi vi phạm Luật Bản quyền và có thể phải chịu sự xử lý theo pháp luật.
Bắt đầu giao dịch
Đăng ký và giao dịch để nhận phần thưởng USDTEST trị giá
$100
$5500
Tạo tài khoản