ERC721Facet
This core facet manages the ERC721 token functionality for staking position tokens within the staking platform (Staking Diamond).
_This contract is responsible for minting, transferring, and managing the staking position tokens
represented by ERC721 NFTs. Each token uniquely identifies a user's position in a staking campaign,
allowing them to manage the respective position and claim rewards based on their stake (see StakingSkeleton.sol).
The staking position tokens can be configured to be soulbound, meaning they cannot be transferred once minted. This ensures that ownership is retained by the user until they decide to exit the staking campaign. The soulbound property is not applied by default; it can be set during the initialization of the ERC721 facet._
OnlyAdminCanInitialize
Thrown when a non-admin account attempts to call restricted initialization functions.
AlreadyInitialized
Thrown when attempting to re-initialize.
TransferOperationNotSupported
Thrown when token is configured as non-transferable and a transfer operation is attempted.
OnlyDiamondCanMintInternally
Thrown when the mint function is called by an address other than the diamond contract itself.
OnlyDiamondCanBurnInternally
Thrown when the burn function is called by an address other than the diamond contract itself.
ERC721FacetInitialized
Emitted at initErc721Facet().
initErc721Facet
Initializes the ERC721 facet by setting the name, symbol, and baseURI
for the staking position token collection.
_This function configures a dedicated storage slot within the Diamond’s storage structure
(see ERC721FacetStorage.sol).
It should only be called once to set up the initial configuration of the ERC721 facet.
The baseURI_ should end with a / symbol for proper token URI generation.
This function can only be called by the Admin (see AccessControlStakingFacet.sol).
Emits an {ERC721FacetInitialized} event._
Parameters
| Name | Type | Description |
|---|---|---|
| initErc721FacetData | bytes | The ABI-encoded data containing the following: - name_ The name (string) of the staking position token collection. - symbol_ The symbol (string) representing the staking position token collection. - baseURI_ The base URI (string) for token metadata, providing a common root for all token metadata URIs. - isTransferable_ A boolean flag indicating whether the staking position token collection is soulbound. |
balanceOf
See {IERC721-balanceOf}.
ownerOf
See {IERC721-ownerOf}.
name
Retrieves the name of the ERC721 staking position token collection.
symbol
Retrieves the symbol of the ERC721 staking position token collection.
tokenURI
Retrieves the Uniform Resource Identifier (URI) for the tokenId staking position token.
Returns the concatenation of baseURI and tokenId if baseURI is set;
otherwise, returns an empty string.
Parameters
| Name | Type | Description |
|---|---|---|
| tokenId | uint256 | The ID of the staking position token. |
Return Values
| Name | Type | Description |
|---|---|---|
| [0] | string | string The URI of the specified token. |
_baseURI
Returns the baseURI used for generating the Uniform Resource Identifiers (URIs) of the tokens.
Return Values
| Name | Type | Description |
|---|---|---|
| [0] | string | string The base URI for token metadata. |
approve
See {IERC721-approve}.
getApproved
See {IERC721-getApproved}.
setApprovalForAll
See {IERC721-setApprovalForAll}.
isApprovedForAll
See {IERC721-isApprovedForAll}.
transferFrom
See {IERC721-transferFrom}.
If the staking position token collection is soulbound (i.e., non-transferable), this operation is disabled.
safeTransferFrom
See {IERC721-safeTransferFrom}.
If the staking position token collection is soulbound (i.e., non-transferable), this operation is disabled.
safeTransferFrom
See {IERC721-safeTransferFrom}.
If the staking position token collection is soulbound (i.e., non-transferable), this operation is disabled.
_ownerOf
_Returns the owner of the tokenId. Does NOT revert if the token doesn't exist.
IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
core ERC-721 logic MUST be matched with the use of {_increaseBalance} to keep balances
consistent with ownership. The invariant to preserve is that for any address a the value
returned by balanceOf(a) must be equal to the number of tokens such that _ownerOf(tokenId) is a._
_getApproved
Returns the approved address for tokenId. Returns 0 if tokenId is not minted.
_isAuthorized
_Returns whether spender is allowed to manage owner's tokens, or tokenId in
particular (ignoring whether it is owned by owner).
WARNING: This function assumes that owner is the actual owner of tokenId and does not verify this
assumption._
_checkAuthorized
_Checks if spender can operate on tokenId, assuming the provided owner is the actual owner.
Reverts if:
spenderdoes not have approval fromownerfortokenId.spenderdoes not have approval to manage all ofowner's assets.
WARNING: This function assumes that owner is the actual owner of tokenId and does not verify this
assumption._
_increaseBalance
_Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
WARNING: Increasing an account's balance using this function tends to be paired with an override of the
{_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
remain consistent with one another._
_update
_Transfers tokenId from its current owner to to, or alternatively mints (or burns) if the current owner
(or to) is the zero address. Returns the owner of the tokenId before the update.
The auth argument is optional. If the value passed is non 0, then this function will check that
auth is either the owner of the token, or approved to operate on the token (by the owner).
Emits a {Transfer} event.
NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}._
mint
Mints a staking position token with the specified tokenId to the address to.
Only the Staking Diamond contract can mint staking position NFT tokens.
Parameters
| Name | Type | Description |
|---|---|---|
| to | address | The address that will receive the staking position token. |
| tokenId | uint256 | The ID of the staking position token to mint. |
_mint
_Mints tokenId and transfers it to to.
WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
Requirements:
tokenIdmust not exist.tocannot be the zero address.
Emits a {Transfer} event._
_safeMint
_Mints tokenId, transfers it to to and checks for to acceptance.
Requirements:
tokenIdmust not exist.- If
torefers to a smart contract, it must implement{IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
Emits a {Transfer} event._
_safeMint
Same as {xref-ERC721-_safeMint-address-uint256-}[_safeMint], with an additional data parameter which is
forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
burn
Burns tokenId token.
Only the Staking Diamond contract can burn staking position NFT tokens.
Parameters
| Name | Type | Description |
|---|---|---|
| tokenId | uint256 | The ID of the staking position token to be burned. |
_burn
_Destroys tokenId.
The approval is cleared when the token is burned.
This is an internal function that does not check if the sender is authorized to operate on the token.
Requirements:
tokenIdmust exist.
Emits a {Transfer} event._
_transfer
_Transfers tokenId from from to to.
As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
Requirements:
tocannot be the zero address.tokenIdtoken must be owned byfrom.
Emits a {Transfer} event._
_safeTransfer
_Safely transfers tokenId token from from to to, checking that contract recipients
are aware of the ERC-721 standard to prevent tokens from being forever locked.
data is additional data, it has no specified format and it is sent in call to to.
This internal function is like {safeTransferFrom} in the sense that it invokes
{IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
implement alternative mechanisms to perform token transfer, such as signature-based.
Requirements:
tokenIdtoken must exist and be owned byfrom.tocannot be the zero address.fromcannot be the zero address.- If
torefers to a smart contract, it must implement{IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
Emits a {Transfer} event._
_safeTransfer
Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[_safeTransfer], with an additional
data parameter which is forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
_approve
_Approve to to operate on tokenId
The auth argument is optional. If the value passed is non 0, then this function will check that auth is
either the owner of the token, or approved to operate on all tokens held by this owner.
Emits an {Approval} event.
Overrides to this logic should be done to the variant with an additional bool emitEvent argument._
_approve
Variant of _approve with an optional flag to enable or disable the {Approval} event. The event is not
emitted in the context of transfers.
_setApprovalForAll
_Approve operator to operate on all of owner tokens
Requirements:
- operator can't be the address zero.
Emits an {ApprovalForAll} event._
_requireOwned
_Reverts if the tokenId doesn't have a current owner (it hasn't been minted, or it has been burned).
Returns the owner.
Overrides to ownership logic should be done to {_ownerOf}._

