Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Account

Inherits: AbstractSigner, IAccount

A simple ERC4337 account implementation. This base implementation only includes the minimal logic to process user operations. Developers must implement the {AbstractSigner-_rawSignatureValidation} function to define the account's validation logic. NOTE: This core account doesn't include any mechanism for performing arbitrary external calls. This is an essential feature that all Account should have. We leave it up to the developers to implement the mechanism of their choice. Common choices include ERC-6900, ERC-7579 and ERC-7821 (among others). IMPORTANT: Implementing a mechanism to validate signatures is a security-sensitive operation as it may allow an attacker to bypass the account's security measures. Check out {SignerECDSA}, {SignerP256}, or {SignerRSA} for digital signature validation implementations.

Note: stateless:

Functions

onlyEntryPointOrSelf

Revert if the caller is not the entry point or the account itself.

modifier onlyEntryPointOrSelf();

onlyEntryPoint

Revert if the caller is not the entry point.

modifier onlyEntryPoint();

entryPoint

Canonical entry point for the account that forwards and validates user operations.

function entryPoint() public view virtual returns (IEntryPoint);

getNonce

Return the account nonce for the canonical sequence.

function getNonce() public view virtual returns (uint256);

getNonce

Return the account nonce for a given sequence (key).

function getNonce(uint192 key) public view virtual returns (uint256);

validateUserOp

*Validates a user operation. MUST validate the caller is a trusted EntryPoint MUST validate that the signature is a valid signature of the userOpHash, and SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert. MUST pay the entryPoint (caller) at least the “missingAccountFunds” (which might be zero, in case the current account’s deposit is high enough) Returns an encoded packed validation data that is composed of the following elements:

  • authorizer (address): 0 for success, 1 for failure, otherwise the address of an authorizer contract
  • validUntil (uint48): The UserOp is valid only up to this time. Zero for “infinite”.
  • validAfter (uint48): The UserOp is valid only after this time.*
function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
    public
    virtual
    onlyEntryPoint
    returns (uint256);

_validateUserOp

Returns the validationData for a given user operation. By default, this checks the signature of the signable hash (produced by _signableUserOpHash) using the abstract signer ({AbstractSigner-_rawSignatureValidation}). NOTE: The userOpHash is assumed to be correct. Calling this function with a userOpHash that does not match the userOp will result in undefined behavior.

function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) internal virtual returns (uint256);

_signableUserOpHash

Virtual function that returns the signable hash for a user operations. Since v0.8.0 of the entrypoint, userOpHash is an EIP-712 hash that can be signed directly.

function _signableUserOpHash(PackedUserOperation calldata, bytes32 userOpHash)
    internal
    view
    virtual
    returns (bytes32);

_payPrefund

Sends the missing funds for executing the user operation to the {entrypoint}. The missingAccountFunds must be defined by the entrypoint when calling {validateUserOp}.

function _payPrefund(uint256 missingAccountFunds) internal virtual;

_checkEntryPoint

Ensures the caller is the {entrypoint}.

function _checkEntryPoint() internal view virtual;

_checkEntryPointOrSelf

Ensures the caller is the {entrypoint} or the account itself.

function _checkEntryPointOrSelf() internal view virtual;

receive

Receive Ether.

receive() external payable virtual;

Errors

AccountUnauthorized

Unauthorized call to the account.

error AccountUnauthorized(address sender);