Skip to content

Commit d666f50

Browse files
authored
feat: Remove hook group (#39)
1 parent a641a76 commit d666f50

File tree

5 files changed

+32
-52
lines changed

5 files changed

+32
-52
lines changed

foundry.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ libs = ['lib']
77
out = 'out'
88
optimizer = true
99
optimizer_runs = 200
10-
ignored_error_codes = []
1110
fs_permissions = [
1211
{ access = "read", path = "./out-optimized" }
1312
]

src/account/AccountLoupe.sol

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet
88
import {IAccountLoupe} from "../interfaces/IAccountLoupe.sol";
99
import {FunctionReference, IPluginManager} from "../interfaces/IPluginManager.sol";
1010
import {IStandardExecutor} from "../interfaces/IStandardExecutor.sol";
11-
import {AccountStorage, getAccountStorage, HookGroup, toFunctionReferenceArray} from "./AccountStorage.sol";
11+
import {AccountStorage, getAccountStorage, SelectorData, toFunctionReferenceArray} from "./AccountStorage.sol";
1212

1313
abstract contract AccountLoupe is IAccountLoupe {
1414
using EnumerableMap for EnumerableMap.Bytes32ToUintMap;
@@ -43,14 +43,14 @@ abstract contract AccountLoupe is IAccountLoupe {
4343

4444
/// @inheritdoc IAccountLoupe
4545
function getExecutionHooks(bytes4 selector) external view returns (ExecutionHooks[] memory execHooks) {
46-
HookGroup storage hooks = getAccountStorage().selectorData[selector].executionHooks;
47-
uint256 preExecHooksLength = hooks.preHooks.length();
48-
uint256 postOnlyExecHooksLength = hooks.postOnlyHooks.length();
46+
SelectorData storage selectorData = getAccountStorage().selectorData[selector];
47+
uint256 preExecHooksLength = selectorData.preHooks.length();
48+
uint256 postOnlyExecHooksLength = selectorData.postOnlyHooks.length();
4949
uint256 maxExecHooksLength = postOnlyExecHooksLength;
5050

5151
// There can only be as many associated post hooks to run as there are pre hooks.
5252
for (uint256 i = 0; i < preExecHooksLength;) {
53-
(, uint256 count) = hooks.preHooks.at(i);
53+
(, uint256 count) = selectorData.preHooks.at(i);
5454
unchecked {
5555
maxExecHooksLength += (count + 1);
5656
++i;
@@ -62,14 +62,14 @@ abstract contract AccountLoupe is IAccountLoupe {
6262
uint256 actualExecHooksLength;
6363

6464
for (uint256 i = 0; i < preExecHooksLength;) {
65-
(bytes32 key,) = hooks.preHooks.at(i);
65+
(bytes32 key,) = selectorData.preHooks.at(i);
6666
FunctionReference preExecHook = FunctionReference.wrap(bytes21(key));
6767

68-
uint256 associatedPostExecHooksLength = hooks.associatedPostHooks[preExecHook].length();
68+
uint256 associatedPostExecHooksLength = selectorData.associatedPostHooks[preExecHook].length();
6969
if (associatedPostExecHooksLength > 0) {
7070
for (uint256 j = 0; j < associatedPostExecHooksLength;) {
7171
execHooks[actualExecHooksLength].preExecHook = preExecHook;
72-
(key,) = hooks.associatedPostHooks[preExecHook].at(j);
72+
(key,) = selectorData.associatedPostHooks[preExecHook].at(j);
7373
execHooks[actualExecHooksLength].postExecHook = FunctionReference.wrap(bytes21(key));
7474

7575
unchecked {
@@ -91,7 +91,7 @@ abstract contract AccountLoupe is IAccountLoupe {
9191
}
9292

9393
for (uint256 i = 0; i < postOnlyExecHooksLength;) {
94-
(bytes32 key,) = hooks.postOnlyHooks.at(i);
94+
(bytes32 key,) = selectorData.postOnlyHooks.at(i);
9595
execHooks[actualExecHooksLength].postExecHook = FunctionReference.wrap(bytes21(key));
9696

9797
unchecked {

src/account/AccountStorage.sol

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ bytes32 constant _ACCOUNT_STORAGE_SLOT = 0x9f09680beaa4e5c9f38841db2460c40149916
1212

1313
struct PluginData {
1414
bool anyExternalExecPermitted;
15-
// boolean to indicate if the plugin can spend native tokens, if any of the execution function can spend
16-
// native tokens, a plugin is considered to be able to spend native tokens of the accounts
15+
// boolean to indicate if the plugin can spend native tokens from the account.
1716
bool canSpendNativeToken;
1817
bytes32 manifestHash;
1918
FunctionReference[] dependencies;
@@ -31,14 +30,6 @@ struct PermittedExternalCallData {
3130
mapping(bytes4 => bool) permittedSelectors;
3231
}
3332

34-
// Represets a set of pre- and post- hooks.
35-
struct HookGroup {
36-
EnumerableMap.Bytes32ToUintMap preHooks;
37-
// bytes21 key = pre hook function reference
38-
mapping(FunctionReference => EnumerableMap.Bytes32ToUintMap) associatedPostHooks;
39-
EnumerableMap.Bytes32ToUintMap postOnlyHooks;
40-
}
41-
4233
// Represents data associated with a specifc function selector.
4334
struct SelectorData {
4435
// The plugin that implements this execution function.
@@ -50,7 +41,10 @@ struct SelectorData {
5041
EnumerableMap.Bytes32ToUintMap preUserOpValidationHooks;
5142
EnumerableMap.Bytes32ToUintMap preRuntimeValidationHooks;
5243
// The execution hooks for this function selector.
53-
HookGroup executionHooks;
44+
EnumerableMap.Bytes32ToUintMap preHooks;
45+
// bytes21 key = pre hook function reference
46+
mapping(FunctionReference => EnumerableMap.Bytes32ToUintMap) associatedPostHooks;
47+
EnumerableMap.Bytes32ToUintMap postOnlyHooks;
5448
}
5549

5650
struct AccountStorage {

src/account/PluginManagerInternals.sol

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
getAccountStorage,
2222
SelectorData,
2323
getPermittedCallKey,
24-
HookGroup,
2524
PermittedExternalCallData
2625
} from "./AccountStorage.sol";
2726

@@ -126,50 +125,38 @@ abstract contract PluginManagerInternals is IPluginManager {
126125
{
127126
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];
128127

129-
_addHooks(_selectorData.executionHooks, preExecHook, postExecHook);
130-
}
131-
132-
function _removeExecHooks(bytes4 selector, FunctionReference preExecHook, FunctionReference postExecHook)
133-
internal
134-
{
135-
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];
136-
137-
_removeHooks(_selectorData.executionHooks, preExecHook, postExecHook);
138-
}
139-
140-
function _addHooks(HookGroup storage hooks, FunctionReference preExecHook, FunctionReference postExecHook)
141-
internal
142-
{
143128
if (!preExecHook.isEmpty()) {
144-
_addOrIncrement(hooks.preHooks, _toSetValue(preExecHook));
129+
_addOrIncrement(_selectorData.preHooks, _toSetValue(preExecHook));
145130

146131
if (!postExecHook.isEmpty()) {
147-
_addOrIncrement(hooks.associatedPostHooks[preExecHook], _toSetValue(postExecHook));
132+
_addOrIncrement(_selectorData.associatedPostHooks[preExecHook], _toSetValue(postExecHook));
148133
}
149134
} else {
150135
if (postExecHook.isEmpty()) {
151136
// both pre and post hooks cannot be null
152137
revert NullFunctionReference();
153138
}
154139

155-
_addOrIncrement(hooks.postOnlyHooks, _toSetValue(postExecHook));
140+
_addOrIncrement(_selectorData.postOnlyHooks, _toSetValue(postExecHook));
156141
}
157142
}
158143

159-
function _removeHooks(HookGroup storage hooks, FunctionReference preExecHook, FunctionReference postExecHook)
144+
function _removeExecHooks(bytes4 selector, FunctionReference preExecHook, FunctionReference postExecHook)
160145
internal
161146
{
147+
SelectorData storage _selectorData = getAccountStorage().selectorData[selector];
148+
162149
if (!preExecHook.isEmpty()) {
163-
_removeOrDecrement(hooks.preHooks, _toSetValue(preExecHook));
150+
_removeOrDecrement(_selectorData.preHooks, _toSetValue(preExecHook));
164151

165152
if (!postExecHook.isEmpty()) {
166-
_removeOrDecrement(hooks.associatedPostHooks[preExecHook], _toSetValue(postExecHook));
153+
_removeOrDecrement(_selectorData.associatedPostHooks[preExecHook], _toSetValue(postExecHook));
167154
}
168155
} else {
169156
// The case where both pre and post hooks are null was checked during installation.
170157

171158
// May ignore return value, as the manifest hash is validated to ensure that the hook exists.
172-
_removeOrDecrement(hooks.postOnlyHooks, _toSetValue(postExecHook));
159+
_removeOrDecrement(_selectorData.postOnlyHooks, _toSetValue(postExecHook));
173160
}
174161
}
175162

src/account/UpgradeableModularAccount.sol

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {FunctionReference, IPluginManager} from "../interfaces/IPluginManager.so
1717
import {IStandardExecutor, Call} from "../interfaces/IStandardExecutor.sol";
1818
import {AccountExecutor} from "./AccountExecutor.sol";
1919
import {AccountLoupe} from "./AccountLoupe.sol";
20-
import {AccountStorage, HookGroup, getAccountStorage, getPermittedCallKey} from "./AccountStorage.sol";
20+
import {AccountStorage, getAccountStorage, getPermittedCallKey, SelectorData} from "./AccountStorage.sol";
2121
import {AccountStorageInitializable} from "./AccountStorageInitializable.sol";
2222
import {PluginManagerInternals} from "./PluginManagerInternals.sol";
2323

@@ -459,14 +459,14 @@ contract UpgradeableModularAccount is
459459
internal
460460
returns (PostExecToRun[] memory postHooksToRun)
461461
{
462-
HookGroup storage hooks = getAccountStorage().selectorData[selector].executionHooks;
463-
uint256 preExecHooksLength = hooks.preHooks.length();
464-
uint256 postOnlyHooksLength = hooks.postOnlyHooks.length();
462+
SelectorData storage selectorData = getAccountStorage().selectorData[selector];
463+
uint256 preExecHooksLength = selectorData.preHooks.length();
464+
uint256 postOnlyHooksLength = selectorData.postOnlyHooks.length();
465465
uint256 maxPostExecHooksLength = postOnlyHooksLength;
466466

467467
// There can only be as many associated post hooks to run as there are pre hooks.
468468
for (uint256 i = 0; i < preExecHooksLength;) {
469-
(, uint256 count) = hooks.preHooks.at(i);
469+
(, uint256 count) = selectorData.preHooks.at(i);
470470
unchecked {
471471
maxPostExecHooksLength += (count + 1);
472472
++i;
@@ -479,7 +479,7 @@ contract UpgradeableModularAccount is
479479

480480
// Copy post-only hooks to the array.
481481
for (uint256 i = 0; i < postOnlyHooksLength;) {
482-
(bytes32 key,) = hooks.postOnlyHooks.at(i);
482+
(bytes32 key,) = selectorData.postOnlyHooks.at(i);
483483
postHooksToRun[actualPostHooksToRunLength].postExecHook = _toFunctionReference(key);
484484
unchecked {
485485
++actualPostHooksToRunLength;
@@ -490,7 +490,7 @@ contract UpgradeableModularAccount is
490490
// Then run the pre hooks and copy the associated post hooks (along with their pre hook's return data) to
491491
// the array.
492492
for (uint256 i = 0; i < preExecHooksLength;) {
493-
(bytes32 key,) = hooks.preHooks.at(i);
493+
(bytes32 key,) = selectorData.preHooks.at(i);
494494
FunctionReference preExecHook = _toFunctionReference(key);
495495

496496
if (preExecHook.isEmptyOrMagicValue()) {
@@ -501,10 +501,10 @@ contract UpgradeableModularAccount is
501501

502502
bytes memory preExecHookReturnData = _runPreExecHook(preExecHook, data);
503503

504-
uint256 associatedPostExecHooksLength = hooks.associatedPostHooks[preExecHook].length();
504+
uint256 associatedPostExecHooksLength = selectorData.associatedPostHooks[preExecHook].length();
505505
if (associatedPostExecHooksLength > 0) {
506506
for (uint256 j = 0; j < associatedPostExecHooksLength;) {
507-
(key,) = hooks.associatedPostHooks[preExecHook].at(j);
507+
(key,) = selectorData.associatedPostHooks[preExecHook].at(j);
508508
postHooksToRun[actualPostHooksToRunLength].postExecHook = _toFunctionReference(key);
509509
postHooksToRun[actualPostHooksToRunLength].preExecHookReturnData = preExecHookReturnData;
510510

0 commit comments

Comments
 (0)