Skip to content

Commit

Permalink
Move interfaces/entities/utils to shared-contracts (#264)
Browse files Browse the repository at this point in the history
* move to shared contracts

* added a changeset
  • Loading branch information
oveddan authored Mar 20, 2024
1 parent 4327a77 commit 079a596
Show file tree
Hide file tree
Showing 36 changed files with 689 additions and 393 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-brooms-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zoralabs/zora-1155-contracts": patch
---

Moved shared functionality into shared-contracts. premintWithSignerContract takes firstMinter as an argument
2 changes: 2 additions & 0 deletions packages/1155-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
"solmate": "6.1.0",
"forge-std": "https://github.com/foundry-rs/forge-std#705263c95892a906d7af65f0f73ce8a4a0c80b80",
"ds-test": "https://github.com/dapphub/ds-test#cd98eff28324bfac652e63a239a60632a761790b",
"@zoralabs/mints-contracts": "*",
"@zoralabs/protocol-rewards": "*",
"@zoralabs/shared-contracts": "*",
"@zoralabs/openzeppelin-contracts-upgradeable": "4.8.4",
"@openzeppelin/contracts": "4.9.2"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/1155-contracts/remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ ds-test/=node_modules/ds-test/src/
forge-std/=node_modules/forge-std/src/
@zoralabs/openzeppelin-contracts-upgradeable/=node_modules/@zoralabs/openzeppelin-contracts-upgradeable/
@zoralabs/protocol-rewards/src/=node_modules/@zoralabs/protocol-rewards/src/
@zoralabs/mints-contracts/src/=node_modules/@zoralabs/mints-contracts/src/
@zoralabs/shared-contracts/=node_modules/@zoralabs/shared-contracts/src/
@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/
_imagine=_imagine/
solemate/=/node_modules/solemate/src/
Expand Down
112 changes: 8 additions & 104 deletions packages/1155-contracts/src/delegation/ZoraCreator1155Attribution.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,100 +7,14 @@ import {IZoraCreator1155Errors} from "../interfaces/IZoraCreator1155Errors.sol";
import {ICreatorRoyaltiesControl} from "../interfaces/ICreatorRoyaltiesControl.sol";
import {ECDSAUpgradeable} from "@zoralabs/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/ECDSAUpgradeable.sol";
import {ZoraCreatorFixedPriceSaleStrategy} from "../minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.sol";
import {PremintEncoding} from "@zoralabs/shared-contracts/premint/PremintEncoding.sol";
import {IERC1271} from "../interfaces/IERC1271.sol";

struct ContractCreationConfig {
// Creator/admin of the created contract. Must match the account that signed the message
address contractAdmin;
// Metadata URI for the created contract
string contractURI;
// Name of the created contract
string contractName;
}

struct PremintConfig {
// The config for the token to be created
TokenCreationConfig tokenConfig;
// Unique id of the token, used to ensure that multiple signatures can't be used to create the same intended token.
// only one signature per token id, scoped to the contract hash can be executed.
uint32 uid;
// Version of this premint, scoped to the uid and contract. Not used for logic in the contract, but used externally to track the newest version
uint32 version;
// If executing this signature results in preventing any signature with this uid from being minted.
bool deleted;
}

struct TokenCreationConfig {
// Metadata URI for the created token
string tokenURI;
// Max supply of the created token
uint256 maxSupply;
// Max tokens that can be minted for an address, 0 if unlimited
uint64 maxTokensPerAddress;
// Price per token in eth wei. 0 for a free mint.
uint96 pricePerToken;
// The start time of the mint, 0 for immediate. Prevents signatures from being used until the start time.
uint64 mintStart;
// The duration of the mint, starting from the first mint of this token. 0 for infinite
uint64 mintDuration;
// deperecated field; will be ignored.
uint32 royaltyMintSchedule;
// RoyaltyBPS for created tokens. The royalty amount in basis points for secondary sales.
uint32 royaltyBPS;
// This is the address that will be set on the `royaltyRecipient` for the created token on the 1155 contract,
// which is the address that receives creator rewards and secondary royalties for the token,
// and on the `fundsRecipient` on the ZoraCreatorFixedPriceSaleStrategy contract for the token,
// which is the address that receives paid mint funds for the token.
address royaltyRecipient;
// Fixed price minter address
address fixedPriceMinter;
}

struct PremintConfigV2 {
// The config for the token to be created
TokenCreationConfigV2 tokenConfig;
// Unique id of the token, used to ensure that multiple signatures can't be used to create the same intended token.
// only one signature per token id, scoped to the contract hash can be executed.
uint32 uid;
// Version of this premint, scoped to the uid and contract. Not used for logic in the contract, but used externally to track the newest version
uint32 version;
// If executing this signature results in preventing any signature with this uid from being minted.
bool deleted;
}

struct TokenCreationConfigV2 {
// Metadata URI for the created token
string tokenURI;
// Max supply of the created token
uint256 maxSupply;
// Max tokens that can be minted for an address, 0 if unlimited
uint64 maxTokensPerAddress;
// Price per token in eth wei. 0 for a free mint.
uint96 pricePerToken;
// The start time of the mint, 0 for immediate. Prevents signatures from being used until the start time.
uint64 mintStart;
// The duration of the mint, starting from the first mint of this token. 0 for infinite
uint64 mintDuration;
// RoyaltyBPS for created tokens. The royalty amount in basis points for secondary sales.
uint32 royaltyBPS;
// This is the address that will be set on the `royaltyRecipient` for the created token on the 1155 contract,
// which is the address that receives creator rewards and secondary royalties for the token,
// and on the `fundsRecipient` on the ZoraCreatorFixedPriceSaleStrategy contract for the token,
// which is the address that receives paid mint funds for the token.
address payoutRecipient;
// Fixed price minter address
address fixedPriceMinter;
// create referral
address createReferral;
}
import {PremintConfig, ContractCreationConfig, TokenCreationConfig, PremintConfigV2, TokenCreationConfigV2} from "@zoralabs/shared-contracts/entities/Premint.sol";

library ZoraCreator1155Attribution {
string internal constant NAME = "Preminter";
bytes32 internal constant HASHED_NAME = keccak256(bytes(NAME));
string internal constant VERSION_1 = "1";
bytes32 internal constant HASHED_VERSION_1 = keccak256(bytes(VERSION_1));
string internal constant VERSION_2 = "2";
bytes32 internal constant HASHED_VERSION_2 = keccak256(bytes(VERSION_2));

/**
* @dev Returns the domain separator for the specified chain.
Expand Down Expand Up @@ -164,7 +78,7 @@ library ZoraCreator1155Attribution {
(signatory, recoverError) = ECDSAUpgradeable.tryRecover(digest, signature);

if (recoverError != ECDSAUpgradeable.RecoverError.NoError) {
revert IZoraCreator1155Errors.InvalidSignature(recoverError);
revert IZoraCreator1155Errors.InvalidSignature();
}
}
}
Expand Down Expand Up @@ -367,16 +281,6 @@ library PremintTokenSetup {
}
}

library PremintEncoding {
function encodePremintV1(PremintConfig memory premintConfig) internal pure returns (bytes memory encodedPremintConfig, bytes32 hashedVersion) {
return (abi.encode(premintConfig), ZoraCreator1155Attribution.HASHED_VERSION_1);
}

function encodePremintV2(PremintConfigV2 memory premintConfig) internal pure returns (bytes memory encodedPremintConfig, bytes32 hashedVersion) {
return (abi.encode(premintConfig), ZoraCreator1155Attribution.HASHED_VERSION_2);
}
}

struct DecodedCreatorAttribution {
bytes32 structHash;
string domainName;
Expand Down Expand Up @@ -416,11 +320,11 @@ library DelegatedTokenCreation {
// based on version of encoded premint config, decode corresponding premint config,
// and then recover signer from the signature, and then build token setup actions based
// on the decoded premint config.
if (premintVersion == ZoraCreator1155Attribution.HASHED_VERSION_1) {
if (premintVersion == PremintEncoding.HASHED_VERSION_1) {
PremintConfig memory premintConfig = abi.decode(premintConfigEncoded, (PremintConfig));

creatorAttribution = recoverCreatorAttribution(
ZoraCreator1155Attribution.VERSION_1,
PremintEncoding.VERSION_1,
ZoraCreator1155Attribution.hashPremint(premintConfig),
tokenContract,
signature,
Expand All @@ -432,7 +336,7 @@ library DelegatedTokenCreation {
PremintConfigV2 memory premintConfig = abi.decode(premintConfigEncoded, (PremintConfigV2));

creatorAttribution = recoverCreatorAttribution(
ZoraCreator1155Attribution.VERSION_2,
PremintEncoding.VERSION_2,
ZoraCreator1155Attribution.hashPremint(premintConfig),
tokenContract,
signature,
Expand All @@ -449,8 +353,8 @@ library DelegatedTokenCreation {

function _supportedPremintSignatureVersions() internal pure returns (string[] memory versions) {
versions = new string[](2);
versions[0] = ZoraCreator1155Attribution.VERSION_1;
versions[1] = ZoraCreator1155Attribution.VERSION_2;
versions[0] = PremintEncoding.VERSION_1;
versions[1] = PremintEncoding.VERSION_2;
}

function recoverCreatorAttribution(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ import {ZoraCreatorFixedPriceSaleStrategy} from "../minters/fixed-price/ZoraCrea
import {IMinter1155} from "../interfaces/IMinter1155.sol";
import {ERC1155DelegationStorageV1} from "../delegation/ERC1155DelegationStorageV1.sol";
import {ZoraCreator1155PremintExecutorImplLib} from "./ZoraCreator1155PremintExecutorImplLib.sol";
import {PremintEncoding, ZoraCreator1155Attribution, DelegatedTokenCreation, ContractCreationConfig, PremintConfig, PremintConfigV2, TokenCreationConfig, TokenCreationConfigV2} from "./ZoraCreator1155Attribution.sol";
import {ZoraCreator1155Attribution, DelegatedTokenCreation} from "./ZoraCreator1155Attribution.sol";
import {PremintEncoding, EncodedPremintConfig} from "@zoralabs/shared-contracts/premint/PremintEncoding.sol";
import {ContractCreationConfig, PremintConfig, PremintConfigV2, TokenCreationConfig, TokenCreationConfigV2, MintArguments, PremintResult} from "@zoralabs/shared-contracts/entities/Premint.sol";
import {IZoraCreator1155PremintExecutor} from "../interfaces/IZoraCreator1155PremintExecutor.sol";
import {IZoraCreator1155DelegatedCreationLegacy, IHasSupportedPremintSignatureVersions} from "../interfaces/IZoraCreator1155DelegatedCreation.sol";
import {ZoraCreator1155FactoryImpl} from "../factory/ZoraCreator1155FactoryImpl.sol";
import {IRewardsErrors} from "@zoralabs/protocol-rewards/src/interfaces/IRewardsErrors.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";

/// @title Enables creation of and minting tokens on Zora1155 contracts transactions using eip-712 signatures.
/// Signature must provided by the contract creator, or an account that's permitted to create new tokens on the contract.
Expand Down Expand Up @@ -62,37 +66,36 @@ contract ZoraCreator1155PremintExecutorImpl is
bytes calldata signature,
uint256 quantityToMint,
MintArguments calldata mintArguments,
address firstMinter,
address signerContract
) public payable returns (PremintResult memory result) {
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV2(premintConfig);
address fixedPriceMinter = premintConfig.tokenConfig.fixedPriceMinter;
uint32 uid = premintConfig.uid;
result = ZoraCreator1155PremintExecutorImplLib.getOrCreateContractAndToken(
zora1155Factory,
contractConfig,
PremintEncoding.encodePremintV2(premintConfig),
signature,
firstMinter,
signerContract
);

// we wrap this here to get around stack too deep issues
{
result = ZoraCreator1155PremintExecutorImplLib.premint({
zora1155Factory: zora1155Factory,
contractConfig: contractConfig,
encodedPremintConfig: encodedPremint,
premintVersion: premintVersion,
signature: signature,
quantityToMint: quantityToMint,
fixedPriceMinter: fixedPriceMinter,
mintArguments: mintArguments,
signerContract: signerContract
});
if (quantityToMint > 0) {
ZoraCreator1155PremintExecutorImplLib.mintWithEth(
IZoraCreator1155(result.contractAddress),
premintConfig.tokenConfig.fixedPriceMinter,
result.tokenId,
quantityToMint,
mintArguments
);
}

{
emit PremintedV2({
contractAddress: result.contractAddress,
tokenId: result.tokenId,
createdNewContract: result.createdNewContract,
uid: uid,
minter: msg.sender,
quantityMinted: quantityToMint
});
}
emit PremintedV2({
contractAddress: result.contractAddress,
tokenId: result.tokenId,
createdNewContract: result.createdNewContract,
uid: premintConfig.uid,
minter: firstMinter,
quantityMinted: quantityToMint
});
}

/// @notice Creates a new token on the given erc1155 contract on behalf of a creator, and mints x tokens to the executor of this transaction.
Expand All @@ -113,7 +116,7 @@ contract ZoraCreator1155PremintExecutorImpl is
uint256 quantityToMint,
MintArguments calldata mintArguments
) external payable returns (PremintResult memory result) {
return premintV2WithSignerContract(contractConfig, premintConfig, signature, quantityToMint, mintArguments, address(0));
return premintV2WithSignerContract(contractConfig, premintConfig, signature, quantityToMint, mintArguments, msg.sender, address(0));
}

/// Creates a new token on the given erc1155 contract on behalf of a creator, and mints x tokens to the executor of this transaction.
Expand All @@ -134,40 +137,39 @@ contract ZoraCreator1155PremintExecutorImpl is
uint256 quantityToMint,
MintArguments calldata mintArguments
) external payable returns (PremintResult memory result) {
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV1(premintConfig);
address fixedPriceMinter = premintConfig.tokenConfig.fixedPriceMinter;
uint32 uid = premintConfig.uid;
result = ZoraCreator1155PremintExecutorImplLib.getOrCreateContractAndToken(
zora1155Factory,
contractConfig,
PremintEncoding.encodePremintV1(premintConfig),
signature,
msg.sender,
address(0)
);

{
result = ZoraCreator1155PremintExecutorImplLib.premint({
zora1155Factory: zora1155Factory,
contractConfig: contractConfig,
encodedPremintConfig: encodedPremint,
premintVersion: premintVersion,
signature: signature,
quantityToMint: quantityToMint,
fixedPriceMinter: fixedPriceMinter,
mintArguments: mintArguments,
signerContract: address(0)
});
if (quantityToMint > 0) {
ZoraCreator1155PremintExecutorImplLib.mintWithEth(
IZoraCreator1155(result.contractAddress),
premintConfig.tokenConfig.fixedPriceMinter,
result.tokenId,
quantityToMint,
mintArguments
);
}

{
emit PremintedV2({
contractAddress: result.contractAddress,
tokenId: result.tokenId,
createdNewContract: result.createdNewContract,
uid: uid,
minter: msg.sender,
quantityMinted: quantityToMint
});
}
emit PremintedV2({
contractAddress: result.contractAddress,
tokenId: result.tokenId,
createdNewContract: result.createdNewContract,
uid: premintConfig.uid,
minter: msg.sender,
quantityMinted: quantityToMint
});
}

/// @notice Gets the deterministic contract address for the given contract creation config.
/// Contract address is generated deterministically from a hash based on the contract uri, contract name,
/// contract admin, and the msg.sender, which is this contract's address.
function getContractAddress(ContractCreationConfig calldata contractConfig) public view returns (address) {
function getContractAddress(ContractCreationConfig calldata contractConfig) public view override returns (address) {
return ZoraCreator1155PremintExecutorImplLib.getContractAddress(zora1155Factory, contractConfig);
}

Expand All @@ -192,7 +194,7 @@ contract ZoraCreator1155PremintExecutorImpl is
ZoraCreator1155Attribution.hashPremint(premintConfig),
signature,
contractAddress,
ZoraCreator1155Attribution.HASHED_VERSION_1,
PremintEncoding.HASHED_VERSION_1,
block.chainid,
address(0)
);
Expand Down Expand Up @@ -241,7 +243,7 @@ contract ZoraCreator1155PremintExecutorImpl is
// try get token id for uid 0 - if call fails, we know this didn't support premint
try ERC1155DelegationStorageV1(contractAddress).delegatedTokenId(uint32(0)) returns (uint256) {
versions = new string[](1);
versions[0] = ZoraCreator1155Attribution.VERSION_1;
versions[0] = PremintEncoding.VERSION_1;
} catch {
versions = new string[](0);
}
Expand Down
Loading

0 comments on commit 079a596

Please sign in to comment.