From 3aeb117f443be5e0a62afa297ad8c48d60ad874e Mon Sep 17 00:00:00 2001 From: Vectorized Date: Tue, 3 Oct 2023 16:24:52 +0000 Subject: [PATCH 1/2] T --- pages/protocol/core/_meta.json | 5 +- pages/protocol/core/i-minter-module.mdx | 387 ------------------ ...sound-creator-v1.mdx => sound-creator.mdx} | 16 +- pages/protocol/core/sound-edition.mdx | 1 - pages/protocol/libraries/ownable-roles.mdx | 24 -- pages/protocol/overview/_meta.json | 4 +- pages/protocol/overview/deployments.mdx | 18 +- pages/protocol/overview/design.mdx | 19 +- pages/protocol/overview/erc721a-info.mdx | 86 ---- pages/protocol/overview/gas.mdx | 57 --- pages/protocol/overview/index.mdx | 13 +- 11 files changed, 25 insertions(+), 605 deletions(-) delete mode 100644 pages/protocol/core/i-minter-module.mdx rename pages/protocol/core/{sound-creator-v1.mdx => sound-creator.mdx} (88%) delete mode 100644 pages/protocol/overview/erc721a-info.mdx delete mode 100644 pages/protocol/overview/gas.mdx diff --git a/pages/protocol/core/_meta.json b/pages/protocol/core/_meta.json index 44d260b..bdba8ea 100644 --- a/pages/protocol/core/_meta.json +++ b/pages/protocol/core/_meta.json @@ -1,6 +1,5 @@ { - "sound-creator-v1": "SoundCreatorV1", - "sound-edition": "SoundEdition", - "i-minter-module": "IMinterModule", + "sound-creator": "SoundCreatorV2", + "sound-edition": "SoundEditionV2", "i-metadata-module": "IMetadataModule" } diff --git a/pages/protocol/core/i-minter-module.mdx b/pages/protocol/core/i-minter-module.mdx deleted file mode 100644 index 3551eba..0000000 --- a/pages/protocol/core/i-minter-module.mdx +++ /dev/null @@ -1,387 +0,0 @@ -# IMinterModule - -**[`contracts/core/interfaces/IMinterModule.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/interfaces/IMinterModule.sol)** - -This interface is specific for the minter modules used by sound.xyz. - -If you are building contracts to interact with the minter modules, this may be of convenience. - -If you are building your own minters, it is not mandatory implement this interface. - -Inherits: - -- [IERC165](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol) - -## Structs - -### BaseData - -```solidity -struct BaseData { - // The start unix timestamp of the mint. - uint32 startTime; - // The end unix timestamp of the mint. - uint32 endTime; - // The affiliate fee in basis points. - uint16 affiliateFeeBPS; - // Whether the mint is paused. - bool mintPaused; -} -``` - -Used for internal storage of data pertaining to mints. - -## Write Functions - -### setEditionMintPaused - -```solidity -function setEditionMintPaused( - address edition, - uint128 mintId, - bool paused -) external -``` - -Sets the paused status for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the edition's owner or admin. - -| Params: | | -| --------- | -------------------------------------------------------------------- | -| `edition` | The edition address. | -| `mintId` | The mint ID, a global incrementing identifier used within the minter | -| `paused` | Whether the mint is paused. | - -### setTimeRange - -```solidity -function setTimeRange( - address edition, - uint128 mintId, - uint32 startTime, - uint32 endTime -) external -``` - -Sets the time range for an edition mint. - -**Calling conditions:** - -- The caller must be the edition's owner or admin. - -| Params: | | -| ----------- | -------------------------------------------------------------------- | -| `edition` | The edition address. | -| `mintId` | The mint ID, a global incrementing identifier used within the minter | -| `startTime` | The start time of the mint. | -| `endTime` | The end time of the mint. | - -### setAffiliateFee - -```solidity -function setAffiliateFee( - address edition, - uint128 mintId, - uint16 affiliateFeeBPS -) external -``` - -Sets the affiliate fee for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the edition's owner or admin. - -| Params: | | -| ----------------- | -------------------------------------------------------------------- | -| `edition` | The edition address. | -| `mintId` | The mint ID, a global incrementing identifier used within the minter | -| `affiliateFeeBPS` | The affiliate fee in basis points. | - -### withdrawForAffiliate - -```solidity -function withdrawForAffiliate(address affiliate) external -``` - -Withdraws all the accrued fees for `affiliate`. - -| Params: | | -| ----------- | ------------------------ | -| `affiliate` | The affiliate's address. | - -### withdrawForPlatform - -```solidity -function withdrawForPlatform() external -``` - -Withdraws all the accrued fees for the platform. - -## Read-only Functions - -### affiliateFeesAccrued - -```solidity -function affiliateFeesAccrued(address affiliate) external view returns (uint128) -``` - -The total fees accrued for `affiliate`. - -| Params: | | -| ----------- | ------------------------ | -| `affiliate` | The affiliate's address. | - -### platformFeesAccrued - -```solidity -function platformFeesAccrued() external view returns (uint128) -``` - -The total fees accrued for the platform. - -### isAffiliated - -```solidity -function isAffiliated( - address edition, - uint128 mintId, - address affiliate -) external view returns (bool) -``` - -Whether `affiliate` is affiliated for (`edition`, `mintId`). - -| Params: | | -| ----------- | ------------------------ | -| `edition` | The edition's address. | -| `mintId` | The mint ID. | -| `affiliate` | The affiliate's address. | - -### totalPrice - -```solidity -function totalPrice( - address edition, - uint128 mintId, - address minter, - uint32 quantity -) external view returns (uint128) -``` - -The total price for `quantity` tokens for (`edition`, `mintId`). - -| Params: | | -| ---------- | ----------------------------- | -| `edition` | The edition's address. | -| `mintId` | The mint ID. | -| `mintId` | The minter's address. | -| `quantity` | The number of tokens to mint. | - -### nextMintId - -```solidity -function nextMintId() external view returns (uint128) -``` - -The next mint ID. A mint ID is assigned sequentially starting from (0, 1, 2, ...), and is shared amongst all editions connected to the minter contract. - -### moduleInterfaceId - -```solidity -function moduleInterfaceId() external view returns (bytes4) -``` - -The interface ID of the minter. - -### feeRegistry - -```solidity -function feeRegistry() external view returns (ISoundFeeRegistry) -``` - -The fee registry. Used for handling platform fees. - -## Events - -### MintConfigCreated - -```solidity -event MintConfigCreated( - address indexed edition, - address indexed creator, - uint128 mintId, - uint32 startTime, - uint32 endTime, - uint16 affiliateFeeBPS - ) -``` - -Emitted when the mint instance for an `edition` is created. - -| Params: | | -| ----------------- | -------------------------------------------------------------------- | -| `edition` | The edition address. | -| `mintId` | The mint ID, a global incrementing identifier used within the minter | -| `startTime` | The start time of the mint. | -| `endTime` | The end time of the mint. | -| `affiliateFeeBPS` | The affiliate fee in basis points. | - -### MintPausedSet - -```solidity -event MintPausedSet(address indexed edition, uint128 mintId, bool paused) -``` - -Emitted when the `paused` status of `edition` is updated. - -| Params: | | -| --------- | ------------------------------------------------------------------------ | -| `edition` | The edition address. | -| `mintId` | The mint ID, to distinguish between multiple mints for the same edition. | -| `paused` | The new paused status. | - -### TimeRangeSet - -```solidity -event TimeRangeSet(address indexed edition, uint128 indexed mintId, uint32 startTime, uint32 endTime) -``` - -Emitted when the `paused` status of `edition` is updated. - -| Params: | | -| ----------- | ------------------------------------------------------------------------ | -| `edition` | The edition address. | -| `mintId` | The mint ID, to distinguish between multiple mints for the same edition. | -| `startTime` | The start time of the mint. | -| `endTime` | The end time of the mint. | - -### AffiliateFeeSet - -Emitted when the `affiliateFeeBPS` is updated. - -```solidity -event AffiliateFeeSet(address indexed edition, uint128 indexed mintId, uint16 bps) -``` - -| Params: | | -| --------- | ------------------------------------------------------------------------ | -| `edition` | The edition address. | -| `mintId` | The mint ID, to distinguish between multiple mints for the same edition. | -| `bps` | The affiliate fee basis points. | - -### Minted - -Emitted when a mint happens. - -```solidity -event Minted( - address indexed edition, - uint128 indexed mintId, - address indexed buyer, - uint32 fromTokenId, - uint32 quantity, - uint128 requiredEtherValue, - uint128 platformFee, - uint128 affiliateFee, - address affiliate, - bool affiliated - ) -``` - -| Params: | | -| -------------------- | ------------------------------------------------------------------------ | -| `edition` | The edition address. | -| `mintId` | The mint ID, to distinguish between multiple mints for the same edition. | -| `buyer` | The buyer address. | -| `fromTokenId` | The first token ID of the batch. | -| `quantity` | The size of the batch. | -| `requiredEtherValue` | Total amount of Ether required for payment. | -| `platformFee` | The cut paid to the platform. | -| `affiliateFee` | The cut paid to the affiliate. | -| `affiliate` | The affiliate's address. | -| `affiliated` | Whether the affiliate is affiliated. | - -## Errors - -### Underpaid - -```solidity -error Underpaid(uint256 paid, uint256 required) -``` - -The Ether value paid is below the value required. - -| Params: | | -| ---------- | -------------------------------- | -| `paid` | The amount sent to the contract. | -| `required` | The amount required to mint. | - -### ExceedsAvailableSupply - -```solidity -error ExceedsAvailableSupply(uint32 available) -``` - -The number minted has exceeded the max mintable amount. - -| Params: | | -| ----------- | -------------------------------------------------- | -| `available` | The number of tokens remaining available for mint. | - -### MintNotOpen - -```solidity -error MintNotOpen(uint256 blockTimestamp, uint32 startTime, uint32 endTime) -``` - -The mint is not opened. - -| Params: | | -| ---------------- | ---------------------------- | -| `blockTimestamp` | The current block timestamp. | -| `startTime` | The start time of the mint. | -| `endTime` | The end time of the mint. | - -### MintPaused - -```solidity -error MintPaused() -``` - -The mint is paused. error MintPaused(); - -### InvalidTimeRange - -```solidity -error InvalidTimeRange() -``` - -The `startTime` is not less than the `endTime`. - -### Unauthorized - -```solidity -error Unauthorized() -``` - -Unauthorized caller error Unauthorized(); - -### InvalidAffiliateFeeBPS - -```solidity -error InvalidAffiliateFeeBPS() -``` - -The affiliate fee numerator must not exceed `MAX_BPS`. - -### FeeRegistryIsZeroAddress - -```solidity -error FeeRegistryIsZeroAddress() -``` - -Fee registry cannot be the zero address. diff --git a/pages/protocol/core/sound-creator-v1.mdx b/pages/protocol/core/sound-creator.mdx similarity index 88% rename from pages/protocol/core/sound-creator-v1.mdx rename to pages/protocol/core/sound-creator.mdx index 9110d45..eaa036a 100644 --- a/pages/protocol/core/sound-creator-v1.mdx +++ b/pages/protocol/core/sound-creator.mdx @@ -1,18 +1,12 @@ -# SoundCreatorV1 +# SoundCreatorV2 -**[`contracts/core/SoundCreatorV1.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/SoundCreatorV1.sol)** +**[`contracts/core/SoundCreatorV2.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/SoundCreatorV2.sol)** A factory that allows for a single transaction setup that: + 1. Clones and initializes a `SoundEdition`. + 2. Forwards calldata to an array of target contracts. These calldata can be used to set up the required authorizations and mint schedules. -1. Deploys a minimal proxy of [SoundEdition](/protocol/core/sound-edition) to a deterministic address with a `salt`, and calls its [`initialize`](/protocol/core/sound-edition#initialize) function with the provided `initData` calldata. -2. Authorize one or more minter contracts on SoundEdition. -3. Configure one or more minter contracts to mint on SoundEdition. - -These three steps are perfomed in the [`createSoundAndMints`](sound-creator-v1#createsoundandmints) function. - -Inherits: - -- [OwnableRoles](/protocol/libraries/ownable-roles) +These three steps are perfomed in the [`createSoundAndMints`](sound-creator#createsoundandmints) function. ## Write Functions diff --git a/pages/protocol/core/sound-edition.mdx b/pages/protocol/core/sound-edition.mdx index b6cb8d9..0ac3913 100644 --- a/pages/protocol/core/sound-edition.mdx +++ b/pages/protocol/core/sound-edition.mdx @@ -20,7 +20,6 @@ Inherits: - [ERC721ABurnableUpgradeable](/protocol/libraries/erc721a-burnable-upgradeable) - [ERC721AQueryableUpgradeable](/protocol/libraries/erc721a-queryable-upgradeable) - [OwnableRoles](/protocol/libraries/ownable-roles) from Solady -- [OperatorFilterer](https://github.com/Vectorized/closedsea/blob/main/src/OperatorFilterer.sol) from ClosedSea ## Structs diff --git a/pages/protocol/libraries/ownable-roles.mdx b/pages/protocol/libraries/ownable-roles.mdx index a874d13..94862eb 100644 --- a/pages/protocol/libraries/ownable-roles.mdx +++ b/pages/protocol/libraries/ownable-roles.mdx @@ -162,30 +162,6 @@ function rolesOf(address user) public view virtual returns (uint256) Returns the roles of `user`. -### rolesFromOrdinals - -```solidity -function rolesFromOrdinals( - uint8[] memory ordinals -) public pure returns (uint256) -``` - -Convenience function to return a `roles` bitmap from the `ordinals`. -This is meant for frontends like Etherscan, and is therefore not fully optimized. -Not recommended to be called on-chain. - -### ordinalsFromRoles - -```solidity -function ordinalsFromRoles( - uint256 roles -) public pure returns (uint8[] memory) -``` - -Convenience function to return an array of `ordinals` from the `roles` bitmap. -This is meant for frontends like Etherscan, and is therefore not fully optimized. -Not recommended to be called on-chain. - ## Events ### OwnershipTransferred diff --git a/pages/protocol/overview/_meta.json b/pages/protocol/overview/_meta.json index 943905c..ad522fe 100644 --- a/pages/protocol/overview/_meta.json +++ b/pages/protocol/overview/_meta.json @@ -1,7 +1,5 @@ { "index": "Features", "design": "Design", - "deployments": "Deployments", - "gas": "Gas benchmarks", - "erc721a-info": "ERC721a Info" + "deployments": "Deployments" } diff --git a/pages/protocol/overview/deployments.mdx b/pages/protocol/overview/deployments.mdx index afd0a03..69246fd 100644 --- a/pages/protocol/overview/deployments.mdx +++ b/pages/protocol/overview/deployments.mdx @@ -1,13 +1,11 @@ ## Deployments -Permissionless zero-fee deployments on Goerli testnet and Mainnet: +The following contracts have been deployed on Mainnet, Optimism, Goerli, Optimism-Goerli, and Sepolia. -| Contract | Address | -| --------------------------- | -------------------------------------------- | -| `GoldenEggMetadata` | `0x3ca50e8da8c3d359fc934aea0161f5346ccb62a1` | -| `FixedPriceSignatureMinter` | `0xc8ae7e42e834bc11c906d01726e55571a0620158` | -| `MerkleDropMinter` | `0xda4b6fbb85918700e5ee91f6ce3cc2148af02912` | -| `RangeEditionMinter` | `0x4552f8b70a72a8ea1084bf7b7ba50f10f2f9daa7` | -| `EditionMaxMinter` | `0x5e5d50ea70c9a1b6ed64506f121b094156b8fd20` | -| `SoundEditionV1_1` | `0xE5fEB62FB34aDbA661B7c8256887a8B9a21C2278` | -| `SoundCreatorV1` | `0xaef3e8c8723d9c31863be8de54df2668ef7c4b89` | +| Contract | Address | +|---|---| +| `SoundEditionV2` | `0x0000000000c78FEE168002D89D141517b8E6E0FE` +| `SoundCreatorV2` | `0x0000000000aec84F5BFc2af15EAfb943bf4e3522` +| `SuperMinter` | `0x0000000000CF4558c36229ac0026ee16D3aE35Cd` +| `SoundOnChainMetadata` | `0x0000000000724868d80283B098Ffa809B2181692` +| `SoundMetadata` | `0x0000000000f5A96Dc85959cAeb0Cfe680f108FB5` \ No newline at end of file diff --git a/pages/protocol/overview/design.mdx b/pages/protocol/overview/design.mdx index 5d27af2..af33f67 100644 --- a/pages/protocol/overview/design.mdx +++ b/pages/protocol/overview/design.mdx @@ -12,31 +12,24 @@ These contracts form the core of the system. -- [SoundCreatorV1](/protocol/core/sound-creator-v1) - A factory that deploys minimal proxies of [SoundEdition](/protocol/core/sound-edition). -- [SoundEdition](/protocol/core/sound-edition) - The NFT implementation contract, based on the [721a standard](https://github.com/chiru-labs/ERC721A). -- [IMinterModule](/protocol/core/i-minter-module) - The interface for minter module contracts. -- [IMetadataModule](/protocol/core/i-metadata-module) - The interface for metadata module contracts. +- [SoundCreatorV2](/protocol/core/sound-creator) - A factory that deploys minimal proxies of [SoundEditionV2](/protocol/core/sound-edition). +- [SoundEditionV2](/protocol/core/sound-edition) - The NFT implementation contract, based on [ERC721A](https://github.com/chiru-labs/ERC721A). ### Module contracts -These are the current set of modules that can be optionally implemented by Sound Editions. - #### Metadata modules -- [GoldenEggMetadata](/protocol/modules/golden-egg-metadata) - Implements the Golden Egg used by sound.xyz. +- [SoundMetadata](/protocol/modules/sound-metadata) - Metadata module for SoundEditionV2. +- [SoundOnChainMetadata](/protocol/modules/sound-on-chain-metadata) - Metadata module for SoundEditionV2 (on chain JSON variant). #### Minter modules -The Sound protocol team built this initial set of minters, but any conceivable type of auction or distribution -can be built into custom minters: open editions, bonding-curves, dutch auctions, and more. +Contracts authorized with the `MINTER_ROLE` on a SoundEditionV2 can mint NFTs. -- [EditionMaxMinter](/protocol/modules/minters/edition-max-minter) - A minimalist fixed-price public minting module. Can implement single-schedule range mints. -- [RangeEditionMinter](/protocol/modules/minters/range-edition-minter) - Implements any number of fixed-price range mint schedules for an edition. -- [FixedPriceSignatureMinter](/protocol/modules/minters/fixed-price-signature-minter) - Implements fixed-price signature-based minting. -- [MerkleDropMinter](/protocol/modules/minters/merkle-drop-minter) - Implements fixed-price Merkle proof minting (allow lists). +- [SuperMinter](/protocol/modules/minters/superminter) - Generalized singleton minter that supports a variety of minting mechanisms. diff --git a/pages/protocol/overview/erc721a-info.mdx b/pages/protocol/overview/erc721a-info.mdx deleted file mode 100644 index 059fbd0..0000000 --- a/pages/protocol/overview/erc721a-info.mdx +++ /dev/null @@ -1,86 +0,0 @@ -# ERC721a Info - -The following is some info and recommendations to help developers get the most from the [ERC721a standard](https://github.com/chiru-labs/ERC721A) that [SoundEdition](/protocol/core/sound-edition) implements. - -## ERC721A vs ERC1155 - -| | ERC721A | ERC1155 | -| ---------------- | -------------- | ---------------------- | -| O(1) ownerOf | Yes | No ownerOf | -| O(1) balanceOf | For all tokens | Within fungible tokens | -| O(1)\* bulk mint | For all tokens | Within fungible tokens | -| # mint `SSTORE`s | 3 | 1 | - -\* Approximately O(1) for ERC721A. - - For unique collections, ERC1155 needs a counter which needs 1 more `SSTORE`. - -ERC1155 requires centralized indexing services to emulate ERC721-like functionality off-chain. - -## Transfers - -For users, it is more gas optimal to transfer bulk minted tokens in ascending token ID order. - -For example, if you have bulk minted token IDs (33, 34, ..., 99), -you should transfer in the order (33, 34, ..., 99). - -This is due to how the lazy-initialization mechanism works internally: -it scans uninitialized slots in descending order until it finds an initialized slot. - -## Aux - -Consider using `ERC721A._getAux` and -`ERC721A._setAux` to get / set per-address variables -(e.g. number of whitelist mints per address). - -This can help remove an extra cold `SLOAD` and `SSTORE` operation. - -## Minting - -For typical artwork collections, consider using `_mint` over `_safeMint` if you don't expect users to mint to contracts. - -## Batch Size - -During transfers, ERC721A scans through ownership storage slots until it finds an initialized slot. - -To prevent expensive first-time transfer fees for tokens minted in large batches, either: - -- Restrict the max batch size for public mints to a reasonable number. - -- Break up excessively large batches into mini batches internally when minting. - -- Use `ERC721a._initializeOwnershipAt` every couple tokens to reduce number of reads during a transfer. - -## Efficient Tokenomics - -ERC721A keeps track of additional variables in the internal mappings. - -- `ERC721a.startTimestamp` (starting time of holding) per token. -- `ERC721a.numberMinted` per address. -- `ERC721a.numberBurned` per address. - -These variables hitchhike on the `SLOAD`s and `SSTORE`s at near zero additional gas cost (< 1%). - -You can use them to design tokenomics with very minimal gas overhead. - -The `ERC721a.startTimestamp`, is available via the -`ERC721a.TokenOwnership` struct. - -You can get it from the -`ERC721a._ownershipOf` function or the non-reverting -`ERC721a.ERC721AQueryable.explicitOwnershipOf` function. - -## Other Implementations - -ERC721A is not a one-size-fits-all solution. - -It is heavily optimized for generative artwork NFT collections. - -If your collection does not expect a busy mint phase (e.g. a pure utility NFT), -or does not require bulk minting, -these excellent implementations can be better for lowering overall transaction fees: - -- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) -- [Solmate](https://github.com/Rari-Capital/solmate) - -Use the right tool for the job. diff --git a/pages/protocol/overview/gas.mdx b/pages/protocol/overview/gas.mdx deleted file mode 100644 index d7bfd8b..0000000 --- a/pages/protocol/overview/gas.mdx +++ /dev/null @@ -1,57 +0,0 @@ -import Image from 'next/image' -import { IndentedParagraph } from '../../../components/IndentedParagraph' -import { IndentedDiv } from '../../../components/IndentedDiv' -import { ETH_PRICE, GAS_PRICE_IN_GWEI, gasFigures, getDollarEstimate } from '../../../lib/gas' -import { styled } from '../../../stitches.config' - -export const Div1 = styled('div', { - marginTop: 16, -}) - -export const Div2 = styled('div', { - marginTop: 8, -}) - -# Gas benchmarks - -## Edition & mint config creation - -The following are some scenarios that can be used to estimate the gas cost of deploying & initializing your edition, as well as initializing the configuration(s) for a sale. Each of the listed transactions can be made separately, but it is more convenient to use [`SoundCreatorV1.createSoundAndMints`](/protocol/core/sound-creator-v1#createsoundandmints), which can execute any arbitrary list of contract calls. - - - Dollar figures below assume a gas price of {GAS_PRICE_IN_GWEI} gwei and ETH price of ${ETH_PRICE.toLocaleString()}. To - check calculations with different figures, use a [gas - calculator](https://legacy.ethgasstation.info/calculatorTxV.php). - - -### Public fixed-price edition - -Gas total: **{gasFigures.CREATE_EDITION_1.toLocaleString()}** -Price estimate: **{getDollarEstimate(gasFigures.CREATE_EDITION_1)}** - -- 229,073 gas to deploy & initialize the minimal proxy of [SoundEdition](/protocol/core/sound-edition). -- 24,264 gas to register `MINTER_ROLE` for [EditionMaxMinter](/protocol/modules/minters/edition-max-minter) (`SoundEdition.grantRoles`). -- 74,927 gas for [`EditionMaxMinter.createEditionMint`](/protocol/modules/minters/edition-max-minter#createeditionmint). - -### Public sale + 1 presale - -Gas total: **{gasFigures.CREATE_EDITION_2.toLocaleString()}** -Price estimate: **{getDollarEstimate(gasFigures.CREATE_EDITION_2)}** - -- 229,073 gas to deploy & initialize the minimal proxy of [SoundEdition](/protocol/core/sound-edition). -- 24,264 gas to register `MINTER_ROLE` for [EditionMaxMinter](/protocol/modules/minters/edition-max-minter) (`SoundEdition.grantRoles`). -- 24,264 gas to register `MINTER_ROLE` for [MerkleDropMinter](/protocol/modules/minters/merkle-drop-minter) (`SoundEdition.grantRoles`). -- 74,927 gas for [`EditionMaxMinter.createEditionMint`](/protocol/modules/minters/edition-max-minter#createeditionmint) public sale config. -- 98,515 gas for [`MerkleDropMinter.createEditionMint`](/protocol/modules/minters/merkle-drop-minter#createeditionmint) presale config. - -### Public sale + 1 free mint + 1 presale - -Gas total: **{gasFigures.CREATE_EDITION_3.toLocaleString()}** -Price estimate: **{getDollarEstimate(gasFigures.CREATE_EDITION_3)}** - -- 229,073 gas to deploy & initialize the minimal proxy of [SoundEdition](/protocol/core/sound-edition). -- 24,264 gas to register `MINTER_ROLE` for [EditionMaxMinter](/protocol/modules/minters/edition-max-minter) (`SoundEdition.grantRoles`). -- 24,264 gas to register `MINTER_ROLE` for [MerkleDropMinter](/protocol/modules/minters/merkle-drop-minter) (`SoundEdition.grantRoles`). -- 74,927 gas for [`EditionMaxMinter.createEditionMint`](/protocol/modules/minters/edition-max-minter#createeditionmint) public sale config. -- 98,515 gas for [`MerkleDropMinter.createEditionMint`](/protocol/modules/minters/merkle-drop-minter#createeditionmint) free mint config. -- 98,515 gas for [`MerkleDropMinter.createEditionMint`](/protocol/modules/minters/merkle-drop-minter#createeditionmint) presale config. diff --git a/pages/protocol/overview/index.mdx b/pages/protocol/overview/index.mdx index 4b86b12..f900e2a 100644 --- a/pages/protocol/overview/index.mdx +++ b/pages/protocol/overview/index.mdx @@ -6,15 +6,15 @@ import { IndentedDiv } from '../../../components/IndentedDiv' The Sound Protocol is a permissionless, open-source, modular smart contract framework for efficient creation of digital collectibles by musicians, artists, and creators. -Introductory overview: [Sound Protocol: Technical Deep Dive](https://sound.mirror.xyz/kkecS95u8VuB7b08kCmaooRTBVHqp3AdyAsszY7PA8k) - [Sound Protocol Github repo](https://github.com/soundxyz/sound-protocol) ## Features ### Permissionless -Anyone can freely deploy Sound contracts. + + Anyone can freely deploy and manage NFT contracts on the Sound Protocol. The latest contracts are not ownable contracts. All logic in the new contracts are made to be as general as possible. Any platform can build bespoke logic on Sound Protocol simply through configuration. + ### Non-upgradeable contracts @@ -41,10 +41,3 @@ Introductory overview: [Sound Protocol: Technical Deep Dive](https://sound.mirro With each song as its own contract, Sound Protocol supports end-to-end royalties across primary and secondary sales. Any address can be set to receive the edition’s revenue, be it the artist’s wallet or a payment splitter contract. - -### Gas efficient - - - A great amount of effort was made toward making the Sound Protocol gas efficient. See [gas - benchmarks](/protocol/overview/gas) section for details. - From cdafc2e8d144c45588c6c17eb28e8e043645e727 Mon Sep 17 00:00:00 2001 From: Vectorized Date: Fri, 6 Oct 2023 23:54:51 +0000 Subject: [PATCH 2/2] Update files --- pages/protocol/core/sound-creator.mdx | 349 +++- pages/protocol/core/sound-edition.mdx | 1261 ++++++++---- pages/protocol/libraries/_meta.json | 6 + pages/protocol/modules/_meta.json | 5 +- pages/protocol/modules/metadata/_meta.json | 3 - .../modules/metadata/golden-egg-metadata.mdx | 21 - pages/protocol/modules/minters/_meta.json | 6 - .../modules/minters/edition-max-minter.mdx | 266 --- .../minters/fixed-price-signature-minter.mdx | 316 --- .../modules/minters/merkle-drop-minter.mdx | 372 ---- .../modules/minters/range-edition-minter.mdx | 342 ---- pages/protocol/modules/sound-metadata.mdx | 220 +++ .../modules/sound-on-chain-metadata.mdx | 507 +++++ pages/protocol/modules/super-minter.mdx | 1709 +++++++++++++++++ pages/protocol/overview/design.mdx | 14 +- 15 files changed, 3580 insertions(+), 1817 deletions(-) create mode 100644 pages/protocol/libraries/_meta.json delete mode 100644 pages/protocol/modules/metadata/_meta.json delete mode 100644 pages/protocol/modules/metadata/golden-egg-metadata.mdx delete mode 100644 pages/protocol/modules/minters/_meta.json delete mode 100644 pages/protocol/modules/minters/edition-max-minter.mdx delete mode 100644 pages/protocol/modules/minters/fixed-price-signature-minter.mdx delete mode 100644 pages/protocol/modules/minters/merkle-drop-minter.mdx delete mode 100644 pages/protocol/modules/minters/range-edition-minter.mdx create mode 100644 pages/protocol/modules/sound-metadata.mdx create mode 100644 pages/protocol/modules/sound-on-chain-metadata.mdx create mode 100644 pages/protocol/modules/super-minter.mdx diff --git a/pages/protocol/core/sound-creator.mdx b/pages/protocol/core/sound-creator.mdx index eaa036a..f525897 100644 --- a/pages/protocol/core/sound-creator.mdx +++ b/pages/protocol/core/sound-creator.mdx @@ -3,68 +3,181 @@ **[`contracts/core/SoundCreatorV2.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/SoundCreatorV2.sol)** A factory that allows for a single transaction setup that: - 1. Clones and initializes a `SoundEdition`. + 1. Clones and initializes a SoundEdition. 2. Forwards calldata to an array of target contracts. These calldata can be used to set up the required authorizations and mint schedules. -These three steps are perfomed in the [`createSoundAndMints`](sound-creator#createsoundandmints) function. +This factory does not store the implementation address. Instead, it is provided as an argument to the function calls. + +This factory allows for collectors to execute an artist-signed SoundCreation struct payload and mint in a single transaction. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Structs + +{/* ------------------------------------------------------------------------------------------- */} + +### SoundCreation + +```solidity +struct SoundCreation { + // The address of the SoundEdition implementation. + address implementation; + // The initial owner of the deployed SoundEdition. + address owner; + // The salt used for deploying the SoundEdition via the SoundCreator factory. + bytes32 salt; + // The calldata passed to the SoundEdition to initialize it. + bytes initData; + // Array of contracts to call after initializing the SoundEdition. + address[] contracts; + // Array of abi encoded calldata to pass to each entry in `contracts`. + bytes[] data; + // The current nonce used to sign the SoundCreation struct, if required. + // Just generate some really random number on the client side for this. + uint256 nonce; +} +``` + +A struct containing all the data required for creating a SoundEdition and setting up all other relevant contracts. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Write Functions -### createSoundAndMints +{/* ------------------------------------------------------------------------------------------- */} + +### create ```solidity -function createSoundAndMints( - bytes32 salt, - bytes calldata initData, - address[] calldata contracts, - bytes[] calldata data -) external returns (address soundEdition, bytes[] memory results) +function create(SoundCreation calldata creation) + external + returns (address soundEdition, bytes[] memory results) ``` -Creates a Sound Edition proxy, initializes it, and creates mint configurations on a given set of minter addresses. +Creates a SoundEdition and sets up all other relevant contracts. **Calling conditions:** -- The lengths of `contracts` and `data` must be the same. -- All of the `contracts` must exist, and all of `data` must be properly encoded to be valid calldata for each of the the contracts. +- The caller must be `creation.owner`. + +|Params:|| +|---|---| +|`creation`|The SoundCreation struct. -| Params: | | -| ----------- | -------------------------------------------------------------------------------------------------------------------- | -| `salt` | The salt used for the CREATE2 to deploy the clone to a deterministic address. | -| `initData` | The calldata to initialize SoundEdition via `abi.encodeWithSelector`. | -| `contracts` | A list of contracts to call. | -| `data` | A list of calldata created via `abi.encodeWithSelector` This must contain the same number of entries as `contracts`. | +Returns the address of the clone, and the results of calling each of the contracts. -| Returns: | | -| -------------- | ---------------------------------------------------------------------- | -| `soundEdition` | Returns the address of the created contract. | -| `results` | The results of calling the contracts. Use `abi.decode` to decode them. | +{/* ------------------------------------------------------------------------------------------- */} -### setEditionImplementation +### createWithSignature ```solidity -function setEditionImplementation(address newImplementation) external +function createWithSignature(SoundCreation calldata creation, bytes calldata signature) + external + returns (address soundEdition, bytes[] memory results) ``` -Changes the SoundEdition implementation contract address. +Creates a SoundEdition on behalf of `creation.owner`. -**Calling conditions:** +|Params:|| +|---|---| +|`creation`|The SoundCreation struct. +|`signature`|The signature for the SoundCreation struct, by `creation.owner`. + +Returns the address of the clone, and the results of calling each of the contracts. + +{/* ------------------------------------------------------------------------------------------- */} + +### mint + +```solidity +function mint( + address minter, + bytes calldata mintData, + address refundTo +) external payable +``` + +Calls `minter` with `mintData`. + +After which, refunds any remaining ETH balance in the contract. + +If `minter` is the zero address, the function is a no-op. + +|Params:|| +|---|---| +|`minter`|The minter contract to call. +|`mintData`|The abi encoded calldata to the minter contract. +|`refundTo`|The address to transfer any remaining ETH in the contract after the calls.
If `address(0)`,remaining ETH will NOT be refunded.
If `address(1)`, remaining ETH will be refunded to `msg.sender`.
If anything else, remaining ETH will be refunded to `refundTo`. | + +Returns the address of the clone, and the results of calling each of the contracts. + +{/* ------------------------------------------------------------------------------------------- */} + +### createWithSignatureAndMint -- The caller must be the owner of the contract. +```solidity +function createWithSignatureAndMint( + SoundCreation calldata creation, + bytes calldata signature, + address minter, + bytes calldata mintData, + address refundTo +) external payable returns (address soundEdition, bytes[] memory results) +``` + +Equivalent to calling [`createWithSignature`](#createWithSignature), followed by [`mint`](#mint). + +|Params:|| +|---|---| +|`creation`|The SoundCreation struct. +|`signature`|The signature for the SoundCreation struct, by `creation.owner`. +|`minter`|The minter contract to call. +|`mintData`|The abi encoded calldata to the minter contract. +|`refundTo`|The address to transfer any remaining ETH in the contract after the calls.
If `address(0)`,remaining ETH will NOT be refunded.
If `address(1)`, remaining ETH will be refunded to `msg.sender`.
If anything else, remaining ETH will be refunded to `refundTo`. | -| Params: | | -| ------------------- | ----------------------------------------- | -| `newImplementation` | The new implementation address to be set. | +Returns the address of the clone, and the results of calling each of the contracts. + +{/* ------------------------------------------------------------------------------------------- */} + +### invalidateNonces + +```solidity +function invalidateNonces(uint256[] calldata nonces) external +``` + +Invalidates the nonces for the `msg.sender`. + +|Params:|| +|---|---| +|`nonces`|An array of nonces. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Read-only Functions -### soundEditionImplementation +{/* ------------------------------------------------------------------------------------------- */} + +### noncesInvalidated ```solidity -function soundEditionImplementation() external returns (address) +function noncesInvalidated(address signer, uint256[] calldata nonces) + external + view + returns (bool[] memory results) ``` -The address of the sound edition implementation. +Returns whether each of the `nonces` of `signer` has been invalidated. + +|Params:|| +|---|---| +|`signer`|The signer of the signature. +|`nonces`|An array of nonces. + + +{/* ------------------------------------------------------------------------------------------- */} ### soundEditionAddress @@ -77,24 +190,110 @@ function soundEditionAddress( Returns the deterministic address for the sound edition clone. -| Params: | | -| :------ | :-----------------------------------------------: | -| `by` | The caller of the `createSoundAndMints` function. | -| `salt` | The salt, generated on the client side. | +|Params:|| +|---|---| +|`by`|The caller of the `createSoundAndMints` function. +|`salt`|The salt, generated on the client side. + +{/* ------------------------------------------------------------------------------------------- */} -| Returns: | | -| :------- | :--------------------------: | -| `addr` | The computed address. | -| `exists` | Whether the contract exists. | +### isValidSignature + +```solidity +function isValidSignature( + SoundCreation calldata creation, + bytes calldata signature +) external view returns (bool isValid) +``` + +Returns if the signature for the creation struct is correctly signed, as well as the creation's nonce is still valid. + +|Params:|| +|---|---| +|`creation`|The SoundCreation struct. +|`signature`|The signature for the SoundCreation struct. + +{/* ------------------------------------------------------------------------------------------- */} + +### computeDigest + +```solidity +function computeDigest(SoundCreation calldata creation) + external + view + returns (bytes32 digest) +``` + +Computes the EIP-712 hash of the SoundCreation struct. + +|Params:|| +|---|---| +|`creation`|The SoundCreation struct. + +{/* ------------------------------------------------------------------------------------------- */} + +### SOUND_CREATION_TYPEHASH + +```solidity +function SOUND_CREATION_TYPEHASH() external view returns (bytes32) +``` + +Returns the SoundCreation struct's EIP-712 typehash. + +{/* ------------------------------------------------------------------------------------------- */} + +### DOMAIN_TYPEHASH + +```solidity +function DOMAIN_TYPEHASH() external view returns (bytes32) +``` + +Returns the EIP-712 domain typehash. + +{/* ------------------------------------------------------------------------------------------- */} + +### name + +```solidity +function name() external pure returns (string) +``` + +Returns the EIP-712 domain name. + +{/* ------------------------------------------------------------------------------------------- */} + +### version + +```solidity +function version() external pure returns (string) +``` + +Returns the EIP-712 domain version. + +{/* ------------------------------------------------------------------------------------------- */} + +### domainSeparator + +```solidity +function domainSeparator() external pure returns (string) +``` + +Returns the EIP-712 domain separator. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Events -### SoundEditionCreated +{/* ------------------------------------------------------------------------------------------- */} + +### Created ```solidity -event SoundEditionCreated( - address indexed soundEdition, - address indexed deployer, +event Created( + address indexed implementation, + address indexed edition, + address indexed owner, bytes initData, address[] contracts, bytes[] data, @@ -104,29 +303,38 @@ event SoundEditionCreated( Emitted when an edition is created. -| Params: | | -| -------------- | ---------------------------------------------------------------------- | -| `soundEdition` | The address of the edition. | -| `deployer` | The address of the deployer. | -| `initData` | The calldata to initialize SoundEdition via `abi.encodeWithSelector`. | -| `contracts` | The list of contracts called. | -| `data` | The list of calldata created via `abi.encodeWithSelector` | -| `results` | The results of calling the contracts. Use `abi.decode` to decode them. | +|Params:|| +|---|---| +|`implementation`|The address of the SoundEdition implementation. +|`edition`|The address of the deployed SoundEdition. +|`owner`|The address of the owner. +|`initData`|The calldata to initialize SoundEdition via `abi.encodeWithSelector`. +|`contracts`|The list of contracts called. +|`data`|The list of calldata created via `abi.encodeWithSelector`. +|`results`|The results of calling the contracts. Use `abi.decode` to decode them. + +{/* ------------------------------------------------------------------------------------------- */} -### SoundEditionImplementationSet +### NoncesInvalidated ```solidity -event SoundEditionImplementationSet(address newImplementation) +event NoncesInvalidated(address indexed signer, uint256[] nonces) ``` -Emitted when the edition implementation address is set. +Emitted when the `nonces` of `signer` are invalidated. -| Params: | | -| ------------------- | ----------------------------------------- | -| `newImplementation` | The new implementation address to be set. | +|Params:|| +|---|---| +|`signer`|The signer of the nonce. +|`nonces`|The array of invalidated nonces. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Errors +{/* ------------------------------------------------------------------------------------------- */} + ### ImplementationAddressCantBeZero ```solidity @@ -135,6 +343,8 @@ error ImplementationAddressCantBeZero() Thrown if the implementation address is zero. +{/* ------------------------------------------------------------------------------------------- */} + ### ArrayLengthsMismatch ```solidity @@ -142,3 +352,24 @@ error ArrayLengthsMismatch() ``` Thrown if the lengths of the input arrays are not equal. + +{/* ------------------------------------------------------------------------------------------- */} + +### Unauthorized + +```solidity +error Unauthorized() +``` + +Not authorized to perform the action. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidSignature + +```solidity +error InvalidSignature() +``` + +The signature for the SoundCreation struct is invalid. +This could be caused be an invalid parameter, signer, or invalidated nonce. diff --git a/pages/protocol/core/sound-edition.mdx b/pages/protocol/core/sound-edition.mdx index 0ac3913..e3bb193 100644 --- a/pages/protocol/core/sound-edition.mdx +++ b/pages/protocol/core/sound-edition.mdx @@ -1,18 +1,34 @@ -# SoundEdition +# SoundEditionV2 -**[`contracts/core/SoundEditionV1_1.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/SoundEditionV1_1.sol)** +[`contracts/core/SoundEditionV2.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/core/SoundEditionV2.sol) The Sound Protocol NFT contract. +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + Overview: -- An implementation of [ERC721A](https://github.com/chiru-labs/ERC721A). -- Enables the owner, authorized minter contracts or administrators to batch mint NFTs. Authorization is granted by the owner via the [`grantRoles`](#grantRoles) function inherited from [`OwnableRoles`](/protocol/libraries/ownable-roles). +- Inherits [ERC721A](https://github.com/chiru-labs/ERC721A). +- Enables the owner, authorized minter contracts or administrators to batch mint NFTs. Authorization is granted by the owner via the [`grantRoles`](/protocol/libraries/ownable-roles#grantroles) function inherited from [`OwnableRoles`](/protocol/libraries/ownable-roles). - Token IDs are minted sequentially (e.g. 1, 2, 3...) starting from 1. - Can optionally implement a `metadataModule` that effectively overrides the default `tokenURI` function. - Can natively support [range editions](https://sound.mirror.xyz/hmz2pueqBV37MD-mULjvch0vQoc-VKJdsfqXf8jTB30) via a dynamic maximum mintable supply (based on a `editionCutoffTime`), - Has a pseudorandom `mintRandomness` number optionally set on each [`mint`](#mint) call, which can be used for game mechanics. - Implements [EIP-2981 Royalty Standard](https://eips.ethereum.org/EIPS/eip-2981). +- Supports per-token tier. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +Tiers: + +- The zeroth tier is called the `GA_TIER` (short for General Admission). This is a special tier that uses default settings on the SoundEdition, as well as platform default settings on minters. +- Tiers can range from 0 to 255 inclusive. +- Each tier contains its own max mintable range, cutoff time, and mint randomness. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} Inherits: @@ -21,13 +37,76 @@ Inherits: - [ERC721AQueryableUpgradeable](/protocol/libraries/erc721a-queryable-upgradeable) - [OwnableRoles](/protocol/libraries/ownable-roles) from Solady +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + ## Structs -### EditionInfo +{/* ------------------------------------------------------------------------------------------- */} + +### TierInfo + +```solidity +struct TierInfo { + // The tier. + uint8 tier; + // The current max mintable amount. + uint32 maxMintable; + // The lower bound of the maximum number of tokens that can be minted for the tier. + uint32 maxMintableLower; + // The upper bound of the maximum number of tokens that can be minted for the tier. + uint32 maxMintableUpper; + // The timestamp (in seconds since unix epoch) after which the + // max amount of tokens mintable for the tier will drop from + // `maxMintableUpper` to `maxMintableLower`. + uint32 cutoffTime; + // The total number of tokens minted for the tier. + uint32 minted; + // The mint randomness for the tier. + uint256 mintRandomness; + // Whether the tier mints have concluded. + bool mintConcluded; + // Whether the tier has mint randomness enabled. + bool mintRandomnessEnabled; + // Whether the tier is frozen. + bool isFrozen; +} +``` + +The information pertaining to a tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### TierCreation + +```solidity +struct TierCreation { + // The tier. + uint8 tier; + // The lower bound of the maximum number of tokens that can be minted for the tier. + uint32 maxMintableLower; + // The upper bound of the maximum number of tokens that can be minted for the tier. + uint32 maxMintableUpper; + // The timestamp (in seconds since unix epoch) after which the + // max amount of tokens mintable for the tier will drop from + // `maxMintableUpper` to `maxMintableLower`. + uint32 cutoffTime; + // Whether the tier has mint randomness enabled. + bool mintRandomnessEnabled; + // Whether the tier is frozen. + bool isFrozen; +} +``` + +A struct containing the arguments for creating a tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### EditionInfo ```solidity struct EditionInfo { - // Base URI for the tokenId. + // Base URI for the metadata. string baseURI; // Contract URI for OpenSea storefront. string contractURI; @@ -37,28 +116,14 @@ struct EditionInfo { string symbol; // Address that receives primary and secondary royalties. address fundingRecipient; - // The current max mintable amount; - uint32 editionMaxMintable; - // The lower limit of the maximum number of tokens that can be minted. - uint32 editionMaxMintableUpper; - // The upper limit of the maximum number of tokens that can be minted. - uint32 editionMaxMintableLower; - // The timestamp (in seconds since unix epoch) after which the - // max amount of tokens mintable will drop from - // `maxMintableUpper` to `maxMintableLower`. - uint32 editionCutoffTime; - // Address of metadata module, address(0x00) if not used. + // Address of the metadata module. Optional. address metadataModule; - // The current mint randomness value. - uint256 mintRandomness; + // Whether the metadata is frozen. + bool isMetadataFrozen; + // Whether the ability to create tiers is frozen. + bool isCreateTierFrozen; // The royalty BPS (basis points). uint16 royaltyBPS; - // Whether the mint randomness is enabled. - bool mintRandomnessEnabled; - // Whether the mint has concluded. - bool mintConcluded; - // Whether the metadata has been frozen. - bool isMetadataFrozen; // Next token ID to be minted. uint256 nextTokenId; // Total number of tokens burned. @@ -67,79 +132,106 @@ struct EditionInfo { uint256 totalMinted; // Total number of tokens currently in existence. uint256 totalSupply; + // An array of tier info. From lowest (0-indexed) to highest. + TierInfo[] tierInfo; } ``` -Holds information pertaining to the SoundEdition. +The information pertaining to this edition. + +{/* ------------------------------------------------------------------------------------------- */} -This struct is intended for off-chain queries, and can be retrieved via the `editionInfo` function. +### EditionInitialization + +```solidity +struct EditionInitialization { + // Name of the collection. + string name; + // Symbol of the collection. + string symbol; + // Address of the metadata module. Optional. + address metadataModule; + // Base URI for the metadata. + string baseURI; + // Contract URI for OpenSea storefront. + string contractURI; + // Address that receives primary and secondary royalties. + address fundingRecipient; + // The royalty BPS (basis points). + uint16 royaltyBPS; + // Whether the metadata is frozen. + bool isMetadataFrozen; + // Whether the ability to create tiers is frozen. + bool isCreateTierFrozen; + // An array of tier creation structs. From lowest (0-indexed) to highest. + TierCreation[] tierCreations; +} +``` + +A struct containing the arguments for initialization. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Write Functions -### initialize - -```solidity -function initialize( - string memory name_, - string memory symbol_, - address metadataModule_, - string memory baseURI_, - string memory contractURI_, - address fundingRecipient_, - uint16 royaltyBPS_, - uint32 editionMaxMintableLower_, - uint32 editionMaxMintableUpper_, - uint32 editionCutoffTime_, - uint8 flags_ -) external +{/* ------------------------------------------------------------------------------------------- */} + +### initialize + +```solidity +function initialize(EditionInitialization calldata init) external ``` Initializes the contract. -This function is called in the [`createSoundAndMints`](sound-creator-v1#createsoundandmints) function of SoundCreatorV1, right after the creation of the SoundEdtion, within the same transaction. - -| Params: | | -| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name_` | Name of the collection. | -| `symbol_` | Symbol of the collection. | -| `metadataModule_` | Address of metadata module, address(0x00) if not used. | -| `baseURI_` | Base URI. | -| `contractURI_` | Contract URI for OpenSea storefront. | -| `fundingRecipient_` | Address that receives primary and secondary royalties. | -| `royaltyBPS_` | Royalty amount in bps (basis points). | -| `editionMaxMintableLower_` | The lower bound of the max mintable quantity for the edition. | -| `editionMaxMintableUpper_` | The upper bound of the max mintable quantity for the edition. | -| `editionCutoffTime_` | The timestamp after which `editionMaxMintable` drops from `editionMaxMintableUpper` to `max(_totalMinted(), editionMaxMintableLower)`. | -| `flags_` | The bitwise OR result of the initialization flags.
See: [METADATA_IS_FROZEN_FLAG](#metadata_is_frozen_flag)
See: [MINT_RANDOMNESS_ENABLED_FLAG](#mint_randomness_enabled_flag) | +This function is called in the [`create`](/protocol/core/sound-creator#create) function of SoundCreatorV2, right after the creation of the SoundEdtion, within the same transaction. + +|Params:|| +|---|---| +|`init`|The initialization struct. + +{/* ------------------------------------------------------------------------------------------- */} ### mint ```solidity -function mint(address to, uint256 quantity) external payable returns (uint256) +function mint( + uint8 tier, + address to, + uint256 quantity +) external payable returns (uint256 fromTokenId) ``` -Mints `quantity` tokens to addrress `to` +Mints `quantity` tokens to addrress `to` Each token will be assigned a token ID that is consecutively increasing. **Calling conditions:** - The caller must be the owner of the contract, or have either the - [`ADMIN_ROLE`](sound-edition#admin_role), [`MINTER_ROLE`](sound-edition#minter_role), which can be granted via `grantRoles`. + [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role), [`MINTER_ROLE`](/protocol/core/sound-edition#minter_role), which can be granted via [`grantRoles`](/protocol/libraries/ownable-roles#grantroles). Multiple minters, such as different minter contracts, can be authorized simultaneously. -| Params: | | -| ---------- | ------------------------- | -| `to` | Address to mint to. | -| `quantity` | Number of tokens to mint. | +|Params:|| +|---|---| +|`tier`| The tier. +|`to`| Address to mint to. +|`quantity`| Number of tokens to mint. Returns the first token ID minted. +{/* ------------------------------------------------------------------------------------------- */} + ### airdrop ```solidity -function airdrop(address[] calldata to, uint256 quantity) external returns (uint256) +function airdrop( + uint8 tier, + address[] calldata to, + uint256 quantity +) external returns (uint256 fromTokenId) ``` Mints `quantity` tokens to each of the addresses in `to`. @@ -147,22 +239,27 @@ Mints `quantity` tokens to each of the addresses in `to`. **Calling conditions:** - The caller must be the owner of the contract, or have the - [`ADMIN_ROLE`](sound-edition#admin_role), which can be granted via `grantRoles`. - -| Params: | | -| ---------- | ------------------------- | -| `to` | Address to mint to. | -| `quantity` | Number of tokens to mint. | - + [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role), which can be granted via [`grantRoles`](/protocol/libraries/ownable-roles#grantroles). + +|Params:|| +|---|---| +|`tier`| The tier. +|`to`| Addresses to mint to. +|`quantity`| Number of tokens to mint. + Returns the first token ID minted. +{/* ------------------------------------------------------------------------------------------- */} + ### withdrawETH ```solidity function withdrawETH() external ``` -Withdraws collected ETH royalties to the fundingRecipient. +Withdraws collected ETH royalties to the fundingRecipient. + +{/* ------------------------------------------------------------------------------------------- */} ### withdrawERC20 @@ -170,11 +267,13 @@ Withdraws collected ETH royalties to the fundingRecipient. function withdrawERC20(address[] calldata tokens) external ``` -Withdraws collected ERC20 royalties to the fundingRecipient. +Withdraws collected ERC20 royalties to the fundingRecipient. + +|Params:|| +|---|---| +| `tokens` | array of ERC20 tokens to withdraw -| Params: | | -| -------- | --------------------------------- | -| `tokens` | array of ERC20 tokens to withdraw | +{/* ------------------------------------------------------------------------------------------- */} ### setMetadataModule @@ -184,13 +283,14 @@ function setMetadataModule(address metadataModule) external Sets metadata module. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `metadataModule` | Address of metadata module. -| Params: | | -| ---------------- | --------------------------- | -| `metadataModule` | Address of metadata module. | +{/* ------------------------------------------------------------------------------------------- */} ### setBaseURI @@ -200,13 +300,14 @@ function setBaseURI(string memory baseURI) external Sets global base URI. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `baseURI` | The base URI to be set. -| Params: | | -| --------- | ----------------------- | -| `baseURI` | The base URI to be set. | +{/* ------------------------------------------------------------------------------------------- */} ### setContractURI @@ -216,13 +317,14 @@ function setContractURI(string memory contractURI) external Sets contract URI. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `contractURI` | The contract URI to be set. -| Params: | | -| ------------- | --------------------------- | -| `contractURI` | The contract URI to be set. | +{/* ------------------------------------------------------------------------------------------- */} ### freezeMetadata @@ -232,9 +334,23 @@ function freezeMetadata() external Freezes metadata by preventing any more changes to base URI. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). + +{/* ------------------------------------------------------------------------------------------- */} + +### freezeCreateTier + +```solidity +function freezeCreateTier() external +``` -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +Freezes any more new tiers from being added. + +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). + +{/* ------------------------------------------------------------------------------------------- */} ### setFundingRecipient @@ -244,13 +360,36 @@ function setFundingRecipient(address fundingRecipient) external Sets funding recipient address. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). + +|Params:|| +|---|---| +| `fundingRecipient` | Address to be set as the new funding recipient. + +{/* ------------------------------------------------------------------------------------------- */} + +### createSplit + +```solidity +function createSplit(address splitMain, bytes calldata splitData) + external + returns (address split) +``` + +Creates a new split wallet via the SplitMain contract, then sets it as the `fundingRecipient`. -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -| Params: | | -| ------------------ | ----------------------------------------------- | -| `fundingRecipient` | Address to be set as the new funding recipient. | +|Params:|| +|---|---| +| `splitMain` | The address of the SplitMain contract. +| `splitData` | The calldata to forward to the SplitMain contract to create a split. + +Returns the address of the new split contract. + +{/* ------------------------------------------------------------------------------------------- */} ### setRoyalty @@ -260,256 +399,375 @@ function setRoyalty(uint16 bps) external Sets royalty amount in bps (basis points). -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `bps` | The new royalty basis points to be set. -| Params: | | -| ------- | --------------------------------------- | -| `bps` | The new royalty basis points to be set. | +{/* ------------------------------------------------------------------------------------------- */} -### setEditionMaxMintableRange +### freezeTier ```solidity -function setEditionMaxMintableRange( - uint32 editionMaxMintableLower_, - uint32 editionMaxMintableUpper_ +function freezeTier(uint8 tier) external +``` + +Freezes the tier. + +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). + +|Params:|| +|---|---| +| `tier` | The tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### setMaxMintableRange + +```solidity +function setMaxMintableRange( + uint8 tier, + uint32 lower, + uint32 upper ) external ``` Sets the edition max mintable range. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `tier` | The tier. +| `lower` | The lower limit of the maximum number of tokens that can be minted. +| `upper` | The upper limit of the maximum number of tokens that can be minted. -| Params: | | -| -------------------------- | ------------------------------------------------------------------- | -| `editionMaxMintableLower_` | The lower limit of the maximum number of tokens that can be minted. | -| `editionMaxMintableUpper_` | The upper limit of the maximum number of tokens that can be minted. | +{/* ------------------------------------------------------------------------------------------- */} -### setEditionCutoffTime +### setCutoffTime ```solidity -function setEditionCutoffTime(uint32 editionCutoffTime_) external +function setCutoffTime(uint8 tier, uint32 cutoffTime) external ``` -Sets the timestamp after which, the `editionMaxMintable` drops from `editionMaxMintableUpper` to `editionMaxMintableLower`. +Sets the timestamp after which, the max mintable amount for the `tier` drops from the upper limit to the lower limit. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `tier` | The tier. +| `cutoffTime` | The timestamp. -| Params: | | -| -------------------- | -------------- | -| `editionCutoffTime_` | The timestamp. | +{/* ------------------------------------------------------------------------------------------- */} ### setMintRandomnessEnabled ```solidity -function setMintRandomnessEnabled(bool mintRandomnessEnabled_) external +function setMintRandomnessEnabled(bool enabled) external ``` Sets whether the `mintRandomness` is enabled. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `tier` | The tier. +| `enabled` | The boolean value. -| Params: | | -| ------------------------ | ------------------ | -| `mintRandomnessEnabled_` | The boolean value. | +{/* ------------------------------------------------------------------------------------------- */} -### setOperatorFilteringEnabled +### createTier ```solidity -function setOperatorFilteringEnabled(bool operatorFilteringEnabled_) external +function createTier(TierCreation calldata creation) external ``` -Sets whether OpenSea's [OperatorFilter registry](https://github.com/ProjectOpenSea/operator-filter-registry) is enabled. +Adds a new tier. -**Calling conditions:** +**Calling conditions:** + - The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role). -- The caller must be the owner of the contract, or have the [`ADMIN_ROLE`](sound-edition#admin_role). +|Params:|| +|---|---| +| `creation` | The tier creation data. -| Params: | | -| --------------------------- | ------------------ | -| `operatorFilteringEnabled_` | The boolean value. | +{/* ------------------------------------------------------------------------------------------- */} -### setApprovalForAll +### emitAllMetadataUpdate ```solidity -function setApprovalForAll(address operator, bool approved) external +function emitAllMetadataUpdate() external ``` -Approves or removes `operator` as an operator for the caller. -Operators can call `transferFrom` or ` safeTransferFrom` for any token owned by the caller. If the `OPERATOR_FILTERING_ENABLED_FLAG` is set, -this function will revert if the operator is not approved by the [OperatorFilter registry](https://github.com/ProjectOpenSea/operator-filter-registry). +Emits an event to signal to marketplaces to refresh all the metadata. -**Calling conditions:** +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} -- The `operator` cannot be the caller. +## Read-only Functions -| Params: | | -| ---------- | ---------------------------------------- | -| `operator` | The operator address. | -| `approved` | Whether or not the operator is approved. | +{/* ------------------------------------------------------------------------------------------- */} -### approve +### editionInfo ```solidity -function approve(address operator, bool approved) external +function editionInfo() external view returns (EditionInfo memory) ``` -Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. If the `OPERATOR_FILTERING_ENABLED_FLAG` is set, -this function will revert if the operator is not approved by the [OperatorFilter registry](https://github.com/ProjectOpenSea/operator-filter-registry). +Returns the edition info. -**Calling conditions:** +{/* ------------------------------------------------------------------------------------------- */} -- The `operator` cannot be the caller. +### tierInfo -| Params: | | -| --------- | -------------------------- | -| `to` | The permissioned operator. | -| `tokenId` | The permissioned token. | +```solidity +function tierInfo(uint8 tier) external view returns (TierInfo memory info) +``` -### transferFrom +|Params:|| +|---|---| +| `tier` | The tier. -```solidity - function transferFrom(address from, address to, uint256 tokenId) external payable +Returns the tier info. + +{/* ------------------------------------------------------------------------------------------- */} + +### GA_TIER + +```solidity +function GA_TIER() external pure returns (uint8) ``` -Transfers `tokenId` token from `from` to `to`. +Returns the GA tier, which is 0. -> **WARNING: -> Usage of this method is discouraged, use `safeTransferFrom` whenever possible.** +{/* ------------------------------------------------------------------------------------------- */} -**Calling conditions:** +### BPS_DENOMINATOR + +```solidity +function BPS_DENOMINATOR() external pure returns (uint8) +``` -- `from` cannot be the zero address. -- `from` can only be approved operators (if `OPERATOR_FILTERING_ENABLED_FLAG` is set) -- `to` cannot be the zero address. -- `tokenId` token must be owned by `from`. -- If the caller is not `from`, it must be approved to move this token - by either `approve` or `setApprovalForAll`. +Returns the basis points denominator used in fee calculations, which is 10000. -| Params: | | -| --------- | ----------------------- | -| `from` | The sender. | -| `to` | The receiver. | -| `tokenId` | The permissioned token. | +{/* ------------------------------------------------------------------------------------------- */} -### safeTransferFrom +### MINTER_ROLE ```solidity - function safeTransferFrom(address from, address to, bytes calldata data) external payable +function MINTER_ROLE() external view returns (uint256) ``` -Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. +Returns the minter role flag. -**Calling conditions:** +{/* ------------------------------------------------------------------------------------------- */} -- `from` cannot be the zero address. -- `from` can only be approved operators (if `OPERATOR_FILTERING_ENABLED_FLAG` is set) - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be have been allowed to move - this token by either `approve` or `setApprovalForAll`. - If `to` refers to a smart contract, it must implement - `IERC721Receiver-onERC721Received`, which is called upon a safe transfer. - -| Params: | | -| --------- | --------------------------------------------------------------------- | -| `from` | The sender. | -| `to` | The receiver. | -| `tokenId` | The permissioned token. | -| `data` | Optional data to be used by receiver if receiver is a smart contract. | +### ADMIN_ROLE -## Read-only Functions +```solidity +function ADMIN_ROLE() external view returns (uint256) +``` -### editionInfo +Returns the admin role flag. -```solidity -function editionInfo() external view returns (EditionInfo memory) +{/* ------------------------------------------------------------------------------------------- */} + +### tokenTier + +```solidity +function tokenTier(uint256 tokenId) external view returns (uint8) ``` -Returns the edition info. +|Params:|| +|---|---| +| `tokenId` | The token ID. -### supportsInterface +Returns the tier of the `tokenId`. -`IERC165-supportsInterface` +{/* ------------------------------------------------------------------------------------------- */} -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) +### explicitTokenTier + +```solidity +function explicitTokenTier(uint256 tokenId) external view returns (uint8) ``` -Returns `true` if this contract implements the interface defined by `interfaceId`. +|Params:|| +|---|---| +| `tokenId` | The token ID. -See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. +Returns the tier of the `tokenId`. -| Params: | | -| ------------- | ------------------------ | -| `interfaceId` | The 4 byte interface ID. | +> Note: Will NOT revert if any `tokenId` does not exist. +> +> If the token has not been minted, the tier will be zero. +> +> If the token is burned, the tier will be the tier before it was burned. -| Supported Interface IDs: | | -| ------------------------ | ------------ | -| `IERC165` | `0x01ffc9a7` | -| `ERC721` | `0x80ac58cd` | -| `ERC721Metadata` | `0x5b5e139f` | -| `ISoundEditionV1` | `0x50899e54` | -| `ISoundEditionV1_1` | `0x425aac3d` | +{/* ------------------------------------------------------------------------------------------- */} -### MINTER_ROLE +### tierTokenIds -```solidity -function MINTER_ROLE() external view returns (uint256) +```solidity +function tierTokenIds(uint8 tier) external view returns (uint256[] memory tokenIds) ``` -Returns the minter role flag. +|Params:|| +|---|---| +| `tier` | The tier. -### ADMIN_ROLE +Returns an array of all the token IDs in the tier. -```solidity -function ADMIN_ROLE() external view returns (uint256) +{/* ------------------------------------------------------------------------------------------- */} + +### tierTokenIdsIn + +```solidity +function tierTokenIdsIn( + uint8 tier, + uint256 start, + uint256 stop +) external view returns (uint256[] memory tokenIds) ``` -Returns the admin role flag. +|Params:|| +|---|---| +| `tier` | The tier. +| `start` | The start of the range. Inclusive. +| `stop` | The stop of the range. Exclusive. -### ADDRESS_BATCH_MINT_LIMIT +Returns an array of all the token IDs in the tier, within the range [start, stop). -```solidity -function ADDRESS_BATCH_MINT_LIMIT() external pure returns (uint256) +{/* ------------------------------------------------------------------------------------------- */} + +### tierTokenIdIndex + +```solidity +function tierTokenIdIndex(uint256 tokenId) external view returns (uint256) +``` + +|Params:|| +|---|---| +| `tokenId` | The token ID to find. + +Returns the index of `tokenId` in it's tier token ID array. + +If not found, returns `type(uint256).max`. + +{/* ------------------------------------------------------------------------------------------- */} + +### maxMintable + +```solidity +function maxMintable(uint8 tier) external view returns (uint32) ``` -Returns the maximum limit for the mint or airdrop `quantity`. +|Params:|| +|---|---| +| `tier` | The tier. -Prevents the first-time transfer costs for tokens near the end of large mint batches via ERC721A from becoming too expensive due to the need to scan many storage slots. +Returns the maximum amount of tokens mintable for the tier. -See: https://chiru-labs.github.io/ERC721A/#/tips?id=batch-size +{/* ------------------------------------------------------------------------------------------- */} -### Initialization flags +### maxMintableUpper -Each flag is a bit in the `uint256 _flags` passed to the `initialze` function. +```solidity +function maxMintableUpper(uint8 tier) external view returns (uint32) +``` + +|Params:|| +|---|---| +| `tier` | The tier. + +Returns the upper bound for the maximum tokens that can be minted for the tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### maxMintableLower + +```solidity +function maxMintableLower(uint8 tier) external view returns (uint32) +``` + +|Params:|| +|---|---| +| `tier` | The tier. + +Returns the lower bound for the maximum tokens that can be minted for the tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### cutoffTime + +```solidity +function cutoffTime(uint8 tier) external view returns (uint32) +``` + +|Params:|| +|---|---| +| `tier` | The tier. + +Returns the timestamp after which `maxMintable` drops from `maxMintableUpper` to `maxMintableLower`. + +{/* ------------------------------------------------------------------------------------------- */} + +### tierMinted + +```solidity +function tierMinted(uint8 tier) external view returns (uint32) +``` -- `METADATA_IS_FROZEN_FLAG` - If set, the metadata is frozen and cannot be changed. -- `MINT_RANDOMNESS_ENABLED_FLAG` - If set, the `mintRandomness` function is enabled. -- `OPERATOR_FILTERING_ENABLED_FLAG` - If set, the edition will be compatible with OpenSea's [OperatorFilter registry](https://github.com/ProjectOpenSea/operator-filter-registry) for creator fees. +|Params:|| +|---|---| +| `tier` | The tier. -Each flag's base-10 value can be retrieved by calling its name as a function. +Returns the number of tokens minted for the tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### supportsInterface + +`IERC165-supportsInterface` ```solidity -function METADATA_IS_FROZEN_FLAG() external pure returns (uint8); -function MINT_RANDOMNESS_ENABLED_FLAG() external pure returns (uint8); -function OPERATOR_FILTERING_ENABLED_FLAG() external pure returns (uint8); +function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) ``` +Returns `true` if this contract implements the interface defined by `interfaceId`. + +See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. + +|Params:|| +|---|---| +| `interfaceId` | The 4 byte interface ID. + +|Supported Interface IDs:|| +|---|---| +| `IERC165` | `0x01ffc9a7` +| `ERC721` | `0x80ac58cd` +| `ERC721Metadata` | `0x5b5e139f` +| `ISoundEditionV2` | `0x7888cfe1` + +{/* ------------------------------------------------------------------------------------------- */} + ### baseURI ```solidity function baseURI() external view returns (string memory) ``` -Returns the base token URI for the collection. +Returns the base token URI for the collection. + +{/* ------------------------------------------------------------------------------------------- */} ### contractURI @@ -517,9 +775,11 @@ Returns the base token URI for the collection. function contractURI() external view returns (string memory) ``` -Returns the contract URI to be used by Opensea. +Returns the contract URI to be used by Opensea. + +See: https://docs.opensea.io/docs/contract-level-metadata -See: https://docs.opensea.io/docs/contract-level-metadata +{/* ------------------------------------------------------------------------------------------- */} ### fundingRecipient @@ -527,7 +787,9 @@ See: https://docs.opensea.io/docs/contract-level-metadata function fundingRecipient() external view returns (address) ``` -Returns the address of the funding recipient. +Returns the address of the funding recipient. + +{/* ------------------------------------------------------------------------------------------- */} ### editionMaxMintable @@ -535,7 +797,9 @@ Returns the address of the funding recipient. function editionMaxMintable() external view returns (uint32) ``` -Returns the maximum amount of tokens mintable for this edition. +Returns the maximum amount of tokens mintable for this edition. + +{/* ------------------------------------------------------------------------------------------- */} ### editionMaxMintableUpper @@ -543,7 +807,9 @@ Returns the maximum amount of tokens mintable for this edition. function editionMaxMintableUpper() external view returns (uint32) ``` -Returns the upper bound for the maximum tokens that can be minted for this edition. +Returns the upper bound for the maximum tokens that can be minted for this edition. + +{/* ------------------------------------------------------------------------------------------- */} ### editionMaxMintableLower @@ -551,7 +817,9 @@ Returns the upper bound for the maximum tokens that can be minted for this editi function editionMaxMintableLower() external view returns (uint32) ``` -Returns the lower bound for the maximum tokens that can be minted for this edition. +Returns the lower bound for the maximum tokens that can be minted for this edition. + +{/* ------------------------------------------------------------------------------------------- */} ### editionCutoffTime @@ -559,7 +827,9 @@ Returns the lower bound for the maximum tokens that can be minted for this editi function editionCutoffTime() external view returns (uint32) ``` -Returns the timestamp after which `editionMaxMintable` drops from `editionMaxMintableUpper` to `editionMaxMintableLower`. +Returns the timestamp after which `editionMaxMintable` drops from `editionMaxMintableUpper` to `editionMaxMintableLower`. + +{/* ------------------------------------------------------------------------------------------- */} ### metadataModule @@ -567,7 +837,9 @@ Returns the timestamp after which `editionMaxMintable` drops from `editionMaxMin function metadataModule() external view returns (address) ``` -Returns the address of the metadata module. +Returns the address of the metadata module. + +{/* ------------------------------------------------------------------------------------------- */} ### mintRandomness @@ -575,10 +847,14 @@ Returns the address of the metadata module. function mintRandomness() external view returns (uint256) ``` -Returns a pseudorandom number based on latest block hash, which is stored upon each mint unless [mintConcluded](#mintconcluded) is true. Used for game mechanics like the Sound Golden Egg. Returns 0 before revealed. +Returns the randomness based on latest block hash, which is stored upon each mint unless [mintConcluded](#mintconcluded) is true. -> **WARNING** -> This value should NOT be used for any reward of significant monetary value, due to it being computed via a purely on-chain pseudorandom mechanism. +Used for game mechanics like the Sound Golden Egg. Returns 0 before revealed. + +> :warning: +> This value should NOT be used for any reward of significant monetary value, due to it being computed via a purely on-chain psuedorandom mechanism. + +{/* ------------------------------------------------------------------------------------------- */} ### mintRandomnessEnabled @@ -586,15 +862,9 @@ Returns a pseudorandom number based on latest block hash, which is stored upon e function mintRandomnessEnabled() external view returns (bool) ``` -Returns whether the `mintRandomness` has been enabled. - -### operatorFilteringEnabled - -```solidity -function operatorFilteringEnabled() external view returns (bool) -``` +Returns whether the `mintRandomness` has been enabled. -Returns whether the edition implements OpenSea's [OperatorFilter registry](https://github.com/ProjectOpenSea/operator-filter-registry) +{/* ------------------------------------------------------------------------------------------- */} ### mintConcluded @@ -602,7 +872,9 @@ Returns whether the edition implements OpenSea's [OperatorFilter registry](https function mintConcluded() external view returns (bool) ``` -Returns whether the mint has been concluded. +Returns whether the mint has been concluded. + +{/* ------------------------------------------------------------------------------------------- */} ### royaltyBPS @@ -610,7 +882,9 @@ Returns whether the mint has been concluded. function royaltyBPS() external view returns (uint16) ``` -Returns the royalty basis points. +Returns the royalty basis points. + +{/* ------------------------------------------------------------------------------------------- */} ### isMetadataFrozen @@ -618,7 +892,9 @@ Returns the royalty basis points. function isMetadataFrozen() external view returns (bool) ``` -Returns whether the metadata module is frozen. +Returns whether the metadata module is frozen. + +{/* ------------------------------------------------------------------------------------------- */} ### nextTokenId @@ -626,7 +902,9 @@ Returns whether the metadata module is frozen. function nextTokenId() external view returns (uint256) ``` -Returns the next token ID to be minted. +Returns the next token ID to be minted. + +{/* ------------------------------------------------------------------------------------------- */} ### numberMinted @@ -634,11 +912,13 @@ Returns the next token ID to be minted. function numberMinted(address owner) external view returns (uint256) ``` -Returns the number of tokens minted by `owner`. +Returns the number of tokens minted by `owner`. -| Params: | | -| ------- | ----------------------------------- | -| `owner` | Address to query for number minted. | +|Params:|| +|---|---| +| `owner` | Address to query for number minted. + +{/* ------------------------------------------------------------------------------------------- */} ### numberBurned @@ -646,11 +926,13 @@ Returns the number of tokens minted by `owner`. function numberBurned(address owner) external view returns (uint256) ``` -Returns the number of tokens burned by `owner`. +Returns the number of tokens burned by `owner`. + +|Params:|| +|---|---| +| `owner` | Address to query for number burned. -| Params: | | -| ------- | ----------------------------------- | -| `owner` | Address to query for number burned. | +{/* ------------------------------------------------------------------------------------------- */} ### totalMinted @@ -658,7 +940,9 @@ Returns the number of tokens burned by `owner`. function totalMinted() external view returns (uint256) ``` -Returns the total amount of tokens minted. +Returns the total amount of tokens minted. + +{/* ------------------------------------------------------------------------------------------- */} ### totalBurned @@ -666,45 +950,56 @@ Returns the total amount of tokens minted. function totalBurned() external view returns (uint256); ``` -Returns the total amount of tokens burned. +Returns the total amount of tokens burned. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} ## Events +{/* ------------------------------------------------------------------------------------------- */} + ### MetadataModuleSet ```solidity -event MetadataModuleSet(address metadataModule); +event MetadataModuleSet(address metadataModule) ``` -Emitted when the metadata module is set. +Emitted when the metadata module is set. -| Params: | | -| ---------------- | ----------------------------------- | -| `metadataModule` | the address of the metadata module. | +|Params:|| +|---|---| +| `metadataModule` | the address of the metadata module. + +{/* ------------------------------------------------------------------------------------------- */} ### BaseURISet ```solidity -event BaseURISet(string baseURI); +event BaseURISet(string baseURI) ``` -Emitted when the `baseURI` is set. +Emitted when the `baseURI` is set. + +|Params:|| +|---|---| +| `baseURI` | the base URI of the edition. -| Params: | | -| --------- | ---------------------------- | -| `baseURI` | The base URI of the edition. | +{/* ------------------------------------------------------------------------------------------- */} ### ContractURISet ```solidity -event ContractURISet(string contractURI); +event ContractURISet(string contractURI) ``` -Emitted when the `contractURI` is set. +Emitted when the `contractURI` is set. -| Params: | | -| ------------- | -------------------------------- | -| `contractURI` | The contract URI of the edition. | +|Params:|| +|---|---| +| `contractURI` | The contract URI of the edition. + +{/* ------------------------------------------------------------------------------------------- */} ### MetadataFrozen @@ -712,25 +1007,38 @@ Emitted when the `contractURI` is set. event MetadataFrozen(address metadataModule, string baseURI, string contractURI) ``` -Emitted when the metadata is frozen (e.g.: `baseURI` can no longer be changed). +Emitted when the metadata is frozen (e.g.: `baseURI` can no longer be changed). + +|Params:|| +|---|---| +| `metadataModule` | The address of the metadata module. +| `baseURI` | The base URI of the edition. +| `contractURI` | The contract URI of the edition. -| Params: | | -| ---------------- | ----------------------------------- | -| `metadataModule` | The address of the metadata module. | -| `baseURI` | The base URI of the edition. | -| `contractURI` | The contract URI of the edition. | +{/* ------------------------------------------------------------------------------------------- */} + +### CreateTierFrozen + +```solidity +event CreateTierFrozen() +``` + +Emitted when the ability to create tier is removed. event CreateTierFrozen(); +{/* ------------------------------------------------------------------------------------------- */} ### FundingRecipientSet ```solidity -event FundingRecipientSet(address fundingRecipient) +event FundingRecipientSet(address recipient) ``` -Emitted when the `fundingRecipient` is set. +Emitted when the `fundingRecipient` is set. -| Params: | | -| ------------------ | ------------------------------------- | -| `fundingRecipient` | The address of the funding recipient. | +|Params:|| +|---|---| +| `recipient` | The address of the funding recipient. + +{/* ------------------------------------------------------------------------------------------- */} ### RoyaltySet @@ -738,87 +1046,101 @@ Emitted when the `fundingRecipient` is set. event RoyaltySet(uint16 bps) ``` -Emitted when the `royaltyBPS` is set. +Emitted when the `royaltyBPS` is set. + +|Params:|| +|---|---| +| `bps` | The new royalty, measured in basis points. -| Params: | | -| ------- | ------------------------------------------ | -| `bps` | The new royalty, measured in basis points. | +{/* ------------------------------------------------------------------------------------------- */} -### EditionMaxMintableRangeSet +### MaxMintableRangeSet ```solidity -event EditionMaxMintableRangeSet( - uint32 editionMaxMintableLower_, - uint32 editionMaxMintableUpper_ -) +event MaxMintableRangeSet(uint8 tier, uint32 lower, uint32 upper) ``` -Emitted when the edition's maximum mintable token quantity range is set. +Emitted when the tier's maximum mintable token quantity range is set. -| Params: | | -| -------------------------- | ------------------------------------------------------------------- | -| `editionMaxMintableLower_` | The lower limit of the maximum number of tokens that can be minted. | -| `editionMaxMintableUpper_` | The upper limit of the maximum number of tokens that can be minted. | +|Params:|| +|---|---| +| `tier` | The tier. +| `lower` | The lower limit of the maximum number of tokens that can be minted. +| `upper` | The upper limit of the maximum number of tokens that can be minted. -### EditionCutoffTimeSet +{/* ------------------------------------------------------------------------------------------- */} + +### CutoffTimeSet ```solidity -event EditionCutoffTimeSet(uint32 editionCutoffTime_) +event CutoffTimeSet(uint8 tier, uint32 cutoff) ``` -Emitted when the edition's cutoff time set. +Emitted when the tier's cutoff time set. + +|Params:|| +|---|---| +| `tier` | The tier. +| `cutoff` | The timestamp. -| Params: | | -| -------------------- | -------------- | -| `editionCutoffTime_` | The timestamp. | +{/* ------------------------------------------------------------------------------------------- */} ### MintRandomnessEnabledSet ```solidity -event MintRandomnessEnabledSet(bool mintRandomnessEnabled_) +event MintRandomnessEnabledSet(uint8 tier, bool enabled) ``` -Emitted when the `mintRandomnessEnabled` is set. +Emitted when the `mintRandomnessEnabled` for the tier is set. -| Params: | | -| ------------------------ | ------------------ | -| `mintRandomnessEnabled_` | The boolean value. | +|Params:|| +|---|---| +| `tier` | The tier. +| `enabled` | The boolean value. + +{/* ------------------------------------------------------------------------------------------- */} ### SoundEditionInitialized ```solidity -event SoundEditionInitialized( - address indexed edition_, - string name_, - string symbol_, - address metadataModule_, - string baseURI_, - string contractURI_, - address fundingRecipient_, - uint16 royaltyBPS_, - uint32 editionMaxMintableLower_, - uint32 editionMaxMintableUpper_, - uint32 editionCutoffTime_, - uint8 flags_ - ) -``` - -Emitted upon initialization. - -| Params: | | -| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition_` | The address of the edition. | -| `name_` | Name of the collection. | -| `symbol_` | Symbol of the collection. | -| `metadataModule_` | Address of metadata module, `address(0)` if not used. | -| `baseURI_` | Base URI. | -| `contractURI_` | Contract URI for OpenSea storefront. | -| `fundingRecipient_` | Address that receives primary and secondary royalties. | -| `royaltyBPS_` | Royalty amount in bps (basis points). | -| `editionMaxMintableLower_` | The lower bound of the max mintable quantity for the edition. | -| `editionMaxMintableUpper_` | The upper bound of the max mintable quantity for the edition. | -| `editionCutoffTime_` | The timestamp after which `editionMaxMintable` drops from `editionMaxMintableUpper` to `max(_totalMinted(), editionMaxMintableLower)`. | -| `flags_` | The bitwise OR result of the initialization flags.
See: [METADATA_IS_FROZEN_FLAG](#metadata_is_frozen_flag)
See: [MINT_RANDOMNESS_ENABLED_FLAG](#mint_randomness_enabled_flag) | +event SoundEditionInitialized(EditionInitialization init) +``` + +Emitted upon initialization. + +|Params:|| +|---|---| +| `init` | The initialization data. + +{/* ------------------------------------------------------------------------------------------- */} + +### TierCreated + +```solidity +event TierCreated(TierCreation creation) +``` + +Emitted when a tier is created. + +|Params:|| +|---|---| +| `creation` | The tier creation data. + +{/* ------------------------------------------------------------------------------------------- */} + +### TierFrozen + +```solidity +event TierFrozen(uint8 tier) +``` + +Emitted when a tier is frozen. + +|Params:|| +|---|---| +| `tier` | The tier. + +{/* ------------------------------------------------------------------------------------------- */} ### ETHWithdrawn @@ -826,58 +1148,81 @@ Emitted upon initialization. event ETHWithdrawn(address recipient, uint256 amount, address caller) ``` -Emitted upon ETH withdrawal. +Emitted upon ETH withdrawal. -| Params: | | -| ----------- | ------------------------------------------ | -| `recipient` | The recipient of the withdrawal.. | -| `amount` | The amount withdrawn. | -| `caller` | The account that initiated the withdrawal. | +|Params:|| +|---|---| +| `recipient` | The recipient of the withdrawal. +| `amount` | The amount withdrawn. +| `caller` | The account that initiated the withdrawal. + +{/* ------------------------------------------------------------------------------------------- */} ### ERC20Withdrawn ```solidity -event ERC20Withdrawn(address recipient, uint256 amount, address caller) +event ERC20Withdrawn(address recipient, address[] tokens, uint256[] amounts, address caller) ``` -Emitted upon ERC20 withdrawal. +Emitted upon ERC20 withdrawal. + +|Params:|| +|---|---| +| `recipient` | The recipient of the withdrawal. +| `tokens` | The addresses of the ERC20 tokens. +| `amounts` | The amount of each token withdrawn. +| `caller` | The account that initiated the withdrawal. -| Params: | | -| ----------- | ------------------------------------------ | -| `recipient` | The recipient of the withdrawal.. | -| `tokens` | The addresses of the ERC20 tokens. | -| `amount` | The amount of each token withdrawn. | -| `caller` | The account that initiated the withdrawal. | +{/* ------------------------------------------------------------------------------------------- */} ### Minted ```solidity -event Minted(address to, uint256 quantity, uint256 fromTokenId); +event Minted(uint8 tier, address to, uint256 quantity, uint256 fromTokenId) ``` -Emitted upon a mint. +Emitted upon a mint. + +|Params:|| +|---|---| +| `tier` | The tier. +| `to` | The address to mint to. +| `quantity` | The number of minted. +| `fromTokenId` | The first token ID minted. -| Params: | | -| ------------- | -------------------------- | -| `to` | The address to mint to. | -| `quantity` | The number of minted. | -| `fromTokenId` | The first token ID minted. | +{/* ------------------------------------------------------------------------------------------- */} ### Airdropped ```solidity -event Minted(address to, uint256 quantity, uint256 fromTokenId); +event Airdropped(uint8 tier, address[] to, uint256 quantity, uint256 fromTokenId) ``` -Emitted upon an airdrop. +Emitted upon an airdrop. + +|Params:|| +|---|---| +| `tier` | The tier. +| `to` | The recipients of the airdrop. +| `quantity` | The number of tokens airdropped to each address in `to`. +| `fromTokenId` | The first token ID minted to the first address in `to`. + +{/* ------------------------------------------------------------------------------------------- */} + +### to + +```solidity +event BatchMetadataUpdate(uint256 fromTokenId, uint256 toTokenId) +``` -| Params: | | -| ------------- | -------------------------------------------------------- | -| `to` | The recipients of the airdrop. | -| `quantity` | The number of tokens airdropped to each address in `to`. | -| `fromTokenId` | The first token ID minted to the first address in `to`. | +EIP-4906 event to signal marketplaces to refresh the metadata. -## Errors +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Errors + +{/* ------------------------------------------------------------------------------------------- */} ### MetadataIsFrozen @@ -885,43 +1230,49 @@ Emitted upon an airdrop. error MetadataIsFrozen() ``` -The edition's metadata is frozen. +The edition's metadata is frozen (e.g.: `baseURI` can no longer be changed). -### InvalidRoyaltyBPS +{/* ------------------------------------------------------------------------------------------- */} + +### CreateTierIsFrozen ```solidity -error InvalidRoyaltyBPS() +error CreateTierIsFrozen() ``` -The given `royaltyBPS` is invalid. +The ability to create tiers is frozen. -### InvalidRandomnessLock +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidRoyaltyBPS ```solidity -error InvalidRandomnessLock() +error InvalidRoyaltyBPS() ``` -The given `randomnessLockedAfterMinted` value is invalid. +The given `royaltyBPS` is invalid. + +{/* ------------------------------------------------------------------------------------------- */} -### ExceedsEditionAvailableSupply +### ZeroTiersProvided ```solidity -error ExceedsEditionAvailableSupply(uint32 available) +error ZeroTiersProvided() ``` -The requested quantity exceeds the edition's remaining mintable token quantity. +A minimum of one tier must be provided to initialize a Sound Edition. -| Params: | | -| ----------- | -------------------------------------------------- | -| `available` | The number of tokens remaining available for mint. | +{/* ------------------------------------------------------------------------------------------- */} -### InvalidAmount +### ExceedsAvailableSupply ```solidity -error InvalidAmount() +error ExceedsAvailableSupply() ``` -The given amount is invalid. +The requested quantity exceeds the edition's remaining mintable token quantity. + +{/* ------------------------------------------------------------------------------------------- */} ### InvalidFundingRecipient @@ -929,60 +1280,124 @@ The given amount is invalid. error InvalidFundingRecipient() ``` -The given `fundingRecipient` address is invalid. +The given `fundingRecipient` address is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidMaxMintableRange + +```solidity +error InvalidMaxMintableRange() +``` + +The `maxMintableLower` must not be greater than `maxMintableUpper`. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintHasConcluded + +```solidity +error MintHasConcluded() +``` + +The mint has already concluded. + +{/* ------------------------------------------------------------------------------------------- */} -### InvalidEditionMaxMintableRange +### MintNotConcluded ```solidity -error InvalidEditionMaxMintableRange() +error MintNotConcluded() ``` -The `editionMaxMintableLower` must not be greater than `editionMaxMintableUpper`. +The mint has not concluded. -### MaximumHasAlreadyBeenReached +{/* ------------------------------------------------------------------------------------------- */} + +### MintsAlreadyExist ```solidity -error MaximumHasAlreadyBeenReached() +error MintsAlreadyExist() ``` -The `editionMaxMintable` has already been reached. +Cannot perform the operation after a token has been minted. -### ExceedsAddressBatchMintLimit +{/* ------------------------------------------------------------------------------------------- */} + +### TierMintsAlreadyExist ```solidity -error ExceedsAddressBatchMintLimit() +error TierMintsAlreadyExist() ``` -The mint `quantity` cannot exceed `ADDRESS_BATCH_MINT_LIMIT` tokens. +Cannot perform the operation after a token has been minted in the tier. + +{/* ------------------------------------------------------------------------------------------- */} -### MintRandomnessAlreadyRevealed +### TokenIdsNotStrictlyAscending ```solidity -error MintRandomnessAlreadyRevealed() +error TokenIdsNotStrictlyAscending() ``` -The mint randomness has already been revealed. +The token IDs must be in strictly ascending order. + +{/* ------------------------------------------------------------------------------------------- */} -### NoAddressesToAirdrop +### TierDoesNotExist ```solidity -error NoAddressesToAirdrop() +error TierDoesNotExist() ``` -No addresses to airdrop. +The tier does not exist. -### MintHasConcluded +{/* ------------------------------------------------------------------------------------------- */} + +### TierAlreadyExists ```solidity -error MintHasConcluded() +error TierAlreadyExists() ``` -The mint has already concluded. +The tier already exists. -### MintsAlreadyExist +{/* ------------------------------------------------------------------------------------------- */} + +### TierIsFrozen ```solidity -error MintsAlreadyExist() +error TierIsFrozen() +``` + +The tier is frozen. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidTokenTier + +```solidity +error InvalidTokenTier() +``` + +One of more of the tokens do not have the correct token tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### CannotBurnImmediately + +```solidity +error CannotBurnImmediately() +``` + +Please wait for a while before you burn. + +{/* ------------------------------------------------------------------------------------------- */} + +### TierQueryForNonexistentToken + +```solidity +error TierQueryForNonexistentToken() ``` -Cannot perform the operation after a token has been minted. +The token for the tier query doesn't exist. diff --git a/pages/protocol/libraries/_meta.json b/pages/protocol/libraries/_meta.json new file mode 100644 index 0000000..84f6e3e --- /dev/null +++ b/pages/protocol/libraries/_meta.json @@ -0,0 +1,6 @@ +{ + "erc721a-upgradeable": "ERC721AUpgradeable", + "erc721a-queryable-upgradeable": "ERC721AQueryableUpgradeable", + "erc721a-burnable-upgradeable": "ERC721ABurnableUpgradeable", + "ownable-roles": "OwnableRoles" +} diff --git a/pages/protocol/modules/_meta.json b/pages/protocol/modules/_meta.json index 9ec8225..6e593d5 100644 --- a/pages/protocol/modules/_meta.json +++ b/pages/protocol/modules/_meta.json @@ -1,4 +1,5 @@ { - "metadata": "Metadata", - "minters": "Minters" + "super-minter": "SuperMinter", + "sound-metadata": "SoundMetadata", + "sound-on-chain-metadata": "SoundOnChainMetadata" } diff --git a/pages/protocol/modules/metadata/_meta.json b/pages/protocol/modules/metadata/_meta.json deleted file mode 100644 index 00f299e..0000000 --- a/pages/protocol/modules/metadata/_meta.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "golden-egg-metadata": "GoldenEgg Metadata" -} diff --git a/pages/protocol/modules/metadata/golden-egg-metadata.mdx b/pages/protocol/modules/metadata/golden-egg-metadata.mdx deleted file mode 100644 index dfd8542..0000000 --- a/pages/protocol/modules/metadata/golden-egg-metadata.mdx +++ /dev/null @@ -1,21 +0,0 @@ -# GoldenEggMetadata - -**[`contracts/modules/GoldenEggMetadata.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/GoldenEggMetadata.sol)** - -A metadata module that implements the sound.xyz Golden Egg, a lottery mechanism that rewards a unique 1-of-1 NFT per edition. - -Inherits: - -- [IMetadataModule](/protocol/core/i-metadata-module) - -### getGoldenEggTokenId - -```solidity -function getGoldenEggTokenId(ISoundEditionV1 edition) external view returns (uint256) -``` - -Returns token ID for the golden egg after the [`SoundEdition.mintRandomness`](/protocol/core/sound-edition#mintrandomness) is locked, else returns 0. - -| Params: | | -| --------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | diff --git a/pages/protocol/modules/minters/_meta.json b/pages/protocol/modules/minters/_meta.json deleted file mode 100644 index ba510d8..0000000 --- a/pages/protocol/modules/minters/_meta.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "edition-max-minter": "EditionMaxMinter", - "range-edition-minter": "RangeEditionMinter", - "fixed-price-signature-minter": "FixedPriceSignatureMinter", - "merkle-drop-minter": "MerkleDropMinter" -} diff --git a/pages/protocol/modules/minters/edition-max-minter.mdx b/pages/protocol/modules/minters/edition-max-minter.mdx deleted file mode 100644 index 31948f0..0000000 --- a/pages/protocol/modules/minters/edition-max-minter.mdx +++ /dev/null @@ -1,266 +0,0 @@ -# EditionMaxMinter - -**[`contracts/modules/EditionMaxMinter.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/EditionMaxMinter.sol)** - -A minimalist fixed-price public minting module. Can implement single-schedule range mints. - -Derives the following values from the `edition`: - -- `maxMintableLower` -- `maxMintableUpper` -- `cutoffTime` - -Inherits: - -- [IMinterModule](/protocol/core/i-minter-module) - -## Structs - -### MintInfo - -```solidity -struct MintInfo { - // Start timestamp of sale (in seconds since unix epoch). - uint32 startTime; - // End timestamp of sale (in seconds since unix epoch). - uint32 endTime; - // The affiliate fee in basis points. - uint16 affiliateFeeBPS; - // Whether the mint is paused. - bool mintPaused; - // Sale price in ETH for minting a single token. - uint96 price; - // The maximum number of tokens that can be minted by an account. - uint32 maxMintablePerAccount; - // The lower limit of the maximum number of tokens that can be minted. - // This is the `editionMaxMintableLower` from the `edition`. - uint32 maxMintableLower; - // The upper limit of the maximum number of tokens that can be minted. - // This is the `editionMaxMintableUpper` from the `edition`. - uint32 maxMintableUpper; - // The cutoff timestamp when the maximum number of tokens that can - // be minted drops from `maxMintableUpper` to `maxMintableLower`. - // This is the `editionCutoffTime` from the `edition`. - uint32 cutoffTime; -} -``` - -Holds information pertaining to a mint. - -This struct is intended for off-chain queries, and can be retrieved via the `mintInfo` function. - -## Write Functions - -### createEditionMint - -```solidity -function createEditionMint( - address edition, - uint96 price, - uint32 startTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintablePerAccount - ) external returns (uint128 mintId) -``` - -Initializes a range mint instance - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ----------------------- | -------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted by an account. | - -### mint - -```solidity -function mint( - address edition, - uint128 mintId, - uint32 quantity, - address affiliate - ) external payable -``` - -Mints tokens for a given edition. - -| Params: | | -| ----------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `quantity` | Token quantity to mint in song `edition`. | -| `affiliate` | The affiliate address. | - -### setPrice - -```solidity -function setPrice( - address edition, - uint128 mintId, - uint96 price - ) external -``` - -Sets the `price` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### setMaxMintablePerAccount - -```solidity -function setMaxMintablePerAccount( - address edition, - uint128 mintId, - uint32 maxMintablePerAccount - ) external -``` - -Sets the `maxMintablePerAccount` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ----------------------- | -------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted by an account. | - -## Read-only Functions - -### mintInfo - -```solidity -function mintInfo( - address edition, - uint128 mintId -) external view returns (MintInfo memory) -``` - -Returns a [`MintInfo`](#mintinfo) instance containing the full minter parameter set. - -| Params: | | -| --------- | ----------------------------------------- | -| `edition` | The edition to get the mint instance for. | -| `mintId` | The ID of the mint instance. | - -### supportsInterface - -`IERC165-supportsInterface` - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) -``` - -Returns `true` if this contract implements the interface defined by `interfaceId`. - -See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. - -| Params: | | -| ------------- | ------------------------ | -| `interfaceId` | The 4 byte interface ID. | - -| Supported Interface IDs: | | -| ------------------------ | ------------ | -| `IERC165` | `0x01ffc9a7` | -| `IMinterModule` | `0x37c74bd8` | -| `IEditionMaxMinter` | `0xa7ea8688` | - -## Events - -### EditionMaxMintCreated - -```solidity -event EditionMaxMintCreated( - address indexed edition, - uint128 indexed mintId, - uint96 price, - uint32 startTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintablePerAccount - ) -``` - -Emitted when a edition max is created. - -| Params: | | -| ----------------------- | ------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted per account. | - -### PriceSet - -```solidity -event PriceSet( - address indexed edition, - uint128 indexed mintId, - uint96 price -) -``` - -Emitted when the `price` is changed for (`edition`, `mintId`). - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### MaxMintablePerAccountSet - -```solidity -event MaxMintablePerAccountSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintablePerAccount -) -``` - -Emitted when the `maxMintablePerAccount` is changed for (`edition`, `mintId`). - -| Params: | | -| ----------------------- | ------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted per account. | - -## Errors - -### ExceedsMaxPerAccount - -```solidity -error ExceedsMaxPerAccount() -``` - -The number of tokens minted has exceeded the number allowed for each account. - -### MaxMintablePerAccountIsZero - -```solidity -error MaxMintablePerAccountIsZero() -``` - -The max mintable per account cannot be zero. diff --git a/pages/protocol/modules/minters/fixed-price-signature-minter.mdx b/pages/protocol/modules/minters/fixed-price-signature-minter.mdx deleted file mode 100644 index b494bb9..0000000 --- a/pages/protocol/modules/minters/fixed-price-signature-minter.mdx +++ /dev/null @@ -1,316 +0,0 @@ -# FixedPriceSignatureMinter - -**[`contracts/modules/FixedPriceSignatureMinter.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/FixedPriceSignatureMinter.sol)** - -A minter that enables permissioned mints via ECDSA signatures. - -Inherits: - -- [IMinterModule](/protocol/core/i-minter-module) - -## Structs - -### MintInfo - -```solidity -struct MintInfo { - // Start timestamp of sale (in seconds since unix epoch). - uint32 startTime; - // End timestamp of sale (in seconds since unix epoch). - uint32 endTime; - // The affiliate fee in basis points. - uint16 affiliateFeeBPS; - // Whether the mint is paused. - bool mintPaused; - // Sale price in ETH for minting a single token. - uint96 price; - // The maximum number of tokens that can be minted. - uint32 maxMintable; - // The maximum number of tokens that can be minted by an account. - uint32 maxMintablePerAccount; - // The total number of tokens minted. - uint32 totalMinted; - // The address of the signer. - address signer; -} -``` - -Holds information pertaining to a mint. - -This struct is intended for off-chain queries, and can be retrieved via the `mintInfo` function. - -## Write Functions - -### createEditionMint - -```solidity -function createEditionMint( - address edition, - uint96 price, - uint32 startTime, - uint32 cutoffTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintableLower, - uint32 maxMintableUpper, - uint32 maxMintablePerAccount_ - ) external returns (uint128 mintId) -``` - -Initializes a range edition mint instance. - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `cutoffTime` | The timestamp (in seconds since unix epoch) after which the max amount of tokens mintable will drop from `maxMintableUpper` to `maxMintableLower`. | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | -| `maxMintablePerAccount_` | The maximum number of tokens that can be minted by an account. | - -### setMaxMintableRange - -```solidity -function setMaxMintableRange( - address edition, - uint128 mintId, - uint32 maxMintableLower, - uint32 maxMintableUpper -) external -``` - -Sets the max mintable range. - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------------ | ------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### mint - -```solidity -function mint( - address edition, - uint128 mintId, - uint32 quantity, - address affiliate -) external payable -``` - -Mints tokens for a given edition. - -| Params: | | -| ---------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `quantity` | Token quantity to mint in song `edition`. | - -### setPrice - -```solidity -function setPrice( - address edition, - uint128 mintId, - uint96 price -) external -``` - -Sets the `price` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### setMaxMintablePerAccount - -```solidity -function setMaxMintablePerAccount( - address edition, - uint128 mintId, - uint32 maxMintablePerAccount -) external -``` - -Sets the `maxMintablePerAccount` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ----------------------- | -------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted by an account. | - -## Read-only Functions - -### mintInfo - -```solidity -function mintInfo( - address edition, - uint128 mintId -) external view returns (MintInfo memory) -``` - -Returns [`MintInfo`](#mintinfo) instance containing the full minter parameter set. - -| Params: | | -| --------- | ----------------------------------------- | -| `edition` | The edition to get the mint instance for. | -| `mintId` | The ID of the mint instance. | - -### supportsInterface - -`IERC165-supportsInterface` - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) -``` - -Returns `true` if this contract implements the interface defined by `interfaceId`. - -See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. - -| Params: | | -| ------------- | ------------------------ | -| `interfaceId` | The 4 byte interface ID. | - -| Supported Interface IDs: | | -| ---------------------------- | ------------ | -| `IERC165` | `0x01ffc9a7` | -| `IMinterModule` | `0x37c74bd8` | -| `IFixedPriceSignatureMinter` | `0xa61bd96f` | - -## Events - -### RangeEditionMintCreated - -```solidity -event RangeEditionMintCreated( - address indexed edition, - uint128 indexed mintId, - uint96 price, - uint32 startTime, - uint32 cutoffTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintableLower, - uint32 maxMintableUpper, - uint32 maxMintablePerAccount -) -``` - -Emitted when a range edition is created. - -| Params: | | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `cutoffTime` | The timestamp (in seconds since unix epoch) after which the max amount of tokens mintable will drop from `maxMintableUpper` to `maxMintableLower`. | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### MaxMintableRangeSet - -```solidity -event MaxMintableRangeSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintableLower, - uint32 maxMintableUpper -) -``` - -Emitted when the max mintable range is updated. - -| Params: | | -| ------------------ | ------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### PriceSet - -```solidity -event PriceSet( - address indexed edition, - uint128 indexed mintId, - uint96 price -) -``` - -Emitted when the `price` is changed for (`edition`, `mintId`). - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### MaxMintablePerAccountSet - -```solidity -event MaxMintablePerAccountSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintablePerAccount -) -``` - -Emitted when the `maxMintablePerAccount` is changed for (`edition`, `mintId`). - -| Params: | | -| ----------------------- | ------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted per account. | - -## Errors - -### InvalidMaxMintableRange - -```solidity -error InvalidMaxMintableRange() -``` - -The `maxMintableLower` must not be greater than `maxMintableUpper`. - -### ExceedsMaxPerAccount - -```solidity -error ExceedsMaxPerAccount() -``` - -The number of tokens minted has exceeded the number allowed for each account. - -### MaxMintablePerAccountIsZero - -```solidity -error MaxMintablePerAccountIsZero() -``` - -The max mintable per account cannot be zero. diff --git a/pages/protocol/modules/minters/merkle-drop-minter.mdx b/pages/protocol/modules/minters/merkle-drop-minter.mdx deleted file mode 100644 index bfb078d..0000000 --- a/pages/protocol/modules/minters/merkle-drop-minter.mdx +++ /dev/null @@ -1,372 +0,0 @@ -# MerkleDropMinter - -**[`contracts/modules/MerkleDropMinter.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/MerkleDropMinter.sol)** - -A minter that enables permissioned mints via Merkle proofs. - -Inherits: - -- [IMinterModule](/protocol/core/i-minter-module) - -## Structs - -### MintInfo - -```solidity -struct MintInfo { - // Start timestamp of sale (in seconds since unix epoch). - uint32 startTime; - // End timestamp of sale (in seconds since unix epoch). - uint32 endTime; - // The affiliate fee in basis points. - uint16 affiliateFeeBPS; - // Whether the mint is paused. - bool mintPaused; - // Sale price in ETH for minting a single token. - uint96 price; - // The maximum number of tokens that can be minted. - uint32 maxMintable; - // The maximum number of tokens that can be minted by an account. - uint32 maxMintablePerAccount; - // The total number of tokens minted. - uint32 totalMinted; - // Hash of the root node for the merkle tree drop. - bytes32 merkleRootHash; -} -``` - -Holds information pertaining to a mint. - -This struct is intended for off-chain queries, and can be retrieved via the `mintInfo` function. - -## Write Functions - -### createEditionMint - -```solidity -function createEditionMint( - address edition, - bytes32 merkleRootHash, - uint96 price, - uint32 startTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintable_, - uint32 maxMintablePerAccount_ -) external returns (uint128 mintId) -``` - -Initializes merkle drop mint instance. - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------------------ | ------------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `merkleRootHash` | bytes32 hash of the Merkle tree representing eligible mints. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintable_` | The maximum number of tokens that can can be minted for this sale. | -| `maxMintablePerAccount_` | The maximum number of tokens that a single account can mint. | - -### mint - -```solidity -function mint( - address edition, - uint128 mintId, - uint32 requestedQuantity, - bytes32[] calldata merkleProof, - address affiliate -) external payable -``` - -Mints a token for a particular mint instance. - -| Params: | | -| ------------------- | ------------------------------- | -| `mintId` | The ID of the mint instance. | -| `requestedQuantity` | The quantity of tokens to mint. | - -### setPrice - -```solidity -function setPrice( - address edition, - uint128 mintId, - uint96 price -) external -``` - -Sets the `price` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### setMaxMintablePerAccount - -```solidity -function setMaxMintablePerAccount( - address edition, - uint128 mintId, - uint32 maxMintablePerAccount -) external -``` - -Sets the `maxMintablePerAccount` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ----------------------- | -------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted by an account. | - -### setMaxMintable - -```solidity -function setMaxMintable( - address edition, - uint128 mintId, - uint32 maxMintable -) external -``` - -Sets the `maxMintable` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------- | ----------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintable` | The maximum number of tokens that can be minted on this schedule. | - -### setMerkleRootHash - -```solidity -function setMerkleRootHash( - address edition, - uint128 mintId, - bytes32 merkleRootHash -) external -``` - -Sets the `merkleRootHash` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ---------------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `merkleRootHash` | The merkle root hash of the entries. | - -## Read-only Functions - -### mintInfo - -```solidity -function mintInfo( - address edition, - uint128 mintId -) external view returns (MintInfo memory) -``` - -Returns [`MintInfo`](#mintinfo) instance containing the full minter parameter set. - -| Params: | | -| --------- | ----------------------------------------- | -| `edition` | The edition to get the mint instance for. | -| `mintId` | The ID of the mint instance. | - -### supportsInterface - -`IERC165-supportsInterface` - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) -``` - -Returns `true` if this contract implements the interface defined by `interfaceId`. - -See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. - -| Params: | | -| ------------- | ------------------------ | -| `interfaceId` | The 4 byte interface ID. | - -| Supported Interface IDs: | | -| ------------------------ | ------------ | -| `IERC165` | `0x01ffc9a7` | -| `IMinterModule` | `0x37c74bd8` | -| `IMerkleDropMinter` | `0x89691c4c` | - -## Events - -### MerkleDropMintCreated - -```solidity -event MerkleDropMintCreated( - address indexed edition, - uint128 indexed mintId, - bytes32 merkleRootHash, - uint96 price, - uint32 startTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintable, - uint32 maxMintablePerAccount - ) -``` - -Emitted when a new merkle drop mint is created. - -| Params: | | -| ----------------------- | ------------------------------------------------------ | -| `edition` | The edition address. | -| `mintId` | The mint ID. | -| `merkleRootHash` | The root of the merkle tree of the approved addresses. | -| `price` | The price at which each token will be sold, in ETH. | -| `startTime` | The time minting can begin. | -| `endTime` | The time minting will end. | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintable` | The maximum number of tokens that can be minted. | -| `maxMintablePerAccount` | The maximum number of tokens that an account can mint. | - -### DropClaimed - -```solidity -event DropClaimed(address recipient, uint32 quantity) -``` - -Emitted when tokens are claimed by an account. - -| Params: | | -| ----------- | --------------------------------------------------- | -| `recipient` | The address of the account that claimed the tokens. | -| `quantity` | The quantity of tokens claimed. | - -### PriceSet - -```solidity -event PriceSet( - address indexed edition, - uint128 indexed mintId, - uint96 price -) -``` - -Emitted when the `price` is changed for (`edition`, `mintId`). - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### MaxMintableSet - -```solidity -event MaxMintableSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintable -) -``` - -Emitted when the `maxMintable` is changed for (`edition`, `mintId`). - -| Params: | | -| ------------- | ----------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintable` | The maximum number of tokens that can be minted on this schedule. | - -### MaxMintablePerAccountSet - -```solidity -event MaxMintablePerAccountSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintablePerAccount -) -``` - -Emitted when the `maxMintablePerAccount` is changed for (`edition`, `mintId`). - -| Params: | | -| ----------------------- | ------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted per account. | - -### MerkleRootHashSet - -```solidity -event MerkleRootHashSet( - address indexed edition, - uint128 indexed mintId, - bytes32 merkleRootHash -) -``` - -Emitted when the `merkleRootHash` is changed for (`edition`, `mintId`). - -| Params: | | -| ---------------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `merkleRootHash` | The merkle root hash of the entries. | - -## Errors - -### InvalidMerkleProof - -```solidity -error InvalidMerkleProof() -``` - -The merkle proof is invalid. - -### ExceedsMaxPerAccount - -```solidity -error ExceedsMaxPerAccount() -``` - -The number of tokens minted has exceeded the number allowed for each account. - -### MerkleRootHashIsEmpty - -```solidity -error MerkleRootHashIsEmpty() -``` - -The merkle root hash is empty. - -### MaxMintablePerAccountIsZero - -```solidity -error MaxMintablePerAccountIsZero() -``` - -The max mintable per account cannot be zero. diff --git a/pages/protocol/modules/minters/range-edition-minter.mdx b/pages/protocol/modules/minters/range-edition-minter.mdx deleted file mode 100644 index e6b8071..0000000 --- a/pages/protocol/modules/minters/range-edition-minter.mdx +++ /dev/null @@ -1,342 +0,0 @@ -# RangeEditionMinter - -**[`contracts/modules/RangeEditionMinter.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/RangeEditionMinter.sol)** - -A minter that enables multiple schedules of fixed-price mints with a maximum mintable supply that drops from a upper bound to a lower bound after a defined cutoff time. - -Inherits: - -- [IMinterModule](/protocol/core/i-minter-module) - -## Structs - -### MintInfo - -```solidity -struct MintInfo { - // Start timestamp of sale (in seconds since unix epoch). - uint32 startTime; - // End timestamp of sale (in seconds since unix epoch). - uint32 endTime; - // The affiliate fee in basis points. - uint16 affiliateFeeBPS; - // Whether the mint is paused. - bool mintPaused; - // Sale price in ETH for minting a single token. - uint96 price; - // The maximum number of tokens that can be minted by an account. - uint32 maxMintablePerAccount; - // The lower limit of the maximum number of tokens that can be minted. - uint32 maxMintableLower; - // The upper limit of the maximum number of tokens that can be minted. - uint32 maxMintableUpper; - // The cutoff timestamp when the maximum number of tokens that can - // be minted drops from `maxMintableUpper` to `maxMintableLower`. - uint32 cutoffTime; -} -``` - -Holds information pertaining to a mint. - -This struct is intended for off-chain queries, and can be retrieved via the `mintInfo` function. - -## Write Functions - -### createEditionMint - -```solidity -function createEditionMint( - address edition, - uint96 price, - uint32 startTime, - uint32 cutoffTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintableLower, - uint32 maxMintableUpper, - uint32 maxMintablePerAccount_ -) external returns (uint128 mintId) -``` - -Initializes a range mint instance - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `cutoffTime` | The timestamp (in seconds since unix epoch) after which the max amount of tokens mintable will drop from `maxMintableUpper` to `maxMintableLower`. | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | -| `maxMintablePerAccount_` | The maximum number of tokens that can be minted by an account. | - -### setTimeRange - -```solidity -function setTimeRange( - address edition, - uint128 mintId, - uint32 startTime, - uint32 cutoffTime, - uint32 endTime -) external -``` - -Sets the time range. - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `cutoffTime` | The timestamp (in seconds since unix epoch) after which the max amount of tokens mintable will drop from `maxMintableUpper` to `maxMintableLower`. | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | - -### setMaxMintableRange - -```solidity -function setMaxMintableRange( - address edition, - uint128 mintId, - uint32 maxMintableLower, - uint32 maxMintableUpper - ) external -``` - -Sets the max mintable range. - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ------------------ | ------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### mint - -```solidity -function mint( - address edition, - uint128 mintId, - uint32 quantity, - address affiliate -) external payable -``` - -Mints tokens for a given edition. - -| Params: | | -| ---------- | -------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `quantity` | Token quantity to mint in song `edition`. | - -### setPrice - -```solidity -function setPrice( - address edition, - uint128 mintId, - uint96 price -) external -``` - -Sets the `price` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### setMaxMintablePerAccount - -```solidity -function setMaxMintablePerAccount( - address edition, - uint128 mintId, - uint32 maxMintablePerAccount -) external -``` - -Sets the `maxMintablePerAccount` for (`edition`, `mintId`). - -**Calling conditions:** - -- The caller must be the owner or an adminstrator (via the [`ADMIN_ROLE`](/protocol/core/sound-edition#admin_role)) of the `edition` contract. - -| Params: | | -| ----------------------- | -------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted by an account. | - -## Read-only Functions - -### mintInfo - -```solidity -function mintInfo( - address edition, - uint128 mintId -) external view returns (MintInfo memory) -``` - -Returns [`MintInfo`](#mintinfo) instance containing the full minter parameter set. - -| Params: | | -| --------- | ----------------------------------------- | -| `edition` | The edition to get the mint instance for. | -| `mintId` | The ID of the mint instance. | - -### supportsInterface - -`IERC165-supportsInterface` - -```solidity -function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) -``` - -Returns `true` if this contract implements the interface defined by `interfaceId`. - -See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. - -| Params: | | -| ------------- | ------------------------ | -| `interfaceId` | The 4 byte interface ID. | - -| Supported Interface IDs: | | -| ------------------------ | ------------ | -| `IERC165` | `0x01ffc9a7` | -| `IMinterModule` | `0x37c74bd8` | -| `IRangeEditionMinter` | `0x4d4a2e35` | - -## Events - -### RangeEditionMintCreated - -```solidity -event RangeEditionMintCreated( - address indexed edition, - uint128 indexed mintId, - uint96 price, - uint32 startTime, - uint32 cutoffTime, - uint32 endTime, - uint16 affiliateFeeBPS, - uint32 maxMintableLower, - uint32 maxMintableUpper, - uint32 maxMintablePerAccount -) -``` - -Emitted when a range edition is created. - -| Params: | | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | -| `startTime` | Start timestamp of sale (in seconds since unix epoch). | -| `cutoffTime` | The timestamp (in seconds since unix epoch) after which the max amount of tokens mintable will drop from `maxMintableUpper` to `maxMintableLower`. | -| `endTime` | End timestamp of sale (in seconds since unix epoch). | -| `affiliateFeeBPS` | The affiliate fee in basis points. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### MaxMintableRangeSet - -```solidity -event MaxMintableRangeSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintableLower, - uint32 maxMintableUpper -) -``` - -Emitted when the max mintable range is updated. - -| Params: | | -| ------------------ | ------------------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintableLower` | The lower limit of the maximum number of tokens that can be minted. | -| `maxMintableUpper` | The upper limit of the maximum number of tokens that can be minted. | - -### PriceSet - -```solidity -event PriceSet( - address indexed edition, - uint128 indexed mintId, - uint96 price -) -``` - -Emitted when the `price` is changed for (`edition`, `mintId`). - -| Params: | | -| --------- | ---------------------------------------------------------- | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `price` | Sale price in ETH for minting a single token in `edition`. | - -### MaxMintablePerAccountSet - -```solidity -event MaxMintablePerAccountSet( - address indexed edition, - uint128 indexed mintId, - uint32 maxMintablePerAccount -) -``` - -Emitted when the `maxMintablePerAccount` is changed for (`edition`, `mintId`). - -| Params: | | -| ----------------------- | ------------------------------------------------------------ | -| `edition` | Address of the song edition contract we are minting for. | -| `mintId` | The mint ID. | -| `maxMintablePerAccount` | The maximum number of tokens that can be minted per account. | - -## Errors - -### InvalidMaxMintableRange - -```solidity -error InvalidMaxMintableRange() -``` - -The `maxMintableLower` must not be greater than `maxMintableUpper`. - -### ExceedsMaxPerAccount - -```solidity -error ExceedsMaxPerAccount() -``` - -The number of tokens minted has exceeded the number allowed for each account. - -### MaxMintablePerAccountIsZero - -```solidity -error MaxMintablePerAccountIsZero() -``` - -The max mintable per account cannot be zero. diff --git a/pages/protocol/modules/sound-metadata.mdx b/pages/protocol/modules/sound-metadata.mdx new file mode 100644 index 0000000..22e4a7c --- /dev/null +++ b/pages/protocol/modules/sound-metadata.mdx @@ -0,0 +1,220 @@ +# SoundMetadata + +[`contracts/modules/SoundMetadata.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/SoundMetadata.sol) + +Sound Metadata module with per-tier overrides. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +Inherits: + +- [IMetadataModule](i-metadata-module.md) + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Write Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### setNumberedUpTo + +```solidity +function setNumberedUpTo(address edition, uint32 tokenId) external +``` + +Sets the maximum `tokenId` for `edition` that has a numbered JSON. + +|Params:|| +|---|---| +| `edition` | The address of the SoundEdition. +| `tokenId` | The maximum `tokenId` for `edition` that has a numbered JSON. + +{/* ------------------------------------------------------------------------------------------- */} + +### setBaseURI + +```solidity +function setBaseURI( + address edition, + uint8 tier, + string calldata uri + ) external +``` + +Sets the base URI for (`edition`, `tier`). + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `uri` | The base URI. + +{/* ------------------------------------------------------------------------------------------- */} + +### setUseTierTokenIdIndex + +```solidity +function setUseTierTokenIdIndex(address edition, bool value) external +``` + +Sets whether to use the tier token ID index Defaults to true. + +|Params:|| +|---|---| +| `edition` | The address of the SoundEdition. +| `value` | Whether to use the tier token ID index for `edition`. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Read-only Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### DEFAULT_NUMBER_UP_TO + +```solidity +function DEFAULT_NUMBER_UP_TO() external pure returns (uint32) +``` + +Returns the default maximum `tokenId` for `edition` that has a numbered json. + +{/* ------------------------------------------------------------------------------------------- */} + +### numberedUpTo + +```solidity +function numberedUpTo(address edition) external view returns (uint32) +``` + +Returns the maximum `tokenId` for `edition` that has a numbered json. + +|Params:|| +|---|---| +| `edition` | The address of the SoundEdition. + +{/* ------------------------------------------------------------------------------------------- */} + +### useTierTokenIdIndex + +```solidity +function useTierTokenIdIndex(address edition) external view returns (bool) +``` + +Returns whether to use the tier token ID index. Defaults to true. + +|Params:|| +|---|---| +| `edition` | The address of the SoundEdition. + +{/* ------------------------------------------------------------------------------------------- */} + +### baseURI + +```solidity +function baseURI(address edition, uint8 tier) external view returns (string memory) +``` + +Returns the base URI override for the (`edition`, `tier`). + +|Params:|| +|---|---| +| `edition` | The address of the SoundEdition. +| `tier` | The tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### tokenURI + +```solidity +function tokenURI(uint256 tokenId) external view returns (string memory) +``` + +When registered on a SoundEdition proxy, its `tokenURI` redirects execution to this `tokenURI`. + +|Params:|| +|---|---| +| `tokenId` | The token ID to retrieve the token URI for. + +{/* ------------------------------------------------------------------------------------------- */} + +### goldenEggTokenId + +```solidity +function goldenEggTokenId(address edition, uint8 tier) external view returns (uint256 tokenId) +``` + +Returns token ID for the golden egg after the `mintRandomness` is locked, else returns 0. + +|Params:|| +|---|---| +| `edition` | The edition address. +| `tier` | The tier of the token. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Events + +{/* ------------------------------------------------------------------------------------------- */} + +### NumberUpToSet + +```solidity +event NumberUpToSet(address indexed edition, uint32 tokenId) +``` + +Emitted when the `tokenId` for `edition` with a json is set. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tokenId` | The maximum `tokenId` for `edition` that has a numberd json. + +{/* ------------------------------------------------------------------------------------------- */} + +### BaseURISet + +```solidity +event BaseURISet(address indexed edition, uint8 tier, string uri) +``` + +Emitted when the base URI for (`edition`, `tier`) is set. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `uri` | The base URI. + +{/* ------------------------------------------------------------------------------------------- */} + +### UseTierTokenIdIndexSet + +```solidity +event UseTierTokenIdIndexSet(address indexed edition, bool value) +``` + +Emitted when the option use the tier token ID is set. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `value` | Whether to use the tier token ID for `edition`. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Errors + +{/* ------------------------------------------------------------------------------------------- */} + +### Unauthorized + +```solidity +error Unauthorized() +``` + +The caller is not authorized to perform the operation. \ No newline at end of file diff --git a/pages/protocol/modules/sound-on-chain-metadata.mdx b/pages/protocol/modules/sound-on-chain-metadata.mdx new file mode 100644 index 0000000..a74bfe6 --- /dev/null +++ b/pages/protocol/modules/sound-on-chain-metadata.mdx @@ -0,0 +1,507 @@ +# SoundOnChainMetadata + +[`contracts/modules/SoundOnChainMetadata.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/SoundOnChainMetadata.sol) + +Sound Metadata module with per-tier overrides (on-chain JSON variant). + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +Inherits: + +- [IMetadataModule](i-metadata-module.md) + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## JSON Templating + +Suppose we want to generate the following JSON: + +```javascript +{ + "animation_url": "", + "artist": "Daniel Allan", + "artwork": { + "mimeType": "image/gif", + "uri": "ar://J5NZ-e2NUcQj1OuuhpTjAKtdW_nqwnwo5FypF_a6dE4", + "nft": null + }, + "attributes": [{ + "trait_type": "Criteria", + "value": "Song Edition" + }], + "bpm": null, + "credits": null, + "description": "Criteria is an 8-track project between Daniel Allan and Reo Cragun.\n\nA fusion of electronic music and hip-hop - Criteria brings together the best of both worlds and is meant to bring web3 music to a wider audience.\n\nThe collection consists of 2500 editions with activations across Sound, Bonfire, OnCyber, Spinamp and Arpeggi.", + "duration": 105, + "external_url": "https://www.sound.xyz/danielallan/criteria", + "genre": "Pop", + "image": "ar://J5NZ-e2NUcQj1OuuhpTjAKtdW_nqwnwo5FypF_a6dE4", + "isrc": null, + "key": null, + "license": null, + "locationCreated": null, + "losslessAudio": "", + "lyrics": null, + "mimeType": "audio/wave", + "nftSerialNumber": 11, + "name": "Criteria #11", + "originalReleaseDate": null, + "project": null, + "publisher": null, + "recordLabel": null, + "tags": null, + "title": "Criteria", + "trackNumber": 1, + "version": "sound-edition-20220930", + "visualizer": null +} +``` + +We can represent it as a template: + +```javascript +{ + "animation_url": [["animationURI"]], + "artist": [["artist"]], + "artwork": { + "mimeType": [["artworkMime"]], + "uri": [["artworkURI"]], + "nft": null + }, + "attributes": [{ + "trait_type": [["title"]], + "value": "Song Edition" + }], + "bpm": [["bpm"]], + "credits": [["credits"]], + "description": [["description"]], + "duration": [["duration"]], + "external_url": [["externalURI"]], + "genre": [["genre"]], + "image": [["artworkURI"]], + "isrc": [["isrc"]], + "key": [["key"]], + "license": [["license"]], + "locationCreated": [["locationCreated"]], + "losslessAudio": [["losslessAudio"]], + "lyrics": [["lyrics"]], + "mimeType": [["mime"]], + "nftSerialNumber": [["sn"]], + "name": [[["title"], " #", ["sn"]]], + "originalReleaseDate": [["originalReleaseDate"]], + "project": [["project"]], + "publisher": [["publisher"]], + "recordLabel": [["recordLabel"]], + "tags": [["tags"]], + "title": [["title"]], + "trackNumber": [["trackNumber"]], + "version": [["version"]], + "visualizer": [["visualizer"]] +} +``` + +We can represent substitutions with two different formats: + +- Literal substitution: `[["visualizer"]]` +- String concatenation substitution: `[[["title"], " #", ["sn"]]]` + +The behavior of these two formats will be described later. + +The metadata contract will have a function for users to upload templates: + +```solidity +function createTemplate(string memory template) + public + returns (string memory templateId) +``` + +Anyone can upload a template to the metadata contract, and it will return a template ID, which is a very short base64 string of 12 characters. + +We will then need a way to specify per-edition values to be substituted into these templates. + +```solidity +function setValues( + address edition, + string memory values +) public onlyOwnerOrAdmin(edition) +``` + +In this case, the values is a JSON describing what templates to use, and what values are to be substituted: + +```javascript +{ + "base": { + "template": "g5wQ129ioUEq", + "values": { + "animationURI": "", + "artist": "Daniel Allan", + "artworkMime": "image/gif", + "artworkURI": "ar://J5NZ-e2NUcQj1OuuhpTjAKtdW_nqwnwo5FypF_a6dE4", + "description": "Criteria is an 8-track project between Daniel Allan and Reo Cragun.\n\nA fusion of electronic music and hip-hop - Criteria brings together the best of both worlds and is meant to bring web3 music to a wider audience.\n\nThe collection consists of 2500 editions with activations across Sound, Bonfire, OnCyber, Spinamp and Arpeggi.", + "duration": 105, + "genre": "Pop", + "losslessAudio": "", + "mime": "audio/wave", + "title": "Criteria", + "trackNumber": 1, + "version": "sound-edition-20220930" + } + }, + "0": { + "values": { + "artworkURI": "tier0ArtworkURI" + } + }, + "1": { + "values": { + "artworkURI": "tier1ArtworkURI" + }, + "goldenEgg": { + "template": "dEF12ji78WuR", + "values": { + "artworkURI": "goldenEggArtworkURI" + } + } + } +} +``` + +Note that there are some special keys not shown above: + +- `"sn"` : The serial number, which will be the base 10 decimal string of the token’s tier-index. If the token happens to be the golden egg, this will be “goldenEgg”. +- `"id"` : The token ID, which will be the base 10 decimal string of the token’s ID. If the token happens to be the golden egg, this will be “goldenEgg”. +- `"tier"`: The token tier, which will be the base 10 decimal string of the token’s tier. + +If the values JSON contains any of these reserved keys, it will override the default values. + +### Substitution Rules + +#### Literal substitution + +`[["visualizer"]]` + +If the value is a string, it will be double-quoted. + +If it is a number, boolean, null, object, array, it will not be double quoted. + +If the value is missing, it will be considered as `null`. + +#### String concatenation substitution + +`[[["title"], " #", ["sn"]]]` + +Values will not be double-quoted. Strings will be automatically decoded and re-encoded. + +If the value is an object or an array, the function will revert. + +If the value is missing, it will be considered as `null`. + +### Inheritance + +The inheritance precedence is: `"goldenEgg"` > `"tier"` > `"base"` . + +#### Illustration by Example + +Suppose we have three different templates: + +```javascript +"1": '{"x":[["x"]],"b":[["b"]],"n":[[["tier"],"-",["sn"]]],"i":[["id"]],"s":"ONE"}' +"2": '{"x":[["x"]],"b":[["b"]],"n":[[["tier"],"-",["sn"]]],"i":[["id"]],"s":"TWO"}' +"3": '{"x":[["x"]],"b":[["b"]],"n":[[["tier"],"-",["sn"]]],"i":[["id"]],"s":"THREE"}' +``` + +And suppose we have an edition with this values JSON: + +```javascript +{ + "base": { + "template": "1", + "values": { + "x": 11, + "b": "B" + } + }, + "7": { + "template": "2", + "values": { + "x": 22 + } + }, + "goldenEgg": { + "template": "3", + "values": { + "x": 33 + } + } +} +``` + +For `id=1000, sn=111, tier=1, goldenEgg=false`, the token JSON will be: + +```javascript +{"x":11,"b":"B","n":"1-111","i":1000,"s":"ONE"} +``` + +For `id=2000, sn=222, tier=7, goldenEgg=false`, the token JSON will be: + +```javascript +{"x":22,"b":"B","n":"7-222","i":2000,"s":"TWO"} +``` + +For `id=3000, sn=333, tier=7, goldenEgg=true`, the token JSON will be: + +```javascript +{"x":33,"b":"B","n":"7-333","i":3000,"s":"THREE"} +``` + +Note that the special fields `"id"`, `"sn"` , `"tier"` are not provided in the values JSON. The metadata contract automatically retrieves and substitutes them in. + +#### Shorthands + +For JSON compactness, you can use: + +- `"g"` instead of `"goldenEgg"` +- `"b"` instead of `"base"` + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Write Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### createTemplate + +```solidity +function createTemplate(string memory templateJSON) external returns (string memory templateId) +``` + +Creates a new template. + +|Params:|| +|---|---| +| `templateJSON` | The template JSON. + +{/* ------------------------------------------------------------------------------------------- */} + +### setValues + +```solidity +function setValues(address edition, string memory valuesJSON) external +``` + +Sets the values for the (`edition`, `tier`). + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `valuesJSON` | The JSON string of values. + +{/* ------------------------------------------------------------------------------------------- */} + +### setValuesCompressed + +```solidity +function setValuesCompressed(address edition, bytes memory compressed) external +``` + +Sets the values for the (`edition`, `tier`). + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `compressed` | The JSON string of values, in compressed form. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Read-only Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### predictTemplateId + +```solidity +function predictTemplateId(string memory templateJSON) + external + view + returns (string memory templateId) +``` + +Returns the deterministic template ID. + +|Params:|| +|---|---| +| `templateJSON` | The template JSON. + +{/* ------------------------------------------------------------------------------------------- */} + +### getTemplate + +```solidity +function getTemplate(string memory templateId) + external + view + returns (string memory templateJSON) +``` + +Returns the template JSON for the template ID. + +|Params:|| +|---|---| +| `templateId` | The template ID. + +{/* ------------------------------------------------------------------------------------------- */} + +### getValues + +```solidity +function getValues(address edition) + external + view + returns (string memory valuesJSON) +``` + +Returns the template ID and the values JSON for the (`edition`, `tier`). + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. + +{/* ------------------------------------------------------------------------------------------- */} + +### rawTokenJSON + +```solidity +function rawTokenJSON( + address edition, + uint256 tokenId, + uint256 sn, + uint8 tier, + bool isGoldenEgg +) external view returns (string memory json) +``` + +Returns the JSON string, assuming the following parameters. + +|Params:|| +|---|---| +| `edition` | The edition address. +| `tokenId` | The token ID. +| `sn` | The serial number of the token (index of the token in its tier + 1). +| `tier` | The token tier. +| `isGoldenEgg` | Whether the token is a golden egg. + +{/* ------------------------------------------------------------------------------------------- */} + +### tokenURI + +```solidity +function tokenURI(uint256 tokenId) external view returns (string memory uri) +``` + +When registered on a SoundEdition proxy, its `tokenURI` redirects execution to this `tokenURI`. + +|Params:|| +|---|---| +| `tokenId` | The token ID to retrieve the token URI for. + +{/* ------------------------------------------------------------------------------------------- */} + +### goldenEggTokenId + +```solidity +function goldenEggTokenId(address edition, uint8 tier) + external + view + returns (uint256 tokenId) +``` + +Returns token ID for the golden egg after the `mintRandomness` is locked, else returns 0. + +|Params:|| +|---|---| +| `edition` | The edition address. +| `tier` | The tier of the token. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Events + +{/* ------------------------------------------------------------------------------------------- */} + +### TemplateCreated + +```solidity +event TemplateCreated(string templateId) +``` + +Emitted when a new template is created. + +|Params:|| +|---|---| +| `templateId` | The template ID for the template. + +{/* ------------------------------------------------------------------------------------------- */} + +### ValuesSet + +```solidity +event ValuesSet(address indexed edition, bool compressed) +``` + +Emitted when the values for a (`edition`, `tier`) is set. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `compressed` | Whether the values JSON is compressed with `solady.LibZip.flzCompress`. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Errors + +{/* ------------------------------------------------------------------------------------------- */} + +### Unauthorized + +```solidity +error Unauthorized() +``` + +Unauthorized caller. + +{/* ------------------------------------------------------------------------------------------- */} + +### TemplateIdTaken + +```solidity +error TemplateIdTaken() +``` + +The template ID has been taken. + +{/* ------------------------------------------------------------------------------------------- */} + +### TemplateDoesNotExist + +```solidity +error TemplateDoesNotExist() +``` + +The template does not exist. + +{/* ------------------------------------------------------------------------------------------- */} + +### ValuesDoNotExist + +```solidity +error ValuesDoNotExist() +``` + +The values do not exist. + diff --git a/pages/protocol/modules/super-minter.mdx b/pages/protocol/modules/super-minter.mdx new file mode 100644 index 0000000..26a2ef4 --- /dev/null +++ b/pages/protocol/modules/super-minter.mdx @@ -0,0 +1,1709 @@ +# SuperMinter + +[`contracts/modules/SuperMinter.sol`](https://github.com/soundxyz/sound-protocol/blob/master/contracts/modules/SuperMinter.sol) + +Generalized minter. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +Modes: + +- `DEFAULT`. No mint gatekeeping. +- `VERIFY_MERKLE`. Minters must be included in a Merkle Tree. +- `VERIFY_SIGNATURE`. Minters must be authorized via a signature by a signer. The price and quantity restrictions can be adjusted via the signature. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +Inherits: + +- [IERC165](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol) + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Structs + +{/* ------------------------------------------------------------------------------------------- */} + +### MintCreation + +```solidity +struct MintCreation { + // The edition address. + address edition; + // The base price per token. + // For `VERIFY_SIGNATURE`, this will be the minimum limit of the signed price. + // Will be 0 if the `tier` is `GA_TIER`. + uint96 price; + // The start time of the mint. + uint32 startTime; + // The end time of the mint. + uint32 endTime; + // The maximum number of tokens an account can mint in this mint. + uint32 maxMintablePerAccount; + // The maximum number of tokens mintable. + uint32 maxMintable; + // The affiliate fee BPS. + uint16 affiliateFeeBPS; + // The affiliate Merkle root, if any. + bytes32 affiliateMerkleRoot; + // The tier of the mint. + uint8 tier; + // The address of the platform. + address platform; + // The mode of the mint. Options: `DEFAULT`, `VERIFY_MERKLE`, `VERIFY_SIGNATURE`. + uint8 mode; + // The signer address, required if `mode` is `VERIFY_SIGNATURE`. + // If set to `address(1)`, the platform signer will be used instead. + address signer; + // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`. + bytes32 merkleRoot; +} +``` + +A struct containing the arguments to create a mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintTo + +```solidity +struct MintTo { + // The mint ID. + address edition; + // The tier of the mint. + uint8 tier; + // The edition-tier schedule number. + uint8 scheduleNum; + // The address to mint to. + address to; + // The number of tokens to mint. + uint32 quantity; + // The allowlisted address. Used if `mode` is `VERIFY_MERKLE`. + address allowlisted; + // The allowlisted quantity. Used if `mode` is `VERIFY_MERKLE`. + // A default zero value means no limit. + uint32 allowlistedQuantity; + // The allowlist Merkle proof. + bytes32[] allowlistProof; + // The signed price. Used if `mode` is `VERIFY_SIGNATURE`. + uint96 signedPrice; + // The signed quantity. Used if `mode` is `VERIFY_SIGNATURE`. + uint32 signedQuantity; + // The signed claimed ticket. Used if `mode` is `VERIFY_SIGNATURE`. + uint32 signedClaimTicket; + // The expiry timestamp for the signature. Used if `mode` is `VERIFY_SIGNATURE`. + uint32 signedDeadline; + // The signature by the signer. Used if `mode` is `VERIFY_SIGNATURE`. + bytes signature; + // The affiliate address. Optional. + address affiliate; + // The Merkle proof for the affiliate. + bytes32[] affiliateProof; + // The attribution ID, optional. + uint256 attributionId; +} +``` + +A struct containing the arguments for mint-to. + +{/* ------------------------------------------------------------------------------------------- */} + +### TokenPriceAndFees + +```solidity +struct TotalPriceAndFees { + // The required Ether value. + // `subTotal + platformFlatFee`. + uint256 total; + // The total price before any additive fees. + uint256 subTotal; + // The price per token. + uint256 unitPrice; + // The total platform fees. + // `platformFlatFee + platformMintBPSFee`. + uint256 platformFee; + // The total platform flat fees. + // `platformTxFlatFee + platformMintFlatFee`. + uint256 platformFlatFee; + // The platform per-transaction flat fees. + uint256 platformTxFlatFee; + // The total platform per-token flat fees. + uint256 platformMintFlatFee; + // The total platform per-token BPS fees. + uint256 platformMintBPSFee; + // The total affiliate fees. + uint256 affiliateFee; +} +``` + +{/* ------------------------------------------------------------------------------------------- */} + +### MintedLogData + +```solidity +struct MintedLogData { + // The number of tokens minted. + uint32 quantity; + // The starting token ID minted. + uint256 fromTokenId; + // The allowlisted address. + address allowlisted; + // The allowlisted quantity. + uint32 allowlistedQuantity; + // The signed quantity. + uint32 signedQuantity; + // The signed claim ticket. + uint32 signedClaimTicket; + // The affiliate address. + address affiliate; + // Whether the affiliate address is affiliated. + bool affiliated; + // The total price paid, inclusive of all fees. + uint256 requiredEtherValue; + // The price per token. + uint256 unitPrice; + // The total platform fees. + uint256 platformFee; + // The total platform flat fees. + uint256 platformFlatFee; + // The total affiliate fees. + uint256 affiliateFee; +} +``` + +A struct containing the log data for the `Minted` event. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformFeeConfig + +```solidity +struct PlatformFeeConfig { + // The per-transaction flat fee. + uint96 perTxFlat; + // The per-token flat fee. + uint96 perMintFlat; + // The per-token fee BPS. + uint16 perMintBPS; + // Whether the fees are active. + bool active; +} +``` + +A struct to hold the fee configuration for a platform and a tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintInfo + +```solidity +struct MintInfo { + // The mint ID. + address edition; + // The tier of the mint. + uint8 tier; + // The edition-tier schedule number. + uint8 scheduleNum; + // The platform address. + address platform; + // The base price per token. + // For `VERIFY_SIGNATURE` this will be the minimum limit of the signed price. + // If the `tier` is `GA_TIER`, and the `mode` is NOT `VERIFY_SIGNATURE`, + // this value will be the GA price instead. + uint96 price; + // The start time of the mint. + uint32 startTime; + // The end time of the mint. + uint32 endTime; + // The maximum number of tokens an account can mint in this mint. + uint32 maxMintablePerAccount; + // The maximum number of tokens mintable. + uint32 maxMintable; + // The total number of tokens minted. + uint32 minted; + // The affiliate fee BPS. + uint16 affiliateFeeBPS; + // The mode of the mint. + uint8 mode; + // Whether the mint is paused. + bool paused; + // Whether the mint already has mints. + bool hasMints; + // The affiliate Merkle root, if any. + bytes32 affiliateMerkleRoot; + // The Merkle root hash, required if `mode` is `VERIFY_MERKLE`. + bytes32 merkleRoot; + // The signer address, required if `mode` is `VERIFY_SIGNATURE`. + // This value will be the platform signer instead if it is configured to be `address(1)`. + address signer; + // Whether the platform signer is being used instead + // (i.e. `signer` configured to be `address(1)`). + bool usePlatformSigner; +} +``` + +A struct containing the mint information. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Write Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### createEditionMint + +```solidity +function createEditionMint(MintCreation calldata c) external returns (uint8 scheduleNum) +``` + +Creates a mint. + +|Params:|| +|---|---| +| `c` | The mint creation struct. + +|Returns:|| +|---|---| +| `scheduleNum` | The per-edition, per-tier schedule number (auto-incrementing). + +{/* ------------------------------------------------------------------------------------------- */} + +### mintTo + +```solidity +function mintTo(MintTo calldata p) external payable +``` + +Performs a mint. + +|Params:|| +|---|---| +| `p` | The mint-to parameters. + +{/* ------------------------------------------------------------------------------------------- */} + +### setPrice + +```solidity +function setPrice( + address edition, + uint8 tier, + uint8 scheduleNum, + uint96 price +) external +``` + +Sets the price of the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `price` | The price per token. + +{/* ------------------------------------------------------------------------------------------- */} + +### setPaused + +```solidity +function setPaused( + address edition, + uint8 tier, + uint8 scheduleNum, + bool paused +) external +``` + +Pause or unpase the the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `paused` | Whether to pause the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### setTimeRange + +```solidity +function setTimeRange( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 startTime, + uint32 endTime +) external +``` + +Sets the time range for the the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `startTime` | The mint start time. +| `endTime` | The mint end time. + +{/* ------------------------------------------------------------------------------------------- */} + +### setStartTime + +```solidity +function setStartTime( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 startTime +) external +``` + +Sets the start time for the the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `startTime` | The mint start time. + +{/* ------------------------------------------------------------------------------------------- */} + +### setAffiliateFee + +```solidity +function setAffiliateFee( + address edition, + uint8 tier, + uint8 scheduleNum, + uint16 bps + ) external +``` + +Sets the affiliate fee BPS for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `bps` | The fee BPS. + +{/* ------------------------------------------------------------------------------------------- */} + +### setAffiliateMerkleRoot + +```solidity +function setAffiliateMerkleRoot( + address edition, + uint8 tier, + uint8 scheduleNum, + bytes32 root +) external +``` + +Sets the affiliate Merkle root for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `root` | The affiliate Merkle root. + +{/* ------------------------------------------------------------------------------------------- */} + +### setMaxMintablePerAccount + +```solidity +function setMaxMintablePerAccount( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 value +) external +``` + +Sets the max mintable per account. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `value` | The max mintable per account. + +{/* ------------------------------------------------------------------------------------------- */} + +### setMaxMintable + +```solidity +function setMaxMintable( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 value +) external +``` + +Sets the max mintable for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `value` | The max mintable for the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### setMerkleRoot + +```solidity +function setMerkleRoot( + address edition, + uint8 tier, + uint8 scheduleNum, + bytes32 merkleRoot +) external +``` + +Sets the mode for the mint. The mint mode must be `VERIFY_MERKLE`. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `merkleRoot` | The Merkle root of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### setSigner + +```solidity +function setSigner( + address edition, + uint8 tier, + uint8 scheduleNum, + address signer +) external +``` + +Sets the signer for the mint. The mint mode must be `VERIFY_SIGNATURE`. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `signer` | The signer of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### withdrawForAffiliate + +```solidity +function withdrawForAffiliate(address affiliate) external +``` + +Withdraws all accrued fees of the affiliate, to the affiliate. + +|Params:|| +|---|---| +| `affiliate` | The affiliate address. + +{/* ------------------------------------------------------------------------------------------- */} + +### withdrawForPlatform + +```solidity +function withdrawForPlatform(address platform) external +``` + +Withdraws all accrued fees of the platform, to the their fee address. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + +### setPlatformFeeAddress + +```solidity +function setPlatformFeeAddress(address recipient) external +``` + +Allows the caller, as a platform, to set their fee address + +|Params:|| +|---|---| +| `recipient` | The platform fee address of the caller. + +{/* ------------------------------------------------------------------------------------------- */} + +### setPlatformFeeConfig + +```solidity +function setPlatformFeeConfig(uint8 tier, PlatformFeeConfig memory c) external +``` + +Allows the caller, as a platform, to set their per-tier fee configuration. + +|Params:|| +|---|---| +| `tier` | The tier of the mint. +| `c` | The platform fee configuration struct. + +{/* ------------------------------------------------------------------------------------------- */} + +### setDefaultPlatformFeeConfig + +```solidity +function setDefaultPlatformFeeConfig(PlatformFeeConfig memory c) external +``` + +Allows the caller, as a platform, to set their default fee configuration. + +|Params:|| +|---|---| +| `c` | The platform fee configuration struct. + +{/* ------------------------------------------------------------------------------------------- */} + +### setGAPrice + +```solidity +function setGAPrice(uint96 price) external +``` + +Allows the platform to set the price for the GA tier. + +|Params:|| +|---|---| +| `price` | The price per token for the GA tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### setPlatformSigner + +```solidity +function setPlatformSigner(address signer) external +``` + +Allows the platform to set their signer. + +|Params:|| +|---|---| +| `signer` | The signer for the platform. + + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Read-only Functions + +{/* ------------------------------------------------------------------------------------------- */} + +### GA_TIER + +```solidity +function GA_TIER() external pure returns (uint8) +``` + +Returns the GA tier. Which is 0. + +{/* ------------------------------------------------------------------------------------------- */} + +### MINT_TO_TYPEHASH + +```solidity +function MINT_TO_TYPEHASH() external pure returns (bytes32) +``` + +The EIP-712 typehash for signed mints. + +{/* ------------------------------------------------------------------------------------------- */} + +### DEFAULT + +```solidity +function DEFAULT() external pure returns (uint8) +``` + +The default mint mode. + +{/* ------------------------------------------------------------------------------------------- */} + +### VERIFY_MERKLE + +```solidity +function VERIFY_MERKLE() external pure returns (uint8) +``` + +The mint mode for Merkle drops. + +{/* ------------------------------------------------------------------------------------------- */} + +### VERIFY_SIGNATURE + +```solidity +function VERIFY_SIGNATURE() external pure returns (uint8) +``` + +The mint mode for Signature drops. + +{/* ------------------------------------------------------------------------------------------- */} + +### BPS_DENOMINATOR + +```solidity +function BPS_DENOMINATOR() external pure returns (uint16) +``` + +The denominator used in BPS fee calculations. + +{/* ------------------------------------------------------------------------------------------- */} + +### MAX_AFFILIATE_FEE_BPS + +```solidity +function MAX_AFFILIATE_FEE_BPS() external pure returns (uint16) +``` + +The maximum affiliate fee BPS. + +{/* ------------------------------------------------------------------------------------------- */} + +### MAX_PLATFORM_PER_MINT_FEE_BPS + +```solidity +function MAX_PLATFORM_PER_MINT_FEE_BPS() external pure returns (uint16) +``` + +The maximum per-mint platform fee BPS. + +{/* ------------------------------------------------------------------------------------------- */} + +### MAX_PLATFORM_PER_MINT_FLAT_FEE + +```solidity +function MAX_PLATFORM_PER_MINT_FLAT_FEE() external pure returns (uint96) +``` + +The maximum platform per-mint flat fee. + +{/* ------------------------------------------------------------------------------------------- */} + +### MAX_PLATFORM_PER_TX_FLAT_FEE + +```solidity +function MAX_PLATFORM_PER_TX_FLAT_FEE() external pure returns (uint96) +``` + +The maximum platform per-transaction flat fee. + +{/* ------------------------------------------------------------------------------------------- */} + +### platformFeesAccrued + +```solidity +function platformFeesAccrued(address platform) external view returns (uint256) +``` + +Returns the amount of fees accrued by the platform. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + +### platformFeeAddress + +```solidity +function platformFeeAddress(address platform) external view returns (address) +``` + +Returns the fee recipient for the platform. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + +### affiliateFeesAccrued + +```solidity +function affiliateFeesAccrued(address affiliate) external view returns (uint256) +``` + +Returns the amount of fees accrued by the affiliate. + +|Params:|| +|---|---| +| `affiliate` | The affiliate address. + +{/* ------------------------------------------------------------------------------------------- */} + +### computeMintToDigest + +```solidity +function computeMintToDigest(MintTo calldata p) external view returns (bytes32) +``` + +Returns the EIP-712 digest of the mint-to data for signature mints. + +|Params:|| +|---|---| +| `p` | The mint-to parameters. + +{/* ------------------------------------------------------------------------------------------- */} + +### totalPriceAndFees + +```solidity +function totalPriceAndFees( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 quantity +) external view returns (TotalPriceAndFees memory) +``` + +Returns the total price and fees for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `quantity` | How many tokens to mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### totalPriceAndFeesWithSignedPrice + +```solidity +function totalPriceAndFeesWithSignedPrice( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32 quantity, + uint96 signedPrice +) external view returns (TotalPriceAndFees memory) +``` + +Returns the total price and fees for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `quantity` | How many tokens to mint. +| `signedPrice` | The signed price. + +{/* ------------------------------------------------------------------------------------------- */} + +### gaPrice + +```solidity +function gaPrice(address platform) external view returns (uint96) +``` + +Returns the GA price for the platform. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + +### platformSigner + +```solidity +function platformSigner(address platform) external view returns (address) +``` + +Returns the signer for the platform. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + + +### nextScheduleNum + +```solidity +function nextScheduleNum(address edition, uint8 tier) external view returns (uint8) +``` + +Returns the next mint schedule number for the edition-tier. + +|Params:|| +|---|---| +| `edition` | The Sound Edition address. +| `tier` | The tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### numberMinted + +```solidity +function numberMinted( + address edition, + uint8 tier, + uint8 scheduleNum, + address collector +) external view returns (uint32) +``` + +Returns the number of tokens minted by `collector` for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `collector` | The address which tokens are minted to, or in the case of `VERIFY_MERKLE`, is the allowlisted address. + +{/* ------------------------------------------------------------------------------------------- */} + +### isAffiliatedWithProof + +```solidity +function isAffiliatedWithProof( + address edition, + uint8 tier, + uint8 scheduleNum, + address affiliate, + bytes32[] calldata affiliateProof + ) external view returns (bool) +``` + +Returns whether the affiliate is affiliated for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `affiliate` | The affiliate address. +| `affiliateProof` | The Merkle proof for the affiliate. + +{/* ------------------------------------------------------------------------------------------- */} + +### isAffiliated + +```solidity +function isAffiliated( + address edition, + uint8 tier, + uint8 scheduleNum, + address affiliate +) external view returns (bool) +``` + +Returns whether the affiliate is affiliated for the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `affiliate` | The affiliate address. + +{/* ------------------------------------------------------------------------------------------- */} + +### checkClaimTickets + +```solidity +function checkClaimTickets( + address edition, + uint8 tier, + uint8 scheduleNum, + uint32[] calldata claimTickets +) external view returns (bool[] memory) +``` + +Returns whether the claim tickets have been used. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `claimTickets` | An array of claim tickets. + +{/* ------------------------------------------------------------------------------------------- */} + +### platformFeeConfig + +```solidity +function platformFeeConfig(address platform, uint8 tier) + external + view + returns (PlatformFeeConfig memory) +``` + +Returns the platform fee configuration for the tier. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `tier` | The tier of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### defaultPlatformFeeConfig + +```solidity +function defaultPlatformFeeConfig(address platform) + external + view + returns (PlatformFeeConfig memory) +``` + +Returns the default platform fee configuration. + +|Params:|| +|---|---| +| `platform` | The platform address. + +{/* ------------------------------------------------------------------------------------------- */} + +### effectivePlatformFeeConfig + +```solidity +function effectivePlatformFeeConfig(address platform, uint8 tier) + external + view + returns (PlatformFeeConfig memory) +``` + +Returns the effective platform fee configuration. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `tier` | The tier of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### mintInfoList + +```solidity +function mintInfoList(address edition) external view returns (MintInfo[] memory) +``` + +Returns an array of mint information structs pertaining to the mint. + +|Params:|| +|---|---| +| `edition` | The Sound Edition address. + +{/* ------------------------------------------------------------------------------------------- */} + +### mintInfo + +```solidity +function mintInfo( + address edition, + uint8 tier, + uint8 scheduleNum +) external view returns (MintInfo memory) +``` + +Returns information pertaining to the mint. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. + +{/* ------------------------------------------------------------------------------------------- */} + +### name + +```solidity +function name() external pure returns (string memory) +``` + +Retuns the EIP-712 name for the contract. + +{/* ------------------------------------------------------------------------------------------- */} + +### version + +```solidity +function version() external pure returns (string memory) +``` + +Retuns the EIP-712 version for the contract. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Events + +{/* ------------------------------------------------------------------------------------------- */} + +### MintCreated + +```solidity +event MintCreated( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + MintCreation creation +) +``` + +Emitted when a new mint is created. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `creation` | The mint creation struct. + +{/* ------------------------------------------------------------------------------------------- */} + +### PausedSet + +```solidity +event PausedSet(address indexed edition, uint8 tier, uint8 scheduleNum, bool paused) +``` + +Emitted when a mint is paused or un-paused. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `paused` | Whether the mint is paused. + +{/* ------------------------------------------------------------------------------------------- */} + +### TimeRangeSet + +```solidity +event TimeRangeSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + uint32 startTime, + uint32 endTime +) +``` + +Emitted when the time range of a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `startTime` | The start time. +| `endTime` | The end time. + +{/* ------------------------------------------------------------------------------------------- */} + + +### PriceSet + +```solidity +event PriceSet(address indexed edition, uint8 tier, uint8 scheduleNum, uint96 price) +``` + +Emitted when the base per-token price of a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `price` | The base per-token price. + +{/* ------------------------------------------------------------------------------------------- */} + +### MaxMintablePerAccountSet + +```solidity +event MaxMintablePerAccountSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + uint32 value +) +``` + +Emitted when the max mintable per account for a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `value` | The max mintable per account. + +{/* ------------------------------------------------------------------------------------------- */} + +### MaxMintableSet + +```solidity +event MaxMintableSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + uint32 value +) +``` + +Emitted when the max mintable for a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `value` | The max mintable for the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### MerkleRootSet + +```solidity +event MerkleRootSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + bytes32 merkleRoot +) +``` + +Emitted when the Merkle root of a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `merkleRoot` | The Merkle root of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### SignerSet + +```solidity +event SignerSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + address signer +) +``` + +Emitted when the signer of a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `signer` | The signer of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### AffiliateFeeSet + +```solidity +event AffiliateFeeSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + uint16 bps +) +``` + +Emitted when the affiliate fee BPS for a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `bps` | The affiliate fee BPS. + +{/* ------------------------------------------------------------------------------------------- */} + +### AffiliateMerkleRootSet + +```solidity +event AffiliateMerkleRootSet( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + bytes32 root +) +``` + +Emitted when the affiliate Merkle root for a mint is updated. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `root` | The affiliate Merkle root hash. + +{/* ------------------------------------------------------------------------------------------- */} + +### Minted + +```solidity +event Minted( + address indexed edition, + uint8 tier, + uint8 scheduleNum, + address indexed to, + MintedLogData data, + uint256 indexed attributionId +) +``` + +Emitted when tokens are minted. + +|Params:|| +|---|---| +| `edition` | The address of the Sound Edition. +| `tier` | The tier. +| `scheduleNum` | The edition-tier schedule number. +| `to` | The recipient of the tokens minted. +| `data` | The mint-to log data. +| `attributionId` | The optional attribution ID. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformFeeConfigSet + +```solidity +event PlatformFeeConfigSet( + address indexed platform, + uint8 tier, + PlatformFeeConfig config +) +``` + +Emitted when the platform fee configuration for `tier` is updated. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `tier` | The tier of the mint. +| `config` | The platform fee configuration. + +{/* ------------------------------------------------------------------------------------------- */} + +### DefaultPlatformFeeConfigSet + +```solidity +event DefaultPlatformFeeConfigSet( + address indexed platform, + PlatformFeeConfig config +) +``` + +Emitted when the default platform fee configuration is updated. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `config` | The platform fee configuration. + +{/* ------------------------------------------------------------------------------------------- */} + +### AffiliateFeesWithdrawn + +```solidity +event AffiliateFeesWithdrawn(address indexed affiliate, uint256 accrued) +``` + +Emitted when affiliate fees are withdrawn. + +|Params:|| +|---|---| +| `affiliate` | The recipient of the fees. +| `accrued` | The amount of Ether accrued and withdrawn. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformFeesWithdrawn + +```solidity +event PlatformFeesWithdrawn(address indexed platform, uint256 accrued) +``` + +Emitted when platform fees are withdrawn. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `accrued` | The amount of Ether accrued and withdrawn. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformFeeAddressSet + +```solidity +event PlatformFeeAddressSet(address indexed platform, address recipient) +``` + +Emitted when the platform fee recipient address is updated. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `recipient` | The platform fee recipient address. + +{/* ------------------------------------------------------------------------------------------- */} + +### GAPriceSet + +```solidity +event GAPriceSet(address indexed platform, uint96 price) +``` + +Emitted when the per-token price for the GA tier is set. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `price` | The price per token for the GA tier. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformSignerSet + +```solidity +event PlatformSignerSet(address indexed platform, address signer) +``` + +Emitted when the signer for a platform is set. + +|Params:|| +|---|---| +| `platform` | The platform address. +| `signer` | The signer for the platform. + +{/* ------------------------------------------------------------------------------------------- */} +{/* ------------------------------------------------------------------------------------------- */} + +## Errors + +{/* ------------------------------------------------------------------------------------------- */} + +### WrongPayment + +```solidity +error WrongPayment(uint256 paid, uint256 required) +``` + +Exact payment required. + +|Params:|| +|---|---| +| `paid` | The amount of Ether paid. +| `required` | The amount of Ether required. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintNotOpen + +```solidity +error MintNotOpen(uint256 blockTimestamp, uint32 startTime, uint32 endTime) +``` + +The mint is not opened. + +|Params:|| +|---|---| +| `blockTimestamp` | The current block timestamp. +| `startTime` | The opening time of the mint. +| `endTime` | The closing time of the mint. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintPaused + +```solidity +error MintPaused() +``` + +The mint is paused. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintsAlreadyExist + +```solidity +error MintsAlreadyExist() +``` + +Cannot perform the operation when any mints exist. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidTimeRange + +```solidity +error InvalidTimeRange() +``` + +The time range is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidMaxMintableRange + +```solidity +error InvalidMaxMintableRange() +``` + +The max mintable range is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidAffiliateFeeBPS + +```solidity +error InvalidAffiliateFeeBPS() +``` + +The affiliate fee BPS cannot exceed the limit. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidPlatformFeeBPS + +```solidity +error InvalidPlatformFeeBPS() +``` + +The affiliate fee BPS cannot exceed the limit. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidPlatformFlatFee + +```solidity +error InvalidPlatformFlatFee() +``` + +The affiliate fee BPS cannot exceed the limit. + +{/* ------------------------------------------------------------------------------------------- */} + +### ExceedsMaxPerAccount + +```solidity +error ExceedsMaxPerAccount() +``` + +Cannot mint more than the maximum limit per account. + +{/* ------------------------------------------------------------------------------------------- */} + +### ExceedsMintSupply + +```solidity +error ExceedsMintSupply() +``` + +Cannot mint more than the maximum supply. + +{/* ------------------------------------------------------------------------------------------- */} + +### ExceedsSignedQuantity + +```solidity +error ExceedsSignedQuantity() +``` + +Cannot mint more than the signed quantity. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidSignature + +```solidity +error InvalidSignature() +``` + +The signature is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### SignatureExpired + +```solidity +error SignatureExpired() +``` + +The signature has expired. + +{/* ------------------------------------------------------------------------------------------- */} + +### SignatureAlreadyUsed + +```solidity +error SignatureAlreadyUsed() +``` + +The signature claim ticket has already been used. + +{/* ------------------------------------------------------------------------------------------- */} + +### SignerIsZeroAddress + +```solidity +error SignerIsZeroAddress() +``` + +The signer cannot be the zero address. + +{/* ------------------------------------------------------------------------------------------- */} + +### MerkleRootIsEmpty + +```solidity +error MerkleRootIsEmpty() +``` + +The Merkle root cannot be empty. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidMerkleProof + +```solidity +error InvalidMerkleProof() +``` + +The Merkle proof is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### CallerNotDelegated + +```solidity +error CallerNotDelegated() +``` + +The caller has not been delegated via delegate cash. + +{/* ------------------------------------------------------------------------------------------- */} + +### MaxMintablePerAccountIsZero + +```solidity +error MaxMintablePerAccountIsZero() +``` + +The max mintable amount per account cannot be zero. + +{/* ------------------------------------------------------------------------------------------- */} + +### MaxMintableIsZero + +```solidity +error MaxMintableIsZero() +``` + +The max mintable value cannot be zero. + +{/* ------------------------------------------------------------------------------------------- */} + +### PlatformFeeAddressIsZero + +```solidity +error PlatformFeeAddressIsZero() +``` + +The plaform fee address cannot be the zero address. + +{/* ------------------------------------------------------------------------------------------- */} + +### MintDoesNotExist + +```solidity +error MintDoesNotExist() +``` + +The mint does not exist. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidAffiliate + +```solidity +error InvalidAffiliate() +``` + +The affiliate provided is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidMode + +```solidity +error InvalidMode() +``` + +The mint mode provided is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### SignedPriceTooLow + +```solidity +error SignedPriceTooLow() +``` + +The signed price is too low. + +{/* ------------------------------------------------------------------------------------------- */} + +### InvalidPlatformFeeConfig + +```solidity +error InvalidPlatformFeeConfig() +``` + +The platform fee configuration provided is invalid. + +{/* ------------------------------------------------------------------------------------------- */} + +### NotConfigurable + +```solidity +error NotConfigurable() +``` + +The parameter cannot be configured. + diff --git a/pages/protocol/overview/design.mdx b/pages/protocol/overview/design.mdx index af33f67..df7c4c7 100644 --- a/pages/protocol/overview/design.mdx +++ b/pages/protocol/overview/design.mdx @@ -1,11 +1,7 @@ -import Image from 'next/image' import { IndentedDiv } from '../../../components/IndentedDiv' ## Design -
-Sound Protocol diagram - ### Core contracts These contracts form the core of the system. @@ -19,17 +15,21 @@ These contracts form the core of the system. ### Module contracts - - #### Metadata modules + + - [SoundMetadata](/protocol/modules/sound-metadata) - Metadata module for SoundEditionV2. - [SoundOnChainMetadata](/protocol/modules/sound-on-chain-metadata) - Metadata module for SoundEditionV2 (on chain JSON variant). + + #### Minter modules Contracts authorized with the `MINTER_ROLE` on a SoundEditionV2 can mint NFTs. -- [SuperMinter](/protocol/modules/minters/superminter) - Generalized singleton minter that supports a variety of minting mechanisms. + + +- [SuperMinter](/protocol/modules/super-minter) - Generalized singleton minter that supports a variety of minting mechanisms.