Thank you! Your submission has been received!

Oops! Something went wrong while submitting the form

**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.

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} .

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.

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?

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.

This dummy signature has a few constraints:

- 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. - The dummy value must, when supplied to the account’s validation function, cause the worst-case gas usage and must not cause a revert.
- 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:**

- It’s the exact length of an ECDSA signature
- It has the maximum number of non-zero bytes allowed in an ECDSA signature
- It’s a valid ECDSA signature (so that the
_{.recover()}call does not revert - 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:**

- Only using
_{REVERT}on signatures that cannot be the dummy signature. Return_{SIG_VALIDATION_FAILED}when the dummy signature is supplied. - 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.
- 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.

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.

This dummy _{paymasterAndData} has a few constraints:

- 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. - The dummy value must, when supplied to the paymaster’s validation function, cause the worst-case gas usage and must not cause a revert.
- 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:

- The dummy value must contain a valid paymaster contract address
- Maximum length and byte values for
_{preVerificationGas}calculations - 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:**

- Only using
_{revert}on data that cannot be part of the dummy. Return_{SIG_VALIDATION_FAILED}instead. - 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.

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:

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

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:**

- Estimate gas
- Fund account for gas
- 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.

The approach taken by Rundler for _{eth_estimateUserOperationGas} is as follows:

- 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”

- 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.

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

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 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 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!

🦀

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!