Docs

Modular Contracts v0.0.3 - Improved module integrations

Stanley Szeto

We have recently refactored our Modular Contracts to introduce new changes that we believe will benefit both the developer and ecosystem experience as a whole.

With that, we have made changes to our Minting, Royalty, Metadata, and a new Sequential Token ID module along with our Core contracts.

Minting

beforeMintWithSignature

In the Claimable and Mintable modules, the beforeMint function has now been split into two functions: beforeMint and beforeMintWithSignature.

All signature-based mints will now be done through the beforeMintWithSignature function, and all regular mints will now be done through the beforeMint function.

With the splitting of functionality, a division in the parameters passed into both functions has also been introduced.

For regular minting, the following parameters are now introduced:

/**
* @notice The parameters sent to the `beforeMintERC20` callback function.
*/
struct ClaimParamsERC721 {
address currency;
uint256 pricePerUnit;
bytes32[] recipientAllowlistProof;
}
// No params needed for the mintable module

For signature mints, the following parameters are now introduced:

/**
* @notice The request struct signed by an authorized party to mint tokens.
*
* @param startTimestamp The timestamp at which the minting request is valid.
* @param endTimestamp The timestamp at which the minting request expires.
* @param currency The address of the currency used to pay for the minted tokens.
* @param pricePerUnit The price per unit of the minted tokens.
* @param uid A unique identifier for the minting request.
*/
struct ClaimSignatureParamsERC721 {
uint48 startTimestamp;
uint48 endTimestamp;
address currency;
uint256 maxMintPerWallet;
uint256 pricePerUnit;
bytes32 uid;
}
/**
* @notice The request struct signed by an authorized party to mint tokens.
*
* @param startTimestamp The timestamp at which the minting request is valid.
* @param endTimestamp The timestamp at which the minting request expires.
* @param currency The address of the currency used to pay for the minted tokens.
* @param pricePerUnit The price per unit of the minted tokens.
* @param uid A unique identifier for the minting request.
*/
struct MintSignatureParamsERC721 {
uint48 startTimestamp;
uint48 endTimestamp;
address currency;
uint256 pricePerUnit;
bytes32 uid;
}

Reference to code:
ClaimableERC721.sol#L196

maxMintPerWallet

In the Claimable module, maxMintPerWallet has now been introduced in both the claimCondition and claimSignatureParams, along with a totalMinted mapping that tracks the number of mints a wallet has done so far.

This change introduces a new validity rule that allows users to set the maximum number of mints a single wallet can make.

Reference to code:
ClaimableERC721.sol#L75

Mintable module no longer supports URI Metadata

Modular contracts should be composable, and for that to be the case, the functionality of modules should be independent of each other.

We believed that the Mintable module did not achieve this, as it was capable of both validating the mint and setting the URI Metadata.

Due to this, we have removed the functionality to set the URI Metadata from the Mintable module and placed its responsibility solely on Metadata modules.

Royalty

Creator Token Standard has now been implemented

The Creator Token Standard by Limit Break has now been implemented into the Royalty modules. This introduces a beforeTransfer hook into each of the royalty modules along with a transferValidator that validates whether a transfer should be done or not, based on the policies set for the collection.

You can learn more about the Creator Token Standard here.

Reference to code:
RoyaltiesERC721.sol

Metadata

updateMetadata hook

updateMetadata is a new hook that has been introduced, allowing users to set the URI of a token as they mint it.

The purpose of introducing the updateMetadata hook was to allow the URI Metadata of a token to be set during minting, but to place this functionality in the Metadata modules rather than the Mintable module.

Reference to code:
BatchMetadataERC721.sol#L114

BatchMetadata now implements setBaseURI, getBatchId, getBatchRange

These three new functions have been introduced to allow the BatchMetadata module to have delayed reveal functionality through the setBaseURI function.

getBatchId and getBatchRange have also been introduced as helper functions to improve the overall user experience when using the setBaseURI function.

SimpleMetadata and DelayedRevealBatchMetadata are now deprecated

SimpleMetadata and DelayedRevealBatchMetadata have both been deprecated in favor of BatchMetadata.

This change was introduced because:

  1. BatchMetadata is more gas-efficient than SimpleMetadata while achieving the same functionality.
  2. BatchMetadata can now replicate delayed reveal functionality through setBaseURI.

Sequential TokenId

A new module called the SequentialTokenIdERC1155 module has been introduced, which optionally allows for sequential minting in ERC-1155-based collections.

Along with this module, the updateTokenId hook for ERC-1155 core contracts has also been implemented.

Reference to code:
SequentialTokenIdERC1155.sol

Core Contracts

updateTokenId, updateMetadata hooks

To support the newly introduced hook functions, the ERC-721 Core contract now implements the updateMetadata hook, and the ERC-1155 Core contract now implements both the updateTokenId and updateMetadata hooks.

Both of these functions are placed in the mint and mintWithSignature functions.

As previously mentioned:

  • updateTokenId is now responsible for optionally updating the token ID.
  • updateMetadata is now responsible for optionally updating the URI of a token.

Reference to code:
ERC1155Base.sol#L212

baseURI parameter in mint

To properly support the updateMetadata hook, the mint function now accepts the new parameter baseURI, which is passed into the updateMetadata hook.

Reference to code:
ERC1155Base.sol#L205

mintWithSignature function

To support the beforeMintWithSignature function in both the Claimable and Mintable modules, the mintWithSignature function has been introduced, which retrieves the signer of the signature and calls the beforeMintWithSignature function.

Reference to code:
ERC1155Base.sol#L230

Base contracts

Not to be confused with the Base chain, Base contracts serve as the core functionality of both Core and CoreInitializable contracts.

Now, both Core and CoreInitializable contracts inherit from the Base contract. This was done to reduce code duplication and improve maintainability.

Reference to code:
ERC1155Base.sol

To find all the changes made in this refactor, head on over to the GitHub repository.

To start using the contracts today, you can find them on the Explore page of the ThirdWeb Dashboard