Skip to main content

Burn to Redeem

Burn to redeem allows for a combination of token types to be burned to claim an 1155 token. For example, a requirement could be burn x amount of a specific 721 and y amount of a specific 1155 token to be able to mint an 1155 token.

Supported Burn Token Types:

  • ERC-20
  • ERC-721
  • ERC-1155


  • Multi Token Types in a Single Redemption
  • ETH Payment Option
  • Supports Specific TokenId Ranges
  • ETH Payments

Source Code

Factory Contract#

For security reasons, each Zora 1155 contract needs to have a unique burn to redeem minter deployed for it. Meaning, that the factory contract must be called to create a unique burn to redeem minter for each 1155 creator contract.

Checking if a Minter has been deployed#

Before deploying a minter for an 1155, it is possible to check and see if one has been deployed or not by calling the contract.

getDeployedRedeemMinterForCreatorContract returns an address based on if a B2R minter contract has been deployed for a specific 1155 contract. The function will return error if no contract has been deployed.

function getDeployedRedeemMinterForCreatorContract(    address _creatorContract ) external view returns (address) 

doesRedeemMinterExistForCreatorContract returns a bool based on if a contract has been deployed when given the creator's 1155 contract address.

function doesRedeemMinterExistForCreatorContract(    address _creatorContract) public view returns (bool) 

predictMinterAddress returns the address that the b2r minter will be deployed to when given the creator's 1155 contract address.

function predictMinterAddress(    address _creatorContract) public view returns (address)

Deploying the Minter#

Deploying a minter is done by calling the callSale function on the 1155 contract.

The factory uses CREATE2 to generate the B2R contract addresses. This means the address of the deployment can be known ahead of time by calling predictMinterAddress with the 1155 address.

The following can be done in a single transaction using multi-call. The data structure for REDEEM_INSTRUCTIONS can be found here.

Multi-call if the B2R contract hasn't been deployed, but 1155 contract has:

  1. setPermissions(REDEMPTION_MINTER_FACTORY, MINTER): Give permission to the factory.
  2. callSale(REDEMPTION_MINTER_FACTORY, abi.encode(createMinter)): Use the callSale function on the 1155 contract.
    • target.callSale(0, minterFactory, abi.encodeWithSelector(ZoraCreatorRedeemMinterFactoryImpl.createMinter.selector));
  3. clearPermissions(REDEMPTION_MINTER_FACTORY, NONE): Remove permission.
  4. setPermissions(REDEMPTION_MINTER_CONTRACT, MINTER): Give permission to the minter.
  5. callSale(REDEMPTION_MINTER_CONTRACT, abi.encode(setRedeem, {REDEEM_INSTRUCTIONS}): Use callSale on the 1155 to set up a redemption.

Multi-call if the B2R contract has been deployed and already has minter permissions:


Redeem Minter#

Each 1155 contract must have its own deployed burn to redeem minter contract.

Redeeming a Token#

Before a token can be redeemed all the tokens that will be burned must be approved to the specific burn to redeem contract. Once approved, then the user can call the mint function on the 1155 contract to burn their tokens in exchange for the redeem token. The data structure for the instructions and args can be found below.

mint(    REDEMPTION_MINTER_CONTRACT,     tokenId, // Mint Token    quantity, // Mint Amount    abi.encode(        MINT_TO_ADDRESS,         REDEEM_INSTRUCTIONS,         REDEEM_ARGS    ))

Updating a Redemption#

There is no update function within the burn to redeem minter. This means updating requires that a user clear their previous redeem and set a new one. Note, that the clearRedeem function takes in a hash of the instructions.

callSale(    REDEMPTION_MINTER_CONTRACT,     abi.encode(clearRedeem({REDEEM_INSTRUCTIONS_HASH})))
callSale(    REDEMPTION_MINTER_CONTRACT,     abi.encode(setRedeem({REDEEM_INSTRUCTIONS})))

Data Structures#

Redeem Instructions#

Instructions are set when the creator decides on the burn-to-redeem options.

enum RedeemTokenType {  NULL,  ERC721,  ERC1155,  ERC20,}
enum ZoraCreatePermissions {  NONE = 0,  ADMIN = 2 ** 1,  MINTER = 2 ** 2,}
type RedeemInstruction = {  tokenType: RedeemTokenType  amount: BigNumber  tokenIdStart: BigNumber  tokenIdEnd: BigNumber  tokenContract: `0x${string}`  transferRecipient: `0x${string}`  burnFunction: `0x${string}`}
type RedeemMinterConfig = {  mintToken: {    tokenContract: `0x${string}`    tokenId: BigNumber    amount: BigNumber    tokenType: RedeemTokenType  }  instructions: RedeemInstruction[]  saleStart: BigNumber  saleEnd: BigNumber  ethAmount: BigNumber  ethRecipient: `0x${string}`}