Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract contains unverified libraries: __CACHE_BREAKER__
Contract Source Code Verified (Exact Match)
Contract Name:
OnCyberCommunityFactoryFacet
Compiler Version
v0.8.15+commit.e14f2714
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '../../CyberDropBase.sol'; contract OnCyberCommunityFactoryFacet is CyberDropBase {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import '@openzeppelin/contracts/utils/Context.sol'; import './BaseRelayRecipientStorage.sol'; /** * A base contract to be inherited by any contract that want to receive relayed transactions * A subclass must use "_msgSender()" instead of "msg.sender" */ abstract contract BaseRelayRecipient is Context { /* * require a function to be called through GSN only */ // modifier trustedForwarderOnly() { // require(msg.sender == address(s.trustedForwarder), "Function can only be called through the trusted Forwarder"); // _; // } function isTrustedForwarder(address forwarder) public view returns (bool) { return forwarder == BaseRelayRecipientStorage.layout().trustedForwarder; } /** * return the sender of this call. * if the call came through our trusted forwarder, return the original sender. * otherwise, return `msg.sender`. * should be used in the contract anywhere instead of msg.sender */ function _msgSender() internal view virtual override returns (address ret) { if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) { // At this point we know that the sender is a trusted forwarder, // so we trust that the last bytes of msg.data are the verified sender address. // extract sender address from the end of msg.data assembly { ret := shr(96, calldataload(sub(calldatasize(), 20))) } } else { return msg.sender; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; library BaseRelayRecipientStorage { bytes32 internal constant STORAGE_SLOT = keccak256('diamond.storage.BaseRelayRecipientStorage'); struct Layout { /* * Forwarder singleton we accept calls from */ address trustedForwarder; } function layout() internal pure returns (Layout storage lay) { bytes32 slot = STORAGE_SLOT; assembly { lay.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; import '@openzeppelin/contracts/utils/Counters.sol'; import '@solidstate/contracts/token/ERC1155/IERC1155.sol'; import './BaseRelayRecipient/BaseRelayRecipient.sol'; import './BaseRelayRecipient/BaseRelayRecipientStorage.sol'; import './Diamond/LibDiamond.sol'; import './ERC1155URI/ERC1155URI.sol'; import './libraries/LibAppStorage.sol'; contract CyberTokenBase is BaseRelayRecipient, ERC1155URI { using ECDSA for bytes32; using Counters for Counters.Counter; event Minted(address indexed account, uint256 indexed tokenId, uint256 indexed amount); function initialize( string memory _uri, address _manager, address _trustedForwarder, address _opensea, address _oncyber ) public virtual { require(LibDiamond.diamondStorage().contractOwner == msg.sender, 'NO'); BaseRelayRecipientStorage.layout().trustedForwarder = _trustedForwarder; LibDiamond.diamondStorage().supportedInterfaces[type(IERC1155).interfaceId] = true; setURI(_uri); LibAppStorage.layout().manager = _manager; LibAppStorage.layout().opensea = _opensea; LibAppStorage.layout().oncyber = _oncyber; } function totalSupply() public view returns (uint256) { return LibAppStorage.layout().totalSupply.current(); } function manager() public view returns (address) { return LibAppStorage.layout().manager; } function oncyber() public view returns (address) { return LibAppStorage.layout().oncyber; } function minterNonce(address _minter) public view returns (uint256) { return LibAppStorage.layout().minterNonce[_minter].current(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../Strings.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC1155Internal } from './IERC1155Internal.sol'; import { IERC165 } from '../../introspection/IERC165.sol'; /** * @notice ERC1155 interface * @dev see https://github.com/ethereum/EIPs/issues/1155 */ interface IERC1155 is IERC1155Internal, IERC165 { /** * @notice query the balance of given token held by given address * @param account address to query * @param id token to query * @return token balance */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @notice query the balances of given tokens held by given addresses * @param accounts addresss to query * @param ids tokens to query * @return token balances */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @notice query approval status of given operator with respect to given address * @param account address to query for approval granted * @param operator address to query for approval received * @return whether operator is approved to spend tokens held by account */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @notice grant approval to or revoke approval from given operator to spend held tokens * @param operator address whose approval status to update * @param status whether operator should be considered approved */ function setApprovalForAll(address operator, bool status) external; /** * @notice transfer tokens between given addresses, checking for ERC1155Receiver implementation if applicable * @param from sender of tokens * @param to receiver of tokens * @param id token ID * @param amount quantity of tokens to transfer * @param data data payload */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @notice transfer batch of tokens between given addresses, checking for ERC1155Receiver implementation if applicable * @param from sender of tokens * @param to receiver of tokens * @param ids list of token IDs * @param amounts list of quantities of tokens to transfer * @param data data payload */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamond Standard: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ library LibDiamond { bytes32 public constant DIAMOND_STORAGE_POSITION = keccak256('diamond.standard.diamond.storage'); struct FacetAddressAndPosition { address facetAddress; uint16 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint16 facetAddressPosition; // position of facetAddress in facetAddresses array } struct DiamondStorage { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; // facet addresses address[] facetAddresses; // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import '@solidstate/contracts/token/ERC1155/ERC1155.sol'; import './ERC1155URIStorage.sol'; abstract contract ERC1155URI is ERC1155 { function uri(uint256 _tokenId) public view virtual override returns (string memory) { string memory tokenURI = ERC1155URIStorage.layout().tokenURIs[_tokenId]; require(bytes(tokenURI).length != 0, 'ERC1155URI: tokenId not exist'); return string(abi.encodePacked(ERC1155URIStorage.layout().uri, tokenURI)); } function setURI(string memory newUri) internal virtual { ERC1155URIStorage.layout().uri = newUri; } function setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { ERC1155URIStorage.layout().tokenURIs[tokenId] = _tokenURI; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import '@openzeppelin/contracts/utils/Counters.sol'; // library LibAppStorage { bytes32 public constant STORAGE_SLOT = keccak256('app.storage'); struct Layout { address manager; address opensea; Counters.Counter totalSupply; mapping(address => Counters.Counter) minterNonce; address oncyber; } function layout() internal pure returns (Layout storage lay) { bytes32 slot = STORAGE_SLOT; assembly { lay.slot := slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from '../../introspection/IERC165.sol'; /** * @notice Partial ERC1155 interface needed by internal functions */ interface IERC1155Internal { event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); event ApprovalForAll( address indexed account, address indexed operator, bool approved ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC165 interface registration interface * @dev see https://eips.ethereum.org/EIPS/eip-165 */ interface IERC165 { /** * @notice query whether contract has registered support for given interface * @param interfaceId interface id * @return bool whether interface is supported */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { ERC165 } from '../../introspection/ERC165.sol'; import { ERC1155Base, ERC1155BaseInternal } from './base/ERC1155Base.sol'; import { ERC1155Enumerable } from './enumerable/ERC1155Enumerable.sol'; import { ERC1155Metadata } from './metadata/ERC1155Metadata.sol'; /** * @title SolidState ERC1155 implementation */ abstract contract ERC1155 is ERC1155Base, ERC1155Enumerable, ERC1155Metadata, ERC165 { /** * @inheritdoc ERC1155BaseInternal */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override(ERC1155BaseInternal, ERC1155Enumerable) { super._beforeTokenTransfer(operator, from, to, ids, amounts, data); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; library ERC1155URIStorage { bytes32 internal constant STORAGESLOT = keccak256('diamond.storage.ERC1155URI'); struct Layout { mapping(uint256 => string) tokenURIs; string uri; } function layout() internal pure returns (Layout storage lay) { bytes32 slot = STORAGESLOT; assembly { lay.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from './IERC165.sol'; import { ERC165Storage } from './ERC165Storage.sol'; /** * @title ERC165 implementation */ abstract contract ERC165 is IERC165 { using ERC165Storage for ERC165Storage.Layout; /** * @inheritdoc IERC165 */ function supportsInterface(bytes4 interfaceId) public view override returns (bool) { return ERC165Storage.layout().isSupportedInterface(interfaceId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC1155 } from '../IERC1155.sol'; import { IERC1155Receiver } from '../IERC1155Receiver.sol'; import { ERC1155BaseInternal, ERC1155BaseStorage } from './ERC1155BaseInternal.sol'; /** * @title Base ERC1155 contract * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license) */ abstract contract ERC1155Base is IERC1155, ERC1155BaseInternal { /** * @inheritdoc IERC1155 */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { return _balanceOf(account, id); } /** * @inheritdoc IERC1155 */ function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual override returns (uint256[] memory) { require( accounts.length == ids.length, 'ERC1155: accounts and ids length mismatch' ); mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155BaseStorage.layout().balances; uint256[] memory batchBalances = new uint256[](accounts.length); unchecked { for (uint256 i; i < accounts.length; i++) { require( accounts[i] != address(0), 'ERC1155: batch balance query for the zero address' ); batchBalances[i] = balances[ids[i]][accounts[i]]; } } return batchBalances; } /** * @inheritdoc IERC1155 */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return ERC1155BaseStorage.layout().operatorApprovals[account][operator]; } /** * @inheritdoc IERC1155 */ function setApprovalForAll(address operator, bool status) public virtual override { require( msg.sender != operator, 'ERC1155: setting approval status for self' ); ERC1155BaseStorage.layout().operatorApprovals[msg.sender][ operator ] = status; emit ApprovalForAll(msg.sender, operator, status); } /** * @inheritdoc IERC1155 */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { require( from == msg.sender || isApprovedForAll(from, msg.sender), 'ERC1155: caller is not owner nor approved' ); _safeTransfer(msg.sender, from, to, id, amount, data); } /** * @inheritdoc IERC1155 */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { require( from == msg.sender || isApprovedForAll(from, msg.sender), 'ERC1155: caller is not owner nor approved' ); _safeTransferBatch(msg.sender, from, to, ids, amounts, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../../utils/EnumerableSet.sol'; import { ERC1155Base, ERC1155BaseInternal } from '../base/ERC1155Base.sol'; import { IERC1155Enumerable } from './IERC1155Enumerable.sol'; import { ERC1155EnumerableInternal, ERC1155EnumerableStorage } from './ERC1155EnumerableInternal.sol'; /** * @title ERC1155 implementation including enumerable and aggregate functions */ abstract contract ERC1155Enumerable is IERC1155Enumerable, ERC1155Base, ERC1155EnumerableInternal { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; /** * @inheritdoc IERC1155Enumerable */ function totalSupply(uint256 id) public view virtual override returns (uint256) { return ERC1155EnumerableStorage.layout().totalSupply[id]; } /** * @inheritdoc IERC1155Enumerable */ function totalHolders(uint256 id) public view virtual override returns (uint256) { return ERC1155EnumerableStorage.layout().accountsByToken[id].length(); } /** * @inheritdoc IERC1155Enumerable */ function accountsByToken(uint256 id) public view virtual override returns (address[] memory) { EnumerableSet.AddressSet storage accounts = ERC1155EnumerableStorage .layout() .accountsByToken[id]; address[] memory addresses = new address[](accounts.length()); for (uint256 i; i < accounts.length(); i++) { addresses[i] = accounts.at(i); } return addresses; } /** * @inheritdoc IERC1155Enumerable */ function tokensByAccount(address account) public view virtual override returns (uint256[] memory) { EnumerableSet.UintSet storage tokens = ERC1155EnumerableStorage .layout() .tokensByAccount[account]; uint256[] memory ids = new uint256[](tokens.length()); for (uint256 i; i < tokens.length(); i++) { ids[i] = tokens.at(i); } return ids; } /** * @notice ERC1155 hook: update aggregate values * @inheritdoc ERC1155EnumerableInternal */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override(ERC1155BaseInternal, ERC1155EnumerableInternal) { super._beforeTokenTransfer(operator, from, to, ids, amounts, data); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { UintUtils } from '../../../utils/UintUtils.sol'; import { IERC1155Metadata } from './IERC1155Metadata.sol'; import { ERC1155MetadataInternal } from './ERC1155MetadataInternal.sol'; import { ERC1155MetadataStorage } from './ERC1155MetadataStorage.sol'; /** * @notice ERC1155 metadata extensions */ abstract contract ERC1155Metadata is IERC1155Metadata, ERC1155MetadataInternal { using UintUtils for uint256; /** * @notice inheritdoc IERC1155Metadata */ function uri(uint256 tokenId) public view virtual override returns (string memory) { ERC1155MetadataStorage.Layout storage l = ERC1155MetadataStorage .layout(); string memory tokenIdURI = l.tokenURIs[tokenId]; string memory baseURI = l.baseURI; if (bytes(baseURI).length == 0) { return tokenIdURI; } else if (bytes(tokenIdURI).length > 0) { return string(abi.encodePacked(baseURI, tokenIdURI)); } else { return string(abi.encodePacked(baseURI, tokenId.toString())); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library ERC165Storage { struct Layout { mapping(bytes4 => bool) supportedInterfaces; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC165'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } function isSupportedInterface(Layout storage l, bytes4 interfaceId) internal view returns (bool) { return l.supportedInterfaces[interfaceId]; } function setSupportedInterface( Layout storage l, bytes4 interfaceId, bool status ) internal { require(interfaceId != 0xffffffff, 'ERC165: invalid interface id'); l.supportedInterfaces[interfaceId] = status; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC165 } from '../../introspection/IERC165.sol'; /** * @title ERC1155 transfer receiver interface */ interface IERC1155Receiver is IERC165 { /** * @notice validate receipt of ERC1155 transfer * @param operator executor of transfer * @param from sender of tokens * @param id token ID received * @param value quantity of tokens received * @param data data payload * @return function's own selector if transfer is accepted */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @notice validate receipt of ERC1155 batch transfer * @param operator executor of transfer * @param from sender of tokens * @param ids token IDs received * @param values quantities of tokens received * @param data data payload * @return function's own selector if transfer is accepted */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { AddressUtils } from '../../../utils/AddressUtils.sol'; import { IERC1155Internal } from '../IERC1155Internal.sol'; import { IERC1155Receiver } from '../IERC1155Receiver.sol'; import { ERC1155BaseStorage } from './ERC1155BaseStorage.sol'; /** * @title Base ERC1155 internal functions * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license) */ abstract contract ERC1155BaseInternal is IERC1155Internal { using AddressUtils for address; /** * @notice query the balance of given token held by given address * @param account address to query * @param id token to query * @return token balance */ function _balanceOf(address account, uint256 id) internal view virtual returns (uint256) { require( account != address(0), 'ERC1155: balance query for the zero address' ); return ERC1155BaseStorage.layout().balances[id][account]; } /** * @notice mint given quantity of tokens for given address * @dev ERC1155Receiver implementation is not checked * @param account beneficiary of minting * @param id token ID * @param amount quantity of tokens to mint * @param data data payload */ function _mint( address account, uint256 id, uint256 amount, bytes memory data ) internal virtual { require(account != address(0), 'ERC1155: mint to the zero address'); _beforeTokenTransfer( msg.sender, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data ); mapping(address => uint256) storage balances = ERC1155BaseStorage .layout() .balances[id]; balances[account] += amount; emit TransferSingle(msg.sender, address(0), account, id, amount); } /** * @notice mint given quantity of tokens for given address * @param account beneficiary of minting * @param id token ID * @param amount quantity of tokens to mint * @param data data payload */ function _safeMint( address account, uint256 id, uint256 amount, bytes memory data ) internal virtual { _mint(account, id, amount, data); _doSafeTransferAcceptanceCheck( msg.sender, address(0), account, id, amount, data ); } /** * @notice mint batch of tokens for given address * @dev ERC1155Receiver implementation is not checked * @param account beneficiary of minting * @param ids list of token IDs * @param amounts list of quantities of tokens to mint * @param data data payload */ function _mintBatch( address account, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require(account != address(0), 'ERC1155: mint to the zero address'); require( ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch' ); _beforeTokenTransfer( msg.sender, address(0), account, ids, amounts, data ); mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155BaseStorage.layout().balances; for (uint256 i; i < ids.length; i++) { balances[ids[i]][account] += amounts[i]; } emit TransferBatch(msg.sender, address(0), account, ids, amounts); } /** * @notice mint batch of tokens for given address * @param account beneficiary of minting * @param ids list of token IDs * @param amounts list of quantities of tokens to mint * @param data data payload */ function _safeMintBatch( address account, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { _mintBatch(account, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck( msg.sender, address(0), account, ids, amounts, data ); } /** * @notice burn given quantity of tokens held by given address * @param account holder of tokens to burn * @param id token ID * @param amount quantity of tokens to burn */ function _burn( address account, uint256 id, uint256 amount ) internal virtual { require(account != address(0), 'ERC1155: burn from the zero address'); _beforeTokenTransfer( msg.sender, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), '' ); mapping(address => uint256) storage balances = ERC1155BaseStorage .layout() .balances[id]; unchecked { require( balances[account] >= amount, 'ERC1155: burn amount exceeds balances' ); balances[account] -= amount; } emit TransferSingle(msg.sender, account, address(0), id, amount); } /** * @notice burn given batch of tokens held by given address * @param account holder of tokens to burn * @param ids token IDs * @param amounts quantities of tokens to burn */ function _burnBatch( address account, uint256[] memory ids, uint256[] memory amounts ) internal virtual { require(account != address(0), 'ERC1155: burn from the zero address'); require( ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch' ); _beforeTokenTransfer(msg.sender, account, address(0), ids, amounts, ''); mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155BaseStorage.layout().balances; unchecked { for (uint256 i; i < ids.length; i++) { uint256 id = ids[i]; require( balances[id][account] >= amounts[i], 'ERC1155: burn amount exceeds balance' ); balances[id][account] -= amounts[i]; } } emit TransferBatch(msg.sender, account, address(0), ids, amounts); } /** * @notice transfer tokens between given addresses * @dev ERC1155Receiver implementation is not checked * @param operator executor of transfer * @param sender sender of tokens * @param recipient receiver of tokens * @param id token ID * @param amount quantity of tokens to transfer * @param data data payload */ function _transfer( address operator, address sender, address recipient, uint256 id, uint256 amount, bytes memory data ) internal virtual { require( recipient != address(0), 'ERC1155: transfer to the zero address' ); _beforeTokenTransfer( operator, sender, recipient, _asSingletonArray(id), _asSingletonArray(amount), data ); mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155BaseStorage.layout().balances; unchecked { uint256 senderBalance = balances[id][sender]; require( senderBalance >= amount, 'ERC1155: insufficient balances for transfer' ); balances[id][sender] = senderBalance - amount; } balances[id][recipient] += amount; emit TransferSingle(operator, sender, recipient, id, amount); } /** * @notice transfer tokens between given addresses * @param operator executor of transfer * @param sender sender of tokens * @param recipient receiver of tokens * @param id token ID * @param amount quantity of tokens to transfer * @param data data payload */ function _safeTransfer( address operator, address sender, address recipient, uint256 id, uint256 amount, bytes memory data ) internal virtual { _transfer(operator, sender, recipient, id, amount, data); _doSafeTransferAcceptanceCheck( operator, sender, recipient, id, amount, data ); } /** * @notice transfer batch of tokens between given addresses * @dev ERC1155Receiver implementation is not checked * @param operator executor of transfer * @param sender sender of tokens * @param recipient receiver of tokens * @param ids token IDs * @param amounts quantities of tokens to transfer * @param data data payload */ function _transferBatch( address operator, address sender, address recipient, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { require( recipient != address(0), 'ERC1155: transfer to the zero address' ); require( ids.length == amounts.length, 'ERC1155: ids and amounts length mismatch' ); _beforeTokenTransfer(operator, sender, recipient, ids, amounts, data); mapping(uint256 => mapping(address => uint256)) storage balances = ERC1155BaseStorage.layout().balances; for (uint256 i; i < ids.length; i++) { uint256 token = ids[i]; uint256 amount = amounts[i]; unchecked { uint256 senderBalance = balances[token][sender]; require( senderBalance >= amount, 'ERC1155: insufficient balances for transfer' ); balances[token][sender] = senderBalance - amount; } balances[token][recipient] += amount; } emit TransferBatch(operator, sender, recipient, ids, amounts); } /** * @notice transfer batch of tokens between given addresses * @param operator executor of transfer * @param sender sender of tokens * @param recipient receiver of tokens * @param ids token IDs * @param amounts quantities of tokens to transfer * @param data data payload */ function _safeTransferBatch( address operator, address sender, address recipient, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { _transferBatch(operator, sender, recipient, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck( operator, sender, recipient, ids, amounts, data ); } /** * @notice wrap given element in array of length 1 * @param element element to wrap * @return singleton array */ function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } /** * @notice revert if applicable transfer recipient is not valid ERC1155Receiver * @param operator executor of transfer * @param from sender of tokens * @param to receiver of tokens * @param id token ID * @param amount quantity of tokens to transfer * @param data data payload */ function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155Received( operator, from, id, amount, data ) returns (bytes4 response) { require( response == IERC1155Receiver.onERC1155Received.selector, 'ERC1155: ERC1155Receiver rejected tokens' ); } catch Error(string memory reason) { revert(reason); } catch { revert('ERC1155: transfer to non ERC1155Receiver implementer'); } } } /** * @notice revert if applicable transfer recipient is not valid ERC1155Receiver * @param operator executor of transfer * @param from sender of tokens * @param to receiver of tokens * @param ids token IDs * @param amounts quantities of tokens to transfer * @param data data payload */ function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived( operator, from, ids, amounts, data ) returns (bytes4 response) { require( response == IERC1155Receiver.onERC1155BatchReceived.selector, 'ERC1155: ERC1155Receiver rejected tokens' ); } catch Error(string memory reason) { revert(reason); } catch { revert('ERC1155: transfer to non ERC1155Receiver implementer'); } } } /** * @notice ERC1155 hook, called before all transfers including mint and burn * @dev function should be overridden and new implementation must call super * @dev called for both single and batch transfers * @param operator executor of transfer * @param from sender of tokens * @param to receiver of tokens * @param ids token IDs * @param amounts quantities of tokens to transfer * @param data data payload */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library AddressUtils { function toString(address account) internal pure returns (string memory) { bytes32 value = bytes32(uint256(uint160(account))); bytes memory alphabet = '0123456789abcdef'; bytes memory chars = new bytes(42); chars[0] = '0'; chars[1] = 'x'; for (uint256 i = 0; i < 20; i++) { chars[2 + i * 2] = alphabet[uint8(value[i + 12] >> 4)]; chars[3 + i * 2] = alphabet[uint8(value[i + 12] & 0x0f)]; } return string(chars); } function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable account, uint256 amount) internal { (bool success, ) = account.call{ value: amount }(''); require(success, 'AddressUtils: failed to send value'); } function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, 'AddressUtils: failed low-level call'); } function functionCall( address target, bytes memory data, string memory error ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, error); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'AddressUtils: failed low-level call with value' ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) internal returns (bytes memory) { require( address(this).balance >= value, 'AddressUtils: insufficient balance for call' ); return _functionCallWithValue(target, data, value, error); } function _functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) private returns (bytes memory) { require( isContract(target), 'AddressUtils: function call to non-contract' ); (bool success, bytes memory returnData) = target.call{ value: value }( data ); if (success) { return returnData; } else if (returnData.length > 0) { assembly { let returnData_size := mload(returnData) revert(add(32, returnData), returnData_size) } } else { revert(error); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library ERC1155BaseStorage { struct Layout { mapping(uint256 => mapping(address => uint256)) balances; mapping(address => mapping(address => bool)) operatorApprovals; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC1155Base'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Set implementation with enumeration functions * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ library EnumerableSet { struct Set { bytes32[] _values; // 1-indexed to allow 0 to signify nonexistence mapping(bytes32 => uint256) _indexes; } struct Bytes32Set { Set _inner; } struct AddressSet { Set _inner; } struct UintSet { Set _inner; } function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } function indexOf(Bytes32Set storage set, bytes32 value) internal view returns (uint256) { return _indexOf(set._inner, value); } function indexOf(AddressSet storage set, address value) internal view returns (uint256) { return _indexOf(set._inner, bytes32(uint256(uint160(value)))); } function indexOf(UintSet storage set, uint256 value) internal view returns (uint256) { return _indexOf(set._inner, bytes32(value)); } function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } function _at(Set storage set, uint256 index) private view returns (bytes32) { require( set._values.length > index, 'EnumerableSet: index out of bounds' ); return set._values[index]; } function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } function _indexOf(Set storage set, bytes32 value) private view returns (uint256) { unchecked { return set._indexes[value] - 1; } } function _length(Set storage set) private view returns (uint256) { return set._values.length; } function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); set._indexes[value] = set._values.length; return true; } else { return false; } } function _remove(Set storage set, bytes32 value) private returns (bool) { uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { uint256 index = valueIndex - 1; bytes32 last = set._values[set._values.length - 1]; // move last value to now-vacant index set._values[index] = last; set._indexes[last] = index + 1; // clear last index set._values.pop(); delete set._indexes[value]; return true; } else { return false; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC1155 enumerable and aggregate function interface */ interface IERC1155Enumerable { /** * @notice query total minted supply of given token * @param id token id to query * @return token supply */ function totalSupply(uint256 id) external view returns (uint256); /** * @notice query total number of holders for given token * @param id token id to query * @return quantity of holders */ function totalHolders(uint256 id) external view returns (uint256); /** * @notice query holders of given token * @param id token id to query * @return list of holder addresses */ function accountsByToken(uint256 id) external view returns (address[] memory); /** * @notice query tokens held by given address * @param account address to query * @return list of token ids */ function tokensByAccount(address account) external view returns (uint256[] memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../../utils/EnumerableSet.sol'; import { ERC1155BaseInternal, ERC1155BaseStorage } from '../base/ERC1155BaseInternal.sol'; import { ERC1155EnumerableStorage } from './ERC1155EnumerableStorage.sol'; /** * @title ERC1155Enumerable internal functions */ abstract contract ERC1155EnumerableInternal is ERC1155BaseInternal { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.UintSet; /** * @notice ERC1155 hook: update aggregate values * @inheritdoc ERC1155BaseInternal */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual override { super._beforeTokenTransfer(operator, from, to, ids, amounts, data); if (from != to) { ERC1155EnumerableStorage.Layout storage l = ERC1155EnumerableStorage .layout(); mapping(uint256 => EnumerableSet.AddressSet) storage tokenAccounts = l.accountsByToken; EnumerableSet.UintSet storage fromTokens = l.tokensByAccount[from]; EnumerableSet.UintSet storage toTokens = l.tokensByAccount[to]; for (uint256 i; i < ids.length; i++) { uint256 amount = amounts[i]; if (amount > 0) { uint256 id = ids[i]; if (from == address(0)) { l.totalSupply[id] += amount; } else if (_balanceOf(from, id) == amount) { tokenAccounts[id].remove(from); fromTokens.remove(id); } if (to == address(0)) { l.totalSupply[id] -= amount; } else if (_balanceOf(to, id) == 0) { tokenAccounts[id].add(to); toTokens.add(id); } } } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../../utils/EnumerableSet.sol'; library ERC1155EnumerableStorage { struct Layout { mapping(uint256 => uint256) totalSupply; mapping(uint256 => EnumerableSet.AddressSet) accountsByToken; mapping(address => EnumerableSet.UintSet) tokensByAccount; } bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC1155Enumerable'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library UintUtils { function toString(uint256 value) internal pure returns (string memory) { 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); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC1155Metadata interface */ interface IERC1155Metadata { /** * @notice get generated URI for given token * @return token URI */ function uri(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC1155MetadataInternal } from './IERC1155MetadataInternal.sol'; import { ERC1155MetadataStorage } from './ERC1155MetadataStorage.sol'; /** * @notice ERC1155Metadata internal functions */ abstract contract ERC1155MetadataInternal is IERC1155MetadataInternal { /** * @notice set base metadata URI * @dev base URI is a non-standard feature adapted from the ERC721 specification * @param baseURI base URI */ function _setBaseURI(string memory baseURI) internal { ERC1155MetadataStorage.layout().baseURI = baseURI; } /** * @notice set per-token metadata URI * @param tokenId token whose metadata URI to set * @param tokenURI per-token URI */ function _setTokenURI(uint256 tokenId, string memory tokenURI) internal { ERC1155MetadataStorage.layout().tokenURIs[tokenId] = tokenURI; emit URI(tokenURI, tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @notice ERC1155 metadata extensions */ library ERC1155MetadataStorage { bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.ERC1155Metadata'); struct Layout { string baseURI; mapping(uint256 => string) tokenURIs; } function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial ERC1155Metadata interface needed by internal functions */ interface IERC1155MetadataInternal { event URI(string value, uint256 indexed tokenId); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '@openzeppelin/contracts/utils/Counters.sol'; library LibDropStorage { bytes32 public constant STORAGE_SLOT = keccak256('drop.app.storage'); // Deprecated struct DropV1 { uint256 timeStart; uint256 timeEnd; uint256 priceStart; uint256 priceEnd; uint256 stepDuration; uint256 amountCap; uint256 shareCyber; address payable creator; Counters.Counter minted; mapping(address => Counters.Counter) mintCounter; } struct Layout { mapping(uint256 => DropV1) dropsV1; // Deprecated mapping(uint256 => Drop) drops; } function layout() internal pure returns (Layout storage lay) { bytes32 slot = STORAGE_SLOT; assembly { lay.slot := slot } } struct Drop { uint256 timeStart; uint256 timeEnd; uint256 price; uint256 amountCap; uint256 shareCyber; address payable creator; uint256 minted; mapping(address => Counters.Counter) mintCounter; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol'; import '@openzeppelin/contracts/utils/Counters.sol'; import './libraries/LibAppStorage.sol'; import './libraries/LibDropStorage.sol'; import './CyberTokenBase.sol'; contract CyberDropBase is CyberTokenBase { using ECDSA for bytes32; using Counters for Counters.Counter; event DropCreated(address indexed account, uint256 indexed tokenId); event DropUpdated(address indexed account, uint256 indexed tokenId); function dropMintCounter(uint256 _tokenId, address _minter) external view returns (uint256) { LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[_tokenId]; require(drop.amountCap != 0, 'DNE'); return drop.mintCounter[_minter].current(); } function getDrop(uint256 _tokenId) external view returns ( uint256 timeStart, uint256 timeEnd, uint256 price, uint256 amountCap, uint256 shareCyber, address creator, uint256 minted ) { LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[_tokenId]; require(drop.amountCap != 0, 'DNE'); return (drop.timeStart, drop.timeEnd, drop.price, drop.amountCap, drop.shareCyber, drop.creator, drop.minted); } function createDrop( string memory _uri, uint256 _timeStart, uint256 _timeEnd, uint256 _price, uint256 _amountCap, uint256 _shareCyber, bytes memory _signature ) external returns (uint256 tokenId) { require(_timeEnd - _timeStart > 0, 'IT'); require(_shareCyber <= 100, 'ISO'); require(_amountCap > 0, 'IAC'); LibAppStorage.Layout storage layout = LibAppStorage.layout(); address sender = _msgSender(); uint256 nonce = minterNonce(sender); bytes memory _message = abi.encodePacked( _uri, _timeStart, _timeEnd, _price, _amountCap, _shareCyber, sender, nonce ); address recoveredAddress = keccak256(_message).toEthSignedMessageHash().recover(_signature); require(recoveredAddress == layout.manager, 'NM'); tokenId = layout.totalSupply.current(); // Effects setTokenURI(tokenId, _uri); layout.totalSupply.increment(); layout.minterNonce[sender].increment(); LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[tokenId]; drop.timeStart = _timeStart; drop.timeEnd = _timeEnd; drop.price = _price; drop.amountCap = _amountCap; drop.shareCyber = _shareCyber; drop.creator = payable(sender); emit DropCreated(sender, tokenId); } function updateDrop( uint256 _tokenId, string memory _uri, uint256 _timeStart, uint256 _timeEnd ) external { require(_timeEnd - _timeStart > 0, 'IT'); LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[_tokenId]; address sender = _msgSender(); require(drop.creator == sender, 'NM'); setTokenURI(_tokenId, _uri); drop.timeStart = _timeStart; drop.timeEnd = _timeEnd; emit DropUpdated(sender, _tokenId); } function mint( uint256 _tokenId, uint256 _quantity, bytes memory _signature ) external payable returns (bool success) { address sender = _msgSender(); LibDropStorage.Drop storage drop = LibDropStorage.layout().drops[_tokenId]; require(drop.amountCap - drop.minted >= _quantity, 'CR'); require(block.timestamp > drop.timeStart && block.timestamp <= drop.timeEnd, 'OOT'); require(msg.value == drop.price * _quantity, 'IA'); uint256 senderDropNonce = drop.mintCounter[sender].current(); bytes memory _message = abi.encodePacked(_tokenId, _quantity, sender, senderDropNonce); LibAppStorage.Layout storage layout = LibAppStorage.layout(); address recoveredAddress = keccak256(_message).toEthSignedMessageHash().recover(_signature); require(recoveredAddress == layout.manager, 'NM'); // Effects drop.minted += _quantity; drop.mintCounter[sender].increment(); _safeMint(sender, _tokenId, _quantity, ''); if (drop.price > 0) { uint256 amountOnCyber = (msg.value * drop.shareCyber) / 100; uint256 amountCreator = msg.value - amountOnCyber; drop.creator.transfer(amountCreator); payable(layout.oncyber).transfer(amountOnCyber); } emit Minted(sender, _tokenId, _quantity); return true; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '../../CyberDropBase.sol'; contract OnCyberAndFriendsFactoryFacet is CyberDropBase {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '../../CyberDropBase.sol'; contract OMFactoryFacet is CyberDropBase {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '../../CyberDropBase.sol'; contract CyberObjectFactoryFacet is CyberDropBase {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import '../../CyberDropBase.sol'; abstract contract LuxContract { function mintThroughBurn( address newOwner, uint256 tokenId, uint256 amount ) public virtual; } contract CyberDestinationUtilityFactoryFacet is CyberDropBase { function burnTransfer(uint256 quantity, bool isLux) public { // definitions uint256 toBurn = isLux ? quantity * 20 : quantity * 2; ERC1155 lootPodContract = ERC1155(0xb7bE4001BfF2c5F4a61dd2435E4c9A19D8d12343); // replace with 0xb7be4001bff2c5f4a61dd2435e4c9a19d8d12343 // check balance require(balanceOf(msg.sender, 5) >= toBurn, 'NS'); // replace with 5 require(lootPodContract.balanceOf(msg.sender, 1) >= toBurn, 'NR'); // burn mechanisms lootPodContract.safeTransferFrom(msg.sender, 0x000000000000000000000000000000000000dEaD, 1, toBurn, ''); _burn(msg.sender, 5, toBurn); // replace with 5 // mint new token LuxContract luxPodContract = LuxContract(0x895554bc4F48fe1c2bf5C198bFA3513Da538f86b); // replace w new rtfkt contract luxPodContract.mintThroughBurn(msg.sender, isLux ? 2 : 1, quantity); } function updateTokenURI(uint256 tokenId, string memory _tokenURI) public { LibAppStorage.Layout storage layout = LibAppStorage.layout(); require(msg.sender == layout.manager, 'NM'); setTokenURI(tokenId, _tokenURI); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; // import '../../CyberDropBase.sol'; contract CyberDestinationFactoryFacet is CyberDropBase {}
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import '@solidstate/contracts/token/ERC1155/IERC1155.sol'; // contract OnCyberMultiSender { function transfer( IERC1155 _token, uint256 id, address[] calldata _receivers, uint256[] calldata _quantities ) external { require(_receivers.length == _quantities.length, 'OnCyberMultiSender: receivers and quantities length mismatch'); for (uint256 i = 0; i < _receivers.length; i++) { _token.safeTransferFrom(msg.sender, _receivers[i], id, _quantities[i], ''); } } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": { "": { "__CACHE_BREAKER__": "0x00000000d41867734bbee4c6863d9255b2b06ac1" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"DropCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"DropUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"accountsByToken","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"},{"internalType":"uint256","name":"_timeStart","type":"uint256"},{"internalType":"uint256","name":"_timeEnd","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_amountCap","type":"uint256"},{"internalType":"uint256","name":"_shareCyber","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"createDrop","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address","name":"_minter","type":"address"}],"name":"dropMintCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getDrop","outputs":[{"internalType":"uint256","name":"timeStart","type":"uint256"},{"internalType":"uint256","name":"timeEnd","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"amountCap","type":"uint256"},{"internalType":"uint256","name":"shareCyber","type":"uint256"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"},{"internalType":"address","name":"_manager","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"address","name":"_opensea","type":"address"},{"internalType":"address","name":"_oncyber","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isTrustedForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"mint","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"minterNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oncyber","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":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","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":"status","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"tokensByAccount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalHolders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"string","name":"_uri","type":"string"},{"internalType":"uint256","name":"_timeStart","type":"uint256"},{"internalType":"uint256","name":"_timeEnd","type":"uint256"}],"name":"updateDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506137b7806100206000396000f3fe60806040526004361061017f5760003560e01c8063572b6c05116100d6578063bc01188e1161007f578063e985e9c511610059578063e985e9c51461053d578063f242432a146105a5578063faf32540146105c557600080fd5b8063bc01188e14610494578063bd85b039146104d1578063e751c9811461051d57600080fd5b806385bff2e7116100b057806385bff2e714610434578063a22cb46514610454578063b3a721d11461047457600080fd5b8063572b6c051461035b5780636787d449146103a95780636dcfd8411461040757600080fd5b806313ba55df116101385780632eb2c2d6116101125780632eb2c2d6146102bd578063481c6a75146102dd5780634e1273f41461032e57600080fd5b806313ba55df1461024957806318160ddd146102695780631b0239471461029d57600080fd5b806308dc9f421161016957806308dc9f42146101e75780630b885ac3146101fa5780630e89341c1461021c57600080fd5b8062fdd58e1461018457806301ffc9a7146101b7575b600080fd5b34801561019057600080fd5b506101a461019f366004612bdd565b6105e5565b6040519081526020015b60405180910390f35b3480156101c357600080fd5b506101d76101d2366004612c1d565b6105fa565b60405190151581526020016101ae565b6101d76101f5366004612cf8565b61063b565b34801561020657600080fd5b5061021a610215366004612d48565b610a29565b005b34801561022857600080fd5b5061023c610237366004612dc8565b610c12565b6040516101ae9190612e39565b34801561025557600080fd5b506101a4610264366004612dc8565b610d6a565b34801561027557600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a60546101a4565b3480156102a957600080fd5b506101a46102b8366004612e4c565b610da0565b3480156102c957600080fd5b5061021a6102d8366004612efc565b610ddd565b3480156102e957600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e546001600160a01b03165b6040516001600160a01b0390911681526020016101ae565b34801561033a57600080fd5b5061034e610349366004612fa6565b610ea9565b6040516101ae91906130ac565b34801561036757600080fd5b506101d7610376366004612e4c565b7fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993546001600160a01b0390811691161490565b3480156103b557600080fd5b506103c96103c4366004612dc8565b6110d0565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b031660a083015260c082015260e0016101ae565b34801561041357600080fd5b50610427610422366004612dc8565b611183565b6040516101ae91906130bf565b34801561044057600080fd5b5061034e61044f366004612e4c565b611261565b34801561046057600080fd5b5061021a61046f36600461310c565b611334565b34801561048057600080fd5b506101a461048f366004613148565b61143d565b3480156104a057600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a62546001600160a01b0316610316565b3480156104dd57600080fd5b506101a46104ec366004612dc8565b60009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ea602052604090205490565b34801561052957600080fd5b506101a4610538366004613174565b6114c6565b34801561054957600080fd5b506101d7610558366004613208565b6001600160a01b0391821660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832093909416825291909152205460ff1690565b3480156105b157600080fd5b5061021a6105c0366004613232565b6117d3565b3480156105d157600080fd5b5061021a6105e0366004613297565b611898565b60006105f183836119a5565b90505b92915050565b6001600160e01b0319811660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604081205460ff166105f4565b600080610646611a6a565b60008681527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260409020600681015460038201549293509091869161068d91613304565b10156106e05760405162461bcd60e51b815260206004820152600260248201527f435200000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b8054421180156106f4575080600101544211155b6107405760405162461bcd60e51b815260206004820152600360248201527f4f4f54000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b848160020154610750919061331b565b341461079e5760405162461bcd60e51b815260206004820152600260248201527f494100000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b6001600160a01b038216600090815260078201602090815260408083205481519283018a9052908201889052606085811b6bffffffffffffffffffffffff191690830152607482018190529190609401604051602081830303815290604052905060006108287f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e90565b905060006108948861088e85805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611ac0565b82549091506001600160a01b038083169116146108d85760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b888560060160008282546108ec919061333a565b90915550506001600160a01b038616600090815260078601602052604090208054600101905561092d868b8b60405180602001604052806000815250611adc565b6002850154156109e1576000606486600401543461094b919061331b565b6109559190613352565b905060006109638234613304565b60058801546040519192506001600160a01b03169082156108fc029083906000818181858888f193505050501580156109a0573d6000803e3d6000fd5b5060048401546040516001600160a01b039091169083156108fc029084906000818181858888f193505050501580156109dd573d6000803e3d6000fd5b5050505b888a876001600160a01b03167f25b428dfde728ccfaddad7e29e4ac23c24ed7fd1a6e3e3f91894a9a073f5dfff60405160405180910390a45060019998505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b03163314610aa25760405162461bcd60e51b815260206004820152600260248201527f4e4f00000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b7fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385161790557fd9b67a26000000000000000000000000000000000000000000000000000000006000527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f845f7f8d885943dffdc1524acbd9538b2923f93aad26d306df3b8982c7f0632d805460ff19166001179055610b6685611afd565b7f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e80546001600160a01b0395861673ffffffffffffffffffffffffffffffffffffffff19918216179091557f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5f8054938616938216939093179092557f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a628054919094169116179091555050565b60008181527fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c836020526040812080546060929190610c4f90613374565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7b90613374565b8015610cc85780601f10610c9d57610100808354040283529160200191610cc8565b820191906000526020600020905b815481529060010190602001808311610cab57829003601f168201915b505050505090508051600003610d205760405162461bcd60e51b815260206004820152601d60248201527f455243313135355552493a20746f6b656e4964206e6f7420657869737400000060448201526064016106d7565b604051610d53907fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c849083906020016133ae565b604051602081830303815290604052915050919050565b60008181527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb602052604081206105f490611b2c565b6001600160a01b03811660009081527f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a6160205260408120546105f4565b6001600160a01b038516331480610e3657506001600160a01b03851660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832033845290915290205460ff165b610e945760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016106d7565b610ea2338686868686611b36565b5050505050565b60608151835114610f225760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016106d7565b82517f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b9060009067ffffffffffffffff811115610f6157610f61612c41565b604051908082528060200260200182016040528015610f8a578160200160208202803683370190505b50905060005b85518110156110c75760006001600160a01b0316868281518110610fb657610fb6613435565b60200260200101516001600160a01b03160361103a5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527f20746865207a65726f206164647265737300000000000000000000000000000060648201526084016106d7565b82600086838151811061104f5761104f613435565b60200260200101518152602001908152602001600020600087838151811061107957611079613435565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020548282815181106110b4576110b4613435565b6020908102919091010152600101610f90565b50949350505050565b60008181527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260408120600381015482918291829182918291829182036111425760405162461bcd60e51b8152602060048201526003602482015262444e4560e81b60448201526064016106d7565b805460018201546002830154600384015460048501546005860154600690960154949e939d50919b50995097506001600160a01b0390921695509350915050565b60008181527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb602052604081206060916111bc82611b2c565b67ffffffffffffffff8111156111d4576111d4612c41565b6040519080825280602002602001820160405280156111fd578160200160208202803683370190505b50905060005b61120c83611b2c565b8110156112595761121d8382611b5a565b82828151811061122f5761122f613435565b6001600160a01b0390921660209283029190910190910152806112518161344b565b915050611203565b509392505050565b6001600160a01b03811660009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ec602052604081206060916112a482611b2c565b67ffffffffffffffff8111156112bc576112bc612c41565b6040519080825280602002602001820160405280156112e5578160200160208202803683370190505b50905060005b6112f483611b2c565b811015611259576113058382611b5a565b82828151811061131757611317613435565b60209081029190910101528061132c8161344b565b9150506112eb565b6001600160a01b03821633036113b25760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016106d7565b3360008181527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008281527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260408120600381015482036114a35760405162461bcd60e51b8152602060048201526003602482015262444e4560e81b60448201526064016106d7565b6001600160a01b0383166000908152600782016020526040902054949350505050565b6000806114d38888613304565b116115055760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106d7565b60648311156115565760405162461bcd60e51b815260206004820152600360248201527f49534f000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b600084116115a65760405162461bcd60e51b815260206004820152600360248201527f494143000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b7f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e60006115d1611a6a565b905060006115de82610da0565b905060008b8b8b8b8b8b8888604051602001611601989796959493929190613464565b604051602081830303815290604052905060006116768761088e84805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b85549091506001600160a01b038083169116146116ba5760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b600285015495506116cb868e611b66565b6116db8560020180546001019055565b6001600160a01b038416600090815260038601602052604090208054600101905560007f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe659600101600088815260200190815260200160002090508c81600001819055508b81600101819055508a8160020181905550898160030181905550888160040181905550848160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555086856001600160a01b03167f4011446e11141f68f741bffe55d700b48cbc73fb927148a01c8f4664c3be014260405160405180910390a3505050505050979650505050505050565b6001600160a01b03851633148061182c57506001600160a01b03851660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832033845290915290205460ff165b61188a5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016106d7565b610ea2338686868686611ba2565b60006118a48383613304565b116118d65760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106d7565b60008481527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a602052604081209061190c611a6a565b60058301549091506001600160a01b038083169116146119535760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b61195d8686611b66565b8382556001820183905560405186906001600160a01b038316907fc177a540715440475d2386abd75ffd850e00fb1d9212ce20cfed7063e6dfb31190600090a3505050505050565b60006001600160a01b038316611a235760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084016106d7565b7f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b6000928352602090815260408084206001600160a01b0395909516845293905250205490565b600060183610801590611aa657507fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993546001600160a01b031633145b15611ab8575060131936013560601c90565b503390565b90565b6000806000611acf8585611bbe565b9150915061125981611c2c565b611ae884848484611de5565b611af733600086868686611f28565b50505050565b7fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c84611b288282613504565b5050565b60006105f4825490565b611b448686868686866120d6565b611b5286868686868661236e565b505050505050565b60006105f1838361246a565b60008281527fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c8360205260409020611b9d8282613504565b505050565b611bb086868686868661250b565b611b52868686868686611f28565b6000808251604103611bf45760208301516040840151606085015160001a611be8878285856126b3565b94509450505050611c25565b8251604003611c1d5760208301516040840151611c128683836127a0565b935093505050611c25565b506000905060025b9250929050565b6000816004811115611c4057611c406135c4565b03611c485750565b6001816004811115611c5c57611c5c6135c4565b03611ca95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106d7565b6002816004811115611cbd57611cbd6135c4565b03611d0a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106d7565b6003816004811115611d1e57611d1e6135c4565b03611d765760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106d7565b6004816004811115611d8a57611d8a6135c4565b03611de25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016106d7565b50565b6001600160a01b038416611e615760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106d7565b611e8033600086611e71876127f2565b611e7a876127f2565b8661283d565b60008381527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602090815260408083206001600160a01b0388168452918290528220805491928592611ed390849061333a565b909155505060408051858152602081018590526001600160a01b0387169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b6001600160a01b0384163b15611b525760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611f6c90899089908890889088906004016135da565b6020604051808303816000875af1925050508015611fa7575060408051601f3d908101601f19168201909252611fa49181019061361d565b60015b61205c57611fb361363a565b806308c379a003611fec5750611fc7613655565b80611fd25750611fee565b8060405162461bcd60e51b81526004016106d79190612e39565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016106d7565b6001600160e01b0319811663f23a6e6160e01b146120cd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b60648201526084016106d7565b50505050505050565b6001600160a01b03841661213a5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b60648201526084016106d7565b81518351146121b15760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d6174636800000000000000000000000000000000000000000000000060648201526084016106d7565b6121bf86868686868661283d565b7f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b60005b845181101561230d57600085828151811061220057612200613435565b60200260200101519050600085838151811061221e5761221e613435565b602090810291909101810151600084815286835260408082206001600160a01b038e1683529093529190912054909150818110156122b25760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201526a37b9103a3930b739b332b960a91b60648201526084016106d7565b6000838152602086815260408083206001600160a01b038e811685529252808320938590039093558a16815290812080548392906122f190849061333a565b92505081905550505080806123059061344b565b9150506121e3565b50846001600160a01b0316866001600160a01b0316886001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161235d9291906136df565b60405180910390a450505050505050565b6001600160a01b0384163b15611b525760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906123b2908990899088908890889060040161370d565b6020604051808303816000875af19250505080156123ed575060408051601f3d908101601f191682019092526123ea9181019061361d565b60015b6123f957611fb361363a565b6001600160e01b0319811663bc197c8160e01b146120cd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b60648201526084016106d7565b815460009082106124e35760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60448201527f647300000000000000000000000000000000000000000000000000000000000060648201526084016106d7565b8260000182815481106124f8576124f8613435565b9060005260206000200154905092915050565b6001600160a01b03841661256f5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b60648201526084016106d7565b61257e868686611e71876127f2565b60008381527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602081815260408084206001600160a01b038a16855290915290912054838110156126255760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201526a37b9103a3930b739b332b960a91b60648201526084016106d7565b6000858152602083815260408083206001600160a01b038b8116855292528083209387900390935587168152908120805485929061266490849061333a565b909155505060408051858152602081018590526001600160a01b038088169289821692918b16917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910161235d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126ea5750600090506003612797565b8460ff16601b1415801561270257508460ff16601c14155b156127135750600090506004612797565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612767573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661279057600060019250925050612797565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127d660ff86901c601b61333a565b90506127e4878288856126b3565b935093505050935093915050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061282c5761282c613435565b602090810291909101015292915050565b611b52868686868686611b52868686868686836001600160a01b0316856001600160a01b031614611b52576001600160a01b0385811660009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ec6020526040808220928716825281207fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ea927fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb929091905b8751811015612a3857600087828151811061290d5761290d613435565b602002602001015190506000811115612a2557600089838151811061293457612934613435565b6020026020010151905060006001600160a01b03168c6001600160a01b031603612981576000818152602088905260408120805484929061297690849061333a565b909155506129b69050565b8161298c8d836119a5565b036129b65760008181526020879052604090206129a9908d612a45565b506129b48582612a5a565b505b6001600160a01b038b166129ed57600081815260208890526040812080548492906129e2908490613304565b90915550612a239050565b6129f78b826119a5565b600003612a23576000818152602087905260409020612a16908c612a66565b50612a218482612a7b565b505b505b5080612a308161344b565b9150506128f0565b5050505050505050505050565b60006105f1836001600160a01b038416612a87565b60006105f18383612a87565b60006105f1836001600160a01b038416612b72565b60006105f18383612b72565b60008181526001830160205260408120548015612b68576000612aab600183613304565b85549091506000908690612ac190600190613304565b81548110612ad157612ad1613435565b9060005260206000200154905080866000018381548110612af457612af4613435565b600091825260209091200155612b0b82600161333a565b60008281526001880160205260409020558554869080612b2d57612b2d61376b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f4565b60009150506105f4565b6000818152600183016020526040812054612bb9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f4565b5060006105f4565b80356001600160a01b0381168114612bd857600080fd5b919050565b60008060408385031215612bf057600080fd5b612bf983612bc1565b946020939093013593505050565b6001600160e01b031981168114611de257600080fd5b600060208284031215612c2f57600080fd5b8135612c3a81612c07565b9392505050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff81118282101715612c7d57612c7d612c41565b6040525050565b600082601f830112612c9557600080fd5b813567ffffffffffffffff811115612caf57612caf612c41565b604051612cc6601f8301601f191660200182612c57565b818152846020838601011115612cdb57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612d0d57600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612d3257600080fd5b612d3e86828701612c84565b9150509250925092565b600080600080600060a08688031215612d6057600080fd5b853567ffffffffffffffff811115612d7757600080fd5b612d8388828901612c84565b955050612d9260208701612bc1565b9350612da060408701612bc1565b9250612dae60608701612bc1565b9150612dbc60808701612bc1565b90509295509295909350565b600060208284031215612dda57600080fd5b5035919050565b60005b83811015612dfc578181015183820152602001612de4565b83811115611af75750506000910152565b60008151808452612e25816020860160208601612de1565b601f01601f19169290920160200192915050565b6020815260006105f16020830184612e0d565b600060208284031215612e5e57600080fd5b6105f182612bc1565b600067ffffffffffffffff821115612e8157612e81612c41565b5060051b60200190565b600082601f830112612e9c57600080fd5b81356020612ea982612e67565b604051612eb68282612c57565b83815260059390931b8501820192828101915086841115612ed657600080fd5b8286015b84811015612ef15780358352918301918301612eda565b509695505050505050565b600080600080600060a08688031215612f1457600080fd5b612f1d86612bc1565b9450612f2b60208701612bc1565b9350604086013567ffffffffffffffff80821115612f4857600080fd5b612f5489838a01612e8b565b94506060880135915080821115612f6a57600080fd5b612f7689838a01612e8b565b93506080880135915080821115612f8c57600080fd5b50612f9988828901612c84565b9150509295509295909350565b60008060408385031215612fb957600080fd5b823567ffffffffffffffff80821115612fd157600080fd5b818501915085601f830112612fe557600080fd5b81356020612ff282612e67565b604051612fff8282612c57565b83815260059390931b850182019282810191508984111561301f57600080fd5b948201945b838610156130445761303586612bc1565b82529482019490820190613024565b9650508601359250508082111561305a57600080fd5b5061306785828601612e8b565b9150509250929050565b600081518084526020808501945080840160005b838110156130a157815187529582019590820190600101613085565b509495945050505050565b6020815260006105f16020830184613071565b6020808252825182820181905260009190848201906040850190845b818110156131005783516001600160a01b0316835292840192918401916001016130db565b50909695505050505050565b6000806040838503121561311f57600080fd5b61312883612bc1565b91506020830135801515811461313d57600080fd5b809150509250929050565b6000806040838503121561315b57600080fd5b8235915061316b60208401612bc1565b90509250929050565b600080600080600080600060e0888a03121561318f57600080fd5b873567ffffffffffffffff808211156131a757600080fd5b6131b38b838c01612c84565b985060208a0135975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a01359150808211156131ec57600080fd5b506131f98a828b01612c84565b91505092959891949750929550565b6000806040838503121561321b57600080fd5b61322483612bc1565b915061316b60208401612bc1565b600080600080600060a0868803121561324a57600080fd5b61325386612bc1565b945061326160208701612bc1565b93506040860135925060608601359150608086013567ffffffffffffffff81111561328b57600080fd5b612f9988828901612c84565b600080600080608085870312156132ad57600080fd5b84359350602085013567ffffffffffffffff8111156132cb57600080fd5b6132d787828801612c84565b949794965050505060408301359260600135919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613316576133166132ee565b500390565b6000816000190483118215151615613335576133356132ee565b500290565b6000821982111561334d5761334d6132ee565b500190565b60008261336f57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061338857607f821691505b6020821081036133a857634e487b7160e01b600052602260045260246000fd5b50919050565b60008084546133bc81613374565b600182811680156133d457600181146133e957613418565b60ff1984168752821515830287019450613418565b8860005260208060002060005b8581101561340f5781548a8201529084019082016133f6565b50505082870194505b50505050835161342c818360208801612de1565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161345d5761345d6132ee565b5060010190565b60008951613476818460208e01612de1565b91909101978852506020870195909552604086019390935260608086019290925260808501521b6bffffffffffffffffffffffff191660a083015260b482015260d401919050565b601f821115611b9d57600081815260208120601f850160051c810160208610156134e55750805b601f850160051c820191505b81811015611b52578281556001016134f1565b815167ffffffffffffffff81111561351e5761351e612c41565b6135328161352c8454613374565b846134be565b602080601f831160018114613567576000841561354f5750858301515b600019600386901b1c1916600185901b178555611b52565b600085815260208120601f198616915b8281101561359657888601518255948401946001909101908401613577565b50858210156135b45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052602160045260246000fd5b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261361260a0830184612e0d565b979650505050505050565b60006020828403121561362f57600080fd5b8151612c3a81612c07565b600060033d1115611abd5760046000803e5060005160e01c90565b600060443d10156136635790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561369357505050505090565b82850191508151818111156136ab5750505050505090565b843d87010160208285010111156136c55750505050505090565b6136d460208286010187612c57565b509095945050505050565b6040815260006136f26040830185613071565b82810360208401526137048185613071565b95945050505050565b60006001600160a01b03808816835280871660208401525060a0604083015261373960a0830186613071565b828103606084015261374b8186613071565b9050828103608084015261375f8185612e0d565b98975050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220875864685e82b792d01fb06a86eff31b919a76acbcd5307197c3a7c5e40805cc64736f6c634300080f0033
Deployed Bytecode
0x60806040526004361061017f5760003560e01c8063572b6c05116100d6578063bc01188e1161007f578063e985e9c511610059578063e985e9c51461053d578063f242432a146105a5578063faf32540146105c557600080fd5b8063bc01188e14610494578063bd85b039146104d1578063e751c9811461051d57600080fd5b806385bff2e7116100b057806385bff2e714610434578063a22cb46514610454578063b3a721d11461047457600080fd5b8063572b6c051461035b5780636787d449146103a95780636dcfd8411461040757600080fd5b806313ba55df116101385780632eb2c2d6116101125780632eb2c2d6146102bd578063481c6a75146102dd5780634e1273f41461032e57600080fd5b806313ba55df1461024957806318160ddd146102695780631b0239471461029d57600080fd5b806308dc9f421161016957806308dc9f42146101e75780630b885ac3146101fa5780630e89341c1461021c57600080fd5b8062fdd58e1461018457806301ffc9a7146101b7575b600080fd5b34801561019057600080fd5b506101a461019f366004612bdd565b6105e5565b6040519081526020015b60405180910390f35b3480156101c357600080fd5b506101d76101d2366004612c1d565b6105fa565b60405190151581526020016101ae565b6101d76101f5366004612cf8565b61063b565b34801561020657600080fd5b5061021a610215366004612d48565b610a29565b005b34801561022857600080fd5b5061023c610237366004612dc8565b610c12565b6040516101ae9190612e39565b34801561025557600080fd5b506101a4610264366004612dc8565b610d6a565b34801561027557600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a60546101a4565b3480156102a957600080fd5b506101a46102b8366004612e4c565b610da0565b3480156102c957600080fd5b5061021a6102d8366004612efc565b610ddd565b3480156102e957600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e546001600160a01b03165b6040516001600160a01b0390911681526020016101ae565b34801561033a57600080fd5b5061034e610349366004612fa6565b610ea9565b6040516101ae91906130ac565b34801561036757600080fd5b506101d7610376366004612e4c565b7fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993546001600160a01b0390811691161490565b3480156103b557600080fd5b506103c96103c4366004612dc8565b6110d0565b60408051978852602088019690965294860193909352606085019190915260808401526001600160a01b031660a083015260c082015260e0016101ae565b34801561041357600080fd5b50610427610422366004612dc8565b611183565b6040516101ae91906130bf565b34801561044057600080fd5b5061034e61044f366004612e4c565b611261565b34801561046057600080fd5b5061021a61046f36600461310c565b611334565b34801561048057600080fd5b506101a461048f366004613148565b61143d565b3480156104a057600080fd5b507f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a62546001600160a01b0316610316565b3480156104dd57600080fd5b506101a46104ec366004612dc8565b60009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ea602052604090205490565b34801561052957600080fd5b506101a4610538366004613174565b6114c6565b34801561054957600080fd5b506101d7610558366004613208565b6001600160a01b0391821660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832093909416825291909152205460ff1690565b3480156105b157600080fd5b5061021a6105c0366004613232565b6117d3565b3480156105d157600080fd5b5061021a6105e0366004613297565b611898565b60006105f183836119a5565b90505b92915050565b6001600160e01b0319811660009081527f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e705602052604081205460ff166105f4565b600080610646611a6a565b60008681527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260409020600681015460038201549293509091869161068d91613304565b10156106e05760405162461bcd60e51b815260206004820152600260248201527f435200000000000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b8054421180156106f4575080600101544211155b6107405760405162461bcd60e51b815260206004820152600360248201527f4f4f54000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b848160020154610750919061331b565b341461079e5760405162461bcd60e51b815260206004820152600260248201527f494100000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b6001600160a01b038216600090815260078201602090815260408083205481519283018a9052908201889052606085811b6bffffffffffffffffffffffff191690830152607482018190529190609401604051602081830303815290604052905060006108287f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e90565b905060006108948861088e85805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90611ac0565b82549091506001600160a01b038083169116146108d85760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b888560060160008282546108ec919061333a565b90915550506001600160a01b038616600090815260078601602052604090208054600101905561092d868b8b60405180602001604052806000815250611adc565b6002850154156109e1576000606486600401543461094b919061331b565b6109559190613352565b905060006109638234613304565b60058801546040519192506001600160a01b03169082156108fc029083906000818181858888f193505050501580156109a0573d6000803e3d6000fd5b5060048401546040516001600160a01b039091169083156108fc029084906000818181858888f193505050501580156109dd573d6000803e3d6000fd5b5050505b888a876001600160a01b03167f25b428dfde728ccfaddad7e29e4ac23c24ed7fd1a6e3e3f91894a9a073f5dfff60405160405180910390a45060019998505050505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b03163314610aa25760405162461bcd60e51b815260206004820152600260248201527f4e4f00000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b7fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385161790557fd9b67a26000000000000000000000000000000000000000000000000000000006000527fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131f6020527f845f7f8d885943dffdc1524acbd9538b2923f93aad26d306df3b8982c7f0632d805460ff19166001179055610b6685611afd565b7f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e80546001600160a01b0395861673ffffffffffffffffffffffffffffffffffffffff19918216179091557f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5f8054938616938216939093179092557f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a628054919094169116179091555050565b60008181527fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c836020526040812080546060929190610c4f90613374565b80601f0160208091040260200160405190810160405280929190818152602001828054610c7b90613374565b8015610cc85780601f10610c9d57610100808354040283529160200191610cc8565b820191906000526020600020905b815481529060010190602001808311610cab57829003601f168201915b505050505090508051600003610d205760405162461bcd60e51b815260206004820152601d60248201527f455243313135355552493a20746f6b656e4964206e6f7420657869737400000060448201526064016106d7565b604051610d53907fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c849083906020016133ae565b604051602081830303815290604052915050919050565b60008181527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb602052604081206105f490611b2c565b6001600160a01b03811660009081527f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a6160205260408120546105f4565b6001600160a01b038516331480610e3657506001600160a01b03851660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832033845290915290205460ff165b610e945760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016106d7565b610ea2338686868686611b36565b5050505050565b60608151835114610f225760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d61746368000000000000000000000000000000000000000000000060648201526084016106d7565b82517f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b9060009067ffffffffffffffff811115610f6157610f61612c41565b604051908082528060200260200182016040528015610f8a578160200160208202803683370190505b50905060005b85518110156110c75760006001600160a01b0316868281518110610fb657610fb6613435565b60200260200101516001600160a01b03160361103a5760405162461bcd60e51b815260206004820152603160248201527f455243313135353a2062617463682062616c616e636520717565727920666f7260448201527f20746865207a65726f206164647265737300000000000000000000000000000060648201526084016106d7565b82600086838151811061104f5761104f613435565b60200260200101518152602001908152602001600020600087838151811061107957611079613435565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020548282815181106110b4576110b4613435565b6020908102919091010152600101610f90565b50949350505050565b60008181527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260408120600381015482918291829182918291829182036111425760405162461bcd60e51b8152602060048201526003602482015262444e4560e81b60448201526064016106d7565b805460018201546002830154600384015460048501546005860154600690960154949e939d50919b50995097506001600160a01b0390921695509350915050565b60008181527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb602052604081206060916111bc82611b2c565b67ffffffffffffffff8111156111d4576111d4612c41565b6040519080825280602002602001820160405280156111fd578160200160208202803683370190505b50905060005b61120c83611b2c565b8110156112595761121d8382611b5a565b82828151811061122f5761122f613435565b6001600160a01b0390921660209283029190910190910152806112518161344b565b915050611203565b509392505050565b6001600160a01b03811660009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ec602052604081206060916112a482611b2c565b67ffffffffffffffff8111156112bc576112bc612c41565b6040519080825280602002602001820160405280156112e5578160200160208202803683370190505b50905060005b6112f483611b2c565b811015611259576113058382611b5a565b82828151811061131757611317613435565b60209081029190910101528061132c8161344b565b9150506112eb565b6001600160a01b03821633036113b25760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c66000000000000000000000000000000000000000000000060648201526084016106d7565b3360008181527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60008281527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a60205260408120600381015482036114a35760405162461bcd60e51b8152602060048201526003602482015262444e4560e81b60448201526064016106d7565b6001600160a01b0383166000908152600782016020526040902054949350505050565b6000806114d38888613304565b116115055760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106d7565b60648311156115565760405162461bcd60e51b815260206004820152600360248201527f49534f000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b600084116115a65760405162461bcd60e51b815260206004820152600360248201527f494143000000000000000000000000000000000000000000000000000000000060448201526064016106d7565b7f47dc25f21c7793543edaeb1ef19d41726ddbada967ae9a7980b9bd8a45228a5e60006115d1611a6a565b905060006115de82610da0565b905060008b8b8b8b8b8b8888604051602001611601989796959493929190613464565b604051602081830303815290604052905060006116768761088e84805190602001206040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b85549091506001600160a01b038083169116146116ba5760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b600285015495506116cb868e611b66565b6116db8560020180546001019055565b6001600160a01b038416600090815260038601602052604090208054600101905560007f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe659600101600088815260200190815260200160002090508c81600001819055508b81600101819055508a8160020181905550898160030181905550888160040181905550848160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555086856001600160a01b03167f4011446e11141f68f741bffe55d700b48cbc73fb927148a01c8f4664c3be014260405160405180910390a3505050505050979650505050505050565b6001600160a01b03851633148061182c57506001600160a01b03851660009081527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68c6020908152604080832033845290915290205460ff165b61188a5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201526808185c1c1c9bdd995960ba1b60648201526084016106d7565b610ea2338686868686611ba2565b60006118a48383613304565b116118d65760405162461bcd60e51b8152602060048201526002602482015261125560f21b60448201526064016106d7565b60008481527f6862122c88c20d0f389f9211fb45e4a0982f5f74838cd11cfb5e8c8b41fbe65a602052604081209061190c611a6a565b60058301549091506001600160a01b038083169116146119535760405162461bcd60e51b81526020600482015260026024820152614e4d60f01b60448201526064016106d7565b61195d8686611b66565b8382556001820183905560405186906001600160a01b038316907fc177a540715440475d2386abd75ffd850e00fb1d9212ce20cfed7063e6dfb31190600090a3505050505050565b60006001600160a01b038316611a235760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084016106d7565b7f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b6000928352602090815260408084206001600160a01b0395909516845293905250205490565b600060183610801590611aa657507fa5e014e253d3b66bd348c3cdd05f38b9805fff0b6471d004b58c6ada26cae993546001600160a01b031633145b15611ab8575060131936013560601c90565b503390565b90565b6000806000611acf8585611bbe565b9150915061125981611c2c565b611ae884848484611de5565b611af733600086868686611f28565b50505050565b7fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c84611b288282613504565b5050565b60006105f4825490565b611b448686868686866120d6565b611b5286868686868661236e565b505050505050565b60006105f1838361246a565b60008281527fb3408a5d8f30170919d3996b6cc182726500ad24733d17ace2f621485f6e7c8360205260409020611b9d8282613504565b505050565b611bb086868686868661250b565b611b52868686868686611f28565b6000808251604103611bf45760208301516040840151606085015160001a611be8878285856126b3565b94509450505050611c25565b8251604003611c1d5760208301516040840151611c128683836127a0565b935093505050611c25565b506000905060025b9250929050565b6000816004811115611c4057611c406135c4565b03611c485750565b6001816004811115611c5c57611c5c6135c4565b03611ca95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106d7565b6002816004811115611cbd57611cbd6135c4565b03611d0a5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106d7565b6003816004811115611d1e57611d1e6135c4565b03611d765760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106d7565b6004816004811115611d8a57611d8a6135c4565b03611de25760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016106d7565b50565b6001600160a01b038416611e615760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016106d7565b611e8033600086611e71876127f2565b611e7a876127f2565b8661283d565b60008381527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602090815260408083206001600160a01b0388168452918290528220805491928592611ed390849061333a565b909155505060408051858152602081018590526001600160a01b0387169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b6001600160a01b0384163b15611b525760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611f6c90899089908890889088906004016135da565b6020604051808303816000875af1925050508015611fa7575060408051601f3d908101601f19168201909252611fa49181019061361d565b60015b61205c57611fb361363a565b806308c379a003611fec5750611fc7613655565b80611fd25750611fee565b8060405162461bcd60e51b81526004016106d79190612e39565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e74657200000000000000000000000060648201526084016106d7565b6001600160e01b0319811663f23a6e6160e01b146120cd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b60648201526084016106d7565b50505050505050565b6001600160a01b03841661213a5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b60648201526084016106d7565b81518351146121b15760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e6774682060448201527f6d69736d6174636800000000000000000000000000000000000000000000000060648201526084016106d7565b6121bf86868686868661283d565b7f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b60005b845181101561230d57600085828151811061220057612200613435565b60200260200101519050600085838151811061221e5761221e613435565b602090810291909101810151600084815286835260408082206001600160a01b038e1683529093529190912054909150818110156122b25760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201526a37b9103a3930b739b332b960a91b60648201526084016106d7565b6000838152602086815260408083206001600160a01b038e811685529252808320938590039093558a16815290812080548392906122f190849061333a565b92505081905550505080806123059061344b565b9150506121e3565b50846001600160a01b0316866001600160a01b0316886001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb878760405161235d9291906136df565b60405180910390a450505050505050565b6001600160a01b0384163b15611b525760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906123b2908990899088908890889060040161370d565b6020604051808303816000875af19250505080156123ed575060408051601f3d908101601f191682019092526123ea9181019061361d565b60015b6123f957611fb361363a565b6001600160e01b0319811663bc197c8160e01b146120cd5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b60648201526084016106d7565b815460009082106124e35760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60448201527f647300000000000000000000000000000000000000000000000000000000000060648201526084016106d7565b8260000182815481106124f8576124f8613435565b9060005260206000200154905092915050565b6001600160a01b03841661256f5760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b60648201526084016106d7565b61257e868686611e71876127f2565b60008381527f1799cf914cb0cb442ca7c7ac709ee40d0cb89e87351dc08d517fbda27d50c68b602081815260408084206001600160a01b038a16855290915290912054838110156126255760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a20696e73756666696369656e742062616c616e636573206660448201526a37b9103a3930b739b332b960a91b60648201526084016106d7565b6000858152602083815260408083206001600160a01b038b8116855292528083209387900390935587168152908120805485929061266490849061333a565b909155505060408051858152602081018590526001600160a01b038088169289821692918b16917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910161235d565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156126ea5750600090506003612797565b8460ff16601b1415801561270257508460ff16601c14155b156127135750600090506004612797565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612767573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661279057600060019250925050612797565b9150600090505b94509492505050565b6000807f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8316816127d660ff86901c601b61333a565b90506127e4878288856126b3565b935093505050935093915050565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061282c5761282c613435565b602090810291909101015292915050565b611b52868686868686611b52868686868686836001600160a01b0316856001600160a01b031614611b52576001600160a01b0385811660009081527fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ec6020526040808220928716825281207fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424ea927fb31c2c74f86ca3ce94d901f5f5bbe66f7161eec2f7b5aa0b75a86371436424eb929091905b8751811015612a3857600087828151811061290d5761290d613435565b602002602001015190506000811115612a2557600089838151811061293457612934613435565b6020026020010151905060006001600160a01b03168c6001600160a01b031603612981576000818152602088905260408120805484929061297690849061333a565b909155506129b69050565b8161298c8d836119a5565b036129b65760008181526020879052604090206129a9908d612a45565b506129b48582612a5a565b505b6001600160a01b038b166129ed57600081815260208890526040812080548492906129e2908490613304565b90915550612a239050565b6129f78b826119a5565b600003612a23576000818152602087905260409020612a16908c612a66565b50612a218482612a7b565b505b505b5080612a308161344b565b9150506128f0565b5050505050505050505050565b60006105f1836001600160a01b038416612a87565b60006105f18383612a87565b60006105f1836001600160a01b038416612b72565b60006105f18383612b72565b60008181526001830160205260408120548015612b68576000612aab600183613304565b85549091506000908690612ac190600190613304565b81548110612ad157612ad1613435565b9060005260206000200154905080866000018381548110612af457612af4613435565b600091825260209091200155612b0b82600161333a565b60008281526001880160205260409020558554869080612b2d57612b2d61376b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506105f4565b60009150506105f4565b6000818152600183016020526040812054612bb9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556105f4565b5060006105f4565b80356001600160a01b0381168114612bd857600080fd5b919050565b60008060408385031215612bf057600080fd5b612bf983612bc1565b946020939093013593505050565b6001600160e01b031981168114611de257600080fd5b600060208284031215612c2f57600080fd5b8135612c3a81612c07565b9392505050565b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff81118282101715612c7d57612c7d612c41565b6040525050565b600082601f830112612c9557600080fd5b813567ffffffffffffffff811115612caf57612caf612c41565b604051612cc6601f8301601f191660200182612c57565b818152846020838601011115612cdb57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612d0d57600080fd5b8335925060208401359150604084013567ffffffffffffffff811115612d3257600080fd5b612d3e86828701612c84565b9150509250925092565b600080600080600060a08688031215612d6057600080fd5b853567ffffffffffffffff811115612d7757600080fd5b612d8388828901612c84565b955050612d9260208701612bc1565b9350612da060408701612bc1565b9250612dae60608701612bc1565b9150612dbc60808701612bc1565b90509295509295909350565b600060208284031215612dda57600080fd5b5035919050565b60005b83811015612dfc578181015183820152602001612de4565b83811115611af75750506000910152565b60008151808452612e25816020860160208601612de1565b601f01601f19169290920160200192915050565b6020815260006105f16020830184612e0d565b600060208284031215612e5e57600080fd5b6105f182612bc1565b600067ffffffffffffffff821115612e8157612e81612c41565b5060051b60200190565b600082601f830112612e9c57600080fd5b81356020612ea982612e67565b604051612eb68282612c57565b83815260059390931b8501820192828101915086841115612ed657600080fd5b8286015b84811015612ef15780358352918301918301612eda565b509695505050505050565b600080600080600060a08688031215612f1457600080fd5b612f1d86612bc1565b9450612f2b60208701612bc1565b9350604086013567ffffffffffffffff80821115612f4857600080fd5b612f5489838a01612e8b565b94506060880135915080821115612f6a57600080fd5b612f7689838a01612e8b565b93506080880135915080821115612f8c57600080fd5b50612f9988828901612c84565b9150509295509295909350565b60008060408385031215612fb957600080fd5b823567ffffffffffffffff80821115612fd157600080fd5b818501915085601f830112612fe557600080fd5b81356020612ff282612e67565b604051612fff8282612c57565b83815260059390931b850182019282810191508984111561301f57600080fd5b948201945b838610156130445761303586612bc1565b82529482019490820190613024565b9650508601359250508082111561305a57600080fd5b5061306785828601612e8b565b9150509250929050565b600081518084526020808501945080840160005b838110156130a157815187529582019590820190600101613085565b509495945050505050565b6020815260006105f16020830184613071565b6020808252825182820181905260009190848201906040850190845b818110156131005783516001600160a01b0316835292840192918401916001016130db565b50909695505050505050565b6000806040838503121561311f57600080fd5b61312883612bc1565b91506020830135801515811461313d57600080fd5b809150509250929050565b6000806040838503121561315b57600080fd5b8235915061316b60208401612bc1565b90509250929050565b600080600080600080600060e0888a03121561318f57600080fd5b873567ffffffffffffffff808211156131a757600080fd5b6131b38b838c01612c84565b985060208a0135975060408a0135965060608a0135955060808a0135945060a08a0135935060c08a01359150808211156131ec57600080fd5b506131f98a828b01612c84565b91505092959891949750929550565b6000806040838503121561321b57600080fd5b61322483612bc1565b915061316b60208401612bc1565b600080600080600060a0868803121561324a57600080fd5b61325386612bc1565b945061326160208701612bc1565b93506040860135925060608601359150608086013567ffffffffffffffff81111561328b57600080fd5b612f9988828901612c84565b600080600080608085870312156132ad57600080fd5b84359350602085013567ffffffffffffffff8111156132cb57600080fd5b6132d787828801612c84565b949794965050505060408301359260600135919050565b634e487b7160e01b600052601160045260246000fd5b600082821015613316576133166132ee565b500390565b6000816000190483118215151615613335576133356132ee565b500290565b6000821982111561334d5761334d6132ee565b500190565b60008261336f57634e487b7160e01b600052601260045260246000fd5b500490565b600181811c9082168061338857607f821691505b6020821081036133a857634e487b7160e01b600052602260045260246000fd5b50919050565b60008084546133bc81613374565b600182811680156133d457600181146133e957613418565b60ff1984168752821515830287019450613418565b8860005260208060002060005b8581101561340f5781548a8201529084019082016133f6565b50505082870194505b50505050835161342c818360208801612de1565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161345d5761345d6132ee565b5060010190565b60008951613476818460208e01612de1565b91909101978852506020870195909552604086019390935260608086019290925260808501521b6bffffffffffffffffffffffff191660a083015260b482015260d401919050565b601f821115611b9d57600081815260208120601f850160051c810160208610156134e55750805b601f850160051c820191505b81811015611b52578281556001016134f1565b815167ffffffffffffffff81111561351e5761351e612c41565b6135328161352c8454613374565b846134be565b602080601f831160018114613567576000841561354f5750858301515b600019600386901b1c1916600185901b178555611b52565b600085815260208120601f198616915b8281101561359657888601518255948401946001909101908401613577565b50858210156135b45787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052602160045260246000fd5b60006001600160a01b03808816835280871660208401525084604083015283606083015260a0608083015261361260a0830184612e0d565b979650505050505050565b60006020828403121561362f57600080fd5b8151612c3a81612c07565b600060033d1115611abd5760046000803e5060005160e01c90565b600060443d10156136635790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561369357505050505090565b82850191508151818111156136ab5750505050505090565b843d87010160208285010111156136c55750505050505090565b6136d460208286010187612c57565b509095945050505050565b6040815260006136f26040830185613071565b82810360208401526137048185613071565b95945050505050565b60006001600160a01b03808816835280871660208401525060a0604083015261373960a0830186613071565b828103606084015261374b8186613071565b9050828103608084015261375f8185612e0d565b98975050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220875864685e82b792d01fb06a86eff31b919a76acbcd5307197c3a7c5e40805cc64736f6c634300080f0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.