diff --git a/standard/ERCs/erc-6900.md b/standard/ERCs/erc-6900.md index c923427c..85ef43f5 100644 --- a/standard/ERCs/erc-6900.md +++ b/standard/ERCs/erc-6900.md @@ -90,12 +90,37 @@ Each step is modular, supporting different implementations, that allows for open Module execution and management interface. Modular Smart Contract Accounts **MUST** implement this interface to support installing and uninstalling modules, and open-ended execution. ```solidity - +/// A packed representation of a module function. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes type ModuleEntity is bytes24; -type ValidationConfig is bytes26; - -type HookConfig is bytes26; +/// A packed representation of a validation function and its associated flags. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes +/// Flags: 1 byte +/// +/// Validation flags layout: +/// 0b00000___ // unused +/// 0b_____A__ // isGlobal +/// 0b______B_ // isSignatureValidation +/// 0b_______C // isUserOpValidation +type ValidationConfig is bytes25; + +/// A packed representation of a hook function and its associated flags. +/// Consists of the following, left-aligned: +/// Module address: 20 bytes +/// Entity ID: 4 bytes +/// Flags: 1 byte +/// +/// Hook flags layout: +/// 0b00000___ // unused +/// 0b_____A__ // hasPre (exec only) +/// 0b______B_ // hasPost (exec only) +/// 0b_______C // hook type (0 for exec, 1 for validation) +type HookConfig is bytes25; struct Call { // The target address for the account to call. @@ -137,9 +162,9 @@ interface IModularAccount { /// @notice Install a module to the modular account. /// @param module The module to install. - /// @param manifest the manifest describing functions to install - /// @param moduleInstallData Optional data to be decoded and used by the module to setup initial module data - /// for the modular account. + /// @param manifest the manifest describing functions to install. + /// @param moduleInstallData Optional data to be used by the account to handle the initial execution setup, + /// data encoding is implementation-specific. function installExecution( address module, ExecutionManifest calldata manifest, @@ -151,10 +176,10 @@ interface IModularAccount { /// @dev This does not validate anything against the manifest - the caller must ensure validity. /// @param validationConfig The validation function to install, along with configuration flags. /// @param selectors The selectors to install the validation function for. - /// @param installData Optional data to be decoded and used by the module to setup initial module state. - /// @param hooks Optional hooks to install, associated with the validation function. These may be - /// pre validation hooks or execution hooks. The expected format is a bytes26 HookConfig, followed by the - /// install data, if any. + /// @param installData Optional data to be used by the account to handle the initial validation setup, data + /// encoding is implementation-specific. + /// @param hooks Optional hooks to install and associate with the validation function, data encoding is + /// implementation-specific. function installValidation( ValidationConfig validationConfig, bytes4[] calldata selectors, @@ -164,11 +189,10 @@ interface IModularAccount { /// @notice Uninstall a validation function from a set of execution selectors. /// @param validationFunction The validation function to uninstall. - /// @param uninstallData Optional data to be decoded and used by the module to clear module data for the - /// account. - /// @param hookUninstallData Optional data to be used by hooks for cleanup. If any are provided, the array must - /// be of a length equal to existing pre validation hooks plus permission hooks. Hooks are indexed by - /// pre validation hook order first, then permission hooks. + /// @param uninstallData Optional data to be used by the account to handle the validation uninstallation, data + /// encoding is implementation-specific. + /// @param hookUninstallData Optional data to be used by the account to handle hook uninstallation, data encoding + /// is implementation-specific. function uninstallValidation( ModuleEntity validationFunction, bytes calldata uninstallData, @@ -178,8 +202,8 @@ interface IModularAccount { /// @notice Uninstall a module from the modular account. /// @param module The module to uninstall. /// @param manifest the manifest describing functions to uninstall. - /// @param moduleUninstallData Optional data to be decoded and used by the module to clear module data for the - /// modular account. + /// @param moduleUninstallData Optional data to be used by the account to handle the execution uninstallation, data + /// encoding is implementation-specific. function uninstallExecution( address module, ExecutionManifest calldata manifest, @@ -378,8 +402,6 @@ interface IValidationHookModule is IModule { bytes calldata authorization ) external; - // TODO: support this hook type within the account & in the manifest - /// @notice Run the pre signature validation hook specified by the `entityId`. /// @dev To indicate the call should revert, the function MUST revert. /// @param entityId An identifier that routes the call to different internal implementations, should there @@ -387,11 +409,10 @@ interface IValidationHookModule is IModule { /// @param sender The caller address. /// @param hash The hash of the message being signed. /// @param signature The signature of the message. - // function preSignatureValidationHook(uint32 entityId, address sender, bytes32 hash, bytes calldata - // signature) - // external - // view - // returns (bytes4); + function preSignatureValidationHook(uint32 entityId, address sender, bytes32 hash, bytes calldata signature) + external + view + returns (bytes4); } ``` @@ -462,8 +483,6 @@ interface IExecutionHookModule is IModule { ### Expected behavior -TODO for v0.8 - #### Validations and their installation /uninstallation An account can have more than one validation module/function installed. @@ -509,18 +528,6 @@ During execution uninstallation, the account MUST correctly clear flags and othe - the account SHOULD call `onUnInstall` on the execution module to initialize the states and track call success if required by user. - the account MUST emit `ExecutionUninstalled` as defined in the interface for all uninstalled executions. -#### Responsibilties of `StandardExecutor` and `ModuleExecutor` - -`StandardExecutor` functions are used for open-ended calls to external addresses. - -`ModuleExecutor` functions are specifically used by modules to request the account to execute with account's context. Explicit permissions are required for modules to use `ModuleExecutor`. - -The following behavior MUST be followed: - -- `StandardExecutor` can NOT call module execution functions and/or `ModuleExecutor`. This is guaranteed by checking whether the call's target implements the `IModule` interface via ERC-165 as required. -- `StandardExecutor` can NOT be called by module execution functions and/or `ModuleExecutor`. -- Module execution functions MUST NOT request access to `StandardExecutor`, they MAY request access to `ModuleExecutor`. - ### Validation Call Flow Modular accounts support three different calls flows for validation: user op validation, runtime validation, and signature validation. User op validation happens within the account's implementation of the function `validateUserOp`, defined in the ERC-4337 interface `IAccount`. Runtime validation happens through the dispatcher function `executeWithAuthorization`, or when using direct call validation. Signature validation happens within the account's implementation of the function `isValidSignature`, defined in ERC-1271. @@ -569,7 +576,7 @@ Module execution functions where the field `isPublic` is set to true, or native ### Extension -#### Semi-modular account +#### Semi-Modular Account Account implementers MAY choose to design a semi-modular account, where certain features, such as default validation, are integrated into the core account. This approach SHOULD ensure compatibility with fully modular accounts, as defined in this proposal, to maintain interoperability across different implementations.