Skip to content

Commit

Permalink
1155 now takes encoded premint struct and external library decodes it…
Browse files Browse the repository at this point in the history
…, allowing it to support multiple versions of the signature
  • Loading branch information
oveddan committed Oct 20, 2023
1 parent 42c8f70 commit 87a2b98
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ library ZoraCreator1155Attribution {
library PremintTokenSetup {
uint256 constant PERMISSION_BIT_MINTER = 2 ** 2;

function makeSetupNewTokenCalls(uint256 newTokenId, TokenCreationConfigV2 calldata tokenConfig) internal view returns (bytes[] memory calls) {
function makeSetupNewTokenCalls(uint256 newTokenId, TokenCreationConfigV2 memory tokenConfig) internal view returns (bytes[] memory calls) {
return
_buildCalls({
newTokenId: newTokenId,
Expand All @@ -270,7 +270,7 @@ library PremintTokenSetup {
});
}

function makeSetupNewTokenCalls(uint256 newTokenId, TokenCreationConfig calldata tokenConfig) internal view returns (bytes[] memory calls) {
function makeSetupNewTokenCalls(uint256 newTokenId, TokenCreationConfig memory tokenConfig) internal view returns (bytes[] memory calls) {
return
_buildCalls({
newTokenId: newTokenId,
Expand Down Expand Up @@ -352,13 +352,49 @@ struct DelegatedTokenSetup {
address createReferral;
}

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

function decodePremintV1(bytes memory encodedPremint) internal pure returns (PremintConfig memory) {
return abi.decode(encodedPremint, (PremintConfig));
}

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

function decodePremintV2(bytes memory encodedPremint) internal pure returns (PremintConfigV2 memory) {
return abi.decode(encodedPremint, (PremintConfigV2));
}
}

library DelegatedTokenCreation {
function recoverDelegatedToken(
PremintConfigV2 calldata premintConfig,
bytes memory premintConfigEncoded,
bytes32 premintVersion,
bytes calldata signature,
address tokenContract,
uint256 nextTokenId
) external view returns (DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) {
if (premintVersion == ZoraCreator1155Attribution.HASHED_VERSION_1) {
PremintConfig memory premintConfig = PremintEncoding.decodePremintV1(premintConfigEncoded);

return recoverDelegatedToken(premintConfig, signature, tokenContract, nextTokenId);
} else {
PremintConfigV2 memory premintConfig = PremintEncoding.decodePremintV2(premintConfigEncoded);

return recoverDelegatedToken(premintConfig, signature, tokenContract, nextTokenId);
}
}

function recoverDelegatedToken(
PremintConfigV2 memory premintConfig,
bytes calldata signature,
address tokenContract,
uint256 nextTokenId
) private view returns (DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) {
validatePremint(premintConfig.tokenConfig.mintStart, premintConfig.deleted);

params.structHash = ZoraCreator1155Attribution.hashPremint(premintConfig);
Expand All @@ -378,19 +414,19 @@ library DelegatedTokenCreation {

params.uid = premintConfig.uid;

tokenSetupActions = PremintTokenSetup.makeSetupNewTokenCalls(nextTokenId, premintConfig.tokenConfig);
tokenSetupActions = PremintTokenSetup.makeSetupNewTokenCalls({newTokenId: nextTokenId, tokenConfig: premintConfig.tokenConfig});

params.tokenURI = premintConfig.tokenConfig.tokenURI;
params.maxSupply = premintConfig.tokenConfig.maxSupply;
params.createReferral = premintConfig.tokenConfig.createReferral;
}

function recoverDelegatedToken(
PremintConfig calldata premintConfig,
PremintConfig memory premintConfig,
bytes calldata signature,
address tokenContract,
uint256 nextTokenId
) external view returns (DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) {
) private view returns (DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) {
validatePremint(premintConfig.tokenConfig.mintStart, premintConfig.deleted);

params.structHash = ZoraCreator1155Attribution.hashPremint(premintConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ 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 {ZoraCreator1155Attribution, ContractCreationConfig, PremintConfig, PremintConfigV2, TokenCreationConfig, TokenCreationConfigV2} from "./ZoraCreator1155Attribution.sol";
import {PremintEncoding, ZoraCreator1155Attribution, ContractCreationConfig, PremintConfig, PremintConfigV2, TokenCreationConfig, TokenCreationConfigV2} from "./ZoraCreator1155Attribution.sol";

interface IZoraCreator1155PremintV1Signatures {
function delegateSetupNewToken(PremintConfig calldata premintConfig, bytes calldata signature, address sender) external returns (uint256 newTokenId);
Expand Down Expand Up @@ -92,19 +92,23 @@ contract ZoraCreator1155PremintExecutorImpl is
uint256 quantityToMint,
bytes calldata mintArguments
) external payable returns (uint256 newTokenId) {
// get or create the contract with the given params
// contract address is deterministic.
(IZoraCreator1155 tokenContract, bool isNewContract) = ZoraCreator1155PremintExecutorImplLib.getOrCreateContract(zora1155Factory, contractConfig);

// pass the signature and the premint config to the token contract to create the token.
// The token contract will verify the signature and that the signer has permission to create a new token.
// and then create and setup the token using the given token config.
newTokenId = tokenContract.delegateSetupNewToken(premintConfig, signature, msg.sender);

_performMint(tokenContract, premintConfig.tokenConfig.fixedPriceMinter, newTokenId, quantityToMint, mintArguments);

// emit Preminted event
emit PremintedV2(address(tokenContract), newTokenId, isNewContract, premintConfig.uid, msg.sender, quantityToMint, mintArguments);
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV2(premintConfig);
address fixedPriceMinter = premintConfig.tokenConfig.fixedPriceMinter;
uint32 uid = premintConfig.uid;

// we wrap this here to get around stack too deep issues
{
newTokenId = _premint({
contractConfig: contractConfig,
encodedPremintConfig: encodedPremint,
premintVersion: premintVersion,
signature: signature,
quantityToMint: quantityToMint,
fixedPriceMinter: fixedPriceMinter,
uid: uid,
mintArguments: mintArguments
});
}
}

/// 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 @@ -124,17 +128,44 @@ contract ZoraCreator1155PremintExecutorImpl is
uint256 quantityToMint,
bytes memory mintArguments
) public payable returns (uint256 newTokenId) {
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV1(premintConfig);

return
_premint({
contractConfig: contractConfig,
encodedPremintConfig: encodedPremint,
premintVersion: premintVersion,
signature: signature,
quantityToMint: quantityToMint,
fixedPriceMinter: premintConfig.tokenConfig.fixedPriceMinter,
uid: premintConfig.uid,
mintArguments: mintArguments
});
}

function _premint(
ContractCreationConfig calldata contractConfig,
bytes memory encodedPremintConfig,
bytes32 premintVersion,
bytes calldata signature,
uint256 quantityToMint,
address fixedPriceMinter,
uint32 uid,
bytes memory mintArguments
) private returns (uint256 newTokenId) {
// get or create the contract with the given params
// contract address is deterministic.
(IZoraCreator1155 tokenContract, bool isNewContract) = ZoraCreator1155PremintExecutorImplLib.getOrCreateContract(zora1155Factory, contractConfig);

// assume contract has legacy interface expecting v1 signatures; call it.
newTokenId = IZoraCreator1155PremintV1Signatures(address(tokenContract)).delegateSetupNewToken(premintConfig, signature, msg.sender);
// pass the signature and the premint config to the token contract to create the token.
// The token contract will verify the signature and that the signer has permission to create a new token.
// and then create and setup the token using the given token config.
newTokenId = tokenContract.delegateSetupNewToken(encodedPremintConfig, premintVersion, signature, msg.sender);

_performMint(tokenContract, premintConfig.tokenConfig.fixedPriceMinter, newTokenId, quantityToMint, mintArguments);
_performMint(tokenContract, fixedPriceMinter, newTokenId, quantityToMint, mintArguments);

// emit Preminted event
emit PremintedV2(address(tokenContract), newTokenId, isNewContract, premintConfig.uid, msg.sender, quantityToMint, mintArguments);
emit PremintedV2(address(tokenContract), newTokenId, isNewContract, uid, msg.sender, quantityToMint, mintArguments);
}

function _performMint(
Expand Down
7 changes: 6 additions & 1 deletion packages/1155-contracts/src/interfaces/IZoraCreator1155.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ interface IZoraCreator1155 is IZoraCreator1155TypesV1, IZoraCreator1155Errors, I
/// @param maxSupply maxSupply for the token, set to 0 for open edition
function setupNewToken(string memory tokenURI, uint256 maxSupply) external returns (uint256 tokenId);

function delegateSetupNewToken(PremintConfigV2 calldata premintConfig, bytes calldata signature, address sender) external returns (uint256 newTokenId);
function delegateSetupNewToken(
bytes memory premintConfigEncoded,
bytes32 premintVersion,
bytes calldata signature,
address sender
) external returns (uint256 newTokenId);

function updateTokenURI(uint256 tokenId, string memory _newURI) external;

Expand Down
19 changes: 3 additions & 16 deletions packages/1155-contracts/src/nft/ZoraCreator1155Impl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -752,27 +752,14 @@ contract ZoraCreator1155Impl is
/// @param premintConfig configuration of token to be created
/// @param signature EIP-712 Signature created on the premintConfig by an account with the PERMISSION_BIT_MINTER role on the contract.
function delegateSetupNewToken(
PremintConfig calldata premintConfig,
bytes calldata signature,
address sender
) external nonReentrant returns (uint256 newTokenId) {
(DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) = DelegatedTokenCreation.recoverDelegatedToken(
premintConfig,
signature,
address(this),
nextTokenId
);

return _delegateSetupNewToken(params, tokenSetupActions, sender);
}

function delegateSetupNewToken(
PremintConfigV2 calldata premintConfig,
bytes memory premintConfig,
bytes32 premintVersion,
bytes calldata signature,
address sender
) external nonReentrant returns (uint256 newTokenId) {
(DelegatedTokenSetup memory params, bytes[] memory tokenSetupActions) = DelegatedTokenCreation.recoverDelegatedToken(
premintConfig,
premintVersion,
signature,
address(this),
nextTokenId
Expand Down
9 changes: 7 additions & 2 deletions packages/1155-contracts/test/nft/ZoraCreator1155.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Zora1155} from "../../src/proxies/Zora1155.sol";
import {ZoraCreatorFixedPriceSaleStrategy} from "../../src/minters/fixed-price/ZoraCreatorFixedPriceSaleStrategy.sol";
import {UpgradeGate} from "../../src/upgrades/UpgradeGate.sol";
import {PremintConfigV2, TokenCreationConfigV2} from "../../src/delegation/ZoraCreator1155Attribution.sol";
import {ZoraCreator1155Attribution} from "../../src/delegation/ZoraCreator1155Attribution.sol";
import {ZoraCreator1155Attribution, PremintEncoding} from "../../src/delegation/ZoraCreator1155Attribution.sol";

import {IZoraCreator1155Errors} from "../../src/interfaces/IZoraCreator1155Errors.sol";
import {IZoraCreator1155} from "../../src/interfaces/IZoraCreator1155.sol";
Expand Down Expand Up @@ -1104,7 +1104,12 @@ contract ZoraCreator1155Test is Test {
bytes memory signature = abi.encodePacked(r, s, v);

vm.prank(collector);
uint256 tokenId = target.delegateSetupNewToken(premintConfig, signature, collectors[0]);
uint256 tokenId;

{
(bytes memory premintConfigEncoded, bytes32 version) = PremintEncoding.encodePremintV2(premintConfig);
tokenId = target.delegateSetupNewToken(premintConfigEncoded, version, signature, collectors[0]);
}

RewardsSettings memory settings = target.computeFreeMintRewards(quantity);

Expand Down

0 comments on commit 87a2b98

Please sign in to comment.