-
Notifications
You must be signed in to change notification settings - Fork 12.4k
Add Account framework docs and guides #5660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 133 commits
Commits
Show all changes
140 commits
Select commit
Hold shift + click to select a range
f5544fd
Add Account framework
ernestognw 40dfd20
Add missing mocks
ernestognw 0bcc521
Adding missing hardhat config
ernestognw 7e75026
up
ernestognw 5fb074c
Remove unnecessary files for mocks
ernestognw e5df541
Remove more unnecessary mock files
ernestognw 5ad9788
replace hardcoded links
ernestognw 7090f67
lockfile
ernestognw c4af1d7
update ethers
ernestognw aa8f29b
add missing interface
ernestognw 415c00d
Add changesets
ernestognw f60aa3a
up
ernestognw 087a844
up
ernestognw 79629b7
up
ernestognw f47cab7
up
ernestognw 8f58197
up
ernestognw ecede7f
up
ernestognw 68bd96a
up
ernestognw d5cb119
chore: empty commit
ernestognw 6a0ae8a
change read permissions
ernestognw a49a157
Update lucky-donuts-scream.md
ernestognw a634278
Update clean-ways-push.md
ernestognw 8b6501a
Update tame-bears-mix.md
ernestognw 39a1026
reset package-lock.json
ernestognw 71a6b25
up
ernestognw 35d4a12
up
ernestognw a95705b
reset dependencies
ernestognw 90509bd
reset dependencies
ernestognw 10f40d7
reset dependencies
ernestognw 36fb044
lint
ernestognw f534243
Add ERC7913 signers and utilities
ernestognw c0e5e45
Add Account framework docs and guides
ernestognw 7e10f80
Attempt to fix tests
ernestognw c6ed868
up
ernestognw b87c8e2
Merge branch 'master' into feature/account-abstraction
ernestognw f6d07c2
adjust action.yml
ernestognw cfa2392
up
ernestognw 9a8e63f
Merge branch 'master' into feature/account-abstraction
ernestognw 3a90091
lint
ernestognw bdec803
lint
ernestognw 73c12c7
Merge branch 'master' into feature/account-abstraction
ernestognw 1c97739
Test ethers 6.13.6-beta.1
ernestognw 6b1bbd8
up
ernestognw 7764515
up
ernestognw 19fe4c5
up
ernestognw 11c42c3
checks
ernestognw be68753
up
ernestognw f0a1155
build in slither
ernestognw c42a7fd
Update build command
ernestognw 6e576ca
compile hardhat too
ernestognw 593e879
revert slither changes
ernestognw c3f39a1
Remove package-lock.json to skip installing dependencies
ernestognw db76c3b
up
ernestognw 8eebff0
Add @custom:stateless tag
ernestognw 65fa7de
update upgradeable.patch
ernestognw abac3bd
fix conflicts
ernestognw 7d120b9
rollback <package-version>
ernestognw 02eccc1
update upgradeable.patch
ernestognw c39d5f5
Tweak workflows
ernestognw 54f632a
Use Solidity 0.8.27 as default and set default EVM to prague
ernestognw 58c794e
Adjust ERC2771Forwarder gas to avoid GasFloorMoreThanGasLimit
ernestognw 6a60523
Remove console.log
ernestognw 80edba8
Add EnumerableSetExtended and EnumerableMapExtended
ernestognw 29c48d9
Fix lint and enable formatting after generation
ernestognw fae0a67
Add ERC7913 signers and utilities
ernestognw c6b299e
Merge branch 'feature/erc7913' into docs/account
ernestognw e412bd9
Add EnumerableSetExtended and EnumerableMapExtended
ernestognw f7f64ee
Add changeset and fix linting
ernestognw 2c33b49
Merge branch 'master' into docs/account
ernestognw b0b70eb
Merge branch 'master' into feature/enumerable-extended
ernestognw b695659
Remove TODOs
ernestognw 5c4fb88
Reset package-lock
ernestognw 8f32638
Revert run.js
ernestognw b12ca61
Merge Enumerable{Set,Map}Extended into Enumerable{Set,Map}
Amxx 45fa35f
Update scripts/generate/templates/Enumerable.opts.js
Amxx bec8059
clarification
Amxx 0d7f9d0
speedup generation with selective linter
Amxx 2376a45
update documentation
Amxx 1e35eab
Merge master
ernestognw c275c03
Remove unnecesary code
ernestognw 5975d79
Remove Bytes32x2
ernestognw 9356599
Update .changeset/pink-dolls-shop.md
ernestognw 86c2cb8
Remove unnecessary _hashes
ernestognw 6898230
Simplify
ernestognw 4e2bc70
Improve changesets
ernestognw 2a1f503
remove unecessary import
Amxx 326c466
Use Arrays.sol
ernestognw 52ac908
Merge branch 'feature/enumerable-extended' into feature/erc7913
ernestognw 6725618
up
ernestognw 0cce4d5
up
ernestognw 5c45ff0
Merge branch 'master' into feature/erc7913
Amxx 80d8bd5
Merge branch 'master' into feature/erc7913
ernestognw 30f3bfa
cleanup
ernestognw eab64f8
Remove EnumerableSetExtended usage
ernestognw e3dcc2b
Add tests
ernestognw 3ac675d
Add changesets
ernestognw b20b017
Merge branch 'master' into feature/erc7913
ernestognw 804ceea
Organize
ernestognw d0f5961
Review
ernestognw 98108d9
Increase SignatureChecker's pragma
ernestognw 906a805
Merge branch 'master' into docs/account
ernestognw 1bfa65c
Fix
ernestognw 1a9c074
Remove
ernestognw 4135626
Merge branch 'feature/erc7913' into docs/account
ernestognw e1ffe05
Pragma consistency
ernestognw 7070e39
Merge branch 'feature/erc7913' into docs/account
ernestognw 709493e
Fix compilation
ernestognw 91aeb92
Increase SignatureChecker minimum pragma to 0.8.24
ernestognw a1ca133
Update mocks
ernestognw 6491896
Merge branch 'master' into docs/account
ernestognw 7cf7b85
Merge branch 'master' into docs/account
ernestognw ce284c4
Merge branch 'master' into docs/account
ernestognw 1567931
Minimize changes
ernestognw fd5ac83
up
ernestognw ca2284d
Merge branch 'master' into docs/account
ernestognw e636dcd
Merge branch 'master' into docs/account
ernestognw fd60f74
up
ernestognw de857b4
up
ernestognw 5729b5a
fix compilation
ernestognw 5099acb
do not transpile contracts/mocks/docs
Amxx cdd1f24
Merge branch 'master' into docs/account
Amxx f2f74f7
exclude accounts
ernestognw dc1927d
draft 7821
ernestognw 14c79f9
Update transpile.sh
Amxx d4c461a
Move 7913 examples to .adoc file
ernestognw 1180ed0
up
ernestognw fe88580
Merge branch 'master' into docs/account
Amxx 645102d
Update transpile.sh
Amxx fa79cb0
up
ernestognw 773d687
up
ernestognw 4f98c5a
Update contracts/mocks/docs/account/MyFactoryAccount.sol
Amxx 26d971a
Review suggestions
ernestognw e6fda11
Add userOpHash EIP-712 type explanation
ernestognw 07a2ca0
nits
ernestognw 9ce669f
Update factory
ernestognw 613307d
up
ernestognw 5b216ed
up
ernestognw 47a1504
review suggestions
ernestognw 1eeafd9
up
ernestognw 86c2fa9
up
Amxx File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // contracts/MyAccountERC7702.sol | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.20; | ||
|
|
||
| import {Account} from "../../../account/Account.sol"; | ||
| import {ERC721Holder} from "../../../token/ERC721/utils/ERC721Holder.sol"; | ||
| import {ERC1155Holder} from "../../../token/ERC1155/utils/ERC1155Holder.sol"; | ||
| import {ERC7821} from "../../../account/extensions/draft-ERC7821.sol"; | ||
| import {SignerERC7702} from "../../../utils/cryptography/signers/SignerERC7702.sol"; | ||
|
|
||
| contract MyAccountERC7702 is Account, SignerERC7702, ERC7821, ERC721Holder, ERC1155Holder { | ||
| /// @dev Allows the entry point as an authorized executor. | ||
| function _erc7821AuthorizedExecutor( | ||
| address caller, | ||
| bytes32 mode, | ||
| bytes calldata executionData | ||
| ) internal view virtual override returns (bool) { | ||
| return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| // contracts/MyFactoryAccount.sol | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| pragma solidity ^0.8.20; | ||
|
|
||
| import {Clones} from "../../../proxy/Clones.sol"; | ||
| import {Address} from "../../../utils/Address.sol"; | ||
|
|
||
| /** | ||
| * @dev A factory contract to create accounts on demand. | ||
| */ | ||
| contract MyFactoryAccount { | ||
| using Clones for address; | ||
| using Address for address; | ||
|
|
||
| address private immutable _impl; | ||
|
|
||
| constructor(address impl_) { | ||
| require(impl_.code.length > 0); | ||
| _impl = impl_; | ||
| } | ||
|
|
||
| /// @dev Predict the address of the account | ||
| function predictAddress(bytes32 salt, bytes calldata callData) public view returns (address, bytes32) { | ||
ernestognw marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| bytes32 calldataSalt = _saltedCallData(salt, callData); | ||
| return (_impl.predictDeterministicAddress(calldataSalt, address(this)), calldataSalt); | ||
| } | ||
|
|
||
| /// @dev Create clone accounts on demand | ||
| function cloneAndInitialize(bytes32 salt, bytes calldata callData) public returns (address) { | ||
| (address predicted, bytes32 _calldataSalt) = predictAddress(salt, callData); | ||
| if (predicted.code.length == 0) { | ||
| _impl.cloneDeterministic(_calldataSalt); | ||
| predicted.functionCall(callData); | ||
| } | ||
| return predicted; | ||
| } | ||
|
|
||
| function _saltedCallData(bytes32 salt, bytes calldata callData) internal pure returns (bytes32) { | ||
| // Scope salt to the callData to avoid front-running the salt with a different callData | ||
| return keccak256(abi.encodePacked(salt, callData)); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| = Account Abstraction | ||
|
|
||
| Unlike Externally Owned Accounts (EOAs), smart contracts may contain arbitrary verification logic based on authentication mechanisms different to Ethereum's native xref:api:utils.adoc#ECDSA[ECDSA] and have execution advantages such as batching or gas sponsorship. To leverage these properties of smart contracts, the community has widely adopted https://eips.ethereum.org/EIPS/eip-4337[ERC-4337], a standard to process user operations through an alternative mempool. | ||
|
|
||
| The library provides multiple contracts for Account Abstraction following this standard as it enables more flexible and user-friendly interactions with applications. Account Abstraction use cases include wallets in novel contexts (e.g. embedded wallets), more granular configuration of accounts, and recovery mechanisms. | ||
|
|
||
| == ERC-4337 Overview | ||
|
|
||
| The ERC-4337 is a detailed specification of how to implement the necessary logic to handle operations without making changes to the protocol level (i.e. the rules of the blockchain itself). This specification defines the following components: | ||
|
|
||
| === UserOperation | ||
|
|
||
| A `UserOperation` is a higher-layer pseudo-transaction object that represents the intent of the account. This shares some similarities with regular EVM transactions like the concept of `gasFees` or `callData` but includes fields that enable new capabilities. | ||
|
|
||
| ```solidity | ||
| struct PackedUserOperation { | ||
| address sender; | ||
| uint256 nonce; | ||
| bytes initCode; // concatenation of factory address and factoryData (or empty) | ||
| bytes callData; | ||
| bytes32 accountGasLimits; // concatenation of verificationGas (16 bytes) and callGas (16 bytes) | ||
| uint256 preVerificationGas; | ||
| bytes32 gasFees; // concatenation of maxPriorityFee (16 bytes) and maxFeePerGas (16 bytes) | ||
| bytes paymasterAndData; // concatenation of paymaster fields (or empty) | ||
| bytes signature; | ||
| } | ||
| ``` | ||
|
|
||
| This process of bundling user operations involves several costs that the bundler must cover, including base transaction fees, calldata serialization, entrypoint execution, and paymaster context costs. To compensate for these expenses, bundlers use the `preVerificationGas` and `gasFees` fields to charge users appropriately. | ||
|
|
||
| NOTE: Estimating `preVerificationGas` is not standardized as it varies based on network conditions such as gas prices and the size of the operation bundle. | ||
|
|
||
| TIP: Use xref:api:account.adoc#ERC4337Utils[`ERC4337Utils`] to manipulate the `UserOperation` struct and other ERC-4337 related values. | ||
|
|
||
| === Entrypoint | ||
|
|
||
| Each `UserOperation` is executed through a contract known as the https://etherscan.io/address/0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108#code[`EntryPoint`]. This contract is a singleton deployed across multiple networks at the same address although other custom implementations may be used. | ||
|
|
||
| The Entrypoint contracts is considered a trusted entity by the account. | ||
|
|
||
| === Bundlers | ||
|
|
||
| The bundler is a piece of _offchain_ infrastructure that is in charge of processing an alternative mempool of user operations. Bundlers themselves call the Entrypoint contract's `handleOps` function with an array of UserOperations that are executed and included in a block. | ||
|
|
||
| During the process, the bundler pays for the gas of executing the transaction and gets refunded during the execution phase of the Entrypoint contract. | ||
|
|
||
| ```solidity | ||
| /// @dev Process `userOps` and `beneficiary` receives all | ||
| /// the gas fees collected during the bundle execution. | ||
| function handleOps( | ||
| PackedUserOperation[] calldata ops, | ||
| address payable beneficiary | ||
| ) external { ... } | ||
| ``` | ||
|
|
||
| === Account Contract | ||
|
|
||
| The Account Contract is a smart contract that implements the logic required to validate a `UserOperation` in the context of ERC-4337. Any smart contract account should conform with the `IAccount` interface to validate operations. | ||
|
|
||
| ```solidity | ||
| interface IAccount { | ||
| function validateUserOp(PackedUserOperation calldata, bytes32, uint256) external returns (uint256 validationData); | ||
| } | ||
| ``` | ||
|
|
||
| Similarly, an Account should have a way to execute these operations by either handling arbitrary calldata on its `fallback` or implementing the `IAccountExecute` interface: | ||
|
|
||
| ```solidity | ||
| interface IAccountExecute { | ||
| function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external; | ||
| } | ||
| ``` | ||
|
|
||
| NOTE: The `IAccountExecute` interface is optional. Developers might want to use xref:api:account.adoc#ERC7821[`ERC-7821`] for a minimal batched execution interface or rely on ERC-7579 or any other execution logic. | ||
|
|
||
| To build your own account, see xref:accounts.adoc[accounts]. | ||
|
|
||
| === Factory Contract | ||
|
|
||
| The smart contract accounts are created by a Factory contract defined by the Account developer. This factory receives arbitrary bytes as `initData` and returns an `address` where the logic of the account is deployed. | ||
|
|
||
| To build your own factory, see xref:accounts.adoc#accounts_factory[account factories]. | ||
|
|
||
| === Paymaster Contract | ||
|
|
||
| A Paymaster is an optional entity that can sponsor gas fees for Accounts, or allow them to pay for those fees in ERC-20 instead of native currency. This abstracts gas away of the user experience in the same way that computational costs of cloud servers are abstracted away from end-users. | ||
|
|
||
| To build your own paymaster, see https://docs.openzeppelin.com/community-contracts/0.0.1/paymasters[paymasters]. | ||
|
|
||
| == Further notes | ||
|
|
||
| === ERC-7562 Validation Rules | ||
|
|
||
| To process a bundle of `UserOperations`, bundlers call xref:api:account.adoc#Account-validateUserOp-struct-PackedUserOperation-bytes32-uint256-[`validateUserOp`] on each operation sender to check whether the operation can be executed. However, the bundler has no guarantee that the state of the blockchain will remain the same after the validation phase. To overcome this problem, https://eips.ethereum.org/EIPS/eip-7562[ERC-7562] proposes a set of limitations to EVM code so that bundlers (or node operators) are protected from unexpected state changes. | ||
|
|
||
| These rules outline the requirements for operations to be processed by the canonical mempool. | ||
|
|
||
| Accounts can access its own storage during the validation phase, they might easily violate ERC-7562 storage access rules in undirect ways. For example, most accounts access their public keys from storage when validating a signature, limiting the ability of having accounts that validate operations for other accounts (e.g. via ERC-1271) | ||
|
|
||
| TIP: Although any Account that breaks such rules may still be processed by a private bundler, developers should keep in mind the centralization tradeoffs of relying on private infrastructure instead of _permissionless_ execution. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.