// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.18; import "./SmartAssetURIStorage.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "../Interfaces/ISmartAssetURIStorageOverridable.sol"; /** * @title SmartAssetURIStorageOverridable. * @author Arianee - Dynamic NFTs for real-world use cases and consumer engagement (www.arianee.org). */ abstract contract SmartAssetURIStorageOverridable is SmartAssetURIStorage, ERC721URIStorage, ISmartAssetURIStorageOverridable { /** * @notice HYDRATE_OTHER_PARAM_INDEX_TOKEN_URI: the index of tokenURI in the otherParams array of the hydrateToken function. * NOTE: This index must be unique across all contracts that inherit from SmartAssetBase. */ uint256 public constant HYDRATE_OTHER_PARAM_INDEX_TOKEN_URI = 0; /** * @notice This emits when a smart asset's URI is updated. */ event TokenURIUpdated(uint256 indexed tokenId, string newURI); constructor(string memory baseURI_) SmartAssetURIStorage(baseURI_) {} /** * @notice Set the URI for a given token ID. * @param newTokenURI The new token URI. */ function setTokenURI(uint256 tokenId, string memory newTokenURI) public isIssuer(tokenId) { super._setTokenURI(tokenId, newTokenURI); emit TokenURIUpdated(tokenId, tokenURI(tokenId)); } /** * @dev See {SmartAssetBase-hydrateToken} */ function hydrateToken(TokenHydratationParams memory tokenHydratationParams) public virtual override onlyRole(MINTER_ROLE) whenNotPaused { uint256 tokenId = tokenHydratationParams.tokenId; require( tokenHydratationParams.otherParams.length > HYDRATE_OTHER_PARAM_INDEX_TOKEN_URI, "SmartAssetRecoverable: HYDRATE_OTHER_PARAM_INDEX_TOKEN_URI is missing" ); bytes memory newTokenURIBytes = tokenHydratationParams.otherParams[HYDRATE_OTHER_PARAM_INDEX_TOKEN_URI]; string memory newTokenURI = string(newTokenURIBytes); super.hydrateToken(tokenHydratationParams); setTokenURI(tokenId, newTokenURI); } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override(ERC721URIStorage, ERC721) returns (string memory) { return super.tokenURI(tokenId); } /** * @dev See {ERC721-_burn}. */ function _burn(uint256 tokenId) internal virtual override(ERC721URIStorage, ERC721) { super._burn(tokenId); } /** * @dev See {SmartAssetBase-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId, uint256 batchSize ) internal virtual override(SmartAssetBase, ERC721) whenNotPaused { super._beforeTokenTransfer(from, to, tokenId, batchSize); } /** * @dev See {SmartAssetBase-_transfer}. */ function _transfer(address from, address to, uint256 tokenId) internal virtual override(SmartAssetBase, ERC721) { super._transfer(from, to, tokenId); } /** * @dev See {SmartAssetURIStorage-_baseURI} */ function _baseURI() internal view virtual override(SmartAssetURIStorage, ERC721) returns (string memory) { return super._baseURI(); } /** * @dev See {SmartAssetBase-_afterTokenTransfer}. */ function _afterTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal virtual override(SmartAssetBase, ERC721) { SmartAssetBase._afterTokenTransfer(from, to, tokenId, batchSize); } /** * @dev See {SmartAssetBase-_msgSender}. */ function _msgSender() internal view virtual override(SmartAssetBase, Context) returns (address) { return SmartAssetBase._msgSender(); } /** * @dev See {SmartAssetBase-_msgData}. */ function _msgData() internal view virtual override(SmartAssetBase, Context) returns (bytes calldata) { return SmartAssetBase._msgData(); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(SmartAssetURIStorage, ERC721) returns (bool) { return interfaceId == type(ISmartAssetURIStorageOverridable).interfaceId || super.supportsInterface(interfaceId); } }