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:
spender
does not have approval fromowner
fortokenId
.spender
does 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:
tokenId
must not exist.to
cannot be the zero address.
Emits a {Transfer}
event._
_safeMint
_Mints tokenId
, transfers it to to
and checks for to
acceptance.
Requirements:
tokenId
must not exist.- If
to
refers 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:
tokenId
must exist.
Emits a {Transfer}
event._
_transfer
_Transfers tokenId
from from
to to
.
As opposed to {transferFrom}
, this imposes no restrictions on msg.sender.
Requirements:
to
cannot be the zero address.tokenId
token 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:
tokenId
token must exist and be owned byfrom
.to
cannot be the zero address.from
cannot be the zero address.- If
to
refers 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}
._