From 841b156e48ede105277548be56a5b34e1ffb48f1 Mon Sep 17 00:00:00 2001 From: 0age <37939117+0age@users.noreply.github.com> Date: Sun, 3 Nov 2024 10:05:33 -0800 Subject: [PATCH] create DomainLib --- src/lib/ClaimProcessorLib.sol | 24 +--------- src/lib/ClaimProcessorLogic.sol | 6 ++- src/lib/ConstructorLogic.sol | 6 +-- src/lib/DomainLib.sol | 77 +++++++++++++++++++++++++++++++++ src/lib/HashLib.sol | 76 +++++++++----------------------- src/lib/ValidityLib.sol | 4 +- 6 files changed, 109 insertions(+), 84 deletions(-) create mode 100644 src/lib/DomainLib.sol diff --git a/src/lib/ClaimProcessorLib.sol b/src/lib/ClaimProcessorLib.sol index e891ffc..837928d 100644 --- a/src/lib/ClaimProcessorLib.sol +++ b/src/lib/ClaimProcessorLib.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.27; -import { COMPACT_TYPEHASH, BATCH_COMPACT_TYPEHASH, MULTICHAIN_COMPACT_TYPEHASH } from "../types/EIP712Types.sol"; import { SplitComponent, BatchClaimComponent, SplitBatchClaimComponent } from "../types/Components.sol"; import { EfficiencyLib } from "./EfficiencyLib.sol"; import { EventLib } from "./EventLib.sol"; +import { HashLib } from "./HashLib.sol"; import { IdLib } from "./IdLib.sol"; import { RegistrationLib } from "./RegistrationLib.sol"; import { ValidityLib } from "./ValidityLib.sol"; @@ -27,6 +27,7 @@ library ClaimProcessorLib { using EfficiencyLib for uint256; using EfficiencyLib for bytes32; using EventLib for address; + using HashLib for uint256; using IdLib for uint256; using ValidityLib for uint256; using ValidityLib for uint96; @@ -739,25 +740,4 @@ library ClaimProcessorLib { ) internal returns (bool) { return messageHash.processSplitBatchClaimWithQualificationAndSponsorDomain(messageHash, calldataPointer, offsetToId, sponsorDomain, typehash, domainSeparator, operation); } - - /** - * @notice Internal pure function for retrieving EIP-712 typehashes where no witness data is - * provided, returning the corresponding typehash based on the index provided. The available - * typehashes are: - * - 0: COMPACT_TYPEHASH - * - 1: BATCH_COMPACT_TYPEHASH - * - 2: MULTICHAIN_COMPACT_TYPEHASH - * @param i The index of the EIP-712 typehash to retrieve. - * @return typehash The corresponding EIP-712 typehash. - */ - function typehashes(uint256 i) internal pure returns (bytes32 typehash) { - assembly ("memory-safe") { - let m := mload(0x40) - mstore(0, COMPACT_TYPEHASH) - mstore(0x20, BATCH_COMPACT_TYPEHASH) - mstore(0x40, MULTICHAIN_COMPACT_TYPEHASH) - typehash := mload(shl(5, i)) - mstore(0x40, m) - } - } } diff --git a/src/lib/ClaimProcessorLogic.sol b/src/lib/ClaimProcessorLogic.sol index 6dc41b5..76a2c07 100644 --- a/src/lib/ClaimProcessorLogic.sol +++ b/src/lib/ClaimProcessorLogic.sol @@ -51,9 +51,10 @@ import { import { ClaimHashLib } from "./ClaimHashLib.sol"; import { ClaimProcessorLib } from "./ClaimProcessorLib.sol"; +import { DomainLib } from "./DomainLib.sol"; +import { HashLib } from "./HashLib.sol"; import { EfficiencyLib } from "./EfficiencyLib.sol"; import { FunctionCastLib } from "./FunctionCastLib.sol"; -import { HashLib } from "./HashLib.sol"; import { SharedLogic } from "./SharedLogic.sol"; import { ValidityLib } from "./ValidityLib.sol"; @@ -117,12 +118,13 @@ contract ClaimProcessorLogic is SharedLogic { using ClaimHashLib for ExogenousQualifiedSplitBatchMultichainClaim; using ClaimHashLib for ExogenousQualifiedSplitBatchMultichainClaimWithWitness; using ClaimProcessorLib for uint256; + using DomainLib for uint256; + using HashLib for uint256; using EfficiencyLib for uint256; using FunctionCastLib for function(bytes32, uint256, uint256, bytes32, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool); using FunctionCastLib for function(bytes32, uint256, uint256, bytes32, bytes32, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool); using FunctionCastLib for function(bytes32, bytes32, uint256, uint256, bytes32, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool); using FunctionCastLib for function(bytes32, bytes32, uint256, uint256, bytes32, bytes32, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool); - using HashLib for uint256; using ValidityLib for uint96; using ValidityLib for uint256; using ValidityLib for bytes32; diff --git a/src/lib/ConstructorLogic.sol b/src/lib/ConstructorLogic.sol index 0f98468..04ae01b 100644 --- a/src/lib/ConstructorLogic.sol +++ b/src/lib/ConstructorLogic.sol @@ -5,7 +5,7 @@ import { Lock } from "../types/Lock.sol"; import { ResetPeriod } from "../types/ResetPeriod.sol"; import { Scope } from "../types/Scope.sol"; -import { HashLib } from "./HashLib.sol"; +import { DomainLib } from "./DomainLib.sol"; import { IdLib } from "./IdLib.sol"; import { MetadataRenderer } from "./MetadataRenderer.sol"; @@ -21,8 +21,8 @@ import { Tstorish } from "tstorish/Tstorish.sol"; * for activating TSTORE support if the chain eventually adds support for it. */ contract ConstructorLogic is Tstorish { - using HashLib for bytes32; - using HashLib for uint256; + using DomainLib for bytes32; + using DomainLib for uint256; using IdLib for uint256; // Address of the Permit2 contract, optionally used for depositing ERC20 tokens. diff --git a/src/lib/DomainLib.sol b/src/lib/DomainLib.sol new file mode 100644 index 0000000..509f0ab --- /dev/null +++ b/src/lib/DomainLib.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +/** + * @title DomainLib + * @notice Libray contract implementing logic for deriving domain hashes. + */ +library DomainLib { + /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. + bytes32 internal constant _DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; + + /// @dev `keccak256(bytes("The Compact"))`. + bytes32 internal constant _NAME_HASH = 0x5e6f7b4e1ac3d625bac418bc955510b3e054cb6cc23cc27885107f080180b292; + + /// @dev `keccak256("0")`. + bytes32 internal constant _VERSION_HASH = 0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d; + + function toLatest(bytes32 initialDomainSeparator, uint256 initialChainId) internal view returns (bytes32 domainSeparator) { + // Set the initial domain separator as the default domain separator. + domainSeparator = initialDomainSeparator; + + assembly ("memory-safe") { + // Rederive the domain separator if the initial chain ID differs from the current one. + if xor(chainid(), initialChainId) { + // Retrieve the free memory pointer. + let m := mload(0x40) + + // Prepare domain data: EIP-712 typehash, name hash, version hash, chain ID, and verifying contract. + mstore(m, _DOMAIN_TYPEHASH) + mstore(add(m, 0x20), _NAME_HASH) + mstore(add(m, 0x40), _VERSION_HASH) + mstore(add(m, 0x60), chainid()) + mstore(add(m, 0x80), address()) + + // Derive the domain separator. + domainSeparator := keccak256(m, 0xa0) + } + } + } + + function toNotarizedDomainSeparator(uint256 notarizedChainId) internal view returns (bytes32 notarizedDomainSeparator) { + assembly ("memory-safe") { + // Retrieve the free memory pointer. + let m := mload(0x40) + + // Prepare domain data: EIP-712 typehash, name hash, version hash, notarizing chain ID, and verifying contract. + mstore(m, _DOMAIN_TYPEHASH) + mstore(add(m, 0x20), _NAME_HASH) + mstore(add(m, 0x40), _VERSION_HASH) + mstore(add(m, 0x60), notarizedChainId) + mstore(add(m, 0x80), address()) + + // Derive the domain separator. + notarizedDomainSeparator := keccak256(m, 0xa0) + } + } + + function withDomain(bytes32 messageHash, bytes32 domainSeparator) internal pure returns (bytes32 domainHash) { + assembly ("memory-safe") { + // Retrieve and cache the free memory pointer. + let m := mload(0x40) + + // Prepare the 712 prefix. + mstore(0, 0x1901) + + // Prepare the domain separator. + mstore(0x20, domainSeparator) + + // Prepare the message hash and compute the domain hash. + mstore(0x40, messageHash) + domainHash := keccak256(0x1e, 0x42) + + // Restore the free memory pointer. + mstore(0x40, m) + } + } +} diff --git a/src/lib/HashLib.sol b/src/lib/HashLib.sol index c8686a2..af73392 100644 --- a/src/lib/HashLib.sol +++ b/src/lib/HashLib.sol @@ -43,61 +43,6 @@ library HashLib { using EfficiencyLib for uint256; using FunctionCastLib for function (BatchTransfer calldata, uint256) internal view returns (bytes32); - /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`. - bytes32 internal constant _DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; - - /// @dev `keccak256(bytes("The Compact"))`. - bytes32 internal constant _NAME_HASH = 0x5e6f7b4e1ac3d625bac418bc955510b3e054cb6cc23cc27885107f080180b292; - - /// @dev `keccak256("0")`. - bytes32 internal constant _VERSION_HASH = 0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d; - - function toLatest(bytes32 initialDomainSeparator, uint256 initialChainId) internal view returns (bytes32 domainSeparator) { - domainSeparator = initialDomainSeparator; - - assembly ("memory-safe") { - // Prepare the domain separator, rederiving it if necessary. - if xor(chainid(), initialChainId) { - let m := mload(0x40) // Grab the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), _NAME_HASH) - mstore(add(m, 0x40), _VERSION_HASH) - mstore(add(m, 0x60), chainid()) - mstore(add(m, 0x80), address()) - domainSeparator := keccak256(m, 0xa0) - } - } - } - - function toNotarizedDomainSeparator(uint256 notarizedChainId) internal view returns (bytes32 notarizedDomainSeparator) { - assembly ("memory-safe") { - let m := mload(0x40) // Grab the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), _NAME_HASH) - mstore(add(m, 0x40), _VERSION_HASH) - mstore(add(m, 0x60), notarizedChainId) - mstore(add(m, 0x80), address()) - notarizedDomainSeparator := keccak256(m, 0xa0) - } - } - - function withDomain(bytes32 messageHash, bytes32 domainSeparator) internal pure returns (bytes32 domainHash) { - assembly ("memory-safe") { - let m := mload(0x40) // Grab the free memory pointer. - - // Prepare the 712 prefix. - mstore(0, 0x1901) - - mstore(0x20, domainSeparator) - - // Prepare the message hash and compute the domain hash. - mstore(0x40, messageHash) - domainHash := keccak256(0x1e, 0x42) - - mstore(0x40, m) // Restore the free memory pointer. - } - } - function toBasicTransferMessageHash(BasicTransfer calldata transfer) internal view returns (bytes32 messageHash) { assembly ("memory-safe") { let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied. @@ -472,4 +417,25 @@ library HashLib { qualificationMessageHash := keccak256(m, add(0x40, qualificationPayloadLength)) } } + + /** + * @notice Internal pure function for retrieving EIP-712 typehashes where no witness data is + * provided, returning the corresponding typehash based on the index provided. The available + * typehashes are: + * - 0: COMPACT_TYPEHASH + * - 1: BATCH_COMPACT_TYPEHASH + * - 2: MULTICHAIN_COMPACT_TYPEHASH + * @param i The index of the EIP-712 typehash to retrieve. + * @return typehash The corresponding EIP-712 typehash. + */ + function typehashes(uint256 i) internal pure returns (bytes32 typehash) { + assembly ("memory-safe") { + let m := mload(0x40) + mstore(0, COMPACT_TYPEHASH) + mstore(0x20, BATCH_COMPACT_TYPEHASH) + mstore(0x40, MULTICHAIN_COMPACT_TYPEHASH) + typehash := mload(shl(5, i)) + mstore(0x40, m) + } + } } diff --git a/src/lib/ValidityLib.sol b/src/lib/ValidityLib.sol index be1d269..d88ec1e 100644 --- a/src/lib/ValidityLib.sol +++ b/src/lib/ValidityLib.sol @@ -6,7 +6,7 @@ import { Scope } from "../types/Scope.sol"; import { IdLib } from "./IdLib.sol"; import { ConsumerLib } from "./ConsumerLib.sol"; import { EfficiencyLib } from "./EfficiencyLib.sol"; -import { HashLib } from "./HashLib.sol"; +import { DomainLib } from "./DomainLib.sol"; import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol"; /** @@ -19,7 +19,7 @@ library ValidityLib { using IdLib for uint256; using ConsumerLib for uint256; using EfficiencyLib for bool; - using HashLib for bytes32; + using DomainLib for bytes32; using SignatureCheckerLib for address; using ValidityLib for uint256;