diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b2e1ce..c5d0257c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - `PaymasterERC20Guarantor`: Add extension of `PaymasterERC20` that enables third parties to guarantee user operations by prefunding gas costs upfront, with repayment handling for successful operations. - `ERC7579Validator`: Add abstract validator module for ERC-7579 accounts that provides base implementation for signature validation. -- `ERC7579SignatureValidator`: Add implementation of `ERC7579Validator` that enables ERC-7579 accounts to integrate with address-less cryptographic keys through ERC-7913 signature verification. +- `ERC7579Signature`: Add implementation of `ERC7579Validator` that enables ERC-7579 accounts to integrate with address-less cryptographic keys and account signatures through ERC-7913 signature verification. ## 29-04-2025 diff --git a/contracts/account/README.adoc b/contracts/account/README.adoc index f5b45bd3..122f794a 100644 --- a/contracts/account/README.adoc +++ b/contracts/account/README.adoc @@ -8,13 +8,13 @@ This directory includes contracts to build accounts for ERC-4337. These include: * {AccountERC7579}: An extension of `Account` that implements support for ERC-7579 modules. * {AccountERC7579Hooked}: An extension of `AccountERC7579` with support for a single hook module (type 4). * {ERC7821}: Minimal batch executor implementation contracts. Useful to enable easy batch execution for smart contracts. - * {ERC7579Validator}: Abstract validator module for ERC-7579 accounts that provides base implementation for signature validation. - * {ERC7579SignatureValidator}: Implementation of ERC7579Validator using ERC-7913 signature verification for address-less cryptographic keys. - * {ERC7579Multisig}: An abstract multisig module for ERC-7579 accounts using ERC-7913 signer keys. - * {ERC7579MultisigWeighted}: An abstract weighted multisig module that allows different weights to be assigned to signers. - * {ERC7579MultisigConfirmation}: An abstract confirmation-based multisig module that each signer to provide a confirmation signature. * {ERC7579Executor}: An executor module that enables executing calls from accounts where the it's installed. * {ERC7579DelayedExecutor}: An executor module that adds a delay before executing an account operation. + * {ERC7579Validator}: Abstract validator module for ERC-7579 accounts that provides base implementation for signature validation. + * {ERC7579Signature}: Implementation of {ERC7579Validator} using ERC-7913 signature verification for address-less cryptographic keys and account signatures. + * {ERC7579Multisig}: An extension of {ERC7579Validator} that enables validation using ERC-7913 signer keys. + * {ERC7579MultisigWeighted}: An extension of {ERC7579Multisig} that allows different weights to be assigned to signers. + * {ERC7579MultisigConfirmation}: An extension of {ERC7579Multisig} that requires each signer to provide a confirmation signature. * {PaymasterCore}: An ERC-4337 paymaster implementation that includes the core logic to validate and pay for user operations. * {PaymasterERC20}: A paymaster that allows users to pay for user operations using ERC-20 tokens. * {PaymasterERC20Guarantor}: A paymaster that enables third parties to guarantee user operations by pre-funding gas costs, with the option for users to repay or for guarantors to absorb the cost. @@ -35,12 +35,6 @@ This directory includes contracts to build accounts for ERC-4337. These include: == Modules -{{ERC7579Multisig}} - -{{ERC7579MultisigWeighted}} - -{{ERC7579MultisigConfirmation}} - === Executors {{ERC7579Executor}} @@ -51,7 +45,13 @@ This directory includes contracts to build accounts for ERC-4337. These include: {{ERC7579Validator}} -{{ERC7579SignatureValidator}} +{{ERC7579Signature}} + +{{ERC7579Multisig}} + +{{ERC7579MultisigWeighted}} + +{{ERC7579MultisigConfirmation}} == Paymaster diff --git a/contracts/account/modules/ERC7579Multisig.sol b/contracts/account/modules/ERC7579Multisig.sol index 971ba742..d4621cc3 100644 --- a/contracts/account/modules/ERC7579Multisig.sol +++ b/contracts/account/modules/ERC7579Multisig.sol @@ -3,40 +3,23 @@ pragma solidity ^0.8.27; import {ERC7913Utils} from "../../utils/cryptography/ERC7913Utils.sol"; import {EnumerableSetExtended} from "../../utils/structs/EnumerableSetExtended.sol"; -import {IERC7579Module} from "@openzeppelin/contracts/interfaces/draft-IERC7579.sol"; import {Mode} from "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol"; +import {ERC7579Validator} from "./ERC7579Validator.sol"; /** - * @dev Implementation of an {IERC7579Module} that uses ERC-7913 signers for multisignature + * @dev Implementation of an {ERC7579Validator} that uses ERC-7913 signers for multisignature * validation. * * This module provides a base implementation for multisignature validation that can be - * attached to any function through the {_validateMultisignature} internal function. The signers + * attached to any function through the {_rawERC7579Validation} internal function. The signers * are represented using the ERC-7913 format, which concatenates a verifier address and * a key: `verifier || key`. * - * Example implementation: - * - * ```solidity - * function execute( - * address account, - * Mode mode, - * bytes calldata executionCalldata, - * bytes32 salt, - * bytes calldata signature - * ) public virtual { - * require(_validateMultisignature(account, hash, signature)); - * // ... rest of execute logic - * } - * ``` - * - * Example use case: - * * A smart account with this module installed can require multiple signers to approve * operations before they are executed, such as requiring 3-of-5 guardians to approve * a social recovery operation. */ -abstract contract ERC7579Multisig is IERC7579Module { +abstract contract ERC7579Multisig is ERC7579Validator { using EnumerableSetExtended for EnumerableSetExtended.BytesSet; using ERC7913Utils for bytes32; using ERC7913Utils for bytes; @@ -178,11 +161,11 @@ abstract contract ERC7579Multisig is IERC7579Module { * Where `signingSigners` are the authorized signers and signatures are their corresponding * signatures of the operation `hash`. */ - function _validateMultisignature( + function _rawERC7579Validation( address account, bytes32 hash, bytes calldata signature - ) internal view virtual returns (bool) { + ) internal view virtual override returns (bool) { (bytes[] memory signingSigners, bytes[] memory signatures) = abi.decode(signature, (bytes[], bytes[])); return _validateThreshold(account, signingSigners) && diff --git a/contracts/account/modules/ERC7579SignatureValidator.sol b/contracts/account/modules/ERC7579Signature.sol similarity index 58% rename from contracts/account/modules/ERC7579SignatureValidator.sol rename to contracts/account/modules/ERC7579Signature.sol index ef1388c3..1f5dcdff 100644 --- a/contracts/account/modules/ERC7579SignatureValidator.sol +++ b/contracts/account/modules/ERC7579Signature.sol @@ -10,53 +10,22 @@ import {IERC7579Module} from "@openzeppelin/contracts/interfaces/draft-IERC7579. * @dev Implementation of {ERC7579Validator} module using ERC-7913 signature verification. * * This validator allows ERC-7579 accounts to integrate with address-less cryptographic keys - * through the ERC-7913 signature verification system. Each account can store its own ERC-7913 - * formatted signer (a concatenation of a verifier address and a key: `verifier || key`). + * and account signatures through the ERC-7913 signature verification system. Each account + * can store its own ERC-7913 formatted signer (a concatenation of a verifier address and a + * key: `verifier || key`). * * This enables accounts to use signature schemes without requiring each key to have its own - * Ethereum address. - * - * The validator implements two key functions from ERC-7579: - * - * * `validateUserOp`: Validates ERC-4337 user operations using ERC-7913 signatures - * * `isValidSignatureWithSender`: Implements ERC-1271 signature verification via ERC-7913 - * - * Example usage with an account: - * - * ```solidity - * contract MyAccount is Account, AccountERC7579 { - * function initialize(address validator, bytes memory signerData) public initializer { - * // Install the validator module - * bytes memory initData = abi.encode(signerData); - * _installModule(MODULE_TYPE_VALIDATOR, validator, initData); - * } - * } - * ``` - * - * Example of validator installation with a P256 key: - * - * ```solidity - * // Address of the P256 verifier contract - * address p256verifier = 0x123...; - * - * // P256 public key bytes - * bytes memory p256PublicKey = 0x456...; - * - * // Combine into ERC-7913 signer format - * bytes memory signerData = bytes.concat(abi.encodePacked(p256verifier), p256PublicKey); - * - * // Initialize the account with the validator and signer - * account.initialize(address(new ERC7579SignatureValidator()), signerData); - * ``` + * Ethereum address.A smart account with this module installed can keep an emergency key as a + * backup. */ -contract ERC7579SignatureValidator is ERC7579Validator { +contract ERC7579Signature is ERC7579Validator { mapping(address account => bytes signer) private _signers; /// @dev Emitted when the signer is set. - event ERC7579SignatureValidatorSignerSet(address indexed account, bytes signer); + event ERC7579SignatureSignerSet(address indexed account, bytes signer); /// @dev Thrown when the signer length is less than 20 bytes. - error ERC7579SignatureValidatorInvalidSignerLength(); + error ERC7579SignatureInvalidSignerLength(); /// @dev Return the ERC-7913 signer (i.e. `verifier || key`). function signer(address account) public view virtual returns (bytes memory) { @@ -88,18 +57,18 @@ contract ERC7579SignatureValidator is ERC7579Validator { /// @dev Sets the ERC-7913 signer (i.e. `verifier || key`) for the calling account. function setSigner(bytes memory signer_) public virtual { - require(signer_.length >= 20, ERC7579SignatureValidatorInvalidSignerLength()); + require(signer_.length >= 20, ERC7579SignatureInvalidSignerLength()); _setSigner(msg.sender, signer_); } /// @dev Internal version of {setSigner} that takes an `account` as argument without validating `signer_`. function _setSigner(address account, bytes memory signer_) internal virtual { _signers[account] = signer_; - emit ERC7579SignatureValidatorSignerSet(account, signer_); + emit ERC7579SignatureSignerSet(account, signer_); } /** - * @dev See {ERC7579Validator-_rawSignatureValidationWithSender}. + * @dev See {ERC7579Validator-_rawERC7579Validation}. * * Validates a `signature` using ERC-7913 verification. * @@ -107,11 +76,11 @@ contract ERC7579SignatureValidator is ERC7579Validator { * the account's stored signer. Derived contracts can override this to implement * custom validation logic based on the sender. */ - function _rawSignatureValidationWithSender( - address /* sender */, + function _rawERC7579Validation( + address account, bytes32 hash, bytes calldata signature ) internal view virtual override returns (bool) { - return ERC7913Utils.isValidSignatureNow(signer(msg.sender), hash, signature); + return ERC7913Utils.isValidSignatureNow(signer(account), hash, signature); } } diff --git a/contracts/account/modules/ERC7579Validator.sol b/contracts/account/modules/ERC7579Validator.sol index 2a542eba..fc35a0b5 100644 --- a/contracts/account/modules/ERC7579Validator.sol +++ b/contracts/account/modules/ERC7579Validator.sol @@ -6,11 +6,12 @@ import {IERC7579Module, IERC7579Validator, MODULE_TYPE_VALIDATOR} from "@openzep import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol"; import {ERC4337Utils} from "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol"; import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; + /** * @dev Abstract validator module for ERC-7579 accounts. * * This contract provides the base implementation for signature validation in ERC-7579 accounts. - * Developers must implement the onInstall, onUninstall, and {_rawSignatureValidationWithSender} + * Developers must implement the onInstall, onUninstall, and {_rawERC7579Validation} * functions in derived contracts to define the specific signature validation logic. * * Example usage: @@ -25,8 +26,8 @@ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; * // Uninstall logic here * } * - * function _rawSignatureValidationWithSender( - * address sender, + * function _rawERC7579Validation( + * address account, * bytes32 hash, * bytes calldata signature * ) internal view override returns (bool) { @@ -34,6 +35,22 @@ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol"; * } * } * ``` + * + * Developers can restrict other operations by using the internal {_rawERC7579Validation}. + * Example usage: + * + * ```solidity + * function execute( + * address account, + * Mode mode, + * bytes calldata executionCalldata, + * bytes32 salt, + * bytes calldata signature + * ) public virtual { + * require(_rawERC7579Validation(account, hash, signature)); + * // ... rest of execute logic + * } + * ``` */ abstract contract ERC7579Validator is IERC7579Module, IERC7579Validator { /// @inheritdoc IERC7579Module @@ -47,33 +64,37 @@ abstract contract ERC7579Validator is IERC7579Module, IERC7579Validator { bytes32 userOpHash ) public view virtual returns (uint256) { return - _rawSignatureValidationWithSender(msg.sender, userOpHash, userOp.signature) + _rawERC7579Validation(msg.sender, userOpHash, userOp.signature) ? ERC4337Utils.SIG_VALIDATION_SUCCESS : ERC4337Utils.SIG_VALIDATION_FAILED; } - /// @inheritdoc IERC7579Validator + /** + * @dev See {IERC7579Validator-isValidSignatureWithSender}. + * + * Ignores the `sender` parameter and validates using {_rawERC7579Validation}. + * Consider overriding this function to implement custom validation logic + * based on the original sender. + */ function isValidSignatureWithSender( - address sender, + address /* sender */, bytes32 hash, bytes calldata signature ) public view virtual returns (bytes4) { return - _rawSignatureValidationWithSender(sender, hash, signature) + _rawERC7579Validation(msg.sender, hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff); } /** - * @dev Internal version of {isValidSignatureWithSender} to be implemented by derived contracts. + * @dev Validation algorithm. * - * WARNING: Signature validation is a critical security function for smart accounts as it - * determines whether operations can be executed on the account. Implementations must carefully - * handle cryptographic verification to prevent unauthorized access. Thorough security review and - * testing are required before deployment. + * WARNING: Validation is a critical security function. Implementations must carefully + * handle cryptographic verification to prevent unauthorized access. */ - function _rawSignatureValidationWithSender( - address sender, + function _rawERC7579Validation( + address account, bytes32 hash, bytes calldata signature ) internal view virtual returns (bool); diff --git a/contracts/mocks/account/modules/ERC7579MultisigMocks.sol b/contracts/mocks/account/modules/ERC7579MultisigMocks.sol index 6f2b9a76..57ac0a32 100644 --- a/contracts/mocks/account/modules/ERC7579MultisigMocks.sol +++ b/contracts/mocks/account/modules/ERC7579MultisigMocks.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.27; import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; import {ERC7579Executor} from "../../../account/modules/ERC7579Executor.sol"; +import {ERC7579Validator} from "../../../account/modules/ERC7579Validator.sol"; import {ERC7579Multisig} from "../../../account/modules/ERC7579Multisig.sol"; import {ERC7579MultisigWeighted} from "../../../account/modules/ERC7579MultisigWeighted.sol"; import {ERC7579MultisigConfirmation} from "../../../account/modules/ERC7579MultisigConfirmation.sol"; @@ -14,6 +15,10 @@ abstract contract ERC7579MultisigExecutorMock is EIP712, ERC7579Executor, ERC757 bytes32 private constant EXECUTE_OPERATION = keccak256("ExecuteOperation(address account,bytes32 mode,bytes executionCalldata,bytes32 salt)"); + function isModuleType(uint256 moduleTypeId) public pure override(ERC7579Executor, ERC7579Validator) returns (bool) { + return ERC7579Executor.isModuleType(moduleTypeId) || ERC7579Executor.isModuleType(moduleTypeId); + } + // Data encoding: [uint16(executionCalldataLength), executionCalldata, signature] function _validateExecution( address account, @@ -24,7 +29,7 @@ abstract contract ERC7579MultisigExecutorMock is EIP712, ERC7579Executor, ERC757 uint16 executionCalldataLength = uint16(uint256(bytes32(data[0:2]))); // First 2 bytes are the length bytes calldata executionCalldata = data[2:2 + executionCalldataLength]; // Next bytes are the calldata bytes32 typeHash = _getExecuteTypeHash(account, salt, mode, executionCalldata); - require(_validateMultisignature(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature + require(_rawERC7579Validation(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature return executionCalldata; } @@ -42,6 +47,10 @@ abstract contract ERC7579MultisigWeightedExecutorMock is EIP712, ERC7579Executor bytes32 private constant EXECUTE_OPERATION = keccak256("ExecuteOperation(address account,bytes32 mode,bytes executionCalldata,bytes32 salt)"); + function isModuleType(uint256 moduleTypeId) public pure override(ERC7579Executor, ERC7579Validator) returns (bool) { + return ERC7579Executor.isModuleType(moduleTypeId) || ERC7579Executor.isModuleType(moduleTypeId); + } + // Data encoding: [uint16(executionCalldataLength), executionCalldata, signature] function _validateExecution( address account, @@ -52,7 +61,7 @@ abstract contract ERC7579MultisigWeightedExecutorMock is EIP712, ERC7579Executor uint16 executionCalldataLength = uint16(uint256(bytes32(data[0:2]))); // First 2 bytes are the length bytes calldata executionCalldata = data[2:2 + executionCalldataLength]; // Next bytes are the calldata bytes32 typeHash = _getExecuteTypeHash(account, salt, mode, executionCalldata); - require(_validateMultisignature(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature + require(_rawERC7579Validation(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature return executionCalldata; } @@ -70,6 +79,10 @@ abstract contract ERC7579MultisigConfirmationExecutorMock is ERC7579Executor, ER bytes32 private constant EXECUTE_OPERATION = keccak256("ExecuteOperation(address account,bytes32 mode,bytes executionCalldata,bytes32 salt)"); + function isModuleType(uint256 moduleTypeId) public pure override(ERC7579Executor, ERC7579Validator) returns (bool) { + return ERC7579Executor.isModuleType(moduleTypeId) || ERC7579Executor.isModuleType(moduleTypeId); + } + // Data encoding: [uint16(executionCalldataLength), executionCalldata, signature] function _validateExecution( address account, @@ -80,7 +93,7 @@ abstract contract ERC7579MultisigConfirmationExecutorMock is ERC7579Executor, ER uint16 executionCalldataLength = uint16(uint256(bytes32(data[0:2]))); // First 2 bytes are the length bytes calldata executionCalldata = data[2:2 + executionCalldataLength]; // Next bytes are the calldata bytes32 typeHash = _getExecuteTypeHash(account, salt, mode, executionCalldata); - require(_validateMultisignature(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature + require(_rawERC7579Validation(account, typeHash, data[2 + executionCalldataLength:])); // Remaining bytes are the signature return executionCalldata; } diff --git a/test/account/examples/AccountERC7702WithModulesMock.test.js b/test/account/examples/AccountERC7702WithModulesMock.test.js index 61c444b5..2474f694 100644 --- a/test/account/examples/AccountERC7702WithModulesMock.test.js +++ b/test/account/examples/AccountERC7702WithModulesMock.test.js @@ -23,7 +23,7 @@ async function fixture() { await setBalance(eoa.address, ethers.WeiPerEther); // ERC-7579 validator module - const validator = await ethers.deployContract('$ERC7579SignatureValidator'); + const validator = await ethers.deployContract('$ERC7579Signature'); // ERC-4337 account const helper = new ERC4337Helper(); diff --git a/test/account/extensions/AccountERC7579.test.js b/test/account/extensions/AccountERC7579.test.js index 00a1bc82..f50d5744 100644 --- a/test/account/extensions/AccountERC7579.test.js +++ b/test/account/extensions/AccountERC7579.test.js @@ -22,7 +22,7 @@ async function fixture() { const anotherTarget = await ethers.deployContract('CallReceiverMockExtended'); // ERC-7579 signature validator - const erc7579Validator = await ethers.deployContract('$ERC7579SignatureValidator'); + const erc7579Validator = await ethers.deployContract('$ERC7579Signature'); // ERC-7913 verifiers const verifierP256 = await ethers.deployContract('ERC7913P256Verifier'); diff --git a/test/account/extensions/AccountERC7579Hooked.test.js b/test/account/extensions/AccountERC7579Hooked.test.js index 35dffb4c..75a7ea2c 100644 --- a/test/account/extensions/AccountERC7579Hooked.test.js +++ b/test/account/extensions/AccountERC7579Hooked.test.js @@ -16,7 +16,7 @@ async function fixture() { const anotherTarget = await ethers.deployContract('CallReceiverMockExtended'); // ERC-7579 validator - const validator = await ethers.deployContract('$ERC7579SignatureValidator'); + const validator = await ethers.deployContract('$ERC7579Signature'); // ERC-4337 signer const signer = ethers.Wallet.createRandom(); diff --git a/test/account/modules/ERC7579Multisig.test.js b/test/account/modules/ERC7579Multisig.test.js index 177052b1..55f1f56b 100644 --- a/test/account/modules/ERC7579Multisig.test.js +++ b/test/account/modules/ERC7579Multisig.test.js @@ -217,7 +217,7 @@ describe('ERC7579Multisig', function () { const messageHash = ethers.hashMessage(testMessage); const multiSignature = await this.multiSigner.signMessage(testMessage); // Should succeed with valid signatures meeting threshold - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, multiSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, multiSignature)).to .eventually.be.true; }); @@ -234,7 +234,7 @@ describe('ERC7579Multisig', function () { const multiSignature = await multiSigner.signMessage(testMessage); // Should fail because threshold is 2 but only 1 signature provided - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, multiSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, multiSignature)).to .eventually.be.false; }); @@ -248,7 +248,7 @@ describe('ERC7579Multisig', function () { const multiSignature = await multiSigner.signMessage(testMessage); // Should succeed with valid signature meeting threshold - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, multiSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, multiSignature)).to .eventually.be.true; }); @@ -262,7 +262,7 @@ describe('ERC7579Multisig', function () { const multiSignature = await multiSigner.signMessage(testMessage); // Should fail because signer is not authorized - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, multiSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, multiSignature)).to .eventually.be.false; }); @@ -274,7 +274,7 @@ describe('ERC7579Multisig', function () { const multiSignature = await this.multiSigner.signMessage(differentMessage); // Should fail because signature is for a different hash - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, multiSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, multiSignature)).to .eventually.be.false; }); }); diff --git a/test/account/modules/ERC7579MultisigWeighted.test.js b/test/account/modules/ERC7579MultisigWeighted.test.js index 959e9bc0..e0666612 100644 --- a/test/account/modules/ERC7579MultisigWeighted.test.js +++ b/test/account/modules/ERC7579MultisigWeighted.test.js @@ -289,20 +289,20 @@ describe('ERC7579MultisigWeighted', function () { const exactSigner = new NonNativeSigner(new MultiERC7913SigningKey([signerECDSA1, signerECDSA2])); const exactSignature = await exactSigner.signMessage(testMessage); - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, exactSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, exactSignature)).to .eventually.be.true; // Also works with all signers (1+2+3=6 > threshold 3) const sufficientSignature = await this.multiSigner.signMessage(testMessage); - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, sufficientSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, sufficientSignature)).to .eventually.be.true; // Also try with just signerECDSA3 (weight 3) = 3, exactly meeting threshold const minimumSigner = new NonNativeSigner(new MultiERC7913SigningKey([signerECDSA3])); const minimumSignature = await minimumSigner.signMessage(testMessage); - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, minimumSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, minimumSignature)).to .eventually.be.true; }); @@ -317,7 +317,7 @@ describe('ERC7579MultisigWeighted', function () { const insufficientSignature = await insufficientSigner.signMessage(testMessage); // Should fail because total weight (1) < threshold (4) - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, insufficientSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, insufficientSignature)).to .eventually.be.false; }); @@ -333,14 +333,14 @@ describe('ERC7579MultisigWeighted', function () { const insufficientSignature = await insufficientSigner.signMessage(testMessage); // First verify this combination is insufficient - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, insufficientSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, insufficientSignature)).to .eventually.be.false; // Now increase the weight of signerECDSA2 to make it sufficient await this.mockFromAccount.setSignerWeights([this.signers[1]], [3]); // Now weight is 1+3=4 >= threshold 4 // Same signature should now pass - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, insufficientSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, insufficientSignature)).to .eventually.be.true; }); @@ -357,7 +357,7 @@ describe('ERC7579MultisigWeighted', function () { const invalidSignature = await invalidSigner.signMessage(differentMessage); // Should fail because signature is invalid for the hash - await expect(this.mock.$_validateMultisignature(this.mockAccount.address, messageHash, invalidSignature)).to + await expect(this.mock.$_rawERC7579Validation(this.mockAccount.address, messageHash, invalidSignature)).to .eventually.be.false; }); }); diff --git a/test/account/modules/ERC7579SignatureValidator.test.js b/test/account/modules/ERC7579SignatureValidator.test.js index 7ff3761d..680aab62 100644 --- a/test/account/modules/ERC7579SignatureValidator.test.js +++ b/test/account/modules/ERC7579SignatureValidator.test.js @@ -19,7 +19,7 @@ async function fixture() { const [other] = await ethers.getSigners(); // Deploy ERC-7579 signature validator - const mock = await ethers.deployContract('$ERC7579SignatureValidator'); + const mock = await ethers.deployContract('$ERC7579Signature'); // ERC-7913 verifiers const verifierP256 = await ethers.deployContract('ERC7913P256Verifier'); @@ -53,16 +53,16 @@ function prepareSigner(prototype) { .then(signature => Object.assign(userOp, { signature })); } -describe('ERC7579SignatureValidator', function () { +describe('ERC7579Signature', function () { beforeEach(async function () { Object.assign(this, await loadFixture(fixture)); }); - it('reverts with ERC7579SignatureValidatorInvalidSignerLength when signer length is less than 20 bytes', async function () { + it('reverts with ERC7579SignatureInvalidSignerLength when signer length is less than 20 bytes', async function () { const shortSigner = '0x0123456789'; // Less than 20 bytes await expect(this.mockFromAccount.onInstall(shortSigner)).to.be.revertedWithCustomError( this.mock, - 'ERC7579SignatureValidatorInvalidSignerLength', + 'ERC7579SignatureInvalidSignerLength', ); }); @@ -76,17 +76,17 @@ describe('ERC7579SignatureValidator', function () { await expect(this.mock.signer(this.mockAccount.address)).to.eventually.equal(signerData); // No change in signers }); - it('emits event on ERC7579SignatureValidatorSignerSet on both installation and uninstallation', async function () { + it('emits event on ERC7579SignatureSignerSet on both installation and uninstallation', async function () { const signerData = ethers.solidityPacked(['address'], [signerECDSA.address]); // First install await expect(this.mockFromAccount.onInstall(signerData)) - .to.emit(this.mock, 'ERC7579SignatureValidatorSignerSet') + .to.emit(this.mock, 'ERC7579SignatureSignerSet') .withArgs(this.mockAccount.address, signerData); // Then uninstall await expect(this.mockFromAccount.onUninstall('0x')) - .to.emit(this.mock, 'ERC7579SignatureValidatorSignerSet') + .to.emit(this.mock, 'ERC7579SignatureSignerSet') .withArgs(this.mockAccount.address, '0x'); }); @@ -103,7 +103,7 @@ describe('ERC7579SignatureValidator', function () { it('sets signer correctly with setSigner and emits event', async function () { const signerData = ethers.solidityPacked(['address'], [signerECDSA.address]); await expect(this.mockFromAccount.setSigner(signerData)) - .to.emit(this.mockFromAccount, 'ERC7579SignatureValidatorSignerSet') + .to.emit(this.mockFromAccount, 'ERC7579SignatureSignerSet') .withArgs(this.mockAccount.address, signerData); await expect(this.mock.signer(this.mockAccount.address)).to.eventually.equal(signerData); }); @@ -111,7 +111,7 @@ describe('ERC7579SignatureValidator', function () { it('reverts when calling setSigner with invalid signer length', async function () { await expect(this.mock.setSigner('0x0123456789')).to.be.revertedWithCustomError( this.mock, - 'ERC7579SignatureValidatorInvalidSignerLength', + 'ERC7579SignatureInvalidSignerLength', ); }); diff --git a/test/account/modules/ERC7579Validator.test.js b/test/account/modules/ERC7579Validator.test.js index b3ab86a6..3ff3bf9b 100644 --- a/test/account/modules/ERC7579Validator.test.js +++ b/test/account/modules/ERC7579Validator.test.js @@ -12,7 +12,7 @@ async function fixture() { const [other] = await ethers.getSigners(); // Deploy ERC-7579 validator module - const mock = await ethers.deployContract('$ERC7579SignatureValidator'); + const mock = await ethers.deployContract('$ERC7579Signature'); // ERC-4337 env const helper = new ERC4337Helper();