-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathAccountStorage.sol
More file actions
99 lines (83 loc) · 3.78 KB
/
AccountStorage.sol
File metadata and controls
99 lines (83 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {HookConfig, ModuleEntity, ValidationFlags} from "../interfaces/IModularAccount.sol";
// bytes = keccak256("ERC6900.ReferenceModularAccount.Storage")
bytes32 constant _ACCOUNT_STORAGE_SLOT = 0xc531f081ecdb5a90f38c197521797881a6e5c752a7d451780f325a95f8b91f45;
// Represents data associated with a specifc function selector.
struct ExecutionStorage {
// The module that implements this execution function.
// If this is a native function, the address must remain address(0).
address module;
// Whether or not the function needs runtime validation, or can be called by anyone. The function can still be
// state changing if this flag is set to true.
// Note that even if this is set to true, user op validation will still be required, otherwise anyone could
// drain the account of native tokens by wasting gas.
bool skipRuntimeValidation;
// Whether or not a global validation function may be used to validate this function.
bool allowGlobalValidation;
// The execution hooks for this function selector.
EnumerableSet.Bytes32Set executionHooks;
}
struct ValidationStorage {
// ValidationFlags layout:
// 0b00000___ // unused
// 0b_____A__ // isGlobal
// 0b______B_ // isSignatureValidation
// 0b_______C // isUserOpValidation
ValidationFlags validationFlags;
// The validation hooks for this validation function.
HookConfig[] validationHooks;
// Execution hooks associated with this entity, to be run when this validation is used.
EnumerableSet.Bytes32Set executionHooks;
// The set of selectors that may be validated by this validation function.
EnumerableSet.Bytes32Set selectors;
}
struct AccountStorage {
// AccountStorageInitializable variables
uint8 initialized;
bool initializing;
// Execution functions and their associated functions
mapping(bytes4 selector => ExecutionStorage) executionStorage;
mapping(ModuleEntity validationFunction => ValidationStorage) validationStorage;
// For ERC165 introspection
mapping(bytes4 => uint256) supportedIfaces;
}
function getAccountStorage() pure returns (AccountStorage storage _storage) {
assembly ("memory-safe") {
_storage.slot := _ACCOUNT_STORAGE_SLOT
}
}
using EnumerableSet for EnumerableSet.Bytes32Set;
function toSetValue(ModuleEntity moduleEntity) pure returns (bytes32) {
return bytes32(ModuleEntity.unwrap(moduleEntity));
}
function toModuleEntity(bytes32 setValue) pure returns (ModuleEntity) {
return ModuleEntity.wrap(bytes24(setValue));
}
// ExecutionHook layout:
// 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF______________________ Hook Module Entity
// 0x________________________________________________AA____________________ is pre hook
// 0x__________________________________________________BB__________________ is post hook
function toSetValue(HookConfig hookConfig) pure returns (bytes32) {
return bytes32(HookConfig.unwrap(hookConfig));
}
function toHookConfig(bytes32 setValue) pure returns (HookConfig) {
return HookConfig.wrap(bytes25(setValue));
}
function toSetValue(bytes4 selector) pure returns (bytes32) {
return bytes32(selector);
}
function toSelector(bytes32 setValue) pure returns (bytes4) {
return bytes4(setValue);
}
/// @dev Helper function to get all elements of a set into memory.
function toModuleEntityArray(EnumerableSet.Bytes32Set storage set) view returns (ModuleEntity[] memory) {
uint256 length = set.length();
ModuleEntity[] memory result = new ModuleEntity[](length);
for (uint256 i = 0; i < length; ++i) {
bytes32 key = set.at(i);
result[i] = ModuleEntity.wrap(bytes24(key));
}
return result;
}