Skip to content
Lattice

ERC6900ModuleManagerLib

Git Source

Title: ERC6900ModuleManagerLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from ERC-6900 reference implementation (https://github.com/erc6900/reference-implementation)

Logic + ERC-7201 storage for the ERC-6900 module registry: the execution registry (selector → module + exec hooks) and the validation registry (ModuleEntity → flags + selectors + validation /exec hooks). Backs the ERC6900ModuleManager config facet and (via the read helpers) the IERC6900AccountView loupe.

Re-implemented FRESH from the ERC-6900 reference semantics (erc6900/reference-implementation @ 65892c2; reference is MIT — not a dependency). Lattice-native deviations: ERC-7201 namespaced storage (not the reference's plain-keccak slot); a Diamond facet-map shadow check in place of the reference's static KnownSelectorsLib.isNativeFunction list (diamondCut is the sole selector authority); and the account-or-admin _authorizeConfig model shared with the ERC-7579 flavor. Module callbacks are data-gated (called only when their bytes arg is non-empty) and state is written BEFORE every callback; onInstall failure reverts the whole install, onUninstall failure is swallowed into the event's onUninstallSucceeded flag — matching the reference.

Constants

_ACCOUNT_ID

ERC-6900 account identifier (vendorname.accountname.semver; names contain no period).

string private constant _ACCOUNT_ID = "lattice.modular-account-6900.0.1.0";

Functions

erc6900ModuleManagerStorage

function erc6900ModuleManagerStorage() internal pure returns (ERC6900ModuleManagerStorage storage $);

Returns

NameTypeDescription
$ERC6900ModuleManagerStorage

accountId

function accountId() internal pure returns (string memory);

Returns

NameTypeDescription
<none>string

getExecutionData

The execution-function install state for selector (module, validation flags, exec hooks). A native function — one the Diamond dispatches to a facet — reports the account itself as the module (per IERC6900AccountView); execute/executeBatch additionally report allowGlobalValidation (matching the executor's native validation-gated set). An unowned selector reports all zero.

function getExecutionData(bytes4 selector) internal view returns (ExecutionDataView memory data);

Parameters

NameTypeDescription
selectorbytes4

Returns

NameTypeDescription
dataExecutionDataView

getValidationData

The validation-function install state for validationFunction (flags, hooks, selectors).

function getValidationData(ModuleEntity validationFunction) internal view returns (ValidationDataView memory data);

Parameters

NameTypeDescription
validationFunctionModuleEntity

Returns

NameTypeDescription
dataValidationDataView

interfaceRefCount

How many installed modules advertise interfaceId via their manifest (ERC-165 refcount).

function interfaceRefCount(bytes4 interfaceId) internal view returns (uint256);

Parameters

NameTypeDescription
interfaceIdbytes4

Returns

NameTypeDescription
<none>uint256

installExecution

Installs an execution module from its manifest. Order (matching the reference): execution functions → execution hooks → interface ids → onInstall. State is written before the callback; a reverting onInstall reverts the whole install (ModuleInstallCallbackFailed).

function installExecution(address module, ExecutionManifest calldata manifest, bytes calldata installData)
        internal;

Parameters

NameTypeDescription
moduleaddress
manifestExecutionManifest
installDatabytes

uninstallExecution

Uninstalls an execution module. Reverse-by-type of install (hooks → functions → interface ids), then onUninstall. No ownership/installed checks (auth-gated); a reverting onUninstall is SWALLOWED into the event's onUninstallSucceeded flag, never reverting the uninstall.

function uninstallExecution(address module, ExecutionManifest calldata manifest, bytes calldata uninstallData)
        internal;

Parameters

NameTypeDescription
moduleaddress
manifestExecutionManifest
uninstallDatabytes

installValidation

Installs (or updates) a validation function. Order (matching the reference): per hook (store → onInstall) → selectors → flags → the validation module's own onInstall. Flags are OVERWRITTEN wholesale (this is also the update path); selectors/hooks are only ever added. Validation (pre-validation) hooks go to an ordered array (duplicates allowed, capped at MAX_VALIDATION_ASSOC_HOOKS); execution hooks go to a deduped set.

function installValidation(
        ValidationConfig validationConfig,
        bytes4[] calldata selectors,
        bytes calldata installData,
        bytes[] calldata hooks
    ) internal;

Parameters

NameTypeDescription
validationConfigValidationConfig
selectorsbytes4[]
installDatabytes
hooksbytes[]

uninstallValidation

Uninstalls a validation function. Order: clear flags → (if hookUninstallData non-empty) run hook onUninstalls [validation hooks, then execution hooks] → wipe hooks/selectors → the validation module's own onUninstall. Every onUninstall revert is swallowed into onUninstallSucceeded. Passing empty hookUninstallData clears all state but skips every hook callback.

function uninstallValidation(
        ModuleEntity validationFunction,
        bytes calldata uninstallData,
        bytes[] calldata hookUninstallData
    ) internal;

Parameters

NameTypeDescription
validationFunctionModuleEntity
uninstallDatabytes
hookUninstallDatabytes[]

_toHookConfigs

function _toHookConfigs(EnumerableSet.Bytes32Set storage set) private view returns (HookConfig[] memory out);

Parameters

NameTypeDescription
setEnumerableSet.Bytes32Set

Returns

NameTypeDescription
outHookConfig[]

_hookKey

Set key for a HookConfig: the bytes25 left-aligned in a bytes32 (low 7 bytes zero).

function _hookKey(HookConfig hookConfig) private pure returns (bytes32);

Parameters

NameTypeDescription
hookConfigHookConfig

Returns

NameTypeDescription
<none>bytes32

_addInterface

Refcount a manifest interface id; advertise it via the Diamond's ERC-165 map on the first claim. The refcount and the Diamond's native ERC-165 bits share one bool map, so a module may not refcount an id the account already owns natively (bit set, refcount 0) — a later uninstall would clear that native bit and desync the ERC-165 view. The ERC-165 invalid sentinel must always read false, so it too is rejected. (Native ids are registered at construction, before any module install.)

function _addInterface(ERC6900ModuleManagerStorage storage $, bytes4 interfaceId) private;

Parameters

NameTypeDescription
$ERC6900ModuleManagerStorage
interfaceIdbytes4

_removeInterface

Drop one manifest interface-id reference; retract from ERC-165 when the last module drops it. The checked decrement panics on over-uninstall — matching the reference's refcount underflow.

function _removeInterface(ERC6900ModuleManagerStorage storage $, bytes4 interfaceId) private;

Parameters

NameTypeDescription
$ERC6900ModuleManagerStorage
interfaceIdbytes4

_onInstall

Data-gated onInstall: skipped when data is empty; a revert is re-thrown as ModuleInstallCallbackFailed (reverting the whole install).

function _onInstall(address module, bytes calldata data) private;

Parameters

NameTypeDescription
moduleaddress
databytes

_onUninstall

Data-gated onUninstall: skipped (treated as success) when data is empty; a revert is SWALLOWED and reported as false so a malicious module cannot brick uninstallation.

function _onUninstall(address module, bytes calldata data) private returns (bool);

Parameters

NameTypeDescription
moduleaddress
databytes

Returns

NameTypeDescription
<none>bool

_decodeHook

Splits an installValidation hook entry abi.encodePacked(bytes25 HookConfig, bytes hookData) at the fixed 25-byte boundary. h[25:] bounds-checks the length (reverts if < 25); the calldataload reads the leading 25 bytes (low 7 of the 32-byte word are masked off by the bytes25 cast).

function _decodeHook(bytes calldata h) private pure returns (HookConfig hookConfig, bytes calldata hookData);

Parameters

NameTypeDescription
hbytes

Returns

NameTypeDescription
hookConfigHookConfig
hookDatabytes

_drainBytes32

function _drainBytes32(EnumerableSet.Bytes32Set storage set) private;

Parameters

NameTypeDescription
setEnumerableSet.Bytes32Set

_drainBytes4

function _drainBytes4(EnumerableSet.Bytes4Set storage set) private;

Parameters

NameTypeDescription
setEnumerableSet.Bytes4Set

_authorizeConfig

function _authorizeConfig() private view;