-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(SingleSignerValidation): add replay safe hash and utility contra…
…cts for EIP-712 in modules [2/2] (#141)
- Loading branch information
Showing
6 changed files
with
89 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
// A base for modules that use EIP-712 structured data signing. | ||
// | ||
// Unlike other EIP712 libraries, this mixin uses the salt field to hold the account address. | ||
// | ||
// It omits the name and version from the EIP-712 domain, as modules are intended to be deployed as | ||
// immutable singletons, thus a different versions and instances would have a different module address. | ||
// | ||
// Due to depending on the account address to calculate the domain separator, this abstract contract does not | ||
// implement EIP-5267, as the domain retrieval function does not provide a parameter to use for the account address | ||
// (internally the verifyingContract), and the computed `msg.sender` for an `eth_call` without an override is | ||
// address(0). | ||
abstract contract ModuleEIP712 { | ||
// keccak256( | ||
// "EIP712Domain(uint256 chainId,address verifyingContract,bytes32 salt)" | ||
// ) | ||
bytes32 private constant _DOMAIN_SEPARATOR_TYPEHASH = | ||
0x71062c282d40422f744945d587dbf4ecfd4f9cfad1d35d62c944373009d96162; | ||
|
||
function _domainSeparator(address account) internal view returns (bytes32) { | ||
return keccak256( | ||
abi.encode( | ||
_DOMAIN_SEPARATOR_TYPEHASH, block.chainid, address(this), bytes32(uint256(uint160(account))) | ||
) | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// SPDX-License-Identifier: UNLICENSED | ||
pragma solidity ^0.8.25; | ||
|
||
import {ModuleEIP712} from "./ModuleEIP712.sol"; | ||
|
||
import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; | ||
|
||
// A contract mixin for modules that wish to use EIP-712 to wrap the hashes sent to the EIP-1271 function | ||
// `isValidSignature`. | ||
// This makes signatures generated by owners of contract accounts non-replayable across multiple accounts owned by | ||
// the same owner. | ||
abstract contract ReplaySafeWrapper is ModuleEIP712 { | ||
// keccak256("ReplaySafeHash(bytes32 hash)") | ||
bytes32 private constant _REPLAY_SAFE_HASH_TYPEHASH = | ||
0x294a8735843d4afb4f017c76faf3b7731def145ed0025fc9b1d5ce30adf113ff; | ||
|
||
/// @notice Wraps a hash in an EIP-712 envelope to prevent cross-account replay attacks. | ||
/// Uses the ModuleEIP712 domain separator, which includes the chainId, module address, and account address. | ||
/// @param account The account that will validate the message hash. | ||
/// @param hash The hash to wrap. | ||
/// @return The the replay-safe hash, computed by wrapping the input hash in an EIP-712 struct. | ||
function replaySafeHash(address account, bytes32 hash) public view virtual returns (bytes32) { | ||
return MessageHashUtils.toTypedDataHash({ | ||
domainSeparator: _domainSeparator(account), | ||
structHash: _hashStruct(hash) | ||
}); | ||
} | ||
|
||
function _hashStruct(bytes32 hash) internal view virtual returns (bytes32) { | ||
return keccak256(abi.encode(_REPLAY_SAFE_HASH_TYPEHASH, hash)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters