Skip to content

Commit cd9b527

Browse files
authored
Merge branch 'master' into aa/erc7913-signer
2 parents fb0e649 + b6af12a commit cd9b527

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1265
-437
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,16 @@
44
- `SignerERC7913`: Abstract signer that verifies signatures using the ERC-7913 workflow.
55
- `ERC7913SignatureVerifierP256` and `ERC7913SignatureVerifierRSA`: Ready to use ERC-7913 verifiers that implement key verification for P256 (secp256r1) and RSA keys.
66

7+
## 03-04-2025
8+
9+
- `PaymasterNFT`: Extension of `PaymasterCore` that approves sponsoring of user operation based on ownership of an ERC-721 NFT.
10+
- `PaymasterERC20`: Extension of `PaymasterCore` that sponsors user operations against payment in ERC-20 tokens.
11+
12+
## 28-03-2025
13+
14+
- Deprecate `Account` and rename `AccountCore` to `Account`.
15+
- Update `Account` and `Paymaster` to support entrypoint v0.8.0.
16+
717
## 07-03-2025
818

919
- `ERC7786Aggregator`: Add an aggregator that implements a meta gateway on top of multiple ERC-7786 gateways.

contracts/account/Account.sol

Lines changed: 132 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,141 @@
22

33
pragma solidity ^0.8.20;
44

5-
import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
6-
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
7-
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
8-
import {ERC7739} from "../utils/cryptography/ERC7739.sol";
9-
import {AccountCore} from "./AccountCore.sol";
5+
import {PackedUserOperation, IAccount, IEntryPoint} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";
6+
import {ERC4337Utils} from "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol";
7+
import {AbstractSigner} from "../utils/cryptography/AbstractSigner.sol";
108

119
/**
12-
* @dev Extension of {AccountCore} with recommended feature that most account abstraction implementation will want:
10+
* @dev A simple ERC4337 account implementation. This base implementation only includes the minimal logic to process
11+
* user operations.
1312
*
14-
* * {ERC721Holder} and {ERC1155Holder} to accept ERC-712 and ERC-1155 token transfers transfers.
15-
* * {ERC7739} for ERC-1271 signature support with ERC-7739 replay protection
13+
* Developers must implement the {AbstractSigner-_rawSignatureValidation} function to define the account's validation logic.
1614
*
17-
* TIP: Use {ERC7821} to enable external calls in batches.
15+
* NOTE: This core account doesn't include any mechanism for performing arbitrary external calls. This is an essential
16+
* feature that all Account should have. We leave it up to the developers to implement the mechanism of their choice.
17+
* Common choices include ERC-6900, ERC-7579 and ERC-7821 (among others).
1818
*
19-
* NOTE: To use this contract, the {ERC7739-_rawSignatureValidation} function must be
20-
* implemented using a specific signature verification algorithm. See {SignerECDSA}, {SignerP256} or {SignerRSA}.
19+
* IMPORTANT: Implementing a mechanism to validate signatures is a security-sensitive operation as it may allow an
20+
* attacker to bypass the account's security measures. Check out {SignerECDSA}, {SignerP256}, or {SignerRSA} for
21+
* digital signature validation implementations.
2122
*/
22-
abstract contract Account is AccountCore, ERC721Holder, ERC1155Holder, ERC7739 {}
23+
abstract contract Account is AbstractSigner, IAccount {
24+
/**
25+
* @dev Unauthorized call to the account.
26+
*/
27+
error AccountUnauthorized(address sender);
28+
29+
/**
30+
* @dev Revert if the caller is not the entry point or the account itself.
31+
*/
32+
modifier onlyEntryPointOrSelf() {
33+
_checkEntryPointOrSelf();
34+
_;
35+
}
36+
37+
/**
38+
* @dev Revert if the caller is not the entry point.
39+
*/
40+
modifier onlyEntryPoint() {
41+
_checkEntryPoint();
42+
_;
43+
}
44+
45+
/**
46+
* @dev Canonical entry point for the account that forwards and validates user operations.
47+
*/
48+
function entryPoint() public view virtual returns (IEntryPoint) {
49+
return ERC4337Utils.ENTRYPOINT_V08;
50+
}
51+
52+
/**
53+
* @dev Return the account nonce for the canonical sequence.
54+
*/
55+
function getNonce() public view virtual returns (uint256) {
56+
return getNonce(0);
57+
}
58+
59+
/**
60+
* @dev Return the account nonce for a given sequence (key).
61+
*/
62+
function getNonce(uint192 key) public view virtual returns (uint256) {
63+
return entryPoint().getNonce(address(this), key);
64+
}
65+
66+
/**
67+
* @inheritdoc IAccount
68+
*/
69+
function validateUserOp(
70+
PackedUserOperation calldata userOp,
71+
bytes32 userOpHash,
72+
uint256 missingAccountFunds
73+
) public virtual onlyEntryPoint returns (uint256) {
74+
uint256 validationData = _validateUserOp(userOp, userOpHash);
75+
_payPrefund(missingAccountFunds);
76+
return validationData;
77+
}
78+
79+
/**
80+
* @dev Returns the validationData for a given user operation. By default, this checks the signature of the
81+
* signable hash (produced by {_signableUserOpHash}) using the abstract signer ({AbstractSigner-_rawSignatureValidation}).
82+
*
83+
* NOTE: The userOpHash is assumed to be correct. Calling this function with a userOpHash that does not match the
84+
* userOp will result in undefined behavior.
85+
*/
86+
function _validateUserOp(
87+
PackedUserOperation calldata userOp,
88+
bytes32 userOpHash
89+
) internal virtual returns (uint256) {
90+
return
91+
_rawSignatureValidation(_signableUserOpHash(userOp, userOpHash), userOp.signature)
92+
? ERC4337Utils.SIG_VALIDATION_SUCCESS
93+
: ERC4337Utils.SIG_VALIDATION_FAILED;
94+
}
95+
96+
/**
97+
* @dev Virtual function that returns the signable hash for a user operations. Since v0.8.0 of the entrypoint,
98+
* `userOpHash` is an EIP-712 hash that can be signed directly.
99+
*/
100+
function _signableUserOpHash(
101+
PackedUserOperation calldata /*userOp*/,
102+
bytes32 userOpHash
103+
) internal view virtual returns (bytes32) {
104+
return userOpHash;
105+
}
106+
107+
/**
108+
* @dev Sends the missing funds for executing the user operation to the {entrypoint}.
109+
* The `missingAccountFunds` must be defined by the entrypoint when calling {validateUserOp}.
110+
*/
111+
function _payPrefund(uint256 missingAccountFunds) internal virtual {
112+
if (missingAccountFunds > 0) {
113+
(bool success, ) = payable(msg.sender).call{value: missingAccountFunds}("");
114+
success; // Silence warning. The entrypoint should validate the result.
115+
}
116+
}
117+
118+
/**
119+
* @dev Ensures the caller is the {entrypoint}.
120+
*/
121+
function _checkEntryPoint() internal view virtual {
122+
address sender = msg.sender;
123+
if (sender != address(entryPoint())) {
124+
revert AccountUnauthorized(sender);
125+
}
126+
}
127+
128+
/**
129+
* @dev Ensures the caller is the {entrypoint} or the account itself.
130+
*/
131+
function _checkEntryPointOrSelf() internal view virtual {
132+
address sender = msg.sender;
133+
if (sender != address(this) && sender != address(entryPoint())) {
134+
revert AccountUnauthorized(sender);
135+
}
136+
}
137+
138+
/**
139+
* @dev Receive Ether.
140+
*/
141+
receive() external payable virtual {}
142+
}

contracts/account/AccountCore.sol

Lines changed: 0 additions & 143 deletions
This file was deleted.

contracts/account/README.adoc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@ NOTE: This document is better viewed at https://docs.openzeppelin.com/community-
44

55
This directory includes contracts to build accounts for ERC-4337. These include:
66

7-
* {AccountCore}: An ERC-4337 smart account implementation that includes the core logic to process user operations.
8-
* {Account}: An extension of `AccountCore` that implements the recommended features for ERC-4337 smart accounts.
9-
* {AccountERC7579}: An extension of `AccountCore` that implements support for ERC-7579 modules.
7+
* {Account}: An ERC-4337 smart account implementation that includes the core logic to process user operations.
8+
* {AccountERC7579}: An extension of `Account` that implements support for ERC-7579 modules.
109
* {AccountERC7579Hooked}: An extension of `AccountERC7579` with support for a single hook module (type 4).
1110
* {ERC7821}: Minimal batch executor implementation contracts. Useful to enable easy batch execution for smart contracts.
1211

1312
== Core
1413

15-
{{AccountCore}}
16-
1714
{{Account}}
1815

1916
== Extensions

0 commit comments

Comments
 (0)