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 | 16972464 | 476 days ago | IN | Create: ERC721Facet | 0 ETH | 0.0439827 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
ERC721Facet
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/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import "../../../diamond/IDiamondFacet.sol"; import "../token-store/TokenStoreLib.sol"; import "./ERC721Internal.sol"; /// @author Kam Amini <[email protected]> /// /// @notice Use at your own risk contract ERC721Facet is IDiamondFacet { using Address for address; function getFacetName() external pure override returns (string memory) { return "erc721"; } // CAUTION: Don't forget to update the version when adding new functionality function getFacetVersion() external pure override returns (string memory) { return "3.0.0"; } function getFacetPI() external pure override returns (string[] memory) { string[] memory pi = new string[](16); pi[ 0] = "setERC721Settings(string,string,bool)"; pi[ 1] = "balanceOf(address)"; pi[ 2] = "ownerOf(uint256)"; pi[ 3] = "name()"; pi[ 4] = "setName(string)"; pi[ 5] = "symbol()"; pi[ 6] = "setSymbol(string)"; pi[ 7] = "tokenURI(uint256)"; pi[ 8] = "approve(address,uint256)"; pi[ 9] = "getApproved(uint256)"; pi[10] = "setApprovalForAll(address,bool)"; pi[11] = "isApprovedForAll(address,address)"; pi[12] = "transferFromMe(address,uint256)"; pi[13] = "transferFrom(address,address,uint256)"; pi[14] = "safeTransferFrom(address,address,uint256)"; pi[15] = "safeTransferFrom(address,address,uint256,bytes)"; return pi; } function getFacetProtectedPI() external pure override returns (string[] memory) { string[] memory pi = new string[](4); pi[0] = "setERC721Settings(string,string,bool)"; pi[1] = "setName(string)"; pi[2] = "setSymbol(string)"; pi[3] = "transferFromMe(address,uint256)"; return pi; } function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { return interfaceId == type(IDiamondFacet).interfaceId || interfaceId == type(IERC721).interfaceId; } function setERC721Settings( string memory name_, string memory symbol_, bool reserveZeroToken ) external { ERC721Internal._setERC721Settings(name_, symbol_, reserveZeroToken); } // Most of the code is copied from: // https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol function balanceOf(address owner) external view returns (uint256) { return ERC721Internal._balanceOf(owner); } function ownerOf(uint256 tokenId) external view returns (address) { return ERC721Internal._ownerOf(tokenId); } function name() external view returns (string memory) { return ERC721Internal._getName(); } function setName(string memory name_) external { ERC721Internal._setName(name_); } function symbol() external view returns (string memory) { return ERC721Internal._getSymbol(); } function setSymbol(string memory symbol_) external { ERC721Internal._setSymbol(symbol_); } function tokenURI(uint256 tokenId) external view returns (string memory) { require(ERC721Internal._exists(tokenId), "ERC721F:NET"); return TokenStoreLib._getTokenURI(tokenId); } function approve(address to, uint256 tokenId) external { address owner = ERC721Internal._ownerOf(tokenId); require(to != owner, "ERC721F:ATC"); require( msg.sender == owner || ERC721Internal._isApprovedForAll(owner, msg.sender), "ERC721F:NO" ); ERC721Internal._approve(to, tokenId); } function getApproved(uint256 tokenId) external view returns (address) { return ERC721Internal._getApproved(tokenId); } function setApprovalForAll(address operator, bool approved) external { ERC721Internal._setApprovalForAll(msg.sender, operator, approved); } function isApprovedForAll(address owner, address operator) external view returns (bool) { return ERC721Internal._isApprovedForAll(owner, operator); } function transferFromMe( address to, uint256 tokenId ) external { ERC721Internal._transferFromMe(to, tokenId); } function transferFrom( address from, address to, uint256 tokenId ) external { require(ERC721Internal._isApprovedOrOwner(msg.sender, tokenId), "ERC721F:NO"); ERC721Internal._transfer(from, to, tokenId); } function safeTransferFrom( address from, address to, uint256 tokenId ) external { safeTransferFrom(from, to, tokenId, ""); } function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public { require(ERC721Internal._isApprovedOrOwner(msg.sender, tokenId), "ERC721F:NO"); _safeTransfer(from, to, tokenId, data); } function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal { ERC721Internal._transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721F:BADTO"); } function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to) .onERC721Received(msg.sender, from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721F:BADTO"); } else { /* solhint-disable no-inline-assembly */ assembly { revert(add(32, reason), mload(reason)) } /* solhint-enable no-inline-assembly */ } } } else { return true; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// 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 (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // 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 "./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 "../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(); } }
// 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";
/* * 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 (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 "./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":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"bool","name":"reserveZeroToken","type":"bool"}],"name":"setERC721Settings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"symbol_","type":"string"}],"name":"setSymbol","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":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFromMe","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061234a806100206000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806368498a33116100b8578063b84c82461161007c578063b84c82461461026e578063b88d4fde14610281578063c47f002714610294578063c87b56dd146102a7578063e985e9c5146102ba578063f8c2be4f146102cd57610137565b806368498a331461021857806370a08231146102205780637de062db1461024057806395d89b4114610253578063a22cb4651461025b57610137565b806323b872dd116100ff57806323b872dd146101c4578063320dcd97146101d757806340cc7925146101df57806342842e0e146101f25780636352211e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063081812fc1461017a578063095ea7b31461019a5780631078fade146101af575b600080fd5b61014f61014a366004611c7a565b6102d5565b60405161015c9190611f3b565b60405180910390f35b61016d61030e565b60405161015c9190611f46565b61018d610188366004611d56565b61031d565b60405161015c9190611e8a565b6101ad6101a8366004611c51565b610328565b005b6101b76103b7565b60405161015c9190611edb565b6101ad6101d2366004611b74565b61090c565b61016d61093d565b6101ad6101ed366004611c51565b61095d565b6101ad610200366004611b74565b61096b565b61018d610213366004611d56565b610986565b6101b7610991565b61023361022e366004611b28565b610b0a565b60405161015c919061210b565b6101ad61024e366004611ce5565b610b15565b61016d610b20565b6101ad610269366004611c28565b610b2a565b6101ad61027c366004611cb2565b610b35565b6101ad61028f366004611baf565b610b41565b6101ad6102a2366004611cb2565b610b79565b61016d6102b5366004611d56565b610b82565b61014f6102c8366004611b42565b610bb2565b61016d610bc5565b60006001600160e01b0319821663b2fe033560e01b148061030657506001600160e01b031982166380ac58cd60e01b145b90505b919050565b6060610318610be4565b905090565b600061030682610c7c565b600061033382610cd4565b9050806001600160a01b0316836001600160a01b031614156103705760405162461bcd60e51b815260040161036790612056565b60405180910390fd5b336001600160a01b038216148061038c575061038c8133610d1a565b6103a85760405162461bcd60e51b8152600401610367906120e7565b6103b28383610d57565b505050565b604080516010808252610220820190925260609160009190816020015b60608152602001906001900390816103d45790505090506040518060600160405280602581526020016122a0602591398160008151811061042557634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601281526020017162616c616e63654f6628616464726573732960701b8152508160018151811061047c57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601081526020016f6f776e65724f662875696e743235362960801b815250816002815181106104d157634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806040016040528060068152602001656e616d65282960d01b8152508160038151811061051c57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600f81526020016e7365744e616d6528737472696e672960881b8152508160048151811061057057634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600881526020016773796d626f6c282960c01b815250816005815181106105bd57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017073657453796d626f6c28737472696e672960781b8152508160068151811061061357634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806011815260200170746f6b656e5552492875696e743235362960781b8152508160078151811061066957634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601881526020017f617070726f766528616464726573732c75696e74323536290000000000000000815250816008815181106106cb57634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806014815260200173676574417070726f7665642875696e743235362960601b8152508160098151811061072457634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f736574417070726f76616c466f72416c6c28616464726573732c626f6f6c290081525081600a8151811061078657634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602181526020016122f46021913981600b815181106107cb57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f7472616e7366657246726f6d4d6528616464726573732c75696e74323536290081525081600c8151811061082d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602581526020016122526025913981600d8151811061087257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602981526020016122776029913981600e815181106108b757634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602f81526020016122c5602f913981600f815181106108fc57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152905090565b6109163382610dd2565b6109325760405162461bcd60e51b8152600401610367906120e7565b6103b2838383610e70565b60408051808201909152600681526565726337323160d01b602082015290565b6109678282610eda565b5050565b6103b283838360405180602001604052806000815250610b41565b600061030682610cd4565b60408051600480825260a0820190925260609160009190816020015b60608152602001906001900390816109ad5790505090506040518060600160405280602581526020016122a060259139816000815181106109fe57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600f81526020016e7365744e616d6528737472696e672960881b81525081600181518110610a5257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017073657453796d626f6c28737472696e672960781b81525081600281518110610aa857634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f7472616e7366657246726f6d4d6528616464726573732c75696e743235362900815250816003815181106108fc57634e487b7160e01b600052603260045260246000fd5b600061030682610f3b565b6103b2838383610f8d565b6060610318610fca565b610967338383610fe2565b610b3e8161109a565b50565b610b4b3383610dd2565b610b675760405162461bcd60e51b8152600401610367906120e7565b610b73848484846110b9565b50505050565b610b3e816110ec565b6060610b8d82611104565b610ba95760405162461bcd60e51b815260040161036790611fa2565b61030682611132565b6000610bbe8383610d1a565b9392505050565b6040805180820190915260058152640332e302e360dc1b602082015290565b6060610bee61113d565b8054610bf99061218f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c259061218f565b8015610c725780601f10610c4757610100808354040283529160200191610c72565b820191906000526020600020905b815481529060010190602001808311610c5557829003601f168201915b5050505050905090565b600080610c8883610cd4565b6001600160a01b03161415610caf5760405162461bcd60e51b815260040161036790612031565b610cb761113d565b60009283526004016020525060409020546001600160a01b031690565b600080610cdf61113d565b600084815260029190910160205260409020546001600160a01b03169050806103065760405162461bcd60e51b815260040161036790612031565b6000610d2461113d565b6001600160a01b039384166000908152600591909101602090815260408083209490951682529290925250205460ff1690565b81610d6061113d565b60008381526004919091016020526040902080546001600160a01b0319166001600160a01b0392831617905581908316610d9982610cd4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dde83610cd4565b9050806001600160a01b0316846001600160a01b03161480610e325750610e0361113d565b6001600160a01b03808316600090815260059290920160209081526040808420928816845291905290205460ff165b80610e685750836001600160a01b0316610e4a61113d565b600085815260049190910160205260409020546001600160a01b0316145b949350505050565b826001600160a01b0316610e8382610cd4565b6001600160a01b031614610ea95760405162461bcd60e51b815260040161036790611fc7565b6001600160a01b038216610ecf5760405162461bcd60e51b815260040161036790611f59565b6103b2838383611147565b30610ee482610cd4565b6001600160a01b031614610f0a5760405162461bcd60e51b815260040161036790611fc7565b6001600160a01b038216610f305760405162461bcd60e51b815260040161036790611f59565b610967308383611147565b60006001600160a01b038216610f635760405162461bcd60e51b815260040161036790611f59565b610f6b61113d565b6001600160a01b03929092166000908152600390920160205250604090205490565b610f96836110ec565b610f9f8261109a565b808015610fb35750610fb16000611104565b155b156103b257610fc130611268565b506103b2611273565b6060610fd461113d565b6001018054610bf99061218f565b816001600160a01b0316836001600160a01b031614156110145760405162461bcd60e51b81526004016103679061207b565b8061101d61113d565b6001600160a01b038581166000818152600593909301602090815260408085209388168086529390915292839020805460ff19169415159490941790935590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319061108d908590611f3b565b60405180910390a3505050565b806110a361113d565b60010190805190602001906109679291906119d3565b6110c4848484610e70565b6110d08484848461127d565b610b735760405162461bcd60e51b8152600401610367906120c0565b806110f561113d565b815161096792602001906119d3565b60008061110f61113d565b60009384526002016020526040909220546001600160a01b031690911415919050565b606061030682611391565b60006103186115b3565b61114f61113d565b60008281526004919091016020526040902080546001600160a01b0319169055600161117961113d565b6003016000856001600160a01b03166001600160a01b0316815260200190815260200160002060008282546111ae919061214c565b90915550600190506111be61113d565b6003016000846001600160a01b03166001600160a01b0316815260200190815260200160002060008282546111f39190612120565b9091555082905061120261113d565b6000838152600291909101602052604080822080546001600160a01b0319166001600160a01b0394851617905551839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a46103b282826115d7565b6000610306826115e1565b61127b6116b5565b565b6000611291846001600160a01b03166116d3565b1561138657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906112c8903390899088908890600401611e9e565b602060405180830381600087803b1580156112e257600080fd5b505af1925050508015611312575060408051601f3d908101601f1916820190925261130f91810190611c96565b60015b61136c573d808015611340576040519150601f19603f3d011682016040523d82523d6000602084013e611345565b606091505b5080516113645760405162461bcd60e51b8152600401610367906120c0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610e68565b506001949350505050565b606061139c826116e2565b6113b85760405162461bcd60e51b815260040161036790612010565b6113c06116ed565b6002015460ff1615611413576113d46116ed565b6003016113e0836116f7565b6113e86116ed565b6004016040516020016113fd93929190611e57565b6040516020818303038152906040529050610309565b600061141d6116ed565b600084815260059190910160205260409020805461143a9061218f565b80601f01602080910402602001604051908101604052809291908181526020018280546114669061218f565b80156114b35780601f10611488576101008083540402835291602001916114b3565b820191906000526020600020905b81548152906001019060200180831161149657829003601f168201915b50505050509050805160001415611560576114cc6116ed565b60010180546114da9061218f565b80601f01602080910402602001604051908101604052809291908181526020018280546115069061218f565b80156115535780601f1061152857610100808354040283529160200191611553565b820191906000526020600020905b81548152906001019060200180831161153657829003601f168201915b5050505050915050610309565b6115686116ed565b80546115739061218f565b15159050611582579050610309565b61158a6116ed565b60405161159c91908390602001611e32565b604051602081830303815290604052915050919050565b7fd7aeb8e4f0c59b8cd9990692700804773e94b3a69feac86b7147c9c8edad330c90565b6109678282611812565b6000806115ec61184c565b5490506115f761184c565b600401541580611612575061160a61184c565b600401548111155b61162e5760405162461bcd60e51b8152600401610367906120a0565b600161163861184c565b8054600090611648908490612120565b90915550506001600160a01b038316301415611678576116683382611856565b611673333083610932565b61168d565b6116823082611856565b61168d308483610932565b600161169761184c565b60050160008282546116a99190612120565b90915550909392505050565b60016116bf611860565b6003015560006116cd611860565b60050155565b6001600160a01b03163b151590565b600061030682611104565b600061031861186a565b60608161171c57506040805180820190915260018152600360fc1b6020820152610309565b8160005b81156117465780611730816121ca565b915061173f9050600a83612138565b9150611720565b60008167ffffffffffffffff81111561176f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611799576020820181803683370190505b5090505b8415610e68576117ae60018361214c565b91506117bb600a866121e5565b6117c6906030612120565b60f81b8183815181106117e957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061180b600a86612138565b945061179d565b61181a6116ed565b6001600160a01b0390921660009081526006929092016020908152604083208054600181018255908452922090910155565b600061031861188e565b61096782826118b2565b60006103186119af565b7f73fe048652e51f080002cab7173201110a5a7526ce7d7ec1a97184a03368b94f90565b7f03cd5238ba7b5bfbba66bfdb519abdd9e7b08e4c8df3a518a3d0d7ab9a5c495a90565b6001600160a01b0382166118d85760405162461bcd60e51b815260040161036790611feb565b6118e181611104565b156118fe5760405162461bcd60e51b815260040161036790611f7d565b600161190861113d565b6003016000846001600160a01b03166001600160a01b03168152602001908152602001600020600082825461193d9190612120565b9091555082905061194c61113d565b6000838152600291909101602052604080822080546001600160a01b0319166001600160a01b03948516179055518392851691907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461096782826115d7565b7f1112f5cf60fb4141783e19a055147d95474ef924bfa04c648816921afcffeb7490565b8280546119df9061218f565b90600052602060002090601f016020900481019282611a015760008555611a47565b82601f10611a1a57805160ff1916838001178555611a47565b82800160010185558215611a47579182015b82811115611a47578251825591602001919060010190611a2c565b50611a53929150611a57565b5090565b5b80821115611a535760008155600101611a58565b600067ffffffffffffffff80841115611a8757611a87612225565b604051601f8501601f19908116603f01168101908282118183101715611aaf57611aaf612225565b81604052809350858152868686011115611ac857600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461030957600080fd5b8035801515811461030957600080fd5b600082601f830112611b19578081fd5b610bbe83833560208501611a6c565b600060208284031215611b39578081fd5b610bbe82611ae2565b60008060408385031215611b54578081fd5b611b5d83611ae2565b9150611b6b60208401611ae2565b90509250929050565b600080600060608486031215611b88578081fd5b611b9184611ae2565b9250611b9f60208501611ae2565b9150604084013590509250925092565b60008060008060808587031215611bc4578081fd5b611bcd85611ae2565b9350611bdb60208601611ae2565b925060408501359150606085013567ffffffffffffffff811115611bfd578182fd5b8501601f81018713611c0d578182fd5b611c1c87823560208401611a6c565b91505092959194509250565b60008060408385031215611c3a578182fd5b611c4383611ae2565b9150611b6b60208401611af9565b60008060408385031215611c63578182fd5b611c6c83611ae2565b946020939093013593505050565b600060208284031215611c8b578081fd5b8135610bbe8161223b565b600060208284031215611ca7578081fd5b8151610bbe8161223b565b600060208284031215611cc3578081fd5b813567ffffffffffffffff811115611cd9578182fd5b610e6884828501611b09565b600080600060608486031215611cf9578283fd5b833567ffffffffffffffff80821115611d10578485fd5b611d1c87838801611b09565b94506020860135915080821115611d31578384fd5b50611d3e86828701611b09565b925050611d4d60408501611af9565b90509250925092565b600060208284031215611d67578081fd5b5035919050565b60008151808452611d86816020860160208601612163565b601f01601f19169290920160200192915050565b805460009060028104600180831680611db457607f831692505b6020808410821415611dd457634e487b7160e01b86526022600452602486fd5b818015611de85760018114611df957611e26565b60ff19861689528489019650611e26565b611e0288612114565b60005b86811015611e1e5781548b820152908501908301611e05565b505084890196505b50505050505092915050565b6000611e3e8285611d9a565b8351611e4e818360208801612163565b01949350505050565b6000611e638286611d9a565b8451611e73818360208901612163565b611e7f81830186611d9a565b979650505050505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ed190830184611d6e565b9695505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611f2e57603f19888603018452611f1c858351611d6e565b94509285019290850190600101611f00565b5092979650505050505050565b901515815260200190565b600060208252610bbe6020830184611d6e565b6020808252600a9082015269455243373231493a5a4160b01b604082015260600190565b6020808252600b908201526a455243373231493a54414d60a81b604082015260600190565b6020808252600b908201526a115490cdcc8c518e93915560aa1b604082015260600190565b6020808252600a9082015269455243373231493a494f60b01b604082015260600190565b6020808252600b908201526a455243373231493a4d5a4160a81b604082015260600190565b6020808252600790820152661514d24e93915560ca1b604082015260600190565b6020808252600b908201526a115490cdcc8c524e93915560aa1b604082015260600190565b6020808252600b908201526a455243373231463a41544360a81b604082015260600190565b6020808252600b908201526a455243373231493a41544360a81b604082015260600190565b60208082526006908201526509a92749a82b60d31b604082015260600190565b6020808252600d908201526c455243373231463a424144544f60981b604082015260600190565b6020808252600a9082015269455243373231463a4e4f60b01b604082015260600190565b90815260200190565b60009081526020902090565b60008219821115612133576121336121f9565b500190565b6000826121475761214761220f565b500490565b60008282101561215e5761215e6121f9565b500390565b60005b8381101561217e578181015183820152602001612166565b83811115610b735750506000910152565b6002810460018216806121a357607f821691505b602082108114156121c457634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156121de576121de6121f9565b5060010190565b6000826121f4576121f461220f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610b3e57600080fdfe7472616e7366657246726f6d28616464726573732c616464726573732c75696e7432353629736166655472616e7366657246726f6d28616464726573732c616464726573732c75696e743235362973657445524337323153657474696e677328737472696e672c737472696e672c626f6f6c29736166655472616e7366657246726f6d28616464726573732c616464726573732c75696e743235362c6279746573296973417070726f766564466f72416c6c28616464726573732c6164647265737329a26469706673582212203179831d42e2632a1c0e18d22fe4e2867d56d9b7e5353a4bc8bceab84f760dcd64736f6c63430008010033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c806368498a33116100b8578063b84c82461161007c578063b84c82461461026e578063b88d4fde14610281578063c47f002714610294578063c87b56dd146102a7578063e985e9c5146102ba578063f8c2be4f146102cd57610137565b806368498a331461021857806370a08231146102205780637de062db1461024057806395d89b4114610253578063a22cb4651461025b57610137565b806323b872dd116100ff57806323b872dd146101c4578063320dcd97146101d757806340cc7925146101df57806342842e0e146101f25780636352211e1461020557610137565b806301ffc9a71461013c57806306fdde0314610165578063081812fc1461017a578063095ea7b31461019a5780631078fade146101af575b600080fd5b61014f61014a366004611c7a565b6102d5565b60405161015c9190611f3b565b60405180910390f35b61016d61030e565b60405161015c9190611f46565b61018d610188366004611d56565b61031d565b60405161015c9190611e8a565b6101ad6101a8366004611c51565b610328565b005b6101b76103b7565b60405161015c9190611edb565b6101ad6101d2366004611b74565b61090c565b61016d61093d565b6101ad6101ed366004611c51565b61095d565b6101ad610200366004611b74565b61096b565b61018d610213366004611d56565b610986565b6101b7610991565b61023361022e366004611b28565b610b0a565b60405161015c919061210b565b6101ad61024e366004611ce5565b610b15565b61016d610b20565b6101ad610269366004611c28565b610b2a565b6101ad61027c366004611cb2565b610b35565b6101ad61028f366004611baf565b610b41565b6101ad6102a2366004611cb2565b610b79565b61016d6102b5366004611d56565b610b82565b61014f6102c8366004611b42565b610bb2565b61016d610bc5565b60006001600160e01b0319821663b2fe033560e01b148061030657506001600160e01b031982166380ac58cd60e01b145b90505b919050565b6060610318610be4565b905090565b600061030682610c7c565b600061033382610cd4565b9050806001600160a01b0316836001600160a01b031614156103705760405162461bcd60e51b815260040161036790612056565b60405180910390fd5b336001600160a01b038216148061038c575061038c8133610d1a565b6103a85760405162461bcd60e51b8152600401610367906120e7565b6103b28383610d57565b505050565b604080516010808252610220820190925260609160009190816020015b60608152602001906001900390816103d45790505090506040518060600160405280602581526020016122a0602591398160008151811061042557634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601281526020017162616c616e63654f6628616464726573732960701b8152508160018151811061047c57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601081526020016f6f776e65724f662875696e743235362960801b815250816002815181106104d157634e487b7160e01b600052603260045260246000fd5b6020026020010181905250604051806040016040528060068152602001656e616d65282960d01b8152508160038151811061051c57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600f81526020016e7365744e616d6528737472696e672960881b8152508160048151811061057057634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600881526020016773796d626f6c282960c01b815250816005815181106105bd57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017073657453796d626f6c28737472696e672960781b8152508160068151811061061357634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806011815260200170746f6b656e5552492875696e743235362960781b8152508160078151811061066957634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601881526020017f617070726f766528616464726573732c75696e74323536290000000000000000815250816008815181106106cb57634e487b7160e01b600052603260045260246000fd5b602002602001018190525060405180604001604052806014815260200173676574417070726f7665642875696e743235362960601b8152508160098151811061072457634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f736574417070726f76616c466f72416c6c28616464726573732c626f6f6c290081525081600a8151811061078657634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602181526020016122f46021913981600b815181106107cb57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f7472616e7366657246726f6d4d6528616464726573732c75696e74323536290081525081600c8151811061082d57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602581526020016122526025913981600d8151811061087257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602981526020016122776029913981600e815181106108b757634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060600160405280602f81526020016122c5602f913981600f815181106108fc57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152905090565b6109163382610dd2565b6109325760405162461bcd60e51b8152600401610367906120e7565b6103b2838383610e70565b60408051808201909152600681526565726337323160d01b602082015290565b6109678282610eda565b5050565b6103b283838360405180602001604052806000815250610b41565b600061030682610cd4565b60408051600480825260a0820190925260609160009190816020015b60608152602001906001900390816109ad5790505090506040518060600160405280602581526020016122a060259139816000815181106109fe57634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280600f81526020016e7365744e616d6528737472696e672960881b81525081600181518110610a5257634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601181526020017073657453796d626f6c28737472696e672960781b81525081600281518110610aa857634e487b7160e01b600052603260045260246000fd5b60200260200101819052506040518060400160405280601f81526020017f7472616e7366657246726f6d4d6528616464726573732c75696e743235362900815250816003815181106108fc57634e487b7160e01b600052603260045260246000fd5b600061030682610f3b565b6103b2838383610f8d565b6060610318610fca565b610967338383610fe2565b610b3e8161109a565b50565b610b4b3383610dd2565b610b675760405162461bcd60e51b8152600401610367906120e7565b610b73848484846110b9565b50505050565b610b3e816110ec565b6060610b8d82611104565b610ba95760405162461bcd60e51b815260040161036790611fa2565b61030682611132565b6000610bbe8383610d1a565b9392505050565b6040805180820190915260058152640332e302e360dc1b602082015290565b6060610bee61113d565b8054610bf99061218f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c259061218f565b8015610c725780601f10610c4757610100808354040283529160200191610c72565b820191906000526020600020905b815481529060010190602001808311610c5557829003601f168201915b5050505050905090565b600080610c8883610cd4565b6001600160a01b03161415610caf5760405162461bcd60e51b815260040161036790612031565b610cb761113d565b60009283526004016020525060409020546001600160a01b031690565b600080610cdf61113d565b600084815260029190910160205260409020546001600160a01b03169050806103065760405162461bcd60e51b815260040161036790612031565b6000610d2461113d565b6001600160a01b039384166000908152600591909101602090815260408083209490951682529290925250205460ff1690565b81610d6061113d565b60008381526004919091016020526040902080546001600160a01b0319166001600160a01b0392831617905581908316610d9982610cd4565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600080610dde83610cd4565b9050806001600160a01b0316846001600160a01b03161480610e325750610e0361113d565b6001600160a01b03808316600090815260059290920160209081526040808420928816845291905290205460ff165b80610e685750836001600160a01b0316610e4a61113d565b600085815260049190910160205260409020546001600160a01b0316145b949350505050565b826001600160a01b0316610e8382610cd4565b6001600160a01b031614610ea95760405162461bcd60e51b815260040161036790611fc7565b6001600160a01b038216610ecf5760405162461bcd60e51b815260040161036790611f59565b6103b2838383611147565b30610ee482610cd4565b6001600160a01b031614610f0a5760405162461bcd60e51b815260040161036790611fc7565b6001600160a01b038216610f305760405162461bcd60e51b815260040161036790611f59565b610967308383611147565b60006001600160a01b038216610f635760405162461bcd60e51b815260040161036790611f59565b610f6b61113d565b6001600160a01b03929092166000908152600390920160205250604090205490565b610f96836110ec565b610f9f8261109a565b808015610fb35750610fb16000611104565b155b156103b257610fc130611268565b506103b2611273565b6060610fd461113d565b6001018054610bf99061218f565b816001600160a01b0316836001600160a01b031614156110145760405162461bcd60e51b81526004016103679061207b565b8061101d61113d565b6001600160a01b038581166000818152600593909301602090815260408085209388168086529390915292839020805460ff19169415159490941790935590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319061108d908590611f3b565b60405180910390a3505050565b806110a361113d565b60010190805190602001906109679291906119d3565b6110c4848484610e70565b6110d08484848461127d565b610b735760405162461bcd60e51b8152600401610367906120c0565b806110f561113d565b815161096792602001906119d3565b60008061110f61113d565b60009384526002016020526040909220546001600160a01b031690911415919050565b606061030682611391565b60006103186115b3565b61114f61113d565b60008281526004919091016020526040902080546001600160a01b0319169055600161117961113d565b6003016000856001600160a01b03166001600160a01b0316815260200190815260200160002060008282546111ae919061214c565b90915550600190506111be61113d565b6003016000846001600160a01b03166001600160a01b0316815260200190815260200160002060008282546111f39190612120565b9091555082905061120261113d565b6000838152600291909101602052604080822080546001600160a01b0319166001600160a01b0394851617905551839285811692908716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9190a46103b282826115d7565b6000610306826115e1565b61127b6116b5565b565b6000611291846001600160a01b03166116d3565b1561138657604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906112c8903390899088908890600401611e9e565b602060405180830381600087803b1580156112e257600080fd5b505af1925050508015611312575060408051601f3d908101601f1916820190925261130f91810190611c96565b60015b61136c573d808015611340576040519150601f19603f3d011682016040523d82523d6000602084013e611345565b606091505b5080516113645760405162461bcd60e51b8152600401610367906120c0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610e68565b506001949350505050565b606061139c826116e2565b6113b85760405162461bcd60e51b815260040161036790612010565b6113c06116ed565b6002015460ff1615611413576113d46116ed565b6003016113e0836116f7565b6113e86116ed565b6004016040516020016113fd93929190611e57565b6040516020818303038152906040529050610309565b600061141d6116ed565b600084815260059190910160205260409020805461143a9061218f565b80601f01602080910402602001604051908101604052809291908181526020018280546114669061218f565b80156114b35780601f10611488576101008083540402835291602001916114b3565b820191906000526020600020905b81548152906001019060200180831161149657829003601f168201915b50505050509050805160001415611560576114cc6116ed565b60010180546114da9061218f565b80601f01602080910402602001604051908101604052809291908181526020018280546115069061218f565b80156115535780601f1061152857610100808354040283529160200191611553565b820191906000526020600020905b81548152906001019060200180831161153657829003601f168201915b5050505050915050610309565b6115686116ed565b80546115739061218f565b15159050611582579050610309565b61158a6116ed565b60405161159c91908390602001611e32565b604051602081830303815290604052915050919050565b7fd7aeb8e4f0c59b8cd9990692700804773e94b3a69feac86b7147c9c8edad330c90565b6109678282611812565b6000806115ec61184c565b5490506115f761184c565b600401541580611612575061160a61184c565b600401548111155b61162e5760405162461bcd60e51b8152600401610367906120a0565b600161163861184c565b8054600090611648908490612120565b90915550506001600160a01b038316301415611678576116683382611856565b611673333083610932565b61168d565b6116823082611856565b61168d308483610932565b600161169761184c565b60050160008282546116a99190612120565b90915550909392505050565b60016116bf611860565b6003015560006116cd611860565b60050155565b6001600160a01b03163b151590565b600061030682611104565b600061031861186a565b60608161171c57506040805180820190915260018152600360fc1b6020820152610309565b8160005b81156117465780611730816121ca565b915061173f9050600a83612138565b9150611720565b60008167ffffffffffffffff81111561176f57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611799576020820181803683370190505b5090505b8415610e68576117ae60018361214c565b91506117bb600a866121e5565b6117c6906030612120565b60f81b8183815181106117e957634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061180b600a86612138565b945061179d565b61181a6116ed565b6001600160a01b0390921660009081526006929092016020908152604083208054600181018255908452922090910155565b600061031861188e565b61096782826118b2565b60006103186119af565b7f73fe048652e51f080002cab7173201110a5a7526ce7d7ec1a97184a03368b94f90565b7f03cd5238ba7b5bfbba66bfdb519abdd9e7b08e4c8df3a518a3d0d7ab9a5c495a90565b6001600160a01b0382166118d85760405162461bcd60e51b815260040161036790611feb565b6118e181611104565b156118fe5760405162461bcd60e51b815260040161036790611f7d565b600161190861113d565b6003016000846001600160a01b03166001600160a01b03168152602001908152602001600020600082825461193d9190612120565b9091555082905061194c61113d565b6000838152600291909101602052604080822080546001600160a01b0319166001600160a01b03948516179055518392851691907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a461096782826115d7565b7f1112f5cf60fb4141783e19a055147d95474ef924bfa04c648816921afcffeb7490565b8280546119df9061218f565b90600052602060002090601f016020900481019282611a015760008555611a47565b82601f10611a1a57805160ff1916838001178555611a47565b82800160010185558215611a47579182015b82811115611a47578251825591602001919060010190611a2c565b50611a53929150611a57565b5090565b5b80821115611a535760008155600101611a58565b600067ffffffffffffffff80841115611a8757611a87612225565b604051601f8501601f19908116603f01168101908282118183101715611aaf57611aaf612225565b81604052809350858152868686011115611ac857600080fd5b858560208301376000602087830101525050509392505050565b80356001600160a01b038116811461030957600080fd5b8035801515811461030957600080fd5b600082601f830112611b19578081fd5b610bbe83833560208501611a6c565b600060208284031215611b39578081fd5b610bbe82611ae2565b60008060408385031215611b54578081fd5b611b5d83611ae2565b9150611b6b60208401611ae2565b90509250929050565b600080600060608486031215611b88578081fd5b611b9184611ae2565b9250611b9f60208501611ae2565b9150604084013590509250925092565b60008060008060808587031215611bc4578081fd5b611bcd85611ae2565b9350611bdb60208601611ae2565b925060408501359150606085013567ffffffffffffffff811115611bfd578182fd5b8501601f81018713611c0d578182fd5b611c1c87823560208401611a6c565b91505092959194509250565b60008060408385031215611c3a578182fd5b611c4383611ae2565b9150611b6b60208401611af9565b60008060408385031215611c63578182fd5b611c6c83611ae2565b946020939093013593505050565b600060208284031215611c8b578081fd5b8135610bbe8161223b565b600060208284031215611ca7578081fd5b8151610bbe8161223b565b600060208284031215611cc3578081fd5b813567ffffffffffffffff811115611cd9578182fd5b610e6884828501611b09565b600080600060608486031215611cf9578283fd5b833567ffffffffffffffff80821115611d10578485fd5b611d1c87838801611b09565b94506020860135915080821115611d31578384fd5b50611d3e86828701611b09565b925050611d4d60408501611af9565b90509250925092565b600060208284031215611d67578081fd5b5035919050565b60008151808452611d86816020860160208601612163565b601f01601f19169290920160200192915050565b805460009060028104600180831680611db457607f831692505b6020808410821415611dd457634e487b7160e01b86526022600452602486fd5b818015611de85760018114611df957611e26565b60ff19861689528489019650611e26565b611e0288612114565b60005b86811015611e1e5781548b820152908501908301611e05565b505084890196505b50505050505092915050565b6000611e3e8285611d9a565b8351611e4e818360208801612163565b01949350505050565b6000611e638286611d9a565b8451611e73818360208901612163565b611e7f81830186611d9a565b979650505050505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090611ed190830184611d6e565b9695505050505050565b6000602080830181845280855180835260408601915060408482028701019250838701855b82811015611f2e57603f19888603018452611f1c858351611d6e565b94509285019290850190600101611f00565b5092979650505050505050565b901515815260200190565b600060208252610bbe6020830184611d6e565b6020808252600a9082015269455243373231493a5a4160b01b604082015260600190565b6020808252600b908201526a455243373231493a54414d60a81b604082015260600190565b6020808252600b908201526a115490cdcc8c518e93915560aa1b604082015260600190565b6020808252600a9082015269455243373231493a494f60b01b604082015260600190565b6020808252600b908201526a455243373231493a4d5a4160a81b604082015260600190565b6020808252600790820152661514d24e93915560ca1b604082015260600190565b6020808252600b908201526a115490cdcc8c524e93915560aa1b604082015260600190565b6020808252600b908201526a455243373231463a41544360a81b604082015260600190565b6020808252600b908201526a455243373231493a41544360a81b604082015260600190565b60208082526006908201526509a92749a82b60d31b604082015260600190565b6020808252600d908201526c455243373231463a424144544f60981b604082015260600190565b6020808252600a9082015269455243373231463a4e4f60b01b604082015260600190565b90815260200190565b60009081526020902090565b60008219821115612133576121336121f9565b500190565b6000826121475761214761220f565b500490565b60008282101561215e5761215e6121f9565b500390565b60005b8381101561217e578181015183820152602001612166565b83811115610b735750506000910152565b6002810460018216806121a357607f821691505b602082108114156121c457634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156121de576121de6121f9565b5060010190565b6000826121f4576121f461220f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610b3e57600080fdfe7472616e7366657246726f6d28616464726573732c616464726573732c75696e7432353629736166655472616e7366657246726f6d28616464726573732c616464726573732c75696e743235362973657445524337323153657474696e677328737472696e672c737472696e672c626f6f6c29736166655472616e7366657246726f6d28616464726573732c616464726573732c75696e743235362c6279746573296973417070726f766564466f72416c6c28616464726573732c6164647265737329a26469706673582212203179831d42e2632a1c0e18d22fe4e2867d56d9b7e5353a4bc8bceab84f760dcd64736f6c63430008010033
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.