Skip to content

Commit 38a045b

Browse files
authored
Feat/excessively safe call (#23)
* using module lib for removing module * using erc2771 call * rollback to action/fallback separation
1 parent 8974127 commit 38a045b

11 files changed

Lines changed: 52 additions & 23 deletions

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "lib/solady"]
55
path = lib/solady
66
url = https://github.com/vectorized/solady
7+
[submodule "lib/ExcessivelySafeCall"]
8+
path = lib/ExcessivelySafeCall
9+
url = https://github.com/nomad-xyz/ExcessivelySafeCall

lib/ExcessivelySafeCall

Submodule ExcessivelySafeCall added at 81cd99c

remappings.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
solady/=lib/solady/
1+
ExcessivelySafeCall/=lib/ExcessivelySafeCall/src/
2+
ds-test/=lib/forge-std/lib/ds-test/src/
3+
forge-std/=lib/forge-std/src/
4+
solady/=lib/solady/src/

src/Kernel.sol

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {IAccount, ValidationData, ValidAfter, ValidUntil, parseValidationData} f
66
import {IEntryPoint} from "./interfaces/IEntryPoint.sol";
77
import {IAccountExecute} from "./interfaces/IAccountExecute.sol";
88
import {IERC7579Account} from "./interfaces/IERC7579Account.sol";
9+
import {ModuleLib} from "./utils/ModuleLib.sol";
910
import {
1011
ValidationManager,
1112
ValidationMode,
@@ -23,7 +24,7 @@ import {HookManager} from "./core/HookManager.sol";
2324
import {ExecutorManager} from "./core/ExecutorManager.sol";
2425
import {SelectorManager} from "./core/SelectorManager.sol";
2526
import {IModule, IValidator, IHook, IExecutor, IFallback, IPolicy, ISigner} from "./interfaces/IERC7579Modules.sol";
26-
import {EIP712} from "solady/src/utils/EIP712.sol";
27+
import {EIP712} from "solady/utils/EIP712.sol";
2728
import {ExecLib, ExecMode, CallType, CALLTYPE_SINGLE, CALLTYPE_DELEGATECALL} from "./utils/ExecLib.sol";
2829

2930
bytes32 constant ERC1967_IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
@@ -119,7 +120,7 @@ contract Kernel is IAccount, IAccountExecute, IERC7579Account, ValidationManager
119120
mstore(senderPtr, shl(96, caller()))
120121

121122
// Add 20 bytes for the address appended add the end
122-
// NOTE: we are only allowing static call for fallback
123+
// NOTE: we are only allowing call for fallback
123124
success := staticcall(gas(), fallbackHandler, calldataPtr, add(calldatasize(), 20), 0, 0)
124125

125126
result := mload(0x40)
@@ -330,6 +331,7 @@ contract Kernel is IAccount, IAccountExecute, IERC7579Account, ValidationManager
330331
_installExecutor(IExecutor(module), executorData, hook);
331332
_installHook(hook, hookData);
332333
} else if (moduleType == 3) {
334+
//TODO : update this to use _installSelector
333335
bytes calldata fallbackData;
334336
bytes calldata hookData;
335337
assembly {
@@ -396,7 +398,7 @@ contract Kernel is IAccount, IAccountExecute, IERC7579Account, ValidationManager
396398
{
397399
if (moduleType == type(uint256).max) {
398400
// force uninstall option
399-
IModule(module).onUninstall(deInitData);
401+
ModuleLib.uninstallModule(module, deInitData);
400402
}
401403
if (moduleType == 1) {
402404
ValidationStorage storage vs = _validationStorage();
@@ -439,19 +441,19 @@ contract Kernel is IAccount, IAccountExecute, IERC7579Account, ValidationManager
439441
// force call onInstall for hook
440442
// NOTE: for hook, kernel does not support independant hook install,
441443
// hook is expected to be paired with proper validator/executor/selector
442-
IHook(module).onUninstall(deInitData);
444+
ModuleLib.uninstallModule(module, deInitData);
443445
} else if (moduleType == 5) {
444446
// force call onInstall for policy
445447
// NOTE: for policy, kernel does not support independant policy install,
446448
// policy is expected to be paired with proper permissionId
447-
// to "ADD" permission, use "installValidations()" function
448-
IPolicy(module).onUninstall(deInitData);
449+
// to "REMOVE" permission, use "uninstallValidation()" function
450+
ModuleLib.uninstallModule(module, deInitData);
449451
} else if (moduleType == 6) {
450452
// force call onInstall for signer
451453
// NOTE: for signer, kernel does not support independant signer install,
452454
// signer is expected to be paired with proper permissionId
453-
// to "ADD" permission, use "installValidations()" function
454-
ISigner(module).onUninstall(deInitData);
455+
// to "REMOVE" permission, use "installValidation()" function
456+
ModuleLib.uninstallModule(module, deInitData);
455457
} else if (moduleType == 7) {
456458
IHook hook = _uninstallSelector(bytes4(deInitData[0:4]));
457459
bytes calldata hookData = deInitData[4:];
@@ -483,7 +485,7 @@ contract Kernel is IAccount, IAccountExecute, IERC7579Account, ValidationManager
483485
} else if (moduleType == 3) {
484486
(IFallback fallbackHandler,) = _fallbackConfig();
485487
return fallbackHandler == IFallback(module);
486-
} else if (moduleType == 6) {
488+
} else if (moduleType == 7) {
487489
return _selectorConfig(bytes4(additionalContext[0:4])).target == module;
488490
} else {
489491
return false;

src/core/ExecutorManager.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pragma solidity ^0.8.0;
22

33
import {IHook, IExecutor} from "../interfaces/IERC7579Modules.sol";
4+
import {ModuleLib} from "../utils/ModuleLib.sol";
45

56
bytes32 constant EXECUTOR_MANAGER_STORAGE_SLOT = 0x1bbee3173dbdc223633258c9f337a0fff8115f206d302bea0ed3eac003b68b86;
67

@@ -39,6 +40,6 @@ abstract contract ExecutorManager {
3940
ExecutorConfig storage config = _executorConfig(executor);
4041
hook = config.hook;
4142
config.hook = IHook(address(0));
42-
executor.onUninstall(executorData);
43+
ModuleLib.uninstallModule(address(executor), executorData);
4344
}
4445
}

src/core/HookManager.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pragma solidity ^0.8.0;
22

33
import {IHook} from "../interfaces/IERC7579Modules.sol";
4+
import {ModuleLib} from "../utils/ModuleLib.sol";
45

56
bytes32 constant HOOK_MANAGER_STORAGE_SLOT = 0x4605d5f70bb605094b2e761eccdc27bed9a362d8612792676bf3fb9b12832ffc;
67

@@ -46,7 +47,7 @@ abstract contract HookManager {
4647
}
4748
if (bytes1(hookData[0]) == bytes1(0xff)) {
4849
// 0xff means you want to call uninstall hook
49-
hook.onUninstall(hookData[1:]);
50+
ModuleLib.uninstallModule(address(hook), hookData[1:]);
5051
return;
5152
}
5253
}

src/core/SelectorManager.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ bytes32 constant SELECTOR_MANAGER_STORAGE_SLOT = 0x7c341349a4360fdd5d5bc07e69f32
1010
abstract contract SelectorManager {
1111
struct SelectorConfig {
1212
IHook hook; // 20 bytes for hook address
13-
address target; // 20 bytes target will be fallback module, called with delegatecall or call
13+
address target; // 20 bytes target will be fallback module, called with call
1414
}
1515

1616
struct SelectorStorage {

src/core/ValidationManager.sol

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
pragma solidity ^0.8.0;
22

3-
import {IValidator, IHook, IPolicy, ISigner} from "../interfaces/IERC7579Modules.sol";
3+
import {IValidator, IHook, IPolicy, ISigner, IFallback} from "../interfaces/IERC7579Modules.sol";
44
import {PackedUserOperation} from "../interfaces/PackedUserOperation.sol";
55
import {SelectorManager} from "./SelectorManager.sol";
66
import {HookManager} from "./HookManager.sol";
77
import {ValidationData, ValidAfter, ValidUntil, parseValidationData} from "../interfaces/IAccount.sol";
88
import {IAccountExecute} from "../interfaces/IAccountExecute.sol";
9-
import {EIP712} from "solady/src/utils/EIP712.sol";
9+
import {EIP712} from "solady/utils/EIP712.sol";
10+
import {ModuleLib} from "../utils/ModuleLib.sol";
1011
import {
1112
ValidationId,
1213
PolicyData,
@@ -158,7 +159,7 @@ abstract contract ValidationManager is EIP712, SelectorManager, HookManager {
158159
ValidationType vType = ValidatorLib.getType(vId);
159160
if (vType == VALIDATION_TYPE_VALIDATOR) {
160161
IValidator validator = ValidatorLib.getValidator(vId);
161-
validator.onUninstall(validatorData);
162+
ModuleLib.uninstallModule(address(validator), validatorData);
162163
} else if (vType == VALIDATION_TYPE_PERMISSION) {
163164
PermissionId permission = ValidatorLib.getPermissionId(vId);
164165
_uninstallPermission(permission, validatorData);
@@ -180,10 +181,13 @@ abstract contract ValidationManager is EIP712, SelectorManager, HookManager {
180181
PolicyData[] storage policyData = config.policyData;
181182
for (uint256 i = 0; i < policyData.length; i++) {
182183
(PassFlag flag, IPolicy policy) = ValidatorLib.decodePolicyData(policyData[i]);
183-
policy.onUninstall(abi.encodePacked(bytes32(PermissionId.unwrap(pId)), permissionDisableData[i]));
184+
ModuleLib.uninstallModule(
185+
address(policy), abi.encodePacked(bytes32(PermissionId.unwrap(pId)), permissionDisableData[i])
186+
);
184187
policyData[i] = PolicyData.wrap(bytes22(0));
185188
}
186-
config.signer.onUninstall(
189+
ModuleLib.uninstallModule(
190+
address(config.signer),
187191
abi.encodePacked(bytes32(PermissionId.unwrap(pId)), permissionDisableData[permissionDisableData.length - 1])
188192
);
189193
config.signer = ISigner(address(0));
@@ -248,7 +252,7 @@ abstract contract ValidationManager is EIP712, SelectorManager, HookManager {
248252
}
249253

250254
// clean up the policyData
251-
if(state.permissionConfig[permission].policyData.length > 0) {
255+
if (state.permissionConfig[permission].policyData.length > 0) {
252256
delete state.permissionConfig[permission].policyData;
253257
}
254258
unchecked {
@@ -364,7 +368,9 @@ abstract contract ValidationManager is EIP712, SelectorManager, HookManager {
364368
if (selectorData.length >= 44) {
365369
// install selector with hook and target contract
366370
_installSelector(
367-
selector, address(bytes20(selectorData[4:24])), IHook(address(bytes20(selectorData[24:44])))
371+
selector,
372+
address(bytes20(selectorData[4:24])),
373+
IHook(address(bytes20(selectorData[24:44])))
368374
);
369375
_installHook(IHook(address(bytes20(selectorData[24:44]))), selectorData[44:]);
370376
_setSelector(vId, selector, true);

src/utils/ModuleLib.sol

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pragma solidity ^0.8.0;
2+
3+
import {ExcessivelySafeCall} from "ExcessivelySafeCall/ExcessivelySafeCall.sol";
4+
5+
library ModuleLib {
6+
event ModuleUninstallResult(address module, bool result);
7+
8+
function uninstallModule(address module, bytes memory deinitData) internal returns (bool result) {
9+
(result,) = ExcessivelySafeCall.excessivelySafeCall(module, gasleft(), 0, 0, deinitData);
10+
emit ModuleUninstallResult(module, result);
11+
}
12+
}

src/validator/ECDSAValidator.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pragma solidity ^0.8.0;
22

3-
import {ECDSA} from "solady/src/utils/ECDSA.sol";
3+
import {ECDSA} from "solady/utils/ECDSA.sol";
44
import {
55
IValidator,
66
IHook,

0 commit comments

Comments
 (0)