ERC-721
Overview
Max Total Supply
1 OCEAN-NFT
Holders
1
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 OCEAN-NFTLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Minimal Proxy Contract for 0x4344d4bc29531db736378e9a3da85bf1eff0cb22
Contract Name:
ERC721Template
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.12; // Copyright BigchainDB GmbH and Ocean Protocol contributors // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) // Code is Apache-2.0 and docs are CC-BY-4.0 import "../interfaces/IERC721Template.sol"; import "../utils/ERC721/ERC721.sol"; import "../utils/ERC725/ERC725Ocean.sol"; import "../utils/ERC721/IERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Create2.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "../interfaces/IFactory.sol"; import "../interfaces/IERC20Template.sol"; import "../utils/ERC721RolesAddress.sol"; contract ERC721Template is ERC721("Template", "TemplateSymbol"), ERC721RolesAddress, ERC725Ocean, ReentrancyGuard { string private _name; string private _symbol; //uint256 private tokenId = 1; bool private initialized; bool public hasMetaData; string public metaDataDecryptorUrl; string public metaDataDecryptorAddress; uint8 public metaDataState; address private _tokenFactory; address[] private deployedERC20List; uint8 private constant templateId = 1; mapping(address => bool) private deployedERC20; bool public transferable; //stored here only for ABI reasons event TokenCreated( address indexed newTokenAddress, address indexed templateAddress, string name, string symbol, uint256 cap, address creator ); event MetadataCreated( address indexed createdBy, uint8 state, string decryptorUrl, bytes flags, bytes data, bytes32 metaDataHash, uint256 timestamp, uint256 blockNumber ); event MetadataUpdated( address indexed updatedBy, uint8 state, string decryptorUrl, bytes flags, bytes data, bytes32 metaDataHash, uint256 timestamp, uint256 blockNumber ); event MetadataValidated( address indexed validator, bytes32 metaDataHash, uint8 v, bytes32 r, bytes32 s ); event MetadataState( address indexed updatedBy, uint8 state, uint256 timestamp, uint256 blockNumber ); event TokenURIUpdate( address indexed updatedBy, string tokenURI, uint256 tokenID, uint256 timestamp, uint256 blockNumber ); modifier onlyNFTOwner() { require(msg.sender == ownerOf(1), "ERC721Template: not NFTOwner"); _; } /** * @dev initialize * Calls private _initialize function. Only if contract is not initialized. This function mints an NFT (tokenId=1) to the owner and add owner as Manager Role * @param owner NFT Owner * @param name_ NFT name * @param symbol_ NFT Symbol * @param tokenFactory NFT factory address * @param additionalERC20Deployer address of additionalERC20Deployer * @param additionalMetaDataUpdater address of additionalMetaDataUpdater * @param tokenURI tokenURI * @param transferable_ if set to false, this NFT is non-transferable @return boolean */ function initialize( address owner, string calldata name_, string calldata symbol_, address tokenFactory, address additionalERC20Deployer, address additionalMetaDataUpdater, string memory tokenURI, bool transferable_ ) external returns (bool) { require( !initialized, "ERC721Template: token instance already initialized" ); if(additionalERC20Deployer != address(0)) _addToCreateERC20List(additionalERC20Deployer); if(additionalMetaDataUpdater != address(0)) _addToMetadataList(additionalMetaDataUpdater); bool initResult = _initialize( owner, name_, symbol_, tokenFactory, tokenURI, transferable_ ); //register all erc721 interfaces registerAllInterfaces(); //register erc725 interfaces _registerInterface(_INTERFACE_ID_ERC725X); _registerInterface(_INTERFACE_ID_ERC725Y); return(initResult); } /** * @dev _initialize * Calls private _initialize function. Only if contract is not initialized. * This function mints an NFT (tokenId=1) to the owner * and add owner as Manager Role (Roles admin) * @param owner NFT Owner * @param name_ NFT name * @param symbol_ NFT Symbol * @param tokenFactory NFT factory address * @param tokenURI tokenURI for token 1 @return boolean */ function _initialize( address owner, string memory name_, string memory symbol_, address tokenFactory, string memory tokenURI, bool transferable_ ) internal returns (bool) { require( owner != address(0), "ERC721Template:: Invalid minter, zero address" ); _name = name_; _symbol = symbol_; _tokenFactory = tokenFactory; defaultBaseURI = ""; initialized = true; hasMetaData = false; transferable = transferable_; _safeMint(owner, 1); _addManager(owner); // we add the nft owner to all other roles (so that doesn't need to make multiple transactions) Roles storage user = permissions[owner]; user.updateMetadata = true; user.deployERC20 = true; user.store = true; // no need to push to auth since it has been already added in _addManager() _setTokenURI(1, tokenURI); return initialized; } /** * @dev setTokenURI * sets tokenURI for a tokenId * @param tokenId token ID * @param tokenURI token URI */ function setTokenURI(uint256 tokenId, string memory tokenURI) public { require(msg.sender == ownerOf(tokenId), "ERC721Template: not NFTOwner"); _setTokenURI(tokenId, tokenURI); emit TokenURIUpdate(msg.sender, tokenURI, tokenId, /* solium-disable-next-line */ block.timestamp, block.number); } /** * @dev setMetaDataState * Updates metadata state * @param _metaDataState metadata state */ function setMetaDataState(uint8 _metaDataState) public { require( permissions[msg.sender].updateMetadata, "ERC721Template: NOT METADATA_ROLE" ); metaDataState = _metaDataState; emit MetadataState(msg.sender, _metaDataState, /* solium-disable-next-line */ block.timestamp, block.number); } struct metaDataProof { address validatorAddress; uint8 v; // v of validator signed message bytes32 r; // r of validator signed message bytes32 s; // s of validator signed message } /** * @dev setMetaData * Creates or update Metadata for Aqua(emit event) Also, updates the METADATA_DECRYPTOR key * @param _metaDataState metadata state * @param _metaDataDecryptorUrl decryptor URL * @param _metaDataDecryptorAddress decryptor public key * @param flags flags used by Aquarius * @param data data used by Aquarius * @param _metaDataHash hash of clear data (before the encryption, if any) * @param _metadataProofs optional signatures of entitys who validated data (before the encryption, if any) */ function setMetaData(uint8 _metaDataState, string calldata _metaDataDecryptorUrl , string calldata _metaDataDecryptorAddress, bytes calldata flags, bytes calldata data,bytes32 _metaDataHash, metaDataProof[] memory _metadataProofs) external { require( permissions[msg.sender].updateMetadata, "ERC721Template: NOT METADATA_ROLE" ); _setMetaData(_metaDataState, _metaDataDecryptorUrl, _metaDataDecryptorAddress,flags, data,_metaDataHash, _metadataProofs); } function _setMetaData(uint8 _metaDataState, string calldata _metaDataDecryptorUrl , string calldata _metaDataDecryptorAddress, bytes calldata flags, bytes calldata data,bytes32 _metaDataHash, metaDataProof[] memory _metadataProofs) internal { metaDataState = _metaDataState; metaDataDecryptorUrl = _metaDataDecryptorUrl; metaDataDecryptorAddress = _metaDataDecryptorAddress; if(!hasMetaData){ emit MetadataCreated(msg.sender, _metaDataState, _metaDataDecryptorUrl, flags, data, _metaDataHash, /* solium-disable-next-line */ block.timestamp, block.number); hasMetaData = true; } else emit MetadataUpdated(msg.sender, metaDataState, _metaDataDecryptorUrl, flags, data, _metaDataHash, /* solium-disable-next-line */ block.timestamp, block.number); //check proofs and emit an event for each proof require(_metadataProofs.length <= 50, 'Too Many Proofs'); bytes memory prefix = "\x19Ethereum Signed Message:\n32"; for (uint256 i = 0; i < _metadataProofs.length; i++) { if(_metadataProofs[i].validatorAddress != address(0)){ bytes32 prefixedHash = keccak256(abi.encodePacked(prefix, _metaDataHash)); address signer = ecrecover(prefixedHash, _metadataProofs[i].v, _metadataProofs[i].r, _metadataProofs[i].s); require(signer == _metadataProofs[i].validatorAddress, "Invalid proof signer"); } emit MetadataValidated(_metadataProofs[i].validatorAddress, _metaDataHash, _metadataProofs[i].v, _metadataProofs[i].r, _metadataProofs[i].s); } } struct metaDataAndTokenURI { uint8 metaDataState; string metaDataDecryptorUrl; string metaDataDecryptorAddress; bytes flags; bytes data; bytes32 metaDataHash; uint256 tokenId; string tokenURI; metaDataProof[] metadataProofs; } /** * @dev setMetaDataAndTokenURI * Helper function to improve UX Calls setMetaData & setTokenURI * @param _metaDataAndTokenURI metaDataAndTokenURI struct */ function setMetaDataAndTokenURI(metaDataAndTokenURI calldata _metaDataAndTokenURI) external { require( permissions[msg.sender].updateMetadata, "ERC721Template: NOT METADATA_ROLE" ); _setMetaData(_metaDataAndTokenURI.metaDataState, _metaDataAndTokenURI.metaDataDecryptorUrl, _metaDataAndTokenURI.metaDataDecryptorAddress, _metaDataAndTokenURI.flags, _metaDataAndTokenURI.data, _metaDataAndTokenURI.metaDataHash, _metaDataAndTokenURI.metadataProofs); setTokenURI(_metaDataAndTokenURI.tokenId, _metaDataAndTokenURI.tokenURI); } /** * @dev getMetaData * Returns metaDataState, metaDataDecryptorUrl, metaDataDecryptorAddress */ function getMetaData() external view returns (string memory, string memory, uint8, bool){ return (metaDataDecryptorUrl, metaDataDecryptorAddress, metaDataState, hasMetaData); } /** * @dev createERC20 * ONLY user with deployERC20 permission (assigned by Manager) can call it Creates a new ERC20 datatoken. It also adds initial minting and fee management permissions to custom users. * @param _templateIndex ERC20Template index * @param strings refers to an array of strings * [0] = name * [1] = symbol * @param addresses refers to an array of addresses * [0] = minter account who can mint datatokens (can have multiple minters) * [1] = feeManager initial feeManager for this DT * [2] = publishing Market Address * [3] = publishing Market Fee Token * @param uints refers to an array of uints * [0] = cap_ the total ERC20 cap * [1] = publishing Market Fee Amount * @param bytess refers to an array of bytes * Currently not used, usefull for future templates @return ERC20 token address */ function createERC20( uint256 _templateIndex, string[] calldata strings, address[] calldata addresses, uint256[] calldata uints, bytes[] calldata bytess ) external nonReentrant returns (address ) { require( permissions[msg.sender].deployERC20, "ERC721Template: NOT ERC20DEPLOYER_ROLE" ); address token = IFactory(_tokenFactory).createToken( _templateIndex, strings, addresses, uints, bytess ); deployedERC20[token] = true; deployedERC20List.push(token); return token; } /** * @dev isERC20Deployer * @return true if the account has ERC20 Deploy role */ function isERC20Deployer(address account) external view returns (bool) { return permissions[account].deployERC20; } /** * @dev name * It returns the token name. * @return Datatoken name. */ function name() public view override returns (string memory) { return _name; } /** * @dev symbol * It returns the token symbol. * @return Datatoken symbol. */ function symbol() public view override returns (string memory) { return _symbol; } /** * @dev isInitialized * It checks whether the contract is initialized. * @return true if the contract is initialized. */ function isInitialized() external view returns (bool) { return initialized; } /** * @dev addManager * Only NFT Owner can add a new manager (Roles admin) * There can be multiple minters * @param _managerAddress new manager address */ function addManager(address _managerAddress) external onlyNFTOwner { _addManager(_managerAddress); } /** * @dev removeManager * Only NFT Owner can remove a manager (Roles admin) * There can be multiple minters * @param _managerAddress new manager address */ function removeManager(address _managerAddress) external onlyNFTOwner { _removeManager(_managerAddress); } /** * @notice Executes any other smart contract. Is only callable by the Manager. * * * @param _operation the operation to execute: CALL = 0; DELEGATECALL = 1; CREATE2 = 2; CREATE = 3; * @param _to the smart contract or address to interact with. * `_to` will be unused if a contract is created (operation 2 and 3) * @param _value the value of ETH to transfer * @param _data the call data, or the contract data to deploy **/ function executeCall( uint256 _operation, address _to, uint256 _value, bytes calldata _data ) external payable onlyManager { execute(_operation, _to, _value, _data); } /** * @dev setNewData * ONLY user with store permission (assigned by Manager) can call it This function allows to set any arbitrary key-value into the 725 standard * There can be multiple store updaters * @param _key key (see 725 for standard (keccak256)) Data keys, should be the keccak256 hash of a type name. e.g. keccak256('ERCXXXMyNewKeyType') is 0x6935a24ea384927f250ee0b954ed498cd9203fc5d2bf95c735e52e6ca675e047 * @param _value data to store at that key */ function setNewData(bytes32 _key, bytes calldata _value) external { require( permissions[msg.sender].store, "ERC721Template: NOT STORE UPDATER" ); setData(_key, _value); } /** * @dev setDataERC20 * ONLY callable FROM the ERC20Template and BY the corresponding ERC20Deployer This function allows to store data with a preset key (keccak256(ERC20Address)) into NFT 725 Store * @param _key keccak256(ERC20Address) see setData into ERC20Template.sol * @param _value data to store at that key */ function setDataERC20(bytes32 _key, bytes calldata _value) external { require( deployedERC20[msg.sender], "ERC721Template: NOT ERC20 Contract" ); setData(_key, _value); } /** * @dev cleanPermissions * Only NFT Owner can call it. * This function allows to remove all ROLES at erc721 level: * Managers, ERC20Deployer, MetadataUpdater, StoreUpdater * Permissions at erc20 level stay. */ function cleanPermissions() external onlyNFTOwner { _cleanPermissions(); //make sure that owner still has permissions _addManager(ownerOf(1)); } /** * @dev transferFrom * Used for transferring the NFT, can be used by an approved relayer Even if we only have 1 tokenId, we leave it open as arguments for being a standard ERC721 @param from nft owner @param to nft receiver @param tokenId tokenId (1) */ function transferFrom( address from, address to, uint256 tokenId ) external { require(transferable, "ERC721Template: Is non transferable"); require(tokenId == 1, "ERC721Template: Cannot transfer this tokenId"); _cleanERC20Permissions(getAddressLength(deployedERC20List)); _cleanPermissions(); _addManager(to); // we add the nft owner to all other roles (so that doesn't need to make multiple transactions) Roles storage user = permissions[to]; user.updateMetadata = true; user.deployERC20 = true; user.store = true; // no need to push to auth since it has been already added in _addManager() _transferFrom(from, to, tokenId); } /** * @dev safeTransferFrom * Used for transferring the NFT, can be used by an approved relayer Even if we only have 1 tokenId, we leave it open as arguments for being a standard ERC721 @param from nft owner @param to nft receiver @param tokenId tokenId (1) */ function safeTransferFrom(address from, address to,uint256 tokenId) external { require(transferable, "ERC721Template: Is non transferable"); require(tokenId == 1, "ERC721Template: Cannot transfer this tokenId"); _cleanERC20Permissions(getAddressLength(deployedERC20List)); _cleanPermissions(); _addManager(to); // we add the nft owner to all other roles (so that doesn't need to make multiple transactions) Roles storage user = permissions[to]; user.updateMetadata = true; user.deployERC20 = true; user.store = true; // no need to push to auth since it has been already added in _addManager() _safeTransferFrom(from, to, tokenId, ""); } /** * @dev getAddressLength * It returns the array lentgh @param array address array we want to get length * @return length */ function getAddressLength(address[] memory array) private pure returns (uint256) { return array.length; } /** * @dev _cleanERC20Permissions * Internal function used to clean permissions at ERC20 level when transferring the NFT @param length lentgh of the deployedERC20List */ function _cleanERC20Permissions(uint256 length) internal { for (uint256 i = 0; i < length; i++) { IERC20Template(deployedERC20List[i]).cleanFrom721(); } } /** * @dev getId * Return template id in case we need different ABIs. * If you construct your own template, please make sure to change the hardcoded value */ function getId() pure public returns (uint8) { return 1; } /** * @dev fallback function * this is a default fallback function in which receives * the collected ether. */ fallback() external payable {} /** * @dev receive function * this is a default receive function in which receives * the collected ether. */ receive() external payable {} /** * @dev withdrawETH * transfers all the accumlated ether the ownerOf */ function withdrawETH() external payable { payable(ownerOf(1)).transfer(address(this).balance); } function getTokensList() external view returns (address[] memory) { return deployedERC20List; } function isDeployed(address datatoken) external view returns (bool) { return deployedERC20[datatoken]; } function setBaseURI(string memory _baseURI) external onlyNFTOwner { defaultBaseURI = _baseURI; } }
pragma solidity 0.8.12; // Copyright BigchainDB GmbH and Ocean Protocol contributors // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) // Code is Apache-2.0 and docs are CC-BY-4.0 /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721Template { enum RolesType { Manager, DeployERC20, UpdateMetadata, Store } /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); event MetadataCreated( address indexed createdBy, uint8 state, string decryptorUrl, bytes flags, bytes data, string metaDataDecryptorAddress, uint256 timestamp, uint256 blockNumber ); event MetadataUpdated( address indexed updatedBy, uint8 state, string decryptorUrl, bytes flags, bytes data, string metaDataDecryptorAddress, uint256 timestamp, uint256 blockNumber ); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); function name() external view returns (string memory); function symbol() external view returns (string memory); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); function isERC20Deployer(address acount) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, * it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, * it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, * it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ // function safeTransferFrom( // address from, // address to, // uint256 tokenId, // bytes calldata data // ) external; function transferFrom(address from, address to) external; function initialize( address admin, string calldata name, string calldata symbol, address erc20Factory, address additionalERC20Deployer, address additionalMetaDataUpdater, string calldata tokenURI, bool transferable ) external returns (bool); struct Roles { bool manager; bool deployERC20; bool updateMetadata; bool store; } struct metaDataProof { address validatorAddress; uint8 v; // v of validator signed message bytes32 r; // r of validator signed message bytes32 s; // s of validator signed message } function getPermissions(address user) external view returns (Roles memory); function setDataERC20(bytes32 _key, bytes calldata _value) external; function setMetaData(uint8 _metaDataState, string calldata _metaDataDecryptorUrl , string calldata _metaDataDecryptorAddress, bytes calldata flags, bytes calldata data,bytes32 _metaDataHash, metaDataProof[] memory _metadataProofs) external; function getMetaData() external view returns (string memory, string memory, uint8, bool); function createERC20( uint256 _templateIndex, string[] calldata strings, address[] calldata addresses, uint256[] calldata uints, bytes[] calldata bytess ) external returns (address); function removeFromCreateERC20List(address _allowedAddress) external; function addToCreateERC20List(address _allowedAddress) external; function addToMetadataList(address _allowedAddress) external; function removeFromMetadataList(address _allowedAddress) external; function getId() pure external returns (uint8); }
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) import "@openzeppelin/contracts/utils/Context.sol"; import "./IERC721.sol"; import "./IERC721Metadata.sol"; import "./Address.sol"; import "./Strings.sol"; import "./IERC721Receiver.sol"; import "./IERC721Enumerable.sol"; import "./IERC721Receiver.sol"; import "./ERC165.sol"; import "./EnumerableSet.sol"; import "./EnumerableMap.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using Strings for uint256; using EnumerableSet for EnumerableSet.UintSet; using EnumerableMap for EnumerableMap.UintToAddressMap; // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; // Token name string private _name; // Token symbol string private _symbol; // baseURI string internal defaultBaseURI; // Mapping from holder address to their (enumerable) set of owned tokens mapping (address => EnumerableSet.UintSet) private _holderTokens; // Enumerable mapping from token ids to their owners EnumerableMap.UintToAddressMap private _tokenOwners; // Mapping from token ID to approved address mapping (uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping (address => mapping (address => bool)) private _operatorApprovals; // Optional mapping for token URIs mapping (uint256 => string) private _tokenURIs; /* * bytes4(keccak256('balanceOf(address)')) == 0x70a08231 * bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e * bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3 * bytes4(keccak256('getApproved(uint256)')) == 0x081812fc * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465 * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5 * bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde * * => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^ * 0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd */ bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd; /* * bytes4(keccak256('name()')) == 0x06fdde03 * bytes4(keccak256('symbol()')) == 0x95d89b41 * bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd * * => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f */ bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f; /* * bytes4(keccak256('totalSupply()')) == 0x18160ddd * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59 * bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7 * * => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63 */ bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor (string memory name_, string memory symbol_){ _name = name_; _symbol = symbol_; registerAllInterfaces(); } function registerAllInterfaces() internal { // register the supported interfaces to conform to ERC721 via ERC165 _registerInterface(_INTERFACE_ID_ERC721); _registerInterface(_INTERFACE_ID_ERC721_METADATA); _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _holderTokens[owner].length(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token"); } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { return _holderTokens[owner].at(index); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds return _tokenOwners.length(); } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { (uint256 tokenId, ) = _tokenOwners.at(index); return tokenId; } /** * @dev Returns the base URI set via {_setBaseURI}. This will be * automatically added as a prefix in {tokenURI} to each token's URI, or * to the token ID if no specific URI is set for that token ID. */ function baseURI() public view virtual returns (string memory) { return _baseURI(); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } else{ return _tokenURI; } } /** * @dev Base URI for computing {tokenURI}. Empty by default, can be overriden * in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return defaultBaseURI; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require(_msgSender() == owner || ERC721.isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function _transferFrom(address from, address to, uint256 tokenId) internal virtual { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function _safeTransferFrom(address from, address to, uint256 tokenId) internal virtual { _safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) internal virtual { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol 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 equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _tokenOwners.contains(tokenId); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || ERC721.isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * 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. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual { _mint(to, tokenId); require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev 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. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _holderTokens[owner].remove(tokenId); _tokenOwners.remove(tokenId); emit Transfer(owner, address(0), tokenId); } /** * @dev 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 by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _holderTokens[from].remove(tokenId); _holderTokens[to].add(tokenId); _tokenOwners.set(tokenId, to); emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { // solhint-disable-next-line no-inline-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity 0.8.12; // interfaces import "../../interfaces/IERC725X.sol"; import "../../interfaces/IERC725Y.sol"; import "../ERC721/ERC165.sol"; // libraries import "@openzeppelin/contracts/utils/Create2.sol"; import "solidity-bytes-utils/contracts/BytesLib.sol"; /** * @title ERC725 X / ERC725 Y executor * @dev Implementation of a contract module which provides the ability to call arbitrary functions at any other smart contract and itself, * including using `delegatecall`, as well creating contracts using `create` and `create2`. * This is the basis for a smart contract based account system, but could also be used as a proxy account system. * * `execute` MUST only be called by the owner of the contract set via ERC173. * * @author Fabian Vogelsteller <[email protected]> */ contract ERC725Ocean is ERC165, IERC725X, IERC725Y { bytes4 internal constant _INTERFACE_ID_ERC725X = 0x44c028fe; uint256 constant OPERATION_CALL = 0; uint256 constant OPERATION_DELEGATECALL = 1; uint256 constant OPERATION_CREATE2 = 2; uint256 constant OPERATION_CREATE = 3; bytes4 internal constant _INTERFACE_ID_ERC725Y = 0x2bd57b73; mapping(bytes32 => bytes) internal store; constructor() { _registerInterface(_INTERFACE_ID_ERC725X); _registerInterface(_INTERFACE_ID_ERC725Y); } /* Public functions */ /** * @notice Executes any other smart contract. Is only callable by the owner. * * * @param _operation the operation to execute: CALL = 0; DELEGATECALL = 1; CREATE2 = 2; CREATE = 3; * @param _to the smart contract or address to interact with. `_to` will be unused if a contract is created (operation 2 and 3) * @param _value the value of ETH to transfer * @param _data the call data, or the contract data to deploy */ function execute(uint256 _operation, address _to, uint256 _value, bytes calldata _data) internal { // emit event emit Executed(_operation, _to, _value, _data); uint256 txGas = gasleft() - 2500; // CALL if (_operation == OPERATION_CALL) { executeCall(_to, _value, _data, txGas); // DELEGATE CALL // TODO: risky as storage slots can be overridden, remove? // } else if (_operation == OPERATION_DELEGATECALL) { // address currentOwner = owner(); // executeDelegateCall(_to, _data, txGas); // // Check that the owner was not overridden // require(owner() == currentOwner, "Delegate call is not allowed to modify the owner!"); // CREATE } else if (_operation == OPERATION_CREATE) { performCreate(_value, _data); // CREATE2 } else if (_operation == OPERATION_CREATE2) { bytes32 salt = BytesLib.toBytes32(_data, _data.length - 32); bytes memory data = BytesLib.slice(_data, 0, _data.length - 32); address contractAddress = Create2.deploy(_value, salt, data); emit ContractCreated(contractAddress); } else { revert("Wrong operation type"); } } /* Internal functions */ // Taken from GnosisSafe // https://github.com/gnosis/safe-contracts/blob/development/contracts/base/Executor.sol function executeCall(address to, uint256 value, bytes memory data, uint256 txGas) internal returns (bool success) { // solium-disable-next-line security/no-inline-assembly assembly { success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0) } } // Taken from GnosisSafe // https://github.com/gnosis/safe-contracts/blob/development/contracts/base/Executor.sol function executeDelegateCall(address to, bytes memory data, uint256 txGas) internal returns (bool success) { // solium-disable-next-line security/no-inline-assembly assembly { success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0) } } // Taken from GnosisSafe // https://github.com/gnosis/safe-contracts/blob/development/contracts/libraries/CreateCall.sol function performCreate(uint256 value, bytes memory deploymentData) internal returns (address newContract) { // solium-disable-next-line security/no-inline-assembly assembly { newContract := create(value, add(deploymentData, 0x20), mload(deploymentData)) } require(newContract != address(0), "Could not deploy contract"); emit ContractCreated(newContract); } /* Public functions */ /** * @notice Gets data at a given `key` * @param _key the key which value to retrieve * @return _value The data stored at the key */ function getData(bytes32 _key) public view override virtual returns (bytes memory _value) { return store[_key]; } /** * @notice Sets data at a given `key` * @param _key the key which value to retrieve * @param _value the bytes to set. */ function setData(bytes32 _key, bytes calldata _value) internal virtual { store[_key] = _value; emit DataChanged(_key, _value); } }
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Create2.sol) pragma solidity ^0.8.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy( uint256 amount, bytes32 salt, bytes memory bytecode ) internal returns (address) { address addr; require(address(this).balance >= amount, "Create2: insufficient balance"); require(bytecode.length != 0, "Create2: bytecode length is zero"); assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); return addr; } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress( bytes32 salt, bytes32 bytecodeHash, address deployer ) internal pure returns (address) { bytes32 _data = keccak256(abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)); return address(uint160(uint256(_data))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
pragma solidity 0.8.12; // Copyright BigchainDB GmbH and Ocean Protocol contributors // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) // Code is Apache-2.0 and docs are CC-BY-4.0 interface IFactory { function createToken( uint256 _templateIndex, string[] calldata strings, address[] calldata addresses, uint256[] calldata uints, bytes[] calldata bytess ) external returns (address token); function erc721List(address ERC721address) external returns (address); function erc20List(address erc20dt) external view returns(bool); struct NftCreateData{ string name; string symbol; uint256 templateIndex; string tokenURI; bool transferable; address owner; } struct ErcCreateData{ uint256 templateIndex; string[] strings; address[] addresses; uint256[] uints; bytes[] bytess; } struct PoolData{ uint256[] ssParams; uint256[] swapFees; address[] addresses; } struct FixedData{ address fixedPriceAddress; address[] addresses; uint256[] uints; } struct DispenserData{ address dispenserAddress; uint256 maxTokens; uint256 maxBalance; bool withMint; address allowedSwapper; } function createNftWithErc20( NftCreateData calldata _NftCreateData, ErcCreateData calldata _ErcCreateData ) external returns (address , address); function createNftWithErc20WithPool( NftCreateData calldata _NftCreateData, ErcCreateData calldata _ErcCreateData, PoolData calldata _PoolData ) external returns (address, address , address); function createNftWithErc20WithFixedRate( NftCreateData calldata _NftCreateData, ErcCreateData calldata _ErcCreateData, FixedData calldata _FixedData ) external returns (address, address , bytes32 ); function createNftWithErc20WithDispenser( NftCreateData calldata _NftCreateData, ErcCreateData calldata _ErcCreateData, DispenserData calldata _DispenserData ) external returns (address, address); }
pragma solidity 0.8.12; // Copyright BigchainDB GmbH and Ocean Protocol contributors // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) // Code is Apache-2.0 and docs are CC-BY-4.0 interface IERC20Template { struct RolesERC20 { bool minter; bool feeManager; } struct providerFee{ address providerFeeAddress; address providerFeeToken; // address of the token marketplace wants to add fee on top uint256 providerFeeAmount; // amount to be transfered to marketFeeCollector uint8 v; // v of provider signed message bytes32 r; // r of provider signed message bytes32 s; // s of provider signed message uint256 validUntil; //validity expresses in unix timestamp bytes providerData; //data encoded by provider } struct consumeMarketFee{ address consumeMarketFeeAddress; address consumeMarketFeeToken; // address of the token marketplace wants to add fee on top uint256 consumeMarketFeeAmount; // amount to be transfered to marketFeeCollector } function initialize( string[] calldata strings_, address[] calldata addresses_, address[] calldata factoryAddresses_, uint256[] calldata uints_, bytes[] calldata bytes_ ) external returns (bool); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint256); function cap() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom( address from, address to, uint256 value ) external returns (bool); function mint(address account, uint256 value) external; function isMinter(address account) external view returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permissions(address user) external view returns (RolesERC20 memory); function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; function cleanFrom721() external; function deployPool( uint256[] memory ssParams, uint256[] memory swapFees, address[] memory addresses ) external returns (address); function createFixedRate( address fixedPriceAddress, address[] memory addresses, uint[] memory uints ) external returns (bytes32); function createDispenser( address _dispenser, uint256 maxTokens, uint256 maxBalance, bool withMint, address allowedSwapper) external; function getPublishingMarketFee() external view returns (address , address, uint256); function setPublishingMarketFee( address _publishMarketFeeAddress, address _publishMarketFeeToken, uint256 _publishMarketFeeAmount ) external; function startOrder( address consumer, uint256 serviceIndex, providerFee calldata _providerFee, consumeMarketFee calldata _consumeMarketFee ) external; function reuseOrder( bytes32 orderTxId, providerFee calldata _providerFee ) external; function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; function getERC721Address() external view returns (address); function isERC20Deployer(address user) external view returns(bool); function getPools() external view returns(address[] memory); struct fixedRate{ address contractAddress; bytes32 id; } function getFixedRates() external view returns(fixedRate[] memory); function getDispensers() external view returns(address[] memory); function getId() pure external returns (uint8); function getPaymentCollector() external view returns (address); }
pragma solidity 0.8.12; // Copyright BigchainDB GmbH and Ocean Protocol contributors // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) // Code is Apache-2.0 and docs are CC-BY-4.0 contract ERC721RolesAddress { mapping(address => Roles) internal permissions; address[] public auth; struct Roles { bool manager; bool deployERC20; bool updateMetadata; bool store; } enum RolesType { Manager, DeployERC20, UpdateMetadata, Store } /** * @dev getPermissions * Returns list of roles for an user * @param user user address */ function getPermissions(address user) public view returns (Roles memory) { return permissions[user]; } modifier onlyManager() { require( permissions[msg.sender].manager == true, "ERC721RolesAddress: NOT MANAGER" ); _; } event AddedTo725StoreList( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); event RemovedFrom725StoreList( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); /** * @dev addTo725StoreList * Adds store role to an user. * It can be called only by a manager * @param _allowedAddress user address */ function addTo725StoreList(address _allowedAddress) public onlyManager { if(_allowedAddress != address(0)){ Roles storage user = permissions[_allowedAddress]; user.store = true; _pushToAuth(_allowedAddress); emit AddedTo725StoreList(_allowedAddress,msg.sender,block.timestamp,block.number); } } /** * @dev removeFrom725StoreList * Removes store role from an user. * It can be called by a manager or by the same user, if he already has store role * @param _allowedAddress user address */ function removeFrom725StoreList(address _allowedAddress) public { if(permissions[msg.sender].manager == true || (msg.sender == _allowedAddress && permissions[msg.sender].store == true) ){ Roles storage user = permissions[_allowedAddress]; user.store = false; emit RemovedFrom725StoreList(_allowedAddress,msg.sender,block.timestamp,block.number); _SafeRemoveFromAuth(_allowedAddress); } else{ revert("ERC721RolesAddress: Not enough permissions to remove from 725StoreList"); } } event AddedToCreateERC20List( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); event RemovedFromCreateERC20List( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); /** * @dev addToCreateERC20List * Adds deployERC20 role to an user. * It can be called only by a manager * @param _allowedAddress user address */ function addToCreateERC20List(address _allowedAddress) public onlyManager { _addToCreateERC20List(_allowedAddress); } //it's only called internally, so is without checking onlyManager function _addToCreateERC20List(address _allowedAddress) internal { Roles storage user = permissions[_allowedAddress]; user.deployERC20 = true; _pushToAuth(_allowedAddress); emit AddedToCreateERC20List(_allowedAddress,msg.sender,block.timestamp,block.number); } /** * @dev removeFromCreateERC20List * Removes deployERC20 role from an user. * It can be called by a manager or by the same user, if he already has deployERC20 role * @param _allowedAddress user address */ function removeFromCreateERC20List(address _allowedAddress) public { if(permissions[msg.sender].manager == true || (msg.sender == _allowedAddress && permissions[msg.sender].deployERC20 == true) ){ Roles storage user = permissions[_allowedAddress]; user.deployERC20 = false; emit RemovedFromCreateERC20List(_allowedAddress,msg.sender,block.timestamp,block.number); _SafeRemoveFromAuth(_allowedAddress); } else{ revert("ERC721RolesAddress: Not enough permissions to remove from ERC20List"); } } event AddedToMetadataList( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); event RemovedFromMetadataList( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); /** * @dev addToMetadataList * Adds metadata role to an user. * It can be called only by a manager * @param _allowedAddress user address */ function addToMetadataList(address _allowedAddress) public onlyManager { _addToMetadataList(_allowedAddress); } //it's only called internally, so is without checking onlyManager function _addToMetadataList(address _allowedAddress) internal { if(_allowedAddress != address(0)){ Roles storage user = permissions[_allowedAddress]; user.updateMetadata = true; _pushToAuth(_allowedAddress); emit AddedToMetadataList(_allowedAddress,msg.sender,block.timestamp,block.number); } } /** * @dev removeFromMetadataList * Removes metadata role from an user. * It can be called by a manager or by the same user, if he already has metadata role * @param _allowedAddress user address */ function removeFromMetadataList(address _allowedAddress) public { if(permissions[msg.sender].manager == true || (msg.sender == _allowedAddress && permissions[msg.sender].updateMetadata == true) ){ Roles storage user = permissions[_allowedAddress]; user.updateMetadata = false; emit RemovedFromMetadataList(_allowedAddress,msg.sender,block.timestamp,block.number); _SafeRemoveFromAuth(_allowedAddress); } else{ revert("ERC721RolesAddress: Not enough permissions to remove from metadata list"); } } event AddedManager( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); event RemovedManager( address indexed user, address indexed signer, uint256 timestamp, uint256 blockNumber ); /** * @dev _addManager * Internal function to add manager role for an addres * @param _managerAddress user address */ function _addManager(address _managerAddress) internal { if(_managerAddress != address(0)){ Roles storage user = permissions[_managerAddress]; user.manager = true; _pushToAuth(_managerAddress); emit AddedManager(_managerAddress,msg.sender,block.timestamp,block.number); } } /** * @dev _removeManager * Internal function to clear the manager role for an addres * @param _managerAddress user address */ function _removeManager(address _managerAddress) internal { Roles storage user = permissions[_managerAddress]; user.manager = false; emit RemovedManager(_managerAddress,msg.sender,block.timestamp,block.number); _SafeRemoveFromAuth(_managerAddress); } event CleanedPermissions( address indexed signer, uint256 timestamp, uint256 blockNumber ); /** * @dev _cleanPermissions * Internal function to clear all existing permisions */ function _cleanPermissions() internal { for (uint256 i = 0; i < auth.length; i++) { Roles storage user = permissions[auth[i]]; user.manager = false; user.deployERC20 = false; user.updateMetadata = false; user.store = false; } delete auth; emit CleanedPermissions(msg.sender,block.timestamp,block.number); } /** * @dev addMultipleUsersToRoles * Add multiple users to multiple roles * @param addresses Array of addresses * @param roles Array of coresponding roles */ function addMultipleUsersToRoles(address[] memory addresses, RolesType[] memory roles) external onlyManager { require(addresses.length == roles.length && roles.length>0 && roles.length<50, "Invalid array size"); uint256 i; for(i=0; i<roles.length; i++){ if(addresses[i] != address(0)){ Roles storage user = permissions[addresses[i]]; if(roles[i] == RolesType.Manager) { user.manager = true; emit AddedManager(addresses[i],msg.sender,block.timestamp,block.number); } if(roles[i] == RolesType.DeployERC20) { user.deployERC20 = true; emit AddedToCreateERC20List(addresses[i],msg.sender,block.timestamp,block.number); } if(roles[i] == RolesType.UpdateMetadata) { user.updateMetadata = true; emit AddedToMetadataList(addresses[i],msg.sender,block.timestamp,block.number); } if(roles[i] == RolesType.Store) { user.store = true; emit AddedTo725StoreList(addresses[i],msg.sender,block.timestamp,block.number); } _pushToAuth(addresses[i]); } } } /** * @dev _pushToAuth * Checks auth array and adds the user address if does not exists * @param user address to be checked */ function _pushToAuth(address user) internal { uint256 i; for (i = 0; i < auth.length; i++) { if(auth[i] == user) break; } if(i == auth.length){ // element was not found auth.push(user); } } /** * @dev _SafeRemoveFromAuth * Checks if user has any roles left, and if not, it will remove it from auth array * @param user address to be checked and removed */ function _SafeRemoveFromAuth(address user) internal { Roles storage userRoles = permissions[user]; if (userRoles.manager == false && userRoles.deployERC20 == false && userRoles.updateMetadata == false && userRoles.store == false ){ uint256 i; for (i = 0; i < auth.length; i++) { if(auth[i] == user) break; } if(i < auth.length){ auth[i] = auth[auth.length -1]; auth.pop(); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; import "../ERC721/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/utils/[email protected]
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) /** * @dev String operations. */ library Strings { bytes16 private constant alphabet = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = alphabet[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // File @openzeppelin/contracts/token/ERC721/[email protected]
pragma solidity 0.8.12; // SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; import "../ERC721/IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts may inherit from this and call {_registerInterface} to declare * their support of an interface. */ abstract contract ERC165 is IERC165 { /* * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7 */ bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7; /** * @dev Mapping of interface ids to whether or not it's supported. */ mapping(bytes4 => bool) private _supportedInterfaces; constructor () { // Derived contracts need only register support for their own interfaces, // we register support for ERC165 itself here _registerInterface(_INTERFACE_ID_ERC165); } /** * @dev See {IERC165-supportsInterface}. * * Time complexity O(1), guaranteed to always use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return _supportedInterfaces[interfaceId]; } /** * @dev Registers the contract as an implementer of the interface defined by * `interfaceId`. Support of the actual ERC165 interface is automatic and * registering its interface id is not required. * * See {IERC165-supportsInterface}. * * Requirements: * * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`). */ function _registerInterface(bytes4 interfaceId) internal virtual { require(interfaceId != 0xffffffff, "ERC165: invalid interface id"); _supportedInterfaces[interfaceId] = true; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.12; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct MapEntry { bytes32 _key; bytes32 _value; } struct Map { // Storage of map keys and values MapEntry[] _entries; // Position of the entry defined by a key in the `entries` array, plus 1 // because index 0 means a key is not in the map. mapping (bytes32 => uint256) _indexes; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) { // Equivalent to !contains(map, key) map._entries.push(MapEntry({ _key: key, _value: value })); // The entry is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value map._indexes[key] = map._entries.length; return true; } else { map._entries[keyIndex - 1]._value = value; return false; } } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { // We read and store the key's index to prevent multiple reads from the same storage slot uint256 keyIndex = map._indexes[key]; if (keyIndex != 0) { // Equivalent to contains(map, key) // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one // in the array, and then remove the last entry (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = keyIndex - 1; uint256 lastIndex = map._entries.length - 1; // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. MapEntry storage lastEntry = map._entries[lastIndex]; // Move the last entry to the index where the entry to delete is map._entries[toDeleteIndex] = lastEntry; // Update the index for the moved entry map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved entry was stored map._entries.pop(); // Delete the index for the deleted slot delete map._indexes[key]; return true; } else { return false; } } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._indexes[key] != 0; } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._entries.length; } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { require(map._entries.length > index, "EnumerableMap: index out of bounds"); MapEntry storage entry = map._entries[index]; return (entry._key, entry._value); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { uint256 keyIndex = map._indexes[key]; if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key) return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) { uint256 keyIndex = map._indexes[key]; require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key) return map._entries[keyIndex - 1]._value; // All indexes are 1-based } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.12; /** * @dev Contract module which provides the ability to call arbitrary functions at any other smart contract and itself, * including using `delegatecall`, as well creating contracts using `create` and `create2`. * This is the basis for a smart contract based account system, but could also be used as a proxy account system. * * ERC 165 interface id: 0x44c028fe * * `execute` should only be callable by the owner of the contract set via ERC173. */ interface IERC725X /* is ERC165, ERC173 */ { /** * @dev Emitted when a contract is created. */ event ContractCreated(address indexed contractAddress); /** * @dev Emitted when a contract executed. */ event Executed(uint256 indexed _operation, address indexed _to, uint256 indexed _value, bytes _data); /** * @dev Executes any other smart contract. * SHOULD only be callable by the owner of the contract set via ERC173. * * Requirements: * * - `operationType`, the operation to execute. So far defined is: * CALL = 0; * DELEGATECALL = 1; * CREATE2 = 2; * CREATE = 3; * * - `data` the call data that will be used with the contract at `to` * * Emits a {ContractCreated} event, when a contract is created under `operationType` 2 and 3. */ // function execute(uint256 operationType, address to, uint256 value, bytes calldata data) internal payable; }
// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.12; /** * @title ERC725 Y data store * @dev Contract module which provides the ability to set arbitrary key value sets that can be changed over time. * It is intended to standardise certain keys value pairs to allow automated retrievals and interactions * from interfaces and other smart contracts. * * ERC 165 interface id: 0x2bd57b73 * * `setData` should only be callable by the owner of the contract set via ERC173. */ interface IERC725Y /* is ERC165, ERC173 */ { /** * @dev Emitted when data at a key is changed. */ event DataChanged(bytes32 indexed key, bytes value); /** * @dev Gets data at a given `key` */ function getData(bytes32 key) external view returns (bytes memory value); /** * @dev Sets data at a given `key`. * SHOULD only be callable by the owner of the contract set via ERC173. * * Emits a {DataChanged} event. */ // function setData(bytes32 key, bytes calldata value) internal; }
// SPDX-License-Identifier: Unlicense /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.8.0 <0.9.0; library BytesLib { function concat( bytes memory _preBytes, bytes memory _postBytes ) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // Store the length of the first bytes array at the beginning of // the memory for tempBytes. let length := mload(_preBytes) mstore(tempBytes, length) // Maintain a memory counter for the current write location in the // temp bytes array by adding the 32 bytes for the array length to // the starting location. let mc := add(tempBytes, 0x20) // Stop copying when the memory counter reaches the length of the // first bytes array. let end := add(mc, length) for { // Initialize a copy counter to the start of the _preBytes data, // 32 bytes into its memory. let cc := add(_preBytes, 0x20) } lt(mc, end) { // Increase both counters by 32 bytes each iteration. mc := add(mc, 0x20) cc := add(cc, 0x20) } { // Write the _preBytes data into the tempBytes memory 32 bytes // at a time. mstore(mc, mload(cc)) } // Add the length of _postBytes to the current length of tempBytes // and store it as the new length in the first 32 bytes of the // tempBytes memory. length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) // Move the memory counter back from a multiple of 0x20 to the // actual end of the _preBytes data. mc := end // Stop copying when the memory counter reaches the new combined // length of the arrays. end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } // Update the free-memory pointer by padding our last write location // to 32 bytes: add 31 bytes to the end of tempBytes to move to the // next 32 byte block, then round down to the nearest multiple of // 32. If the sum of the length of the two arrays is zero then add // one before rounding down to leave a blank 32 bytes (the length block with 0). mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) // Round down to the nearest 32 bytes. )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { // Read the first 32 bytes of _preBytes storage, which is the length // of the array. (We don't need to use the offset into the slot // because arrays use the entire slot.) let fslot := sload(_preBytes.slot) // Arrays of 31 bytes or less have an even value in their slot, // while longer arrays have an odd value. The actual length is // the slot divided by two for odd values, and the lowest order // byte divided by two for even values. // If the slot is even, bitwise and the slot with 255 and divide by // two to get the length. If the slot is odd, bitwise and the slot // with -1 and divide by two. let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage switch add(lt(slength, 32), lt(newlength, 32)) case 2 { // Since the new array still fits in the slot, we just need to // update the contents of the slot. // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length sstore( _preBytes.slot, // all the modifications to the slot are inside this // next block add( // we can just add to the slot contents because the // bytes we want to change are the LSBs fslot, add( mul( div( // load the bytes from memory mload(add(_postBytes, 0x20)), // zero all bytes to the right exp(0x100, sub(32, mlength)) ), // and now shift left the number of bytes to // leave space for the length in the slot exp(0x100, sub(32, newlength)) ), // increase length by the double of the memory // bytes length mul(mlength, 2) ) ) ) } case 1 { // The stored value fits in the slot, but the combined value // will exceed it. // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // The contents of the _postBytes array start 32 bytes into // the structure. Our first read should obtain the `submod` // bytes that can fit into the unused space in the last word // of the stored array. To get this, we read 32 bytes starting // from `submod`, so the data we read overlaps with the array // contents by `submod` bytes. Masking the lowest-order // `submod` bytes allows us to add that value directly to the // stored value. let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) // Start copying to the last used word of the stored array. let sc := add(keccak256(0x0, 0x20), div(slength, 32)) // save new length sstore(_preBytes.slot, add(mul(newlength, 2), 1)) // Copy over the first `submod` bytes of the new data as in // case 1 above. let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, "slice_overflow"); require(_bytes.length >= _start + _length, "slice_outOfBounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { require(_bytes.length >= _start + 1 , "toUint8_outOfBounds"); uint8 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x1), _start)) } return tempUint; } function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) { require(_bytes.length >= _start + 2, "toUint16_outOfBounds"); uint16 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x2), _start)) } return tempUint; } function toUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32) { require(_bytes.length >= _start + 4, "toUint32_outOfBounds"); uint32 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x4), _start)) } return tempUint; } function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) { require(_bytes.length >= _start + 8, "toUint64_outOfBounds"); uint64 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x8), _start)) } return tempUint; } function toUint96(bytes memory _bytes, uint256 _start) internal pure returns (uint96) { require(_bytes.length >= _start + 12, "toUint96_outOfBounds"); uint96 tempUint; assembly { tempUint := mload(add(add(_bytes, 0xc), _start)) } return tempUint; } function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) { require(_bytes.length >= _start + 16, "toUint128_outOfBounds"); uint128 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x10), _start)) } return tempUint; } function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) { require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) { require(_bytes.length >= _start + 32, "toBytes32_outOfBounds"); bytes32 tempBytes32; assembly { tempBytes32 := mload(add(add(_bytes, 0x20), _start)) } return tempBytes32; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) // if lengths don't match the arrays are not equal switch eq(length, mload(_postBytes)) case 1 { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { // if any of these checks fails then arrays are not equal if iszero(eq(mload(mc), mload(cc))) { // unsuccess: success := 0 cb := 0 } } } default { // unsuccess: success := 0 } } return success; } function equalStorage( bytes storage _preBytes, bytes memory _postBytes ) internal view returns (bool) { bool success = true; assembly { // we know _preBytes_offset is 0 let fslot := sload(_preBytes.slot) // Decode the length of the stored array like in concatStorage(). let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) // if lengths don't match the arrays are not equal switch eq(slength, mlength) case 1 { // slength can contain both the length and contents of the array // if length < 32 bytes so let's prepare for that // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { // blank the last byte which is the length fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { // unsuccess: success := 0 } } default { // cb is a circuit breaker in the for loop since there's // no said feature for inline assembly loops // cb = 1 - don't breaker // cb = 0 - break let cb := 1 // get the keccak hash to get the contents of the array mstore(0x0, _preBytes.slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) // the next line is the loop condition: // while(uint256(mc < end) + cb == 2) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { // unsuccess: success := 0 cb := 0 } } } } } default { // unsuccess: success := 0 } } return success; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"AddedManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"AddedTo725StoreList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"AddedToCreateERC20List","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"AddedToMetadataList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"CleanedPermissions","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"key","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"value","type":"bytes"}],"name":"DataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_operation","type":"uint256"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"uint256","name":"_value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"createdBy","type":"address"},{"indexed":false,"internalType":"uint8","name":"state","type":"uint8"},{"indexed":false,"internalType":"string","name":"decryptorUrl","type":"string"},{"indexed":false,"internalType":"bytes","name":"flags","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"metaDataHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"MetadataCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updatedBy","type":"address"},{"indexed":false,"internalType":"uint8","name":"state","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"MetadataState","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updatedBy","type":"address"},{"indexed":false,"internalType":"uint8","name":"state","type":"uint8"},{"indexed":false,"internalType":"string","name":"decryptorUrl","type":"string"},{"indexed":false,"internalType":"bytes","name":"flags","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"metaDataHash","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"MetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"bytes32","name":"metaDataHash","type":"bytes32"},{"indexed":false,"internalType":"uint8","name":"v","type":"uint8"},{"indexed":false,"internalType":"bytes32","name":"r","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"MetadataValidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"RemovedFrom725StoreList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"RemovedFromCreateERC20List","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"RemovedFromMetadataList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"signer","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"RemovedManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTokenAddress","type":"address"},{"indexed":true,"internalType":"address","name":"templateAddress","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"},{"indexed":false,"internalType":"uint256","name":"cap","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"TokenCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"updatedBy","type":"address"},{"indexed":false,"internalType":"string","name":"tokenURI","type":"string"},{"indexed":false,"internalType":"uint256","name":"tokenID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"TokenURIUpdate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_managerAddress","type":"address"}],"name":"addManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"enum ERC721RolesAddress.RolesType[]","name":"roles","type":"uint8[]"}],"name":"addMultipleUsersToRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"addTo725StoreList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"addToCreateERC20List","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"addToMetadataList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cleanPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_templateIndex","type":"uint256"},{"internalType":"string[]","name":"strings","type":"string[]"},{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"uints","type":"uint256[]"},{"internalType":"bytes[]","name":"bytess","type":"bytes[]"}],"name":"createERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_operation","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"executeCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getData","outputs":[{"internalType":"bytes","name":"_value","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getId","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getMetaData","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getPermissions","outputs":[{"components":[{"internalType":"bool","name":"manager","type":"bool"},{"internalType":"bool","name":"deployERC20","type":"bool"},{"internalType":"bool","name":"updateMetadata","type":"bool"},{"internalType":"bool","name":"store","type":"bool"}],"internalType":"struct ERC721RolesAddress.Roles","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokensList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasMetaData","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"tokenFactory","type":"address"},{"internalType":"address","name":"additionalERC20Deployer","type":"address"},{"internalType":"address","name":"additionalMetaDataUpdater","type":"address"},{"internalType":"string","name":"tokenURI","type":"string"},{"internalType":"bool","name":"transferable_","type":"bool"}],"name":"initialize","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"datatoken","type":"address"}],"name":"isDeployed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isERC20Deployer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metaDataDecryptorAddress","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metaDataDecryptorUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"metaDataState","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"removeFrom725StoreList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"removeFromCreateERC20List","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_allowedAddress","type":"address"}],"name":"removeFromMetadataList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_managerAddress","type":"address"}],"name":"removeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"setDataERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_metaDataState","type":"uint8"},{"internalType":"string","name":"_metaDataDecryptorUrl","type":"string"},{"internalType":"string","name":"_metaDataDecryptorAddress","type":"string"},{"internalType":"bytes","name":"flags","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes32","name":"_metaDataHash","type":"bytes32"},{"components":[{"internalType":"address","name":"validatorAddress","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct ERC721Template.metaDataProof[]","name":"_metadataProofs","type":"tuple[]"}],"name":"setMetaData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"metaDataState","type":"uint8"},{"internalType":"string","name":"metaDataDecryptorUrl","type":"string"},{"internalType":"string","name":"metaDataDecryptorAddress","type":"string"},{"internalType":"bytes","name":"flags","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes32","name":"metaDataHash","type":"bytes32"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenURI","type":"string"},{"components":[{"internalType":"address","name":"validatorAddress","type":"address"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct ERC721Template.metaDataProof[]","name":"metadataProofs","type":"tuple[]"}],"internalType":"struct ERC721Template.metaDataAndTokenURI","name":"_metaDataAndTokenURI","type":"tuple"}],"name":"setMetaDataAndTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_metaDataState","type":"uint8"}],"name":"setMetaDataState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"setNewData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenURI","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.