@@ -11,7 +11,6 @@ import {Bytes} from "@openzeppelin/contracts/utils/Bytes.sol";
1111import {Packing} from "@openzeppelin/contracts/utils/Packing.sol " ;
1212import {Address} from "@openzeppelin/contracts/utils/Address.sol " ;
1313import {Calldata} from "@openzeppelin/contracts/utils/Calldata.sol " ;
14- import {ERC7739 } from "../../utils/cryptography/ERC7739.sol " ;
1514import {AccountCore} from "../AccountCore.sol " ;
1615
1716/**
@@ -43,7 +42,7 @@ import {AccountCore} from "../AccountCore.sol";
4342 */
4443abstract contract AccountERC7579 is
4544 AccountCore ,
46- ERC7739 ,
45+ IERC1271 ,
4746 IERC7579Execution ,
4847 IERC7579AccountConfig ,
4948 IERC7579ModuleConfig
@@ -145,12 +144,12 @@ abstract contract AccountERC7579 is
145144 return false ;
146145 }
147146
148- /// @dev Executes a transaction from the entry point or the account itself. See {_execute}.
147+ /// @inheritdoc IERC7579Execution
149148 function execute (bytes32 mode , bytes calldata executionCalldata ) public payable virtual onlyEntryPointOrSelf {
150149 _execute (Mode.wrap (mode), executionCalldata);
151150 }
152151
153- /// @dev Executes a transaction from the executor module. See {_execute}.
152+ /// @inheritdoc IERC7579Execution
154153 function executeFromExecutor (
155154 bytes32 mode ,
156155 bytes calldata executionCalldata
@@ -164,6 +163,30 @@ abstract contract AccountERC7579 is
164163 return _execute (Mode.wrap (mode), executionCalldata);
165164 }
166165
166+ /**
167+ * @dev Implement ERC-1271 through IERC7579Validator modules. If module based validation fails, fallback to
168+ * "native" validation by the abstract signer.
169+ *
170+ * NOTE: when combined with {ERC7739} (for example through {Account}), resolution ordering may have an impact
171+ * ({ERC7739} does not call super). Manual resolution might be necessary.
172+ */
173+ function isValidSignature (bytes32 hash , bytes calldata signature ) public view virtual override returns (bytes4 ) {
174+ // check signature length is enough for extraction
175+ if (signature.length >= 20 ) {
176+ (address module , bytes calldata innerSignature ) = _extractSignatureValidator (signature);
177+ // if module is not installed, skip
178+ if (isModuleInstalled (MODULE_TYPE_VALIDATOR, module, Calldata.emptyBytes ())) {
179+ // try validation, skip any revert
180+ try IERC7579Validator (module).isValidSignatureWithSender (address (this ), hash, innerSignature) returns (
181+ bytes4 magic
182+ ) {
183+ if (magic == IERC1271 .isValidSignature.selector ) return magic;
184+ } catch {}
185+ }
186+ }
187+ return bytes4 (0xffffffff );
188+ }
189+
167190 /**
168191 * @dev Validates a user operation with {_signableUserOpHash} and returns the validation data
169192 * if the module specified by the first 20 bytes of the nonce key is installed. Falls back to
@@ -182,26 +205,6 @@ abstract contract AccountERC7579 is
182205 : super ._validateUserOp (userOp, userOpHash);
183206 }
184207
185- /**
186- * @dev Lowest-level signature validation function. See {ERC7739-_rawSignatureValidation}.
187- *
188- * This function delegates the signature validation to a validation module if the first 20 bytes of the
189- * signature correspond to an installed validator module.
190- *
191- * See {_extractSignatureValidator} for the module extraction logic.
192- */
193- function _rawSignatureValidation (
194- bytes32 hash ,
195- bytes calldata signature
196- ) internal view virtual override returns (bool ) {
197- if (signature.length < 20 ) return false ;
198- (address module , bytes calldata innerSignature ) = _extractSignatureValidator (signature);
199- return
200- isModuleInstalled (MODULE_TYPE_VALIDATOR, module, Calldata.emptyBytes ()) &&
201- IERC7579Validator (module).isValidSignatureWithSender (address (this ), hash, innerSignature) ==
202- IERC1271 .isValidSignature.selector ;
203- }
204-
205208 /**
206209 * @dev ERC-7579 execution logic. See {supportsExecutionMode} for supported modes.
207210 *
@@ -387,4 +390,12 @@ abstract contract AccountERC7579 is
387390 ) internal pure virtual returns (bytes4 selector , bytes memory remaining ) {
388391 return (bytes4 (data), data.slice (4 ));
389392 }
393+
394+ /// @dev By default, only use the modules for validation of userOp and signature. Disable raw signatures.
395+ function _rawSignatureValidation (
396+ bytes32 /*hash*/ ,
397+ bytes calldata /*signature*/
398+ ) internal view virtual override returns (bool ) {
399+ return false ;
400+ }
390401}
0 commit comments