// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import { OrderParameters } from "./ConsiderationStructs.sol"; import { ConsiderationBase } from "./ConsiderationBase.sol"; import "./ConsiderationConstants.sol"; contract GettersAndDerivers is ConsiderationBase { constructor(address conduitController) ConsiderationBase(conduitController) {} function _deriveOrderHash( OrderParameters memory orderParameters, uint256 counter ) internal view returns (bytes32 orderHash) { bytes32 typeHash = _ORDER_TYPEHASH; assembly { let typeHashPtr := sub(orderParameters, OneWord) let previousValue := mload(typeHashPtr) mstore(typeHashPtr, typeHash) let counterPtr := add( orderParameters, OrderParameters_counter_offset ) let counterDataPtr := mload(counterPtr) mstore(counterPtr, counter) orderHash := keccak256(typeHashPtr, EIP712_Order_size) mstore(typeHashPtr, previousValue) mstore(counterPtr, counterDataPtr) } } function _deriveConduit(bytes32 conduitKey) internal view returns (address conduit) { // Read conduit controller address from runtime and place on the stack. address conduitController = address(_CONDUIT_CONTROLLER); // Read conduit creation code hash from runtime and place on the stack. bytes32 conduitCreationCodeHash = _CONDUIT_CREATION_CODE_HASH; // Leverage scratch space to perform an efficient hash. assembly { // Retrieve the free memory pointer; it will be replaced afterwards. let freeMemoryPointer := mload(FreeMemoryPointerSlot) // Place the control character and the conduit controller in scratch // space; note that eleven bytes at the beginning are left unused. mstore(0, or(MaskOverByteTwelve, conduitController)) // Place the conduit key in the next region of scratch space. mstore(OneWord, conduitKey) // Place conduit creation code hash in free memory pointer location. mstore(TwoWords, conduitCreationCodeHash) // Derive conduit by hashing and applying a mask over last 20 bytes. conduit := and( // Hash the relevant region. keccak256( // The region starts at memory pointer 11. Create2AddressDerivation_ptr, // The region is 85 bytes long (1 + 20 + 32 + 32). Create2AddressDerivation_length ), // The address equals the last twenty bytes of the hash. MaskOverLastTwentyBytes ) // Restore the free memory pointer. mstore(FreeMemoryPointerSlot, freeMemoryPointer) } } /** * @dev Internal view function to get the EIP-712 domain separator. If the * chainId matches the chainId set on deployment, the cached domain * separator will be returned; otherwise, it will be derived from * scratch. * * @return The domain separator. */ function _domainSeparator() internal view returns (bytes32) { // prettier-ignore return block.chainid == _CHAIN_ID ? _DOMAIN_SEPARATOR : _deriveDomainSeparator(); } /** * @dev Internal view function to retrieve configuration information for * this contract. * * @return version The contract version. * @return domainSeparator The domain separator for this contract. * @return conduitController The conduit Controller set for this contract. */ function _information() internal view returns ( string memory version, bytes32 domainSeparator, address conduitController ) { // Derive the domain separator. domainSeparator = _domainSeparator(); // Declare variable as immutables cannot be accessed within assembly. conduitController = address(_CONDUIT_CONTROLLER); // Allocate a string with the intended length. version = new string(Version_length); // Set the version as data on the newly allocated string. assembly { mstore(add(version, OneWord), shl(Version_shift, Version)) } } /** * @dev Internal pure function to efficiently derive an digest to sign for * an order in accordance with EIP-712. * * @param domainSeparator The domain separator. * @param orderHash The order hash. * * @return value The hash. */ function _deriveEIP712Digest(bytes32 domainSeparator, bytes32 orderHash) internal pure returns (bytes32 value) { // Leverage scratch space to perform an efficient hash. assembly { // Place the EIP-712 prefix at the start of scratch space. mstore(0, EIP_712_PREFIX) // Place the domain separator in the next region of scratch space. mstore(EIP712_DomainSeparator_offset, domainSeparator) // Place the order hash in scratch space, spilling into the first // two bytes of the free memory pointer — this should never be set // as memory cannot be expanded to that size, and will be zeroed out // after the hash is performed. mstore(EIP712_OrderHash_offset, orderHash) // Hash the relevant region (65 bytes). value := keccak256(0, EIP712_DigestPayload_size) // Clear out the dirtied bits in the memory pointer. mstore(EIP712_OrderHash_offset, 0) } } }