WEB3DEV

Cover image for Assinaturas Fictícias e Transferências de Token de Gás do ERC-4337
Paulo Gio
Paulo Gio

Posted on • Atualizado em

Assinaturas Fictícias e Transferências de Token de Gás do ERC-4337

No artigo sobre a Estimativa de Gás do ERC-4337, discutimos como o gás funciona no ERC-4337 e nosso método para estimativa de gás. Com este método, deveríamos ser capazes de fornecer aos usuários valores precisos para enviar suas operações de usuário. Infelizmente, nem sempre é simples assim.

Vamos explorar alguns outros problemas que complicam a estimativa de gás do ERC-4337.

Quais são os valores de assinaturas fictícias?

Na maioria das implementações de contas de contratos inteligentes, o campo de assinatura é computado fora da cadeia ao criar um hash de uma operação de usuário e assinar esse hash usando algum esquema de assinatura (sendo o ECDSA o mais popular). Esta assinatura é verificada na cadeia pelo contrato da conta durante a fase de verificação.

Por exemplo, SimpleAccount usa um esquema de assinatura EIP-191 no hash que é validado na cadeia durante sua função validateUserOp, usando a biblioteca ECDSA do OpenZeppelin.

Esta assinatura deve ser computada após a estimativa de gás, pois esses campos estão incluídos no hash.

No entanto, há partes do passo de estimativa de gás que requerem que o campo de assinatura seja preenchido: preVerificationGas e verificationGasLimit.

preVerificationGas

Na seção sobre estimativa de preVerificationGas na primeira parte desta série, discutimos três cálculos que o empacotador (bundler) usa para contabilizar gás não medido.

Observe que os passos 2 e 3 (calculando a parcela de gás dos dados da chamada (calldata) da operação do usuário e a parcela de gás de qualquer sobrecarga de execução do usuário) dependem diretamente do comprimento e conteúdo de uma operação de usuário, incluindo o campo signature (assinatura).

verificationGasLimit

Quase todas as implementações úteis de uma conta de contrato inteligente requererão alguma verificação de assinatura. Esse gás precisa ser estimado! Este processo de estimativa não pode ser revertido, caso contrário o gás de verificação não poderá ser implementado.

Como escolhemos que assinatura usar?

Como Calcular Valores de Assinatura Fictícia

Para resolver esses problemas, muitos empacotadores (bundlers) ERC-4337 usam uma "Assinatura Fictícia" (dummy signature) que deve ser fornecida pelo chamador de eth_estimateUserOperationGas com base no tipo específico de conta.

Restrições

Esta assinatura fictícia tem algumas restrições:

  1. O comprimento do valor fictício deve ser igual ao comprimento máximo da assinatura e deve conter o número máximo de bytes não-zero válidos para a conta.
    1. Isso garante que os cálculos preVerificationGas possam levar em conta a contribuição da pior assinatura para os custos indiretos dos dados da chamada e do ponto de entrada (entry point).
  2. O valor fictício deve, quando fornecido à função de validação da conta, causar o uso máximo de gás e não deve causar uma reversão.
  3. O valor fictício não deve ser uma assinatura válida para qualquer operação de usuário válida.

Um valor de assinatura fictícia para SimpleAccount pode ser encontrado em nossa documentação para o método eth_estimateUserOperationGas.

Essa assinatura fictícia tem as seguintes propriedades:

  1. Tem o comprimento exato de uma assinatura ECDSA.
  2. Possui o número máximo de bytes não-zero permitidos em uma assinatura ECDSA.
  3. É uma assinatura ECDSA válida (para que a chamada .recover() não seja revertida).
  4. Não é uma assinatura para qualquer operação de usuário conhecida, então SimpleAccount sempre retornará SIG_VALIDATION_FAILED.

Os implementadores de contas precisam garantir a escrita de suas funções de validação de forma que o fornecimento de uma assinatura fictícia seja possível.

Isso significa:

  1. Usar REVERT apenas em assinaturas que não podem ser a assinatura fictícia. Retornar SIG_VALIDATION_FAILED quando a assinatura fictícia for fornecida.
  2. Tomar cuidado para não "encurtar o circuito" de falha para a assinatura fictícia. Ou seja, o valor fictício deve passar por toda a função de validação e usar a quantidade máxima de gás.
  3. Na prática, isso significa remover quaisquer retornos antecipados. Uma função de validação de conta pode determinar que a assinatura é inválida cedo, mas deve continuar a executar a lógica da função e retornar a falha no final.

