Skip to content

Commit 664d49c

Browse files
committed
todo: validator selection
1 parent 342cfb4 commit 664d49c

1 file changed

Lines changed: 127 additions & 5 deletions

File tree

src/SimpleModular7702Account.sol

Lines changed: 127 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,20 @@ import "oz-5.1/utils/cryptography/ECDSA.sol";
99
import {SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILED} from "aa-0.8/core/Helpers.sol";
1010
import "aa-0.8/core/BaseAccount.sol";
1111
import "aa-0.8/interfaces/IEntryPoint.sol";
12+
import "nexus-1.2/interfaces/IERC7579Account.sol";
13+
import {MODULE_TYPE_VALIDATOR, MODULE_TYPE_EXECUTOR} from "nexus-1.2/types/Constants.sol";
14+
import "nexus-1.2/lib/ModeLib.sol";
15+
import "nexus-1.2/base/ExecutionHelper.sol";
16+
import "nexus-1.2/interfaces/base/IModuleManager.sol";
1217

1318
interface ISimpleModular7702Account {
14-
/// @custom:storage-location erc7201:simplemodular7702account.storage.main
1519
struct MainStorage {
1620
mapping(address => bool) validators;
1721
mapping(address => bool) executors;
1822
}
23+
24+
error NotFromEntryPoint();
25+
error NotFromEntryPointOrSelf();
1926
}
2027

