diff --git a/packages/1155-contracts/src/delegation/ZoraCreator1155Attribution.sol b/packages/1155-contracts/src/delegation/ZoraCreator1155Attribution.sol index fac10925d..9fd3df331 100644 --- a/packages/1155-contracts/src/delegation/ZoraCreator1155Attribution.sol +++ b/packages/1155-contracts/src/delegation/ZoraCreator1155Attribution.sol @@ -95,14 +95,60 @@ library ZoraCreator1155Attribution { string internal constant VERSION_2 = "2"; bytes32 internal constant HASHED_VERSION_2 = keccak256(bytes(VERSION_2)); - bytes32 constant ATTRIBUTION_DOMAIN_V1 = - keccak256( - "CreatorAttribution(TokenCreationConfig tokenConfig,uint32 uid,uint32 version,bool deleted)TokenCreationConfig(string tokenURI,uint256 maxSupply,uint64 maxTokensPerAddress,uint96 pricePerToken,uint64 mintStart,uint64 mintDuration,uint32 royaltyMintSchedule,uint32 royaltyBPS,address royaltyRecipient,address fixedPriceMinter)" + /** + * @dev Returns the domain separator for the specified chain. + */ + function _domainSeparatorV4(uint256 chainId, address verifyingContract, bytes32 hashedName, bytes32 hashedVersion) private pure returns (bytes32) { + return _buildDomainSeparator(hashedName, hashedVersion, verifyingContract, chainId); + } + + function _buildDomainSeparator(bytes32 nameHash, bytes32 versionHash, address verifyingContract, uint256 chainId) private pure returns (bytes32) { + return keccak256(abi.encode(TYPE_HASH, nameHash, versionHash, chainId, verifyingContract)); + } + + function _hashTypedDataV4( + bytes32 structHash, + bytes32 hashedName, + bytes32 hashedVersion, + address verifyingContract, + uint256 chainId + ) private pure returns (bytes32) { + return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(chainId, verifyingContract, hashedName, hashedVersion), structHash); + } + + function recoverSignerHashed( + bytes32 hashedPremintConfig, + bytes calldata signature, + address erc1155Contract, + bytes32 signatureVersion, + uint256 chainId + ) internal pure returns (address signatory) { + // first validate the signature - the creator must match the signer of the message + bytes32 digest = premintHashedTypeDataV4( + hashedPremintConfig, + // here we pass the current contract and chain id, ensuring that the message + // only works for the current chain and contract id + erc1155Contract, + signatureVersion, + chainId ); - bytes32 constant ATTRIBUTION_DOMAIN_V2 = + (signatory, ) = ECDSAUpgradeable.tryRecover(digest, signature); + } + + /// Gets hash data to sign for a premint. Allows specifying a different chain id and contract address so that the signature + /// can be verified on a different chain. + /// @param erc1155Contract Contract address that signature is to be verified against + /// @param chainId Chain id that signature is to be verified on + function premintHashedTypeDataV4(bytes32 structHash, address erc1155Contract, bytes32 signatureVersion, uint256 chainId) internal pure returns (bytes32) { + // build the struct hash to be signed + // here we pass the chain id, allowing the message to be signed for another chain + return _hashTypedDataV4(structHash, HASHED_NAME, signatureVersion, erc1155Contract, chainId); + } + + bytes32 constant ATTRIBUTION_DOMAIN_V1 = keccak256( - "CreatorAttribution(TokenCreationConfig tokenConfig,uint32 uid,uint32 version,bool deleted)TokenCreationConfig(string tokenURI,uint256 maxSupply,uint64 maxTokensPerAddress,uint96 pricePerToken,uint64 mintStart,uint64 mintDuration,uint32 royaltyBPS,address royaltyRecipient,address fixedPriceMinter,address createReferral)" + "CreatorAttribution(TokenCreationConfig tokenConfig,uint32 uid,uint32 version,bool deleted)TokenCreationConfig(string tokenURI,uint256 maxSupply,uint64 maxTokensPerAddress,uint96 pricePerToken,uint64 mintStart,uint64 mintDuration,uint32 royaltyMintSchedule,uint32 royaltyBPS,address royaltyRecipient,address fixedPriceMinter)" ); function hashPremint(PremintConfig memory premintConfig) internal pure returns (bytes32) { @@ -112,6 +158,11 @@ library ZoraCreator1155Attribution { ); } + bytes32 constant ATTRIBUTION_DOMAIN_V2 = + keccak256( + "CreatorAttribution(TokenCreationConfig tokenConfig,uint32 uid,uint32 version,bool deleted)TokenCreationConfig(string tokenURI,uint256 maxSupply,uint64 maxTokensPerAddress,uint96 pricePerToken,uint64 mintStart,uint64 mintDuration,uint32 royaltyBPS,address royaltyRecipient,address fixedPriceMinter,address createReferral)" + ); + function hashPremint(PremintConfigV2 memory premintConfig) internal pure returns (bytes32) { return keccak256( @@ -169,57 +220,6 @@ library ZoraCreator1155Attribution { bytes32 internal constant TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - function _buildDomainSeparator(bytes32 nameHash, bytes32 versionHash, address verifyingContract, uint256 chainId) private pure returns (bytes32) { - return keccak256(abi.encode(TYPE_HASH, nameHash, versionHash, chainId, verifyingContract)); - } - - /** - * @dev Returns the domain separator for the specified chain. - */ - function _domainSeparatorV4(uint256 chainId, address verifyingContract, bytes32 hashedName, bytes32 hashedVersion) private pure returns (bytes32) { - return _buildDomainSeparator(hashedName, hashedVersion, verifyingContract, chainId); - } - - function hashTypedDataV4( - bytes32 structHash, - bytes32 hashedName, - bytes32 hashedVersion, - address verifyingContract, - uint256 chainId - ) internal pure returns (bytes32) { - return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(chainId, verifyingContract, hashedName, hashedVersion), structHash); - } - - /// Gets hash data to sign for a premint. Allows specifying a different chain id and contract address so that the signature - /// can be verified on a different chain. - /// @param erc1155Contract Contract address that signature is to be verified against - /// @param chainId Chain id that signature is to be verified on - function premintHashedTypeDataV4(bytes32 structHash, address erc1155Contract, bytes32 signatureVersion, uint256 chainId) internal pure returns (bytes32) { - // build the struct hash to be signed - // here we pass the chain id, allowing the message to be signed for another chain - return hashTypedDataV4(structHash, HASHED_NAME, signatureVersion, erc1155Contract, chainId); - } - - function recoverSignerHashed( - bytes32 hashedPremintConfig, - bytes calldata signature, - address erc1155Contract, - bytes32 signatureVersion, - uint256 chainId - ) internal pure returns (address signatory) { - // first validate the signature - the creator must match the signer of the message - bytes32 digest = premintHashedTypeDataV4( - hashedPremintConfig, - // here we pass the current contract and chain id, ensuring that the message - // only works for the current chain and contract id - erc1155Contract, - signatureVersion, - chainId - ); - - (signatory, ) = ECDSAUpgradeable.tryRecover(digest, signature); - } - function _stringHash(string memory value) private pure returns (bytes32) { return keccak256(bytes(value)); }