Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/account/AccountStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.20;

import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {HookConfig, ModuleEntity, ValidationFlags} from "../interfaces/IModularAccount.sol";
import {HookConfig, ModuleEntity, ValidationFlags} from "../interfaces/IERC6900Account.sol";

// bytes = keccak256("ERC6900.ReferenceModularAccount.Storage")
bytes32 constant _ACCOUNT_STORAGE_SLOT = 0xc531f081ecdb5a90f38c197521797881a6e5c752a7d451780f325a95f8b91f45;
Expand Down
16 changes: 8 additions & 8 deletions src/account/ModularAccountView.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeab
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {HookConfig, IModularAccount, ModuleEntity} from "../interfaces/IModularAccount.sol";
import {ExecutionDataView, IModularAccountView, ValidationDataView} from "../interfaces/IModularAccountView.sol";
import {HookConfig, IERC6900Account, ModuleEntity} from "../interfaces/IERC6900Account.sol";
import {ExecutionDataView, IERC6900AccountView, ValidationDataView} from "../interfaces/IERC6900AccountView.sol";
import {HookConfigLib} from "../libraries/HookConfigLib.sol";
import {ExecutionStorage, ValidationStorage, getAccountStorage, toHookConfig} from "./AccountStorage.sol";

abstract contract ModularAccountView is IModularAccountView {
abstract contract ModularAccountView is IERC6900AccountView {
using EnumerableSet for EnumerableSet.Bytes32Set;
using EnumerableMap for EnumerableMap.AddressToUintMap;
using HookConfigLib for HookConfig;

/// @inheritdoc IModularAccountView
/// @inheritdoc IERC6900AccountView
function getExecutionData(bytes4 selector) external view override returns (ExecutionDataView memory data) {
if (
selector == IModularAccount.execute.selector || selector == IModularAccount.executeBatch.selector
selector == IERC6900Account.execute.selector || selector == IERC6900Account.executeBatch.selector
|| selector == UUPSUpgradeable.upgradeToAndCall.selector
|| selector == IModularAccount.installExecution.selector
|| selector == IModularAccount.uninstallExecution.selector
|| selector == IERC6900Account.installExecution.selector
|| selector == IERC6900Account.uninstallExecution.selector
) {
data.module = address(this);
data.allowGlobalValidation = true;
Expand All @@ -39,7 +39,7 @@ abstract contract ModularAccountView is IModularAccountView {
}
}

/// @inheritdoc IModularAccountView
/// @inheritdoc IERC6900AccountView
function getValidationData(ModuleEntity validationFunction)
external
view
Expand Down
18 changes: 10 additions & 8 deletions src/account/ModuleManagerInternals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet

import {collectReturnData} from "../helpers/CollectReturnData.sol";
import {MAX_VALIDATION_ASSOC_HOOKS} from "../helpers/Constants.sol";
import {ExecutionManifest, ManifestExecutionHook} from "../interfaces/IExecutionModule.sol";

import {
HookConfig,
IModularAccount,
IERC6900Account,
ModuleEntity,
ValidationConfig,
ValidationFlags
} from "../interfaces/IModularAccount.sol";
import {IModule} from "../interfaces/IModule.sol";
} from "../interfaces/IERC6900Account.sol";

import {ExecutionManifest, ManifestExecutionHook} from "../interfaces/IERC6900ExecutionModule.sol";
import {IERC6900Module} from "../interfaces/IERC6900Module.sol";
import {HookConfigLib} from "../libraries/HookConfigLib.sol";
import {KnownSelectorsLib} from "../libraries/KnownSelectorsLib.sol";
import {ModuleEntityLib} from "../libraries/ModuleEntityLib.sol";
Expand All @@ -28,7 +30,7 @@ import {
toSetValue
} from "./AccountStorage.sol";

abstract contract ModuleManagerInternals is IModularAccount {
abstract contract ModuleManagerInternals is IERC6900Account {
using EnumerableSet for EnumerableSet.Bytes32Set;
using ModuleEntityLib for ModuleEntity;
using ValidationConfigLib for ValidationConfig;
Expand Down Expand Up @@ -67,7 +69,7 @@ abstract contract ModuleManagerInternals is IModularAccount {
revert NativeFunctionNotAllowed(selector);
}

// Make sure incoming execution function is not a function in IModule
// Make sure incoming execution function is not a function in IERC6900Module
if (KnownSelectorsLib.isIModuleFunction(selector)) {
revert IModuleFunctionNotAllowed(selector);
}
Expand Down Expand Up @@ -194,7 +196,7 @@ abstract contract ModuleManagerInternals is IModularAccount {
function _onInstall(address module, bytes calldata data) internal {
if (data.length > 0) {
// solhint-disable-next-line no-empty-blocks
try IModule(module).onInstall(data) {}
try IERC6900Module(module).onInstall(data) {}
catch {
bytes memory revertReason = collectReturnData();
revert ModuleInstallCallbackFailed(module, revertReason);
Expand All @@ -207,7 +209,7 @@ abstract contract ModuleManagerInternals is IModularAccount {
if (data.length > 0) {
// Clear the module storage for the account.
// solhint-disable-next-line no-empty-blocks
try IModule(module).onUninstall(data) {}
try IERC6900Module(module).onUninstall(data) {}
catch {
onUninstallSuccess = false;
}
Expand Down
64 changes: 34 additions & 30 deletions src/account/ReferenceModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,18 @@ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet
import {collectReturnData} from "../helpers/CollectReturnData.sol";
import {DIRECT_CALL_VALIDATION_ENTITY_ID} from "../helpers/Constants.sol";
import {_coalescePreValidation, _coalesceValidation} from "../helpers/ValidationResHelpers.sol";
import {IExecutionHookModule} from "../interfaces/IExecutionHookModule.sol";
import {ExecutionManifest} from "../interfaces/IExecutionModule.sol";

import {
Call,
IModularAccount,
IERC6900Account,
ModuleEntity,
ValidationConfig,
ValidationFlags
} from "../interfaces/IModularAccount.sol";
import {IValidationHookModule} from "../interfaces/IValidationHookModule.sol";
import {IValidationModule} from "../interfaces/IValidationModule.sol";
} from "../interfaces/IERC6900Account.sol";
import {IERC6900ExecutionHookModule} from "../interfaces/IERC6900ExecutionHookModule.sol";
import {ExecutionManifest} from "../interfaces/IERC6900ExecutionModule.sol";
import {IERC6900ValidationHookModule} from "../interfaces/IERC6900ValidationHookModule.sol";
import {IERC6900ValidationModule} from "../interfaces/IERC6900ValidationModule.sol";
import {HookConfig, HookConfigLib} from "../libraries/HookConfigLib.sol";
import {ModuleEntityLib} from "../libraries/ModuleEntityLib.sol";
import {SparseCalldataSegmentLib} from "../libraries/SparseCalldataSegmentLib.sol";
Expand All @@ -35,7 +36,7 @@ import {ModularAccountView} from "./ModularAccountView.sol";
import {ModuleManagerInternals} from "./ModuleManagerInternals.sol";

contract ReferenceModularAccount is
IModularAccount,
IERC6900Account,
AccountExecutor,
ModularAccountView,
AccountStorageInitializable,
Expand Down Expand Up @@ -159,7 +160,7 @@ contract ReferenceModularAccount is
_doCachedPostExecHooks(postValidatorExecHooks);
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation.
function execute(address target, uint256 value, bytes calldata data)
external
Expand All @@ -171,7 +172,7 @@ contract ReferenceModularAccount is
result = _exec(target, value, data);
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation function.
function executeBatch(Call[] calldata calls)
external
Expand All @@ -188,7 +189,7 @@ contract ReferenceModularAccount is
}
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
function executeWithRuntimeValidation(bytes calldata data, bytes calldata authorization)
external
payable
Expand Down Expand Up @@ -225,7 +226,7 @@ contract ReferenceModularAccount is
return returnData;
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation.
function installExecution(
address module,
Expand All @@ -235,7 +236,7 @@ contract ReferenceModularAccount is
_installExecution(module, manifest, moduleInstallData);
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation.
function uninstallExecution(
address module,
Expand All @@ -256,7 +257,7 @@ contract ReferenceModularAccount is
_installValidation(validationConfig, selectors, installData, hooks);
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation.
/// @dev This function can be used to update (to a certain degree) previously installed validation functions.
/// - preValidationHook, executionHooks, and selectors can be added later. Though they won't be deleted.
Expand All @@ -270,7 +271,7 @@ contract ReferenceModularAccount is
_installValidation(validationConfig, selectors, installData, hooks);
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
/// @notice May be validated by a global validation.
function uninstallValidation(
ModuleEntity validationFunction,
Expand All @@ -295,7 +296,7 @@ contract ReferenceModularAccount is
return getAccountStorage().supportedIfaces[interfaceId] > 0;
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
function accountId() external pure virtual returns (string memory) {
return "erc6900.reference-modular-account.0.8.0";
}
Expand Down Expand Up @@ -328,7 +329,7 @@ contract ReferenceModularAccount is
(currentSignatureSegment, signature) = signature.advanceSegmentIfAtIndex(uint8(i));

// If this reverts, bubble up revert reason.
IValidationHookModule(hookModule).preSignatureValidationHook(
IERC6900ValidationHookModule(hookModule).preSignatureValidationHook(
hookEntityId, msg.sender, hash, currentSignatureSegment
);
}
Expand Down Expand Up @@ -398,7 +399,7 @@ contract ReferenceModularAccount is

(address module, uint32 entityId) = preUserOpValidationHooks[i].moduleEntity().unpack();
uint256 currentValidationRes =
IValidationHookModule(module).preUserOpValidationHook(entityId, userOp, userOpHash);
IERC6900ValidationHookModule(module).preUserOpValidationHook(entityId, userOp, userOpHash);

if (uint160(currentValidationRes) > 1) {
// If the aggregator is not 0 or 1, it is an unexpected value
Expand Down Expand Up @@ -486,7 +487,7 @@ contract ReferenceModularAccount is
returns (bytes memory preExecHookReturnData)
{
(address module, uint32 entityId) = preExecHook.unpack();
try IExecutionHookModule(module).preExecutionHook(entityId, msg.sender, msg.value, data) returns (
try IERC6900ExecutionHookModule(module).preExecutionHook(entityId, msg.sender, msg.value, data) returns (
bytes memory returnData
) {
preExecHookReturnData = returnData;
Expand All @@ -511,12 +512,14 @@ contract ReferenceModularAccount is
}

(address module, uint32 entityId) = postHookToRun.postExecHook.unpack();
// solhint-disable-next-line no-empty-blocks
try IExecutionHookModule(module).postExecutionHook(entityId, postHookToRun.preExecHookReturnData) {}
catch {
/* solhint-disable no-empty-blocks */
try IERC6900ExecutionHookModule(module).postExecutionHook(
entityId, postHookToRun.preExecHookReturnData
) {} catch {
bytes memory revertReason = collectReturnData();
revert PostExecHookReverted(module, entityId, revertReason);
}
/* solhint-enable no-empty-blocks */
}
}

Expand All @@ -526,7 +529,7 @@ contract ReferenceModularAccount is
bytes memory currentAuthData
) internal {
(address hookModule, uint32 hookEntityId) = validationHook.unpack();
try IValidationHookModule(hookModule).preRuntimeValidationHook(
try IERC6900ValidationHookModule(hookModule).preRuntimeValidationHook(
hookEntityId, msg.sender, msg.value, callData, currentAuthData
)
// forgefmt: disable-start
Expand Down Expand Up @@ -608,7 +611,7 @@ contract ReferenceModularAccount is
revert UserOpValidationInvalid(module, entityId);
}

return IValidationModule(module).validateUserOp(entityId, userOp, userOpHash);
return IERC6900ValidationModule(module).validateUserOp(entityId, userOp, userOpHash);
}

function _execRuntimeValidation(
Expand All @@ -618,7 +621,7 @@ contract ReferenceModularAccount is
) internal virtual {
(address module, uint32 entityId) = runtimeValidationFunction.unpack();

try IValidationModule(module).validateRuntime(
try IERC6900ValidationModule(module).validateRuntime(
address(this), entityId, msg.sender, msg.value, callData, authorization
)
// forgefmt: disable-start
Expand All @@ -644,8 +647,9 @@ contract ReferenceModularAccount is
}

if (
IValidationModule(module).validateSignature(address(this), entityId, msg.sender, hash, signature)
== _1271_MAGIC_VALUE
IERC6900ValidationModule(module).validateSignature(
address(this), entityId, msg.sender, hash, signature
) == _1271_MAGIC_VALUE
) {
return _1271_MAGIC_VALUE;
}
Expand Down Expand Up @@ -684,15 +688,15 @@ contract ReferenceModularAccount is

_checkIfValidationAppliesSelector(outerSelector, validationFunction, checkingType);

if (outerSelector == IModularAccount.execute.selector) {
if (outerSelector == IERC6900Account.execute.selector) {
(address target,,) = abi.decode(callData[4:], (address, uint256, bytes));

if (target == address(this)) {
// There is no point to call `execute` to recurse exactly once - this is equivalent to just having
// the calldata as a top-level call.
revert SelfCallRecursionDepthExceeded();
}
} else if (outerSelector == IModularAccount.executeBatch.selector) {
} else if (outerSelector == IERC6900Account.executeBatch.selector) {
// executeBatch may be used to batch account actions together, by targetting the account itself.
// If this is done, we must ensure all of the inner calls are allowed by the provided validation
// function.
Expand All @@ -704,8 +708,8 @@ contract ReferenceModularAccount is
bytes4 nestedSelector = bytes4(calls[i].data);

if (
nestedSelector == IModularAccount.execute.selector
|| nestedSelector == IModularAccount.executeBatch.selector
nestedSelector == IERC6900Account.execute.selector
|| nestedSelector == IERC6900Account.executeBatch.selector
) {
// To prevent arbitrarily-deep recursive checking, we limit the depth of self-calls to one
// for the purposes of batching.
Expand Down
4 changes: 2 additions & 2 deletions src/account/SemiModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interface

import {ModuleEntityLib} from "../libraries/ModuleEntityLib.sol";

import {IModularAccount, ModuleEntity, ValidationConfig} from "../interfaces/IModularAccount.sol";
import {IERC6900Account, ModuleEntity, ValidationConfig} from "../interfaces/IERC6900Account.sol";

import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
Expand Down Expand Up @@ -91,7 +91,7 @@ contract SemiModularAccount is ReferenceModularAccount {
revert InitializerDisabled();
}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
function accountId() external pure virtual override returns (string memory) {
return "erc6900.reference-semi-modular-account.0.8.0";
}
Expand Down
4 changes: 2 additions & 2 deletions src/account/SemiModularAccount7702.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import {IModularAccount} from "../interfaces/IModularAccount.sol";
import {IERC6900Account} from "../interfaces/IERC6900Account.sol";
import {SemiModularAccount} from "./SemiModularAccount.sol";
import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol";

Expand All @@ -10,7 +10,7 @@ contract SemiModularAccount7702 is SemiModularAccount {

constructor(IEntryPoint anEntryPoint) SemiModularAccount(anEntryPoint) {}

/// @inheritdoc IModularAccount
/// @inheritdoc IERC6900Account
function accountId() external pure virtual override returns (string memory) {
return "erc6900.reference-semi-modular-account-7702.0.8.0";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.20;

import {ExecutionManifest} from "./IExecutionModule.sol";
import {ExecutionManifest} from "./IERC6900ExecutionModule.sol";

type ModuleEntity is bytes24;
// ModuleEntity is a packed representation of a module function
Expand Down Expand Up @@ -47,7 +47,7 @@ struct Call {
bytes data;
}

interface IModularAccount {
interface IERC6900Account {
event ExecutionInstalled(address indexed module, ExecutionManifest manifest);
event ExecutionUninstalled(address indexed module, bool onUninstallSucceeded, ExecutionManifest manifest);
event ValidationInstalled(address indexed module, uint32 indexed entityId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.20;

import {HookConfig, ModuleEntity, ValidationFlags} from "../interfaces/IModularAccount.sol";
import {HookConfig, ModuleEntity, ValidationFlags} from "../interfaces/IERC6900Account.sol";

/// @dev Represents data associated with a specific function selector.
struct ExecutionDataView {
Expand Down Expand Up @@ -34,7 +34,7 @@ struct ValidationDataView {
bytes4[] selectors;
}

interface IModularAccountView {
interface IERC6900AccountView {
/// @notice Get the execution data for a selector.
/// @dev If the selector is a native function, the module address will be the address of the account.
/// @param selector The selector to get the data for.
Expand Down
Loading
Loading