Skip to main content

JB721TiersHook

Git Source

Inherits: JBOwnable, ERC2771Context, JB721Hook, IJB721TiersHook

A Juicebox project can use this hook to sell tiered ERC-721 NFTs with different prices and metadata. When the project is paid, the hook may mint NFTs to the payer, depending on the hook's setup, the amount paid, and information specified by the payer. The project's owner can enable NFT cash outs through this hook, allowing holders to burn their NFTs to reclaim funds from the project (in proportion to the NFT's price).

State Variables

RULESETS

The contract storing and managing project rulesets.

IJBRulesets public immutable override RULESETS;

STORE

The contract that stores and manages data for this contract's NFTs.

IJB721TiersHookStore public immutable override STORE;

baseURI

The base URI for the NFT tokenUris.

string public override baseURI;

contractURI

This contract's metadata URI.

string public override contractURI;

payCreditsOf

If an address pays more than the price of the NFT they received, the extra amount is stored as credits which can be cashed out to mint NFTs.

mapping(address addr => uint256) public override payCreditsOf;

_firstOwnerOf

The first owner of each token ID, stored on first transfer out.

mapping(uint256 tokenId => address) internal _firstOwnerOf;

_packedPricingContext

Packed context for the pricing of this contract's tiers.

*Packed into a uint256:

  • currency in bits 0-31 (32 bits),
  • pricing decimals in bits 32-39 (8 bits), and
  • prices contract in bits 40-199 (160 bits).*
uint256 internal _packedPricingContext;

Functions

constructor

constructor(
IJBDirectory directory,
IJBPermissions permissions,
IJBRulesets rulesets,
IJB721TiersHookStore store,
address trustedForwarder
)
JBOwnable(permissions, directory.PROJECTS(), msg.sender, uint88(0))
JB721Hook(directory)
ERC2771Context(trustedForwarder);

Parameters

NameTypeDescription
directoryIJBDirectoryA directory of terminals and controllers for projects.
permissionsIJBPermissionsA contract storing permissions.
rulesetsIJBRulesetsA contract storing and managing project rulesets.
storeIJB721TiersHookStoreThe contract which stores the NFT's data.
trustedForwarderaddressThe trusted forwarder for the ERC2771Context.

firstOwnerOf

The first owner of an NFT.

This is generally the address which paid for the NFT.

function firstOwnerOf(uint256 tokenId) external view override returns (address);

Parameters

NameTypeDescription
tokenIduint256The token ID of the NFT to get the first owner of.

Returns

NameTypeDescription
<none>addressThe address of the NFT's first owner.

pricingContext

Context for the pricing of this hook's tiers.

If the prices contract is the zero address, this contract only accepts payments in the currency token.

function pricingContext() external view override returns (uint256 currency, uint256 decimals, IJBPrices prices);

Returns

NameTypeDescription
currencyuint256The currency used for tier prices.
decimalsuint256The amount of decimals being used in tier prices.
pricesIJBPricesThe prices contract used to resolve the value of payments in currencies other than currency.

balanceOf

The total number of this hook's NFTs that an address holds (from all tiers).

function balanceOf(address owner) public view override returns (uint256 balance);

Parameters

NameTypeDescription
owneraddressThe address to check the balance of.

Returns

NameTypeDescription
balanceuint256The number of NFTs the address owns across this hook's tiers.

initialize

Initializes a cloned copy of the original JB721Hook contract.

function initialize(
uint256 projectId,
string memory name,
string memory symbol,
string memory baseUri,
IJB721TokenUriResolver tokenUriResolver,
string memory contractUri,
JB721InitTiersConfig memory tiersConfig,
JB721TiersHookFlags memory flags
)
public
override;

Parameters

NameTypeDescription
projectIduint256The ID of the project this this hook is associated with.
namestringThe name of the NFT collection.
symbolstringThe symbol representing the NFT collection.
baseUristringThe URI to use as a base for full NFT tokenUris.
tokenUriResolverIJB721TokenUriResolverAn optional contract responsible for resolving the token URI for each NFT's token ID.
contractUristringA URI where this contract's metadata can be found.
tiersConfigJB721InitTiersConfigThe NFT tiers and pricing context to initialize the hook with. The tiers must be sorted by category (from least to greatest).
flagsJB721TiersHookFlagsA set of additional options which dictate how the hook behaves.

cashOutWeightOf

The combined cash out weight of the NFTs with the specified token IDs.

An NFT's cash out weight is its price.

To get their relative cash out weight, divide the result by the totalCashOutWeight(...).

function cashOutWeightOf(
uint256[] memory tokenIds,
JBBeforeCashOutRecordedContext calldata
)
public
view
virtual
override
returns (uint256);

Parameters

NameTypeDescription
tokenIdsuint256[]The token IDs of the NFTs to get the cumulative cash out weight of.
<none>JBBeforeCashOutRecordedContext

Returns

NameTypeDescription
<none>uint256weight The cash out weight of the tokenIds.

supportsInterface

Indicates if this contract adheres to the specified interface.

See IERC165-supportsInterface.

function supportsInterface(bytes4 interfaceId) public view override(IERC165, JB721Hook) returns (bool);

Parameters

NameTypeDescription
interfaceIdbytes4The ID of the interface to check for adherence to.

tokenURI

The metadata URI of the NFT with the specified token ID.

Defers to the tokenUriResolver if it is set. Otherwise, use the tokenUri corresponding with the NFT's tier.

function tokenURI(uint256 tokenId) public view virtual override returns (string memory);

Parameters

NameTypeDescription
tokenIduint256The token ID of the NFT to get the metadata URI of.

Returns

NameTypeDescription
<none>stringThe token URI from the tokenUriResolver if it is set. If it isn't set, the token URI for the NFT's tier.

totalCashOutWeight

The combined cash out weight of all outstanding NFTs.

An NFT's cash out weight is its price.

function totalCashOutWeight(JBBeforeCashOutRecordedContext calldata) public view virtual override returns (uint256);

Returns

NameTypeDescription
<none>uint256weight The total cash out weight.

_contextSuffixLength

ERC-2771 specifies the context as being a single address (20 bytes).

function _contextSuffixLength() internal view virtual override(ERC2771Context, Context) returns (uint256);

_currentRulesetOf

The project's current ruleset.

function _currentRulesetOf(uint256 projectId) internal view returns (JBRuleset memory);

Parameters

NameTypeDescription
projectIduint256The ID of the project to check.

Returns

NameTypeDescription
<none>JBRulesetThe project's current ruleset.

_msgData

Returns the calldata, prefered to use over msg.data

function _msgData() internal view override(ERC2771Context, Context) returns (bytes calldata);

Returns

NameTypeDescription
<none>bytescalldata the msg.data of this call

_msgSender

Returns the sender, prefered to use over msg.sender

function _msgSender() internal view override(ERC2771Context, Context) returns (address sender);

Returns

NameTypeDescription
senderaddressthe sender address of this call.

adjustTiers

Add or delete tiers.

Only the contract's owner or an operator with the ADJUST_TIERS permission from the owner can adjust the tiers.

Any added tiers must adhere to this hook's JB721TiersHookFlags.

function adjustTiers(JB721TierConfig[] calldata tiersToAdd, uint256[] calldata tierIdsToRemove) external override;

Parameters

NameTypeDescription
tiersToAddJB721TierConfig[]The tiers to add, as an array of JB721TierConfig structs`.
tierIdsToRemoveuint256[]The tiers to remove, as an array of tier IDs.

mintFor

Manually mint NFTs from the provided tiers .

function mintFor(
uint16[] calldata tierIds,
address beneficiary
)
external
override
returns (uint256[] memory tokenIds);

Parameters

NameTypeDescription
tierIdsuint16[]The IDs of the tiers to mint from.
beneficiaryaddressThe address to mint to.

Returns

NameTypeDescription
tokenIdsuint256[]The IDs of the newly minted tokens.

mintPendingReservesFor

Mint pending reserved NFTs based on the provided information.

"Pending" means that the NFTs have been reserved, but have not been minted yet.

function mintPendingReservesFor(JB721TiersMintReservesConfig[] calldata reserveMintConfigs) external override;

Parameters

NameTypeDescription
reserveMintConfigsJB721TiersMintReservesConfig[]Contains information about how many reserved tokens to mint for each tier.

setDiscountPercentOf

Allows the collection's owner to set the discount for a tier, if the tier allows it.

Only the contract's owner or an operator with the SET_721_DISCOUNT_PERCENT permission from the owner can adjust the tiers.

function setDiscountPercentOf(uint256 tierId, uint256 discountPercent) external override;

Parameters

NameTypeDescription
tierIduint256The ID of the tier to set the discount of.
discountPercentuint256The discount percent to set.

setDiscountPercentsOf

Allows the collection's owner to set the discount percent for multiple tiers.

function setDiscountPercentsOf(JB721TiersSetDiscountPercentConfig[] calldata configs) external override;

Parameters

NameTypeDescription
configsJB721TiersSetDiscountPercentConfig[]The configs to set the discount percent for.

setMetadata

Update this hook's URI metadata properties.

Only this contract's owner can set the metadata.

function setMetadata(
string calldata baseUri,
string calldata contractUri,
IJB721TokenUriResolver tokenUriResolver,
uint256 encodedIPFSTUriTierId,
bytes32 encodedIPFSUri
)
external
override;

Parameters

NameTypeDescription
baseUristringThe new base URI.
contractUristringThe new contract URI.
tokenUriResolverIJB721TokenUriResolverThe new URI resolver.
encodedIPFSTUriTierIduint256The ID of the tier to set the encoded IPFS URI of.
encodedIPFSUribytes32The encoded IPFS URI to set.

mintPendingReservesFor

Mint reserved pending reserved NFTs within the provided tier.

"Pending" means that the NFTs have been reserved, but have not been minted yet.

function mintPendingReservesFor(uint256 tierId, uint256 count) public override;

Parameters

NameTypeDescription
tierIduint256The ID of the tier to mint reserved NFTs from.
countuint256The number of reserved NFTs to mint.

_didBurn

A function which gets called after NFTs have been cashed out and recorded by the terminal.

function _didBurn(uint256[] memory tokenIds) internal virtual override;

Parameters

NameTypeDescription
tokenIdsuint256[]The token IDs of the NFTs that were burned.

_mintAll

Mints one NFT from each of the specified tiers for the beneficiary.

The same tier can be specified more than once.

function _mintAll(
uint256 amount,
uint16[] memory mintTierIds,
address beneficiary
)
internal
returns (uint256 leftoverAmount);

Parameters

NameTypeDescription
amountuint256The amount to base the mints on. The total price of the NFTs being minted cannot be larger than this amount.
mintTierIdsuint16[]An array of NFT tier IDs to be minted.
beneficiaryaddressThe address receiving the newly minted NFTs.

Returns

NameTypeDescription
leftoverAmountuint256The amount leftover after minting.

_processPayment

Process a payment, minting NFTs and updating credits as necessary.

function _processPayment(JBAfterPayRecordedContext calldata context) internal virtual override;

Parameters

NameTypeDescription
contextJBAfterPayRecordedContextPayment context provided by the terminal after it has recorded the payment in the terminal store.

_recordSetTokenUriResolver

Record the setting of a new token URI resolver.

function _recordSetTokenUriResolver(IJB721TokenUriResolver tokenUriResolver) internal;

Parameters

NameTypeDescription
tokenUriResolverIJB721TokenUriResolverThe new token URI resolver.

_setDiscountPercentOf

Internal function to set the discount percent for a tier.

function _setDiscountPercentOf(uint256 tierId, uint256 discountPercent) internal;

Parameters

NameTypeDescription
tierIduint256The ID of the tier to set the discount percent for.
discountPercentuint256The discount percent to set for the tier.

_update

Before transferring an NFT, register its first owner (if necessary).

function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address from);

Parameters

NameTypeDescription
toaddressThe address the NFT is being transferred to.
tokenIduint256The token ID of the NFT being transferred.
authaddress

Errors

JB721TiersHook_AlreadyInitialized

error JB721TiersHook_AlreadyInitialized(uint256 projectId);

JB721TiersHook_NoProjectId

error JB721TiersHook_NoProjectId();

JB721TiersHook_Overspending

error JB721TiersHook_Overspending(uint256 leftoverAmount);

JB721TiersHook_MintReserveNftsPaused

error JB721TiersHook_MintReserveNftsPaused();

JB721TiersHook_TierTransfersPaused

error JB721TiersHook_TierTransfersPaused();