@erc6900/reference-implementation 0.8.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @erc6900/reference-implementation might be problematic. Click here for more details.

Files changed (39) hide show
  1. package/package.json +5 -26
  2. package/preinstall.js +110 -0
  3. package/LICENSE +0 -21
  4. package/README.md +0 -76
  5. package/src/account/AccountExecutor.sol +0 -20
  6. package/src/account/AccountFactory.sol +0 -126
  7. package/src/account/AccountStorage.sol +0 -99
  8. package/src/account/AccountStorageInitializable.sol +0 -67
  9. package/src/account/ModularAccountView.sol +0 -66
  10. package/src/account/ModuleManagerInternals.sol +0 -325
  11. package/src/account/ReferenceModularAccount.sol +0 -769
  12. package/src/account/SemiModularAccount.sol +0 -214
  13. package/src/account/SemiModularAccount7702.sol +0 -38
  14. package/src/helpers/CollectReturnData.sol +0 -14
  15. package/src/helpers/Constants.sol +0 -11
  16. package/src/helpers/EmptyCalldataSlice.sol +0 -12
  17. package/src/helpers/ValidationResHelpers.sol +0 -50
  18. package/src/interfaces/IERC6900Account.sol +0 -127
  19. package/src/interfaces/IERC6900AccountView.sol +0 -52
  20. package/src/interfaces/IERC6900ExecutionHookModule.sol +0 -26
  21. package/src/interfaces/IERC6900ExecutionModule.sol +0 -37
  22. package/src/interfaces/IERC6900Module.sol +0 -24
  23. package/src/interfaces/IERC6900ValidationHookModule.sol +0 -46
  24. package/src/interfaces/IERC6900ValidationModule.sol +0 -53
  25. package/src/libraries/HookConfigLib.sol +0 -135
  26. package/src/libraries/KnownSelectorsLib.sol +0 -65
  27. package/src/libraries/ModuleEntityLib.sol +0 -37
  28. package/src/libraries/ModuleStorageLib.sol +0 -62
  29. package/src/libraries/SparseCalldataSegmentLib.sol +0 -95
  30. package/src/libraries/ValidationConfigLib.sol +0 -119
  31. package/src/modules/BaseModule.sol +0 -54
  32. package/src/modules/ModuleEIP712.sol +0 -29
  33. package/src/modules/ReplaySafeWrapper.sol +0 -38
  34. package/src/modules/TokenReceiverModule.sol +0 -87
  35. package/src/modules/permissions/AllowlistModule.sol +0 -156
  36. package/src/modules/permissions/ERC20TokenLimitModule.sol +0 -145
  37. package/src/modules/permissions/NativeTokenLimitModule.sol +0 -154
  38. package/src/modules/validation/ISingleSignerValidationModule.sol +0 -22
  39. package/src/modules/validation/SingleSignerValidationModule.sol +0 -138
