ERC-4337 Error AA50: Paymaster PostOp Reverted Diagnostic
ERC-4337 error AA50 "postOp reverted" occurs when a paymaster contract's postOp execution hook reverts after the main user call has completed. Paymasters utilize postOp to perform post-execution accounting, such as debiting ERC-20 tokens (e.g. USDC) from the user's smart account to reimburse gas costs. If the user spent all their tokens during the main call or if token allowance is insufficient, postOp reverts. Ensure sufficient token balance remains.
# Root Cause & Technical Architecture
In ERC-4337, if a paymaster requests post-execution execution by returning context from `validatePaymasterUserOp`, the EntryPoint calls `paymaster.postOp(mode, context, actualGasCost)`. In `mode == opSucceeded`, the paymaster typically executes `IERC20.transferFrom(sender, paymaster, tokenCost)`. If the main execution consumed the user's entire token balance or revoked the approval, `transferFrom` reverts, triggering `revert("AA50 postOp reverted")`.
# 4-Step Actionable Diagnostic Protocol
Step-by-Step ResolutionCheck User ERC-20 Token Balance After Execution
Simulate the transaction and verify that the sender wallet maintains enough USDC/ERC-20 balance to pay actualGasCost at completion.
Verify Paymaster Token Allowance Setting
Ensure the smart account has granted sufficient token allowance to the paymaster contract so transferFrom does not revert during postOp.
Audit Paymaster postOp Gas Allocation
In EntryPoint v0.7, paymasterPostOpGasLimit governs the gas available to postOp. Ensure this limit is sufficient for ERC-20 transfer state updates.
Handle postOp Revert Fallback in Paymaster Logic
If building a custom paymaster, ensure postOp catches token transfer failures gracefully in mode postOpReverted to avoid blocking the bundler.
# Diagnostic Verification Code / Command
solidity// ERC-4337 Paymaster postOp Implementation Guard
function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external override {
(address sender, address token, uint256 maxCost) = abi.decode(context, (address, address, uint256));
// Calculate actual token charge based on actualGasCost
uint256 tokenAmount = (actualGasCost * tokenPrice) / 1e18;
// Prevent AA50: Ensure token transfer succeeds or handles revert cleanly
bool success = IERC20(token).transferFrom(sender, address(this), tokenAmount);
require(success, "Token gas reimbursement failed");
} Launch ERC-4337 UserOp Decoder
Execute client-side cryptographic simulation and parameter checks safely in your browser via native WebCrypto without sending private keys or mnemonics over the wire.
Read Full Investigation & Recovery Workflow
Explore complete architectural diagrams, edge-case failure trees, and detailed post-mortem analysis in our verified deep guide.
# Related Diagnostic Codes in ERC-4337 & Safe
Related Hex StatusesERC-4337 Error AA10: Sender Already Constructed UserOp Fix
Fix ERC-4337 error AA10 sender already constructed. Resolve non-empty initCode sent for deployed smart accounts, bundler estimation, and counterfactuals.
ERC-4337 Error AA20: Account Not Deployed EntryPoint Revert
Fix ERC-4337 error AA20 account not deployed. Troubleshoot empty initCode for counterfactual smart accounts, factory calldata, and pre-deployment.
ERC-4337 Error AA24: Signature Error UserOp Validation Fix
Fix ERC-4337 error AA24 signature error. Resolve validateUserOp signature mismatch, userOpHash EIP-712 hashing errors, and signature aggregator faults.
# Frequently Asked Questions
FAQ SchemaWhat is the difference between AA33 and AA50?
AA33 is the v0.6 EntryPoint revert string for postOp failure, whereas AA50 is the modernized error code used in EntryPoint v0.7 specifications.
Why do ERC-20 gas paymasters require a postOp hook?
Actual gas cost is only known after the transaction finishes executing. The postOp hook calculates the exact fee and debits the user accordingly.
Does the user transaction still happen if postOp reverts?
No. If postOp reverts in standard execution, the entire UserOperation (including the user's primary call) is reverted by the EntryPoint.