Como Calcular Valores Fictícios de paymasterAndData

Os mesmos requisitos acima se aplicam ao campo paymasterAndData durante a estimativa de gás: para qualquer implementação do contrato pagador (paymaster) que dependa dos valores dos campos de gás (ou seja, para calcular uma assinatura), precisamos resolver o mesmo problema de fornecer um valor fictício.

Restrições

Esse paymasterAndData fictício tem algumas restrições:

  1. O comprimento do valor fictício deve ser igual ao comprimento máximo do paymasterAndData e deve conter o número máximo de bytes não-zero válidos para a conta.
    1. Isso garante que os cálculos do preVerificationGas possam levar em conta a pior contribuição de paymasterAndData para os custos dos dados da chamada e do ponto de entrada.
  2. O valor fictício deve, quando fornecido à função de validação do contrato pagador, causar o uso máximo de gás e não deve causar uma reversão.
  3. O valor fictício não deve ser um campo paymasterAndData válido para qualquer operação de usuário válida.

Por exemplo, um contrato pagador patrocinador que depende da verificação de uma assinatura de patrocínio sobre o hash de operação do usuário precisará fornecer um valor fictício de paymasterAndData durante a estimativa com propriedades semelhantes às descritas acima:

  1. O valor fictício deve conter um endereço de contrato pagador válido.
  2. Comprimento máximo e valores de byte para cálculos de preVerificationGas.
  3. Quando fornecido à função de validação do contrato pagador, deve consumir o máximo de gás e resultar em um valor de retorno SIG_VALIDATION_FAILED.

Os implementadores de contratos pagadores precisam garantir que escreverão suas funções de validação de forma que seja possível fornecer um paymasterAndData fictício.

Isso significa:

  • Usar revert apenas em dados que não podem fazer parte do paymasterAndData fictício. Retornar SIG_VALIDATION_FAILED em vez disso.
  • Ter cuidado para não "encurtar o circuito" de falha do paymasterAndData fictício. Ou seja, o valor fictício deve passar por toda a função de validação e usar a quantidade máxima de gás.
  • Na prática, isso significa remover quaisquer retornos antecipados. Uma função de validação de contrato pagador pode determinar antecipadamente que a assinatura é inválida, mas deve continuar a executar a lógica da função e retornar a falha no final.

Transferências de Tokens de Gás

A estimativa para verificationGasLimit deve levar em consideração o custo do gás de quaisquer transferências de tokens durante a fase de validação. Muitas operações de usuários envolvem uma transferência de tokens durante a validação para pagar antecipadamente pelo gás, com um reembolso no final da operação para qualquer gás que não tenha sido consumido.

Existem dois casos:

  1. Sem contrato pagador - trata-se de uma transferência de ETH do remetente para o contrato de entrada.
  2. Com um contrato pagador - isso pode ser qualquer coisa (dentro das regras permitidas da especificação) mas frequentemente assume a forma de uma transferência de token ERC-20 do remetente para o contrato pagador.

O que acontece se a conta não tiver fundos suficientes?

Se maxFeePerGas for definido como um valor diferente de zero, a transferência durante a validação será revertida se a conta não tiver tokens suficientes para pagar a taxa. Isso significa que os usuários devem financiar suas contas antes de tentar estimar o gás.

Um fluxo de trabalho desejado que não é possível agora:

  1. Estimar gás
  2. Adicionar fundos na conta para o gás
  3. Enviar operação

Uma possível solução aqui é informar ao usuário para deixar maxFeePerGas não definido, ou definido como zero, ao chamar eth_estimateUserOperationGas. No entanto, isso definirá o custo do gás como zero e, portanto, um valor zero para qualquer transferência de token que precise ocorrer. Em muitos tipos de contas/contratos pagadores, um custo de gás zero irá ignorar a chamada transfer. Isso leva a uma subestimação de gás quando um maxFeePerGas zero é usado.

