Skip to content

Commit

Permalink
Mint arguments are a struct
Browse files Browse the repository at this point in the history
  • Loading branch information
oveddan committed Oct 30, 2023
1 parent 8885f54 commit 6296269
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 86 deletions.
20 changes: 16 additions & 4 deletions packages/1155-contracts/package/preminter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
concat,
recoverAddress,
hashDomain,
zeroAddress,
} from "viem";
import { foundry, zora } from "viem/chains";
import { describe, it, beforeEach, expect } from "vitest";
Expand All @@ -24,7 +25,6 @@ import {
ContractCreationConfig,
PremintConfigV2,
TokenCreationConfigV2,
encodeMintArguments,
preminterTypedDataDefinitionV2,
} from "./preminter";

Expand Down Expand Up @@ -285,7 +285,11 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig,
signedMessage,
quantityToMint,
encodeMintArguments({ mintComment: comment }),
{
mintComment: comment,
mintRecipient: collectorAccount,
mintReferral: zeroAddress,
},
],
value: valueToSend,
});
Expand Down Expand Up @@ -356,7 +360,11 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig2,
signedMessage2,
quantityToMint2,
encodeMintArguments({ mintComment: comment }),
{
mintComment: comment,
mintRecipient: collectorAccount,
mintReferral: zeroAddress,
},
],
value: valueToSend2,
});
Expand Down Expand Up @@ -450,7 +458,11 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig,
signedMessage,
quantityToMint,
encodeMintArguments({ mintComment: comment }),
{
mintComment: comment,
mintRecipient: collectorAccount,
mintReferral: zeroAddress,
},
],
value: valueToSend,
});
Expand Down
20 changes: 1 addition & 19 deletions packages/1155-contracts/package/preminter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Address } from "abitype";
import { ExtractAbiFunction, AbiParametersToPrimitiveTypes } from "abitype";
import { zoraCreator1155PremintExecutorImplABI as preminterAbi } from "./wagmiGenerated";
import { TypedDataDefinition, encodeAbiParameters } from "viem";
import { TypedDataDefinition } from "viem";

type PremintInputs = ExtractAbiFunction<
typeof preminterAbi,
Expand Down Expand Up @@ -142,21 +142,3 @@ export const preminterTypedDataDefinitionV1 = ({

return result;
};

const zeroAddress: Address = "0x0000000000000000000000000000000000000000";

export const encodeMintArguments = ({
mintComment = "",
mintReferral = zeroAddress,
}: {
mintComment?: string;
mintReferral?: Address;
}) => {
return encodeAbiParameters(
[
{ name: "mintReferral", type: "address" },
{ name: "mintComment", type: "string" },
],
[mintReferral, mintComment]
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ interface ILegacyZoraCreator1155PremintExecutor {
) external payable returns (uint256 newTokenId);
}

struct MintArguments {
// which account should receive the tokens minted. If set to address(0), then defaults to the msg.sender
address mintRecipient;
// comment to add to the mint
string mintComment;
// account that referred the minter to mint the tokens, this account will receive a mint referral award. If set to address(0), no account will get the mint referral reward
address mintReferral;
}

/// @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.
/// Mints the first x tokens to the executor of the transaction.
Expand Down Expand Up @@ -71,8 +80,7 @@ contract ZoraCreator1155PremintExecutorImpl is
bool indexed createdNewContract,
uint32 uid,
address minter,
uint256 quantityMinted,
bytes mintArgumets
uint256 quantityMinted
);

/// 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 @@ -90,7 +98,7 @@ contract ZoraCreator1155PremintExecutorImpl is
PremintConfigV2 calldata premintConfig,
bytes calldata signature,
uint256 quantityToMint,
bytes calldata mintArguments
MintArguments calldata mintArguments
) external payable returns (uint256 newTokenId) {
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV2(premintConfig);
address fixedPriceMinter = premintConfig.tokenConfig.fixedPriceMinter;
Expand Down Expand Up @@ -126,7 +134,7 @@ contract ZoraCreator1155PremintExecutorImpl is
PremintConfig calldata premintConfig,
bytes calldata signature,
uint256 quantityToMint,
bytes memory mintArguments
MintArguments memory mintArguments
) public payable returns (uint256 newTokenId) {
(bytes memory encodedPremint, bytes32 premintVersion) = PremintEncoding.encodePremintV1(premintConfig);

Expand All @@ -151,7 +159,7 @@ contract ZoraCreator1155PremintExecutorImpl is
uint256 quantityToMint,
address fixedPriceMinter,
uint32 uid,
bytes memory mintArguments
MintArguments memory mintArguments
) private returns (uint256 newTokenId) {
// get or create the contract with the given params
// contract address is deterministic.
Expand All @@ -165,27 +173,20 @@ contract ZoraCreator1155PremintExecutorImpl is
_performMint(tokenContract, fixedPriceMinter, newTokenId, quantityToMint, mintArguments);

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

function _performMint(
IZoraCreator1155 tokenContract,
address fixedPriceMinter,
uint256 tokenId,
uint256 quantityToMint,
bytes memory mintArguments
MintArguments memory mintArguments
) internal {
(address mintReferral, string memory mintComment) = ZoraCreator1155PremintExecutorImplLib.decodeMintArguments(mintArguments);

bytes memory mintSettings = abi.encode(mintArguments.mintRecipient, mintArguments.mintComment);
if (quantityToMint != 0)
// mint the number of specified tokens to the executor
tokenContract.mintWithRewards{value: msg.value}(
IMinter1155(fixedPriceMinter),
tokenId,
quantityToMint,
abi.encode(msg.sender, mintComment),
mintReferral
);
tokenContract.mintWithRewards{value: msg.value}(IMinter1155(fixedPriceMinter), tokenId, quantityToMint, mintSettings, mintArguments.mintReferral);
}

function isValidSignature(
Expand Down Expand Up @@ -284,7 +285,7 @@ contract ZoraCreator1155PremintExecutorImpl is
string calldata mintComment
) external payable returns (uint256 newTokenId) {
// encode legacy mint arguments to call current function:
bytes memory mintArguments = ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), mintComment);
MintArguments memory mintArguments = MintArguments({mintRecipient: msg.sender, mintComment: mintComment, mintReferral: address(0)});

