Skip to content

Commit 7fb76b7

Browse files
committed
refactor: module suffix to execution and validation interfaces
1 parent e7b0902 commit 7fb76b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+240
-188
lines changed

.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ ENTRYPOINT=
77
# Create2 expected addresses of the contracts.
88
# When running for the first time, the error message will contain the expected addresses.
99
ACCOUNT_IMPL=
10-
SINGLE_SIGNER_VALIDATION=
10+
SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS=
1111
FACTORY=
1212

1313
# Optional, defaults to bytes32(0)
1414
ACCOUNT_IMPL_SALT=
1515
FACTORY_SALT=
16-
SINGLE_SIGNER_VALIDATION_SALT=
16+
SINGLE_SIGNER_VALIDATION_MODULE_SALT=
1717

1818
# Optional, defaults to 0.1 ether and 1 day, respectively
1919
STAKE_AMOUNT=

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Reference implementation for [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900). It is an early draft implementation.
44

5-
The implementation includes an upgradable modular account with three modules (`SingleSignerValidation`, `TokenReceiverModule`, and `AllowlistModule`). It is compliant with ERC-6900 with the latest updates.
5+
The implementation includes an upgradable modular account with three modules (`SingleSignerValidationModule`, `TokenReceiverModule`, and `AllowlistModule`). It is compliant with ERC-6900 with the latest updates.
66

77
## Important Callouts
88

@@ -31,9 +31,10 @@ FOUNDRY_PROFILE=optimized-test forge test -vvv
3131

3232
## Integration testing
3333

34-
The reference implementation provides a sample factory and deploy script for the factory, account implementation, and the demo validation module `SingleSignerValidation`. This is not auditted, nor intended for production use. Limitations set by the GPL-V3 license apply.
34+
The reference implementation provides a sample factory and deploy script for the factory, account implementation, and the demo validation module `SingleSignerValidationModule`. This is not auditted, nor intended for production use. Limitations set by the GPL-V3 license apply.
3535

3636
To run this script, provide appropriate values in a `.env` file based on the `.env.example` template, then run:
37+
3738
```bash
3839
forge script script/Deploy.s.sol <wallet options> -r <rpc_url> --broadcast
3940
```