Outro problema tem a ver com o uso de um maxFeePerGas diferente de zero e tentando a abordagem de estimativa de busca binária definida em "Tentativa 3: Busca Binária", da primeira parte desta série.

O primeiro passo dessa abordagem é garantir que a operação seja possível usando um valor máximo de gás. O remetente pode não ter ativos suficientes para pagar o gás nesse valor máximo e o empacotador nem sempre tem informações suficientes para determinar o saldo do token de taxa (ou seja, o caso do contrato pagador ERC-20) para determinar o limite superior correto.

Como o empacotador da Alchemy resolve a estimativa de gás com a transferência de tokens?

A abordagem adotada pela Rundler para eth_estimateUserOperationGas é a seguinte:

Caso sem Contrato Pagador

  1. O Rundler sempre ignorará maxFeePerGas e maxPriorityFeePerGas e os definirá como 0.
  2. O Rundler sempre adicionará um valor estático de 10 mil de gás a verificationGasLimit para contabilizar a transferência de depósito em ETH do remetente para o ponto de entrada.
  3. Nenhuma alteração do lado do cliente é necessária.

O ponto #1 é uma desvio da especificação do ERC-4337 que diz "limites de gás (e preços) são opcionais, mas são usados se especificados"

Caso com um Contrato Pagador

  1. O Rundler sempre ignorará maxFeePerGas e maxPriorityFeePerGas e os definirá como 0.
  2. O verificationGasLimit do Rundler sempre será subestimado se qualquer lógica do contrato pagador for condicional ao valor da taxa (como uma transferência ERC-20 seria).
  3. Os usuários desses contratos pagadores são obrigados a contabilizar qualquer gás extra que seria incorrido por uma taxa do cliente diferente de zero.

Por exemplo, se usar um contrato pagador ERC-20 que realiza uma transferência durante a fase de validação, sempre adicione um valor de gás estático de 75 mil ao valor de retorno verificationGasLimit de eth_estimateUserOperationGas. Isso exige que os clientes estejam cientes do contrato pagador que estão chamando e tenham conhecimento prévio dos custos subestimados de gás devido às transferências.

O Alchemy aa-sdk permite que o middleware do contrato pagador modifique esse limite de gás de acordo.

O que isso significa para os desenvolvedores?

Valores fictícios e o problema de transferência de tokens afetam os desenvolvedores que constroem contas de contratos inteligentes, contratos pagadores e clientes de contas.

Desenvolvedores de Contas de Contrato Inteligente

Os desenvolvedores de contas de contrato inteligente precisam garantir que um valor de assinatura fictícia sempre possa ser determinado do lado do cliente com base em como a função de validação de conta será executada. Esta assinatura não deve causar um revert e deve resultar em uma estimativa máxima de gás.

Desenvolvedores de Contratos Pagadores

Os desenvolvedores de contratos pagadores devem garantir que um valor fictício de paymasterAndData sempre possa ser determinado com base em como a função de validação do contrato pagador vai funcionar. Este valor não deve causar uma reversão e deve resultar em uma estimativa máxima de gás.

A Alchemy simplifica isso para os usuários em seu contrato pagador patrocinador combinando o processo de estimativa de gás e o processo de simulação via alchemy_requestGasAndPaymasterAndData

Desenvolvedores de Clientes de Conta

Desenvolvedores de clientes de conta que estão integrando com um contrato pagador que realiza transferências durante a fase de validação (ou qualquer outra lógica com base no valor da taxa) e estão usando os pontos de extremidade da Alchemy para estimativa, precisam adicionar qualquer gás potencial associado à transferência ao verificationGasLimit retornado pela estimativa.

Fique atento para uma postagem posterior detalhando mais complicações na estimativa de gás do ERC-4337!

🦀

Continue lendo

Os próximos artigos desta série de 4 partes exploram os desafios da estimativa de gás em blockchains da camada 2 como Optimism e Arbitrum e agregadores de assinatura.

A série conclui com uma visão geral do processo de estimativa de taxa de operação do usuário. Se você perdeu a primeira parte, descubra como funciona a estimativa de gás do ERC-4337!

Artigo original publicado por Dan Coombs e David Philipson. Traduzido por Paulinho Giovannini.

Top comments (0)