0%
HomeBlogTechnical
ERC-4337 Dummy Signatures and Gas Token Transfers

ERC-4337 Dummy Signatures and Gas Token Transfers

Authors:Dan Coombs

Reviewed by Brady Werkheiser


Published on July 11, 20236 min read

This article was co-authored by David Philipson.

In ERC-4337 Gas Estimation we discussed how gas works in ERC-4337 and our method for gas estimation. With this method, we should be able to provide users with accurate values for submitting their user operations. Alas, its not always that simple.

Let’s dive into a few other problems that complicate ERC-4337 gas estimation.

What are dummy signature values?

In most smart contract account implementations the signature field is computed off-chain by hashing a user operation and signing that hash using some signature scheme (ECDSA being the most popular). This signature is verified onchain by the account contract during the verification phase.

For example, SimpleAccount uses an EIP-191 signature scheme on the hash that is validated onchain during its validateUserOp function using OpenZeppelin’s ECDSA library.

This signature must be computed after gas is estimated, as those fields are included in the hash.

However, there are portions of the gas estimation step that require the signature field to be populated: preVerificationGas and verificationGasLimit .

preVerificationGas

In the section on preVerificationGas estimation in part one of this series, we discussed three calculations that the bundler uses to account for unmetered gas.

Notice that steps 2 and 3 (calculating the user ops's share of the calldata gas cost and the user op's share of any execution gas overhead) both directly depend on the length and content of a user operation, including the signature field.

verificationGasLimit

Almost all useful smart contract account implementations will require some signature verification. This gas needs to be estimated! This estimation process cannot revert or else verification gas cannot be implemented.

How do we choose what signature to use?

How to Calculate Dummy Signature Values

To solve these problems, many ERC-4337 bundlers use a “Dummy Signature” that must be provided by the caller of eth_estimateUserOperationGas based on the specific account type.

Constraints

This dummy signature has a few constraints:

  1. The dummy value’s length should be the equal to the maximum signature length and must contain the maximum number of non-zero bytes valid for the account.
    a. This ensures that the preVerificationGas calculations can account for the worst-case signature’s contribution to calldata and entry point overhead costs.

  2. The dummy value must, when supplied to the account’s validation function, cause the worst-case gas usage and must not cause a revert.

  3. The dummy value shouldn’t be a valid signature for any valid user operation.

A dummy signature value for SimpleAccount can be found in our documentation for the eth_estimateUserOperationGas method.

