diff --git a/src/account/SemiModularAccount.sol b/src/account/SemiModularAccount.sol index 8fe637a4..f16d2363 100644 --- a/src/account/SemiModularAccount.sol +++ b/src/account/SemiModularAccount.sol @@ -7,7 +7,7 @@ import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interface import {ModuleEntityLib} from "../helpers/ModuleEntityLib.sol"; -import {ModuleEntity, ValidationConfig} from "../interfaces/IModularAccount.sol"; +import {IModularAccount, ModuleEntity, ValidationConfig} from "../interfaces/IModularAccount.sol"; import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol"; @@ -83,6 +83,11 @@ contract SemiModularAccount is UpgradeableModularAccount { revert InitializerDisabled(); } + /// @inheritdoc IModularAccount + function accountId() external pure override returns (string memory) { + return "erc6900/reference-semi-modular-account/0.8.0"; + } + function _execUserOpValidation( ModuleEntity userOpValidationFunction, PackedUserOperation memory userOp, diff --git a/src/account/UpgradeableModularAccount.sol b/src/account/UpgradeableModularAccount.sol index 2a58f4b9..12ab1da8 100644 --- a/src/account/UpgradeableModularAccount.sol +++ b/src/account/UpgradeableModularAccount.sol @@ -276,6 +276,11 @@ contract UpgradeableModularAccount is return getAccountStorage().supportedIfaces[interfaceId] > 0; } + /// @inheritdoc IModularAccount + function accountId() external pure virtual returns (string memory) { + return "erc6900/reference-modular-account/0.8.0"; + } + /// @inheritdoc UUPSUpgradeable /// @notice May be validated by a global validation. function upgradeToAndCall(address newImplementation, bytes memory data) diff --git a/src/helpers/KnownSelectors.sol b/src/helpers/KnownSelectors.sol index 84c400cf..ba772d66 100644 --- a/src/helpers/KnownSelectors.sol +++ b/src/helpers/KnownSelectors.sol @@ -22,18 +22,20 @@ library KnownSelectors { return // check against IAccount methods selector == IAccount.validateUserOp.selector - // check against module manager methods + // check against IModularAccount methods || selector == IModularAccount.installExecution.selector || selector == IModularAccount.uninstallExecution.selector + || selector == IModularAccount.installValidation.selector + || selector == IModularAccount.uninstallValidation.selector || selector == IModularAccount.execute.selector + || selector == IModularAccount.executeBatch.selector + || selector == IModularAccount.executeWithAuthorization.selector + || selector == IModularAccount.accountId.selector // check against IERC165 methods || selector == IERC165.supportsInterface.selector // check against UUPSUpgradeable methods || selector == UUPSUpgradeable.proxiableUUID.selector || selector == UUPSUpgradeable.upgradeToAndCall.selector - // check against IModularAccount methods - || selector == IModularAccount.execute.selector || selector == IModularAccount.executeBatch.selector - || selector == IModularAccount.executeWithAuthorization.selector - // check against account loupe methods + // check against IAccountLoupe methods || selector == IAccountLoupe.getExecutionData.selector || selector == IAccountLoupe.getValidationData.selector; } diff --git a/src/interfaces/IModularAccount.sol b/src/interfaces/IModularAccount.sol index f6212b54..dcad3ee8 100644 --- a/src/interfaces/IModularAccount.sol +++ b/src/interfaces/IModularAccount.sol @@ -97,4 +97,9 @@ interface IModularAccount { ExecutionManifest calldata manifest, bytes calldata moduleUninstallData ) external; + + /// @notice Return a unique identifier for the account implementation. + /// @dev This function MUST return a string in the format "vendor/account/semver". + /// @return The account ID. + function accountId() external view returns (string memory); } diff --git a/test/account/UpgradeableModularAccount.t.sol b/test/account/UpgradeableModularAccount.t.sol index cfc99497..a2ac85b0 100644 --- a/test/account/UpgradeableModularAccount.t.sol +++ b/test/account/UpgradeableModularAccount.t.sol @@ -184,6 +184,16 @@ contract UpgradeableModularAccountTest is AccountTestBase { _printStorageReadsAndWrites(address(account2)); } + function test_accountId() public { + string memory accountId = account1.accountId(); + assertEq( + accountId, + vm.envOr("SMA_TEST", false) + ? "erc6900/reference-semi-modular-account/0.8.0" + : "erc6900/reference-modular-account/0.8.0" + ); + } + function test_contractInteraction() public { PackedUserOperation memory userOp = PackedUserOperation({ sender: address(account1),