@@ -9,13 +9,20 @@ import "oz-5.1/utils/cryptography/ECDSA.sol";
99import {SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILED} from "aa-0.8/core/Helpers.sol " ;
1010import "aa-0.8/core/BaseAccount.sol " ;
1111import "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
1318interface 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