// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /// @title MockConsentPaymaster — TEST-ONLY ERC-4337 v0.7 paymaster. /// @notice NEVER deploy to chain 2800. Exists solely to drive AereEntryPointV2's /// paymaster-consent gate through its accept / reject / wrong-EntryPoint /// paths in the hardhat suite. /// /// Models a spec-compliant paymaster: the EntryPoint calls /// validatePaymasterUserOp during the validation phase; the paymaster verifies /// the caller is its bound EntryPoint and either consents (returns /// validationData == 0) or refuses (reverts, or returns a nonzero validationData). contract MockConsentPaymaster { struct PackedUserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; bytes32 accountGasLimits; uint256 preVerificationGas; bytes32 gasFees; bytes paymasterAndData; bytes signature; } address public entryPoint; bool public consent = true; // false => revert (explicit no-consent) bool public returnNonzero; // true => consent path returns validationData=1 (sig fail) uint256 public validateCalls; // how many times the EntryPoint asked for consent bytes32 public lastUserOpHash; // the exact op the EntryPoint asked us to sponsor constructor(address _entryPoint) { entryPoint = _entryPoint; } function setConsent(bool c) external { consent = c; } function setReturnNonzero(bool b) external { returnNonzero = b; } function setEntryPoint(address ep) external { entryPoint = ep; } function validatePaymasterUserOp( PackedUserOperation calldata /* op */, bytes32 userOpHash, uint256 /* maxCost */ ) external returns (bytes memory context, uint256 validationData) { require(msg.sender == entryPoint, "PM: not from EntryPoint"); validateCalls++; lastUserOpHash = userOpHash; require(consent, "PM: rejected"); return ("", returnNonzero ? uint256(1) : uint256(0)); } }