This dummy signature has the following properties:

  1. It’s the exact length of an ECDSA signature

  2. It has the maximum number of non-zero bytes allowed in an ECDSA signature

  3. It’s a valid ECDSA signature (so that the .recover() call does not revert

  4. It’s not a signature for any known user operation, so SimpleAccount will always return SIG_VALIDATION_FAILED

Account implementors need to ensure they write their validation functions such that supplying a dummy signature is possible.

This means:

  1. Only using REVERT on signatures that cannot be the dummy signature. Return SIG_VALIDATION_FAILED when the dummy signature is supplied.

  2. Taking care to not “short-circuit” failure for the dummy signature. That is, the dummy value should run through the entire validation function and use the maximum amount of gas.

  3. In practice, this means removing any early returns. An account validation function may determine that the signature is invalid early, but it should continue to run the function logic and return the failure at the very end.

How to Calculate Dummy paymasterAndData Values

The same requirements above apply to the paymasterAndData field during gas estimation: for any paymaster implementation that relies on the gas fields’ values (i.e. for computing a signature), we must solve the same problem of supplying a dummy value.

Constraints

This dummy paymasterAndData has a few constraints:

  1. The dummy value’s length should be the equal to the maximum paymasterAndData length and must contain the maximum number of non-zero bytes valid for the account.
    a. This ensures that the preVerificationGas calculations can account for the worst-case paymasterAndData contribution to calldata and entry point overhead costs.

  2. The dummy value must, when supplied to the paymaster’s validation function, cause the worst-case gas usage and must not cause a revert.

  3. The dummy value shouldn’t be a valid paymasterAndData for any valid user operation.

For example, a sponsoring paymaster that relies on the verification of a sponsorship signature over the user operation hash will need to supply a dummy paymasterAndData value during estimation with similar properties as outlined above:

  1. The dummy value must contain a valid paymaster contract address

  2. Maximum length and byte values for preVerificationGas calculations

  3. When supplied to the paymaster’s validation function it must consume maximum gas and result in a  SIG_VALIDATION_FAILED return value

Paymaster implementors need to insure they write their validation functions such that supplying a dummy paymasterAndData is possible.

This means:

  1. Only using revert on data that cannot be part of the dummy. Return  SIG_VALIDATION_FAILED instead.

  2. Taking care to not “short-circuit” failure for the dummy. That is, the dummy should run through the entire validation function and use the maximum amount of gas.
    a. In practice, this means removing any early returns. A paymaster validation function may determine that the signature is invalid early, but it should continue to run the function logic and return the failure at the very end.

Gas Token Transfers

The estimation for verificationGasLimit must take into account the gas cost of any token transfers during the validation phase.  Many user ops involve a transfer of tokens during the validation to pay up front for gas, with a refund at the end of the operation for any gas that wasn’t consumed.

There are two cases:

  1. No Paymaster - this is a transfer of ETH from the sender to the entry point contract.

  2. With a Paymaster - this can be anything (within the allowed rules of the specification) but often takes the form of an ERC-20 token transfer from the sender to the paymaster.

What happens if the account doesn’t have enough funds?

If maxFeePerGas is set to a non-zero value, the transfer during validation will revert if the account doesn’t hold enough tokens to pay the fee. This means that users must fund their accounts prior to attempting to estimate gas.

A desired workflow that isn’t possible now:

  1. Estimate gas

  2. Fund account for gas

  3. Send operation

A possible solution here is to tell the user to leave maxFeePerGas unset, or set to zero, when calling eth_estimateUserOperationGas. However, this will set the gas cost to zero and thus a zero value for whatever token transfer needs to occur. In many account/paymaster types a zero gas cost will skip the call to transfer.  This leads to a gas underestimation when a zero maxFeePerGas is used.

Another problem has to do with using a non-zero maxFeePerGas and attempting the binary search estimation approach defined in "Attempt 3: Binary Search," from part 1 of this series.

The first step in that approach is to ensure that the operation is possible by using a maximum gas value. The sender may not have enough assets to pay for gas at that maximum value and the bundler doesn’t always have enough information to determine the balance of the fee token (i.e. the ERC-20 paymaster case) to determine the correct upper bound.

How does Alchemy’s bundler solve gas estimation with the transfer of tokens?

The approach taken by Rundler for eth_estimateUserOperationGas is as follows:

No Paymaster Case

  • Rundler will always ignore maxFeePerGas and maxPriorityFeePerGas and set to 0.

  • Rundler will always add a static 10K gas to verificationGasLimit to account for the ETH deposit transfer from sender to entry point.

  • No client-side changes are required.

💡 Bullet #1 is a deviation from the ERC-4337 spec which states “gas limits (and prices) parameters are optional, but are used if specified”

Paymaster Case

  • Rundler will always ignore maxFeePerGas and maxPriorityFeePerGas and set to 0.

  • Rundler’s verificationGasLimit will always be underestimated if any paymaster logic is conditional on the fee value (like an ERC-20 transfer would be)

  • Users of these paymasters are required to account for any extra gas that would be incurred by a non-zero fee client side.

For example, if using an ERC-20 paymaster that does a transfer during the validation phase always add a static 75K gas to the verificationGasLimit return value from eth_estimateUserOperationGas. This requires clients to be aware of the paymaster contract they’re calling into and have prior knowledge of underestimated gas costs due to transfers.

💡 The Alchemy aa-sdk allows paymaster middleware to modify this gas limit accordingly.

What does this mean for developers?

Dummy values and the token transfer problem impacts developers building smart contract accounts, paymasters, and account clients.

Smart Contract Account Developers

Smart contract account developers need to ensure that a dummy signature value is always able to be determined client-side based on how the account validation function is going to run. This signature must not cause a revert and must result in a maximum gas estimate.

Paymaster Developers

Paymaster developers must ensure that a dummy paymasterAndData value is always able to be determined based on how the paymaster validation function is going to run. This value must not cause a revert and must result in a maximum gas estimate.

💡 Alchemy simplifies this for users in its sponsoring paymaster by combining the gas estimation process and the simulation process via alchemy_requestGasAndPaymasterAndData

Account Client Developers

Account client developers who are integrating with a paymaster that performs transfers during the validation phase (or any other logic based on the fee value), and are using Alchemy’s endpoints for estimation, need to add any potential gas associated with the transfer to the verificationGasLimit returned by estimation.

Stay tuned for a later post outlining more ERC-4337 gas estimation complications!

🦀

Continue Reading

The next articles in this 4-part series explore the challenges estimating gas on layer 2 blockchains like Optimism and Arbitrum and signature aggregators.

The series concludes with a walkthrough of the user operation fee estimation process. If you missed part one, learn how ERC-4337 gas estimation works!

Section background image

Build blockchain magic with Alchemy

Alchemy combines the most powerful web3 developer products and tools with resources, community and legendary support.