// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import {Diamond} from "@solarity/solidity-lib/diamond/Diamond.sol"; /** * @notice Structure representing metadata for an NFT. * @param commitment The commitment associated with the metadata (Merkle root). * @param tokenURI The URI of the token metadata. * @param isActive Boolean indicating whether the metadata is active. */ struct NftFMetadata { bytes32 commitment; string tokenURI; bool isActive; } /** * @notice The `NftF` contract * * The `NftF` is a Diamond-based ERC721 token implementation enabling the storage of all core contracts under the same Diamond proxy. * * The `NftF` provides flexibility for implementing eligibility checks through the integration of compliance modules without * affecting the standard ERC721 behaviour. * * Transfer methods forward the entire transfer context to compliance modules, ensuring adherence to specific requirements, * such as regulatory standards or KYC protocols. * * `NftF` is also inherited from `AgentAccessControl`, which is built on Solarity's `DiamondAccessControl`. * This inheritance allows to realise a rather flexible system of roles for controlling privileged functions in the whole system. */ interface INftF is IERC721Metadata { /** * @notice Structure representing a transfer context. * @param selector The function selector of the operation. * @param from The address sending the token. * @param to The address receiving the token. * @param tokenId The ID of the token being transferred. * @param operator The address executing the operation. * @param data Additional data associated with the transfer. */ struct Context { bytes4 selector; address from; address to; uint256 tokenId; address operator; bytes data; } /** * @notice Emitted when metadata is activated for a given token ID. * @param tokenId_ The ID of the token whose metadata was activated. */ event MetadataActivated(uint256 indexed tokenId_); /** * @notice Emitted when metadata is deactivated for a given token ID. * @param tokenId_ The ID of the token whose metadata was deactivated. */ event MetadataDeactivated(uint256 indexed tokenId_); /** * @notice Emitted when metadata is updated. * @param tokenId_ The ID of the token whose metadata was updated. * @param commitment_ The updated commitment value. * @param tokenURI_ The updated token URI. * @param isActive_ The updated active state. */ event MetadataUpdated( uint256 indexed tokenId_, bytes32 commitment_, string tokenURI_, bool isActive_ ); /** * @notice Function to create new `NftF` contract tokens. * * The `isKYCed` hook from the `KYCCompliance` contract is used inside the function to check KYC. * The `canTransfer` and `transferred` hooks are used to check the established regulatory rules * from `RegulatoryCompliance` contract * * This function can only be called by users who have a special role. * In the base version of `NftF` this role is the Agent role. * * To change the role used for access validation, * you need to override `_mintRole` according to the requirements of your business task. * * @param account_ The address to which tokens should be minted * @param commitment_ Merkle root * @param tokenId_ The tokenId to be minted * @param tokenURI The URI of the token */ function mint( address account_, bytes32 commitment_, uint256 tokenId_, string memory tokenURI ) external; /** * @notice Function to burn existing `NftF` contract tokens. * * The `isKYCed` hook from the `KYCCompliance` contract is used within the function to check KYC. * The `canTransfer` and `transferred` hooks are used to check the established regulatory rules * from the `RegulatoryCompliance` contract. * * This function can only be called by users who have a special role. * In the base version of `NftF` this role is the Agent role. * * To change the role used for access verification, * you must override `_burnRole` according to the requirements of your business task. * * @param account_ The address of the user whose balance you want to burn tokens from * @param tokenId_ The tokenId to be burned */ function burn(address account_, uint256 tokenId_) external; /** * @notice Function for forced transfering from one address to another. * * This logic may be needed for smart contracts that will operate with `NftF` tokens. * It will be convenient because users will not need to call `approve` function additionally. * * The `isKYCed` hook from the `KYCCompliance` contract is used inside the function to check KYC. * The `canTransfer` and `transferred` hooks are used to check the established regulatory rules * from `RegulatoryCompliance` contract. * * This function can only be called by users who have a special role. * In the base version of `NftF` this role is the Agent role. * * To change the role used for access verification, * you must override `_forcedTransferRole` according to the requirements of your business task. * * @param from_ The user address where the tokens will be transferred from * @param to_ The user address to whom tokens will be transferred * @param tokenId_ The tokenId to be transferred */ function forcedTransfer(address from_, address to_, uint256 tokenId_) external; /** * @notice Function for balance transfer from one account to another. * * This function can be useful if the user has lost the private key to his account. * In this case, the system can check the user's KYC and transfer the user's funds to a new account. * * The `isKYCed` hook from the `KYCCompliance` contract is used inside the function to check the KYC. * The `canTransfer` and `transferred` hooks are used to check the established regulatory rules * from `RegulatoryCompliance` contract. * * This function can only be called by users who have a special role. * In the base version of `NftF` this role is the Agent role. * * To change the role used for access verification, * you need to redefine `_recoveryRole` according to the requirements of your business task. * * @param oldAccount_ The address of the user's old account * @param newAccount_ The address of the new user account to which the tokens will be migrated */ function recovery(address oldAccount_, address newAccount_) external; /** * @notice Updates metadata for a given token. * @param tokenId_ The ID of the token whose metadata is being updated. * @param commitment_ The new commitment value. * @param _tokenURI The new token URI. */ function updateMetadata( uint256 tokenId_, bytes32 commitment_, string memory _tokenURI ) external; /** * @notice Toggles the activity status of metadata for a given token. * @param tokenId_ The ID of the token whose metadata activity is being changed. * @param isActive_ The new activity status. */ function switchMetadataActivity(uint256 tokenId_, bool isActive_) external; /** * @notice Toggles the transferability of the token. * @param isTransferable Boolean indicating whether transfers should be enabled or disabled. */ function switchTransferability(bool isTransferable) external; /** * @notice Verifies a metadata commitment using a Merkle proof. * @param tokenId_ The ID of the token whose metadata commitment is being verified. * @param proof_ The Merkle proof array. * @param leaf_ The Merkle leaf node. * @return Boolean indicating whether the proof is valid. */ function verifyMetadataCommitment( uint256 tokenId_, bytes32[] memory proof_, bytes32 leaf_ ) external view returns (bool); /** * @notice The function is required to manage the list of facets in a `NftF` contract. * It can be used to add, delete and update existing facets. * * This function can only be called by users who have a special role. * In the basic version of `NftF` this role is the Agent role. * * To change the role used for access validation, * you must override `_diamondCutRole` according to the requirements of your business task * * @param modules_ The array of modules to update */ function diamondCut(Diamond.Facet[] memory modules_) external; /** * @notice This function overloads another `diamondCut` function `NftF` of the contract, * allowing you to pass an additional calldata to call the necessary methods using `delegateCall` on the facet address. * Often this calldata is needed to call various init functions. * * This function can only be called by users who have a special role. * In the basic version of `NftF` this role is the Agent role. * * To change the role used for access validation, * you must override `_diamondCutRole` according to the requirements of your business task. * * @param modules_ The array of modules to update * @param initModule_ The address of the module to execute the passed caldata * @param initData_ The calldata to be executed */ function diamondCut( Diamond.Facet[] memory modules_, address initModule_, bytes memory initData_ ) external; }