diff --git a/CHANGELOG.md b/CHANGELOG.md index b0677388..b0b2e1ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ +## 15-05-2025 + +- `ERC7579Multisig`: Add an abstract multisig module for ERC-7579 accounts using ERC-7913 signer keys. +- `ERC7579MultisigWeighted`: Add an abstract weighted multisig module that allows different weights to be assigned to signers. +- `ERC7579MultisigConfirmation`: Add an abstract confirmation-based multisig module that each signer to provide a confirmation signature. +- `ERC7579Executor`: Add an executor module that enables executing calls from accounts where the it's installed. +- `ERC7579DelayedExecutor`: Add executor module that adds a delay before executing an account operation. + ## 06-05-2025 -- `ERC7913SignatureVerifierZKEmail`: Add ERC-7913 signature verifier that enables email-based authentication through zero-knowledge proofs. +- `ERC7913ZKEmailVerifier`: Add ERC-7913 signature verifier that enables email-based authentication through zero-knowledge proofs. ## 05-05-2025 diff --git a/contracts/account/modules/ERC7579DelayedExecutor.sol b/contracts/account/modules/ERC7579DelayedExecutor.sol index 256ec1a3..49a2b4a9 100644 --- a/contracts/account/modules/ERC7579DelayedExecutor.sol +++ b/contracts/account/modules/ERC7579DelayedExecutor.sol @@ -257,10 +257,9 @@ abstract contract ERC7579DelayedExecutor is ERC7579Executor { * design choice for efficiency, but module implementations may want to override this behavior * to clear scheduled operations during uninstallation for their specific use cases. * - * WARNING: The account's delay will be removed if the account calls this function, allowing - * immediate scheduling of operations. As an account operator, make sure to uninstall to a - * predefined path in your account that properly handles the side effects of uninstallation. - * See {AccountERC7579-uninstallModule}. + * NOTE: Calling this function directly will remove the expiration ({getExpiration}) value and + * will schedule a reset of the delay ({getDelay}) to `0` for the account. Reinstalling the + * module will not immediately reset the delay if the delay reset hasn't taken effect yet. */ function onUninstall(bytes calldata) public virtual { _config[msg.sender].installed = false; diff --git a/contracts/account/modules/ERC7579SignatureValidator.sol b/contracts/account/modules/ERC7579SignatureValidator.sol index cc3e4599..ef1388c3 100644 --- a/contracts/account/modules/ERC7579SignatureValidator.sol +++ b/contracts/account/modules/ERC7579SignatureValidator.sol @@ -65,7 +65,6 @@ contract ERC7579SignatureValidator is ERC7579Validator { /** * @dev See {IERC7579Module-onInstall}. - * Reverts with {ERC7579SignatureValidatorAlreadyInstalled} if the module is already installed. * * NOTE: An account can only call onInstall once. If called directly by the account, * the signer will be set to the provided data. Future installations will behave as a no-op. diff --git a/contracts/account/paymaster/PaymasterERC20Guarantor.sol b/contracts/account/paymaster/PaymasterERC20Guarantor.sol index cb9d80bc..86d3b055 100644 --- a/contracts/account/paymaster/PaymasterERC20Guarantor.sol +++ b/contracts/account/paymaster/PaymasterERC20Guarantor.sol @@ -71,7 +71,7 @@ abstract contract PaymasterERC20Guarantor is PaymasterERC20 { * @dev Handles the refund process for guaranteed operations. * * If the operation was guaranteed, it attempts to get repayment from the user first and then refunds the guarantor. - * Otherwise, fallback to {PaymasterERC20-refund}. See {_refundGuaranteed}. + * Otherwise, fallback to {PaymasterERC20-_refund}. * * NOTE: For guaranteed user operations where the user paid the `actualGasCost` back, this function * doesn't call `super._refund`. Consider whether there are side effects in the parent contract that need to be executed. diff --git a/contracts/interfaces/IERC7821.sol b/contracts/interfaces/IERC7821.sol index 1607caa5..ad60bb83 100644 --- a/contracts/interfaces/IERC7821.sol +++ b/contracts/interfaces/IERC7821.sol @@ -11,18 +11,21 @@ interface IERC7821 { * Reverts and bubbles up error if any call fails. * * `executionData` encoding: - * - If `opData` is empty, `executionData` is simply `abi.encode(calls)`. - * - Else, `executionData` is `abi.encode(calls, opData)`. + * + * * If `opData` is empty, `executionData` is simply `abi.encode(calls)`. + * * Else, `executionData` is `abi.encode(calls, opData)`. * See: https://eips.ethereum.org/EIPS/eip-7579 * * Supported modes: - * - `bytes32(0x01000000000000000000...)`: does not support optional `opData`. - * - `bytes32(0x01000000000078210001...)`: supports optional `opData`. + * + * * `bytes32(0x01000000000000000000...)`: does not support optional `opData`. + * * `bytes32(0x01000000000078210001...)`: supports optional `opData`. * * Authorization checks: - * - If `opData` is empty, the implementation SHOULD require that + * + * * If `opData` is empty, the implementation SHOULD require that * `msg.sender == address(this)`. - * - If `opData` is not empty, the implementation SHOULD use the signature + * * If `opData` is not empty, the implementation SHOULD use the signature * encoded in `opData` to determine if the caller can perform the execution. * * `opData` may be used to store additional data for authentication, @@ -33,8 +36,9 @@ interface IERC7821 { /** * @dev This function is provided for frontends to detect support. * Only returns true for: - * - `bytes32(0x01000000000000000000...)`: does not support optional `opData`. - * - `bytes32(0x01000000000078210001...)`: supports optional `opData`. + * + * * `bytes32(0x01000000000000000000...)`: does not support optional `opData`. + * * `bytes32(0x01000000000078210001...)`: supports optional `opData`. */ function supportsExecutionMode(bytes32 mode) external view returns (bool); } diff --git a/contracts/interfaces/README.adoc b/contracts/interfaces/README.adoc new file mode 100644 index 00000000..894fc8f9 --- /dev/null +++ b/contracts/interfaces/README.adoc @@ -0,0 +1,25 @@ += Interfaces + +[.readme-notice] +NOTE: This document is better viewed at https://docs.openzeppelin.com/contracts/api/interfaces + +== List of standardized interfaces + +These interfaces are available as `.sol` files. These are useful to interact with third party contracts that implement them. + +- {IERC7786GatewaySource}, {IERC7786Receiver} +- {IERC7802} +- {IERC7821} +- {IERC7913SignatureVerifier} + +== Detailed ABI + +{{IERC7786GatewaySource}} + +{{IERC7786Receiver}} + +{{IERC7802}} + +{{IERC7821}} + +{{IERC7913SignatureVerifier}} diff --git a/contracts/utils/README.adoc b/contracts/utils/README.adoc index 09637b85..7af27baf 100644 --- a/contracts/utils/README.adoc +++ b/contracts/utils/README.adoc @@ -12,7 +12,7 @@ Miscellaneous contracts and libraries containing utility functions you can use t * {SignerECDSA}, {SignerP256}, {SignerRSA}: Implementations of an {AbstractSigner} with specific signature validation algorithms. * {SignerERC7702}: Implementation of {AbstractSigner} that validates signatures using the contract's own address as the signer, useful for delegated accounts following EIP-7702. * {SignerERC7913}, {MultiSignerERC7913}, {MultiSignerERC7913Weighted}: Implementations of {AbstractSigner} that validate signatures based on ERC-7913. Including a simple and weighted multisignature scheme. - * {ERC7913SignatureVerifierP256}, {ERC7913SignatureVerifierRSA}, {ERC7913SignatureVerifierZKEmail}: Ready to use ERC-7913 signature verifiers for P256, RSA keys, and ZKEmail. + * {ERC7913P256Verifier}, {ERC7913RSAVerifier}, {ERC7913ZKEmailVerifier}: Ready to use ERC-7913 signature verifiers for P256, RSA keys, and ZKEmail. * {SignerZKEmail}: Implementation of an {AbstractSigner} that enables email-based authentication through zero-knowledge proofs. * {ZKEmailUtils}: Library for ZKEmail signature validation utilities, enabling email-based authentication through zero-knowledge proofs. * {EnumerableSetExtended} and {EnumerableMapExtended}: Extensions of the `EnumerableSet` and `EnumerableMap` libraries with more types, including non-value types. @@ -54,7 +54,7 @@ Miscellaneous contracts and libraries containing utility functions you can use t {{ERC7913RSAVerifier}} -{{ERC7913SignatureVerifierZKEmail}} +{{ERC7913ZKEmailVerifier}} == Structs diff --git a/docs/modules/ROOT/pages/account-abstraction.adoc b/docs/modules/ROOT/pages/account-abstraction.adoc index 47289250..a9a7f572 100644 --- a/docs/modules/ROOT/pages/account-abstraction.adoc +++ b/docs/modules/ROOT/pages/account-abstraction.adoc @@ -1,6 +1,6 @@ = 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. +Unlike Externally Owned Accounts (EOAs), smart contracts may contain arbitrary verification logic based on authentication mechanisms different to Ethereum's native https://docs.openzeppelin.com/contracts/5.x/api/utils#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. @@ -71,7 +71,7 @@ interface IAccountExecute { } ``` -NOTE: The `IAccountExecute` interface is optional. Developers might want to use xref:api:account.adoc#AccountERC7821[`AccountERC7821`] for a minimal batched execution interface or rely on ERC-7579, ERC-6909 or any other execution logic. +NOTE: The `IAccountExecute` interface is optional. Developers might want to use xref:api:account.adoc#ERC7821[`ERC7821`] for a minimal batched execution interface or rely on ERC-7579, ERC-6909 or any other execution logic. To build your own account, see xref:accounts.adoc[accounts]. @@ -85,7 +85,7 @@ To build your own factory, see xref:accounts.adoc#accounts_factory[account facto 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 xref:paymaster.adoc#paymaster[paymasters]. +To build your own paymaster, see xref:paymasters.adoc#paymaster[paymasters]. == Further notes diff --git a/test/account/modules/ERC7579SignatureValidator.test.js b/test/account/modules/ERC7579SignatureValidator.test.js index 6fd328ef..7ff3761d 100644 --- a/test/account/modules/ERC7579SignatureValidator.test.js +++ b/test/account/modules/ERC7579SignatureValidator.test.js @@ -66,7 +66,7 @@ describe('ERC7579SignatureValidator', function () { ); }); - it('reverts with ERC7579SignatureValidatorAlreadyInstalled when the validator is already installed for an account', async function () { + it('behaves as a noop when the validator is already installed for an account', async function () { // First installation should succeed const signerData = ethers.solidityPacked(['address'], [signerECDSA.address]); await expect(this.mockFromAccount.onInstall(signerData)).to.not.be.reverted;