Desde o anúncio da UnisWAPv4, esta plataforma de swap sofreu uma transformação significativa, evoluindo de uma plataforma de swap simples para um fornecedor de serviços de infra-estrutura. Em particular, o recurso Hooks do V4 ganhou muita atenção. Depois de uma investigação aprofundada, compilei alguns conteúdos para ajudar todos a compreender melhor esta transformação e a sua implementação.
O foco da inovação da UnisWAPv4 não é apenas melhorar a tecnologia AMM mas também expandir o ecossistema. Especificamente, esta inovação inclui as seguintes características principais:
Nas secções seguintes, explicarei detalhadamente o significado destas funcionalidades e os seus princípios de implementação.
origem: https://twitter.com/jermywkh/status/1670779830621851650
O UNISWAPv4 adota um método de manutenção de registos semelhante ao Double Entry Bookkeeping para rastrear as alterações de saldo dos tokens correspondentes a cada operação. Este método de contabilidade de dupla entrada requer o registo 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 utilizador troque 100 TokenA por 50 TokenB a partir do pool. O registo no livro-razão seria o seguinte:
No UNISWAPv4, este método de manutenção de registos é usado principalmente para operações principais e uma variável de armazenamento denominada lockState.currencyDelta [currency] é utilizado no código para registar a quantidade de alterações no saldo dos tokens. Se o valor deste delta for positivo, representa o aumento esperado no valor do token no pool, enquanto um valor negativo representa a diminuição esperada no valor do token. Alternativamente, se o valor for positivo, indica a quantidade de falta de token no pool (o valor esperado a ser recebido), enquanto um valor negativo indica o excesso de token no pool (o valor esperado para os utilizadores retirarem). A lista seguinte mostra os efeitos de várias operações no Token Delta:
Entre estas operações, apenas “liquidar” e “take” envolvem a transferência real de tokens, enquanto outras operações são as únicas responsáveis pela atualização do valor do TokenDelta.
Aqui usamos um exemplo simples para ilustrar como atualizar o TokenDelta. Vamos supor que hoje trocamos 100 Tokena por 50 TokenB:
Quando toda a operação de troca estiver concluída, tanto o TokenAdelta como o TokenBDelta são repostos para 0. Isto significa que a operação foi completamente equilibrada, garantindo assim a consistência dos saldos das contas.
Anteriormente, foi mencionado que o UNISWAPv4 utiliza Variáveis de Armazenamento para gravar TokenDelta. No entanto, dentro do contrato, ler e escrever para Variáveis de Armazenamento é bastante caro. Isto leva-nos a outro EIP introduzido pela Uniswap: EIP1153 - Transient Storage Opcodes.
O UnisWAPv4 planeia usar os opcodes TSTORE e TLOAD fornecidos pelo EIP1153 para atualizar o TokenDelta. As Variáveis de Armazenamento que adotarem Opcodes de Armazenamento Transiente serão descartadas após o final 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 no próximo upgrade de Cancun, e o UnisWAPv4 também afirmou que entrará em funcionamento após o upgrade de Cancun, conforme relatado aqui.
origem: https://etherworld.co/2022/12/13/transient-storage-for-beginners/
O UnisWAPv4 introduz um mecanismo de bloqueio, o que significa que antes de executar qualquer operação de Pool, deve primeiro chamar PoolManager.lock () para adquirir um bloqueio. Durante a execução de lock (), verifica se o valor do TokenDelta é 0, caso contrário será revertido. Uma vez que o PoolManager.lock () é adquirido com sucesso, chama a função lockAcquidied () de msg.sender. Dentro da função lockAcquidied (), são realizadas as operações relacionadas com o Pool, tais como swap e modifyPosition.
O processo é ilustrado abaixo. Quando um utilizador precisa de executar uma operação de Troca de Token, tem de chamar um Contrato Inteligente com a função lockAcquid () (referido como Contrato de Callback). O Contrato de Callback chama primeiro PoolManager.lock (), e depois o PoolManager chama a função lockAcquidied () do Contrato de Callback. Dentro da função lockAcquidied (), é definida a lógica relacionada com as operações do Pool, tais como swap, Settle e take. Finalmente, quando o bloqueio () está prestes a terminar, o PoolManager verifica se o TokenDelta associado a esta operação foi reposto para 0, assegurando que o saldo dos ativos no Pool permanece intacto.
Contrato Singleton significa que o UnisWAPv4 abandonou o modelo anterior de Factory-Pool. Cada Pool já não é um Contrato Inteligente independente, mas todos os Pools partilham um único contrato de single. Este design, combinado com o 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 o UNISWAPv3 como exemplo, a troca de ETH por DAI exigiria pelo menos quatro transferências de Token (operações de gravação de armazenamento). Isto inclui várias alterações registadas para USDC, USDT e DAI Tokens. No entanto, com as melhorias no UnisWAPv4, juntamente com o mecanismo de Contabilidade Flash, é necessária apenas uma transferência de Token (mover o DAI do Pool para o utilizador), reduzindo significativamente o número de operações e custos.
origem: https://twitter.com/Uniswap/status/1671208668304486404
Na última atualização do UniSwapv4, a característica mais notável é a Arquitetura Hooks. Esta atualização traz uma grande flexibilidade em termos de disponibilidade do Pool. Hooks são ações adicionais que são acionadas através do Contrato Hooks ao executar operações específicas no Pool. Estas ações são categorizadas em initialize (create pool), modifyPosition (adicionar/remover liquidez), trocar e doar. Cada categoria tem ações de pré-execução e pós-execução.
Este design permite aos utilizadores executar lógica personalizada antes e depois de operações específicas, tornando-a mais flexível e expandindo a funcionalidade do UnisWAPv4.
origem: https://github.com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf
Em seguida, usaremos um exemplo de Ordem Limite para explicar o processo de operação real dos Hooks no UnisWAPv4. Antes de começarmos, vamos explicar brevemente o princípio da implementação de Ordens Limitadas no UNISWAPv4.
A implementação UnisWAPv4 da ordem 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 nesse intervalo for trocada.
Por exemplo, digamos que adicionamos liquidez na faixa de preço de 1900-2000 para ETH, e então o preço do ETH sobe de 1800 para 2100. Neste ponto, toda a liquidez ETH que adicionamos anteriormente na faixa de preço de 1900-2000 foi trocada por USDC (assumindo no pool ETH-USDC). Ao remover a liquidez neste momento, podemos obter um efeito semelhante ao da execução de uma ordem de mercado ETH na faixa de preço atual de 1900-2000.
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 é utilizado para registar a faixa de preço (tick) ao criar um pool, a fim de determinar quais ordens de limite foram correspondidas depois de alguém trocar.
Quando o utilizador precisa de fazer uma encomenda, o contrato Hook executa a operação de adição de liquidez com base na faixa de preço e quantidade especificadas pelo utilizador. No contrato Hook para ordens com limite, pode ver a função place (). A lógica principal é chamar a função lockAcquiredPlace () depois de adquirir o bloqueio para executar a operação de adição de liquidez, o que equivale a colocar uma ordem limite.
origem: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L246
Depois que o utilizador completar um Token de Troca 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. Este comportamento é equivalente ao pedido que está a ser preenchido.
origem: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L192
Aqui está um fluxograma que ilustra o processo de execução de uma ordem limite:
O acima exposto é todo o processo de implementação de Limit-Order usando o mecanismo Hook.
Os ganchos têm vários pontos interessantes que acho que vale a pena partilhar.
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 Hook. Isto significa também que o endereço do contrato Hook precisa de ser concebido de uma forma específica e não pode ser escolhido arbitrariamente como o contrato Hook. Este projeto visa principalmente reduzir o consumo de gás e transferir o custo para a implantação do contrato para alcançar operações mais eficientes. (PS: Na prática, diferentes sais CREATE2 podem ser usados para calcular a força bruta endereços de contrato que cumpram as condições)
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 uma piscina, pode especificar se deseja ativar taxas dinâmicas. Se as taxas dinâmicas estiverem ativadas, a função getFee () do contrato Hook é 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 um cálculo de taxas flexível com base nas circunstâncias reais, aumentando a flexibilidade do sistema.
Cada Pool precisa determinar o contrato do Hook durante a sua criação, e não pode ser alterado posteriormente (embora diferentes Pools possam partilhar o mesmo contrato Hook). Isto é 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 os mesmos, se o contrato Hook for diferente, será considerado como um Pool diferente. Este design garante que o estado e as operações de diferentes Pools possam ser geridos de forma independente, garantindo a consistência dos Pools. No entanto, também aumenta a complexidade do encaminhamento à medida que o número de Pools aumenta (talvez o UniSwapX tenha sido concebido para resolver este problema).
O Uniswapv4 enfatiza claramente a expansão de todo o ecossistema Uniswap, transformando-o em infraestrutura para permitir que mais serviços sejam construídos com base nos Pools Uniswap. Isto ajuda a aumentar a competitividade da Uniswap e reduz o risco de serviços alternativos. No entanto, ainda não se sabe se alcançará o sucesso esperado. Alguns destaques incluem a combinação de Flash Accounting e EIP1153, e acreditamos que mais serviços irão adotar estas funcionalidades 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 opera. Se houver algum erro no artigo, sinta-se à vontade para apontá-lo. Também acolhemos discussões e feedback.
Finalmente, gostaríamos de agradecer a Anton Cheng e Ping Chen por revirem o artigo e fornecerem um feedback valioso!
Desde o anúncio da UnisWAPv4, esta plataforma de swap sofreu uma transformação significativa, evoluindo de uma plataforma de swap simples para um fornecedor de serviços de infra-estrutura. Em particular, o recurso Hooks do V4 ganhou muita atenção. Depois de uma investigação aprofundada, compilei alguns conteúdos para ajudar todos a compreender melhor esta transformação e a sua implementação.
O foco da inovação da UnisWAPv4 não é apenas melhorar a tecnologia AMM mas também expandir o ecossistema. Especificamente, esta inovação inclui as seguintes características principais:
Nas secções seguintes, explicarei detalhadamente o significado destas funcionalidades e os seus princípios de implementação.
origem: https://twitter.com/jermywkh/status/1670779830621851650
O UNISWAPv4 adota um método de manutenção de registos semelhante ao Double Entry Bookkeeping para rastrear as alterações de saldo dos tokens correspondentes a cada operação. Este método de contabilidade de dupla entrada requer o registo 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 utilizador troque 100 TokenA por 50 TokenB a partir do pool. O registo no livro-razão seria o seguinte:
No UNISWAPv4, este método de manutenção de registos é usado principalmente para operações principais e uma variável de armazenamento denominada lockState.currencyDelta [currency] é utilizado no código para registar a quantidade de alterações no saldo dos tokens. Se o valor deste delta for positivo, representa o aumento esperado no valor do token no pool, enquanto um valor negativo representa a diminuição esperada no valor do token. Alternativamente, se o valor for positivo, indica a quantidade de falta de token no pool (o valor esperado a ser recebido), enquanto um valor negativo indica o excesso de token no pool (o valor esperado para os utilizadores retirarem). A lista seguinte mostra os efeitos de várias operações no Token Delta:
Entre estas operações, apenas “liquidar” e “take” envolvem a transferência real de tokens, enquanto outras operações são as únicas responsáveis pela atualização do valor do TokenDelta.
Aqui usamos um exemplo simples para ilustrar como atualizar o TokenDelta. Vamos supor que hoje trocamos 100 Tokena por 50 TokenB:
Quando toda a operação de troca estiver concluída, tanto o TokenAdelta como o TokenBDelta são repostos para 0. Isto significa que a operação foi completamente equilibrada, garantindo assim a consistência dos saldos das contas.
Anteriormente, foi mencionado que o UNISWAPv4 utiliza Variáveis de Armazenamento para gravar TokenDelta. No entanto, dentro do contrato, ler e escrever para Variáveis de Armazenamento é bastante caro. Isto leva-nos a outro EIP introduzido pela Uniswap: EIP1153 - Transient Storage Opcodes.
O UnisWAPv4 planeia usar os opcodes TSTORE e TLOAD fornecidos pelo EIP1153 para atualizar o TokenDelta. As Variáveis de Armazenamento que adotarem Opcodes de Armazenamento Transiente serão descartadas após o final 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 no próximo upgrade de Cancun, e o UnisWAPv4 também afirmou que entrará em funcionamento após o upgrade de Cancun, conforme relatado aqui.
origem: https://etherworld.co/2022/12/13/transient-storage-for-beginners/
O UnisWAPv4 introduz um mecanismo de bloqueio, o que significa que antes de executar qualquer operação de Pool, deve primeiro chamar PoolManager.lock () para adquirir um bloqueio. Durante a execução de lock (), verifica se o valor do TokenDelta é 0, caso contrário será revertido. Uma vez que o PoolManager.lock () é adquirido com sucesso, chama a função lockAcquidied () de msg.sender. Dentro da função lockAcquidied (), são realizadas as operações relacionadas com o Pool, tais como swap e modifyPosition.
O processo é ilustrado abaixo. Quando um utilizador precisa de executar uma operação de Troca de Token, tem de chamar um Contrato Inteligente com a função lockAcquid () (referido como Contrato de Callback). O Contrato de Callback chama primeiro PoolManager.lock (), e depois o PoolManager chama a função lockAcquidied () do Contrato de Callback. Dentro da função lockAcquidied (), é definida a lógica relacionada com as operações do Pool, tais como swap, Settle e take. Finalmente, quando o bloqueio () está prestes a terminar, o PoolManager verifica se o TokenDelta associado a esta operação foi reposto para 0, assegurando que o saldo dos ativos no Pool permanece intacto.
Contrato Singleton significa que o UnisWAPv4 abandonou o modelo anterior de Factory-Pool. Cada Pool já não é um Contrato Inteligente independente, mas todos os Pools partilham um único contrato de single. Este design, combinado com o 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 o UNISWAPv3 como exemplo, a troca de ETH por DAI exigiria pelo menos quatro transferências de Token (operações de gravação de armazenamento). Isto inclui várias alterações registadas para USDC, USDT e DAI Tokens. No entanto, com as melhorias no UnisWAPv4, juntamente com o mecanismo de Contabilidade Flash, é necessária apenas uma transferência de Token (mover o DAI do Pool para o utilizador), reduzindo significativamente o número de operações e custos.
origem: https://twitter.com/Uniswap/status/1671208668304486404
Na última atualização do UniSwapv4, a característica mais notável é a Arquitetura Hooks. Esta atualização traz uma grande flexibilidade em termos de disponibilidade do Pool. Hooks são ações adicionais que são acionadas através do Contrato Hooks ao executar operações específicas no Pool. Estas ações são categorizadas em initialize (create pool), modifyPosition (adicionar/remover liquidez), trocar e doar. Cada categoria tem ações de pré-execução e pós-execução.
Este design permite aos utilizadores executar lógica personalizada antes e depois de operações específicas, tornando-a mais flexível e expandindo a funcionalidade do UnisWAPv4.
origem: https://github.com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf
Em seguida, usaremos um exemplo de Ordem Limite para explicar o processo de operação real dos Hooks no UnisWAPv4. Antes de começarmos, vamos explicar brevemente o princípio da implementação de Ordens Limitadas no UNISWAPv4.
A implementação UnisWAPv4 da ordem 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 nesse intervalo for trocada.
Por exemplo, digamos que adicionamos liquidez na faixa de preço de 1900-2000 para ETH, e então o preço do ETH sobe de 1800 para 2100. Neste ponto, toda a liquidez ETH que adicionamos anteriormente na faixa de preço de 1900-2000 foi trocada por USDC (assumindo no pool ETH-USDC). Ao remover a liquidez neste momento, podemos obter um efeito semelhante ao da execução de uma ordem de mercado ETH na faixa de preço atual de 1900-2000.
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 é utilizado para registar a faixa de preço (tick) ao criar um pool, a fim de determinar quais ordens de limite foram correspondidas depois de alguém trocar.
Quando o utilizador precisa de fazer uma encomenda, o contrato Hook executa a operação de adição de liquidez com base na faixa de preço e quantidade especificadas pelo utilizador. No contrato Hook para ordens com limite, pode ver a função place (). A lógica principal é chamar a função lockAcquiredPlace () depois de adquirir o bloqueio para executar a operação de adição de liquidez, o que equivale a colocar uma ordem limite.
origem: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L246
Depois que o utilizador completar um Token de Troca 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. Este comportamento é equivalente ao pedido que está a ser preenchido.
origem: https://github.com/Uniswap/v4-periphery/blob/main/contracts/hooks/examples/LimitOrder.sol#L192
Aqui está um fluxograma que ilustra o processo de execução de uma ordem limite:
O acima exposto é todo o processo de implementação de Limit-Order usando o mecanismo Hook.
Os ganchos têm vários pontos interessantes que acho que vale a pena partilhar.
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 Hook. Isto significa também que o endereço do contrato Hook precisa de ser concebido de uma forma específica e não pode ser escolhido arbitrariamente como o contrato Hook. Este projeto visa principalmente reduzir o consumo de gás e transferir o custo para a implantação do contrato para alcançar operações mais eficientes. (PS: Na prática, diferentes sais CREATE2 podem ser usados para calcular a força bruta endereços de contrato que cumpram as condições)
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 uma piscina, pode especificar se deseja ativar taxas dinâmicas. Se as taxas dinâmicas estiverem ativadas, a função getFee () do contrato Hook é 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 um cálculo de taxas flexível com base nas circunstâncias reais, aumentando a flexibilidade do sistema.
Cada Pool precisa determinar o contrato do Hook durante a sua criação, e não pode ser alterado posteriormente (embora diferentes Pools possam partilhar o mesmo contrato Hook). Isto é 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 os mesmos, se o contrato Hook for diferente, será considerado como um Pool diferente. Este design garante que o estado e as operações de diferentes Pools possam ser geridos de forma independente, garantindo a consistência dos Pools. No entanto, também aumenta a complexidade do encaminhamento à medida que o número de Pools aumenta (talvez o UniSwapX tenha sido concebido para resolver este problema).
O Uniswapv4 enfatiza claramente a expansão de todo o ecossistema Uniswap, transformando-o em infraestrutura para permitir que mais serviços sejam construídos com base nos Pools Uniswap. Isto ajuda a aumentar a competitividade da Uniswap e reduz o risco de serviços alternativos. No entanto, ainda não se sabe se alcançará o sucesso esperado. Alguns destaques incluem a combinação de Flash Accounting e EIP1153, e acreditamos que mais serviços irão adotar estas funcionalidades 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 opera. Se houver algum erro no artigo, sinta-se à vontade para apontá-lo. Também acolhemos discussões e feedback.
Finalmente, gostaríamos de agradecer a Anton Cheng e Ping Chen por revirem o artigo e fornecerem um feedback valioso!