2128
/**
@@ -28,22 +35,132 @@ contract SimpleModular7702Account is
2835
IERC1271,
2936
ERC1155Holder,
3037
ERC721Holder,
31-
ISimpleModular7702Account
38+
ISimpleModular7702Account,
39+
IERC7579Account,
40+
ExecutionHelper,
41+
IModuleManager
3242
{
33-
/// @dev cast index-erc7201 simplemodular7702account.storage.main
34-
bytes32 private constant MAIN_STORAGE_SLOT = 0xa5dd7474afa9beb4173131c6b804bd94e1d7f3c0417e29327db85be14fbe0000;
43+
using ModeLib for ExecutionMode;
44+
45+
/// @dev cast index-erc7201 ethaccount.SimpleModular7702Account.0.0.1
46+
bytes32 private constant MAIN_STORAGE_SLOT = 0x2518c257f63affc9ee9dcce928ffdd39a87f98d73db3e9927c2e403aea47f400;
3547

3648
function _getMainStorage() private pure returns (MainStorage storage $) {
3749
assembly {
3850
$.slot := MAIN_STORAGE_SLOT
3951
}
4052
}
4153

54+
modifier onlyEntryPoint() {
55+
require(msg.sender == address(entryPoint()), NotFromEntryPoint());
56+
_;
57+
}
58+
59+
modifier onlyEntryPointOrSelf() {
60+
require(msg.sender == address(entryPoint()) || msg.sender == address(this), NotFromEntryPointOrSelf());
61+
_;
62+
}
63+
64+
modifier onlyExecutorModule() virtual {
65+
require(_getMainStorage().executors[msg.sender], InvalidModule(msg.sender));
66+
_;
67+
}
68+
4269
// address of entryPoint v0.8
4370
function entryPoint() public pure override returns (IEntryPoint) {
4471
return IEntryPoint(0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108);
4572
}
4673

74+
function accountId() external pure virtual returns (string memory) {
75+
return "ethaccount.SimpleModular7702Account.0.0.1";
76+
}
77+
78+
function supportsModule(uint256 moduleTypeId) external view virtual returns (bool) {
79+
if (moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR) {
80+
return true;
81+
}
82+
return false;
83+
}
84+
85+
function supportsExecutionMode(ExecutionMode mode) external view virtual returns (bool isSupported) {
86+
(CallType callType, ExecType execType) = mode.decodeBasic();
87+
88+
// Return true if both the call type and execution type are supported.
89+
return (callType == CALLTYPE_SINGLE || callType == CALLTYPE_BATCH || callType == CALLTYPE_DELEGATECALL)
90+
&& (execType == EXECTYPE_DEFAULT || execType == EXECTYPE_TRY);
91+
}
92+
93+
function execute(ExecutionMode mode, bytes calldata executionCalldata) external payable onlyEntryPoint {
94+
(CallType callType, ExecType execType) = mode.decodeBasic();
95+
if (callType == CALLTYPE_SINGLE) {
96+
_handleSingleExecution(executionCalldata, execType);
97+
} else if (callType == CALLTYPE_BATCH) {
98+
_handleBatchExecution(executionCalldata, execType);
99+
} else if (callType == CALLTYPE_DELEGATECALL) {
100+
_handleDelegateCallExecution(executionCalldata, execType);
101+
} else {
102+
revert UnsupportedCallType(callType);
103+
}
104+
}
105+
106+
function executeFromExecutor(ExecutionMode mode, bytes calldata executionCalldata)
107+
external
108+
payable
109+
onlyExecutorModule
110+
returns (bytes[] memory returnData)
111+
{
112+
(CallType callType, ExecType execType) = mode.decodeBasic();
113+
// check if calltype is batch or single or delegate call
114+
if (callType == CALLTYPE_SINGLE) {
115+
returnData = _handleSingleExecutionAndReturnData(executionCalldata, execType);
116+
} else if (callType == CALLTYPE_BATCH) {
117+
returnData = _handleBatchExecutionAndReturnData(executionCalldata, execType);
118+
} else if (callType == CALLTYPE_DELEGATECALL) {
119+
returnData = _handleDelegateCallExecutionAndReturnData(executionCalldata, execType);
120+
} else {
121+
revert UnsupportedCallType(callType);
122+
}
123+
}
124+
125+
function installModule(uint256 moduleTypeId, address module, bytes calldata initData)
126+
external
127+
payable
128+
virtual
129+
override
130+
onlyEntryPointOrSelf
131+
{
132+
// TODO: implement module install
133+
emit ModuleInstalled(moduleTypeId, module);
134+
}
135+
136+
function uninstallModule(uint256 moduleTypeId, address module, bytes calldata deInitData)
137+
external
138+
payable
139+
onlyEntryPointOrSelf
140+
{
141+
require(_isModuleInstalled(moduleTypeId, module), ModuleNotInstalled(moduleTypeId, module));
142+
143+
if (moduleTypeId == MODULE_TYPE_VALIDATOR) {
144+
// TODO: implement validator uninstall
145+
} else if (moduleTypeId == MODULE_TYPE_EXECUTOR) {
146+
// TODO: implement executor uninstall
147+
}
148+
emit ModuleUninstalled(moduleTypeId, module);
149+
}
150+
151+
function _isModuleInstalled(uint256 moduleTypeId, address module) internal view returns (bool) {
152+
if (moduleTypeId == MODULE_TYPE_VALIDATOR) {
153+
return _getMainStorage().validators[module];
154+
} else if (moduleTypeId == MODULE_TYPE_EXECUTOR) {
155+
return _getMainStorage().executors[module];
156+
}
157+
return false;
158+
}
159+
160+
function isModuleInstalled(uint256 moduleTypeId, address module, bytes calldata) external view returns (bool) {
161+
return _isModuleInstalled(moduleTypeId, module);
162+
}
163+
47164
/**
48165
* Make this account callable through ERC-4337 EntryPoint.
49166
* The UserOperation should be signed by this account's private key.
@@ -57,7 +174,12 @@ contract SimpleModular7702Account is
57174
return _checkSignature(userOpHash, userOp.signature) ? SIG_VALIDATION_SUCCESS : SIG_VALIDATION_FAILED;
58175
}
59176

60-
function isValidSignature(bytes32 hash, bytes memory signature) public view returns (bytes4 magicValue) {
177+
function isValidSignature(bytes32 hash, bytes memory signature)
178+
public
179+
view
180+
override(IERC1271, IERC7579Account)
181+
returns (bytes4 magicValue)
182+
{
61183
return _checkSignature(hash, signature) ? this.isValidSignature.selector : bytes4(0xffffffff);
62184
}
63185

0 commit comments

Comments
 (0)