deployments/arb-sepolia.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@ Chain ID: 421614
1616
| v0.8.0-alpha.1 | `0xC64Cb5192a1440Fea12CE03D000EAeB247B2369B` | [explorer](https://sepolia.arbiscan.io/address/0xC64Cb5192a1440Fea12CE03D000EAeB247B2369B) | `0` |
1717
| v0.8.0-alpha.0 | `0x0809BF385117a43A322A4E31d459c0EcaA3B1A08` | [explorer](https://sepolia.arbiscan.io/address/0x0809BF385117a43A322A4E31d459c0EcaA3B1A08) | `0` |
1818

19-
## SingleSignerValidation
19+
## SingleSignerValidationModule
2020

2121
| Version | Address | Explorer | Salt |
2222
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---- |
2323
| v0.8.0-alpha.1 | `0xEa3a0b544d517f6Ed3Dc2186C74D869c702C376e` | [explorer](https://sepolia.arbiscan.io/address/0xEa3a0b544d517f6Ed3Dc2186C74D869c702C376e) | `0` |
2424
| v0.8.0-alpha.0 | `0x9DA8c098A483E257dd96022831DF308cB24fCBE6` | [explorer](https://sepolia.arbiscan.io/address/0x9DA8c098A483E257dd96022831DF308cB24fCBE6) | `0` |
2525

26-
2726
## AllowlistModule
2827

2928
| Version | Address | Explorer | Salt |
3029
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---- |
31-
| v0.8.0-alpha.1 | `0x5B13F222A841A42C59324FFF0A229FfeA1CAcC3c` | [explorer](https://sepolia.arbiscan.io/address/0x5B13F222A841A42C59324FFF0A229FfeA1CAcC3c) | `0` |
30+
| v0.8.0-alpha.1 | `0x5B13F222A841A42C59324FFF0A229FfeA1CAcC3c` | [explorer](https://sepolia.arbiscan.io/address/0x5B13F222A841A42C59324FFF0A229FfeA1CAcC3c) | `0` |

script/Deploy.s.sol

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
88

99
import {AccountFactory} from "../src/account/AccountFactory.sol";
1010
import {UpgradeableModularAccount} from "../src/account/UpgradeableModularAccount.sol";
11-
import {SingleSignerValidation} from "../src/modules/validation/SingleSignerValidation.sol";
11+
import {SingleSignerValidationModule} from "../src/modules/validation/SingleSignerValidationModule.sol";
1212

1313
contract DeployScript is Script {
1414
IEntryPoint public entryPoint = IEntryPoint(payable(vm.envAddress("ENTRYPOINT")));
@@ -17,11 +17,13 @@ contract DeployScript is Script {
1717

1818
address public accountImpl = vm.envOr("ACCOUNT_IMPL", address(0));
1919
address public factory = vm.envOr("FACTORY", address(0));
20-
address public singleSignerValidation = vm.envOr("SINGLE_SIGNER_VALIDATION", address(0));
20+
address public singleSignerValidationModuleAddress =
21+
vm.envOr("SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS", address(0));
2122

2223
bytes32 public accountImplSalt = bytes32(vm.envOr("ACCOUNT_IMPL_SALT", uint256(0)));
2324
bytes32 public factorySalt = bytes32(vm.envOr("FACTORY_SALT", uint256(0)));
24-
bytes32 public singleSignerValidationSalt = bytes32(vm.envOr("SINGLE_SIGNER_VALIDATION_SALT", uint256(0)));
25+
bytes32 public singleSignerValidationModuleSalt =
26+
bytes32(vm.envOr("SINGLE_SIGNER_VALIDATION_MODULE_SALT", uint256(0)));
2527

2628
uint256 public requiredStakeAmount = vm.envOr("STAKE_AMOUNT", uint256(0.1 ether));
2729
uint256 public requiredUnstakeDelay = vm.envOr("UNSTAKE_DELAY", uint256(1 days));
@@ -34,7 +36,7 @@ contract DeployScript is Script {
3436

3537
vm.startBroadcast();
3638
_deployAccountImpl(accountImplSalt, accountImpl);
37-
_deploySingleSignerValidation(singleSignerValidationSalt, singleSignerValidation);
39+
_deploySingleSignerValidationModule(singleSignerValidationModuleSalt, singleSignerValidationModuleAddress);
3840
_deployAccountFactory(factorySalt, factory);
3941
_addStakeForFactory(uint32(requiredUnstakeDelay), requiredStakeAmount);
4042
vm.stopBroadcast();
@@ -72,11 +74,11 @@ contract DeployScript is Script {
7274
}
7375
}
7476

75-
function _deploySingleSignerValidation(bytes32 salt, address expected) internal {
76-
console.log(string.concat("Deploying SingleSignerValidation with salt: ", vm.toString(salt)));
77+
function _deploySingleSignerValidationModule(bytes32 salt, address expected) internal {
78+
console.log(string.concat("Deploying SingleSignerValidationModule with salt: ", vm.toString(salt)));
7779

7880
address addr = Create2.computeAddress(
79-
salt, keccak256(abi.encodePacked(type(SingleSignerValidation).creationCode)), CREATE2_FACTORY
81+
salt, keccak256(abi.encodePacked(type(SingleSignerValidationModule).creationCode)), CREATE2_FACTORY
8082
);
8183
if (addr != expected) {
8284
console.log("Expected address mismatch");
@@ -87,7 +89,7 @@ contract DeployScript is Script {
8789

8890
if (addr.code.length == 0) {
8991
console.log("No code found at expected address, deploying...");
90-
SingleSignerValidation deployed = new SingleSignerValidation{salt: salt}();
92+
SingleSignerValidationModule deployed = new SingleSignerValidationModule{salt: salt}();
9193

9294
if (address(deployed) != expected) {
9395
console.log("Deployed address mismatch");
@@ -96,7 +98,7 @@ contract DeployScript is Script {
9698
revert();
9799
}
98100

99-
console.log("Deployed SingleSignerValidation at: ", address(deployed));
101+
console.log("Deployed SingleSignerValidationModule at: ", address(deployed));
100102
} else {
101103
console.log("Code found at expected address, skipping deployment");
102104
}
@@ -110,7 +112,7 @@ contract DeployScript is Script {
110112
keccak256(
111113
abi.encodePacked(
112114
type(AccountFactory).creationCode,
113-
abi.encode(entryPoint, accountImpl, singleSignerValidation, owner)
115+
abi.encode(entryPoint, accountImpl, singleSignerValidationModuleAddress, owner)
114116
)
115117
),
116118
CREATE2_FACTORY
@@ -125,7 +127,10 @@ contract DeployScript is Script {
125127
if (addr.code.length == 0) {
126128
console.log("No code found at expected address, deploying...");
127129
AccountFactory deployed = new AccountFactory{salt: salt}(
128-
entryPoint, UpgradeableModularAccount(payable(accountImpl)), singleSignerValidation, owner
130+
entryPoint,
131+
UpgradeableModularAccount(payable(accountImpl)),
132+
singleSignerValidationModuleAddress,
133+
owner
129134
);
130135

131136
if (address(deployed) != expected) {

src/account/AccountFactory.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@ contract AccountFactory is Ownable {
1414
UpgradeableModularAccount public immutable ACCOUNT_IMPL;
1515
bytes32 private immutable _PROXY_BYTECODE_HASH;
1616
IEntryPoint public immutable ENTRY_POINT;
17-
address public immutable SINGLE_SIGNER_VALIDATION;
17+
address public immutable SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS;
1818

1919
constructor(
2020
IEntryPoint _entryPoint,
2121
UpgradeableModularAccount _accountImpl,
22-
address _singleSignerValidation,
22+
address _singleSignerValidationModuleAddress,
2323
address owner
2424
) Ownable(owner) {
2525
ENTRY_POINT = _entryPoint;
2626
_PROXY_BYTECODE_HASH =
2727
keccak256(abi.encodePacked(type(ERC1967Proxy).creationCode, abi.encode(address(_accountImpl), "")));
2828
ACCOUNT_IMPL = _accountImpl;
29-
SINGLE_SIGNER_VALIDATION = _singleSignerValidation;
29+
SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS = _singleSignerValidationModuleAddress;
3030
}
3131

3232
/**
@@ -50,7 +50,7 @@ contract AccountFactory is Ownable {
5050
new ERC1967Proxy{salt: combinedSalt}(address(ACCOUNT_IMPL), "");
5151
// point proxy to actual implementation and init plugins
5252
UpgradeableModularAccount(payable(addr)).initializeWithValidation(
53-
ValidationConfigLib.pack(SINGLE_SIGNER_VALIDATION, entityId, true, true),
53+
ValidationConfigLib.pack(SINGLE_SIGNER_VALIDATION_MODULE_ADDRESS, entityId, true, true),
5454
new bytes4[](0),
5555
pluginInstallData,
5656
new bytes[](0)

src/account/ModuleManagerInternals.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {HookConfigLib} from "../helpers/HookConfigLib.sol";
1010
import {KnownSelectors} from "../helpers/KnownSelectors.sol";
1111
import {ModuleEntityLib} from "../helpers/ModuleEntityLib.sol";
1212
import {ValidationConfigLib} from "../helpers/ValidationConfigLib.sol";
13-
import {ExecutionManifest, ManifestExecutionHook} from "../interfaces/IExecution.sol";
13+
import {ExecutionManifest, ManifestExecutionHook} from "../interfaces/IExecutionModule.sol";
1414
import {IModule} from "../interfaces/IModule.sol";
1515
import {HookConfig, IModuleManager, ModuleEntity, ValidationConfig} from "../interfaces/IModuleManager.sol";
1616
import {

src/account/UpgradeableModularAccount.sol

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ import {_coalescePreValidation, _coalesceValidation} from "../helpers/Validation
2121

2222
import {DIRECT_CALL_VALIDATION_ENTITYID, RESERVED_VALIDATION_DATA_INDEX} from "../helpers/Constants.sol";
2323

24-
import {ExecutionManifest} from "../interfaces/IExecution.sol";
25-
import {IExecutionHook} from "../interfaces/IExecutionHook.sol";
24+
import {IExecutionHookModule} from "../interfaces/IExecutionHookModule.sol";
25+
import {ExecutionManifest} from "../interfaces/IExecutionModule.sol";
2626
import {IModuleManager, ModuleEntity, ValidationConfig} from "../interfaces/IModuleManager.sol";
2727
import {Call, IStandardExecutor} from "../interfaces/IStandardExecutor.sol";
28-
import {IValidation} from "../interfaces/IValidation.sol";
29-
import {IValidationHook} from "../interfaces/IValidationHook.sol";
28+
29+
import {IValidationHookModule} from "../interfaces/IValidationHookModule.sol";
30+
import {IValidationModule} from "../interfaces/IValidationModule.sol";
3031
import {AccountExecutor} from "./AccountExecutor.sol";
3132
import {AccountLoupe} from "./AccountLoupe.sol";
3233
import {AccountStorage, getAccountStorage, toHookConfig, toSetValue} from "./AccountStorage.sol";
@@ -316,7 +317,7 @@ contract UpgradeableModularAccount is
316317
}
317318

318319
if (
319-
IValidation(module).validateSignature(address(this), entityId, msg.sender, hash, signature[24:])
320+
IValidationModule(module).validateSignature(address(this), entityId, msg.sender, hash, signature[24:])
320321
== _1271_MAGIC_VALUE
321322
) {
322323
return _1271_MAGIC_VALUE;
@@ -403,7 +404,7 @@ contract UpgradeableModularAccount is
403404

404405
(address module, uint32 entityId) = preUserOpValidationHooks[i].unpack();
405406
uint256 currentValidationRes =
406-
IValidationHook(module).preUserOpValidationHook(entityId, userOp, userOpHash);
407+
IValidationHookModule(module).preUserOpValidationHook(entityId, userOp, userOpHash);
407408

408409
if (uint160(currentValidationRes) > 1) {
409410
// If the aggregator is not 0 or 1, it is an unexpected value
@@ -421,7 +422,7 @@ contract UpgradeableModularAccount is
421422
userOp.signature = signatureSegment.getBody();
422423

423424
(address module, uint32 entityId) = userOpValidationFunction.unpack();
424-
uint256 currentValidationRes = IValidation(module).validateUserOp(entityId, userOp, userOpHash);
425+
uint256 currentValidationRes = IValidationModule(module).validateUserOp(entityId, userOp, userOpHash);
425426

426427
if (preUserOpValidationHooks.length != 0) {
427428
// If we have other validation data we need to coalesce with
@@ -476,12 +477,12 @@ contract UpgradeableModularAccount is
476477

477478
(address module, uint32 entityId) = runtimeValidationFunction.unpack();
478479

479-
try IValidation(module).validateRuntime(
480+
try IValidationModule(module).validateRuntime(
480481
address(this), entityId, msg.sender, msg.value, callData, authSegment.getBody()
481482
)
482483
// forgefmt: disable-start
483484
// solhint-disable-next-line no-empty-blocks
484-
{} catch (bytes memory revertReason) {
485+
{} catch (bytes memory revertReason){
485486
// forgefmt: disable-end
486487
revert RuntimeValidationFunctionReverted(module, entityId, revertReason);
487488
}
@@ -527,7 +528,7 @@ contract UpgradeableModularAccount is
527528
returns (bytes memory preExecHookReturnData)
528529
{
529530
(address module, uint32 entityId) = preExecHook.unpack();
530-
try IExecutionHook(module).preExecutionHook(entityId, msg.sender, msg.value, data) returns (
531+
try IExecutionHookModule(module).preExecutionHook(entityId, msg.sender, msg.value, data) returns (
531532
bytes memory returnData
532533
) {
533534
preExecHookReturnData = returnData;
@@ -553,7 +554,7 @@ contract UpgradeableModularAccount is
553554

554555
(address module, uint32 entityId) = postHookToRun.postExecHook.unpack();
555556
// solhint-disable-next-line no-empty-blocks
556-
try IExecutionHook(module).postExecutionHook(entityId, postHookToRun.preExecHookReturnData) {}
557+
try IExecutionHookModule(module).postExecutionHook(entityId, postHookToRun.preExecHookReturnData) {}
557558
catch (bytes memory revertReason) {
558559
revert PostExecHookReverted(module, entityId, revertReason);
559560
}
@@ -566,12 +567,12 @@ contract UpgradeableModularAccount is
566567
bytes memory currentAuthData
567568
) internal {
568569
(address hookModule, uint32 hookEntityId) = validationHook.unpack();
569-
try IValidationHook(hookModule).preRuntimeValidationHook(
570+
try IValidationHookModule(hookModule).preRuntimeValidationHook(
570571
hookEntityId, msg.sender, msg.value, callData, currentAuthData
571572
)
572573
// forgefmt: disable-start
573574
// solhint-disable-next-line no-empty-blocks
574-
{} catch (bytes memory revertReason) {
575+
{} catch (bytes memory revertReason){
575576
// forgefmt: disable-end
576577
revert PreRuntimeValidationHookFailed(hookModule, hookEntityId, revertReason);
577578
}

src/helpers/KnownSelectors.sol

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
99

1010
import {IAccountLoupe} from "../interfaces/IAccountLoupe.sol";
1111

12-
import {IExecution} from "../interfaces/IExecution.sol";
13-
import {IExecutionHook} from "../interfaces/IExecutionHook.sol";
12+
import {IExecutionHookModule} from "../interfaces/IExecutionHookModule.sol";
13+
import {IExecutionModule} from "../interfaces/IExecutionModule.sol";
1414
import {IModule} from "../interfaces/IModule.sol";
1515
import {IModuleManager} from "../interfaces/IModuleManager.sol";
1616
import {IStandardExecutor} from "../interfaces/IStandardExecutor.sol";
17-
import {IValidation} from "../interfaces/IValidation.sol";
18-
import {IValidationHook} from "../interfaces/IValidationHook.sol";
17+
18+
import {IValidationHookModule} from "../interfaces/IValidationHookModule.sol";
19+
import {IValidationModule} from "../interfaces/IValidationModule.sol";
1920

2021
/// @dev Library to help to check if a selector is a know function selector of the modular account or ERC-4337
2122
/// contract.
@@ -49,11 +50,13 @@ library KnownSelectors {
4950

5051
function isIModuleFunction(bytes4 selector) internal pure returns (bool) {
5152
return selector == IModule.onInstall.selector || selector == IModule.onUninstall.selector
52-
|| selector == IExecution.executionManifest.selector || selector == IModule.moduleMetadata.selector
53-
|| selector == IExecutionHook.preExecutionHook.selector
54-
|| selector == IExecutionHook.postExecutionHook.selector || selector == IValidation.validateUserOp.selector
55-
|| selector == IValidation.validateRuntime.selector || selector == IValidation.validateSignature.selector
56-
|| selector == IValidationHook.preUserOpValidationHook.selector
57-
|| selector == IValidationHook.preRuntimeValidationHook.selector;
53+
|| selector == IExecutionModule.executionManifest.selector || selector == IModule.moduleMetadata.selector
54+
|| selector == IExecutionHookModule.preExecutionHook.selector
55+
|| selector == IExecutionHookModule.postExecutionHook.selector
56+
|| selector == IValidationModule.validateUserOp.selector
57+
|| selector == IValidationModule.validateRuntime.selector
58+
|| selector == IValidationModule.validateSignature.selector
59+
|| selector == IValidationHookModule.preUserOpValidationHook.selector
60+
|| selector == IValidationHookModule.preRuntimeValidationHook.selector;
5861
}
5962
}

src/interfaces/IExecutionHook.sol renamed to src/interfaces/IExecutionHookModule.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pragma solidity ^0.8.25;
33

44
import {IModule} from "./IModule.sol";
55

6-
interface IExecutionHook is IModule {
6+
interface IExecutionHookModule is IModule {
77
/// @notice Run the pre execution hook specified by the `entityId`.
88
/// @dev To indicate the entire call should revert, the function MUST revert.
99
/// @param entityId An identifier that routes the call to different internal implementations, should there

src/interfaces/IExecution.sol renamed to src/interfaces/IExecutionModule.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct ExecutionManifest {
3131
bytes4[] interfaceIds;
3232
}
3333

34-
interface IExecution is IModule {
34+
interface IExecutionModule is IModule {
3535
/// @notice Describe the contents and intended configuration of the module.
3636
/// @dev This manifest MUST stay constant over time.
3737
/// @return A manifest describing the contents and intended configuration of the module.

0 commit comments

Comments
 (0)