Alchemy ERC-4337 Paymasters

QuantstampFiles named in the report

Quantstamp reviewed Alchemy ERC (Alchemy ERC-4337 Paymasters) on 20 May 2025: 9 findings, 0 critical; 3 marked fixed, 6 acknowledged.

No open critical findings
Open the reportOpen Alchemy ERC’s security record

Report hosted on certificate.quantstamp.com.

Trustblock does not review code.

Findings9

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium001
Low062
Low`paymasterData` Field Length Should Be EnforcedAcknowledged

For `mode 1, 2 and 3` the `paymasterData` field is structured in the following way: ``` For v0.6 // ERC-20 format: // - [0:20] 20 bytes for paymaster // - [20:52] 32 bytes for sigTimeRange // - [52] 1 byte for mode (0: pre-approval, 1: post-op, 2: permit) // - [53:85] 32 bytes for conversion factor (scaled token price, calculated off-chain) // PRICE_SCALE * ethPriceUsd * 10^tokenDecimals / (tokenPriceUsd * 10^(ethDecimals)) // - [85:105] 20 bytes for token address // - [105:125] 20 bytes for receiver address // - [125:190] 65 bytes for signature // - [190:] variable bytes for permit (if mode == 2) For v0.7 // ERC-20 format for paymaster data: // - [0] 1 byte for mode (0: pre-approval, 1: post-op, 2: permit) // - [1:33] 32 bytes for conversion factor (scaled token price, calculated off-chain) // PRICE_SCALE * ethPriceUsd * 10^tokenDecimals / (tokenPriceUsd * 10^(ethDecimals)) // - [33:53] 20 bytes for token address // - [53:73] 20 bytes for receiver address // - [73:138] 65 bytes for signature // - [138:] variable bytes for permit (if mode == 2) ``` For example, in the context of paymaster v0.7, the bits 138 onwards are only used in `mode = 2`, but there is no enforcement that the field is not used during `modes = 0` and `1`, which could lead to wasted gas due to byte stuffing. The only check currently enforces the `paymasterData ` to be at least 138 bits. There are no direct exploits here, as this byte stuffing would cause a loss for the user because both the paymaster and the user have to sign this data. There is only one case where the paymaster loses some funds, and that is in `mode 1`, where the user does not pay in `postOp`. However, it would be a good practice to avoid this griefing vector.

LowInaccurate `postOp()`-Gas Cost Charges Due to Single ConstantAcknowledged

The paymaster implementation for EntryPointv0.6 contains a `POST_OP_GAS ` constant that is a snapshot measure of the gas-costs of the `postOp()` call with USDC as the ERC-20-payment token. This is used as this version of the EntryPoint lacks a granular parameter for limiting the `postOp` gas that is needed for the cost calculations. The single value is slightly simplifying the mechanics of the different modes of operation. In `mode = 0`, there is for example not just one, but two `safeTransfers()` compared to `mode = 1`. Some tokens might have differing gas costs for their transfers, especially if e.g. ERC-777 or ERC-1155 tokens with callbacks are used. Different chains might also have different gas costs for certain opcodes that are used in this call. Furthermore, in the version supporting EntryPointv0.6, there is also the possibility of reverts, leading to a second invocation of the `postOp()` call that incurs additional gas costs not captured by this constant. We also want to mention that there are very select few chains that adjust the gas costs of certain opcodes most notably [ZKSync](https://docs.zksync.io/zksync-protocol/rollup/fee-model#different-opcode-pricing), that could lead to inaccuracies with the same value between different chain deployments.

LowIncorrect Gas Penalty Calculation in `postOp()` Overcharges UserAcknowledged

The `VerifyingPaymaster` contract applies a 10% gas penalty in the `postOp()` function based on the **total gas limit**, rather than strictly the **unused execution gas**, contrary to the ERC-4337 specification. The penalty is currently calculated as: ```solidity uint256 gasPenalty = (totalGasLimit * actualUserOpFeePerGas - actualGasCostWithPostOp) / 10; ``` This calculation incorrectly penalizes users for unused pre-operation gas, inflating their final charge. According to the [ERC-4337 specification – Required EntryPoint Contract Functionality](https://eips.ethereum.org/EIPS/eip-4337#required-entrypoint-contract-functionality), the `UNUSED_GAS_PENALTY_PERCENT` (10%) should be applied only to unused gas from `callGasLimit` and `paymasterPostOpGasLimit`.

LowNo Association Between On-Chain Gas Costs and the User’s ERC-20-PaymentAcknowledged

In the flow of using this paymaster, the `UserOperation` sender proposes a `UserOperation` to the paymaster signer API, which calculates the appropriate user token payment and encodes these values into the `paymasterAndData` field of the `UserOperation` struct. The user then confirms this data again by providing a passing validation for the full `UserOperation`. Apart from these off-chain calculations by the Paymaster, the actual gas costs of the `UserOperation` and the token amount are not associated with each other, so the users essentially opt in to some token payment, no matter the actual execution costs. The gas costs could be significantly differ from the underlying ERC-20-payment if the `conversionFactor`, the value indicating the conversion between ETH and the token the user is paying in, is wrongly calculated. In volatile token price conditions, it could also be the case that the signer API signs off a significantly lower `conversionFactor`, resulting in a monetary loss of the paymaster. A compromised signer API could also withdraw the full approval from the `UserOp.sender` in a requested `UserOperation`. If the end user does not detect that when providing the validation for the `UserOperation`, they might be left at a significant financial loss.

LowPotential ERC-7562 Violation in `permit()`-FlowAcknowledged

The standard specification of ERC-7597 uses a `block.timestamp` check to check for freshness of the forwarded `deadline` parameter. However, as defined by ERC-7562, this is a forbidden opcode for the validation phase of `UserOperations` according to OP-011, which would result in default bundlers dropping such `UserOperations`, ultimately not including them in bundles on-chain. Some token implementations support ERC-7597, but skip the `block.timestamp` check if a `uint256.max` value is encoded as part of the deadline of the permit. An example of such a token is USDC. Such implementations would not lead to ERC-7562 complications.

LowPotential Validation Inconsistencies Leading to Paymaster BanAcknowledged

The `_validatePaymasterUserOp()` function includes state-dependent reverts that might change in outcome between after second validation and final simulation/execution on the chain, such as paymaster being paused, signer being updated, or allowances/permits being consumed. If validation produces different results for the same `UserOperation` after the second validation simulation, bundlers may ban the paymaster, stopping UserOperations including this paymaster from being propagated. This aligns with [GREP-40](https://eips.ethereum.org/EIPS/eip-7562#general-reputation-rules) from ERC-7562, which emphasizes deterministic validation to prevent bans. Here is a non-exhaustive list of where this might occur: 1. Both Paymasters could be paused via `pause()`. Depending on when the function is called, there can be a case where `UserOperation` is invalidated just before on-chain execution. 2. Signer can be updated via `updateVerifyingSigner()`, which could lead to signature validation failing and there can be a case where `UserOperation` is invalidated just before on-chain execution. 3. Permit or approval can be withdrawn just before the `UserOperation` is executed on-chain.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (4)

  • paymaster-contracts-2.0.0/src/BasePaymaster.sol
  • paymaster-contracts-1.0.0/src/VerifyingPaymaster.sol
  • paymaster-contracts-2.0.0/src/VerifyingPaymaster.sol
  • paymaster-contracts-1.0.0/src/BasePaymaster.sol

Part of Alchemy ERC’s security record

Alchemy ERC
Audits6 audits by 1 firmLast audit May 2025, by Quantstamp.
Critical findingsNo open critical findingsAcross 6 reports.
Open Alchemy ERC’s security record

Security firm

Quantstamp

236 projects reviewed · 332 reports · latest Oct 2026

See Quantstamp’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us