ERC-4337 Paymasters: Designing Gas Sponsorship for dApps
ERC-4337 paymaster design is the cornerstone of gas sponsorship in Account Abstraction, allowing dApps to abstract away transaction costs from end users. A paymaster contract acts as a gas bank, covering user operation fees in exchange for custom conditions — paying with ERC-20 tokens, gating by user reputation, or subsidizing specific actions. By decoupling fee payment from the native chain currency, paymasters unlock frictionless onboarding and user retention, especially for non-crypto-native audiences.
This guide walks you through designing, building, and integrating paymasters for real-world dApps. We cover the core contract interface, step-by-step implementation of verifying and token paymasters, strategies to hedge against gas price volatility, and security pitfalls to avoid. You'll also find a comparison table of sponsorship models and actionable integration steps using modern tools like Biconomy, Stackup, and Pimlico. Whether you are building a game, a DeFi protocol, or a social app, you'll leave with a solid blueprint for deploying gas sponsorship at scale.
- ERC‑4337 paymaster design chooses between verifying (server‑signed) and token (ERC‑20 for gas) models, each with different complexity and user experience trade‑offs.
- A paymaster’s core hooks are validatePaymasterUserOp (approve & charge) and postOp (finalize accounting), both must be carefully implemented to avoid reentrancy.
- Gas price volatility must be managed with caps, time‑based expiry, and dynamic surcharges to protect the paymaster’s treasury.
- Integration with bundlers like Stackup and Pimlico is straightforward: attach paymasterAndData to the UserOp and submit.
- Advanced paymasters can incorporate conditions (time, volume, reputation) to offer flexible sponsorship without redeploying contracts.
- Security audits focusing on signature replay, oracle manipulation, and deposit management are non‑negotiable before mainnet launch.
What Is an ERC‑4337 Paymaster and Why Does It Matter?
An ERC‑4337 paymaster is a smart contract that pays the gas for a user operation (UserOp) in exchange for meeting arbitrary conditions. It sits between the UserOp and the EntryPoint contract, validating and optionally charging the user in alternative tokens or simply approving the operation for free. Without paymasters, every user must hold ETH (or the chain’s native gas token) to transact — a massive barrier. With paymasters, a dApp can sponsor gas, accept stablecoins, or even earn yield to cover fees.
Real protocols make this concrete: Biconomy’s paymaster infrastructure offers a plug‑and‑play token paymaster that accepts USDC, DAI, or custom ERC‑20s. Stackup provides a modular paymaster builder with both verifying and token flavors. Pimlico’s paymaster focuses on high‑volume sponsorship with dynamic pricing. Understanding ERC‑4337 paymaster design means deciding who pays and under what conditions — a decision that directly impacts user experience and your project’s treasury.
Core Paymaster Contract Interface: validatePaymasterUserOp and postOp
At the heart of every paymaster are two functions mandated by the ERC‑4337 specification:
- validatePaymasterUserOp — Called by the EntryPoint during the validation phase. It receives the UserOp, its hash, and the maximum gas cost the paymaster may be charged. It must approve (or reject) the operation, optionally deduct funds, and return a context that is passed to
postOp. The paymaster must maintain a sufficient deposit in the EntryPoint to cover the gas it sponsors. - postOp — Called after the UserOp execution, with the same context. This is where the paymaster can finalize any accounting — e.g., withdrawing excess ETH that was deposited or executing a swap to refill its gas reserves. postOp is called with a mode flag indicating whether the UserOp execution succeeded or reverted, so the paymaster can settle its accounting accordingly.
For example, a verifying paymaster uses validatePaymasterUserOp to check a server‑generated signature: if valid, the operation is sponsored. A token paymaster uses the same function to pull ERC‑20 tokens from the user (via approval granted in a prior UserOp) before the main call executes. The design must carefully handle reentrancy and ensure the postOp cannot be forced to fail, which would revert the whole operation.
Choosing a Gas Sponsorship Model: Verifying vs. Token vs. Hybrid
Your paymaster’s core logic defines who bears the gas cost and how you recoup it. The three primary models are:
- Verifying Paymaster — Relies on an off‑chain service to sign a “free pass.” The user’s operation includes the paymaster’s signature; the contract checks it in
validatePaymasterUserOp. Ideal for dApps that want to selectively sponsor gas (e.g., first 10 transactions free) without token handling. - Token Paymaster — Accepts the user’s ERC‑20 tokens in exchange for gas. During validation, the contract calls
transferFromto pull tokens at an exchange rate (or via an oracle). Great for apps with a native token or stablecoin economy. - Hybrid / Liquidity Pool Paymaster — Combines sponsorship with a DeFi pool. The paymaster uses the user’s deposited tokens in a lending protocol like Aave to earn yield, which then pays gas. This model is emerging in projects like Etherspot.
Each model has trade‑offs in complexity, latency, and user experience. For most dApps, starting with a verifying paymaster and later adding token support is the pragmatic path.
Step‑by‑Step: Building a Simple Verifying Paymaster
Let’s construct a verifying paymaster that accepts operations only if they contain a valid EIP‑712 signature from a known off‑chain service. Use the eth‑infinitism account‑abstraction contracts as your starting point. Here is the high‑level flow:
- Deploy a VerifyingPaymaster contract that inherits from
BasePaymasterand implementsvalidatePaymasterUserOp. Store the signer’s address as an immutable variable. - In
validatePaymasterUserOp, reconstruct the UserOp hash (excluding the signature itself), hash it with the chain ID and paymaster address, then callECDSA.recoverto verify the signature matches the stored signer. - Return empty context and pre‑fund the EntryPoint with ETH (the paymaster must have enough deposit). The
postOpfunction can be a no‑op. - Off‑chain service: Listen for pending UserOps (via a bundler’s mempool or API), apply custom logic (e.g., user whitelist, rate limit), and sign a valid operation.
The key insight: the off‑chain service can revoke signatures at any time by refusing to sign, giving you full control over sponsorship. The contract is trustless — it only verifies the signature.
Step‑by‑Step: Building a Token Paymaster (e.g., USDC)
A token paymaster lets users pay gas with USDC (or any ERC‑20). Here’s how to design one using Biconomy’s open‑source pattern:
- User approves the paymaster to spend their USDC (via a prior UserOp or a separate approve call).
- In
validatePaymasterUserOp, compute the gas fee equivalent in USDC using an on‑chain oracle (e.g., Chainlink ETH/USD and USDC/USD feeds). Multiply the expected gas cost by the ETH price, then divide by the USDC price. - Call
transferFrom(user, address(this), feeInUSDC)— this must succeed, otherwise the operation is rejected. To avoid reentrancy, the paymaster should keep a balance mapping and deduct after execution. - In
postOp, finalize the accounting. If the actual gas used differs from the estimate, refund the difference in USDC to the user (or keep as surplus).
Critical detail: Token paymasters often require the user to pre‑approve the paymaster contract, adding an extra step to the UX. Some design patterns batch the approval and the main UserOp into one bundled operation. Also, oracles introduce price lag — consider adding a buffer percentage (1‑2%) to cover slippage.
Managing Future Gas Price Volatility: Strategies for Paymasters
When your paymaster commits to sponsor gas, it faces the risk of ETH price spikes or network congestion. Here are proven strategies to protect your treasury:
- Gas price caps — In
validatePaymasterUserOp, reject operations where the expected gas price (from the UserOp’smaxPriorityFeePerGasandmaxFeePerGas) exceeds a contract‑stored limit. Update the limit via governance based on 50‑day trailing averages. - Time‑based validity — Include a deadline in the paymaster context. If the operation isn’t mined within 5 minutes, the signature or fee calculation becomes invalid. This prevents stale ops from draining funds.
- Dynamic surcharges — For token paymasters, increase the surcharge percentage as the gas price rises. For example, use
surcharge = min(10% , max(2% , (gasPrice - historicalAvg) / historicalAvg * 5%)). - Refill strategies — For verifying paymasters, keep a buffer of ETH in the EntryPoint (e.g., 2x daily expected usage). Set up an automated top‑up system using a keeper service like Gelato to maintain the buffer.
- Layer‑2 considerations — If the dApp uses a L2 with low and stable gas (e.g., Arbitrum, Optimism), the volatility risk diminishes, but you still need to account for L1 data cost spikes. Paymasters on L2s can use the L1 fee oracle to adjust.
Integrating Paymasters with Your dApp Frontend: Using Bundlers
On the frontend, integrating a paymaster requires a bundler that supports paymaster data. Here’s the practical flow using Stackup’s bundler or Pimlico’s ERC‑4337 API:
- Create a UserOp as usual, but leave
paymasterAndDataempty initially. - If using a verifying paymaster, send the UserOp (minus signature) to your off‑chain service. The service validates, signs, and returns
paymasterAndData(paymaster address + signature). Attach it to the UserOp. - If using a token paymaster, the frontend must first get the user to approve the paymaster contract to spend their tokens. Then construct the UserOp with
paymasterAndDataencoding the paymaster address and any pre‑computed fee. - Submit the complete UserOp to a bundler. Recent bundlers automatically handle the paymaster flow — the paymaster’s
validatePaymasterUserOpwill be called during the simulation. - Monitor status via the bundler’s API (or wait for the UserOp to appear in a block). Enable a “tx status” component in your UI.
Libraries like Biconomy SDK abstract much of this, providing pre‑built components for paymaster‑enabled transactions. For custom dApps, the @account‑abstraction/sdk from the eth‑infinitism team is the reference implementation.
Comparison Table: Verifying Paymaster vs. Token Paymaster vs. Hybrid
| Feature | Verifying Paymaster | Token Paymaster | Hybrid / Liquidity Pool |
|---|---|---|---|
| User must hold native gas token? | No | No | No |
| User must have ERC‑20 balance? | No | Yes | Optionally (deposit first) |
| Off‑chain component required? | Yes (signer) | Optional (oracle) | Yes (keeper + oracle) |
| Sponsorship control (e.g., per‑user caps) | High (server logic) | Contract‑level (code logic) | Contract + keeper |
| Gas price volatility protection | Signature expiry + cap | Surcharge + cap | Yield buffer + cap |
| Best for | Free tx campaigns, first‑time users | DeFi, games with native tokens | Long‑term subsidy via yield |
| Example implementations | Stackup VerifyingPaymaster, Biconomy FreeSpender | Biconomy TokenPaymaster, Pimlico USDC paymaster | Etherspot Paymaster+Pool, Uniswap‑based paymaster (experimental) |
Security Considerations and Best Practices
Paymasters handle funds (ETH and ERC‑20), making them high‑value targets. Follow these security principles:
- Never trust
tx.originor the UserOp sender without verification. Always validate the operation’s semantics (e.g., replay protection per user, per chain). Use a nonce in the signed data. - Protect against reentrancy in
postOp. IfpostOpmakes external calls (e.g., refund tokens), ensure state changes are committed before the call. Use a reentrancy guard. - Oracle manipulation — For token paymasters, use a TWAP oracle (e.g., Chainlink’s
latestRoundDatawith a staleness check, or a Uniswap V3 TWAP) rather than a simple spot price. - Deposit management — Withdraw excess funds from the EntryPoint only via a dedicated function with an access control. Never allow arbitrary withdrawal.
- Gas griefing — An attacker could craft a UserOp that passes validation but fails execution, costing the paymaster gas. Mitigate by adding a small penalty in the token paymaster (e.g., non‑refundable fee up to a cap) or by using a verifying paymaster that can blacklist addresses.
Audit your paymaster with a firm experienced in ERC‑4337 — OpenZeppelin and Quantstamp have published relevant audit checklists.
Advanced Design: Condition‑Based Sponsorship (Time, Volume, Reputation)
Beyond simple token‑for‑gas, paymasters can embed rich business logic. Examples you can implement:
- Time‑limited sponsorship — Only sponsor operations within a specific campaign window. Store a
uint256 deadlinein the paymaster and check it duringvalidatePaymasterUserOp. - Volume‑based discounts — Track cumulative gas spent per user (via a mapping from user address). Apply a tiered sponsorship: first 10 UO free, then 50% off, then full price.
- Reputation‑based paymaster — Use an on‑chain identity protocol (e.g., Ethereum Attestation Service or Gitcoin Passport score) to gate sponsorship. Only users with a minimum reputation can get gas covered.
- Back‑denominated enforcement — The paymaster can require that the UserOp’s call data includes a specific function selector (e.g.,
mint()on an NFT contract). This prevents abuse of free gas for unrelated operations.
To implement, store the conditions in the paymaster contract as mutable storage (controlled by the dApp’s admin). Your validatePaymasterUserOp then checks these conditions plus the signature/token transfer. This keeps the core interface unchanged while allowing flexible policy updates without redeploying.
Step-by-step
- Decide on a sponsorship model: verifying, token paymaster, or hybrid, based on your dApp’s user base and token economy.
- Deploy a paymaster contract implementing validatePaymasterUserOp and postOp, using an audited base like eth‑infinitism’s BasePaymaster.
- For verifying paymaster: set up an off‑chain signer that validates UserOps against your policy (e.g., whitelist, rate limit) and returns a signed paymasterAndData.
- For token paymaster: integrate a reliable price oracle (Chainlink TWAP) and handle the ERC‑20 approval + transfer in validatePaymasterUserOp.
- Add gas price volatility protections: implement caps, time‑based expiry, and dynamic surcharges in your paymaster logic.
- Frontend integration: use a bundler (e.g., Stackup, Pimlico) that supports the paymaster and construct UserOps with paymasterAndData attached.
- Test thoroughly on a testnet (e.g., Sepolia with ERC‑4337 support) using a local bundler or hosted service.
- Audit the paymaster contract focusing on reentrancy, oracle manipulation, and deposit management before mainnet deployment.
- Monitor gas sponsorship spending and adjust policies (caps, surcharges) based on real usage and network conditions.
Common mistakes to avoid
- Not implementing replay protection in the verifying paymaster signature, allowing the same signed UserOp to be reused.
- Using a single spot price oracle without staleness checks, exposing the token paymaster to price manipulation attacks.
- Forgetting to include a deadline in paymaster context, leaving the contract vulnerable to stale operations with outdated gas prices.
- Allowing the postOp function to make external calls without proper reentrancy guards, enabling draining of paymaster funds.
- Not pre‑funding the EntryPoint with sufficient ETH, causing UserOp execution to fail even if validatePaymasterUserOp succeeds.
- Assuming gas estimation matches actual usage perfectly — always include a buffer or refund mechanism to avoid user loss.
Frequently asked questions
What is the difference between a verifying paymaster and a token paymaster?
A verifying paymaster uses an off‑chain signature to approve gas sponsorship without requiring the user to hold any specific token. A token paymaster, on the other hand, exchanges an ERC‑20 token from the user to cover gas costs, which requires the user to have that token and approve the paymaster contract.
How do I prevent users from draining my paymaster with high gas prices?
Implement a maximum gas price cap in your paymaster contract, and optionally add a time‑based deadline to the operation. For token paymasters, include a dynamic surcharge that scales with the current gas price relative to a historical average.
Do I need to deploy my own bundler to use a paymaster?
No. You can use hosted bundlers from providers like Stackup, Pimlico, or Biconomy. They support the ERC‑4337 standard and will correctly handle the paymaster flow during UserOp simulation.
What is the safest way to price ERC‑20 tokens in a token paymaster?
Use a time‑weighted average price (TWAP) oracle, such as Chainlink’s feeds with a freshness check (e.g., updatedAt less than 30 minutes old). Avoid volatile spot prices and always apply a small margin (e.g., 1‑2%) to cover price fluctuations between oracle update and execution.
Related reading
Track the entities behind the concepts
DeFi Intel maps 11,000+ protocols, tokens and companies to a typed knowledge graph — with live data, incidents and regulation.