From 4835d1244166b85f18e78623d6f324c3fc1ca955 Mon Sep 17 00:00:00 2001 From: Fangting Liu Date: Tue, 16 Jul 2024 10:49:55 -0700 Subject: [PATCH 1/2] delete SingleOwnerPlugin --- README.md | 2 +- src/plugins/owner/SingleOwnerPlugin.sol | 191 ------------------- test/account/AccountLoupe.t.sol | 4 +- test/account/AccountReturnData.t.sol | 6 +- test/account/GlobalValidationTest.t.sol | 6 +- test/account/MultiValidation.t.sol | 26 +-- test/account/PerHookData.t.sol | 43 +++-- test/account/SelfCallAuthorization.t.sol | 2 +- test/account/UpgradeableModularAccount.t.sol | 32 ++-- test/mocks/MSCAFactoryFixture.sol | 81 -------- test/mocks/SingleSignerFactoryFixture.sol | 2 +- test/plugin/SingleOwnerPlugin.t.sol | 186 ------------------ test/plugin/TokenReceiverPlugin.t.sol | 5 +- test/samples/AllowlistPlugin.t.sol | 4 +- test/utils/AccountTestBase.sol | 32 ++-- test/utils/OptimizedTest.sol | 7 - test/utils/TestConstants.sol | 3 +- test/validation/SingleSignerValidation.t.sol | 16 +- 18 files changed, 91 insertions(+), 557 deletions(-) delete mode 100644 src/plugins/owner/SingleOwnerPlugin.sol delete mode 100644 test/mocks/MSCAFactoryFixture.sol delete mode 100644 test/plugin/SingleOwnerPlugin.t.sol diff --git a/README.md b/README.md index fb3e9dbc..1c90c710 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Reference implementation for [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900). It is an early draft implementation. -The implementation includes an upgradable modular account with two plugins (`SingleOwnerPlugin` and `TokenReceiverPlugin`). It is compliant with ERC-6900 with the latest updates. +The implementation includes an upgradable modular account with two plugins (`SingleSignerValidation` and `TokenReceiverPlugin`). It is compliant with ERC-6900 with the latest updates. ## Important Callouts diff --git a/src/plugins/owner/SingleOwnerPlugin.sol b/src/plugins/owner/SingleOwnerPlugin.sol deleted file mode 100644 index 5cfa6592..00000000 --- a/src/plugins/owner/SingleOwnerPlugin.sol +++ /dev/null @@ -1,191 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.25; - -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; -import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; -import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; - -import {PluginManifest, PluginMetadata, SelectorPermission} from "../../interfaces/IPlugin.sol"; -import {IPlugin} from "../../interfaces/IPlugin.sol"; -import {IValidation} from "../../interfaces/IValidation.sol"; -import {BasePlugin, IERC165} from "../BasePlugin.sol"; - -/// @title Single Owner Plugin -/// @author ERC-6900 Authors -/// @notice This plugin allows an EOA or smart contract to own a modular account. -/// It also supports [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signature -/// validation for both validating the signature on user operations and in -/// exposing its own `isValidSignature` method. This only works when the owner of -/// modular account also support ERC-1271. -/// -/// ERC-4337's bundler validation rules limit the types of contracts that can be -/// used as owners to validate user operation signatures. For example, the -/// contract's `isValidSignature` function may not use any forbidden opcodes -/// such as `TIMESTAMP` or `NUMBER`, and the contract may not be an ERC-1967 -/// proxy as it accesses a constant implementation slot not associated with -/// the account, violating storage access rules. This also means that the -/// owner of a modular account may not be another modular account if you want to -/// send user operations through a bundler. -contract SingleOwnerPlugin is IValidation, BasePlugin { - using ECDSA for bytes32; - using MessageHashUtils for bytes32; - - string internal constant _NAME = "Single Owner Plugin"; - string internal constant _VERSION = "1.0.0"; - string internal constant _AUTHOR = "ERC-6900 Authors"; - - uint256 internal constant _SIG_VALIDATION_PASSED = 0; - uint256 internal constant _SIG_VALIDATION_FAILED = 1; - - // bytes4(keccak256("isValidSignature(bytes32,bytes)")) - bytes4 internal constant _1271_MAGIC_VALUE = 0x1626ba7e; - bytes4 internal constant _1271_INVALID = 0xffffffff; - - mapping(uint32 id => mapping(address account => address)) public owners; - - /// @notice This event is emitted when ownership of the account changes. - /// @param account The account whose ownership changed. - /// @param previousOwner The address of the previous owner. - /// @param newOwner The address of the new owner. - event OwnershipTransferred(address indexed account, address indexed previousOwner, address indexed newOwner); - - error AlreadyInitialized(); - error NotAuthorized(); - error NotInitialized(); - - // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - // ┃ Execution functions ┃ - // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - /// @notice Transfer ownership of an account and ID to `newOwner`. The caller address (`msg.sender`) is user to - /// identify the account. - /// @param newOwner The address of the new owner. - function transferOwnership(uint32 id, address newOwner) external { - _transferOwnership(id, newOwner); - } - - // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - // ┃ Plugin interface functions ┃ - // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - /// @inheritdoc IPlugin - function onInstall(bytes calldata data) external override { - (uint32 id, address owner) = abi.decode(data, (uint32, address)); - _transferOwnership(id, owner); - } - - /// @inheritdoc IPlugin - function onUninstall(bytes calldata data) external override { - uint32 id = abi.decode(data, (uint32)); - _transferOwnership(id, address(0)); - } - - /// @inheritdoc IValidation - function validateRuntime( - address account, - uint32 entityId, - address sender, - uint256, - bytes calldata, - bytes calldata - ) external view override { - // Validate that the sender is the owner of the account or self. - if (sender != owners[entityId][account]) { - revert NotAuthorized(); - } - return; - } - - /// @inheritdoc IValidation - function validateUserOp(uint32 entityId, PackedUserOperation calldata userOp, bytes32 userOpHash) - external - view - override - returns (uint256) - { - // Validate the user op signature against the owner. - if ( - SignatureChecker.isValidSignatureNow( - owners[entityId][msg.sender], userOpHash.toEthSignedMessageHash(), userOp.signature - ) - ) { - return _SIG_VALIDATION_PASSED; - } - return _SIG_VALIDATION_FAILED; - } - - // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - // ┃ Execution view functions ┃ - // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - /// @inheritdoc IValidation - /// @dev The signature is valid if it is signed by the owner's private key - /// (if the owner is an EOA) or if it is a valid ERC-1271 signature from the - /// owner (if the owner is a contract). Note that unlike the signature - /// validation used in `validateUserOp`, this does///*not** wrap the digest in - /// an "Ethereum Signed Message" envelope before checking the signature in - /// the EOA-owner case. - function validateSignature(address account, uint32 entityId, address, bytes32 digest, bytes calldata signature) - external - view - override - returns (bytes4) - { - if (SignatureChecker.isValidSignatureNow(owners[entityId][account], digest, signature)) { - return _1271_MAGIC_VALUE; - } - return _1271_INVALID; - } - - // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - // ┃ Plugin view functions ┃ - // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - /// @inheritdoc IPlugin - function pluginManifest() external pure override returns (PluginManifest memory) { - PluginManifest memory manifest; - return manifest; - } - - /// @inheritdoc IPlugin - function pluginMetadata() external pure virtual override returns (PluginMetadata memory) { - PluginMetadata memory metadata; - metadata.name = _NAME; - metadata.version = _VERSION; - metadata.author = _AUTHOR; - - // Permission strings - string memory modifyOwnershipPermission = "Modify Ownership"; - - // Permission descriptions - metadata.permissionDescriptors = new SelectorPermission[](1); - metadata.permissionDescriptors[0] = SelectorPermission({ - functionSelector: this.transferOwnership.selector, - permissionDescription: modifyOwnershipPermission - }); - - return metadata; - } - - // ┏━━━━━━━━━━━━━━━┓ - // ┃ EIP-165 ┃ - // ┗━━━━━━━━━━━━━━━┛ - - /// @inheritdoc BasePlugin - function supportsInterface(bytes4 interfaceId) public view override(BasePlugin, IERC165) returns (bool) { - return interfaceId == type(IValidation).interfaceId || super.supportsInterface(interfaceId); - } - - // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - // ┃ Internal / Private functions ┃ - // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - // Transfers ownership and emits and event. - function _transferOwnership(uint32 id, address newOwner) internal { - address previousOwner = owners[id][msg.sender]; - owners[id][msg.sender] = newOwner; - // Todo: include id in event - emit OwnershipTransferred(msg.sender, previousOwner, newOwner); - } -} diff --git a/test/account/AccountLoupe.t.sol b/test/account/AccountLoupe.t.sol index b65bf3c9..f0670848 100644 --- a/test/account/AccountLoupe.t.sol +++ b/test/account/AccountLoupe.t.sol @@ -115,7 +115,7 @@ contract AccountLoupeTest is CustomValidationTestBase { } function test_pluginLoupe_getValidationHooks() public { - PluginEntity[] memory hooks = account1.getPreValidationHooks(_ownerValidation); + PluginEntity[] memory hooks = account1.getPreValidationHooks(_signerValidation); assertEq(hooks.length, 2); assertEq( @@ -154,7 +154,7 @@ contract AccountLoupeTest is CustomValidationTestBase { bytes[] memory installDatas = new bytes[](2); return ( - _ownerValidation, + _signerValidation, true, true, new bytes4[](0), diff --git a/test/account/AccountReturnData.t.sol b/test/account/AccountReturnData.t.sol index eaf8b8a7..2c3e66fd 100644 --- a/test/account/AccountReturnData.t.sol +++ b/test/account/AccountReturnData.t.sol @@ -10,7 +10,7 @@ import { ResultConsumerPlugin } from "../mocks/plugins/ReturnDataPluginMocks.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; // Tests all the different ways that return data can be read from plugins through an account contract AccountReturnDataTest is AccountTestBase { @@ -58,7 +58,7 @@ contract AccountReturnDataTest is AccountTestBase { (address(regularResultContract), 0, abi.encodeCall(RegularResultContract.foo, ())) ), _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) @@ -86,7 +86,7 @@ contract AccountReturnDataTest is AccountTestBase { bytes memory retData = account1.executeWithAuthorization( abi.encodeCall(account1.executeBatch, (calls)), _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) diff --git a/test/account/GlobalValidationTest.t.sol b/test/account/GlobalValidationTest.t.sol index 433116bc..04d3c230 100644 --- a/test/account/GlobalValidationTest.t.sol +++ b/test/account/GlobalValidationTest.t.sol @@ -26,7 +26,7 @@ contract GlobalValidationTest is AccountTestBase { account2 = UpgradeableModularAccount(payable(factory.getAddress(owner2, 0))); vm.deal(address(account2), 100 ether); - _ownerValidation = PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID); + _signerValidation = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); ethRecipient = makeAddr("ethRecipient"); vm.deal(ethRecipient, 1 wei); @@ -48,7 +48,7 @@ contract GlobalValidationTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner2Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -65,7 +65,7 @@ contract GlobalValidationTest is AccountTestBase { vm.prank(owner2); account2.executeWithAuthorization( abi.encodeCall(UpgradeableModularAccount.execute, (ethRecipient, 1 wei, "")), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, "") ); assertEq(ethRecipient.balance, 2 wei); diff --git a/test/account/MultiValidation.t.sol b/test/account/MultiValidation.t.sol index 2dbae711..8e10e915 100644 --- a/test/account/MultiValidation.t.sol +++ b/test/account/MultiValidation.t.sol @@ -12,22 +12,22 @@ import {PluginEntity} from "../../src/interfaces/IPluginManager.sol"; import {IStandardExecutor} from "../../src/interfaces/IStandardExecutor.sol"; import {PluginEntityLib} from "../../src/helpers/PluginEntityLib.sol"; import {ValidationConfigLib} from "../../src/helpers/ValidationConfigLib.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; +import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerValidation.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; contract MultiValidationTest is AccountTestBase { using ECDSA for bytes32; using MessageHashUtils for bytes32; - SingleOwnerPlugin public validator2; + SingleSignerValidation public validator2; address public owner2; uint256 public owner2Key; function setUp() public { - validator2 = new SingleOwnerPlugin(); + validator2 = new SingleSignerValidation(); (owner2, owner2Key) = makeAddrAndKey("owner2"); } @@ -35,16 +35,16 @@ contract MultiValidationTest is AccountTestBase { function test_overlappingValidationInstall() public { vm.prank(address(entryPoint)); account1.installValidation( - ValidationConfigLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID, true, true), + ValidationConfigLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID, true, true), new bytes4[](0), - abi.encode(TEST_DEFAULT_OWNER_FUNCTION_ID, owner2), + abi.encode(TEST_DEFAULT_VALIDATION_ID, owner2), "", "" ); PluginEntity[] memory validations = new PluginEntity[](2); - validations[0] = PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID); - validations[1] = PluginEntityLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID); + validations[0] = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); + validations[1] = PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID); bytes4[] memory selectors0 = account1.getSelectors(validations[0]); bytes4[] memory selectors1 = account1.getSelectors(validations[1]); @@ -64,14 +64,14 @@ contract MultiValidationTest is AccountTestBase { abi.encodeWithSelector( UpgradeableModularAccount.RuntimeValidationFunctionReverted.selector, address(validator2), - 0, + 1, abi.encodeWithSignature("NotAuthorized()") ) ); account1.executeWithAuthorization( abi.encodeCall(IStandardExecutor.execute, (address(0), 0, "")), _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID), GLOBAL_VALIDATION, "" + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) ); @@ -79,7 +79,7 @@ contract MultiValidationTest is AccountTestBase { account1.executeWithAuthorization( abi.encodeCall(IStandardExecutor.execute, (address(0), 0, "")), _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID), GLOBAL_VALIDATION, "" + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) ); } @@ -105,7 +105,7 @@ contract MultiValidationTest is AccountTestBase { bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner2Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); @@ -120,7 +120,7 @@ contract MultiValidationTest is AccountTestBase { userOp.nonce = 1; (v, r, s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); diff --git a/test/account/PerHookData.t.sol b/test/account/PerHookData.t.sol index 546a156c..b8e10eac 100644 --- a/test/account/PerHookData.t.sol +++ b/test/account/PerHookData.t.sol @@ -37,8 +37,9 @@ contract PerHookDataTest is CustomValidationTestBase { PreValidationHookData[] memory preValidationHookData = new PreValidationHookData[](1); preValidationHookData[0] = PreValidationHookData({index: 0, validationData: abi.encodePacked(_counter)}); - userOp.signature = - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature( + _signerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v) + ); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -59,8 +60,9 @@ contract PerHookDataTest is CustomValidationTestBase { validationData: abi.encodePacked(address(0x1234123412341234123412341234123412341234)) }); - userOp.signature = - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature( + _signerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v) + ); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -80,7 +82,7 @@ contract PerHookDataTest is CustomValidationTestBase { (PackedUserOperation memory userOp, bytes32 userOpHash) = _getCounterUserOP(); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -104,8 +106,9 @@ contract PerHookDataTest is CustomValidationTestBase { preValidationHookData[0] = PreValidationHookData({index: 0, validationData: abi.encodePacked(_counter)}); preValidationHookData[1] = PreValidationHookData({index: 1, validationData: abi.encodePacked(_counter)}); - userOp.signature = - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature( + _signerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v) + ); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -142,8 +145,9 @@ contract PerHookDataTest is CustomValidationTestBase { PreValidationHookData[] memory preValidationHookData = new PreValidationHookData[](1); preValidationHookData[0] = PreValidationHookData({index: 0, validationData: abi.encodePacked(beneficiary)}); - userOp.signature = - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature( + _signerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v) + ); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -166,8 +170,9 @@ contract PerHookDataTest is CustomValidationTestBase { PreValidationHookData[] memory preValidationHookData = new PreValidationHookData[](1); preValidationHookData[0] = PreValidationHookData({index: 0, validationData: ""}); - userOp.signature = - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature( + _signerValidation, GLOBAL_VALIDATION, preValidationHookData, abi.encodePacked(r, s, v) + ); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -195,7 +200,7 @@ contract PerHookDataTest is CustomValidationTestBase { UpgradeableModularAccount.execute, (address(_counter), 0 wei, abi.encodeCall(Counter.increment, ())) ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, preValidationHookData, "") ); assertEq(_counter.number(), 1); @@ -222,7 +227,7 @@ contract PerHookDataTest is CustomValidationTestBase { UpgradeableModularAccount.execute, (address(_counter), 0 wei, abi.encodeCall(Counter.increment, ())) ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, preValidationHookData, "") ); } @@ -241,7 +246,7 @@ contract PerHookDataTest is CustomValidationTestBase { UpgradeableModularAccount.execute, (address(_counter), 0 wei, abi.encodeCall(Counter.increment, ())) ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, "") ); } @@ -259,7 +264,7 @@ contract PerHookDataTest is CustomValidationTestBase { UpgradeableModularAccount.execute, (address(_counter), 0 wei, abi.encodeCall(Counter.increment, ())) ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, preValidationHookData, "") ); } @@ -280,7 +285,7 @@ contract PerHookDataTest is CustomValidationTestBase { ); account1.executeWithAuthorization( abi.encodeCall(UpgradeableModularAccount.execute, (beneficiary, 1 wei, "")), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, preValidationHookData, "") ); } @@ -295,7 +300,7 @@ contract PerHookDataTest is CustomValidationTestBase { UpgradeableModularAccount.execute, (address(_counter), 0 wei, abi.encodeCall(Counter.increment, ())) ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, preValidationHookData, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, preValidationHookData, "") ); } @@ -341,11 +346,11 @@ contract PerHookDataTest is CustomValidationTestBase { bytes memory packedPreValidationHooks = abi.encode(preValidationHooks, preValidationHookData); return ( - _ownerValidation, + _signerValidation, true, true, new bytes4[](0), - abi.encode(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1), + abi.encode(TEST_DEFAULT_VALIDATION_ID, owner1), packedPreValidationHooks, "" ); diff --git a/test/account/SelfCallAuthorization.t.sol b/test/account/SelfCallAuthorization.t.sol index 516f9f34..c490eea4 100644 --- a/test/account/SelfCallAuthorization.t.sol +++ b/test/account/SelfCallAuthorization.t.sol @@ -303,7 +303,7 @@ contract SelfCallAuthorizationTest is AccountTestBase { UpgradeableModularAccount.installValidation, (ValidationConfigLib.pack(comprehensivePluginValidation, false, false), selectors, "", "", "") ), - _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, "") + _encodeSignature(_signerValidation, GLOBAL_VALIDATION, "") ); } diff --git a/test/account/UpgradeableModularAccount.t.sol b/test/account/UpgradeableModularAccount.t.sol index dda78c66..075d7f64 100644 --- a/test/account/UpgradeableModularAccount.t.sol +++ b/test/account/UpgradeableModularAccount.t.sol @@ -14,14 +14,14 @@ import {PluginManifest} from "../../src/interfaces/IPlugin.sol"; import {IAccountLoupe} from "../../src/interfaces/IAccountLoupe.sol"; import {IPluginManager} from "../../src/interfaces/IPluginManager.sol"; import {Call} from "../../src/interfaces/IStandardExecutor.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; +import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerValidation.sol"; import {TokenReceiverPlugin} from "../../src/plugins/TokenReceiverPlugin.sol"; import {Counter} from "../mocks/Counter.sol"; import {ComprehensivePlugin} from "../mocks/plugins/ComprehensivePlugin.sol"; import {MockPlugin} from "../mocks/MockPlugin.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; contract UpgradeableModularAccountTest is AccountTestBase { using ECDSA for bytes32; @@ -77,7 +77,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -95,9 +95,9 @@ contract UpgradeableModularAccountTest is AccountTestBase { callData: abi.encodeCall( UpgradeableModularAccount.execute, ( - address(singleOwnerPlugin), + address(singleSignerValidation), 0, - abi.encodeCall(SingleOwnerPlugin.transferOwnership, (TEST_DEFAULT_OWNER_FUNCTION_ID, owner2)) + abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, owner2)) ) ), accountGasLimits: _encodeGas(VERIFICATION_GAS_LIMIT, CALL_GAS_LIMIT), @@ -110,7 +110,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner2Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -136,7 +136,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner2Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -162,7 +162,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -190,7 +190,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -221,7 +221,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // Generate signature bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); - userOp.signature = _encodeSignature(_ownerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); + userOp.signature = _encodeSignature(_signerValidation, GLOBAL_VALIDATION, abi.encodePacked(r, s, v)); PackedUserOperation[] memory userOps = new PackedUserOperation[](1); userOps[0] = userOp; @@ -409,16 +409,16 @@ contract UpgradeableModularAccountTest is AccountTestBase { } function test_transferOwnership() public { - assertEq(singleOwnerPlugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, address(account1)), owner1); + assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, address(account1)), owner1); vm.prank(address(entryPoint)); account1.execute( - address(singleOwnerPlugin), + address(singleSignerValidation), 0, - abi.encodeCall(SingleOwnerPlugin.transferOwnership, (TEST_DEFAULT_OWNER_FUNCTION_ID, owner2)) + abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, owner2)) ); - assertEq(singleOwnerPlugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, address(account1)), owner2); + assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, address(account1)), owner2); } function test_isValidSignature() public { @@ -426,10 +426,10 @@ contract UpgradeableModularAccountTest is AccountTestBase { (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, message); - // singleOwnerPlugin.ownerOf(address(account1)); + // singleSignerValidation.ownerOf(address(account1)); bytes memory signature = - abi.encodePacked(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID, r, s, v); + abi.encodePacked(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID, r, s, v); bytes4 validationResult = IERC1271(address(account1)).isValidSignature(message, signature); diff --git a/test/mocks/MSCAFactoryFixture.sol b/test/mocks/MSCAFactoryFixture.sol deleted file mode 100644 index 8ca3a51f..00000000 --- a/test/mocks/MSCAFactoryFixture.sol +++ /dev/null @@ -1,81 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; -import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol"; -import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol"; - -import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; -import {ValidationConfigLib} from "../../src/helpers/ValidationConfigLib.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; - -import {OptimizedTest} from "../utils/OptimizedTest.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID} from "../utils/TestConstants.sol"; - -/** - * @title MSCAFactoryFixture - * @dev a factory that initializes UpgradeableModularAccounts with a single plugin, SingleOwnerPlugin - * intended for unit tests and local development, not for production. - */ -contract MSCAFactoryFixture is OptimizedTest { - UpgradeableModularAccount public accountImplementation; - SingleOwnerPlugin public singleOwnerPlugin; - bytes32 private immutable _PROXY_BYTECODE_HASH; - - uint32 public constant UNSTAKE_DELAY = 1 weeks; - - IEntryPoint public entryPoint; - - constructor(IEntryPoint _entryPoint, SingleOwnerPlugin _singleOwnerPlugin) { - entryPoint = _entryPoint; - accountImplementation = _deployUpgradeableModularAccount(_entryPoint); - _PROXY_BYTECODE_HASH = keccak256( - abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(address(accountImplementation), "")) - ); - singleOwnerPlugin = _singleOwnerPlugin; - } - - /** - * create an account, and return its address. - * returns the address even if the account is already deployed. - * Note that during user operation execution, this method is called only if the account is not deployed. - * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after - * account creation - */ - function createAccount(address owner, uint256 salt) public returns (UpgradeableModularAccount) { - address addr = Create2.computeAddress(getSalt(owner, salt), _PROXY_BYTECODE_HASH); - - // short circuit if exists - if (addr.code.length == 0) { - bytes memory pluginInstallData = abi.encode(TEST_DEFAULT_OWNER_FUNCTION_ID, owner); - // not necessary to check return addr since next call will fail if so - new ERC1967Proxy{salt: getSalt(owner, salt)}(address(accountImplementation), ""); - - // point proxy to actual implementation and init plugins - UpgradeableModularAccount(payable(addr)).initializeWithValidation( - ValidationConfigLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID, true, true), - new bytes4[](0), - pluginInstallData, - "", - "" - ); - } - - return UpgradeableModularAccount(payable(addr)); - } - - /** - * calculate the counterfactual address of this account as it would be returned by createAccount() - */ - function getAddress(address owner, uint256 salt) public view returns (address) { - return Create2.computeAddress(getSalt(owner, salt), _PROXY_BYTECODE_HASH); - } - - function addStake() external payable { - entryPoint.addStake{value: msg.value}(UNSTAKE_DELAY); - } - - function getSalt(address owner, uint256 salt) public pure returns (bytes32) { - return keccak256(abi.encodePacked(owner, salt)); - } -} diff --git a/test/mocks/SingleSignerFactoryFixture.sol b/test/mocks/SingleSignerFactoryFixture.sol index c3f663e3..225892d8 100644 --- a/test/mocks/SingleSignerFactoryFixture.sol +++ b/test/mocks/SingleSignerFactoryFixture.sol @@ -51,7 +51,7 @@ contract SingleSignerFactoryFixture is OptimizedTest { // point proxy to actual implementation and init plugins UpgradeableModularAccount(payable(addr)).initializeWithValidation( - ValidationConfigLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID, true, false), + ValidationConfigLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID, true, true), new bytes4[](0), pluginInstallData, "", diff --git a/test/plugin/SingleOwnerPlugin.t.sol b/test/plugin/SingleOwnerPlugin.t.sol deleted file mode 100644 index 6d57e5b7..00000000 --- a/test/plugin/SingleOwnerPlugin.t.sol +++ /dev/null @@ -1,186 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; -import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; - -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; - -import {ContractOwner} from "../mocks/ContractOwner.sol"; -import {OptimizedTest} from "../utils/OptimizedTest.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID} from "../utils/TestConstants.sol"; - -contract SingleOwnerPluginTest is OptimizedTest { - using ECDSA for bytes32; - using MessageHashUtils for bytes32; - - SingleOwnerPlugin public plugin; - EntryPoint public entryPoint; - - bytes4 internal constant _1271_MAGIC_VALUE = 0x1626ba7e; - address public a; - address public b; - - address public owner1; - address public owner2; - ContractOwner public contractOwner; - - // Event declarations (needed for vm.expectEmit) - event OwnershipTransferred(address indexed account, address indexed previousOwner, address indexed newOwner); - - function setUp() public { - plugin = _deploySingleOwnerPlugin(); - entryPoint = new EntryPoint(); - - a = makeAddr("a"); - b = makeAddr("b"); - owner1 = makeAddr("owner1"); - owner2 = makeAddr("owner2"); - contractOwner = new ContractOwner(); - } - - // Tests: - // - uninitialized owner is zero address - // - transferOwnership result is returned via owner afterwards - // - transferOwnership emits OwnershipTransferred event - // - owner() returns correct value after transferOwnership - // - owner() does not return a different account's owner - // - requireFromOwner succeeds when called by owner - // - requireFromOwner reverts when called by non-owner - - function test_uninitializedOwner() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - } - - function test_ownerInitialization() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - } - - function test_ownerInitializationEvent() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(a, address(0), owner1); - - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - } - - function test_ownerMigration() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner2); - assertEq(owner2, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - } - - function test_ownerMigrationEvents() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(a, address(0), owner1); - - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - - vm.expectEmit(true, true, true, true); - emit OwnershipTransferred(a, owner1, owner2); - - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner2); - assertEq(owner2, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - } - - function test_ownerForSender() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - vm.startPrank(b); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, b)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner2); - assertEq(owner2, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, b)); - } - - function test_requireOwner() public { - vm.startPrank(a); - assertEq(address(0), plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1); - assertEq(owner1, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - plugin.validateRuntime(a, TEST_DEFAULT_OWNER_FUNCTION_ID, owner1, 0, "", ""); - - vm.startPrank(b); - vm.expectRevert(SingleOwnerPlugin.NotAuthorized.selector); - plugin.validateRuntime(b, TEST_DEFAULT_OWNER_FUNCTION_ID, owner1, 0, "", ""); - } - - function testFuzz_validateUserOpSig(string memory salt, PackedUserOperation memory userOp) public { - // range bound the possible set of priv keys - (address signer, uint256 privateKey) = makeAddrAndKey(salt); - - vm.startPrank(a); - bytes32 userOpHash = entryPoint.getUserOpHash(userOp); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, userOpHash.toEthSignedMessageHash()); - - // sig cannot cover the whole userop struct since userop struct has sig field - userOp.signature = abi.encodePacked(r, s, v); - - // sig check should fail - uint256 success = plugin.validateUserOp(TEST_DEFAULT_OWNER_FUNCTION_ID, userOp, userOpHash); - assertEq(success, 1); - - // transfer ownership to signer - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, signer); - assertEq(signer, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - - // sig check should pass - success = plugin.validateUserOp(TEST_DEFAULT_OWNER_FUNCTION_ID, userOp, userOpHash); - assertEq(success, 0); - } - - function testFuzz_isValidSignatureForEOAOwner(string memory salt, bytes32 digest) public { - // range bound the possible set of priv keys - (address signer, uint256 privateKey) = makeAddrAndKey(salt); - - vm.startPrank(a); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest); - - // sig check should fail - assertEq( - plugin.validateSignature( - a, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, abi.encodePacked(r, s, v) - ), - bytes4(0xFFFFFFFF) - ); - - // transfer ownership to signer - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, signer); - assertEq(signer, plugin.owners(TEST_DEFAULT_OWNER_FUNCTION_ID, a)); - - // sig check should pass - assertEq( - plugin.validateSignature( - a, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, abi.encodePacked(r, s, v) - ), - _1271_MAGIC_VALUE - ); - } - - function testFuzz_isValidSignatureForContractOwner(bytes32 digest) public { - vm.startPrank(a); - plugin.transferOwnership(TEST_DEFAULT_OWNER_FUNCTION_ID, address(contractOwner)); - bytes memory signature = contractOwner.sign(digest); - assertEq( - plugin.validateSignature(a, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, signature), - _1271_MAGIC_VALUE - ); - } -} diff --git a/test/plugin/TokenReceiverPlugin.t.sol b/test/plugin/TokenReceiverPlugin.t.sol index 2f52a988..1e198f0b 100644 --- a/test/plugin/TokenReceiverPlugin.t.sol +++ b/test/plugin/TokenReceiverPlugin.t.sol @@ -8,7 +8,7 @@ import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Re import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {TokenReceiverPlugin} from "../../src/plugins/TokenReceiverPlugin.sol"; -import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; +import {SingleSignerFactoryFixture} from "../mocks/SingleSignerFactoryFixture.sol"; import {MockERC721} from "../mocks/MockERC721.sol"; import {MockERC1155} from "../mocks/MockERC1155.sol"; import {OptimizedTest} from "../utils/OptimizedTest.sol"; @@ -33,7 +33,8 @@ contract TokenReceiverPluginTest is OptimizedTest, IERC1155Receiver { function setUp() public { entryPoint = new EntryPoint(); - MSCAFactoryFixture factory = new MSCAFactoryFixture(entryPoint, _deploySingleOwnerPlugin()); + SingleSignerFactoryFixture factory = + new SingleSignerFactoryFixture(entryPoint, _deploySingleSignerValidation()); acct = factory.createAccount(address(this), 0); plugin = _deployTokenReceiverPlugin(); diff --git a/test/samples/AllowlistPlugin.t.sol b/test/samples/AllowlistPlugin.t.sol index 4a8fc4ff..ba14ff0b 100644 --- a/test/samples/AllowlistPlugin.t.sol +++ b/test/samples/AllowlistPlugin.t.sol @@ -305,11 +305,11 @@ contract AllowlistPluginTest is CustomValidationTestBase { bytes memory packedPreValidationHooks = abi.encode(preValidationHooks, preValidationHookData); return ( - _ownerValidation, + _signerValidation, true, true, new bytes4[](0), - abi.encode(TEST_DEFAULT_OWNER_FUNCTION_ID, owner1), + abi.encode(TEST_DEFAULT_VALIDATION_ID, owner1), packedPreValidationHooks, "" ); diff --git a/test/utils/AccountTestBase.sol b/test/utils/AccountTestBase.sol index a23f0151..e34c8752 100644 --- a/test/utils/AccountTestBase.sol +++ b/test/utils/AccountTestBase.sol @@ -9,39 +9,35 @@ import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerV import {PluginEntity, PluginEntityLib} from "../../src/helpers/PluginEntityLib.sol"; import {IStandardExecutor, Call} from "../../src/interfaces/IStandardExecutor.sol"; import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {OptimizedTest} from "./OptimizedTest.sol"; -import {TEST_DEFAULT_OWNER_FUNCTION_ID as EXT_CONST_TEST_DEFAULT_OWNER_FUNCTION_ID} from "./TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ID as EXT_CONST_TEST_DEFAULT_VALIDATION_ID} from "./TestConstants.sol"; import {SingleSignerFactoryFixture} from "../mocks/SingleSignerFactoryFixture.sol"; -import {MSCAFactoryFixture} from "../mocks/MSCAFactoryFixture.sol"; /// @dev This contract handles common boilerplate setup for tests using UpgradeableModularAccount with -/// SingleOwnerPlugin. +/// SingleSignerValidation. abstract contract AccountTestBase is OptimizedTest { using PluginEntityLib for PluginEntity; using MessageHashUtils for bytes32; EntryPoint public entryPoint; address payable public beneficiary; - SingleOwnerPlugin public singleOwnerPlugin; - MSCAFactoryFixture public factory; SingleSignerValidation public singleSignerValidation; - SingleSignerFactoryFixture public singleSignerFactory; + SingleSignerFactoryFixture public factory; address public owner1; uint256 public owner1Key; UpgradeableModularAccount public account1; - PluginEntity internal _ownerValidation; + PluginEntity internal _signerValidation; uint8 public constant SELECTOR_ASSOCIATED_VALIDATION = 0; uint8 public constant GLOBAL_VALIDATION = 1; // Re-declare the constant to prevent derived test contracts from having to import it - uint32 public constant TEST_DEFAULT_OWNER_FUNCTION_ID = EXT_CONST_TEST_DEFAULT_OWNER_FUNCTION_ID; + uint32 public constant TEST_DEFAULT_VALIDATION_ID = EXT_CONST_TEST_DEFAULT_VALIDATION_ID; uint256 public constant CALL_GAS_LIMIT = 100000; uint256 public constant VERIFICATION_GAS_LIMIT = 1200000; @@ -56,15 +52,13 @@ abstract contract AccountTestBase is OptimizedTest { (owner1, owner1Key) = makeAddrAndKey("owner1"); beneficiary = payable(makeAddr("beneficiary")); - singleOwnerPlugin = _deploySingleOwnerPlugin(); - factory = new MSCAFactoryFixture(entryPoint, singleOwnerPlugin); singleSignerValidation = _deploySingleSignerValidation(); - singleSignerFactory = new SingleSignerFactoryFixture(entryPoint, singleSignerValidation); + factory = new SingleSignerFactoryFixture(entryPoint, singleSignerValidation); account1 = factory.createAccount(owner1, 0); vm.deal(address(account1), 100 ether); - _ownerValidation = PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID); + _signerValidation = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); } function _runExecUserOp(address target, bytes memory callData) internal { @@ -107,7 +101,7 @@ abstract contract AccountTestBase is OptimizedTest { (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); @@ -160,7 +154,7 @@ abstract contract AccountTestBase is OptimizedTest { account1.executeWithAuthorization( callData, _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) @@ -175,7 +169,7 @@ abstract contract AccountTestBase is OptimizedTest { account1.executeWithAuthorization( callData, _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) @@ -189,15 +183,15 @@ abstract contract AccountTestBase is OptimizedTest { abi.encodeCall( account1.execute, ( - address(singleOwnerPlugin), + address(singleSignerValidation), 0, abi.encodeCall( - SingleOwnerPlugin.transferOwnership, (TEST_DEFAULT_OWNER_FUNCTION_ID, address(this)) + SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, address(this)) ) ) ), _encodeSignature( - PluginEntityLib.pack(address(singleOwnerPlugin), TEST_DEFAULT_OWNER_FUNCTION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" ) diff --git a/test/utils/OptimizedTest.sol b/test/utils/OptimizedTest.sol index f5e66dfc..d884193f 100644 --- a/test/utils/OptimizedTest.sol +++ b/test/utils/OptimizedTest.sol @@ -6,7 +6,6 @@ import {Test} from "forge-std/Test.sol"; import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol"; import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; -import {SingleOwnerPlugin} from "../../src/plugins/owner/SingleOwnerPlugin.sol"; import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerValidation.sol"; import {TokenReceiverPlugin} from "../../src/plugins/TokenReceiverPlugin.sol"; @@ -45,12 +44,6 @@ abstract contract OptimizedTest is Test { : new UpgradeableModularAccount(entryPoint); } - function _deploySingleOwnerPlugin() internal returns (SingleOwnerPlugin) { - return _isOptimizedTest() - ? SingleOwnerPlugin(deployCode("out-optimized/SingleOwnerPlugin.sol/SingleOwnerPlugin.json")) - : new SingleOwnerPlugin(); - } - function _deployTokenReceiverPlugin() internal returns (TokenReceiverPlugin) { return _isOptimizedTest() ? TokenReceiverPlugin(deployCode("out-optimized/TokenReceiverPlugin.sol/TokenReceiverPlugin.json")) diff --git a/test/utils/TestConstants.sol b/test/utils/TestConstants.sol index 1bd467ad..c15b2dd3 100644 --- a/test/utils/TestConstants.sol +++ b/test/utils/TestConstants.sol @@ -1,5 +1,4 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; -uint32 constant TEST_DEFAULT_OWNER_FUNCTION_ID = 0; -uint32 constant TEST_DEFAULT_VALIDATION_ID = 1; +uint32 constant TEST_DEFAULT_VALIDATION_ENTITY_ID = 1; diff --git a/test/validation/SingleSignerValidation.t.sol b/test/validation/SingleSignerValidation.t.sol index af2b1c6e..d6152b36 100644 --- a/test/validation/SingleSignerValidation.t.sol +++ b/test/validation/SingleSignerValidation.t.sol @@ -27,7 +27,7 @@ contract SingleSignerValidationTest is AccountTestBase { function setUp() public { ethRecipient = makeAddr("ethRecipient"); (owner2, owner2Key) = makeAddrAndKey("owner2"); - account = singleSignerFactory.createAccount(owner1, 0); + account = factory.createAccount(owner1, 0); vm.deal(address(account), 100 ether); contractOwner = new ContractOwner(); @@ -77,7 +77,7 @@ contract SingleSignerValidationTest is AccountTestBase { } function test_runtime_with2SameValidationInstalled() public { - uint32 newEntityId = TEST_DEFAULT_OWNER_FUNCTION_ID + 1; + uint32 newEntityId = TEST_DEFAULT_VALIDATION_ENTITY_ID + 1; vm.prank(address(entryPoint)); account.installValidation( ValidationConfigLib.pack(address(singleSignerValidation), newEntityId, true, false), @@ -109,19 +109,19 @@ contract SingleSignerValidationTest is AccountTestBase { // sig check should fail assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, abi.encodePacked(r, s, v) + accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, abi.encodePacked(r, s, v) ), bytes4(0xFFFFFFFF) ); // transfer ownership to signer - singleSignerValidation.transferSigner(TEST_DEFAULT_OWNER_FUNCTION_ID, signer); - assertEq(signer, singleSignerValidation.signerOf(TEST_DEFAULT_OWNER_FUNCTION_ID, accountAddr)); + singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ID, signer); + assertEq(signer, singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, accountAddr)); // sig check should pass assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, abi.encodePacked(r, s, v) + accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, abi.encodePacked(r, s, v) ), _1271_MAGIC_VALUE ); @@ -130,11 +130,11 @@ contract SingleSignerValidationTest is AccountTestBase { function testFuzz_isValidSignatureForContractOwner(bytes32 digest) public { address accountAddr = address(account); vm.startPrank(accountAddr); - singleSignerValidation.transferSigner(TEST_DEFAULT_OWNER_FUNCTION_ID, address(contractOwner)); + singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ID, address(contractOwner)); bytes memory signature = contractOwner.sign(digest); assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_OWNER_FUNCTION_ID, address(this), digest, signature + accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, signature ), _1271_MAGIC_VALUE ); From 42529a6eae968758061bbd4024082c734b089c1b Mon Sep 17 00:00:00 2001 From: Fangting Liu Date: Tue, 16 Jul 2024 17:20:26 -0700 Subject: [PATCH 2/2] update test constant name --- test/account/AccountReturnData.t.sol | 6 +++--- test/account/GlobalValidationTest.t.sol | 3 ++- test/account/MultiValidation.t.sol | 18 +++++++++--------- test/account/PerHookData.t.sol | 2 +- test/account/UpgradeableModularAccount.t.sol | 12 ++++++------ test/mocks/SingleSignerFactoryFixture.sol | 8 +++++--- test/samples/AllowlistPlugin.t.sol | 2 +- test/utils/AccountTestBase.sol | 18 ++++++++++-------- test/validation/SingleSignerValidation.t.sol | 18 +++++++++--------- 9 files changed, 46 insertions(+), 41 deletions(-) diff --git a/test/account/AccountReturnData.t.sol b/test/account/AccountReturnData.t.sol index 2c3e66fd..bb081325 100644 --- a/test/account/AccountReturnData.t.sol +++ b/test/account/AccountReturnData.t.sol @@ -10,7 +10,7 @@ import { ResultConsumerPlugin } from "../mocks/plugins/ReturnDataPluginMocks.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol"; // Tests all the different ways that return data can be read from plugins through an account contract AccountReturnDataTest is AccountTestBase { @@ -58,7 +58,7 @@ contract AccountReturnDataTest is AccountTestBase { (address(regularResultContract), 0, abi.encodeCall(RegularResultContract.foo, ())) ), _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) @@ -86,7 +86,7 @@ contract AccountReturnDataTest is AccountTestBase { bytes memory retData = account1.executeWithAuthorization( abi.encodeCall(account1.executeBatch, (calls)), _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) diff --git a/test/account/GlobalValidationTest.t.sol b/test/account/GlobalValidationTest.t.sol index 04d3c230..7ef7fdc5 100644 --- a/test/account/GlobalValidationTest.t.sol +++ b/test/account/GlobalValidationTest.t.sol @@ -26,7 +26,8 @@ contract GlobalValidationTest is AccountTestBase { account2 = UpgradeableModularAccount(payable(factory.getAddress(owner2, 0))); vm.deal(address(account2), 100 ether); - _signerValidation = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); + _signerValidation = + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID); ethRecipient = makeAddr("ethRecipient"); vm.deal(ethRecipient, 1 wei); diff --git a/test/account/MultiValidation.t.sol b/test/account/MultiValidation.t.sol index 8e10e915..641fcefb 100644 --- a/test/account/MultiValidation.t.sol +++ b/test/account/MultiValidation.t.sol @@ -15,7 +15,7 @@ import {ValidationConfigLib} from "../../src/helpers/ValidationConfigLib.sol"; import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerValidation.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol"; contract MultiValidationTest is AccountTestBase { using ECDSA for bytes32; @@ -35,16 +35,16 @@ contract MultiValidationTest is AccountTestBase { function test_overlappingValidationInstall() public { vm.prank(address(entryPoint)); account1.installValidation( - ValidationConfigLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID, true, true), + ValidationConfigLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID, true, true), new bytes4[](0), - abi.encode(TEST_DEFAULT_VALIDATION_ID, owner2), + abi.encode(TEST_DEFAULT_VALIDATION_ENTITY_ID, owner2), "", "" ); PluginEntity[] memory validations = new PluginEntity[](2); - validations[0] = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); - validations[1] = PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID); + validations[0] = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID); + validations[1] = PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID); bytes4[] memory selectors0 = account1.getSelectors(validations[0]); bytes4[] memory selectors1 = account1.getSelectors(validations[1]); @@ -71,7 +71,7 @@ contract MultiValidationTest is AccountTestBase { account1.executeWithAuthorization( abi.encodeCall(IStandardExecutor.execute, (address(0), 0, "")), _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) ); @@ -79,7 +79,7 @@ contract MultiValidationTest is AccountTestBase { account1.executeWithAuthorization( abi.encodeCall(IStandardExecutor.execute, (address(0), 0, "")), _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), GLOBAL_VALIDATION, "" + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) ); } @@ -105,7 +105,7 @@ contract MultiValidationTest is AccountTestBase { bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner2Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); @@ -120,7 +120,7 @@ contract MultiValidationTest is AccountTestBase { userOp.nonce = 1; (v, r, s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(validator2), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); diff --git a/test/account/PerHookData.t.sol b/test/account/PerHookData.t.sol index b8e10eac..bcb53171 100644 --- a/test/account/PerHookData.t.sol +++ b/test/account/PerHookData.t.sol @@ -350,7 +350,7 @@ contract PerHookDataTest is CustomValidationTestBase { true, true, new bytes4[](0), - abi.encode(TEST_DEFAULT_VALIDATION_ID, owner1), + abi.encode(TEST_DEFAULT_VALIDATION_ENTITY_ID, owner1), packedPreValidationHooks, "" ); diff --git a/test/account/UpgradeableModularAccount.t.sol b/test/account/UpgradeableModularAccount.t.sol index 075d7f64..54af25c6 100644 --- a/test/account/UpgradeableModularAccount.t.sol +++ b/test/account/UpgradeableModularAccount.t.sol @@ -21,7 +21,7 @@ import {Counter} from "../mocks/Counter.sol"; import {ComprehensivePlugin} from "../mocks/plugins/ComprehensivePlugin.sol"; import {MockPlugin} from "../mocks/MockPlugin.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol"; contract UpgradeableModularAccountTest is AccountTestBase { using ECDSA for bytes32; @@ -97,7 +97,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { ( address(singleSignerValidation), 0, - abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, owner2)) + abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ENTITY_ID, owner2)) ) ), accountGasLimits: _encodeGas(VERIFICATION_GAS_LIMIT, CALL_GAS_LIMIT), @@ -409,16 +409,16 @@ contract UpgradeableModularAccountTest is AccountTestBase { } function test_transferOwnership() public { - assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, address(account1)), owner1); + assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ENTITY_ID, address(account1)), owner1); vm.prank(address(entryPoint)); account1.execute( address(singleSignerValidation), 0, - abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, owner2)) + abi.encodeCall(SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ENTITY_ID, owner2)) ); - assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, address(account1)), owner2); + assertEq(singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ENTITY_ID, address(account1)), owner2); } function test_isValidSignature() public { @@ -429,7 +429,7 @@ contract UpgradeableModularAccountTest is AccountTestBase { // singleSignerValidation.ownerOf(address(account1)); bytes memory signature = - abi.encodePacked(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID, r, s, v); + abi.encodePacked(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID, r, s, v); bytes4 validationResult = IERC1271(address(account1)).isValidSignature(message, signature); diff --git a/test/mocks/SingleSignerFactoryFixture.sol b/test/mocks/SingleSignerFactoryFixture.sol index 225892d8..b3da73ec 100644 --- a/test/mocks/SingleSignerFactoryFixture.sol +++ b/test/mocks/SingleSignerFactoryFixture.sol @@ -10,7 +10,7 @@ import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAcc import {SingleSignerValidation} from "../../src/plugins/validation/SingleSignerValidation.sol"; import {OptimizedTest} from "../utils/OptimizedTest.sol"; -import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol"; contract SingleSignerFactoryFixture is OptimizedTest { UpgradeableModularAccount public accountImplementation; @@ -45,13 +45,15 @@ contract SingleSignerFactoryFixture is OptimizedTest { // short circuit if exists if (addr.code.length == 0) { - bytes memory pluginInstallData = abi.encode(TEST_DEFAULT_VALIDATION_ID, owner); + bytes memory pluginInstallData = abi.encode(TEST_DEFAULT_VALIDATION_ENTITY_ID, owner); // not necessary to check return addr since next call will fail if so new ERC1967Proxy{salt: getSalt(owner, salt)}(address(accountImplementation), ""); // point proxy to actual implementation and init plugins UpgradeableModularAccount(payable(addr)).initializeWithValidation( - ValidationConfigLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID, true, true), + ValidationConfigLib.pack( + address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID, true, true + ), new bytes4[](0), pluginInstallData, "", diff --git a/test/samples/AllowlistPlugin.t.sol b/test/samples/AllowlistPlugin.t.sol index ba14ff0b..441fbdcb 100644 --- a/test/samples/AllowlistPlugin.t.sol +++ b/test/samples/AllowlistPlugin.t.sol @@ -309,7 +309,7 @@ contract AllowlistPluginTest is CustomValidationTestBase { true, true, new bytes4[](0), - abi.encode(TEST_DEFAULT_VALIDATION_ID, owner1), + abi.encode(TEST_DEFAULT_VALIDATION_ENTITY_ID, owner1), packedPreValidationHooks, "" ); diff --git a/test/utils/AccountTestBase.sol b/test/utils/AccountTestBase.sol index e34c8752..526365d0 100644 --- a/test/utils/AccountTestBase.sol +++ b/test/utils/AccountTestBase.sol @@ -11,7 +11,8 @@ import {IStandardExecutor, Call} from "../../src/interfaces/IStandardExecutor.so import {UpgradeableModularAccount} from "../../src/account/UpgradeableModularAccount.sol"; import {OptimizedTest} from "./OptimizedTest.sol"; -import {TEST_DEFAULT_VALIDATION_ID as EXT_CONST_TEST_DEFAULT_VALIDATION_ID} from "./TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID as EXT_CONST_TEST_DEFAULT_VALIDATION_ENTITY_ID} from + "./TestConstants.sol"; import {SingleSignerFactoryFixture} from "../mocks/SingleSignerFactoryFixture.sol"; @@ -37,7 +38,7 @@ abstract contract AccountTestBase is OptimizedTest { uint8 public constant GLOBAL_VALIDATION = 1; // Re-declare the constant to prevent derived test contracts from having to import it - uint32 public constant TEST_DEFAULT_VALIDATION_ID = EXT_CONST_TEST_DEFAULT_VALIDATION_ID; + uint32 public constant TEST_DEFAULT_VALIDATION_ENTITY_ID = EXT_CONST_TEST_DEFAULT_VALIDATION_ENTITY_ID; uint256 public constant CALL_GAS_LIMIT = 100000; uint256 public constant VERIFICATION_GAS_LIMIT = 1200000; @@ -58,7 +59,8 @@ abstract contract AccountTestBase is OptimizedTest { account1 = factory.createAccount(owner1, 0); vm.deal(address(account1), 100 ether); - _signerValidation = PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID); + _signerValidation = + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID); } function _runExecUserOp(address target, bytes memory callData) internal { @@ -101,7 +103,7 @@ abstract contract AccountTestBase is OptimizedTest { (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); @@ -154,7 +156,7 @@ abstract contract AccountTestBase is OptimizedTest { account1.executeWithAuthorization( callData, _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) @@ -169,7 +171,7 @@ abstract contract AccountTestBase is OptimizedTest { account1.executeWithAuthorization( callData, _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) @@ -186,12 +188,12 @@ abstract contract AccountTestBase is OptimizedTest { address(singleSignerValidation), 0, abi.encodeCall( - SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ID, address(this)) + SingleSignerValidation.transferSigner, (TEST_DEFAULT_VALIDATION_ENTITY_ID, address(this)) ) ) ), _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) diff --git a/test/validation/SingleSignerValidation.t.sol b/test/validation/SingleSignerValidation.t.sol index d6152b36..a983ea93 100644 --- a/test/validation/SingleSignerValidation.t.sol +++ b/test/validation/SingleSignerValidation.t.sol @@ -9,7 +9,7 @@ import {PluginEntityLib} from "../../src/helpers/PluginEntityLib.sol"; import {ValidationConfigLib} from "../../src/helpers/ValidationConfigLib.sol"; import {AccountTestBase} from "../utils/AccountTestBase.sol"; -import {TEST_DEFAULT_VALIDATION_ID} from "../utils/TestConstants.sol"; +import {TEST_DEFAULT_VALIDATION_ENTITY_ID} from "../utils/TestConstants.sol"; import {ContractOwner} from "../mocks/ContractOwner.sol"; contract SingleSignerValidationTest is AccountTestBase { @@ -50,7 +50,7 @@ contract SingleSignerValidationTest is AccountTestBase { bytes32 userOpHash = entryPoint.getUserOpHash(userOp); (uint8 v, bytes32 r, bytes32 s) = vm.sign(owner1Key, userOpHash.toEthSignedMessageHash()); userOp.signature = _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, abi.encodePacked(r, s, v) ); @@ -68,7 +68,7 @@ contract SingleSignerValidationTest is AccountTestBase { account.executeWithAuthorization( abi.encodeCall(UpgradeableModularAccount.execute, (ethRecipient, 1 wei, "")), _encodeSignature( - PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ID), + PluginEntityLib.pack(address(singleSignerValidation), TEST_DEFAULT_VALIDATION_ENTITY_ID), GLOBAL_VALIDATION, "" ) @@ -109,19 +109,19 @@ contract SingleSignerValidationTest is AccountTestBase { // sig check should fail assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, abi.encodePacked(r, s, v) + accountAddr, TEST_DEFAULT_VALIDATION_ENTITY_ID, address(this), digest, abi.encodePacked(r, s, v) ), bytes4(0xFFFFFFFF) ); // transfer ownership to signer - singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ID, signer); - assertEq(signer, singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ID, accountAddr)); + singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ENTITY_ID, signer); + assertEq(signer, singleSignerValidation.signerOf(TEST_DEFAULT_VALIDATION_ENTITY_ID, accountAddr)); // sig check should pass assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, abi.encodePacked(r, s, v) + accountAddr, TEST_DEFAULT_VALIDATION_ENTITY_ID, address(this), digest, abi.encodePacked(r, s, v) ), _1271_MAGIC_VALUE ); @@ -130,11 +130,11 @@ contract SingleSignerValidationTest is AccountTestBase { function testFuzz_isValidSignatureForContractOwner(bytes32 digest) public { address accountAddr = address(account); vm.startPrank(accountAddr); - singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ID, address(contractOwner)); + singleSignerValidation.transferSigner(TEST_DEFAULT_VALIDATION_ENTITY_ID, address(contractOwner)); bytes memory signature = contractOwner.sign(digest); assertEq( singleSignerValidation.validateSignature( - accountAddr, TEST_DEFAULT_VALIDATION_ID, address(this), digest, signature + accountAddr, TEST_DEFAULT_VALIDATION_ENTITY_ID, address(this), digest, signature ), _1271_MAGIC_VALUE );