Skip to content

Commit

Permalink
create DomainLib
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Nov 3, 2024
1 parent 2b18148 commit 841b156
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 84 deletions.
24 changes: 2 additions & 22 deletions src/lib/ClaimProcessorLib.sol
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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;
Expand Down Expand Up @@ -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)
}
}
}
6 changes: 4 additions & 2 deletions src/lib/ClaimProcessorLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/lib/ConstructorLogic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand All @@ -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.
Expand Down
77 changes: 77 additions & 0 deletions src/lib/DomainLib.sol
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
76 changes: 21 additions & 55 deletions src/lib/HashLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}
}
}
4 changes: 2 additions & 2 deletions src/lib/ValidityLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";

/**
Expand All @@ -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;

Expand Down

0 comments on commit 841b156

Please sign in to comment.