Skip to content

Commit

Permalink
wip on v1/v2 of create referral fix
Browse files Browse the repository at this point in the history
  • Loading branch information
oveddan committed Oct 19, 2023
1 parent 640736f commit 6d90ee0
Show file tree
Hide file tree
Showing 12 changed files with 672 additions and 310 deletions.
54 changes: 33 additions & 21 deletions packages/1155-contracts/package/preminter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import {

import {
ContractCreationConfig,
PremintConfig,
TokenCreationConfig,
preminterTypedDataDefinition,
PremintConfigV2,
TokenCreationConfigV2,
encodeMintArguments,
preminterTypedDataDefinitionV2,
} from "./preminter";

const walletClient = createWalletClient({
Expand All @@ -51,8 +52,19 @@ const publicClient = createPublicClient({
type Address = `0x${string}`;

// JSON-RPC Account
const [deployerAccount, creatorAccount, collectorAccount] =
(await walletClient.getAddresses()) as [Address, Address, Address, Address];
const [
deployerAccount,
creatorAccount,
collectorAccount,
createReferralAccount,
mintReferral,
] = (await walletClient.getAddresses()) as [
Address,
Address,
Address,
Address,
Address
];

type TestContext = {
preminterAddress: `0x${string}`;
Expand All @@ -75,20 +87,20 @@ const defaultContractConfig = ({

const defaultTokenConfig = (
fixedPriceMinterAddress: Address
): TokenCreationConfig => ({
): TokenCreationConfigV2 => ({
tokenURI: "ipfs://tokenIpfsId0",
maxSupply: 100n,
maxTokensPerAddress: 10n,
pricePerToken: 0n,
mintStart: 0n,
mintDuration: 100n,
royaltyMintSchedule: 30,
royaltyBPS: 200,
royaltyRecipient: creatorAccount,
fixedPriceMinter: fixedPriceMinterAddress,
royaltyBPS: 10,
royaltyRecipient: creatorAccount,
createReferral: createReferralAccount,
});

const defaultPremintConfig = (fixedPriceMinter: Address): PremintConfig => ({
const defaultPremintConfig = (fixedPriceMinter: Address): PremintConfigV2 => ({
tokenConfig: defaultTokenConfig(fixedPriceMinter),
deleted: false,
uid: 105,
Expand Down Expand Up @@ -138,7 +150,7 @@ describe("ZoraCreator1155Preminter", () => {
});

const signedMessage = await walletClient.signTypedData({
...preminterTypedDataDefinition({
...preminterTypedDataDefinitionV2({
verifyingContract: contractAddress,
chainId: 999,
premintConfig,
Expand Down Expand Up @@ -177,7 +189,7 @@ describe("ZoraCreator1155Preminter", () => {

// sign message containing contract and token creation config and uid
const signedMessage = await walletClient.signTypedData({
...preminterTypedDataDefinition({
...preminterTypedDataDefinitionV2({
verifyingContract: contractAddress,
// we need to sign here for the anvil chain, cause thats where it is run on
chainId: anvilChainId,
Expand All @@ -187,11 +199,11 @@ describe("ZoraCreator1155Preminter", () => {
});

// recover and verify address is correct
const recoveredAddress = await publicClient.readContract({
const [, , recoveredAddress] = await publicClient.readContract({
abi: preminterAbi,
address: preminterAddress,
functionName: "recoverSigner",
args: [premintConfig, contractAddress, signedMessage],
functionName: "isValidSignature",
args: [contractConfig, premintConfig, signedMessage],
});

expect(recoveredAddress).to.equal(creatorAccount);
Expand Down Expand Up @@ -226,7 +238,7 @@ describe("ZoraCreator1155Preminter", () => {
// have creator sign the message to create the contract
// and the token
const signedMessage = await walletClient.signTypedData({
...preminterTypedDataDefinition({
...preminterTypedDataDefinitionV2({
verifyingContract: contractAddress,
// we need to sign here for the anvil chain, cause thats where it is run on
chainId: anvilChainId,
Expand Down Expand Up @@ -274,7 +286,7 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig,
signedMessage,
quantityToMint,
comment,
encodeMintArguments({ mintComment: comment }),
],
value: valueToSend,
});
Expand Down Expand Up @@ -319,7 +331,7 @@ describe("ZoraCreator1155Preminter", () => {

// sign the message to create the second token
const signedMessage2 = await walletClient.signTypedData({
...preminterTypedDataDefinition({
...preminterTypedDataDefinitionV2({
verifyingContract: contractAddress,
chainId: foundry.id,
premintConfig: premintConfig2,
Expand All @@ -345,7 +357,7 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig2,
signedMessage2,
quantityToMint2,
comment,
encodeMintArguments({ mintComment: comment }),
],
value: valueToSend2,
});
Expand Down Expand Up @@ -403,7 +415,7 @@ describe("ZoraCreator1155Preminter", () => {
// have creator sign the message to create the contract
// and the token
const signedMessage = await walletClient.signTypedData({
...preminterTypedDataDefinition({
...preminterTypedDataDefinitionV2({
verifyingContract: contractAddress,
// we need to sign here for the anvil chain, cause thats where it is run on
chainId: anvilChainId,
Expand Down Expand Up @@ -439,7 +451,7 @@ describe("ZoraCreator1155Preminter", () => {
premintConfig,
signedMessage,
quantityToMint,
comment,
encodeMintArguments({ mintComment: comment }),
],
value: valueToSend,
});
Expand Down
102 changes: 95 additions & 7 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 } from "viem";
import { TypedDataDefinition, encodeAbiParameters } from "viem";

type PremintInputs = ExtractAbiFunction<
typeof preminterAbi,
Expand All @@ -11,18 +11,90 @@ type PremintInputs = ExtractAbiFunction<
type PreminterHashDataTypes = AbiParametersToPrimitiveTypes<PremintInputs>;

export type ContractCreationConfig = PreminterHashDataTypes[0];
export type PremintConfig = PreminterHashDataTypes[1];
export type TokenCreationConfig = PremintConfig["tokenConfig"];
export type PremintConfigs = PreminterHashDataTypes[1];

export type TokenCreationConfigV1 = PremintConfigV2["tokenConfig"];
export type PremintConfigV2 = Extract<
PremintConfigs,
{
tokenConfig: {
createReferral: string;
};
}
>;
export type PremintConfigV1 = Exclude<PremintConfigs, PremintConfigV2>;
export type TokenCreationConfigV2 = PremintConfigV2["tokenConfig"];

const premintV2Types = {
CreatorAttribution: [
{ name: "tokenConfig", type: "TokenCreationConfig" },
// unique id scoped to the contract and token to create.
// ensure that a signature can be replaced, as long as the replacement
// has the same uid, and a newer version.
{ name: "uid", type: "uint32" },
{ name: "version", type: "uint32" },
// if this update should result in the signature being deleted.
{ name: "deleted", type: "bool" },
],
TokenCreationConfig: [
{ name: "tokenURI", type: "string" },
{ name: "maxSupply", type: "uint256" },
{ name: "maxTokensPerAddress", type: "uint64" },
{ name: "pricePerToken", type: "uint96" },
{ name: "mintStart", type: "uint64" },
{ name: "mintDuration", type: "uint64" },
{ name: "royaltyBPS", type: "uint32" },
{ name: "royaltyRecipient", type: "address" },
{ name: "fixedPriceMinter", type: "address" },
{ name: "createReferral", type: "address" },
],
};

// Convenience method to create the structured typed data
// needed to sign for a premint contract and token
export const preminterTypedDataDefinitionV2 = ({
verifyingContract,
premintConfig,
chainId,
}: {
verifyingContract: Address;
premintConfig: PremintConfigV2;
chainId: number;
}) => {
const { tokenConfig, uid, version, deleted } = premintConfig;

const result: TypedDataDefinition<
typeof premintV2Types,
"CreatorAttribution"
> = {
domain: {
chainId,
name: "Preminter",
version: "2",
verifyingContract: verifyingContract,
},
types: premintV2Types,
message: {
tokenConfig,
uid,
version,
deleted,
},
primaryType: "CreatorAttribution",
};

return result;
};

// Convenience method to create the structured typed data
// needed to sign for a premint contract and token
export const preminterTypedDataDefinition = ({
export const preminterTypedDataDefinitionV1 = ({
verifyingContract,
premintConfig,
chainId,
}: {
verifyingContract: Address;
premintConfig: PremintConfig;
premintConfig: PremintConfigV1;
chainId: number;
}) => {
const { tokenConfig, uid, version, deleted } = premintConfig;
Expand Down Expand Up @@ -68,7 +140,23 @@ export const preminterTypedDataDefinition = ({
primaryType: "CreatorAttribution",
};

// console.log({ result, deleted });

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]
);
};
Loading

0 comments on commit 6d90ee0

Please sign in to comment.