@@ -8,6 +8,8 @@ import {SignatureChecker} from "@openzeppelin/contracts/utils/cryptography/Signa
88import {IModule, ModuleMetadata} from "../../interfaces/IModule.sol " ;
99import {IValidationModule} from "../../interfaces/IValidationModule.sol " ;
1010import {BaseModule} from "../BaseModule.sol " ;
11+
12+ import {ReplaySafeWrapper} from "../ReplaySafeWrapper.sol " ;
1113import {ISingleSignerValidationModule} from "./ISingleSignerValidationModule.sol " ;
1214
1315/// @title ECSDA Validation
@@ -18,12 +20,11 @@ import {ISingleSignerValidationModule} from "./ISingleSignerValidationModule.sol
1820/// the account. Account states are to be retrieved from this global singleton directly.
1921///
2022/// - This validation supports ERC-1271. The signature is valid if it is signed by the owner's private key
21- /// (if the owner is an EOA) or if it is a valid ERC-1271 signature from the
22- /// owner (if the owner is a contract).
23+ /// (if the owner is an EOA) or if it is a valid ERC-1271 signature from the owner (if the owner is a contract).
2324///
2425/// - This validation supports composition that other validation can relay on entities in this validation
2526/// to validate partially or fully.
26- contract SingleSignerValidationModule is ISingleSignerValidationModule , BaseModule {
27+ contract SingleSignerValidationModule is ISingleSignerValidationModule , ReplaySafeWrapper , BaseModule {
2728 using MessageHashUtils for bytes32 ;
2829
2930 string internal constant _NAME = "SingleSigner Validation " ;
@@ -94,14 +95,17 @@ contract SingleSignerValidationModule is ISingleSignerValidationModule, BaseModu
9495 /// @inheritdoc IValidationModule
9596 /// @dev The signature is valid if it is signed by the owner's private key
9697 /// (if the owner is an EOA) or if it is a valid ERC-1271 signature from the
97- /// owner (if the owner is a contract). Note that the signature is wrapped in an EIP-191 message
98+ /// owner (if the owner is a contract).
99+ /// Note that the digest is wrapped in an EIP-712 struct to prevent cross-account replay attacks. The
100+ /// replay-safe hash may be retrieved by calling the public function `replaySafeHash`.
98101 function validateSignature (address account , uint32 entityId , address , bytes32 digest , bytes calldata signature )
99102 external
100103 view
101104 override
102105 returns (bytes4 )
103106 {
104- if (SignatureChecker.isValidSignatureNow (signers[entityId][account], digest, signature)) {
107+ bytes32 _replaySafeHash = replaySafeHash (account, digest);
108+ if (SignatureChecker.isValidSignatureNow (signers[entityId][account], _replaySafeHash, signature)) {
105109 return _1271_MAGIC_VALUE;
106110 }
107111 return _1271_INVALID;
0 commit comments