return premint(contractConfig, premintConfig, signature, quantityToMint, mintArguments);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ library ZoraCreator1155PremintExecutorImplLib {
zora1155Factory.deterministicContractAddress(address(this), contractConfig.contractURI, contractConfig.contractName, contractConfig.contractAdmin);
}

function encodeMintArguments(address mintReferral, string memory mintComment) internal pure returns (bytes memory) {
return abi.encode(mintReferral, mintComment);
function encodeMintArguments(address mintRecipient, string memory mintComment) internal pure returns (bytes memory) {
return abi.encode(mintRecipient, mintComment);
}

function decodeMintArguments(bytes memory mintArguments) internal pure returns (address mintReferral, string memory mintComment) {
function decodeMintArguments(bytes memory mintArguments) internal pure returns (address mintRecipient, string memory mintComment) {
return abi.decode(mintArguments, (address, string));
}
}
31 changes: 16 additions & 15 deletions packages/1155-contracts/src/deployment/DeploymentTestingUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "forge-std/Script.sol";
import {IMinter1155} from "..//interfaces/IMinter1155.sol";
import {Zora1155FactoryFixtures} from "../../test/fixtures/Zora1155FactoryFixtures.sol";
import {Zora1155PremintFixtures} from "../../test/fixtures/Zora1155PremintFixtures.sol";
import {ZoraCreator1155PremintExecutorImpl} from "../delegation/ZoraCreator1155PremintExecutorImpl.sol";
import {ZoraCreator1155PremintExecutorImpl, MintArguments} from "../delegation/ZoraCreator1155PremintExecutorImpl.sol";
import {ZoraCreator1155FactoryImpl} from "../factory/ZoraCreator1155FactoryImpl.sol";
import {ZoraCreator1155Attribution, ContractCreationConfig, PremintConfigV2} from "../delegation/ZoraCreator1155Attribution.sol";
import {ZoraCreator1155Impl} from "../nft/ZoraCreator1155Impl.sol";
Expand All @@ -31,26 +31,27 @@ contract DeploymentTestingUtils is Script {
ContractCreationConfig memory contractConfig = Zora1155PremintFixtures.makeDefaultContractCreationConfig(creator);
address deterministicAddress = preminterAtProxy.getContractAddress(contractConfig);

bytes32 signatureVersion = ZoraCreator1155Attribution.HASHED_VERSION_2;
bytes32 structHash = ZoraCreator1155Attribution.hashPremint(premintConfig);
// sign the premint
bytes32 digest = ZoraCreator1155Attribution.premintHashedTypeDataV4(structHash, deterministicAddress, signatureVersion, block.chainid);
uint256 quantityToMint = 1;

(uint8 v, bytes32 r, bytes32 s) = vm.sign(creatorPrivateKey, digest);
address mintRecipient = creator;

uint256 quantityToMint = 1;
MintArguments memory mintArguments = MintArguments({mintRecipient: mintRecipient, mintComment: "", mintReferral: address(0)});

bytes memory signature = abi.encodePacked(r, s, v);
bytes memory signature = signPremint(premintConfig, deterministicAddress, creatorPrivateKey);

// execute the premint
uint256 tokenId = preminterAtProxy.premint{value: 0.000777 ether}(
contractConfig,
premintConfig,
signature,
quantityToMint,
ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), "")
);
uint256 tokenId = preminterAtProxy.premint{value: 0.000777 ether}(contractConfig, premintConfig, signature, quantityToMint, mintArguments);