@@ -1,53 +0,0 @@
1
- // SPDX-License-Identifier: CC0-1.0
2
- pragma solidity ^0.8.20;
3
-
4
- import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol";
5
-
6
- import {IERC6900Module} from "./IERC6900Module.sol";
7
-
8
- interface IERC6900ValidationModule is IERC6900Module {
9
- /// @notice Run the user operation validation function specified by the `entityId`.
10
- /// @param entityId An identifier that routes the call to different internal implementations, should there
11
- /// be more than one.
12
- /// @param userOp The user operation.
13
- /// @param userOpHash The user operation hash.
14
- /// @return Packed validation data for validAfter (6 bytes), validUntil (6 bytes), and authorizer (20 bytes).
15
- function validateUserOp(uint32 entityId, PackedUserOperation calldata userOp, bytes32 userOpHash)
16
- external
17
- returns (uint256);
18
-
19
- /// @notice Run the runtime validation function specified by the `entityId`.
20
- /// @dev To indicate the entire call should revert, the function MUST revert.
21
- /// @param account The account to validate for.
22
- /// @param entityId An identifier that routes the call to different internal implementations, should there
23
- /// be more than one.
24
- /// @param sender The caller address.
25
- /// @param value The call value.
26
- /// @param data The calldata sent.
27
- /// @param authorization Additional data for the validation function to use.
28
- function validateRuntime(
29
- address account,
30
- uint32 entityId,
31
- address sender,
32
- uint256 value,
33
- bytes calldata data,
34
- bytes calldata authorization
35
- ) external;
36
-
37
- /// @notice Validates a signature using ERC-1271.
38
- /// @dev To indicate the entire call should revert, the function MUST revert.
39
- /// @param account The account to validate for.
40
- /// @param entityId An identifier that routes the call to different internal implementations, should there
41
- /// be more than one.
42
- /// @param sender The address that sent the ERC-1271 request to the smart account.
43
- /// @param hash The hash of the ERC-1271 request.
44
- /// @param signature The signature of the ERC-1271 request.
45
- /// @return The ERC-1271 `MAGIC_VALUE` if the signature is valid, or 0xFFFFFFFF if invalid.
46
- function validateSignature(
47
- address account,
48
- uint32 entityId,
49
- address sender,
50
- bytes32 hash,
51
- bytes calldata signature
52
- ) external view returns (bytes4);
53
- }
@@ -1,135 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {HookConfig, ModuleEntity} from "../interfaces/IERC6900Account.sol";
5
-
6
- // Hook types:
7
- // Exec hook: bools for hasPre, hasPost
8
- // Validation hook: no bools
9
-
10
- // Hook fields:
11
- // module address
12
- // entity ID
13
- // hook type
14
- // if exec hook: hasPre, hasPost
15
-
16
- // Hook config is a packed representation of a hook function and flags for its configuration.
17
- // Layout:
18
- // 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA________________________ // Address
19
- // 0x________________________________________BBBBBBBB________________ // Entity ID
20
- // 0x________________________________________________CC______________ // Hook Flags
21
-
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)
27
-
28
- library HookConfigLib {
29
- // Hook type constants
30
- // Exec has no bits set
31
- bytes32 internal constant _HOOK_TYPE_EXEC = bytes32(uint256(0));
32
- // Validation has 1 in the 25th byte
33
- bytes32 internal constant _HOOK_TYPE_VALIDATION = bytes32(uint256(1) << 56);
34
-
35
- // Exec hook flags constants
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);
40
-
41
- function packValidationHook(ModuleEntity _hookFunction) internal pure returns (HookConfig) {
42
- return
43
- HookConfig.wrap(bytes25(bytes25(ModuleEntity.unwrap(_hookFunction)) | bytes25(_HOOK_TYPE_VALIDATION)));
44
- }
45
-
46
- function packValidationHook(address _module, uint32 _entityId) internal pure returns (HookConfig) {
47
- return HookConfig.wrap(
48
- bytes25(
49
- // module address stored in the first 20 bytes
50
- bytes25(bytes20(_module))
51
- // entityId stored in the 21st - 24th byte
52
- | bytes25(bytes24(uint192(_entityId))) | bytes25(_HOOK_TYPE_VALIDATION)
53
- )
54
- );
55
- }
56
-
57
- function packExecHook(ModuleEntity _hookFunction, bool _hasPre, bool _hasPost)
58
- internal
59
- pure
60
- returns (HookConfig)
61
- {
62
- return HookConfig.wrap(
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))
68
- )
69
- );
70
- }
71
-
72
- function packExecHook(address _module, uint32 _entityId, bool _hasPre, bool _hasPost)
73
- internal
74
- pure
75
- returns (HookConfig)
76
- {
77
- return HookConfig.wrap(
78
- bytes25(
79
- // module address stored in the first 20 bytes
80
- bytes25(bytes20(_module))
81
- // entityId stored in the 21st - 24th byte
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))
86
- )
87
- );
88
- }
89
-
90
- function unpackValidationHook(HookConfig _config) internal pure returns (ModuleEntity _hookFunction) {
91
- bytes25 configBytes = HookConfig.unwrap(_config);
92
- _hookFunction = ModuleEntity.wrap(bytes24(configBytes));
93
- }
94
-
95
- function unpackExecHook(HookConfig _config)
96
- internal
97
- pure
98
- returns (ModuleEntity _hookFunction, bool _hasPre, bool _hasPost)
99
- {
100
- bytes25 configBytes = HookConfig.unwrap(_config);
101
- _hookFunction = ModuleEntity.wrap(bytes24(configBytes));
102
- _hasPre = configBytes & _EXEC_HOOK_HAS_PRE != 0;
103
- _hasPost = configBytes & _EXEC_HOOK_HAS_POST != 0;
104
- }
105
-
106
- function module(HookConfig _config) internal pure returns (address) {
107
- return address(bytes20(HookConfig.unwrap(_config)));
108
- }
109
-
110
- function entityId(HookConfig _config) internal pure returns (uint32) {
111
- return uint32(bytes4(HookConfig.unwrap(_config) << 160));
112
- }
113
-
114
- function moduleEntity(HookConfig _config) internal pure returns (ModuleEntity) {
115
- return ModuleEntity.wrap(bytes24(HookConfig.unwrap(_config)));
116
- }
117
-
118
- // Check if the hook is a validation hook
119
- // If false, it is an exec hook
120
- function isValidationHook(HookConfig _config) internal pure returns (bool) {
121
- return HookConfig.unwrap(_config) & _HOOK_TYPE_VALIDATION != 0;
122
- }
123
-
124
- // Check if the exec hook has a pre hook
125
- // Undefined behavior if the hook is not an exec hook
126
- function hasPreHook(HookConfig _config) internal pure returns (bool) {
127
- return HookConfig.unwrap(_config) & _EXEC_HOOK_HAS_PRE != 0;
128
- }
129
-
130
- // Check if the exec hook has a post hook
131
- // Undefined behavior if the hook is not an exec hook
132
- function hasPostHook(HookConfig _config) internal pure returns (bool) {
133
- return HookConfig.unwrap(_config) & _EXEC_HOOK_HAS_POST != 0;
134
- }
135
- }
@@ -1,65 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {IAccount} from "@eth-infinitism/account-abstraction/interfaces/IAccount.sol";
5
- import {IAggregator} from "@eth-infinitism/account-abstraction/interfaces/IAggregator.sol";
6
- import {IPaymaster} from "@eth-infinitism/account-abstraction/interfaces/IPaymaster.sol";
7
- import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
8
- import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
9
-
10
- import {IERC6900Account} from "../interfaces/IERC6900Account.sol";
11
-
12
- import {IERC6900AccountView} from "../interfaces/IERC6900AccountView.sol";
13
-
14
- import {IERC6900ExecutionHookModule} from "../interfaces/IERC6900ExecutionHookModule.sol";
15
-
16
- import {IERC6900ExecutionModule} from "../interfaces/IERC6900ExecutionModule.sol";
17
- import {IERC6900Module} from "../interfaces/IERC6900Module.sol";
18
- import {IERC6900ValidationHookModule} from "../interfaces/IERC6900ValidationHookModule.sol";
19
- import {IERC6900ValidationModule} from "../interfaces/IERC6900ValidationModule.sol";
20
-
21
- /// @dev Library to help to check if a selector is a know function selector of the modular account or ERC-4337
22
- /// contract.
23
- library KnownSelectorsLib {
24
- function isNativeFunction(bytes4 selector) internal pure returns (bool) {
25
- return
26
- // check against IAccount methods
27
- selector == IAccount.validateUserOp.selector
28
- // check against IERC6900Account methods
29
- || selector == IERC6900Account.installExecution.selector
30
- || selector == IERC6900Account.uninstallExecution.selector
31
- || selector == IERC6900Account.installValidation.selector
32
- || selector == IERC6900Account.uninstallValidation.selector || selector == IERC6900Account.execute.selector
33
- || selector == IERC6900Account.executeBatch.selector
34
- || selector == IERC6900Account.executeWithRuntimeValidation.selector
35
- || selector == IERC6900Account.accountId.selector
36
- // check against IERC165 methods
37
- || selector == IERC165.supportsInterface.selector
38
- // check against UUPSUpgradeable methods
39
- || selector == UUPSUpgradeable.proxiableUUID.selector
40
- || selector == UUPSUpgradeable.upgradeToAndCall.selector
41
- // check against IERC6900AccountView methods
42
- || selector == IERC6900AccountView.getExecutionData.selector
43
- || selector == IERC6900AccountView.getValidationData.selector;
44
- }
45
-
46
- function isErc4337Function(bytes4 selector) internal pure returns (bool) {
47
- return selector == IAggregator.validateSignatures.selector
48
- || selector == IAggregator.validateUserOpSignature.selector
49
- || selector == IAggregator.aggregateSignatures.selector
50
- || selector == IPaymaster.validatePaymasterUserOp.selector || selector == IPaymaster.postOp.selector;
51
- }
52
-
53
- function isIModuleFunction(bytes4 selector) internal pure returns (bool) {
54
- return selector == IERC6900Module.onInstall.selector || selector == IERC6900Module.onUninstall.selector
55
- || selector == IERC6900Module.moduleId.selector
56
- || selector == IERC6900ExecutionModule.executionManifest.selector
57
- || selector == IERC6900ExecutionHookModule.preExecutionHook.selector
58
- || selector == IERC6900ExecutionHookModule.postExecutionHook.selector
59
- || selector == IERC6900ValidationModule.validateUserOp.selector
60
- || selector == IERC6900ValidationModule.validateRuntime.selector
61
- || selector == IERC6900ValidationModule.validateSignature.selector
62
- || selector == IERC6900ValidationHookModule.preUserOpValidationHook.selector
63
- || selector == IERC6900ValidationHookModule.preRuntimeValidationHook.selector;
64
- }
65
- }
@@ -1,37 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {ModuleEntity} from "../interfaces/IERC6900Account.sol";
5
- // ModuleEntity is a packed representation of a module function
6
- // Layout:
7
- // 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA________________________ // Address
8
- // 0x________________________________________BBBBBBBB________________ // Entity ID
9
- // 0x________________________________________________0000000000000000 // unused
10
-
11
- library ModuleEntityLib {
12
- function pack(address addr, uint32 entityId) internal pure returns (ModuleEntity) {
13
- return ModuleEntity.wrap(bytes24(bytes20(addr)) | bytes24(uint192(entityId)));
14
- }
15
-
16
- function unpack(ModuleEntity moduleEntity) internal pure returns (address addr, uint32 entityId) {
17
- bytes24 underlying = ModuleEntity.unwrap(moduleEntity);
18
- addr = address(bytes20(underlying));
19
- entityId = uint32(bytes4(underlying << 160));
20
- }
21
-
22
- function isEmpty(ModuleEntity moduleEntity) internal pure returns (bool) {
23
- return ModuleEntity.unwrap(moduleEntity) == bytes24(0);
24
- }
25
-
26
- function notEmpty(ModuleEntity moduleEntity) internal pure returns (bool) {
27
- return ModuleEntity.unwrap(moduleEntity) != bytes24(0);
28
- }
29
-
30
- function eq(ModuleEntity a, ModuleEntity b) internal pure returns (bool) {
31
- return ModuleEntity.unwrap(a) == ModuleEntity.unwrap(b);
32
- }
33
-
34
- function notEq(ModuleEntity a, ModuleEntity b) internal pure returns (bool) {
35
- return ModuleEntity.unwrap(a) != ModuleEntity.unwrap(b);
36
- }
37
- }
@@ -1,62 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- type StoragePointer is bytes32;
5
-
6
- /// @title Module Storage Library
7
- /// @notice Library for allocating and accessing ERC-4337 address-associated storage within modules.
8
- library ModuleStorageLib {
9
- /// @notice Allocates a memory buffer for an associated storage key, and sets the associated address and batch
10
- /// index.
11
- /// @param addr The address to associate with the storage key.
12
- /// @param batchIndex The batch index to associate with the storage key.
13
- /// @param keySize The size of the key in words, where each word is 32 bytes. Not inclusive of the address and
14
- /// batch index.
15
- /// @return key The allocated memory buffer.
16
- function allocateAssociatedStorageKey(address addr, uint256 batchIndex, uint8 keySize)
17
- internal
18
- pure
19
- returns (bytes memory key)
20
- {
21
- /// @solidity memory-safe-assembly
22
- assembly {
23
- // Clear any dirty upper bits of keySize to prevent overflow
24
- keySize := and(keySize, 0xff)
25
-
26
- // compute the total size of the buffer, include the address and batch index
27
- let totalSize := add(64, mul(32, keySize))
28
-
29
- // Allocate memory for the key
30
- key := mload(0x40)
31
- mstore(0x40, add(add(key, totalSize), 32))
32
- mstore(key, totalSize)
33
-
34
- // Clear any dirty upper bits of address
35
- addr := and(addr, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
36
- // Store the address and batch index in the key buffer
37
- mstore(add(key, 32), addr)
38
- mstore(add(key, 64), batchIndex)
39
- }
40
- }
41
-
42
- function associatedStorageLookup(bytes memory key, bytes32 input) internal pure returns (StoragePointer ptr) {
43
- /// @solidity memory-safe-assembly
44
- assembly {
45
- mstore(add(key, 96), input)
46
- ptr := keccak256(add(key, 32), mload(key))
47
- }
48
- }
49
-
50
- function associatedStorageLookup(bytes memory key, bytes32 input1, bytes32 input2)
51
- internal
52
- pure
53
- returns (StoragePointer ptr)
54
- {
55
- /// @solidity memory-safe-assembly
56
- assembly {
57
- mstore(add(key, 96), input1)
58
- mstore(add(key, 128), input2)
59
- ptr := keccak256(add(key, 32), mload(key))
60
- }
61
- }
62
- }
@@ -1,95 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {RESERVED_VALIDATION_DATA_INDEX} from "../helpers/Constants.sol";
5
- import {getEmptyCalldataSlice} from "../helpers/EmptyCalldataSlice.sol";
6
-
7
- /// @title Sparse Calldata Segment Library
8
- /// @notice Library for working with sparsely-packed calldata segments, identified with an index.
9
- /// @dev The first byte of each segment is the index of the segment.
10
- /// To prevent accidental stack-to-deep errors, the body and index of the segment are extracted separately, rather
11
- /// than inline as part of the tuple returned by `getNextSegment`.
12
- library SparseCalldataSegmentLib {
13
- error NonCanonicalEncoding();
14
- error SegmentOutOfOrder();
15
- error ValidationSignatureSegmentMissing();
16
-
17
- /// @notice Splits out a segment of calldata, sparsely-packed.
18
- /// The expected format is:
19
- /// [uint8(index0), uint32(len(segment0)), segment0, uint8(index1), uint32(len(segment1)), segment1,
20
- /// ... uint8(indexN), uint32(len(segmentN)), segmentN]
21
- /// @param source The calldata to extract the segment from.
22
- /// @return segment The extracted segment. Using the above example, this would be segment0.
23
- /// @return remainder The remaining calldata. Using the above example,
24
- /// this would start at uint8(index1) and continue to the end at segmentN.
25
- function getNextSegment(bytes calldata source)
26
- internal
27
- pure
28
- returns (bytes calldata segment, bytes calldata remainder)
29
- {
30
- // The first byte of the segment is the index.
31
- // The next 4 bytes hold the length of the segment, excluding the index.
32
- uint32 length = uint32(bytes4(source[1:5]));
33
-
34
- // The offset of the remainder of the calldata.
35
- uint256 remainderOffset = 5 + length;
36
-
37
- // The segment is the next `length` bytes after the first 5 bytes.
38
- segment = source[5:remainderOffset];
39
-
40
- // The remainder is the rest of the calldata.
41
- remainder = source[remainderOffset:];
42
- }
43
-
44
- /// @notice If the index of the next segment in the source equals the provided index, return the next body and
45
- /// advance the source by one segment.
46
- /// @dev Reverts if the index of the next segment is less than the provided index, or if the extracted segment
47
- /// has length 0.
48
- /// @param source The calldata to extract the segment from.
49
- /// @param index The index of the segment to extract.
50
- /// @return A tuple containing the extracted segment's body, or an empty buffer if the index is not found, and
51
- /// the remaining calldata.
52
- function advanceSegmentIfAtIndex(bytes calldata source, uint8 index)
53
- internal
54
- pure
55
- returns (bytes calldata, bytes calldata)
56
- {
57
- uint8 nextIndex = getIndex(source);
58
-
59
- if (nextIndex < index) {
60
- revert SegmentOutOfOrder();
61
- }
62
-
63
- if (nextIndex == index) {
64
- (bytes calldata segment, bytes calldata remainder) = getNextSegment(source);
65
-
66
- if (segment.length == 0) {
67
- revert NonCanonicalEncoding();
68
- }
69
-
70
- return (segment, remainder);
71
- }
72
-
73
- return (getEmptyCalldataSlice(), source);
74
- }
75
-
76
- /// @notice Extracts the final segment from the source.
77
- /// @dev Reverts if the index of the segment is not RESERVED_VALIDATION_DATA_INDEX.
78
- /// @param source The calldata to extract the segment from.
79
- /// @return The final segment.
80
- function getFinalSegment(bytes calldata source) internal pure returns (bytes calldata) {
81
- if (getIndex(source) != RESERVED_VALIDATION_DATA_INDEX) {
82
- revert ValidationSignatureSegmentMissing();
83
- }
84
-
85
- return source[1:];
86
- }
87
-
88
- /// @notice Extracts the index from a segment.
89
- /// @dev The first byte of the segment is the index.
90
- /// @param segment The segment to extract the index from
91
- /// @return The index of the segment
92
- function getIndex(bytes calldata segment) internal pure returns (uint8) {
93
- return uint8(segment[0]);
94
- }
95
- }
@@ -1,119 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {ModuleEntity, ValidationConfig, ValidationFlags} from "../interfaces/IERC6900Account.sol";
5
-
6
- // Validation config is a packed representation of a validation function and flags for its configuration.
7
- // Layout:
8
- // 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA________________________ // Address
9
- // 0x________________________________________BBBBBBBB________________ // Entity ID
10
- // 0x________________________________________________CC______________ // ValidationFlags
11
- // 0x__________________________________________________00000000000000 // unused
12
-
13
- // ValidationFlags layout:
14
- // 0b00000___ // unused
15
- // 0b_____A__ // isGlobal
16
- // 0b______B_ // isSignatureValidation
17
- // 0b_______C // isUserOpValidation
18
-
19
- library ValidationConfigLib {
20
- // is user op validation flag stored in last bit of the 25th byte
21
- bytes32 internal constant _VALIDATION_FLAG_IS_USER_OP = bytes32(uint256(1) << 56);
22
- // is signature validation flag stored in second to last bit of the 25th byte
23
- bytes32 internal constant _VALIDATION_FLAG_IS_SIGNATURE = bytes32(uint256(1) << 57);
24
- // is global flag stored in the third to last bit of the 25th byte
25
- bytes32 internal constant _VALIDATION_FLAG_IS_GLOBAL = bytes32(uint256(1) << 58);
26
-
27
- function pack(
28
- ModuleEntity _validationFunction,
29
- bool _isGlobal,
30
- bool _isSignatureValidation,
31
- bool _isUserOpValidation
32
- ) internal pure returns (ValidationConfig) {
33
- return ValidationConfig.wrap(
34
- bytes25(
35
- bytes25(ModuleEntity.unwrap(_validationFunction))
36
- | bytes25(bytes32(_isGlobal ? _VALIDATION_FLAG_IS_GLOBAL : bytes32(0)))
37
- | bytes25(bytes32(_isSignatureValidation ? _VALIDATION_FLAG_IS_SIGNATURE : bytes32(0)))
38
- | bytes25(bytes32(_isUserOpValidation ? _VALIDATION_FLAG_IS_USER_OP : bytes32(0)))
39
- )
40
- );
41
- }
42
-
43
- function pack(
44
- address _module,
45
- uint32 _entityId,
46
- bool _isGlobal,
47
- bool _isSignatureValidation,
48
- bool _isUserOpValidation
49
- ) internal pure returns (ValidationConfig) {
50
- return ValidationConfig.wrap(
51
- bytes25(
52
- // module address stored in the first 20 bytes
53
- bytes25(bytes20(_module))
54
- // entityId stored in the 21st - 24th byte
55
- | bytes25(bytes24(uint192(_entityId)))
56
- | bytes25(bytes32(_isGlobal ? _VALIDATION_FLAG_IS_GLOBAL : bytes32(0)))
57
- | bytes25(bytes32(_isSignatureValidation ? _VALIDATION_FLAG_IS_SIGNATURE : bytes32(0)))
58
- | bytes25(bytes32(_isUserOpValidation ? _VALIDATION_FLAG_IS_USER_OP : bytes32(0)))
59
- )
60
- );
61
- }
62
-
63
- function unpackUnderlying(ValidationConfig config)
64
- internal
65
- pure
66
- returns (address _module, uint32 _entityId, ValidationFlags flags)
67
- {
68
- bytes25 configBytes = ValidationConfig.unwrap(config);
69
- _module = address(bytes20(configBytes));
70
- _entityId = uint32(bytes4(configBytes << 160));
71
- flags = ValidationFlags.wrap(uint8(configBytes[24]));
72
- }
73
-
74
- function unpack(ValidationConfig config)
75
- internal
76
- pure
77
- returns (ModuleEntity _validationFunction, ValidationFlags flags)
78
- {
79
- bytes25 configBytes = ValidationConfig.unwrap(config);
80
- _validationFunction = ModuleEntity.wrap(bytes24(configBytes));
81
- flags = ValidationFlags.wrap(uint8(configBytes[24]));
82
- }
83
-
84
- function module(ValidationConfig config) internal pure returns (address) {
85
- return address(bytes20(ValidationConfig.unwrap(config)));
86
- }
87
-
88
- function entityId(ValidationConfig config) internal pure returns (uint32) {
89
- return uint32(bytes4(ValidationConfig.unwrap(config) << 160));
90
- }
91
-
92
- function moduleEntity(ValidationConfig config) internal pure returns (ModuleEntity) {
93
- return ModuleEntity.wrap(bytes24(ValidationConfig.unwrap(config)));
94
- }
95
-
96
- function isGlobal(ValidationConfig config) internal pure returns (bool) {
97
- return ValidationConfig.unwrap(config) & _VALIDATION_FLAG_IS_GLOBAL != 0;
98
- }
99
-
100
- function isGlobal(ValidationFlags flags) internal pure returns (bool) {
101
- return ValidationFlags.unwrap(flags) & 0x04 != 0;
102
- }
103
-
104
- function isSignatureValidation(ValidationConfig config) internal pure returns (bool) {
105
- return ValidationConfig.unwrap(config) & _VALIDATION_FLAG_IS_SIGNATURE != 0;
106
- }
107
-
108
- function isSignatureValidation(ValidationFlags flags) internal pure returns (bool) {
109
- return ValidationFlags.unwrap(flags) & 0x02 != 0;
110
- }
111
-
112
- function isUserOpValidation(ValidationConfig config) internal pure returns (bool) {
113
- return ValidationConfig.unwrap(config) & _VALIDATION_FLAG_IS_USER_OP != 0;
114
- }
115
-
116
- function isUserOpValidation(ValidationFlags flags) internal pure returns (bool) {
117
- return ValidationFlags.unwrap(flags) & 0x01 != 0;
118
- }
119
- }
@@ -1,54 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- import {IAccountExecute} from "@eth-infinitism/account-abstraction/interfaces/IAccountExecute.sol";
5
- import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol";
6
- import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
7
-
8
- import {IERC6900Module} from "../interfaces/IERC6900Module.sol";
9
-
10
- /// @title Base contract for modules
11
- /// @dev Implements ERC-165 to support IERC6900Module's interface, which is a requirement
12
- /// for module installation. This also ensures that module interactions cannot
13
- /// happen via the standard execution funtions `execute` and `executeBatch`.
14
- abstract contract BaseModule is ERC165, IERC6900Module {
15
- error NotImplemented();
16
-
17
- /// @dev Returns true if this contract implements the interface defined by
18
- /// `interfaceId`. See the corresponding
19
- /// https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
20
- /// to learn more about how these ids are created.
21
- ///
22
- /// This function call must use less than 30 000 gas.
23
- ///
24
- /// Supporting the IERC6900Module interface is a requirement for module installation. This is also used
25
- /// by the modular account to prevent standard execution functions `execute` and `executeBatch` from
26
- /// making calls to modules.
27
- /// @param interfaceId The interface ID to check for support.
28
- /// @return True if the contract supports `interfaceId`.
29
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
30
- return interfaceId == type(IERC6900Module).interfaceId || super.supportsInterface(interfaceId);
31
- }
32
-
33
- function _getSelectorAndCalldata(bytes calldata data) internal pure returns (bytes4, bytes memory) {
34
- if (bytes4(data[:4]) == IAccountExecute.executeUserOp.selector) {
35
- (PackedUserOperation memory uo,) = abi.decode(data[4:], (PackedUserOperation, bytes32));
36
- bytes4 selector;
37
- bytes memory callData = uo.callData;
38
- // Bytes arr representation: [bytes32(len), bytes4(executeUserOp.selector), bytes4(actualSelector),
39
- // bytes(actualCallData)]
40
- // 1. Copy actualSelector into a new var
41
- // 2. Shorten bytes arry by 8 by: store length - 8 into the new pointer location
42
- // 3. Move the callData pointer by 8
43
- assembly {
44
- selector := mload(add(callData, 36))
45
-
46
- let len := mload(callData)
47
- mstore(add(callData, 8), sub(len, 8))
48
- callData := add(callData, 8)
49
- }
50
- return (selector, callData);
51
- }
52
- return (bytes4(data[:4]), data[4:]);
53
- }
54
- }
@@ -1,29 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- pragma solidity ^0.8.20;
3
-
4
- // A base for modules that use EIP-712 structured data signing.
5
- //
6
- // Unlike other EIP712 libraries, this mixin uses the salt field to hold the account address.
7
- //
8
- // It omits the name and version from the EIP-712 domain, as modules are intended to be deployed as
9
- // immutable singletons, thus a different versions and instances would have a different module address.
10
- //
11
- // Due to depending on the account address to calculate the domain separator, this abstract contract does not
12
- // implement EIP-5267, as the domain retrieval function does not provide a parameter to use for the account address
13
- // (internally the verifyingContract), and the computed `msg.sender` for an `eth_call` without an override is
14
- // address(0).
15
- abstract contract ModuleEIP712 {
16
- // keccak256(
17
- // "EIP712Domain(uint256 chainId,address verifyingContract,bytes32 salt)"
18
- // )
19
- bytes32 private constant _DOMAIN_SEPARATOR_TYPEHASH =
20
- 0x71062c282d40422f744945d587dbf4ecfd4f9cfad1d35d62c944373009d96162;
21
-
22
- function _domainSeparator(address account) internal view returns (bytes32) {
23
- return keccak256(
24
- abi.encode(
25
- _DOMAIN_SEPARATOR_TYPEHASH, block.chainid, address(this), bytes32(uint256(uint160(account)))
26
- )
27
- );
28
- }
29
- }