Skip to content

Commit e531ee4

Browse files
authored
feat: pack hook config (#169)
1 parent 3ca2c30 commit e531ee4

File tree

5 files changed

+43
-37
lines changed

5 files changed

+43
-37
lines changed

src/account/AccountStorage.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function toSetValue(HookConfig hookConfig) pure returns (bytes32) {
7676
}
7777

7878
function toHookConfig(bytes32 setValue) pure returns (HookConfig) {
79-
return HookConfig.wrap(bytes26(setValue));
79+
return HookConfig.wrap(bytes25(setValue));
8080
}
8181

8282
function toSetValue(bytes4 selector) pure returns (bytes32) {

src/account/ModularAccountView.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet
88
import {HookConfigLib} from "../helpers/HookConfigLib.sol";
99
import {HookConfig, IModularAccount, ModuleEntity} from "../interfaces/IModularAccount.sol";
1010
import {ExecutionDataView, IModularAccountView, ValidationDataView} from "../interfaces/IModularAccountView.sol";
11-
import {ExecutionData, ValidationData, getAccountStorage} from "./AccountStorage.sol";
11+
import {ExecutionData, ValidationData, getAccountStorage, toHookConfig} from "./AccountStorage.sol";
1212

1313
abstract contract ModularAccountView is IModularAccountView {
1414
using EnumerableSet for EnumerableSet.Bytes32Set;
@@ -34,7 +34,7 @@ abstract contract ModularAccountView is IModularAccountView {
3434
uint256 executionHooksLen = executionData.executionHooks.length();
3535
data.executionHooks = new HookConfig[](executionHooksLen);
3636
for (uint256 i = 0; i < executionHooksLen; ++i) {
37-
data.executionHooks[i] = HookConfig.wrap(bytes26(executionData.executionHooks.at(i)));
37+
data.executionHooks[i] = toHookConfig(executionData.executionHooks.at(i));
3838
}
3939
}
4040
}
@@ -55,7 +55,7 @@ abstract contract ModularAccountView is IModularAccountView {
5555
uint256 permissionHooksLen = validationData.permissionHooks.length();
5656
data.permissionHooks = new HookConfig[](permissionHooksLen);
5757
for (uint256 i = 0; i < permissionHooksLen; ++i) {
58-
data.permissionHooks[i] = HookConfig.wrap(bytes26(validationData.permissionHooks.at(i)));
58+
data.permissionHooks[i] = toHookConfig(validationData.permissionHooks.at(i));
5959
}
6060

6161
bytes32[] memory selectors = validationData.selectors.values();

src/account/ModuleManagerInternals.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ abstract contract ModuleManagerInternals is IModularAccount {
229229
ModuleEntity moduleEntity = validationConfig.moduleEntity();
230230

231231
for (uint256 i = 0; i < hooks.length; ++i) {
232-
HookConfig hookConfig = HookConfig.wrap(bytes26(hooks[i][:26]));
233-
bytes calldata hookData = hooks[i][26:];
232+
HookConfig hookConfig = HookConfig.wrap(bytes25(hooks[i][:25]));
233+
bytes calldata hookData = hooks[i][25:];
234234

235235
if (hookConfig.isValidationHook()) {
236236
_validationData.preValidationHooks.push(hookConfig.moduleEntity());

src/helpers/HookConfigLib.sol

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,13 @@ import {HookConfig, ModuleEntity} from "../interfaces/IModularAccount.sol";
1717
// Layout:
1818
// 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA________________________ // Address
1919
// 0x________________________________________BBBBBBBB________________ // Entity ID
20-
// 0x________________________________________________CC______________ // Type
21-
// 0x__________________________________________________DD____________ // exec hook flags
22-
//
20+
// 0x________________________________________________CC______________ // Hook Flags
2321

24-
// Hook types:
25-
// 0x00 // Exec (selector and validation associated)
26-
// 0x01 // Validation
27-
28-
// Exec hook flags layout:
29-
// 0b000000__ // unused
30-
// 0b______A_ // hasPre
31-
// 0b_______B // hasPost
22+
// Hook flags layout:
23+
// 0b00000___ // unused
24+
// 0b_____A__ // hasPre (exec only)
25+
// 0b______B_ // hasPost (exec only)
26+
// 0b_______C // hook type (0 for exec, 1 for validation)
3227

3328
library HookConfigLib {
3429
// Hook type constants
@@ -38,14 +33,14 @@ library HookConfigLib {
3833
bytes32 internal constant _HOOK_TYPE_VALIDATION = bytes32(uint256(1) << 56);
3934

4035
// Exec hook flags constants
41-
// Pre hook has 1 in 2's bit in the 26th byte
42-
bytes32 internal constant _EXEC_HOOK_HAS_PRE = bytes32(uint256(1) << 49);
43-
// Post hook has 1 in 1's bit in the 26th byte
44-
bytes32 internal constant _EXEC_HOOK_HAS_POST = bytes32(uint256(1) << 48);
36+
// Pre hook has 1 in 4's bit in the 25th byte
37+
bytes32 internal constant _EXEC_HOOK_HAS_PRE = bytes32(uint256(1) << 58);
38+
// Post hook has 1 in 2's bit in the 25th byte
39+
bytes32 internal constant _EXEC_HOOK_HAS_POST = bytes32(uint256(1) << 57);
4540

4641
function packValidationHook(ModuleEntity _hookFunction) internal pure returns (HookConfig) {
4742
return
48-
HookConfig.wrap(bytes26(bytes26(ModuleEntity.unwrap(_hookFunction)) | bytes26(_HOOK_TYPE_VALIDATION)));
43+
HookConfig.wrap(bytes25(bytes25(ModuleEntity.unwrap(_hookFunction)) | bytes25(_HOOK_TYPE_VALIDATION)));
4944
}
5045

5146
function packValidationHook(address _module, uint32 _entityId) internal pure returns (HookConfig) {
@@ -65,11 +60,11 @@ library HookConfigLib {
6560
returns (HookConfig)
6661
{
6762
return HookConfig.wrap(
68-
bytes26(
69-
bytes26(ModuleEntity.unwrap(_hookFunction))
70-
// | bytes26(_HOOK_TYPE_EXEC) // Can omit because exec type is 0
71-
| bytes26(_hasPre ? _EXEC_HOOK_HAS_PRE : bytes32(0))
72-
| bytes26(_hasPost ? _EXEC_HOOK_HAS_POST : bytes32(0))
63+
bytes25(
64+
bytes25(ModuleEntity.unwrap(_hookFunction))
65+
// | bytes25(_HOOK_TYPE_EXEC) // Can omit because exec type is 0
66+
| bytes25(_hasPre ? _EXEC_HOOK_HAS_PRE : bytes32(0))
67+
| bytes25(_hasPost ? _EXEC_HOOK_HAS_POST : bytes32(0))
7368
)
7469
);
7570
}
@@ -80,20 +75,20 @@ library HookConfigLib {
8075
returns (HookConfig)
8176
{
8277
return HookConfig.wrap(
83-
bytes26(
78+
bytes25(
8479
// module address stored in the first 20 bytes
85-
bytes26(bytes20(_module))
80+
bytes25(bytes20(_module))
8681
// entityId stored in the 21st - 24th byte
87-
| bytes26(bytes24(uint192(_entityId)))
88-
// | bytes26(_HOOK_TYPE_EXEC) // Can omit because exec type is 0
89-
| bytes26(_hasPre ? _EXEC_HOOK_HAS_PRE : bytes32(0))
90-
| bytes26(_hasPost ? _EXEC_HOOK_HAS_POST : bytes32(0))
82+
| bytes25(bytes24(uint192(_entityId)))
83+
// | bytes25(_HOOK_TYPE_EXEC) // Can omit because exec type is 0
84+
| bytes25(_hasPre ? _EXEC_HOOK_HAS_PRE : bytes32(0))
85+
| bytes25(_hasPost ? _EXEC_HOOK_HAS_POST : bytes32(0))
9186
)
9287
);
9388
}
9489

9590
function unpackValidationHook(HookConfig _config) internal pure returns (ModuleEntity _hookFunction) {
96-
bytes26 configBytes = HookConfig.unwrap(_config);
91+
bytes25 configBytes = HookConfig.unwrap(_config);
9792
_hookFunction = ModuleEntity.wrap(bytes24(configBytes));
9893
}
9994

@@ -102,7 +97,7 @@ library HookConfigLib {
10297
pure
10398
returns (ModuleEntity _hookFunction, bool _hasPre, bool _hasPost)
10499
{
105-
bytes26 configBytes = HookConfig.unwrap(_config);
100+
bytes25 configBytes = HookConfig.unwrap(_config);
106101
_hookFunction = ModuleEntity.wrap(bytes24(configBytes));
107102
_hasPre = configBytes & _EXEC_HOOK_HAS_PRE != 0;
108103
_hasPost = configBytes & _EXEC_HOOK_HAS_POST != 0;

src/interfaces/IModularAccount.sol

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,18 @@ type ValidationConfig is bytes25;
2424
// 0b______B_ // isSignatureValidation
2525
// 0b_______C // isUserOpValidation
2626

27-
type HookConfig is bytes26;
27+
type HookConfig is bytes25;
28+
// HookConfig is a packed representation of a hook function and flags for its configuration.
29+
// Layout:
30+
// 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA________________________ // Address
31+
// 0x________________________________________BBBBBBBB________________ // Entity ID
32+
// 0x________________________________________________CC______________ // Hook Flags
33+
//
34+
// Hook flags layout:
35+
// 0b00000___ // unused
36+
// 0b_____A__ // hasPre (exec only)
37+
// 0b______B_ // hasPost (exec only)
38+
// 0b_______C // hook type (0 for exec, 1 for validation)
2839

2940
struct Call {
3041
// The target address for the account to call.
@@ -82,7 +93,7 @@ interface IModularAccount {
8293
/// @param selectors The selectors to install the validation function for.
8394
/// @param installData Optional data to be decoded and used by the module to setup initial module state.
8495
/// @param hooks Optional hooks to install, associated with the validation function. These may be
85-
/// pre validation hooks or execution hooks. The expected format is a bytes26 HookConfig, followed by the
96+
/// pre validation hooks or execution hooks. The expected format is a bytes25 HookConfig, followed by the
8697
/// install data, if any.
8798
function installValidation(
8899
ValidationConfig validationConfig,

0 commit comments

Comments
 (0)