require(ZoraCreator1155Impl(deterministicAddress).delegatedTokenId(premintConfig.uid) == tokenId, "token id not created for uid");
}

function signPremint(PremintConfigV2 memory premintConfig, address deterministicAddress, uint256 privateKey) private view returns (bytes memory signature) {
bytes32 signatureVersion = ZoraCreator1155Attribution.HASHED_VERSION_2;
bytes32 structHash = ZoraCreator1155Attribution.hashPremint(premintConfig);
// sign the premint
bytes32 digest = ZoraCreator1155Attribution.premintHashedTypeDataV4(structHash, deterministicAddress, signatureVersion, block.chainid);

(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, digest);
return abi.encodePacked(r, s, v);
}
}
12 changes: 6 additions & 6 deletions packages/1155-contracts/src/nft/ZoraCreator1155Impl.sol
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,12 @@ contract ZoraCreator1155Impl is
(DelegatedTokenSetup memory params, DecodedCreatorAttribution memory attribution, bytes[] memory tokenSetupActions) = DelegatedTokenCreation
.decodeAndRecoverDelegatedTokenSetup(premintConfig, premintVersion, signature, address(this), nextTokenId);

// if a token has already been created for a premint config with this uid:
if (delegatedTokenId[params.uid] != 0) {
// return its token id
return delegatedTokenId[params.uid];
}

// this is what attributes this token to have been created by the original creator
emit CreatorAttribution(attribution.structHash, attribution.domainName, attribution.version, attribution.creator, attribution.signature);

Expand All @@ -772,12 +778,6 @@ contract ZoraCreator1155Impl is
bytes[] memory tokenSetupActions,
address sender
) internal returns (uint256 newTokenId) {
// if a token has already been created for a premint config with this uid:
if (delegatedTokenId[params.uid] != 0) {
// return its token id
return delegatedTokenId[params.uid];
}

// require that the signer can create new tokens (is a valid creator)
_requireAdminOrRole(creator, CONTRACT_BASE_ID, PERMISSION_BIT_MINTER);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ library Zora1155PremintFixtures {
return
TokenCreationConfigV2({
tokenURI: "blah.token",
maxSupply: 10,
maxTokensPerAddress: 5,
maxSupply: 20,
maxTokensPerAddress: 10,
pricePerToken: 0,
mintStart: 0,
mintDuration: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {Zora1155PremintFixtures} from "../fixtures/Zora1155PremintFixtures.sol";
import {ZoraCreator1155FactoryImpl} from "../../src/factory/ZoraCreator1155FactoryImpl.sol";
import {Zora1155PremintExecutor} from "../../src/proxies/Zora1155PremintExecutor.sol";
import {ZoraCreator1155Impl} from "../../src/nft/ZoraCreator1155Impl.sol";
import {ZoraCreator1155PremintExecutorImpl} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol";
import {ZoraCreator1155PremintExecutorImpl, MintArguments} from "../../src/delegation/ZoraCreator1155PremintExecutorImpl.sol";
import {Zora1155Factory} from "../../src/proxies/Zora1155Factory.sol";
import {IMinter1155} from "../../src/interfaces/IMinter1155.sol";
import {ProxyShim} from "../../src/utils/ProxyShim.sol";
Expand All @@ -27,6 +27,8 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName {
uint256 internal mintFeeAmount = 0.000777 ether;
ZoraCreator1155PremintExecutorImpl preminterAtProxy;

MintArguments defaultMintArguments;

function setUp() external {
zora = makeAddr("zora");
owner = makeAddr("owner");
Expand All @@ -47,6 +49,8 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName {
// access the executor implementation via the proxy, and initialize the admin
preminterAtProxy = ZoraCreator1155PremintExecutorImpl(address(proxy));
preminterAtProxy.initialize(owner);

defaultMintArguments = MintArguments({mintRecipient: collector, mintComment: "blah", mintReferral: address(0)});
}

function test_canInvokeImplementationMethods() external {
Expand Down Expand Up @@ -82,13 +86,7 @@ contract Zora1155PremintExecutorProxyTest is Test, IHasContractName {
// execute the premint
vm.deal(collector, mintFeeAmount);
vm.prank(collector);
uint256 tokenId = preminterAtProxy.premint{value: mintFeeAmount}(
contractConfig,
premintConfig,
signature,
quantityToMint,
ZoraCreator1155PremintExecutorImplLib.encodeMintArguments(address(0), "")
);
uint256 tokenId = preminterAtProxy.premint{value: mintFeeAmount}(contractConfig, premintConfig, signature, quantityToMint, defaultMintArguments);

assertEq(ZoraCreator1155Impl(deterministicAddress).balanceOf(collector, tokenId), 1);
}
Expand Down
Loading

0 comments on commit 6296269

Please sign in to comment.