Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 16972472 | 476 days ago | IN | Create: TokenStoreFacet | 0 ETH | 0.03486931 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TokenStoreFacet
Compiler Version
v0.8.1+commit.df193b15
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import "../../../diamond/IDiamondFacet.sol"; import "./TokenStoreInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk contract TokenStoreFacet is IDiamondFacet { function getFacetName() external pure override returns (string memory) { return "token-store"; } // CAUTION: Don't forget to update the version when adding new functionality function getFacetVersion() external pure override returns (string memory) { return "4.0.0"; } function getFacetPI() external pure override returns (string[] memory) { string[] memory pi = new string[](9); pi[0] = "getTokenStoreSettings()"; pi[1] = "setTokenStoreSettings(string,string,bool,string,string)"; pi[2] = "getTokenData(uint256)"; pi[3] = "setTokenData(uint256,string)"; pi[4] = "getTokenURI(uint256)"; pi[5] = "setTokenURI(uint256,string)"; pi[6] = "updateTokens(uint256[],string[],string[])"; pi[7] = "ownedTokens(address)"; pi[8] = "findToken(string)"; return pi; } function getFacetProtectedPI() external pure override returns (string[] memory) { string[] memory pi = new string[](4); pi[0] = "setTokenStoreSettings(string,string,bool,string,string)"; pi[1] = "setTokenData(uint256,string)"; pi[2] = "setTokenURI(uint256,string)"; pi[3] = "updateTokens(uint256[],string[],string[])"; return pi; } function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { return interfaceId == type(IDiamondFacet).interfaceId || interfaceId == type(IERC721Metadata).interfaceId; } function getTokenStoreSettings() external view returns ( string memory, string memory, bool, string memory, string memory ) { return TokenStoreInternal._getTokenStoreSettings(); } function setTokenStoreSettings( string memory baseTokenURI, string memory defaultTokenURI, bool useIdempotentTokenURIs, string memory idempotentTokenURIBase, string memory idempotentTokenURIExtension ) external { TokenStoreInternal._setTokenStoreSettings( baseTokenURI, defaultTokenURI, useIdempotentTokenURIs, idempotentTokenURIBase, idempotentTokenURIExtension ); } function getTokenData(uint256 tokenId) external view returns (string memory) { return TokenStoreInternal._getTokenData(tokenId); } function setTokenData( uint256 tokenId, string memory data ) external { TokenStoreInternal._setTokenData(tokenId, data); } function getTokenURI(uint256 tokenId) public view returns (string memory) { return TokenStoreInternal._getTokenURI(tokenId); } function setTokenURI( uint256 tokenId, string memory tokenURI ) external { return TokenStoreInternal._setTokenURI(tokenId, tokenURI); } function updateTokens( uint256[] memory tokenIds, string[] memory uris, string[] memory datas ) external { TokenStoreInternal._updateTokens( tokenIds, uris, datas ); } function ownedTokens(address account) external view returns (uint256[] memory tokens) { return TokenStoreInternal._ownedTokens(account); } function findToken(string memory evidence) external view returns (uint256) { return TokenStoreInternal._findToken(evidence); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.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); }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "@openzeppelin/contracts/interfaces/IERC165.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk interface IDiamondFacet is IERC165 { // NOTE: The override MUST remain 'pure'. function getFacetName() external pure returns (string memory); // NOTE: The override MUST remain 'pure'. function getFacetVersion() external pure returns (string memory); // NOTE: The override MUST remain 'pure'. function getFacetPI() external pure returns (string[] memory); // NOTE: The override MUST remain 'pure'. function getFacetProtectedPI() external pure returns (string[] memory); }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "@openzeppelin/contracts/utils/Strings.sol"; import "../erc721/ERC721Lib.sol"; import "./TokenStoreStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library TokenStoreInternal { event TokenURIChange(uint256 tokenId, string tokenURI); event TokenDataChange(uint256 tokenId, string data); function _getTokenStoreSettings() internal view returns ( string memory, string memory, bool, string memory, string memory ) { return ( __s().baseTokenURI, __s().defaultTokenURI, __s().useIdempotentTokenURIs, __s().idempotentTokenURIBase, __s().idempotentTokenURIExtension ); } function _setTokenStoreSettings( string memory baseTokenURI, string memory defaultTokenURI, bool useIdempotentTokenURIs, string memory idempotentTokenURIBase, string memory idempotentTokenURIExtension ) internal { __s().baseTokenURI = baseTokenURI; __s().defaultTokenURI = defaultTokenURI; __s().useIdempotentTokenURIs = useIdempotentTokenURIs; __s().idempotentTokenURIBase = idempotentTokenURIBase; __s().idempotentTokenURIExtension = idempotentTokenURIExtension; } function _getTokenURI(uint256 tokenId) internal view returns (string memory) { require(ERC721Lib._exists(tokenId), "TSI:NET"); if (__s().useIdempotentTokenURIs) { return string( abi.encodePacked( __s().idempotentTokenURIBase, Strings.toString(tokenId), __s().idempotentTokenURIExtension ) ); } string memory vTokenURI = __s().tokenInfos[tokenId].uri; if (bytes(vTokenURI).length == 0) { return __s().defaultTokenURI; } if (bytes(__s().baseTokenURI).length == 0) { return vTokenURI; } return string(abi.encodePacked(__s().baseTokenURI, vTokenURI)); } function _setTokenURI( uint256 tokenId, string memory tokenURI_ ) internal { require(ERC721Lib._exists(tokenId), "TSI:NET"); __s().tokenInfos[tokenId].uri = tokenURI_; emit TokenURIChange(tokenId, tokenURI_); // WARN: This will override the previous token if the same // uri is being used twice. __s().tokenIndex[keccak256(bytes(tokenURI_))] = tokenId; } function _getTokenData(uint256 tokenId) internal view returns (string memory) { require(ERC721Lib._exists(tokenId), "TSI:NET"); return __s().tokenInfos[tokenId].data; } function _setTokenData( uint256 tokenId, string memory data ) internal { require(ERC721Lib._exists(tokenId), "TSF:NET"); __s().tokenInfos[tokenId].data = data; emit TokenDataChange(tokenId, data); // WARN: This will override the previous token if the same // data is being used twice. __s().tokenIndex[keccak256(bytes(data))] = tokenId; } function _updateTokens( uint256[] memory tokenIds, string[] memory uris, string[] memory datas ) internal { require(tokenIds.length > 0, "M:NTU"); require(tokenIds.length == uris.length, "M:IL"); require(tokenIds.length == datas.length, "M:IL2"); for (uint256 i = 0; i < uris.length; i++) { _setTokenURI(tokenIds[i], uris[i]); _setTokenData(tokenIds[i], datas[i]); } } function _getRelatedTokens(address account) internal view returns (uint256[] memory) { return __s().relatedTokens[account]; } function _addToRelatedTokens(address account, uint256 tokenId) internal { __s().relatedTokens[account].push(tokenId); } function _ownedTokens(address account) internal view returns (uint256[] memory) { uint256 length = 0; if (account != address(0)) { for (uint256 i = 0; i < _getRelatedTokens(account).length; i++) { uint256 tokenId = _getRelatedTokens(account)[i]; if (ERC721Lib._exists(tokenId) && ERC721Lib._ownerOf(tokenId) == account) { length += 1; } } } uint256[] memory tokens = new uint256[](length); if (account != address(0)) { uint256 index = 0; for (uint256 i = 0; i < _getRelatedTokens(account).length; i++) { uint256 tokenId = _getRelatedTokens(account)[i]; if (ERC721Lib._exists(tokenId) && ERC721Lib._ownerOf(tokenId) == account) { tokens[index] = tokenId; index += 1; } } } return tokens; } function _deleteTokenInfo( uint256 tokenId ) internal { if (bytes(__s().tokenInfos[tokenId].uri).length != 0) { delete __s().tokenInfos[tokenId]; } } function _findToken(string memory evidence) internal view returns (uint256) { return __s().tokenIndex[keccak256(bytes(evidence))]; } function __s() private pure returns (TokenStoreStorage.Layout storage) { return TokenStoreStorage.layout(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/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 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @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: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "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] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./ERC721Internal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library ERC721Lib { function _setName(string memory name) internal { ERC721Internal._setName(name); } function _setSymbol(string memory symbol) internal { ERC721Internal._setSymbol(symbol); } function _exists(uint256 tokenId) internal view returns (bool) { return ERC721Internal._exists(tokenId); } function _ownerOf(uint256 tokenId) internal view returns (address) { return ERC721Internal._ownerOf(tokenId); } function _burn(uint256 tokenId) internal { ERC721Internal._burn(tokenId); } function _safeMint(address account, uint256 tokenId) internal { // TODO(kam): We don't have any safe mint in ERC721Internal ERC721Internal._mint(account, tokenId); } function _transfer(address from, address to, uint256 tokenId) internal { ERC721Internal._transfer(from, to, tokenId); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library TokenStoreStorage { struct TokenInfo { string uri; string data; } struct Layout { string baseTokenURI; string defaultTokenURI; bool useIdempotentTokenURIs; string idempotentTokenURIBase; string idempotentTokenURIExtension; mapping(uint256 => TokenInfo) tokenInfos; mapping(address => uint256[]) relatedTokens; // Mapping from hash(uri) and hash(data) to token ID mapping(bytes32 => uint256) tokenIndex; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.token-store.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "../token-store/TokenStoreLib.sol"; import "../minter/MinterLib.sol"; import "../reserve-manager/ReserveManagerLib.sol"; import "./ERC721Storage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library ERC721Internal { event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function _setERC721Settings( string memory name_, string memory symbol_, bool reserveZeroToken ) internal { _setName(name_); _setSymbol(symbol_); if (reserveZeroToken && !_exists(0)) { MinterLib._justMintTo(address(this)); ReserveManagerLib._initReserveManager(); } } function _getName() internal view returns (string memory) { return __s().name; } function _setName(string memory name) internal { __s().name = name; } function _getSymbol() internal view returns (string memory) { return __s().symbol; } function _setSymbol(string memory symbol) internal { __s().symbol = symbol; } function _balanceOf(address owner) internal view returns (uint256) { require(owner != address(0), "ERC721I:ZA"); return __s().balances[owner]; } function _ownerOf(uint256 tokenId) internal view returns (address) { address owner = __s().owners[tokenId]; require(owner != address(0), "ERC721I:NET"); return owner; } function _exists(uint256 tokenId) internal view returns (bool) { return __s().owners[tokenId] != address(0); } function _mint(address to, uint256 tokenId) internal { require(to != address(0), "ERC721I:MZA"); require(!_exists(tokenId), "ERC721I:TAM"); __s().balances[to] += 1; __s().owners[tokenId] = to; emit Transfer(address(0), to, tokenId); TokenStoreLib._addToRelatedTokens(to, tokenId); } function _burn(uint256 tokenId) internal { address owner = _ownerOf(tokenId); // Clear approvals delete __s().tokenApprovals[tokenId]; __s().balances[owner] -= 1; delete __s().owners[tokenId]; emit Transfer(owner, address(0), tokenId); } function _transfer( address from, address to, uint256 tokenId ) internal { require(_ownerOf(tokenId) == from, "ERC721I:IO"); require(to != address(0), "ERC721I:ZA"); _unsafeTransfer(from, to, tokenId); } function _transferFromMe( address to, uint256 tokenId ) internal { require(_ownerOf(tokenId) == address(this), "ERC721I:IO"); require(to != address(0), "ERC721I:ZA"); _unsafeTransfer(address(this), to, tokenId); } function _unsafeTransfer( address from, address to, uint256 tokenId ) internal { // Clear approvals from the previous owner delete __s().tokenApprovals[tokenId]; __s().balances[from] -= 1; __s().balances[to] += 1; __s().owners[tokenId] = to; emit Transfer(from, to, tokenId); TokenStoreLib._addToRelatedTokens(to, tokenId); } function _getApproved(uint256 tokenId) internal view returns (address) { require(_ownerOf(tokenId) != address(0), "ERC721I:NET"); return __s().tokenApprovals[tokenId]; } function _isApprovedForAll(address owner, address operator) internal view returns (bool) { return __s().operatorApprovals[owner][operator]; } function _isApprovedOrOwner( address spender, uint256 tokenId ) internal view returns (bool) { address owner = _ownerOf(tokenId); return ( spender == owner || __s().operatorApprovals[owner][spender] || __s().tokenApprovals[tokenId] == spender ); } function _approve(address to, uint256 tokenId) internal { __s().tokenApprovals[tokenId] = to; emit Approval(_ownerOf(tokenId), to, tokenId); } function _setApprovalForAll( address owner, address operator, bool approved ) internal { require(owner != operator, "ERC721I:ATC"); __s().operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } function __s() private pure returns (ERC721Storage.Layout storage) { return ERC721Storage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./TokenStoreInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library TokenStoreLib { function _getTokenURI(uint256 tokenId) internal view returns (string memory) { return TokenStoreInternal._getTokenURI(tokenId); } function _setTokenURI( uint256 tokenId, string memory tokenURI_ ) internal { TokenStoreInternal._setTokenURI(tokenId, tokenURI_); } function _setTokenData(uint256 tokenId, string memory data) internal { TokenStoreInternal._setTokenData(tokenId, data); } function _addToRelatedTokens(address account, uint256 tokenId) internal { TokenStoreInternal._addToRelatedTokens(account, tokenId); } function _deleteTokenInfo( uint256 tokenId ) internal { TokenStoreInternal._deleteTokenInfo(tokenId); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./MinterInternal.sol"; library MinterLib { function _justMintTo( address owner ) internal returns (uint256) { return MinterInternal._justMintTo(owner); } function _getTokenIdCounter() internal view returns (uint256) { return MinterInternal._getTokenIdCounter(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./ReserveManagerInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library ReserveManagerLib { function _initReserveManager() internal { ReserveManagerInternal._initReserveManager(); } function _reserveForAccount( address account, uint256 nrOfTokens, string memory paymentMethodName ) internal { ReserveManagerInternal._reserveForAccount( account, nrOfTokens, paymentMethodName ); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library ERC721Storage { // Members are copied from: // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol struct Layout { // Token name string name; // Token symbol string symbol; // Mapping from token ID to owner address mapping(uint256 => address) owners; // Mapping owner address to token count mapping(address => uint256) balances; // Mapping from token ID to approved address mapping(uint256 => address) tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) operatorApprovals; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.erc721.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "../token-store/TokenStoreLib.sol"; import "../royalty-manager/RoyaltyManagerLib.sol"; import "../payment-handler/PaymentHandlerLib.sol"; import "./MinterStorage.sol"; library MinterInternal { event PreMint(uint256 nrOfTokens); function _getMintSettings() internal view returns (bool, bool, uint256, uint256, uint256, uint256, uint256) { return ( __s().publicMinting, __s().directMintingAllowed, __s().mintFeeWei, __s().mintPriceWeiPerToken, __s().maxTokenId, __s().nrOfMints, __s().nrOfBurns ); } function _setMintSettings( bool publicMinting, bool directMintingAllowed, uint256 mintFeeWei, uint256 mintPriceWeiPerToken, uint256 maxTokenId ) internal { __s().publicMinting = publicMinting; __s().directMintingAllowed = directMintingAllowed; __s().mintFeeWei = mintFeeWei; __s().mintPriceWeiPerToken = mintPriceWeiPerToken; __s().maxTokenId = maxTokenId; } function _burn(uint256 tokenId) internal { ERC721Lib._burn(tokenId); TokenStoreLib._deleteTokenInfo(tokenId); __s().nrOfBurns += 1; } function _getTokenIdCounter() internal view returns (uint256) { return __s().tokenIdCounter; } function _justMintTo( address owner ) internal returns (uint256) { uint256 tokenId = __s().tokenIdCounter; require(__s().maxTokenId == 0 || tokenId <= __s().maxTokenId, "MI:MAX"); __s().tokenIdCounter += 1; if (owner == address(this)) { ERC721Lib._safeMint(msg.sender, tokenId); ERC721Lib._transfer(msg.sender, address(this), tokenId); } else { ERC721Lib._safeMint(address(this), tokenId); ERC721Lib._transfer(address(this), owner, tokenId); } __s().nrOfMints += 1; return tokenId; } function _preMint(uint256 nrOfTokens) internal { require(nrOfTokens > 0, "MI:ZT"); for (uint256 i = 1; i <= nrOfTokens; i++) { _justMintTo(address(this)); } emit PreMint(nrOfTokens); } function _mint( address[] memory owners, string[] memory uris, string[] memory datas, address[] memory royaltyWallets, uint256[] memory royaltyPercentages, bool handlePayment, string memory paymentMethodName ) internal { require(__s().directMintingAllowed, "MI:DMNA"); require(uris.length > 0, "MI:NTM"); require(datas.length == 0 || uris.length == datas.length, "MI:IL"); require(royaltyWallets.length == 0 || uris.length == royaltyWallets.length, "MI:IL2"); require(royaltyPercentages.length == 0 || uris.length == royaltyPercentages.length, "MI:IL3"); require(uris.length == owners.length, "MI:IL4"); if (handlePayment) { PaymentHandlerLib._handlePayment( 1, __s().mintFeeWei, uris.length, __s().mintPriceWeiPerToken, paymentMethodName ); } for (uint256 i = 0; i < uris.length; i++) { uint256 tokenId = __mintTo(owners[i], uris[i]); // Both royalty wallet and percentage must have sane values otherwise // the operator can always call other methods to set them. if ( royaltyWallets.length > 0 && royaltyPercentages.length > 0 && royaltyWallets[i] != address(0) && royaltyPercentages[i] > 0 ) { RoyaltyManagerLib._setTokenRoyaltyInfo( tokenId, royaltyWallets[i], royaltyPercentages[i]); } if (datas.length > 0) { TokenStoreLib._setTokenData(tokenId, datas[i]); } } } function __mintTo( address owner, string memory uri ) private returns (uint256) { uint256 tokenId = _justMintTo(owner); TokenStoreLib._setTokenURI(tokenId, uri); return tokenId; } function __s() private pure returns (MinterStorage.Layout storage) { return MinterStorage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./RoyaltyManagerInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library RoyaltyManagerLib { function _setTokenRoyaltyInfo( uint256 tokenId, address royaltyWallet, uint256 royaltyPercentage ) internal { RoyaltyManagerInternal._setTokenRoyaltyInfo( tokenId, royaltyWallet, royaltyPercentage ); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./PaymentHandlerInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library PaymentHandlerLib { function _handlePayment( uint256 nrOfItems1, uint256 priceWeiPerItem1, uint256 nrOfItems2, uint256 priceWeiPerItem2, string memory paymentMethodName ) internal { PaymentHandlerInternal._handlePayment( nrOfItems1, priceWeiPerItem1, nrOfItems2, priceWeiPerItem2, paymentMethodName ); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library MinterStorage { struct Layout { uint256 tokenIdCounter; bool publicMinting; bool directMintingAllowed; uint256 mintFeeWei; uint256 mintPriceWeiPerToken; uint256 maxTokenId; uint256 nrOfMints; uint256 nrOfBurns; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.minter.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "../erc721/ERC721Lib.sol"; import "./RoyaltyManagerStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library RoyaltyManagerInternal { event TokenRoyaltyInfoChanged( uint256 tokenId, address royaltyWallet, uint256 royaltyPercentage ); event TokenRoyaltyExempt( uint256 tokenId, bool exempt ); function _getDefaultRoyaltySettings() internal view returns (address, uint256) { return (__s().defaultRoyaltyWallet, __s().defaultRoyaltyPercentage); } // Either set address to zero or set percentage to zero to disable // default royalties. Still, royalties set per token work. function _setDefaultRoyaltySettings( address newDefaultRoyaltyWallet, uint256 newDefaultRoyaltyPercentage ) internal { __s().defaultRoyaltyWallet = newDefaultRoyaltyWallet; require( newDefaultRoyaltyPercentage >= 0 && newDefaultRoyaltyPercentage <= 100, "ROMI:WP" ); __s().defaultRoyaltyPercentage = newDefaultRoyaltyPercentage; } function _getTokenRoyaltyInfo(uint256 tokenId) internal view returns (address, uint256, bool) { require(ERC721Lib._exists(tokenId), "ROMI:NET"); return ( __s().tokenRoyalties[tokenId].royaltyWallet, __s().tokenRoyalties[tokenId].royaltyPercentage, __s().tokenRoyalties[tokenId].exempt ); } function _setTokenRoyaltyInfo( uint256 tokenId, address royaltyWallet, uint256 royaltyPercentage ) internal { require(ERC721Lib._exists(tokenId), "ROMI:NET"); require(royaltyPercentage >= 0 && royaltyPercentage <= 100, "ROMI:WP"); __s().tokenRoyalties[tokenId].royaltyWallet = royaltyWallet; __s().tokenRoyalties[tokenId].royaltyPercentage = royaltyPercentage; __s().tokenRoyalties[tokenId].exempt = false; emit TokenRoyaltyInfoChanged(tokenId, royaltyWallet, royaltyPercentage); } function _exemptTokenRoyalty(uint256 tokenId, bool exempt) internal { require(ERC721Lib._exists(tokenId), "ROMI:NET"); __s().tokenRoyalties[tokenId].exempt = exempt; emit TokenRoyaltyExempt(tokenId, exempt); } function _getRoyaltyInfo( uint256 tokenId, uint256 salePrice ) internal view returns (address, uint256) { require(ERC721Lib._exists(tokenId), "ROMI:NET"); RoyaltyManagerStorage.TokenRoyaltyInfo memory tokenRoyaltyInfo = __s().tokenRoyalties[tokenId]; if (tokenRoyaltyInfo.exempt) { return (address(0), 0); } address royaltyWallet = tokenRoyaltyInfo.royaltyWallet; uint256 royaltyPercentage = tokenRoyaltyInfo.royaltyPercentage; if (royaltyWallet == address(0) || royaltyPercentage == 0) { royaltyWallet = __s().defaultRoyaltyWallet; royaltyPercentage = __s().defaultRoyaltyPercentage; } if (royaltyWallet == address(0) || royaltyPercentage == 0) { return (address(0), 0); } uint256 royalty = (salePrice * royaltyPercentage) / 100; return (royaltyWallet, royalty); } function __s() private pure returns (RoyaltyManagerStorage.Layout storage) { return RoyaltyManagerStorage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library RoyaltyManagerStorage { struct TokenRoyaltyInfo { address royaltyWallet; uint256 royaltyPercentage; bool exempt; } struct Layout { address defaultRoyaltyWallet; uint256 defaultRoyaltyPercentage; mapping(uint256 => TokenRoyaltyInfo) tokenRoyalties; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.royalty-manager.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "../../IUniswapV2Pair.sol"; import "../payment-method-manager/PaymentMethodManagerLib.sol"; import "./PaymentHandlerStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library PaymentHandlerInternal { bytes32 constant public WEI_PAYMENT_METHOD_HASH = keccak256(abi.encode("WEI")); event TransferTo( address to, uint256 amount, string data ); event TransferETH20To( string paymentMethodName, address to, uint256 amount, string data ); function _getPaymentHandlerSettings() internal view returns (address) { return __s().payoutAddress; } function _setPaymentHandlerSettings( address payoutAddress ) internal { __s().payoutAddress = payoutAddress; } function _transferTo( string memory paymentMethodName, address to, uint256 amount, string memory data ) internal { require(to != address(0), "PH:TTZ"); require(amount > 0, "PH:ZAM"); bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); require(nameHash == WEI_PAYMENT_METHOD_HASH || PaymentMethodManagerLib._paymentMethodExists(nameHash), "PH:MNS"); if (nameHash == WEI_PAYMENT_METHOD_HASH) { require(amount <= address(this).balance, "PH:MTB"); /* solhint-disable avoid-low-level-calls */ (bool success, ) = to.call{value: amount}(new bytes(0)); /* solhint-enable avoid-low-level-calls */ require(success, "PH:TF"); emit TransferTo(to, amount, data); } else { address erc20 = PaymentMethodManagerLib._getERC20PaymentMethodAddress(nameHash); require(amount <= IERC20(erc20).balanceOf(address(this)), "PH:MTB"); IERC20(erc20).transfer(to, amount); emit TransferETH20To(paymentMethodName, to, amount, data); } } function _handlePayment( uint256 nrOfItems1, uint256 priceWeiPerItem1, uint256 nrOfItems2, uint256 priceWeiPerItem2, string memory paymentMethodName ) internal { uint256 totalWei = nrOfItems1 * priceWeiPerItem1 + nrOfItems2 * priceWeiPerItem2; if (totalWei == 0) { return; } bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); require(nameHash == WEI_PAYMENT_METHOD_HASH || PaymentMethodManagerLib._paymentMethodExists(nameHash), "PH:MNS"); if (nameHash == WEI_PAYMENT_METHOD_HASH) { PaymentMethodManagerLib._handleWeiPayment( msg.sender, __s().payoutAddress, msg.value, totalWei, ""); } else { PaymentMethodManagerLib. _handleERC20Payment( paymentMethodName, msg.sender, __s().payoutAddress, totalWei, ""); } } function __s() private pure returns (PaymentHandlerStorage.Layout storage) { return PaymentHandlerStorage.layout(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol) pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); 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 (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./PaymentMethodManagerInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library PaymentMethodManagerLib { function _handleWeiPayment( address payer, address dest, uint256 paidPriceWei, // could be the msg.value uint256 priceWeiToPay, string memory data ) internal { PaymentMethodManagerInternal._handleWeiPayment( payer, dest, paidPriceWei, priceWeiToPay, data ); } function _handleERC20Payment( string memory paymentMethodName, address payer, address dest, uint256 priceWeiToPay, string memory data ) internal { PaymentMethodManagerInternal._handleERC20Payment( paymentMethodName, payer, dest, priceWeiToPay, data ); } function _paymentMethodExists( bytes32 paymentMethodNameHash ) internal view returns (bool) { return PaymentMethodManagerLib._paymentMethodExists(paymentMethodNameHash); } function _paymentMethodEnabled( bytes32 paymentMethodNameHash ) internal view returns (bool) { return PaymentMethodManagerLib._paymentMethodEnabled(paymentMethodNameHash); } function _getERC20PaymentMethodAddress( bytes32 paymentMethodNameHash ) internal view returns (address) { return PaymentMethodManagerLib._getERC20PaymentMethodAddress(paymentMethodNameHash); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library PaymentHandlerStorage { struct Layout { address payoutAddress; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.payment-handler.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "../../IUniswapV2Pair.sol"; import "./PaymentMethodManagerStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library PaymentMethodManagerInternal { event ERC20PaymentMethodUpdate( string paymentMethodName, address erc20, address wethPair, bool enabled, string data ); event WeiPayment( address payer, address dest, uint256 paidPriceWei, uint256 priceWeiToPay, string data ); event ERC20Payment( string paymentMethodName, address payer, address dest, uint256 amountWei, uint256 amountTokens, string data ); function _getPaymentMethodManagerSettings() internal view returns (address) { return __s().wethAddress; } function _setPaymentMethodManagerSettings( address wethAddress ) internal { __s().wethAddress = wethAddress; } function _getERC20PaymentMethods() internal view returns (string[] memory) { return __s().erc20PaymentMethodNames; } function _getERC20PaymentMethod( string memory paymentMethodName ) internal view returns (address, address, bool) { bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); require(_paymentMethodExists(nameHash), "PMM:NEM"); return ( __s().erc20PaymentMethods[nameHash].erc20, __s().erc20PaymentMethods[nameHash].wethPair, __s().erc20PaymentMethods[nameHash].enabled ); } function _addOrUpdateERC20PaymentMethod( string memory paymentMethodName, address erc20, address wethPair, bool enabled, string memory data ) internal { bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); __s().erc20PaymentMethods[nameHash].erc20 = erc20; __s().erc20PaymentMethods[nameHash].wethPair = wethPair; __s().erc20PaymentMethods[nameHash].enabled = enabled; address token0 = IUniswapV2Pair(wethPair).token0(); address token1 = IUniswapV2Pair(wethPair).token1(); require(token0 == __s().wethAddress || token1 == __s().wethAddress, "PMM:IPC"); bool reverseIndices = (token1 == __s().wethAddress); __s().erc20PaymentMethods[nameHash].reverseIndices = reverseIndices; if (__s().erc20PaymentMethodNamesIndex[paymentMethodName] == 0) { __s().erc20PaymentMethodNames.push(paymentMethodName); __s().erc20PaymentMethodNamesIndex[paymentMethodName] = __s().erc20PaymentMethodNames.length; } emit ERC20PaymentMethodUpdate( paymentMethodName, erc20, wethPair, enabled, data); } function _enableERC20TokenPayment( string memory paymentMethodName, bool enabled ) internal { bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); require(_paymentMethodExists(nameHash), "PMM:NEM"); __s().erc20PaymentMethods[nameHash].enabled = enabled; emit ERC20PaymentMethodUpdate( paymentMethodName, __s().erc20PaymentMethods[nameHash].erc20, __s().erc20PaymentMethods[nameHash].wethPair, enabled, "" ); } function _handleWeiPayment( address payer, address dest, uint256 paidPriceWei, // could be the msg.value uint256 priceWeiToPay, string memory data ) internal { require(paidPriceWei >= priceWeiToPay, "PMM:IF"); uint256 remainder = paidPriceWei - priceWeiToPay; if (dest != address(0)) { /* solhint-disable avoid-low-level-calls */ (bool success, ) = dest.call{value: priceWeiToPay}(new bytes(0)); /* solhint-enable avoid-low-level-calls */ require(success, "PMM:TF"); emit WeiPayment(payer, dest, paidPriceWei, priceWeiToPay, data); } else { emit WeiPayment( payer, address(this), paidPriceWei, priceWeiToPay, data); } if (remainder > 0) { /* solhint-disable avoid-low-level-calls */ (bool success, ) = payer.call{value: remainder}(new bytes(0)); /* solhint-enable avoid-low-level-calls */ require(success, "PMM:RTF"); } } function _handleERC20Payment( string memory paymentMethodName, address payer, address dest, uint256 priceWeiToPay, string memory data ) internal { bytes32 nameHash = keccak256(abi.encode(paymentMethodName)); require(_paymentMethodExists(nameHash), "PMM:NEM"); require(_paymentMethodEnabled(nameHash), "PMM:NENM"); PaymentMethodManagerStorage.ERC20PaymentMethod memory paymentMethod = __s().erc20PaymentMethods[nameHash]; (uint112 amount0, uint112 amount1,) = IUniswapV2Pair(paymentMethod.wethPair).getReserves(); uint256 reserveWei = amount0; uint256 reserveTokens = amount1; if (paymentMethod.reverseIndices) { reserveWei = amount1; reserveTokens = amount0; } require(reserveWei > 0, "PMM:NWR"); // TODO(kam): check if this is OK uint256 amountTokens = (priceWeiToPay * reserveTokens) / reserveWei; if (dest == address(0)) { dest = address(this); } // this contract must have already been approved by the msg.sender IERC20(paymentMethod.erc20).transferFrom(payer, dest, amountTokens); emit ERC20Payment( paymentMethodName, payer, dest, priceWeiToPay, amountTokens, data); } function _paymentMethodExists( bytes32 paymentMethodNameHash ) internal view returns (bool) { return __s().erc20PaymentMethods[paymentMethodNameHash].erc20 != address(0) && __s().erc20PaymentMethods[paymentMethodNameHash].wethPair != address(0); } function _paymentMethodEnabled( bytes32 paymentMethodNameHash ) internal view returns (bool) { return __s().erc20PaymentMethods[paymentMethodNameHash].enabled; } function _getERC20PaymentMethodAddress( bytes32 paymentMethodNameHash ) internal view returns (address) { require(_paymentMethodExists(paymentMethodNameHash), "PMM:NEM"); return __s().erc20PaymentMethods[paymentMethodNameHash].erc20; } function __s() private pure returns (PaymentMethodManagerStorage.Layout storage) { return PaymentMethodManagerStorage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library PaymentMethodManagerStorage { struct ERC20PaymentMethod { // The internal unique name of the ERC-20 payment method string name; // The ERC-20 contract address erc20; // Uniswap V2 Pair with WETH address wethPair; // True if the read pair from Uniswap has a reverse ordering // for contract addresses bool reverseIndices; // If the payment method is enabled bool enabled; } struct Layout { // The WETH ERC-20 contract address. // On mainnet, it is: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 address wethAddress; // The list of the existing ERC20 payment method names string[] erc20PaymentMethodNames; mapping(string => uint256) erc20PaymentMethodNamesIndex; // name > erc20 payment method mapping(bytes32 => ERC20PaymentMethod) erc20PaymentMethods; // Reserved for future upgrades mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.payment-method-manager.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "../erc721/ERC721Lib.sol"; import "../minter/MinterLib.sol"; import "../whitelist-manager/WhitelistManagerLib.sol"; import "../payment-handler/PaymentHandlerLib.sol"; import "./ReserveManagerStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library ReserveManagerInternal { event ReserveToken(address account, uint256 tokenId); function _initReserveManager() internal { // We always keep the token #0 reserved for the contract __s().reservedTokenIdCounter = 1; __s().totalNrOfReservedTokens = 0; } function _getReservationSettings() internal view returns (bool, bool, uint256, uint256, uint256) { return ( __s().reservationAllowed, __s().reservationAllowedWithoutWhitelisting, __s().reservationFeeWei, __s().reservePriceWeiPerToken, __s().totalNrOfReservedTokens ); } function _setReservationSettings( bool reservationAllowed, bool reservationAllowedWithoutWhitelisting, uint256 reservationFeeWei, uint256 reservePriceWeiPerToken ) internal { __s().reservationAllowed = reservationAllowed; __s().reservationAllowedWithoutWhitelisting = reservationAllowedWithoutWhitelisting; __s().reservationFeeWei = reservationFeeWei; __s().reservePriceWeiPerToken = reservePriceWeiPerToken; } function _reserveForAccount( address account, uint256 nrOfTokens, string memory paymentMethodName ) internal { require(__s().reservationAllowed, "RM:NA"); if (!__s().reservationAllowedWithoutWhitelisting) { uint256 nrOfWhitelistedTokens = WhitelistManagerLib._getWhitelistEntry(account); uint256 nrOfReservedTokens = __s().nrOfReservedTokens[account]; require(nrOfReservedTokens < nrOfWhitelistedTokens, "RM:EMAX"); require(nrOfTokens <= (nrOfWhitelistedTokens - nrOfReservedTokens), "RM:EMAX2"); } PaymentHandlerLib._handlePayment( 1, __s().reservationFeeWei, nrOfTokens, __s().reservePriceWeiPerToken, paymentMethodName ); _reserve(account, nrOfTokens); } // NOTE: This is always allowed function _reserveForAccounts( address[] memory accounts, uint256[] memory nrOfTokensArray ) internal { require(accounts.length == nrOfTokensArray.length, "RM:II"); for (uint256 i = 0; i < accounts.length; i++) { _reserve(accounts[i], nrOfTokensArray[i]); } } function _reserve( address account, uint256 nrOfTokens ) private { require(account != address(this), "RM:IA"); for (uint256 i = 0; i < nrOfTokens; i++) { bool found = false; while (__s().reservedTokenIdCounter < MinterLib._getTokenIdCounter()) { if (ERC721Lib._ownerOf(__s().reservedTokenIdCounter) == address(this)) { found = true; break; } __s().reservedTokenIdCounter += 1; } if (found) { ERC721Lib._transfer(address(this), account, __s().reservedTokenIdCounter); emit ReserveToken(account, __s().reservedTokenIdCounter); } else { MinterLib._justMintTo(account); emit ReserveToken(account, MinterLib._getTokenIdCounter() - 1); } __s().reservedTokenIdCounter += 1; } __s().nrOfReservedTokens[account] += nrOfTokens; __s().totalNrOfReservedTokens += nrOfTokens; } function __s() private pure returns (ReserveManagerStorage.Layout storage) { return ReserveManagerStorage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "./WhitelistManagerInternal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library WhitelistManagerLib { function _getWhitelistEntry(address account) internal view returns (uint256) { return WhitelistManagerInternal._getWhitelistEntry(account); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library ReserveManagerStorage { struct Layout { bool reservationAllowed; bool reservationAllowedWithoutWhitelisting; uint256 reservationFeeWei; uint256 reservePriceWeiPerToken; uint256 reservedTokenIdCounter; mapping(address => uint256) nrOfReservedTokens; uint256 totalNrOfReservedTokens; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.reserve-manager.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; import "../payment-handler/PaymentHandlerLib.sol"; import "./WhitelistManagerStorage.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk library WhitelistManagerInternal { event Whitelist(address account, uint256 nrOfTokens); function _getWhitelistingSettings() internal view returns (bool, uint256, uint256, uint256, uint256) { return ( __s().whitelistingAllowed, __s().whitelistingFeeWei, __s().whitelistingPriceWeiPerToken, __s().maxNrOfWhitelistedTokensPerAccount, __s().totalNrOfWhitelists ); } function _setWhitelistingSettings( bool whitelistingAllowed, uint256 whitelistingFeeWei, uint256 whitelistingPriceWeiPerToken, uint256 maxNrOfWhitelistedTokensPerAccount ) internal { __s().whitelistingAllowed = whitelistingAllowed; __s().whitelistingFeeWei = whitelistingFeeWei; __s().whitelistingPriceWeiPerToken = whitelistingPriceWeiPerToken; __s().maxNrOfWhitelistedTokensPerAccount = maxNrOfWhitelistedTokensPerAccount; } // NOTE: Send 0 for nrOfTokens to de-list the address function _whitelistAccount( address account, uint256 nrOfTokens, string memory paymentMethodName ) internal { require(__s().whitelistingAllowed, "WM:NA"); PaymentHandlerLib._handlePayment( 1, __s().whitelistingFeeWei, nrOfTokens, __s().whitelistingPriceWeiPerToken, paymentMethodName ); _whitelist(account, nrOfTokens); } // NOTE: Send 0 for nrOfTokens to de-list an address // NOTE: This is always allowed function _whitelistAccounts( address[] memory accounts, uint256[] memory nrOfTokensArray ) internal { require(accounts.length == nrOfTokensArray.length, "WM:IL"); for (uint256 i = 0; i < accounts.length; i++) { _whitelist(accounts[i], nrOfTokensArray[i]); } } function _getWhitelistEntry(address account) internal view returns (uint256) { return __s().whitelistEntries[account]; } function _whitelist( address account, uint256 nrOfTokens ) private { require(__s().maxNrOfWhitelistedTokensPerAccount == 0 || nrOfTokens <= __s().maxNrOfWhitelistedTokensPerAccount, "WM:EMAX"); if (nrOfTokens == 0){ // de-list the account uint256 nrOfTokensToBeRemoved = __s().whitelistEntries[account]; __s().whitelistEntries[account] = 0; __s().totalNrOfWhitelists -= nrOfTokensToBeRemoved; } else{ __s().whitelistEntries[account] = nrOfTokens; __s().totalNrOfWhitelists += nrOfTokens; } emit Whitelist(account, nrOfTokens); } function __s() private pure returns (WhitelistManagerStorage.Layout storage) { return WhitelistManagerStorage.layout(); } }
/* * This file is part of the Qomet Technologies contracts (https://github.com/qomet-tech/contracts). * Copyright (c) 2022 Qomet Technologies (https://qomet.tech) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // SPDX-License-Identifier: GNU General Public License v3.0 pragma solidity 0.8.1; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk. Just got the basic /// idea from: https://github.com/solidstate-network/solidstate-solidity library WhitelistManagerStorage { struct Layout { bool whitelistingAllowed; uint256 whitelistingFeeWei; uint256 whitelistingPriceWeiPerToken; uint256 maxNrOfWhitelistedTokensPerAccount; mapping(address => uint256) whitelistEntries; uint256 totalNrOfWhitelists; mapping(bytes32 => bytes) extra; } bytes32 internal constant STORAGE_SLOT = keccak256("qomet-tech.contracts.facets.collection.whitelist-manager.storage"); function layout() internal pure returns (Layout storage s) { bytes32 slot = STORAGE_SLOT; /* solhint-disable no-inline-assembly */ assembly { s.slot := slot } /* solhint-enable no-inline-assembly */ } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"evidence","type":"string"}],"name":"findToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFacetName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFacetPI","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFacetProtectedPI","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getFacetVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenData","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenStoreSettings","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"ownedTokens","outputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"data","type":"string"}],"name":"setTokenData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseTokenURI","type":"string"},{"internalType":"string","name":"defaultTokenURI","type":"string"},{"internalType":"bool","name":"useIdempotentTokenURIs","type":"bool"},{"internalType":"string","name":"idempotentTokenURIBase","type":"string"},{"internalType":"string","name":"idempotentTokenURIExtension","type":"string"}],"name":"setTokenStoreSettings","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":"pure","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"string[]","name":"uris","type":"string[]"},{"internalType":"string[]","name":"datas","type":"string[]"}],"name":"updateTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611e27806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637e4802151161008c578063b12ab40f11610066578063b12ab40f146101d1578063b2129c47146101f1578063f61a269914610204578063f8c2be4f14610217576100ea565b80637e4802151461018b578063a5b941c21461019e578063b09afec1146101be576100ea565b8063320dcd97116100c8578063320dcd97146101425780633bb3a24d146101575780633e7fc2d51461016a57806368498a3314610183576100ea565b806301ffc9a7146100ef5780631078fade14610118578063162094c41461012d575b600080fd5b6101026100fd366004611778565b61021f565b60405161010f9190611ab1565b60405180910390f35b610120610258565b60405161010f9190611a0d565b61014061013b3660046118ac565b6105a3565b005b61014a6105b1565b60405161010f9190611abc565b61014a610165366004611894565b6105d6565b6101726105e1565b60405161010f959493929190611acf565b610120610602565b61014061019936600461169e565b610778565b6101b16101ac3660046117a0565b610788565b60405161010f9190611bf3565b61014a6101cc366004611894565b610793565b6101e46101df366004611677565b61079e565b60405161010f9190611a6d565b6101406101ff3660046117d3565b6107a9565b6101406102123660046118ac565b6107bd565b61014a6107c7565b60006001600160e01b0319821663b2fe033560e01b148061025057506001600160e01b03198216635b5e139f60e01b145b90505b919050565b604080516009808252610140820190925260609160009190816020015b60608152602001906001900390816102755790505090506040518060400160405280601781526020017f676574546f6b656e53746f726553657474696e67732829000000000000000000815250816000815181106102e357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060378152602001611dbb603791398160018151811061032857634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806015815260200174676574546f6b656e446174612875696e743235362960581b8152508160028151811061038257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601c81526020017f736574546f6b656e446174612875696e743235362c737472696e672900000000815250816003815181106103e457634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806014815260200173676574546f6b656e5552492875696e743235362960601b8152508160048151811061043d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601b81526020017f736574546f6b656e5552492875696e743235362c737472696e672900000000008152508160058151811061049f57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060298152602001611d9260299139816006815181106104e457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806040016040528060148152602001736f776e6564546f6b656e7328616464726573732960601b8152508160078151811061053d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017066696e64546f6b656e28737472696e672960781b8152508160088151811061059357634e487b7160e01b600052603260045260246000fd5b6020908102919091010152905090565b6105ad82826107e6565b5050565b60408051808201909152600b81526a746f6b656e2d73746f726560a81b602082015290565b6060610250826108a9565b60608060006060806105f1610acb565b945094509450945094509091929394565b60408051600480825260a0820190925260609160009190816020015b606081526020019060019003908161061e579050509050604051806060016040528060378152602001611dbb603791398160008151811061066f57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601c81526020017f736574546f6b656e446174612875696e743235362c737472696e672900000000815250816001815181106106d157634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601b81526020017f736574546f6b656e5552492875696e743235362c737472696e672900000000008152508160028151811061073357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060298152602001611d92602991398160038151811061059357634e487b7160e01b600052603260045260246000fd5b610783838383610d4c565b505050565b600061025082610e83565b606061025082610eac565b606061025082610f80565b6107b68585858585611168565b5050505050565b6105ad8282611203565b6040805180820190915260058152640342e302e360dc1b602082015290565b6107ef8261128d565b6108145760405162461bcd60e51b815260040161080b90611b4f565b60405180910390fd5b8061081d611298565b6005016000848152602001908152602001600020600001908051906020019061084792919061150c565b507fe63ff1ee191e6fc902b7b47aa9ccf80bd883ec287a6d18db9961e5c5ec6b80f08282604051610879929190611bfc565b60405180910390a18161088a611298565b8251602093840120600090815260079190910190925260409091205550565b60606108b48261128d565b6108d05760405162461bcd60e51b815260040161080b90611b4f565b6108d8611298565b6002015460ff161561092b576108ec611298565b6003016108f8836112a7565b610900611298565b600401604051602001610915939291906119da565b6040516020818303038152906040529050610253565b6000610935611298565b600084815260059190910160205260409020805461095290611ce5565b80601f016020809104026020016040519081016040528092919081815260200182805461097e90611ce5565b80156109cb5780601f106109a0576101008083540402835291602001916109cb565b820191906000526020600020905b8154815290600101906020018083116109ae57829003601f168201915b50505050509050805160001415610a78576109e4611298565b60010180546109f290611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1e90611ce5565b8015610a6b5780601f10610a4057610100808354040283529160200191610a6b565b820191906000526020600020905b815481529060010190602001808311610a4e57829003601f168201915b5050505050915050610253565b610a80611298565b8054610a8b90611ce5565b15159050610a9a579050610253565b610aa2611298565b604051610ab4919083906020016119b5565b604051602081830303815290604052915050919050565b6060806000606080610adb611298565b610ae3611298565b600101610aee611298565b6002015460ff16610afd611298565b600301610b08611298565b600401848054610b1790611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4390611ce5565b8015610b905780601f10610b6557610100808354040283529160200191610b90565b820191906000526020600020905b815481529060010190602001808311610b7357829003601f168201915b50505050509450838054610ba390611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610bcf90611ce5565b8015610c1c5780601f10610bf157610100808354040283529160200191610c1c565b820191906000526020600020905b815481529060010190602001808311610bff57829003601f168201915b50505050509350818054610c2f90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5b90611ce5565b8015610ca85780601f10610c7d57610100808354040283529160200191610ca8565b820191906000526020600020905b815481529060010190602001808311610c8b57829003601f168201915b50505050509150808054610cbb90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce790611ce5565b8015610d345780601f10610d0957610100808354040283529160200191610d34565b820191906000526020600020905b815481529060010190602001808311610d1757829003601f168201915b50505050509050945094509450945094509091929394565b6000835111610d6d5760405162461bcd60e51b815260040161080b90611b30565b8151835114610d8e5760405162461bcd60e51b815260040161080b90611b70565b8051835114610daf5760405162461bcd60e51b815260040161080b90611bd4565b60005b8251811015610e7d57610e13848281518110610dde57634e487b7160e01b600052603260045260246000fd5b6020026020010151848381518110610e0657634e487b7160e01b600052603260045260246000fd5b60200260200101516107e6565b610e6b848281518110610e3657634e487b7160e01b600052603260045260246000fd5b6020026020010151838381518110610e5e57634e487b7160e01b600052603260045260246000fd5b6020026020010151611203565b80610e7581611d20565b915050610db2565b50505050565b6000610e8d611298565b8251602093840120600090815260079190910190925250604090205490565b6060610eb78261128d565b610ed35760405162461bcd60e51b815260040161080b90611b4f565b610edb611298565b6000838152600591909101602052604090206001018054610efb90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2790611ce5565b8015610f745780601f10610f4957610100808354040283529160200191610f74565b820191906000526020600020905b815481529060010190602001808311610f5757829003601f168201915b50505050509050919050565b606060006001600160a01b038316156110315760005b610f9f846113ca565b5181101561102f576000610fb2856113ca565b8281518110610fd157634e487b7160e01b600052603260045260246000fd5b60200260200101519050610fe48161128d565b80156110095750846001600160a01b0316610ffe82611441565b6001600160a01b0316145b1561101c57611019600184611c76565b92505b508061102781611d20565b915050610f96565b505b60008167ffffffffffffffff81111561105a57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611083578160200160208202803683370190505b5090506001600160a01b03841615611161576000805b6110a2866113ca565b5181101561115e5760006110b5876113ca565b82815181106110d457634e487b7160e01b600052603260045260246000fd5b602002602001015190506110e78161128d565b801561110c5750866001600160a01b031661110182611441565b6001600160a01b0316145b1561114b578084848151811061113257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152611148600184611c76565b92505b508061115681611d20565b915050611099565b50505b9392505050565b84611171611298565b8151611180926020019061150c565b508361118a611298565b60010190805190602001906111a092919061150c565b50826111aa611298565b600201805460ff1916911515919091179055816111c5611298565b60030190805190602001906111db92919061150c565b50806111e5611298565b60040190805190602001906111fb92919061150c565b505050505050565b61120c8261128d565b6112285760405162461bcd60e51b815260040161080b90611bb3565b80611231611298565b6005016000848152602001908152602001600020600101908051906020019061125b92919061150c565b507fad80812cc1243d6bbd8b86f20d1d35dbf48c9d00a19db906d9fed4a4f73230ce8282604051610879929190611bfc565b60006102508261144c565b60006112a261147a565b905090565b6060816112cc57506040805180820190915260018152600360fc1b6020820152610253565b8160005b81156112f657806112e081611d20565b91506112ef9050600a83611c8e565b91506112d0565b60008167ffffffffffffffff81111561131f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611349576020820181803683370190505b5090505b84156113c25761135e600183611ca2565b915061136b600a86611d3b565b611376906030611c76565b60f81b81838151811061139957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506113bb600a86611c8e565b945061134d565b949350505050565b60606113d4611298565b6001600160a01b0383166000908152600691909101602090815260409182902080548351818402810184019094528084529091830182828015610f7457602002820191906000526020600020905b8154815260200190600101908083116114225750505050509050919050565b60006102508261149e565b6000806114576114e4565b60009384526002016020526040909220546001600160a01b031690911415919050565b7f73fe048652e51f080002cab7173201110a5a7526ce7d7ec1a97184a03368b94f90565b6000806114a96114e4565b600084815260029190910160205260409020546001600160a01b03169050806102505760405162461bcd60e51b815260040161080b90611b8e565b60007fd7aeb8e4f0c59b8cd9990692700804773e94b3a69feac86b7147c9c8edad330c6112a2565b82805461151890611ce5565b90600052602060002090601f01602090048101928261153a5760008555611580565b82601f1061155357805160ff1916838001178555611580565b82800160010185558215611580579182015b82811115611580578251825591602001919060010190611565565b5061158c929150611590565b5090565b5b8082111561158c5760008155600101611591565b600082601f8301126115b5578081fd5b813560206115ca6115c583611c46565b611c15565b82815281810190858301855b858110156115ff576115ed898684358b010161160c565b845292840192908401906001016115d6565b5090979650505050505050565b600082601f83011261161c578081fd5b813567ffffffffffffffff81111561163657611636611d7b565b611649601f8201601f1916602001611c15565b81815284602083860101111561165d578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611688578081fd5b81356001600160a01b0381168114611161578182fd5b6000806000606084860312156116b2578182fd5b833567ffffffffffffffff808211156116c9578384fd5b818601915086601f8301126116dc578384fd5b813560206116ec6115c583611c46565b82815281810190858301838502870184018c1015611708578889fd5b8896505b8487101561172a57803583526001969096019591830191830161170c565b5097505087013592505080821115611740578384fd5b61174c878388016115a5565b93506040860135915080821115611761578283fd5b5061176e868287016115a5565b9150509250925092565b600060208284031215611789578081fd5b81356001600160e01b031981168114611161578182fd5b6000602082840312156117b1578081fd5b813567ffffffffffffffff8111156117c7578182fd5b6113c28482850161160c565b600080600080600060a086880312156117ea578081fd5b853567ffffffffffffffff80821115611801578283fd5b61180d89838a0161160c565b96506020880135915080821115611822578283fd5b61182e89838a0161160c565b9550604088013591508115158214611844578283fd5b90935060608701359080821115611859578283fd5b61186589838a0161160c565b9350608088013591508082111561187a578283fd5b506118878882890161160c565b9150509295509295909350565b6000602082840312156118a5578081fd5b5035919050565b600080604083850312156118be578182fd5b82359150602083013567ffffffffffffffff8111156118db578182fd5b6118e78582860161160c565b9150509250929050565b60008151808452611909816020860160208601611cb9565b601f01601f19169290920160200192915050565b80546000906002810460018083168061193757607f831692505b602080841082141561195757634e487b7160e01b86526022600452602486fd5b81801561196b576001811461197c576119a9565b60ff198616895284890196506119a9565b61198588611c6a565b60005b868110156119a15781548b820152908501908301611988565b505084890196505b50505050505092915050565b60006119c1828561191d565b83516119d1818360208801611cb9565b01949350505050565b60006119e6828661191d565b84516119f6818360208901611cb9565b611a028183018661191d565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611a6057603f19888603018452611a4e8583516118f1565b94509285019290850190600101611a32565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611aa557835183529284019291840191600101611a89565b50909695505050505050565b901515815260200190565b60006020825261116160208301846118f1565b600060a08252611ae260a08301886118f1565b8281036020840152611af481886118f1565b905085151560408401528281036060840152611b1081866118f1565b90508281036080840152611b2481856118f1565b98975050505050505050565b6020808252600590820152644d3a4e545560d81b604082015260600190565b6020808252600790820152661514d24e93915560ca1b604082015260600190565b602080825260049082015263134e925360e21b604082015260600190565b6020808252600b908201526a115490cdcc8c524e93915560aa1b604082015260600190565b6020808252600790820152661514d18e93915560ca1b604082015260600190565b602080825260059082015264269d24a61960d91b604082015260600190565b90815260200190565b6000838252604060208301526113c260408301846118f1565b604051601f8201601f1916810167ffffffffffffffff81118282101715611c3e57611c3e611d7b565b604052919050565b600067ffffffffffffffff821115611c6057611c60611d7b565b5060209081020190565b60009081526020902090565b60008219821115611c8957611c89611d4f565b500190565b600082611c9d57611c9d611d65565b500490565b600082821015611cb457611cb4611d4f565b500390565b60005b83811015611cd4578181015183820152602001611cbc565b83811115610e7d5750506000910152565b600281046001821680611cf957607f821691505b60208210811415611d1a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415611d3457611d34611d4f565b5060010190565b600082611d4a57611d4a611d65565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe757064617465546f6b656e732875696e743235365b5d2c737472696e675b5d2c737472696e675b5d29736574546f6b656e53746f726553657474696e677328737472696e672c737472696e672c626f6f6c2c737472696e672c737472696e6729a2646970667358221220956fcb4071554171f867b423b056931212ff1b0395aafbd2d1febebccfa5773664736f6c63430008010033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80637e4802151161008c578063b12ab40f11610066578063b12ab40f146101d1578063b2129c47146101f1578063f61a269914610204578063f8c2be4f14610217576100ea565b80637e4802151461018b578063a5b941c21461019e578063b09afec1146101be576100ea565b8063320dcd97116100c8578063320dcd97146101425780633bb3a24d146101575780633e7fc2d51461016a57806368498a3314610183576100ea565b806301ffc9a7146100ef5780631078fade14610118578063162094c41461012d575b600080fd5b6101026100fd366004611778565b61021f565b60405161010f9190611ab1565b60405180910390f35b610120610258565b60405161010f9190611a0d565b61014061013b3660046118ac565b6105a3565b005b61014a6105b1565b60405161010f9190611abc565b61014a610165366004611894565b6105d6565b6101726105e1565b60405161010f959493929190611acf565b610120610602565b61014061019936600461169e565b610778565b6101b16101ac3660046117a0565b610788565b60405161010f9190611bf3565b61014a6101cc366004611894565b610793565b6101e46101df366004611677565b61079e565b60405161010f9190611a6d565b6101406101ff3660046117d3565b6107a9565b6101406102123660046118ac565b6107bd565b61014a6107c7565b60006001600160e01b0319821663b2fe033560e01b148061025057506001600160e01b03198216635b5e139f60e01b145b90505b919050565b604080516009808252610140820190925260609160009190816020015b60608152602001906001900390816102755790505090506040518060400160405280601781526020017f676574546f6b656e53746f726553657474696e67732829000000000000000000815250816000815181106102e357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060378152602001611dbb603791398160018151811061032857634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806015815260200174676574546f6b656e446174612875696e743235362960581b8152508160028151811061038257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601c81526020017f736574546f6b656e446174612875696e743235362c737472696e672900000000815250816003815181106103e457634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806014815260200173676574546f6b656e5552492875696e743235362960601b8152508160048151811061043d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601b81526020017f736574546f6b656e5552492875696e743235362c737472696e672900000000008152508160058151811061049f57634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060298152602001611d9260299139816006815181106104e457634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806040016040528060148152602001736f776e6564546f6b656e7328616464726573732960601b8152508160078151811061053d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017066696e64546f6b656e28737472696e672960781b8152508160088151811061059357634e487b7160e01b600052603260045260246000fd5b6020908102919091010152905090565b6105ad82826107e6565b5050565b60408051808201909152600b81526a746f6b656e2d73746f726560a81b602082015290565b6060610250826108a9565b60608060006060806105f1610acb565b945094509450945094509091929394565b60408051600480825260a0820190925260609160009190816020015b606081526020019060019003908161061e579050509050604051806060016040528060378152602001611dbb603791398160008151811061066f57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601c81526020017f736574546f6b656e446174612875696e743235362c737472696e672900000000815250816001815181106106d157634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601b81526020017f736574546f6b656e5552492875696e743235362c737472696e672900000000008152508160028151811061073357634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806060016040528060298152602001611d92602991398160038151811061059357634e487b7160e01b600052603260045260246000fd5b610783838383610d4c565b505050565b600061025082610e83565b606061025082610eac565b606061025082610f80565b6107b68585858585611168565b5050505050565b6105ad8282611203565b6040805180820190915260058152640342e302e360dc1b602082015290565b6107ef8261128d565b6108145760405162461bcd60e51b815260040161080b90611b4f565b60405180910390fd5b8061081d611298565b6005016000848152602001908152602001600020600001908051906020019061084792919061150c565b507fe63ff1ee191e6fc902b7b47aa9ccf80bd883ec287a6d18db9961e5c5ec6b80f08282604051610879929190611bfc565b60405180910390a18161088a611298565b8251602093840120600090815260079190910190925260409091205550565b60606108b48261128d565b6108d05760405162461bcd60e51b815260040161080b90611b4f565b6108d8611298565b6002015460ff161561092b576108ec611298565b6003016108f8836112a7565b610900611298565b600401604051602001610915939291906119da565b6040516020818303038152906040529050610253565b6000610935611298565b600084815260059190910160205260409020805461095290611ce5565b80601f016020809104026020016040519081016040528092919081815260200182805461097e90611ce5565b80156109cb5780601f106109a0576101008083540402835291602001916109cb565b820191906000526020600020905b8154815290600101906020018083116109ae57829003601f168201915b50505050509050805160001415610a78576109e4611298565b60010180546109f290611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610a1e90611ce5565b8015610a6b5780601f10610a4057610100808354040283529160200191610a6b565b820191906000526020600020905b815481529060010190602001808311610a4e57829003601f168201915b5050505050915050610253565b610a80611298565b8054610a8b90611ce5565b15159050610a9a579050610253565b610aa2611298565b604051610ab4919083906020016119b5565b604051602081830303815290604052915050919050565b6060806000606080610adb611298565b610ae3611298565b600101610aee611298565b6002015460ff16610afd611298565b600301610b08611298565b600401848054610b1790611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610b4390611ce5565b8015610b905780601f10610b6557610100808354040283529160200191610b90565b820191906000526020600020905b815481529060010190602001808311610b7357829003601f168201915b50505050509450838054610ba390611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610bcf90611ce5565b8015610c1c5780601f10610bf157610100808354040283529160200191610c1c565b820191906000526020600020905b815481529060010190602001808311610bff57829003601f168201915b50505050509350818054610c2f90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5b90611ce5565b8015610ca85780601f10610c7d57610100808354040283529160200191610ca8565b820191906000526020600020905b815481529060010190602001808311610c8b57829003601f168201915b50505050509150808054610cbb90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610ce790611ce5565b8015610d345780601f10610d0957610100808354040283529160200191610d34565b820191906000526020600020905b815481529060010190602001808311610d1757829003601f168201915b50505050509050945094509450945094509091929394565b6000835111610d6d5760405162461bcd60e51b815260040161080b90611b30565b8151835114610d8e5760405162461bcd60e51b815260040161080b90611b70565b8051835114610daf5760405162461bcd60e51b815260040161080b90611bd4565b60005b8251811015610e7d57610e13848281518110610dde57634e487b7160e01b600052603260045260246000fd5b6020026020010151848381518110610e0657634e487b7160e01b600052603260045260246000fd5b60200260200101516107e6565b610e6b848281518110610e3657634e487b7160e01b600052603260045260246000fd5b6020026020010151838381518110610e5e57634e487b7160e01b600052603260045260246000fd5b6020026020010151611203565b80610e7581611d20565b915050610db2565b50505050565b6000610e8d611298565b8251602093840120600090815260079190910190925250604090205490565b6060610eb78261128d565b610ed35760405162461bcd60e51b815260040161080b90611b4f565b610edb611298565b6000838152600591909101602052604090206001018054610efb90611ce5565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2790611ce5565b8015610f745780601f10610f4957610100808354040283529160200191610f74565b820191906000526020600020905b815481529060010190602001808311610f5757829003601f168201915b50505050509050919050565b606060006001600160a01b038316156110315760005b610f9f846113ca565b5181101561102f576000610fb2856113ca565b8281518110610fd157634e487b7160e01b600052603260045260246000fd5b60200260200101519050610fe48161128d565b80156110095750846001600160a01b0316610ffe82611441565b6001600160a01b0316145b1561101c57611019600184611c76565b92505b508061102781611d20565b915050610f96565b505b60008167ffffffffffffffff81111561105a57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611083578160200160208202803683370190505b5090506001600160a01b03841615611161576000805b6110a2866113ca565b5181101561115e5760006110b5876113ca565b82815181106110d457634e487b7160e01b600052603260045260246000fd5b602002602001015190506110e78161128d565b801561110c5750866001600160a01b031661110182611441565b6001600160a01b0316145b1561114b578084848151811061113257634e487b7160e01b600052603260045260246000fd5b6020908102919091010152611148600184611c76565b92505b508061115681611d20565b915050611099565b50505b9392505050565b84611171611298565b8151611180926020019061150c565b508361118a611298565b60010190805190602001906111a092919061150c565b50826111aa611298565b600201805460ff1916911515919091179055816111c5611298565b60030190805190602001906111db92919061150c565b50806111e5611298565b60040190805190602001906111fb92919061150c565b505050505050565b61120c8261128d565b6112285760405162461bcd60e51b815260040161080b90611bb3565b80611231611298565b6005016000848152602001908152602001600020600101908051906020019061125b92919061150c565b507fad80812cc1243d6bbd8b86f20d1d35dbf48c9d00a19db906d9fed4a4f73230ce8282604051610879929190611bfc565b60006102508261144c565b60006112a261147a565b905090565b6060816112cc57506040805180820190915260018152600360fc1b6020820152610253565b8160005b81156112f657806112e081611d20565b91506112ef9050600a83611c8e565b91506112d0565b60008167ffffffffffffffff81111561131f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611349576020820181803683370190505b5090505b84156113c25761135e600183611ca2565b915061136b600a86611d3b565b611376906030611c76565b60f81b81838151811061139957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506113bb600a86611c8e565b945061134d565b949350505050565b60606113d4611298565b6001600160a01b0383166000908152600691909101602090815260409182902080548351818402810184019094528084529091830182828015610f7457602002820191906000526020600020905b8154815260200190600101908083116114225750505050509050919050565b60006102508261149e565b6000806114576114e4565b60009384526002016020526040909220546001600160a01b031690911415919050565b7f73fe048652e51f080002cab7173201110a5a7526ce7d7ec1a97184a03368b94f90565b6000806114a96114e4565b600084815260029190910160205260409020546001600160a01b03169050806102505760405162461bcd60e51b815260040161080b90611b8e565b60007fd7aeb8e4f0c59b8cd9990692700804773e94b3a69feac86b7147c9c8edad330c6112a2565b82805461151890611ce5565b90600052602060002090601f01602090048101928261153a5760008555611580565b82601f1061155357805160ff1916838001178555611580565b82800160010185558215611580579182015b82811115611580578251825591602001919060010190611565565b5061158c929150611590565b5090565b5b8082111561158c5760008155600101611591565b600082601f8301126115b5578081fd5b813560206115ca6115c583611c46565b611c15565b82815281810190858301855b858110156115ff576115ed898684358b010161160c565b845292840192908401906001016115d6565b5090979650505050505050565b600082601f83011261161c578081fd5b813567ffffffffffffffff81111561163657611636611d7b565b611649601f8201601f1916602001611c15565b81815284602083860101111561165d578283fd5b816020850160208301379081016020019190915292915050565b600060208284031215611688578081fd5b81356001600160a01b0381168114611161578182fd5b6000806000606084860312156116b2578182fd5b833567ffffffffffffffff808211156116c9578384fd5b818601915086601f8301126116dc578384fd5b813560206116ec6115c583611c46565b82815281810190858301838502870184018c1015611708578889fd5b8896505b8487101561172a57803583526001969096019591830191830161170c565b5097505087013592505080821115611740578384fd5b61174c878388016115a5565b93506040860135915080821115611761578283fd5b5061176e868287016115a5565b9150509250925092565b600060208284031215611789578081fd5b81356001600160e01b031981168114611161578182fd5b6000602082840312156117b1578081fd5b813567ffffffffffffffff8111156117c7578182fd5b6113c28482850161160c565b600080600080600060a086880312156117ea578081fd5b853567ffffffffffffffff80821115611801578283fd5b61180d89838a0161160c565b96506020880135915080821115611822578283fd5b61182e89838a0161160c565b9550604088013591508115158214611844578283fd5b90935060608701359080821115611859578283fd5b61186589838a0161160c565b9350608088013591508082111561187a578283fd5b506118878882890161160c565b9150509295509295909350565b6000602082840312156118a5578081fd5b5035919050565b600080604083850312156118be578182fd5b82359150602083013567ffffffffffffffff8111156118db578182fd5b6118e78582860161160c565b9150509250929050565b60008151808452611909816020860160208601611cb9565b601f01601f19169290920160200192915050565b80546000906002810460018083168061193757607f831692505b602080841082141561195757634e487b7160e01b86526022600452602486fd5b81801561196b576001811461197c576119a9565b60ff198616895284890196506119a9565b61198588611c6a565b60005b868110156119a15781548b820152908501908301611988565b505084890196505b50505050505092915050565b60006119c1828561191d565b83516119d1818360208801611cb9565b01949350505050565b60006119e6828661191d565b84516119f6818360208901611cb9565b611a028183018661191d565b979650505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611a6057603f19888603018452611a4e8583516118f1565b94509285019290850190600101611a32565b5092979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015611aa557835183529284019291840191600101611a89565b50909695505050505050565b901515815260200190565b60006020825261116160208301846118f1565b600060a08252611ae260a08301886118f1565b8281036020840152611af481886118f1565b905085151560408401528281036060840152611b1081866118f1565b90508281036080840152611b2481856118f1565b98975050505050505050565b6020808252600590820152644d3a4e545560d81b604082015260600190565b6020808252600790820152661514d24e93915560ca1b604082015260600190565b602080825260049082015263134e925360e21b604082015260600190565b6020808252600b908201526a115490cdcc8c524e93915560aa1b604082015260600190565b6020808252600790820152661514d18e93915560ca1b604082015260600190565b602080825260059082015264269d24a61960d91b604082015260600190565b90815260200190565b6000838252604060208301526113c260408301846118f1565b604051601f8201601f1916810167ffffffffffffffff81118282101715611c3e57611c3e611d7b565b604052919050565b600067ffffffffffffffff821115611c6057611c60611d7b565b5060209081020190565b60009081526020902090565b60008219821115611c8957611c89611d4f565b500190565b600082611c9d57611c9d611d65565b500490565b600082821015611cb457611cb4611d4f565b500390565b60005b83811015611cd4578181015183820152602001611cbc565b83811115610e7d5750506000910152565b600281046001821680611cf957607f821691505b60208210811415611d1a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415611d3457611d34611d4f565b5060010190565b600082611d4a57611d4a611d65565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fdfe757064617465546f6b656e732875696e743235365b5d2c737472696e675b5d2c737472696e675b5d29736574546f6b656e53746f726553657474696e677328737472696e672c737472696e672c626f6f6c2c737472696e672c737472696e6729a2646970667358221220956fcb4071554171f867b423b056931212ff1b0395aafbd2d1febebccfa5773664736f6c63430008010033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.