-
Notifications
You must be signed in to change notification settings - Fork 8
Modules
Nexus is following the ERC-7579 specification. ERC-7579 is the standard for minimal modular smart accounts. Thus, modules are a crucial component that allows to add features and extend the functionality of Nexus.
There are currently 4 module types specified in ERC-7579 and all of them are supported by Nexus:
- Validators: validate userOperations as per ERC-4337.
- Executors: can initiate executions on behalf of the Smart Account they are installed on.
- Fallback handlers: extend the native functionality of the Smart Account. Calls to functions which are not implemented in the Smart Account are forwarded to fallback handlers.
- Hooks: hook executions by executing code before and after execution.
Nexus implements ERC-7579 installModule
interface for the installation of the modules.
It allows specifying which module to install and accepts data to perform the initial configuration for a module being installed.
Another important parameter that has to be provided at module installation is the moduleTypeId
.
It is an incremental identifier used by accounts, modules, and other entities to identify the module type:
- Validator modules have
type id: 1
- Executors have
type id: 2
- Fallback Handlers have
type id: 3
- Hooks have
type id: 4
There is also Module type id: 0
, which allows multi-type installations. This feature, compatible with ERC-7739, enables installing a module as multiple types (e.g., validator and executor) in one operation using the installModule
interface.
Every module self-reports its type via the isModuleType(uint256 moduleTypeId)
method, and a single module can implement multiple types at once.
In some cases, a user may want to use a module that is not yet installed. To avoid the need for separate userOperation
transactions to install the module, Nexus offers Enable Mode.
For example, if you need to use an executor module, you can batch the installModule(executor)
call before the operation that uses this executor. However, for validators, since validation occurs before execution in ERC-4337, the validator must be installed and enabled before validation starts.
Enable Mode, which is compatible with ERC-7739, allows a module to be installed during the validation phase, and this is fully supported by Nexus and Entrypoint v0.7. Users sign an Enable Mode Data object that specifies which module to install and how it should be configured during the validation.
Any module type can be installed via Module Enable Mode, however, we believe it makes the most sense for validators and hooks.
To install a module via Enable Mode, a user with appropriate rights (owner, etc.) must sign the Enable Mode Data Hash.
This hash is generated using EIP-712 to ensure phishing resistance and security through the following process:
_hashTypedData(
keccak256(
abi.encode(
MODULE_ENABLE_MODE_TYPE_HASH,
module,
moduleType,
userOpHash,
keccak256(initData)
)
)
)
This process leverages ERC-7739, which introduces Typed Data Signatures to minimize signature replay attacks across multiple smart accounts. The structure ensures that the signature is tied to a specific module
and moduleType
to prevent unintended installations.
The key components of the EIP-712 hash are:
-
module
: The module's address to be installed. -
moduleType
: Prevents the signature from being exploited to install the module under a different type. -
userOpHash
: Introduces uniqueness based on fields from theUserOperation
(e.g., nonce). -
keccak256(initData)
: Data used to initialize the module during the installation.
The data (ModuleType moduleType, bytes moduleInitData, bytes enableModeSignature, bytes userOpSignature)
, required to activate Enable Mode, is embedded in the userOp.signature
field.
The encoding must follow a precise structure:
- First 20 bytes: The module's address to be installed.
-
Next 32 bytes:
ModuleType
asuint256
. -
Next 4 bytes: Length of
moduleInitData
. -
Next
<length-of-moduleInitData>
bytes:moduleInitData
. -
Next 4 bytes: Length of
enableModeSignature
. -
Next
<length-of-enableModeSignature>
bytes:enableModeSignature
. -
Remaining bytes:
userOpSignature
.
In Solidity, the encoding is handled as follows:
bytes memory extendedUserOpSignature = abi.encodePacked(
module,
uint256(moduleType),
bytes4(uint32(moduleInitData.length)),
moduleInitData,
bytes4(uint32(enableModeSignature.length)),
enableModeSignature,
userOpSignature
);
To decode this packed data, the parseEnableModeData
method is used, enabling the system to extract and verify the signature.
The ERC-7739 standard plays a crucial role in securing Enable Mode by validating signatures using nested EIP-712 flows. This prevents signature reuse across multiple accounts and ensures compatibility with wallet clients (e.g., MetaMask). If validation using TypedDataSign
fails, the system gracefully falls back to PersonalSign workflows, ensuring robust protection against phishing and replay attacks.
Modules are used according to their types.
Validators validate userOperations. The validator's address should be encoded into the userOp.nonce
field. Nexus decodes this address and forwards the validation flow to the appropriate validator.
Executors can be called directly or via Nexus.execute. The most important ability of executors is to perform actions on behalf of Nexus they are installed on by calling ERC-7579 executeFromExecutor
method. For example, Executors can implement some complex logic of conditionally batching actions together.
Sometimes, developers may want to add native functions to Nexus. To avoid dealing with upgrades, a Fallback can be installed on Nexus, and Nexus will forward the calls to non-existent methods to such modules that implement them.
Hooks are used to actually 'hook' executions. For example, they can store (ideally, temporarily) some data that reflects the state before the execution, and then compare it to what the state is after the execution. Hooks are the most convenient way to implement spending limits for Nexus for example.
There are two methods of querying this.
One can check if a given module is installed as a given type on a given Nexus, by calling Nexus.isModuleInstalled
method.
If one just needs to learn what modules are installed, there are dedicated methods for it:
- getValidatorsPaginated for validators
- getExecutorsPaginated for executors
- getActiveHook for the hook. As you may see, only one hook can be enabled at a given time (this can be a hook multiplexer though).
- getFallbackHandlerBySelector to check where the implementation for a method with a given selector lives
When uninstalling the module it is very important to provide the appropriate data that will deinitialize the module (by clearing its state or in any other way). Leaving the module initialized (configured for a given Smart Account) after its uninstallation may lead to unexpected behaviors when the module is installed on the same Smart Account next time.
The emergencyUninstallHook
function is a safety mechanism designed to remove a potentially problematic hook module from the smart account in case of emergencies. It implements a timelock process to prevent immediate uninstallation, giving account owners a chance to intervene if the request is unauthorized.
When called, it first initiates a one-day waiting period. If called again after this period but within three days, it uninstalls the hook. If not completed within three days, the process resets. This function balances the need for quick response to emergencies with safeguards against unauthorized removals. It's particularly useful when a hook module might be compromised or causing issues, allowing for its removal even if normal uninstallation methods are unavailable.
The function can only be called by the EntryPoint, adding an extra layer of security. It also checks that the hook is actually installed before proceeding with any actions. This emergency uninstall feature provides a crucial failsafe for maintaining the security and functionality of the smart account in extreme situations.
Resource locking ensures that key modules, such as hooks, cannot be uninstalled without waiting for a pre-defined timelock, safeguarding the account's integrity. Hooks are essential for adding custom behavior, including additional validations, logging, or triggering events based on the transaction flow.
The function emergencyUninstallHook
is important for resource locking. Resource locking ensures that key modules, such as hooks, cannot be uninstalled without waiting for a pre-defined timelock, safeguarding the account's integrity. Hooks are essential for adding custom behavior, including additional validations, logging, or triggering events based on the transaction flow.
- Home
- Nexus Architecture
- Access Control
- Execution Framework
- Modules
- Factories
- Migration Guide
- Testing Documentation
- Configuration and Security
- Libraries
- FAQ
- Biconomy Solidity Style Guide
- Security Considerations
- Team
-
Contracts
- Nexus
- Base
- Common
- Factory
- AbstractNexusFactory
- BiconomyMetaFactory
- K1ValidatorFactory
- ModuleWhitelistFactory
- NexusAccountFactory
- Modules
- Utils