Paymaster Contract Development (ERC-4337)
ERC-4337 (Account Abstraction) solves one of Web3's main onboarding problems: a new user can't interact with a dApp until they have ETH to pay gas. A Paymaster is a smart contract that takes on gas payment for users. Either full sponsorship ("gasless transactions") or paying gas in ERC-20 tokens instead of ETH.
How Paymaster Fits in the ERC-4337 Stack
ERC-4337 doesn't change the Ethereum protocol — it works on top via a separate infrastructure layer. Key components:
- UserOperation — object describing user action (like a transaction)
-
Bundler — node collecting UserOperations and sending them through
EntryPointcontract - EntryPoint — the only contract verified by ERC-4337 community (same address on all EVM chains)
- Paymaster — optional contract that pays gas instead of the user
Flow: user signs UserOperation → bundler checks via simulation → EntryPoint calls validatePaymasterUserOp → if ok, executes operation → calls postOp for final settlement.
Two Types of Paymaster and Their Implementation
Sponsoring Paymaster (Free Gas for User)
Simplest case: a studio wants users of their dApp to not pay gas. Paymaster deposits ETH in EntryPoint (entryPoint.depositTo(paymasterAddress)) and approves UserOperations from desired accounts.
Critical part is the validatePaymasterUserOp function:
function validatePaymasterUserOp(
UserOperation calldata userOp,
bytes32 userOpHash,
uint256 maxCost
) external returns (bytes memory context, uint256 validationData)
Here you decide: who to sponsor? Without checks, anyone can drain the Paymaster's deposit. Standard approaches:
Whitelist by address. Simplest — list of allowed Smart Account addresses. Good for beta with limited users.
Off-chain signature. Paymaster backend checks conditions (KYC, subscription, balance) and issues signature, which user includes in paymasterData field. Paymaster on-chain verifies ECDSA signature from trusted key. Allows dynamic sponsorship logic without contract changes. OpenZeppelin provides VerifyingPaymaster as reference implementation.
Time and volume limits. validAfter and validUntil in validationData limit UserOperation validity window — protection from replay in future blocks.
ERC-20 Paymaster (Gas in Tokens)
User pays gas in USDC or project's native token. More complex because ETH/USDC rate must be obtained on-chain. Requires a price oracle — Chainlink Price Feed.
Calculation flow:
-
validatePaymasterUserOp— read ETH/USDC price from Chainlink, calculatemaxCostin tokens,transferFromuser's account - Operation executes
-
postOp— calculate actual gas cost (known precisely only after execution), return excess or charge more
Problem with postOp mode == PostOpMode.postOpReverted: if postOp reverts, EntryPoint calls it again with mode = postOpReverted. If contract doesn't handle this case, it enters infinite revert loop. Must explicitly check mode and handle both states.
Security: What Can Go Wrong
Gas griefing via malicious postOp. If user's Smart Account forces postOp to consume more gas than expected — Paymaster overpays. Protection: set postOpGasLimit with buffer, but not unlimited.
Price manipulation via Chainlink. Using spot price without TWAP, attacker can theoretically flash-loan attack to temporarily change oracle price. For most Paymasters, Chainlink with staleness check is sufficient (price not updated >1 hour — reject operation).
Deposit exhaustion. Need to monitor EntryPoint balance. If deposit drops below threshold — operations start rejecting with unclear error for user. Automatic top-up via Keeper or Gelato Automation.
Stack and Infrastructure
-
Contract: Solidity 0.8.x, OpenZeppelin
BasePaymaster,EntryPointv0.6 or v0.7 -
Testing: Hardhat with
@account-abstraction/sdkor Foundry with mainnet fork - Bundler: Stackup, Alchemy AA SDK, Pimlico — for testing and production
-
Frontend SDK:
permissionless(viem-based) or@alchemy/aa-sdk - Deposit monitoring: The Graph or custom indexer
Work with EntryPoint v0.7 (latest on Ethereum mainnet). If project needs v0.6 compatibility — need separate Paymaster version, interfaces aren't compatible.
Development Process
Analytics. Determine Paymaster type (sponsor vs ERC-20), verification logic, sponsorship limits.
Development. Inherit from OpenZeppelin BasePaymaster, implement _validatePaymasterUserOp and _postOp. Deploy separate backend service for off-chain signature if needed.
Testing. Fork mainnet in Hardhat, deploy EntryPoint (already at standard address), tests with real bundler flow via @account-abstraction/sdk.
Deployment and monitoring. Deploy to target chains, deposit ETH in EntryPoint, set up alerts on deposit balance.
Timelines
Sponsoring Paymaster with whitelist verification — 3 working days. Paymaster with off-chain signature and backend service — 4-5 days. ERC-20 Paymaster with Chainlink integration — 5-7 days.
Cost calculated individually.







