From f784e43a1f50ad25a76fc9ef1428ad8bbcce6d99 Mon Sep 17 00:00:00 2001 From: zeroknots Date: Tue, 14 May 2024 11:21:17 +0700 Subject: [PATCH] feat: prototype for ERC 165 --- foundry.toml | 2 +- src/MSAAdvanced.sol | 2 +- src/core/ModuleManager.sol | 5 +++++ src/interfaces/IERC7579Module.sol | 3 ++- src/modules/SimpleExecutionValidator.sol | 12 ++++++++++++ test/advanced/MSAAdvanced.t.sol | 2 +- test/mocks/MockValidator.sol | 18 ++++++++++++++++++ 7 files changed, 40 insertions(+), 4 deletions(-) diff --git a/foundry.toml b/foundry.toml index 962d64a..7644348 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,7 +1,7 @@ [profile.default] src = "src" out = "out" -libs = ["lib"] +libs = ["node_modules"] fs_permissions = [{ access = "read", path = "out-optimized" }] allow_paths = ["*", "/"] diff --git a/src/MSAAdvanced.sol b/src/MSAAdvanced.sol index 7970c17..e1de95c 100644 --- a/src/MSAAdvanced.sol +++ b/src/MSAAdvanced.sol @@ -164,7 +164,7 @@ contract MSAAdvanced is IMSA, ExecutionHelper, ModuleManager, HookManager { withHook { if (!IModule(module).isModuleType(moduleTypeId)) revert MismatchModuleTypeId(moduleTypeId); - + if (moduleTypeId == MODULE_TYPE_VALIDATOR) _installValidator(module, initData); else if (moduleTypeId == MODULE_TYPE_EXECUTOR) _installExecutor(module, initData); else if (moduleTypeId == MODULE_TYPE_FALLBACK) _installFallbackHandler(module, initData); diff --git a/src/core/ModuleManager.sol b/src/core/ModuleManager.sol index f898b1c..d6b3339 100644 --- a/src/core/ModuleManager.sol +++ b/src/core/ModuleManager.sol @@ -23,6 +23,7 @@ abstract contract ModuleManager is AccountBase, Receiver { error InvalidModule(address module); error NoFallbackHandler(bytes4 selector); error CannotRemoveLastValidator(); + error UnsupportedValidationMethod(); // keccak256("modulemanager.storage.msa"); bytes32 internal constant MODULEMANAGER_STORAGE_LOCATION = @@ -80,6 +81,10 @@ abstract contract ModuleManager is AccountBase, Receiver { function _installValidator(address validator, bytes calldata data) internal virtual { SentinelListLib.SentinelList storage $valdiators = $moduleManager().$valdiators; $valdiators.push(validator); + bool supportsEPv07 = + IERC165(validator).supportsInterface(IValidator.validateUserOp.selector); + if (!supportsEPv07) revert UnsupportedValidationMethod(); + IValidator(validator).onInstall(data); } diff --git a/src/interfaces/IERC7579Module.sol b/src/interfaces/IERC7579Module.sol index 09480a4..d5156f9 100644 --- a/src/interfaces/IERC7579Module.sol +++ b/src/interfaces/IERC7579Module.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.21; import { PackedUserOperation } from "account-abstraction/interfaces/PackedUserOperation.sol"; +import "forge-std/interfaces/IERC165.sol"; uint256 constant VALIDATION_SUCCESS = 0; uint256 constant VALIDATION_FAILED = 1; @@ -47,7 +48,7 @@ interface IModule { function isInitialized(address smartAccount) external view returns (bool); } -interface IValidator is IModule { +interface IValidator is IERC165, IModule { error InvalidTargetAddress(address target); /** diff --git a/src/modules/SimpleExecutionValidator.sol b/src/modules/SimpleExecutionValidator.sol index 04942b2..28ec58b 100644 --- a/src/modules/SimpleExecutionValidator.sol +++ b/src/modules/SimpleExecutionValidator.sol @@ -63,4 +63,16 @@ contract SimpleExecutionValidator is IValidator { override returns (bytes4) { } + + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + if (interfaceId == type(IERC165).interfaceId) { + return true; + } + if (interfaceId == type(IValidator).interfaceId) { + return true; + } + if (interfaceId == IValidator.validateUserOp.selector) { + return true; + } + } } diff --git a/test/advanced/MSAAdvanced.t.sol b/test/advanced/MSAAdvanced.t.sol index 295b8d2..c32b9e5 100644 --- a/test/advanced/MSAAdvanced.t.sol +++ b/test/advanced/MSAAdvanced.t.sol @@ -146,7 +146,7 @@ contract MSAAdvancedTest is TestBaseUtilAdvanced { ( ModeLib.encode( CALLTYPE_DELEGATECALL, EXECTYPE_DEFAULT, MODE_DEFAULT, ModePayload.wrap(0x00) - ), + ), abi.encodePacked(address(delegateTarget), sendValue) ) ); diff --git a/test/mocks/MockValidator.sol b/test/mocks/MockValidator.sol index ef04962..27ffddd 100644 --- a/test/mocks/MockValidator.sol +++ b/test/mocks/MockValidator.sol @@ -8,6 +8,8 @@ import { MODULE_TYPE_VALIDATOR } from "src/interfaces/IERC7579Module.sol"; +import "forge-std/interfaces/IERC165.sol"; + contract MockValidator is IValidator { function onInstall(bytes calldata data) external override { } @@ -46,4 +48,20 @@ contract MockValidator is IValidator { function isInitialized(address smartAccount) external view returns (bool) { return false; } + + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + if (interfaceId == type(IERC165).interfaceId) { + return true; + } + if (interfaceId == type(IValidator).interfaceId) { + return true; + } + if (interfaceId == IValidator.validateUserOp.selector) { + return true; + } + + if (interfaceId == IValidator.isValidSignatureWithSender.selector) { + return true; + } + } }