Skip to content
Lattice

ERC6900ExecutorLib

Git Source

Title: ERC6900ExecutorLib

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

The ERC-6900 RUNTIME executor + dispatch pipeline: the ModularAccount6900 fallback dispatch for installed execution-module selectors, the native execute / executeBatch, and the explicit-auth executeWithRuntimeValidation, plus the runtime-validation pipeline and the execution-hook engine.

Re-implemented FRESH from the ERC-6900 reference (erc6900/reference-implementation @ 65892c2). Reads the registries owned by ERC6900ModuleManagerLib. Key semantics carried over: execution modules are invoked by CALL (own storage context), NOT delegatecall; exec hooks come from two never-merged sources (validation-associated + selector-associated); pre hooks snapshot their post set before running, post hooks run LIFO and ONLY on success; runtime auth bypasses on EntryPoint / self / skipRuntimeValidation and otherwise routes through a direct-call validation. No reentrancy mutex — self-recursion is capped at one level. Lattice deviation: native validation-gated selectors are just execute/executeBatch (Lattice installs/uninstalls are admin-gated in ERC6900ModuleManagerLib, not validation-gated).

Functions

dispatch

Dispatches a call to an installed execution module: auth + pre hooks → CALL module → post hooks. Reverts UnrecognizedFunction if no module owns the selector.

function dispatch() internal returns (bytes memory);

Returns

NameTypeDescription
<none>bytes

execute

execute(target, value, data) — a native execution function: validates the caller + runs the active validation's exec hooks, then CALLs target with value.

function execute(address target, uint256 value, bytes calldata data) internal returns (bytes memory result);

Parameters

NameTypeDescription
targetaddress
valueuint256
databytes

Returns

NameTypeDescription
resultbytes

executeBatch

executeBatch(calls) — atomic; reverts the whole batch on any sub-call failure. No Σ value == msg.value check — per-call value draws on the account's balance.

function executeBatch(Call[] calldata calls) internal returns (bytes[] memory results);

Parameters

NameTypeDescription
callsCall[]

Returns

NameTypeDescription
resultsbytes[]

executeWithRuntimeValidation

executeWithRuntimeValidation(data, authorization) — runs the supplied validation (pre-validation hooks + validateRuntime) + its exec hooks, then self-CALLs data.

function executeWithRuntimeValidation(bytes calldata data, bytes calldata authorization)
        internal
        returns (bytes memory);

Parameters

NameTypeDescription
databytes
authorizationbytes

Returns

NameTypeDescription
<none>bytes

_checkPermittedCallerAndAssociatedHooks

Runtime authorization for a native/module selector + collection of its pre exec hooks. Returns the cached post hooks for the validator set and the selector set (run in reverse on the way out).

function _checkPermittedCallerAndAssociatedHooks(bytes calldata callData)
        private
        returns (PostExecToRun[] memory postValidator, PostExecToRun[] memory postSelector);

Parameters

NameTypeDescription
callDatabytes

Returns

NameTypeDescription
postValidatorPostExecToRun[]
postSelectorPostExecToRun[]

checkValidationAppliesCallData

Validation applicability for callData's selector + the self-call recursion guard (depth 1). Shared with the userOp validation path (#74 sub-task 4), which decodes the selector from the userOp callData and passes GLOBAL or SELECTOR (never EITHER).

function checkValidationAppliesCallData(bytes calldata callData, ModuleEntity vf, ValidationCheckType t)
        internal
        view;

Parameters

NameTypeDescription
callDatabytes
vfModuleEntity
tValidationCheckType

_checkIfValidationApplies

function _checkIfValidationApplies(bytes4 selector, ModuleEntity vf, ValidationCheckType t) private view;

Parameters

NameTypeDescription
selectorbytes4
vfModuleEntity
tValidationCheckType

_globalValidationApplies

function _globalValidationApplies(bytes4 selector, ModuleEntity vf) private view returns (bool);

Parameters

NameTypeDescription
selectorbytes4
vfModuleEntity

Returns

NameTypeDescription
<none>bool

_selectorValidationApplies

function _selectorValidationApplies(bytes4 selector, ModuleEntity vf) private view returns (bool);

Parameters

NameTypeDescription
selectorbytes4
vfModuleEntity

Returns

NameTypeDescription
<none>bool

_globalValidationAllowed

execute/executeBatch are the native validation-gated selectors (Lattice installs/uninstalls are admin-gated in ERC6900ModuleManagerLib, not validation-gated); any other selector opts into global validation via its own allowGlobalValidation flag.

function _globalValidationAllowed(bytes4 selector) private view returns (bool);

Parameters

NameTypeDescription
selectorbytes4

Returns

NameTypeDescription
<none>bool

_doRuntimeValidation

Runs vf's pre-runtime-validation hooks then its validateRuntime (the explicit-auth path, unlike the direct-call path which only runs the hooks).

function _doRuntimeValidation(ModuleEntity vf, bytes calldata data, bytes calldata authData) private;

Parameters

NameTypeDescription
vfModuleEntity
databytes
authDatabytes

_moduleEntityOf

function _moduleEntityOf(bytes calldata auth) private pure returns (ModuleEntity me);

Parameters

NameTypeDescription
authbytes

Returns

NameTypeDescription
meModuleEntity

_doPreRuntimeValidationHooks

function _doPreRuntimeValidationHooks(ModuleEntity vf, bytes calldata data) private;

Parameters

NameTypeDescription
vfModuleEntity
databytes

_doPreHooks

Snapshot the post-hook set BEFORE running any pre hook (so a hook that mutates the set cannot change which post hooks fire), then run pre hooks, caching each pre's return data for its matching post hook.

function _doPreHooks(EnumerableSet.Bytes32Set storage hooks, bytes calldata data)
        private
        returns (PostExecToRun[] memory toRun);

Parameters

NameTypeDescription
hooksEnumerableSet.Bytes32Set
databytes

Returns

NameTypeDescription
toRunPostExecToRun[]

_runPreExecHook

function _runPreExecHook(ModuleEntity hookEntity, bytes calldata data) private returns (bytes memory);

Parameters

NameTypeDescription
hookEntityModuleEntity
databytes

Returns

NameTypeDescription
<none>bytes

_doCachedPostExecHooks

Run cached post hooks LIFO; pre-only entries (empty postExecHook) are skipped. Post hooks run only on the success path — a reverting body bubbles before this is reached.

function _doCachedPostExecHooks(PostExecToRun[] memory toRun) private;

Parameters

NameTypeDescription
toRunPostExecToRun[]

_exec

Raw target CALL with value; bubbles the target's revert data verbatim. The executor NEVER self-calls the account — a self-call would bridge a validation-authorized execute/executeBatch into the admin-gated config functions (msg.sender == address(this) satisfies _authorizeConfig). This is the backstop for the privileged bypass paths (EntryPoint / self / skipRuntimeValidation), which skip the applicability guard entirely.

function _exec(address target, uint256 value, bytes calldata data) private returns (bytes memory);

Parameters

NameTypeDescription
targetaddress
valueuint256
databytes

Returns

NameTypeDescription
<none>bytes

_selectorOf

function _selectorOf(bytes calldata data) private pure returns (bytes4 s);

Parameters

NameTypeDescription
databytes

Returns

NameTypeDescription
sbytes4