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
TokenTracker
Latest 25 from a total of 968 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Transfer From | 19299739 | 153 days ago | IN | 0 ETH | 0.00237112 | ||||
Transfer From | 19299712 | 153 days ago | IN | 0 ETH | 0.00215474 | ||||
Transfer From | 19275727 | 156 days ago | IN | 0 ETH | 0.0012939 | ||||
Set Public Price | 19240910 | 161 days ago | IN | 0 ETH | 0.00105025 | ||||
Withdraw All | 19228436 | 163 days ago | IN | 0 ETH | 0.0008225 | ||||
Mint | 19228396 | 163 days ago | IN | 0.019 ETH | 0.00162735 | ||||
Mint | 19221738 | 164 days ago | IN | 0.019 ETH | 0.00212224 | ||||
Transfer From | 19210716 | 166 days ago | IN | 0 ETH | 0.0009624 | ||||
Set Base Uri | 19210096 | 166 days ago | IN | 0 ETH | 0.00089731 | ||||
Transfer From | 19207292 | 166 days ago | IN | 0 ETH | 0.00134728 | ||||
Withdraw All | 19172615 | 171 days ago | IN | 0 ETH | 0.00078869 | ||||
Mint | 19169921 | 171 days ago | IN | 0.019 ETH | 0.00258165 | ||||
Set Approval For... | 19158272 | 173 days ago | IN | 0 ETH | 0.0005719 | ||||
Mint | 19158235 | 173 days ago | IN | 0.038 ETH | 0.00155362 | ||||
Withdraw All | 19157757 | 173 days ago | IN | 0 ETH | 0.00043236 | ||||
Mint | 19157748 | 173 days ago | IN | 0.038 ETH | 0.00145158 | ||||
Withdraw All | 19125222 | 178 days ago | IN | 0 ETH | 0.00064822 | ||||
Transfer From | 19107886 | 180 days ago | IN | 0 ETH | 0.00076353 | ||||
Transfer From | 19107863 | 180 days ago | IN | 0 ETH | 0.00071199 | ||||
Enable Public Sa... | 19097830 | 181 days ago | IN | 0 ETH | 0.00033719 | ||||
Enable Raffle | 19097827 | 181 days ago | IN | 0 ETH | 0.00036363 | ||||
Set Public Price | 19097818 | 181 days ago | IN | 0 ETH | 0.00041799 | ||||
Set Public Price | 19097799 | 181 days ago | IN | 0 ETH | 0.00035721 | ||||
Add To Whitelist | 19093096 | 182 days ago | IN | 0 ETH | 0.00079516 | ||||
Transfer From | 19077954 | 184 days ago | IN | 0 ETH | 0.00087884 |
Loading...
Loading
Contract Name:
NFT
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ERC721.sol"; import "./DefaultOperatorFilterer.sol"; import "./Context.sol"; import "./Ownable.sol"; contract NFT is ERC721, Ownable, DefaultOperatorFilterer { using Strings for uint256; uint public constant MAX_TOKENS = 15000; uint256 public whitelistPrice = 22 * 10**15; uint256 public rafflePrice = 27 *10**15; uint256 public publicPrice = 29 * 10**15; uint256 public constant MAX_MINT_PER_TX = 5; uint256 public maxMelianID = 4888; uint256 public maxSabarianID = 9776; uint256 public maxRangarkID = 14664; bool public isWhitelist = false; bool public isRaffle = false; bool public isPublic = false; mapping(address => bool) private _iswhitelist; mapping(address => bool) private _israffle; uint256 public totalSupply; string public baseUri; string public baseExtension = ".json"; uint256 private currentCap = 0; address private _devWallet = 0xfdD120ed376F9c7CE805a75bdc92b8f4609F1F38; address private _sellContract = 0x62BC670611bD4bdd4414334153B93807e1077dbF; constructor() ERC721("Valarok", "VALAROK") { baseUri = "https://bafybeialnm3yx3dgechabp4b2obucqavfixuiclejbbt6laglhzsn4mrbq.ipfs.nftstorage.link/"; } // Public Functions function mint(uint256 _numTokens) external payable { uint256 curTotalSupply = totalSupply; require(curTotalSupply + _numTokens <= MAX_TOKENS, "Exceeds total supply."); if(_msgSender() != owner()){ require(_numTokens <= MAX_MINT_PER_TX, "You cannot mint that many in one transaction."); uint256 price = _checkSellingPhase(_msgSender()); require(_numTokens * price <= msg.value, "Insufficient funds."); require(currentCap - curTotalSupply >= _numTokens, "The amount exceeds maximum availability for the ongoing phase!"); } for(uint256 i = 1; i <= _numTokens; ++i){ _safeMint(msg.sender, curTotalSupply + i); } totalSupply += _numTokens; } function _checkSellingPhase(address _buyer) internal view returns (uint256) { uint256 price = 0; if(isWhitelist) { require(_iswhitelist[_buyer], "Your wallet address is not included into the Whitelist"); price = whitelistPrice; } else if(isRaffle) { require(_israffle[_buyer], "Your wallet address is not included into the Raffle"); price = rafflePrice; } else { price = publicPrice; } return price; } // OnlyOwner Functions function setSellingContract (address _address) external onlyOwner { _sellContract = _address; } function updateDevWallet (address _address) external onlyOwner { _devWallet = _address; } function addToWhitelist(address _address) external onlyOwner { _iswhitelist[_address] = true; } function addToRaffle(address _address) external onlyOwner { _israffle[_address] = true; } function enableWhitelist() external onlyOwner { isWhitelist = true; } function enableRaffle() external onlyOwner { isWhitelist = false; isRaffle = true; } function enablePublicSale() external onlyOwner{ isWhitelist = false; isRaffle = false; isPublic = true; } function enableMelian() external onlyOwner { currentCap = maxMelianID; } function enableSabarian() external onlyOwner { require(totalSupply == maxMelianID, "Non puoi attivarla adesso, finisci di mintare i Melian prima!"); currentCap = maxSabarianID; } function enableRangark() external onlyOwner { require(totalSupply == maxSabarianID, "Non puoi attivarla adesso, finisci di mintare i Sabarian prima!"); currentCap = maxRangarkID; } function setBaseUri(string memory _baseUri) external onlyOwner { baseUri = _baseUri; } function setWhitelistPrice(uint256 _price, uint256 _decimals) external onlyOwner { whitelistPrice = _price * 10**_decimals; } function setRafflePrice(uint256 _price, uint256 _decimals) external onlyOwner { rafflePrice = _price * 10**_decimals; } function setPublicPrice(uint256 _price, uint256 _decimals) external onlyOwner { publicPrice = _price * 10**_decimals; } function withdrawAll() external payable onlyOwner { uint256 balance = address(this).balance; require(payable(_devWallet).send(balance), "Transfer failed."); } function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator { super.transferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator { super.safeTransferFrom(from, to, tokenId); } function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override onlyAllowedOperator { super.safeTransferFrom(from, to, tokenId, data); } function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension)) : ""; } function _baseURI() internal view virtual override returns (string memory) { return baseUri; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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.13; import {OperatorFilterer} from "./OperatorFilterer.sol"; contract DefaultOperatorFilterer is OperatorFilterer { address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6); constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./IERC721Metadata.sol"; import "./Address.sol"; import "./Context.sol"; import "./Strings.sol"; import "./ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll( address owner, address operator, bool approved ) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256, /* firstTokenId */ uint256 batchSize ) internal virtual { if (batchSize > 1) { if (from != address(0)) { _balances[from] -= batchSize; } if (to != address(0)) { _balances[to] += batchSize; } } } /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; import "./IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {EnumerableSet} from "./EnumerableSet.sol"; interface IOperatorFilterRegistry { function isOperatorAllowed(address registrant, address operator) external returns (bool); function register(address registrant) external; function registerAndSubscribe(address registrant, address subscription) external; function registerAndCopyEntries(address registrant, address registrantToCopy) external; function updateOperator(address registrant, address operator, bool filtered) external; function updateOperators(address registrant, address[] calldata operators, bool filtered) external; function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external; function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external; function subscribe(address registrant, address registrantToSubscribe) external; function unsubscribe(address registrant, bool copyExistingEntries) external; function subscriptionOf(address addr) external returns (address registrant); function subscribers(address registrant) external returns (address[] memory); function subscriberAt(address registrant, uint256 index) external returns (address); function copyEntriesOf(address registrant, address registrantToCopy) external; function isOperatorFiltered(address registrant, address operator) external returns (bool); function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool); function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool); function filteredOperators(address addr) external returns (address[] memory); function filteredCodeHashes(address addr) external returns (bytes32[] memory); function filteredOperatorAt(address registrant, uint256 index) external returns (address); function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32); function isRegistered(address addr) external returns (bool); function codeHashOf(address addr) external returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; contract OperatorFilterer { error OperatorNotAllowed(address operator); IOperatorFilterRegistry constant operatorFilterRegistry = IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E); constructor(address subscriptionOrRegistrantToCopy, bool subscribe) { // If an inheriting token contract is deployed to a network without the registry deployed, the modifier // will not revert, but the contract will need to be registered with the registry once it is deployed in // order for the modifier to filter addresses. if (address(operatorFilterRegistry).code.length > 0) { if (subscribe) { operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy); } else { if (subscriptionOrRegistrantToCopy != address(0)) { operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy); } else { operatorFilterRegistry.register(address(this)); } } } } modifier onlyAllowedOperator() virtual { // Check registry code length to facilitate testing in environments without a deployed registry. if (address(operatorFilterRegistry).code.length > 0) { if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) { revert OperatorNotAllowed(msg.sender); } } _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; import {Ownable} from "./Ownable.sol"; import {EnumerableSet} from "./EnumerableSet.sol"; import {OperatorFilterRegistryErrorsAndEvents} from "./OperatorFilterRegistryErrorsAndEvents.sol"; /** * @title OperatorFilterRegistry * @notice Borrows heavily from the QQL BlacklistOperatorFilter contract: * https://github.com/qql-art/contracts/blob/main/contracts/BlacklistOperatorFilter.sol * @notice This contracts allows tokens or token owners to register specific addresses or codeHashes that may be * * restricted according to the isOperatorAllowed function. */ contract OperatorFilterRegistry is IOperatorFilterRegistry, OperatorFilterRegistryErrorsAndEvents { using EnumerableSet for EnumerableSet.AddressSet; using EnumerableSet for EnumerableSet.Bytes32Set; /// @dev initialized accounts have a nonzero codehash (see https://eips.ethereum.org/EIPS/eip-1052) /// Note that this will also be a smart contract's codehash when making calls from its constructor. bytes32 constant EOA_CODEHASH = keccak256(""); mapping(address => EnumerableSet.AddressSet) private _filteredOperators; mapping(address => EnumerableSet.Bytes32Set) private _filteredCodeHashes; mapping(address => address) private _registrations; mapping(address => EnumerableSet.AddressSet) private _subscribers; /** * @notice restricts method caller to the address or EIP-173 "owner()" */ modifier onlyAddressOrOwner(address addr) { if (msg.sender != addr) { try Ownable(addr).owner() returns (address owner) { if (msg.sender != owner) { revert OnlyAddressOrOwner(); } } catch (bytes memory reason) { if (reason.length == 0) { revert NotOwnable(); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } _; } /** * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns * true if supplied registrant address is not registered. */ function isOperatorAllowed(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != address(0)) { EnumerableSet.AddressSet storage filteredOperatorsRef; EnumerableSet.Bytes32Set storage filteredCodeHashesRef; filteredOperatorsRef = _filteredOperators[registration]; filteredCodeHashesRef = _filteredCodeHashes[registration]; if (filteredOperatorsRef.contains(operator)) { revert AddressFiltered(operator); } if (operator.code.length > 0) { bytes32 codeHash = operator.codehash; if (filteredCodeHashesRef.contains(codeHash)) { revert CodeHashFiltered(operator, codeHash); } } } return true; } ////////////////// // AUTH METHODS // ////////////////// /** * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner. */ function register(address registrant) external onlyAddressOrOwner(registrant) { if (_registrations[registrant] != address(0)) { revert AlreadyRegistered(); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); } /** * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner. * Note that this does not remove any filtered addresses or codeHashes. * Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes. */ function unregister(address registrant) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = address(0); emit RegistrationUpdated(registrant, false); } /** * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes. */ function registerAndSubscribe(address registrant, address subscription) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } if (registrant == subscription) { revert CannotSubscribeToSelf(); } address subscriptionRegistration = _registrations[subscription]; if (subscriptionRegistration == address(0)) { revert NotRegistered(subscription); } if (subscriptionRegistration != subscription) { revert CannotSubscribeToRegistrantWithSubscription(subscription); } _registrations[registrant] = subscription; _subscribers[subscription].add(registrant); emit RegistrationUpdated(registrant, true); emit SubscriptionUpdated(registrant, subscription, true); } /** * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another * address without subscribing. */ function registerAndCopyEntries(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrantToCopy == registrant) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration != address(0)) { revert AlreadyRegistered(); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _registrations[registrant] = registrant; emit RegistrationUpdated(registrant, true); _copyEntries(registrant, registrantToCopy); } /** * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered. */ function updateOperator(address registrant, address operator, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; if (!filtered) { bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } else { bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } emit OperatorUpdated(registrant, operator, filtered); } /** * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered. */ function updateCodeHash(address registrant, bytes32 codeHash, bool filtered) external onlyAddressOrOwner(registrant) { if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; if (!filtered) { bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } else { bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } emit CodeHashUpdated(registrant, codeHash, filtered); } /** * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates. */ function updateOperators(address registrant, address[] calldata operators, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrant]; uint256 operatorsLength = operators.length; unchecked { if (!filtered) { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool removed = filteredOperatorsRef.remove(operator); if (!removed) { revert AddressNotFiltered(operator); } } } else { for (uint256 i = 0; i < operatorsLength; ++i) { address operator = operators[i]; bool added = filteredOperatorsRef.add(operator); if (!added) { revert AddressAlreadyFiltered(operator); } } } } emit OperatorsUpdated(registrant, operators, filtered); } /** * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates. */ function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrant]; uint256 codeHashesLength = codeHashes.length; unchecked { if (!filtered) { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; bool removed = filteredCodeHashesRef.remove(codeHash); if (!removed) { revert CodeHashNotFiltered(codeHash); } } } else { for (uint256 i = 0; i < codeHashesLength; ++i) { bytes32 codeHash = codeHashes[i]; if (codeHash == EOA_CODEHASH) { revert CannotFilterEOAs(); } bool added = filteredCodeHashesRef.add(codeHash); if (!added) { revert CodeHashAlreadyFiltered(codeHash); } } } } emit CodeHashesUpdated(registrant, codeHashes, filtered); } /** * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous * subscription if present. * Note that accounts with subscriptions may go on to subscribe to other accounts - in this case, * subscriptions will not be forwarded. Instead the former subscription's existing entries will still be * used. */ function subscribe(address registrant, address newSubscription) external onlyAddressOrOwner(registrant) { if (registrant == newSubscription) { revert CannotSubscribeToSelf(); } if (newSubscription == address(0)) { revert CannotSubscribeToZeroAddress(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == newSubscription) { revert AlreadySubscribed(newSubscription); } address newSubscriptionRegistration = _registrations[newSubscription]; if (newSubscriptionRegistration == address(0)) { revert NotRegistered(newSubscription); } if (newSubscriptionRegistration != newSubscription) { revert CannotSubscribeToRegistrantWithSubscription(newSubscription); } if (registration != registrant) { _subscribers[registration].remove(registrant); emit SubscriptionUpdated(registrant, registration, false); } _registrations[registrant] = newSubscription; _subscribers[newSubscription].add(registrant); emit SubscriptionUpdated(registrant, newSubscription, true); } /** * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes. */ function unsubscribe(address registrant, bool copyExistingEntries) external onlyAddressOrOwner(registrant) { address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration == registrant) { revert NotSubscribed(); } _subscribers[registration].remove(registrant); _registrations[registrant] = registrant; emit SubscriptionUpdated(registrant, registration, false); if (copyExistingEntries) { _copyEntries(registrant, registration); } } /** * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr. */ function copyEntriesOf(address registrant, address registrantToCopy) external onlyAddressOrOwner(registrant) { if (registrant == registrantToCopy) { revert CannotCopyFromSelf(); } address registration = _registrations[registrant]; if (registration == address(0)) { revert NotRegistered(registrant); } if (registration != registrant) { revert CannotUpdateWhileSubscribed(registration); } address registrantRegistration = _registrations[registrantToCopy]; if (registrantRegistration == address(0)) { revert NotRegistered(registrantToCopy); } _copyEntries(registrant, registrantToCopy); } /// @dev helper to copy entries from registrantToCopy to registrant and emit events function _copyEntries(address registrant, address registrantToCopy) private { EnumerableSet.AddressSet storage filteredOperatorsRef = _filteredOperators[registrantToCopy]; EnumerableSet.Bytes32Set storage filteredCodeHashesRef = _filteredCodeHashes[registrantToCopy]; uint256 filteredOperatorsLength = filteredOperatorsRef.length(); uint256 filteredCodeHashesLength = filteredCodeHashesRef.length(); unchecked { for (uint256 i = 0; i < filteredOperatorsLength; ++i) { address operator = filteredOperatorsRef.at(i); bool added = _filteredOperators[registrant].add(operator); if (added) { emit OperatorUpdated(registrant, operator, true); } } for (uint256 i = 0; i < filteredCodeHashesLength; ++i) { bytes32 codehash = filteredCodeHashesRef.at(i); bool added = _filteredCodeHashes[registrant].add(codehash); if (added) { emit CodeHashUpdated(registrant, codehash, true); } } } } ////////////////// // VIEW METHODS // ////////////////// /** * @notice Get the subscription address of a given registrant, if any. */ function subscriptionOf(address registrant) external view returns (address subscription) { subscription = _registrations[registrant]; if (subscription == address(0)) { revert NotRegistered(registrant); } else if (subscription == registrant) { subscription = address(0); } } /** * @notice Get the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscribers(address registrant) external view returns (address[] memory) { return _subscribers[registrant].values(); } /** * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant. * Note that order is not guaranteed as updates are made. */ function subscriberAt(address registrant, uint256 index) external view returns (address) { return _subscribers[registrant].at(index); } /** * @notice Returns true if operator is filtered by a given address or its subscription. */ function isOperatorFiltered(address registrant, address operator) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].contains(operator); } return _filteredOperators[registrant].contains(operator); } /** * @notice Returns true if a codeHash is filtered by a given address or its subscription. */ function isCodeHashFiltered(address registrant, bytes32 codeHash) external view returns (bool) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription. */ function isCodeHashOfFiltered(address registrant, address operatorWithCode) external view returns (bool) { bytes32 codeHash = operatorWithCode.codehash; address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].contains(codeHash); } return _filteredCodeHashes[registrant].contains(codeHash); } /** * @notice Returns true if an address has registered */ function isRegistered(address registrant) external view returns (bool) { return _registrations[registrant] != address(0); } /** * @notice Returns a list of filtered operators for a given address or its subscription. */ function filteredOperators(address registrant) external view returns (address[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].values(); } return _filteredOperators[registrant].values(); } /** * @notice Returns the set of filtered codeHashes for a given address or its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashes(address registrant) external view returns (bytes32[] memory) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].values(); } return _filteredCodeHashes[registrant].values(); } /** * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredOperatorAt(address registrant, uint256 index) external view returns (address) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredOperators[registration].at(index); } return _filteredOperators[registrant].at(index); } /** * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or * its subscription. * Note that order is not guaranteed as updates are made. */ function filteredCodeHashAt(address registrant, uint256 index) external view returns (bytes32) { address registration = _registrations[registrant]; if (registration != registrant) { return _filteredCodeHashes[registration].at(index); } return _filteredCodeHashes[registrant].at(index); } /// @dev Convenience method to compute the code hash of an arbitrary contract function codeHashOf(address a) external view returns (bytes32) { return a.codehash; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; contract OperatorFilterRegistryErrorsAndEvents { error CannotFilterEOAs(); error AddressAlreadyFiltered(address operator); error AddressNotFiltered(address operator); error CodeHashAlreadyFiltered(bytes32 codeHash); error CodeHashNotFiltered(bytes32 codeHash); error OnlyAddressOrOwner(); error NotRegistered(address registrant); error AlreadyRegistered(); error AlreadySubscribed(address subscription); error NotSubscribed(); error CannotUpdateWhileSubscribed(address subscription); error CannotSubscribeToSelf(); error CannotSubscribeToZeroAddress(); error NotOwnable(); error AddressFiltered(address filtered); error CodeHashFiltered(address account, bytes32 codeHash); error CannotSubscribeToRegistrantWithSubscription(address registrant); error CannotCopyFromSelf(); event RegistrationUpdated(address indexed registrant, bool indexed registered); event OperatorUpdated(address indexed registrant, address indexed operator, bool indexed filtered); event OperatorsUpdated(address indexed registrant, address[] operators, bool indexed filtered); event CodeHashUpdated(address indexed registrant, bytes32 indexed codeHash, bool indexed filtered); event CodeHashesUpdated(address indexed registrant, bytes32[] codeHashes, bool indexed filtered); event SubscriptionUpdated(address indexed registrant, address indexed subscription, bool indexed subscribed); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "./Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import {IOperatorFilterRegistry} from "./IOperatorFilterRegistry.sol"; import {Ownable} from "./Ownable.sol"; /** * @title OwnedRegistrant * @notice Ownable contract that registers itself with the OperatorFilterRegistry and administers its own entries, * to facilitate a subscription whose ownership can be transferred. */ contract OwnedRegistrant is Ownable { address constant registry = 0x000000000000AAeB6D7670E522A718067333cd4E; constructor(address _owner) { IOperatorFilterRegistry(registry).register(address(this)); transferOwnership(_owner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./Ownable.sol"; contract ReferralStorage is Ownable { struct Sales { address buyer; address seller; uint256 fee; uint256 date; } Sales[] _sales; address[] _affiliates; mapping (address => uint256) public _affInterest; // percentuale mapping (address => bool) public _isAffiliate; // affiliato o no mapping (address => string) public _teamName; // Team Name mapping (uint256 => address) public _uid; mapping (address => uint256) public _uidAssign; mapping (address => uint256) public _invites; mapping (address => uint256) public _earnings; uint256 public _totalSold; uint256 public _totCommission; uint256 _cnt = 1; function addAffiliate(string memory _name, uint256 _percent, address _aff) public onlyOwner { require(_isAffiliate[_aff] == false, "Address already affiliated!"); _teamName[_aff] = _name; _affInterest[_aff] = _percent; _isAffiliate[_aff] = true; _affiliates.push(_aff); _uid[_cnt] = _aff; _uidAssign[_aff] = _cnt; _cnt++; } function retrieveAffiliates() public view returns (address[] memory){ return _affiliates; } function retrieveLenght() public view onlyOwner returns (uint256){ return _affiliates.length; } function retrieveSales() public view returns (Sales[] memory) { return _sales; } function _withReferralSale(uint256 _amount, address _buyer, address _seller, uint256 _date) internal returns (uint256) { uint256 fee = _amount * _affInterest[_seller] / 100; _sales.push(Sales(_buyer, _seller, fee, _date)); _invites[_seller] += 1; _earnings[_seller] += fee; _totalSold += 1; _totCommission += fee; return fee; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _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) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _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); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_MINT_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addToRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableMelian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enablePublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableRangark","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableSabarian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublic","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRaffle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMelianID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRangarkID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSabarianID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numTokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rafflePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseUri","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setPublicPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setRafflePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setSellingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"},{"internalType":"uint256","name":"_decimals","type":"uint256"}],"name":"setWhitelistPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateDevWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
664e28e2290f0000600755665fec5b60ef800060085566670758aa7c8000600955611318600a55612630600b55613948600c55600d805462ffffff1916905560c06040526005608090815264173539b7b760d91b60a052601290620000659082620003b4565b505f601355601480546001600160a01b031990811673fdd120ed376f9c7ce805a75bdc92b8f4609f1f3817909155601580549091167362bc670611bd4bdd4414334153b93807e1077dbf179055348015620000be575f80fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600781526020016656616c61726f6b60c81b8152506040518060400160405280600781526020016656414c41524f4b60c81b815250815f9081620001269190620003b4565b506001620001358282620003b4565b505050620001526200014c620002bf60201b60201c565b620002c3565b6daaeb6d7670e522a718067333cd4e3b156200028d578015620001e057604051633e9f1edf60e11b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e90637d3e3dbe906044015b5f604051808303815f87803b158015620001c3575f80fd5b505af1158015620001d6573d5f803e3d5ffd5b505050506200028d565b6001600160a01b03821615620002315760405163a0af290360e01b81523060048201526001600160a01b03831660248201526daaeb6d7670e522a718067333cd4e9063a0af290390604401620001ab565b604051632210724360e11b81523060048201526daaeb6d7670e522a718067333cd4e90634420e486906024015f604051808303815f87803b15801562000275575f80fd5b505af115801562000288573d5f803e3d5ffd5b505050505b505060405180608001604052806059815260200162002aeb60599139601190620002b89082620003b4565b506200047c565b3390565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806200033d57607f821691505b6020821081036200035c57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115620003af575f81815260208120601f850160051c810160208610156200038a5750805b601f850160051c820191505b81811015620003ab5782815560010162000396565b5050505b505050565b81516001600160401b03811115620003d057620003d062000314565b620003e881620003e1845462000328565b8462000362565b602080601f8311600181146200041e575f8415620004065750858301515b5f19600386901b1c1916600185901b178555620003ab565b5f85815260208120601f198616915b828110156200044e578886015182559484019460019091019084016200042d565b50858210156200046c57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b612661806200048a5f395ff3fe608060405260043610610275575f3560e01c80639de210751161014a578063c87b56dd116100be578063eeaa32fe11610078578063eeaa32fe146106c4578063f18aceda146106e3578063f2fde38b146106f7578063f47c84c514610716578063f8d867941461072b578063fc1a1c3614610740575f80fd5b8063c87b56dd14610615578063cdfb2b4e14610634578063daa28cd214610648578063dc9a153514610667578063e43252d714610686578063e985e9c5146106a5575f80fd5b8063a407ad6a1161010f578063a407ad6a1461057b578063a945bf801461059a578063abaf1de9146105af578063ac4410be146105ce578063b88d4fde146105e2578063c668286214610601575f80fd5b80639de21075146105005780639df47cab14610515578063a0712d681461052a578063a0bcfc7f1461053d578063a22cb4651461055c575f80fd5b80633df1de4e116101ec578063715018a6116101a6578063715018a61461048b578063853828b61461049f5780638da5cb5b146104a75780638ecad721146104c457806395d89b41146104d85780639abc8320146104ec575f80fd5b80633df1de4e146103ec5780634146ed0a1461040157806342842e0e1461041a57806360831b1f146104395780636352211e1461044d57806370a082311461046c575f80fd5b80631816467f1161023d5780631816467f146103495780631d85e95a146103685780631f265e42146103875780632316b4da146103a557806323b872dd146103b957806330dad648146103d8575f80fd5b806301ffc9a71461027957806306fdde03146102ad578063081812fc146102ce578063095ea7b31461030557806318160ddd14610326575b5f80fd5b348015610284575f80fd5b50610298610293366004611ea9565b610755565b60405190151581526020015b60405180910390f35b3480156102b8575f80fd5b506102c16107a6565b6040516102a49190611f11565b3480156102d9575f80fd5b506102ed6102e8366004611f23565b610835565b6040516001600160a01b0390911681526020016102a4565b348015610310575f80fd5b5061032461031f366004611f55565b61085a565b005b348015610331575f80fd5b5061033b60105481565b6040519081526020016102a4565b348015610354575f80fd5b50610324610363366004611f7d565b610973565b348015610373575f80fd5b50610324610382366004611f7d565b61099d565b348015610392575f80fd5b50600d5461029890610100900460ff1681565b3480156103b0575f80fd5b506103246109c7565b3480156103c4575f80fd5b506103246103d3366004611f96565b6109e2565b3480156103e3575f80fd5b50610324610a93565b3480156103f7575f80fd5b5061033b600b5481565b34801561040c575f80fd5b50600d546102989060ff1681565b348015610425575f80fd5b50610324610434366004611f96565b610b1c565b348015610444575f80fd5b50610324610bcd565b348015610458575f80fd5b506102ed610467366004611f23565b610bdd565b348015610477575f80fd5b5061033b610486366004611f7d565b610c3c565b348015610496575f80fd5b50610324610cc0565b610324610cd3565b3480156104b2575f80fd5b506006546001600160a01b03166102ed565b3480156104cf575f80fd5b5061033b600581565b3480156104e3575f80fd5b506102c1610d45565b3480156104f7575f80fd5b506102c1610d54565b34801561050b575f80fd5b5061033b600c5481565b348015610520575f80fd5b5061033b600a5481565b610324610538366004611f23565b610de0565b348015610548575f80fd5b50610324610557366004612056565b610fd7565b348015610567575f80fd5b506103246105763660046120a8565b610fef565b348015610586575f80fd5b506103246105953660046120dd565b610ffa565b3480156105a5575f80fd5b5061033b60095481565b3480156105ba575f80fd5b506103246105c93660046120dd565b61101e565b3480156105d9575f80fd5b50610324611042565b3480156105ed575f80fd5b506103246105fc3660046120fd565b6110cb565b34801561060c575f80fd5b506102c1611183565b348015610620575f80fd5b506102c161062f366004611f23565b611190565b34801561063f575f80fd5b5061032461126a565b348015610653575f80fd5b50610324610662366004611f7d565b611281565b348015610672575f80fd5b50600d546102989062010000900460ff1681565b348015610691575f80fd5b506103246106a0366004611f7d565b6112ac565b3480156106b0575f80fd5b506102986106bf366004612174565b6112d7565b3480156106cf575f80fd5b506103246106de3660046120dd565b611304565b3480156106ee575f80fd5b50610324611328565b348015610702575f80fd5b50610324610711366004611f7d565b611341565b348015610721575f80fd5b5061033b613a9881565b348015610736575f80fd5b5061033b60085481565b34801561074b575f80fd5b5061033b60075481565b5f6001600160e01b031982166380ac58cd60e01b148061078557506001600160e01b03198216635b5e139f60e01b145b806107a057506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f80546107b4906121a5565b80601f01602080910402602001604051908101604052809291908181526020018280546107e0906121a5565b801561082b5780601f106108025761010080835404028352916020019161082b565b820191905f5260205f20905b81548152906001019060200180831161080e57829003601f168201915b5050505050905090565b5f61083f826113b7565b505f908152600460205260409020546001600160a01b031690565b5f61086482610bdd565b9050806001600160a01b0316836001600160a01b0316036108d65760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806108f257506108f281336112d7565b6109645760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016108cd565b61096e8383611415565b505050565b61097b611482565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6109a5611482565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b6109cf611482565b600d805462ffffff191662010000179055565b6daaeb6d7670e522a718067333cd4e3b15610a8857604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af1158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6991906121dd565b610a8857604051633b79c77360e21b81523360048201526024016108cd565b61096e8383836114dc565b610a9b611482565b600b5460105414610b145760405162461bcd60e51b815260206004820152603f60248201527f4e6f6e2070756f6920617474697661726c612061646573736f2c2066696e697360448201527f6369206469206d696e74617265206920536162617269616e207072696d61210060648201526084016108cd565b600c54601355565b6daaeb6d7670e522a718067333cd4e3b15610bc257604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af1158015610b7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ba391906121dd565b610bc257604051633b79c77360e21b81523360048201526024016108cd565b61096e83838361150d565b610bd5611482565b600a54601355565b5f818152600260205260408120546001600160a01b0316806107a05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108cd565b5f6001600160a01b038216610ca55760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016108cd565b506001600160a01b03165f9081526003602052604090205490565b610cc8611482565b610cd15f611527565b565b610cdb611482565b60145460405147916001600160a01b03169082156108fc029083905f818181858888f19350505050610d425760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108cd565b50565b6060600180546107b4906121a5565b60118054610d61906121a5565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8d906121a5565b8015610dd85780601f10610daf57610100808354040283529160200191610dd8565b820191905f5260205f20905b815481529060010190602001808311610dbb57829003601f168201915b505050505081565b601054613a98610df0838361220c565b1115610e365760405162461bcd60e51b815260206004820152601560248201527422bc31b2b2b239903a37ba30b61039bab838363c9760591b60448201526064016108cd565b6006546001600160a01b03163314610f8f576005821115610eaf5760405162461bcd60e51b815260206004820152602d60248201527f596f752063616e6e6f74206d696e742074686174206d616e7920696e206f6e6560448201526c103a3930b739b0b1ba34b7b71760991b60648201526084016108cd565b5f610eb933611578565b905034610ec6828561221f565b1115610f0a5760405162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10333ab732399760691b60448201526064016108cd565b8282601354610f199190612236565b1015610f8d5760405162461bcd60e51b815260206004820152603e60248201527f54686520616d6f756e742065786365656473206d6178696d756d20617661696c60448201527f6162696c69747920666f7220746865206f6e676f696e6720706861736521000060648201526084016108cd565b505b60015b828111610fbc57610fac33610fa7838561220c565b6116bc565b610fb581612249565b9050610f92565b508160105f828254610fce919061220c565b90915550505050565b610fdf611482565b6011610feb82826122ae565b5050565b610feb3383836116d5565b611002611482565b61100d81600a61244a565b611017908361221f565b6008555050565b611026611482565b61103181600a61244a565b61103b908361221f565b6009555050565b61104a611482565b600a54601054146110c35760405162461bcd60e51b815260206004820152603d60248201527f4e6f6e2070756f6920617474697661726c612061646573736f2c2066696e697360448201527f6369206469206d696e746172652069204d656c69616e207072696d612100000060648201526084016108cd565b600b54601355565b6daaeb6d7670e522a718067333cd4e3b1561117157604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af115801561112e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115291906121dd565b61117157604051633b79c77360e21b81523360048201526024016108cd565b61117d848484846117a2565b50505050565b60128054610d61906121a5565b5f818152600260205260409020546060906001600160a01b031661120e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016108cd565b5f6112176117d4565b90505f8151116112355760405180602001604052805f815250611263565b8061123f846117e3565b601260405160200161125393929190612455565b6040516020818303038152906040525b9392505050565b611272611482565b600d805460ff19166001179055565b611289611482565b6001600160a01b03165f908152600f60205260409020805460ff19166001179055565b6112b4611482565b6001600160a01b03165f908152600e60205260409020805460ff19166001179055565b6001600160a01b039182165f90815260056020908152604080832093909416825291909152205460ff1690565b61130c611482565b61131781600a61244a565b611321908361221f565b6007555050565b611330611482565b600d805461ffff1916610100179055565b611349611482565b6001600160a01b0381166113ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108cd565b610d4281611527565b5f818152600260205260409020546001600160a01b0316610d425760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108cd565b5f81815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061144982610bdd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6006546001600160a01b03163314610cd15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108cd565b6114e63382611873565b6115025760405162461bcd60e51b81526004016108cd906124f0565b61096e8383836118d1565b61096e83838360405180602001604052805f8152506110cb565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b600d545f90819060ff1615611616576001600160a01b0383165f908152600e602052604090205460ff1661160d5760405162461bcd60e51b815260206004820152603660248201527f596f75722077616c6c65742061646472657373206973206e6f7420696e636c75604482015275191959081a5b9d1bc81d1a194815da1a5d195b1a5cdd60521b60648201526084016108cd565b506007546107a0565b600d54610100900460ff16156116b2576001600160a01b0383165f908152600f602052604090205460ff166116a95760405162461bcd60e51b815260206004820152603360248201527f596f75722077616c6c65742061646472657373206973206e6f7420696e636c7560448201527264656420696e746f2074686520526166666c6560681b60648201526084016108cd565b506008546107a0565b5060095492915050565b610feb828260405180602001604052805f815250611a40565b816001600160a01b0316836001600160a01b0316036117365760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108cd565b6001600160a01b038381165f81815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6117ac3383611873565b6117c85760405162461bcd60e51b81526004016108cd906124f0565b61117d84848484611a72565b6060601180546107b4906121a5565b60605f6117ef83611aa5565b60010190505f8167ffffffffffffffff81111561180e5761180e611fcf565b6040519080825280601f01601f191660200182016040528015611838576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461184257509392505050565b5f8061187e83610bdd565b9050806001600160a01b0316846001600160a01b031614806118a557506118a581856112d7565b806118c95750836001600160a01b03166118be84610835565b6001600160a01b0316145b949350505050565b826001600160a01b03166118e482610bdd565b6001600160a01b03161461190a5760405162461bcd60e51b81526004016108cd9061253d565b6001600160a01b03821661196c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108cd565b6119798383836001611b7c565b826001600160a01b031661198c82610bdd565b6001600160a01b0316146119b25760405162461bcd60e51b81526004016108cd9061253d565b5f81815260046020908152604080832080546001600160a01b03199081169091556001600160a01b038781168086526003855283862080545f1901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b611a4a8383611c02565b611a565f848484611d97565b61096e5760405162461bcd60e51b81526004016108cd90612582565b611a7d8484846118d1565b611a8984848484611d97565b61117d5760405162461bcd60e51b81526004016108cd90612582565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611ae35772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611b0f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611b2d57662386f26fc10000830492506010015b6305f5e1008310611b45576305f5e100830492506008015b6127108310611b5957612710830492506004015b60648310611b6b576064830492506002015b600a83106107a05760010192915050565b600181111561117d576001600160a01b03841615611bc1576001600160a01b0384165f9081526003602052604081208054839290611bbb908490612236565b90915550505b6001600160a01b0383161561117d576001600160a01b0383165f9081526003602052604081208054839290611bf790849061220c565b909155505050505050565b6001600160a01b038216611c585760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108cd565b5f818152600260205260409020546001600160a01b031615611cbc5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108cd565b611cc95f83836001611b7c565b5f818152600260205260409020546001600160a01b031615611d2d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108cd565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f6001600160a01b0384163b15611e8957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611dda9033908990889088906004016125d4565b6020604051808303815f875af1925050508015611e14575060408051601f3d908101601f19168201909252611e1191810190612610565b60015b611e6f573d808015611e41576040519150601f19603f3d011682016040523d82523d5f602084013e611e46565b606091505b5080515f03611e675760405162461bcd60e51b81526004016108cd90612582565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118c9565b506001949350505050565b6001600160e01b031981168114610d42575f80fd5b5f60208284031215611eb9575f80fd5b813561126381611e94565b5f5b83811015611ede578181015183820152602001611ec6565b50505f910152565b5f8151808452611efd816020860160208601611ec4565b601f01601f19169290920160200192915050565b602081525f6112636020830184611ee6565b5f60208284031215611f33575f80fd5b5035919050565b80356001600160a01b0381168114611f50575f80fd5b919050565b5f8060408385031215611f66575f80fd5b611f6f83611f3a565b946020939093013593505050565b5f60208284031215611f8d575f80fd5b61126382611f3a565b5f805f60608486031215611fa8575f80fd5b611fb184611f3a565b9250611fbf60208501611f3a565b9150604084013590509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f67ffffffffffffffff80841115611ffd57611ffd611fcf565b604051601f8501601f19908116603f0116810190828211818310171561202557612025611fcf565b8160405280935085815286868601111561203d575f80fd5b858560208301375f602087830101525050509392505050565b5f60208284031215612066575f80fd5b813567ffffffffffffffff81111561207c575f80fd5b8201601f8101841361208c575f80fd5b6118c984823560208401611fe3565b8015158114610d42575f80fd5b5f80604083850312156120b9575f80fd5b6120c283611f3a565b915060208301356120d28161209b565b809150509250929050565b5f80604083850312156120ee575f80fd5b50508035926020909101359150565b5f805f8060808587031215612110575f80fd5b61211985611f3a565b935061212760208601611f3a565b925060408501359150606085013567ffffffffffffffff811115612149575f80fd5b8501601f81018713612159575f80fd5b61216887823560208401611fe3565b91505092959194509250565b5f8060408385031215612185575f80fd5b61218e83611f3a565b915061219c60208401611f3a565b90509250929050565b600181811c908216806121b957607f821691505b6020821081036121d757634e487b7160e01b5f52602260045260245ffd5b50919050565b5f602082840312156121ed575f80fd5b81516112638161209b565b634e487b7160e01b5f52601160045260245ffd5b808201808211156107a0576107a06121f8565b80820281158282048414176107a0576107a06121f8565b818103818111156107a0576107a06121f8565b5f6001820161225a5761225a6121f8565b5060010190565b601f82111561096e575f81815260208120601f850160051c810160208610156122875750805b601f850160051c820191505b818110156122a657828155600101612293565b505050505050565b815167ffffffffffffffff8111156122c8576122c8611fcf565b6122dc816122d684546121a5565b84612261565b602080601f83116001811461230f575f84156122f85750858301515b5f19600386901b1c1916600185901b1785556122a6565b5f85815260208120601f198616915b8281101561233d5788860151825594840194600190910190840161231e565b508582101561235a57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b600181815b808511156123a457815f190482111561238a5761238a6121f8565b8085161561239757918102915b93841c939080029061236f565b509250929050565b5f826123ba575060016107a0565b816123c657505f6107a0565b81600181146123dc57600281146123e657612402565b60019150506107a0565b60ff8411156123f7576123f76121f8565b50506001821b6107a0565b5060208310610133831016604e8410600b8410161715612425575081810a6107a0565b61242f838361236a565b805f1904821115612442576124426121f8565b029392505050565b5f61126383836123ac565b5f845160206124678285838a01611ec4565b85519184019161247a8184848a01611ec4565b85549201915f9061248a816121a5565b600182811680156124a257600181146124b7576124e0565b60ff19841687528215158302870194506124e0565b895f52855f205f5b848110156124d8578154898201529083019087016124bf565b505082870194505b50929a9950505050505050505050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061260690830184611ee6565b9695505050505050565b5f60208284031215612620575f80fd5b815161126381611e9456fea2646970667358221220ff1c39dd783efaa43d3da53d3455620551279bfe58ff9d014013591d1f15962664736f6c6343000814003368747470733a2f2f62616679626569616c6e6d3379783364676563686162703462326f6275637161766669787569636c656a626274366c61676c687a736e346d7262712e697066732e6e667473746f726167652e6c696e6b2f
Deployed Bytecode
0x608060405260043610610275575f3560e01c80639de210751161014a578063c87b56dd116100be578063eeaa32fe11610078578063eeaa32fe146106c4578063f18aceda146106e3578063f2fde38b146106f7578063f47c84c514610716578063f8d867941461072b578063fc1a1c3614610740575f80fd5b8063c87b56dd14610615578063cdfb2b4e14610634578063daa28cd214610648578063dc9a153514610667578063e43252d714610686578063e985e9c5146106a5575f80fd5b8063a407ad6a1161010f578063a407ad6a1461057b578063a945bf801461059a578063abaf1de9146105af578063ac4410be146105ce578063b88d4fde146105e2578063c668286214610601575f80fd5b80639de21075146105005780639df47cab14610515578063a0712d681461052a578063a0bcfc7f1461053d578063a22cb4651461055c575f80fd5b80633df1de4e116101ec578063715018a6116101a6578063715018a61461048b578063853828b61461049f5780638da5cb5b146104a75780638ecad721146104c457806395d89b41146104d85780639abc8320146104ec575f80fd5b80633df1de4e146103ec5780634146ed0a1461040157806342842e0e1461041a57806360831b1f146104395780636352211e1461044d57806370a082311461046c575f80fd5b80631816467f1161023d5780631816467f146103495780631d85e95a146103685780631f265e42146103875780632316b4da146103a557806323b872dd146103b957806330dad648146103d8575f80fd5b806301ffc9a71461027957806306fdde03146102ad578063081812fc146102ce578063095ea7b31461030557806318160ddd14610326575b5f80fd5b348015610284575f80fd5b50610298610293366004611ea9565b610755565b60405190151581526020015b60405180910390f35b3480156102b8575f80fd5b506102c16107a6565b6040516102a49190611f11565b3480156102d9575f80fd5b506102ed6102e8366004611f23565b610835565b6040516001600160a01b0390911681526020016102a4565b348015610310575f80fd5b5061032461031f366004611f55565b61085a565b005b348015610331575f80fd5b5061033b60105481565b6040519081526020016102a4565b348015610354575f80fd5b50610324610363366004611f7d565b610973565b348015610373575f80fd5b50610324610382366004611f7d565b61099d565b348015610392575f80fd5b50600d5461029890610100900460ff1681565b3480156103b0575f80fd5b506103246109c7565b3480156103c4575f80fd5b506103246103d3366004611f96565b6109e2565b3480156103e3575f80fd5b50610324610a93565b3480156103f7575f80fd5b5061033b600b5481565b34801561040c575f80fd5b50600d546102989060ff1681565b348015610425575f80fd5b50610324610434366004611f96565b610b1c565b348015610444575f80fd5b50610324610bcd565b348015610458575f80fd5b506102ed610467366004611f23565b610bdd565b348015610477575f80fd5b5061033b610486366004611f7d565b610c3c565b348015610496575f80fd5b50610324610cc0565b610324610cd3565b3480156104b2575f80fd5b506006546001600160a01b03166102ed565b3480156104cf575f80fd5b5061033b600581565b3480156104e3575f80fd5b506102c1610d45565b3480156104f7575f80fd5b506102c1610d54565b34801561050b575f80fd5b5061033b600c5481565b348015610520575f80fd5b5061033b600a5481565b610324610538366004611f23565b610de0565b348015610548575f80fd5b50610324610557366004612056565b610fd7565b348015610567575f80fd5b506103246105763660046120a8565b610fef565b348015610586575f80fd5b506103246105953660046120dd565b610ffa565b3480156105a5575f80fd5b5061033b60095481565b3480156105ba575f80fd5b506103246105c93660046120dd565b61101e565b3480156105d9575f80fd5b50610324611042565b3480156105ed575f80fd5b506103246105fc3660046120fd565b6110cb565b34801561060c575f80fd5b506102c1611183565b348015610620575f80fd5b506102c161062f366004611f23565b611190565b34801561063f575f80fd5b5061032461126a565b348015610653575f80fd5b50610324610662366004611f7d565b611281565b348015610672575f80fd5b50600d546102989062010000900460ff1681565b348015610691575f80fd5b506103246106a0366004611f7d565b6112ac565b3480156106b0575f80fd5b506102986106bf366004612174565b6112d7565b3480156106cf575f80fd5b506103246106de3660046120dd565b611304565b3480156106ee575f80fd5b50610324611328565b348015610702575f80fd5b50610324610711366004611f7d565b611341565b348015610721575f80fd5b5061033b613a9881565b348015610736575f80fd5b5061033b60085481565b34801561074b575f80fd5b5061033b60075481565b5f6001600160e01b031982166380ac58cd60e01b148061078557506001600160e01b03198216635b5e139f60e01b145b806107a057506301ffc9a760e01b6001600160e01b03198316145b92915050565b60605f80546107b4906121a5565b80601f01602080910402602001604051908101604052809291908181526020018280546107e0906121a5565b801561082b5780601f106108025761010080835404028352916020019161082b565b820191905f5260205f20905b81548152906001019060200180831161080e57829003601f168201915b5050505050905090565b5f61083f826113b7565b505f908152600460205260409020546001600160a01b031690565b5f61086482610bdd565b9050806001600160a01b0316836001600160a01b0316036108d65760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806108f257506108f281336112d7565b6109645760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016108cd565b61096e8383611415565b505050565b61097b611482565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6109a5611482565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b6109cf611482565b600d805462ffffff191662010000179055565b6daaeb6d7670e522a718067333cd4e3b15610a8857604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af1158015610a45573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a6991906121dd565b610a8857604051633b79c77360e21b81523360048201526024016108cd565b61096e8383836114dc565b610a9b611482565b600b5460105414610b145760405162461bcd60e51b815260206004820152603f60248201527f4e6f6e2070756f6920617474697661726c612061646573736f2c2066696e697360448201527f6369206469206d696e74617265206920536162617269616e207072696d61210060648201526084016108cd565b600c54601355565b6daaeb6d7670e522a718067333cd4e3b15610bc257604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af1158015610b7f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ba391906121dd565b610bc257604051633b79c77360e21b81523360048201526024016108cd565b61096e83838361150d565b610bd5611482565b600a54601355565b5f818152600260205260408120546001600160a01b0316806107a05760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108cd565b5f6001600160a01b038216610ca55760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016108cd565b506001600160a01b03165f9081526003602052604090205490565b610cc8611482565b610cd15f611527565b565b610cdb611482565b60145460405147916001600160a01b03169082156108fc029083905f818181858888f19350505050610d425760405162461bcd60e51b815260206004820152601060248201526f2a3930b739b332b9103330b4b632b21760811b60448201526064016108cd565b50565b6060600180546107b4906121a5565b60118054610d61906121a5565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8d906121a5565b8015610dd85780601f10610daf57610100808354040283529160200191610dd8565b820191905f5260205f20905b815481529060010190602001808311610dbb57829003601f168201915b505050505081565b601054613a98610df0838361220c565b1115610e365760405162461bcd60e51b815260206004820152601560248201527422bc31b2b2b239903a37ba30b61039bab838363c9760591b60448201526064016108cd565b6006546001600160a01b03163314610f8f576005821115610eaf5760405162461bcd60e51b815260206004820152602d60248201527f596f752063616e6e6f74206d696e742074686174206d616e7920696e206f6e6560448201526c103a3930b739b0b1ba34b7b71760991b60648201526084016108cd565b5f610eb933611578565b905034610ec6828561221f565b1115610f0a5760405162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10333ab732399760691b60448201526064016108cd565b8282601354610f199190612236565b1015610f8d5760405162461bcd60e51b815260206004820152603e60248201527f54686520616d6f756e742065786365656473206d6178696d756d20617661696c60448201527f6162696c69747920666f7220746865206f6e676f696e6720706861736521000060648201526084016108cd565b505b60015b828111610fbc57610fac33610fa7838561220c565b6116bc565b610fb581612249565b9050610f92565b508160105f828254610fce919061220c565b90915550505050565b610fdf611482565b6011610feb82826122ae565b5050565b610feb3383836116d5565b611002611482565b61100d81600a61244a565b611017908361221f565b6008555050565b611026611482565b61103181600a61244a565b61103b908361221f565b6009555050565b61104a611482565b600a54601054146110c35760405162461bcd60e51b815260206004820152603d60248201527f4e6f6e2070756f6920617474697661726c612061646573736f2c2066696e697360448201527f6369206469206d696e746172652069204d656c69616e207072696d612100000060648201526084016108cd565b600b54601355565b6daaeb6d7670e522a718067333cd4e3b1561117157604051633185c44d60e21b81523060048201523360248201526daaeb6d7670e522a718067333cd4e9063c6171134906044016020604051808303815f875af115801561112e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061115291906121dd565b61117157604051633b79c77360e21b81523360048201526024016108cd565b61117d848484846117a2565b50505050565b60128054610d61906121a5565b5f818152600260205260409020546060906001600160a01b031661120e5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016108cd565b5f6112176117d4565b90505f8151116112355760405180602001604052805f815250611263565b8061123f846117e3565b601260405160200161125393929190612455565b6040516020818303038152906040525b9392505050565b611272611482565b600d805460ff19166001179055565b611289611482565b6001600160a01b03165f908152600f60205260409020805460ff19166001179055565b6112b4611482565b6001600160a01b03165f908152600e60205260409020805460ff19166001179055565b6001600160a01b039182165f90815260056020908152604080832093909416825291909152205460ff1690565b61130c611482565b61131781600a61244a565b611321908361221f565b6007555050565b611330611482565b600d805461ffff1916610100179055565b611349611482565b6001600160a01b0381166113ae5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108cd565b610d4281611527565b5f818152600260205260409020546001600160a01b0316610d425760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016108cd565b5f81815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061144982610bdd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6006546001600160a01b03163314610cd15760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108cd565b6114e63382611873565b6115025760405162461bcd60e51b81526004016108cd906124f0565b61096e8383836118d1565b61096e83838360405180602001604052805f8152506110cb565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b600d545f90819060ff1615611616576001600160a01b0383165f908152600e602052604090205460ff1661160d5760405162461bcd60e51b815260206004820152603660248201527f596f75722077616c6c65742061646472657373206973206e6f7420696e636c75604482015275191959081a5b9d1bc81d1a194815da1a5d195b1a5cdd60521b60648201526084016108cd565b506007546107a0565b600d54610100900460ff16156116b2576001600160a01b0383165f908152600f602052604090205460ff166116a95760405162461bcd60e51b815260206004820152603360248201527f596f75722077616c6c65742061646472657373206973206e6f7420696e636c7560448201527264656420696e746f2074686520526166666c6560681b60648201526084016108cd565b506008546107a0565b5060095492915050565b610feb828260405180602001604052805f815250611a40565b816001600160a01b0316836001600160a01b0316036117365760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108cd565b6001600160a01b038381165f81815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6117ac3383611873565b6117c85760405162461bcd60e51b81526004016108cd906124f0565b61117d84848484611a72565b6060601180546107b4906121a5565b60605f6117ef83611aa5565b60010190505f8167ffffffffffffffff81111561180e5761180e611fcf565b6040519080825280601f01601f191660200182016040528015611838576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a850494508461184257509392505050565b5f8061187e83610bdd565b9050806001600160a01b0316846001600160a01b031614806118a557506118a581856112d7565b806118c95750836001600160a01b03166118be84610835565b6001600160a01b0316145b949350505050565b826001600160a01b03166118e482610bdd565b6001600160a01b03161461190a5760405162461bcd60e51b81526004016108cd9061253d565b6001600160a01b03821661196c5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108cd565b6119798383836001611b7c565b826001600160a01b031661198c82610bdd565b6001600160a01b0316146119b25760405162461bcd60e51b81526004016108cd9061253d565b5f81815260046020908152604080832080546001600160a01b03199081169091556001600160a01b038781168086526003855283862080545f1901905590871680865283862080546001019055868652600290945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b611a4a8383611c02565b611a565f848484611d97565b61096e5760405162461bcd60e51b81526004016108cd90612582565b611a7d8484846118d1565b611a8984848484611d97565b61117d5760405162461bcd60e51b81526004016108cd90612582565b5f8072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310611ae35772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310611b0f576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310611b2d57662386f26fc10000830492506010015b6305f5e1008310611b45576305f5e100830492506008015b6127108310611b5957612710830492506004015b60648310611b6b576064830492506002015b600a83106107a05760010192915050565b600181111561117d576001600160a01b03841615611bc1576001600160a01b0384165f9081526003602052604081208054839290611bbb908490612236565b90915550505b6001600160a01b0383161561117d576001600160a01b0383165f9081526003602052604081208054839290611bf790849061220c565b909155505050505050565b6001600160a01b038216611c585760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108cd565b5f818152600260205260409020546001600160a01b031615611cbc5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108cd565b611cc95f83836001611b7c565b5f818152600260205260409020546001600160a01b031615611d2d5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108cd565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f6001600160a01b0384163b15611e8957604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611dda9033908990889088906004016125d4565b6020604051808303815f875af1925050508015611e14575060408051601f3d908101601f19168201909252611e1191810190612610565b60015b611e6f573d808015611e41576040519150601f19603f3d011682016040523d82523d5f602084013e611e46565b606091505b5080515f03611e675760405162461bcd60e51b81526004016108cd90612582565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506118c9565b506001949350505050565b6001600160e01b031981168114610d42575f80fd5b5f60208284031215611eb9575f80fd5b813561126381611e94565b5f5b83811015611ede578181015183820152602001611ec6565b50505f910152565b5f8151808452611efd816020860160208601611ec4565b601f01601f19169290920160200192915050565b602081525f6112636020830184611ee6565b5f60208284031215611f33575f80fd5b5035919050565b80356001600160a01b0381168114611f50575f80fd5b919050565b5f8060408385031215611f66575f80fd5b611f6f83611f3a565b946020939093013593505050565b5f60208284031215611f8d575f80fd5b61126382611f3a565b5f805f60608486031215611fa8575f80fd5b611fb184611f3a565b9250611fbf60208501611f3a565b9150604084013590509250925092565b634e487b7160e01b5f52604160045260245ffd5b5f67ffffffffffffffff80841115611ffd57611ffd611fcf565b604051601f8501601f19908116603f0116810190828211818310171561202557612025611fcf565b8160405280935085815286868601111561203d575f80fd5b858560208301375f602087830101525050509392505050565b5f60208284031215612066575f80fd5b813567ffffffffffffffff81111561207c575f80fd5b8201601f8101841361208c575f80fd5b6118c984823560208401611fe3565b8015158114610d42575f80fd5b5f80604083850312156120b9575f80fd5b6120c283611f3a565b915060208301356120d28161209b565b809150509250929050565b5f80604083850312156120ee575f80fd5b50508035926020909101359150565b5f805f8060808587031215612110575f80fd5b61211985611f3a565b935061212760208601611f3a565b925060408501359150606085013567ffffffffffffffff811115612149575f80fd5b8501601f81018713612159575f80fd5b61216887823560208401611fe3565b91505092959194509250565b5f8060408385031215612185575f80fd5b61218e83611f3a565b915061219c60208401611f3a565b90509250929050565b600181811c908216806121b957607f821691505b6020821081036121d757634e487b7160e01b5f52602260045260245ffd5b50919050565b5f602082840312156121ed575f80fd5b81516112638161209b565b634e487b7160e01b5f52601160045260245ffd5b808201808211156107a0576107a06121f8565b80820281158282048414176107a0576107a06121f8565b818103818111156107a0576107a06121f8565b5f6001820161225a5761225a6121f8565b5060010190565b601f82111561096e575f81815260208120601f850160051c810160208610156122875750805b601f850160051c820191505b818110156122a657828155600101612293565b505050505050565b815167ffffffffffffffff8111156122c8576122c8611fcf565b6122dc816122d684546121a5565b84612261565b602080601f83116001811461230f575f84156122f85750858301515b5f19600386901b1c1916600185901b1785556122a6565b5f85815260208120601f198616915b8281101561233d5788860151825594840194600190910190840161231e565b508582101561235a57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b600181815b808511156123a457815f190482111561238a5761238a6121f8565b8085161561239757918102915b93841c939080029061236f565b509250929050565b5f826123ba575060016107a0565b816123c657505f6107a0565b81600181146123dc57600281146123e657612402565b60019150506107a0565b60ff8411156123f7576123f76121f8565b50506001821b6107a0565b5060208310610133831016604e8410600b8410161715612425575081810a6107a0565b61242f838361236a565b805f1904821115612442576124426121f8565b029392505050565b5f61126383836123ac565b5f845160206124678285838a01611ec4565b85519184019161247a8184848a01611ec4565b85549201915f9061248a816121a5565b600182811680156124a257600181146124b7576124e0565b60ff19841687528215158302870194506124e0565b895f52855f205f5b848110156124d8578154898201529083019087016124bf565b505082870194505b50929a9950505050505050505050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6001600160a01b03858116825284166020820152604081018390526080606082018190525f9061260690830184611ee6565b9695505050505050565b5f60208284031215612620575f80fd5b815161126381611e9456fea2646970667358221220ff1c39dd783efaa43d3da53d3455620551279bfe58ff9d014013591d1f15962664736f6c63430008140033
Deployed Bytecode Sourcemap
179:5671:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1556:305:4;;;;;;;;;;-1:-1:-1;1556:305:4;;;;;:::i;:::-;;:::i;:::-;;;565:14:20;;558:22;540:41;;528:2;513:18;1556:305:4;;;;;;;;2484:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3996:171::-;;;;;;;;;;-1:-1:-1;3996:171:4;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1697:32:20;;;1679:51;;1667:2;1652:18;3996:171:4;1533:203:20;3514:416:4;;;;;;;;;;-1:-1:-1;3514:416:4;;;;;:::i;:::-;;:::i;:::-;;863:26:12;;;;;;;;;;;;;;;;;;;2324:25:20;;;2312:2;2297:18;863:26:12;2178:177:20;2829:103:12;;;;;;;;;;-1:-1:-1;2829:103:12;;;;;:::i;:::-;;:::i;2712:109::-;;;;;;;;;;-1:-1:-1;2712:109:12;;;;;:::i;:::-;;:::i;688:28::-;;;;;;;;;;-1:-1:-1;688:28:12;;;;;;;;;;;3374:137;;;;;;;;;;;;;:::i;4757:157::-;;;;;;;;;;-1:-1:-1;4757:157:12;;;;;:::i;:::-;;:::i;3822:203::-;;;;;;;;;;;;;:::i;562:35::-;;;;;;;;;;;;;;;;650:31;;;;;;;;;;-1:-1:-1;650:31:12;;;;;;;;4922:165;;;;;;;;;;-1:-1:-1;4922:165:12;;;;;:::i;:::-;;:::i;3519:86::-;;;;;;;;;;;;;:::i;2194:223:4:-;;;;;;;;;;-1:-1:-1;2194:223:4;;;;;:::i;:::-;;:::i;1925:207::-;;;;;;;;;;-1:-1:-1;1925:207:4;;;;;:::i;:::-;;:::i;1884:103:16:-;;;;;;;;;;;;;:::i;4570:177:12:-;;;:::i;1236:87:16:-;;;;;;;;;;-1:-1:-1;1309:6:16;;-1:-1:-1;;;;;1309:6:16;1236:87;;468:43:12;;;;;;;;;;;;510:1;468:43;;2653:104:4;;;;;;;;;;;;;:::i;898:21:12:-;;;;;;;;;;;;;:::i;604:35::-;;;;;;;;;;;;;;;;522:33;;;;;;;;;;;;;;;;1368:773;;;;;;:::i;:::-;;:::i;4033:100::-;;;;;;;;;;-1:-1:-1;4033:100:12;;;;;:::i;:::-;;:::i;4239:155:4:-;;;;;;;;;;-1:-1:-1;4239:155:4;;;;;:::i;:::-;;:::i;4288:133:12:-;;;;;;;;;;-1:-1:-1;4288:133:12;;;;;:::i;:::-;;:::i;421:40::-;;;;;;;;;;;;;;;;4429:133;;;;;;;;;;-1:-1:-1;4429:133:12;;;;;:::i;:::-;;:::i;3613:201::-;;;;;;;;;;;;;:::i;5095:222::-;;;;;;;;;;-1:-1:-1;5095:222:12;;;;;:::i;:::-;;:::i;926:37::-;;;;;;;;;;;;;:::i;5333:397::-;;;;;;;;;;-1:-1:-1;5333:397:12;;;;;:::i;:::-;;:::i;3168:83::-;;;;;;;;;;;;;:::i;3057:103::-;;;;;;;;;;-1:-1:-1;3057:103:12;;;;;:::i;:::-;;:::i;723:28::-;;;;;;;;;;-1:-1:-1;723:28:12;;;;;;;;;;;2940:109;;;;;;;;;;-1:-1:-1;2940:109:12;;;;;:::i;:::-;;:::i;4465:164:4:-;;;;;;;;;;-1:-1:-1;4465:164:4;;;;;:::i;:::-;;:::i;4141:139:12:-;;;;;;;;;;-1:-1:-1;4141:139:12;;;;;:::i;:::-;;:::i;3259:107::-;;;;;;;;;;;;;:::i;2142:201:16:-;;;;;;;;;;-1:-1:-1;2142:201:16;;;;;:::i;:::-;;:::i;277:39:12:-;;;;;;;;;;;;311:5;277:39;;375;;;;;;;;;;;;;;;;325:43;;;;;;;;;;;;;;;;1556:305:4;1658:4;-1:-1:-1;;;;;;1695:40:4;;-1:-1:-1;;;1695:40:4;;:105;;-1:-1:-1;;;;;;;1752:48:4;;-1:-1:-1;;;1752:48:4;1695:105;:158;;;-1:-1:-1;;;;;;;;;;963:40:3;;;1817:36:4;1675:178;1556:305;-1:-1:-1;;1556:305:4:o;2484:100::-;2538:13;2571:5;2564:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2484:100;:::o;3996:171::-;4072:7;4092:23;4107:7;4092:14;:23::i;:::-;-1:-1:-1;4135:24:4;;;;:15;:24;;;;;;-1:-1:-1;;;;;4135:24:4;;3996:171::o;3514:416::-;3595:13;3611:23;3626:7;3611:14;:23::i;:::-;3595:39;;3659:5;-1:-1:-1;;;;;3653:11:4;:2;-1:-1:-1;;;;;3653:11:4;;3645:57;;;;-1:-1:-1;;;3645:57:4;;6329:2:20;3645:57:4;;;6311:21:20;6368:2;6348:18;;;6341:30;6407:34;6387:18;;;6380:62;-1:-1:-1;;;6458:18:20;;;6451:31;6499:19;;3645:57:4;;;;;;;;;736:10:1;-1:-1:-1;;;;;3737:21:4;;;;:62;;-1:-1:-1;3762:37:4;3779:5;736:10:1;4465:164:4;:::i;3762:37::-;3715:173;;;;-1:-1:-1;;;3715:173:4;;6731:2:20;3715:173:4;;;6713:21:20;6770:2;6750:18;;;6743:30;6809:34;6789:18;;;6782:62;6880:31;6860:18;;;6853:59;6929:19;;3715:173:4;6529:425:20;3715:173:4;3901:21;3910:2;3914:7;3901:8;:21::i;:::-;3584:346;3514:416;;:::o;2829:103:12:-;1122:13:16;:11;:13::i;:::-;2903:10:12::1;:21:::0;;-1:-1:-1;;;;;;2903:21:12::1;-1:-1:-1::0;;;;;2903:21:12;;;::::1;::::0;;;::::1;::::0;;2829:103::o;2712:109::-;1122:13:16;:11;:13::i;:::-;2789::12::1;:24:::0;;-1:-1:-1;;;;;;2789:24:12::1;-1:-1:-1::0;;;;;2789:24:12;;;::::1;::::0;;;::::1;::::0;;2712:109::o;3374:137::-;1122:13:16;:11;:13::i;:::-;3431:11:12::1;:19:::0;;-1:-1:-1;;3488:15:12;;::::1;::::0;;3374:137::o;4757:157::-;310:42:15;1438:43;:47;1434:225;;1507:67;;-1:-1:-1;;;1507:67:15;;1556:4;1507:67;;;7171:34:20;1563:10:15;7221:18:20;;;7214:43;310:42:15;;1507:40;;7106:18:20;;1507:67:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1502:146;;1602:30;;-1:-1:-1;;;1602:30:15;;1621:10;1602:30;;;1679:51:20;1652:18;;1602:30:15;1533:203:20;1502:146:15;4869:37:12::1;4888:4;4894:2;4898:7;4869:18;:37::i;3822:203::-:0;1122:13:16;:11;:13::i;:::-;3900::12::1;;3885:11;;:28;3877:104;;;::::0;-1:-1:-1;;;3877:104:12;;7720:2:20;3877:104:12::1;::::0;::::1;7702:21:20::0;7759:2;7739:18;;;7732:30;7798:34;7778:18;;;7771:62;7869:33;7849:18;;;7842:61;7920:19;;3877:104:12::1;7518:427:20::0;3877:104:12::1;4005:12;::::0;3992:10:::1;:25:::0;3822:203::o;4922:165::-;310:42:15;1438:43;:47;1434:225;;1507:67;;-1:-1:-1;;;1507:67:15;;1556:4;1507:67;;;7171:34:20;1563:10:15;7221:18:20;;;7214:43;310:42:15;;1507:40;;7106:18:20;;1507:67:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1502:146;;1602:30;;-1:-1:-1;;;1602:30:15;;1621:10;1602:30;;;1679:51:20;1652:18;;1602:30:15;1533:203:20;1502:146:15;5038:41:12::1;5061:4;5067:2;5071:7;5038:22;:41::i;3519:86::-:0;1122:13:16;:11;:13::i;:::-;3586:11:12::1;::::0;3573:10:::1;:24:::0;3519:86::o;2194:223:4:-;2266:7;7081:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7081:16:4;;2330:56;;;;-1:-1:-1;;;2330:56:4;;8152:2:20;2330:56:4;;;8134:21:20;8191:2;8171:18;;;8164:30;-1:-1:-1;;;8210:18:20;;;8203:54;8274:18;;2330:56:4;7950:348:20;1925:207:4;1997:7;-1:-1:-1;;;;;2025:19:4;;2017:73;;;;-1:-1:-1;;;2017:73:4;;8505:2:20;2017:73:4;;;8487:21:20;8544:2;8524:18;;;8517:30;8583:34;8563:18;;;8556:62;-1:-1:-1;;;8634:18:20;;;8627:39;8683:19;;2017:73:4;8303:405:20;2017:73:4;-1:-1:-1;;;;;;2108:16:4;;;;;:9;:16;;;;;;;1925:207::o;1884:103:16:-;1122:13;:11;:13::i;:::-;1949:30:::1;1976:1;1949:18;:30::i;:::-;1884:103::o:0;4570:177:12:-;1122:13:16;:11;:13::i;:::-;4697:10:12::1;::::0;4689:33:::1;::::0;4649:21:::1;::::0;-1:-1:-1;;;;;4697:10:12::1;::::0;4689:33;::::1;;;::::0;4649:21;;4631:15:::1;4689:33:::0;4631:15;4689:33;4649:21;4697:10;4689:33;::::1;;;;;;4681:62;;;::::0;-1:-1:-1;;;4681:62:12;;8915:2:20;4681:62:12::1;::::0;::::1;8897:21:20::0;8954:2;8934:18;;;8927:30;-1:-1:-1;;;8973:18:20;;;8966:46;9029:18;;4681:62:12::1;8713:340:20::0;4681:62:12::1;4620:127;4570:177::o:0;2653:104:4:-;2709:13;2742:7;2735:14;;;;;:::i;898:21:12:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;1368:773::-;1455:11;;311:5;1485:27;1502:10;1455:11;1485:27;:::i;:::-;:41;;1477:75;;;;-1:-1:-1;;;1477:75:12;;9522:2:20;1477:75:12;;;9504:21:20;9561:2;9541:18;;;9534:30;-1:-1:-1;;;9580:18:20;;;9573:51;9641:18;;1477:75:12;9320:345:20;1477:75:12;1309:6:16;;-1:-1:-1;;;;;1309:6:16;736:10:1;1568:23:12;1565:413;;510:1;1615:10;:29;;1607:87;;;;-1:-1:-1;;;1607:87:12;;9872:2:20;1607:87:12;;;9854:21:20;9911:2;9891:18;;;9884:30;9950:34;9930:18;;;9923:62;-1:-1:-1;;;10001:18:20;;;9994:43;10054:19;;1607:87:12;9670:409:20;1607:87:12;1709:13;1725:32;736:10:1;1725:18:12;:32::i;:::-;1709:48;-1:-1:-1;1802:9:12;1780:18;1709:48;1780:10;:18;:::i;:::-;:31;;1772:63;;;;-1:-1:-1;;;1772:63:12;;10459:2:20;1772:63:12;;;10441:21:20;10498:2;10478:18;;;10471:30;-1:-1:-1;;;10517:18:20;;;10510:49;10576:18;;1772:63:12;10257:343:20;1772:63:12;1889:10;1871:14;1858:10;;:27;;;;:::i;:::-;:41;;1850:116;;;;-1:-1:-1;;;1850:116:12;;10940:2:20;1850:116:12;;;10922:21:20;10979:2;10959:18;;;10952:30;11018:34;10998:18;;;10991:62;11089:32;11069:18;;;11062:60;11139:19;;1850:116:12;10738:426:20;1850:116:12;1592:386;1565:413;2006:1;1990:108;2014:10;2009:1;:15;1990:108;;2045:41;2055:10;2067:18;2084:1;2067:14;:18;:::i;:::-;2045:9;:41::i;:::-;2026:3;;;:::i;:::-;;;1990:108;;;;2123:10;2108:11;;:25;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;1368:773:12:o;4033:100::-;1122:13:16;:11;:13::i;:::-;4107:7:12::1;:18;4117:8:::0;4107:7;:18:::1;:::i;:::-;;4033:100:::0;:::o;4239:155:4:-;4334:52;736:10:1;4367:8:4;4377;4334:18;:52::i;4288:133:12:-;1122:13:16;:11;:13::i;:::-;4400::12::1;4404:9:::0;4400:2:::1;:13;:::i;:::-;4391:22;::::0;:6;:22:::1;:::i;:::-;4377:11;:36:::0;-1:-1:-1;;4288:133:12:o;4429:::-;1122:13:16;:11;:13::i;:::-;4541::12::1;4545:9:::0;4541:2:::1;:13;:::i;:::-;4532:22;::::0;:6;:22:::1;:::i;:::-;4518:11;:36:::0;-1:-1:-1;;4429:133:12:o;3613:201::-;1122:13:16;:11;:13::i;:::-;3692:11:12::1;;3677;;:26;3669:100;;;::::0;-1:-1:-1;;;3669:100:12;;15089:2:20;3669:100:12::1;::::0;::::1;15071:21:20::0;15128:2;15108:18;;;15101:30;15167:34;15147:18;;;15140:62;15238:31;15218:18;;;15211:59;15287:19;;3669:100:12::1;14887:425:20::0;3669:100:12::1;3793:13;::::0;3780:10:::1;:26:::0;3613:201::o;5095:222::-;310:42:15;1438:43;:47;1434:225;;1507:67;;-1:-1:-1;;;1507:67:15;;1556:4;1507:67;;;7171:34:20;1563:10:15;7221:18:20;;;7214:43;310:42:15;;1507:40;;7106:18:20;;1507:67:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1502:146;;1602:30;;-1:-1:-1;;;1602:30:15;;1621:10;1602:30;;;1679:51:20;1652:18;;1602:30:15;1533:203:20;1502:146:15;5262:47:12::1;5285:4;5291:2;5295:7;5304:4;5262:22;:47::i;:::-;5095:222:::0;;;;:::o;926:37::-;;;;;;;:::i;5333:397::-;7483:4:4;7081:16;;;:7;:16;;;;;;5406:13:12;;-1:-1:-1;;;;;7081:16:4;5432:76:12;;;;-1:-1:-1;;;5432:76:12;;15519:2:20;5432:76:12;;;15501:21:20;15558:2;15538:18;;;15531:30;15597:34;15577:18;;;15570:62;-1:-1:-1;;;15648:18:20;;;15641:45;15703:19;;5432:76:12;15317:411:20;5432:76:12;5522:28;5553:10;:8;:10::i;:::-;5522:41;;5612:1;5587:14;5581:28;:32;:141;;;;;;;;;;;;;;;;;5653:14;5669:18;:7;:16;:18::i;:::-;5689:13;5636:67;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5581:141;5574:148;5333:397;-1:-1:-1;;;5333:397:12:o;3168:83::-;1122:13:16;:11;:13::i;:::-;3225:11:12::1;:18:::0;;-1:-1:-1;;3225:18:12::1;3239:4;3225:18;::::0;;3168:83::o;3057:103::-;1122:13:16;:11;:13::i;:::-;-1:-1:-1;;;;;3126:19:12::1;;::::0;;;:9:::1;:19;::::0;;;;:26;;-1:-1:-1;;3126:26:12::1;3148:4;3126:26;::::0;;3057:103::o;2940:109::-;1122:13:16;:11;:13::i;:::-;-1:-1:-1;;;;;3012:22:12::1;;::::0;;;:12:::1;:22;::::0;;;;:29;;-1:-1:-1;;3012:29:12::1;3037:4;3012:29;::::0;;2940:109::o;4465:164:4:-;-1:-1:-1;;;;;4586:25:4;;;4562:4;4586:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4465:164::o;4141:139:12:-;1122:13:16;:11;:13::i;:::-;4259::12::1;4263:9:::0;4259:2:::1;:13;:::i;:::-;4250:22;::::0;:6;:22:::1;:::i;:::-;4233:14;:39:::0;-1:-1:-1;;4141:139:12:o;3259:107::-;1122:13:16;:11;:13::i;:::-;3313:11:12::1;:19:::0;;-1:-1:-1;;3343:15:12;3313:19:::1;3343:15;::::0;;3259:107::o;2142:201:16:-;1122:13;:11;:13::i;:::-;-1:-1:-1;;;;;2231:22:16;::::1;2223:73;;;::::0;-1:-1:-1;;;2223:73:16;;17196:2:20;2223:73:16::1;::::0;::::1;17178:21:20::0;17235:2;17215:18;;;17208:30;17274:34;17254:18;;;17247:62;-1:-1:-1;;;17325:18:20;;;17318:36;17371:19;;2223:73:16::1;16994:402:20::0;2223:73:16::1;2307:28;2326:8;2307:18;:28::i;13815:135:4:-:0;7483:4;7081:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7081:16:4;13889:53;;;;-1:-1:-1;;;13889:53:4;;8152:2:20;13889:53:4;;;8134:21:20;8191:2;8171:18;;;8164:30;-1:-1:-1;;;8210:18:20;;;8203:54;8274:18;;13889:53:4;7950:348:20;13094:174:4;13169:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;13169:29:4;-1:-1:-1;;;;;13169:29:4;;;;;;;;:24;;13223:23;13169:24;13223:14;:23::i;:::-;-1:-1:-1;;;;;13214:46:4;;;;;;;;;;;13094:174;;:::o;1401:132:16:-;1309:6;;-1:-1:-1;;;;;1309:6:16;736:10:1;1465:23:16;1457:68;;;;-1:-1:-1;;;1457:68:16;;17603:2:20;1457:68:16;;;17585:21:20;;;17622:18;;;17615:30;17681:34;17661:18;;;17654:62;17733:18;;1457:68:16;17401:356:20;4696:335:4;4891:41;736:10:1;4924:7:4;4891:18;:41::i;:::-;4883:99;;;;-1:-1:-1;;;4883:99:4;;;;;;;:::i;:::-;4995:28;5005:4;5011:2;5015:7;4995:9;:28::i;5102:185::-;5240:39;5257:4;5263:2;5267:7;5240:39;;;;;;;;;;;;:16;:39::i;2503:191:16:-;2596:6;;;-1:-1:-1;;;;;2613:17:16;;;-1:-1:-1;;;;;;2613:17:16;;;;;;;2646:40;;2596:6;;;2613:17;2596:6;;2646:40;;2577:16;;2646:40;2566:128;2503:191;:::o;2149:525:12:-;2267:11;;2216:7;;;;2267:11;;2264:380;;;-1:-1:-1;;;;;2303:20:12;;;;;;:12;:20;;;;;;;;2295:87;;;;-1:-1:-1;;;2295:87:12;;18378:2:20;2295:87:12;;;18360:21:20;18417:2;18397:18;;;18390:30;18456:34;18436:18;;;18429:62;-1:-1:-1;;;18507:18:20;;;18500:52;18569:19;;2295:87:12;18176:418:20;2295:87:12;-1:-1:-1;2405:14:12;;2264:380;;;2440:8;;;;;;;2437:207;;;-1:-1:-1;;;;;2473:17:12;;;;;;:9;:17;;;;;;;;2465:81;;;;-1:-1:-1;;;2465:81:12;;18801:2:20;2465:81:12;;;18783:21:20;18840:2;18820:18;;;18813:30;18879:34;18859:18;;;18852:62;-1:-1:-1;;;18930:18:20;;;18923:49;18989:19;;2465:81:12;18599:415:20;2465:81:12;-1:-1:-1;2569:11:12;;2437:207;;;-1:-1:-1;2621:11:12;;2661:5;2149:525;-1:-1:-1;;2149:525:12:o;8319:110:4:-;8395:26;8405:2;8409:7;8395:26;;;;;;;;;;;;:9;:26::i;13411:315::-;13566:8;-1:-1:-1;;;;;13557:17:4;:5;-1:-1:-1;;;;;13557:17:4;;13549:55;;;;-1:-1:-1;;;13549:55:4;;19221:2:20;13549:55:4;;;19203:21:20;19260:2;19240:18;;;19233:30;19299:27;19279:18;;;19272:55;19344:18;;13549:55:4;19019:349:20;13549:55:4;-1:-1:-1;;;;;13615:25:4;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;13615:46:4;;;;;;;;;;13677:41;;540::20;;;13677::4;;513:18:20;13677:41:4;;;;;;;13411:315;;;:::o;5358:322::-;5532:41;736:10:1;5565:7:4;5532:18;:41::i;:::-;5524:99;;;;-1:-1:-1;;;5524:99:4;;;;;;;:::i;:::-;5634:38;5648:4;5654:2;5658:7;5667:4;5634:13;:38::i;5739:108:12:-;5799:13;5832:7;5825:14;;;;;:::i;427:716:19:-;483:13;534:14;551:17;562:5;551:10;:17::i;:::-;571:1;551:21;534:38;;587:20;621:6;610:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;610:18:19;-1:-1:-1;587:41:19;-1:-1:-1;752:28:19;;;768:2;752:28;809:288;-1:-1:-1;;841:5:19;-1:-1:-1;;;978:2:19;967:14;;962:30;841:5;949:44;1039:2;1030:11;;;-1:-1:-1;1060:21:19;809:288;1060:21;-1:-1:-1;1118:6:19;427:716;-1:-1:-1;;;427:716:19:o;7713:264:4:-;7806:4;7823:13;7839:23;7854:7;7839:14;:23::i;:::-;7823:39;;7892:5;-1:-1:-1;;;;;7881:16:4;:7;-1:-1:-1;;;;;7881:16:4;;:52;;;;7901:32;7918:5;7925:7;7901:16;:32::i;:::-;7881:87;;;;7961:7;-1:-1:-1;;;;;7937:31:4;:20;7949:7;7937:11;:20::i;:::-;-1:-1:-1;;;;;7937:31:4;;7881:87;7873:96;7713:264;-1:-1:-1;;;;7713:264:4:o;11712:1263::-;11871:4;-1:-1:-1;;;;;11844:31:4;:23;11859:7;11844:14;:23::i;:::-;-1:-1:-1;;;;;11844:31:4;;11836:81;;;;-1:-1:-1;;;11836:81:4;;;;;;;:::i;:::-;-1:-1:-1;;;;;11936:16:4;;11928:65;;;;-1:-1:-1;;;11928:65:4;;20113:2:20;11928:65:4;;;20095:21:20;20152:2;20132:18;;;20125:30;20191:34;20171:18;;;20164:62;-1:-1:-1;;;20242:18:20;;;20235:34;20286:19;;11928:65:4;19911:400:20;11928:65:4;12006:42;12027:4;12033:2;12037:7;12046:1;12006:20;:42::i;:::-;12178:4;-1:-1:-1;;;;;12151:31:4;:23;12166:7;12151:14;:23::i;:::-;-1:-1:-1;;;;;12151:31:4;;12143:81;;;;-1:-1:-1;;;12143:81:4;;;;;;;:::i;:::-;12296:24;;;;:15;:24;;;;;;;;12289:31;;-1:-1:-1;;;;;;12289:31:4;;;;;;-1:-1:-1;;;;;12772:15:4;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;12772:20:4;;;12807:13;;;;;;;;;:18;;12289:31;12807:18;;;12847:16;;;:7;:16;;;;;;:21;;;;;;;;;;12886:27;;12312:7;;12886:27;;;3584:346;3514:416;;:::o;8656:319::-;8785:18;8791:2;8795:7;8785:5;:18::i;:::-;8836:53;8867:1;8871:2;8875:7;8884:4;8836:22;:53::i;:::-;8814:153;;;;-1:-1:-1;;;8814:153:4;;;;;;;:::i;6561:313::-;6717:28;6727:4;6733:2;6737:7;6717:9;:28::i;:::-;6764:47;6787:4;6793:2;6797:7;6806:4;6764:22;:47::i;:::-;6756:110;;;;-1:-1:-1;;;6756:110:4;;;;;;;:::i;10146:922:11:-;10199:7;;-1:-1:-1;;;10277:15:11;;10273:102;;-1:-1:-1;;;10313:15:11;;;-1:-1:-1;10357:2:11;10347:12;10273:102;10402:6;10393:5;:15;10389:102;;10438:6;10429:15;;;-1:-1:-1;10473:2:11;10463:12;10389:102;10518:6;10509:5;:15;10505:102;;10554:6;10545:15;;;-1:-1:-1;10589:2:11;10579:12;10505:102;10634:5;10625;:14;10621:99;;10669:5;10660:14;;;-1:-1:-1;10703:1:11;10693:11;10621:99;10747:5;10738;:14;10734:99;;10782:5;10773:14;;;-1:-1:-1;10816:1:11;10806:11;10734:99;10860:5;10851;:14;10847:99;;10895:5;10886:14;;;-1:-1:-1;10929:1:11;10919:11;10847:99;10973:5;10964;:14;10960:66;;11009:1;10999:11;11054:6;10146:922;-1:-1:-1;;10146:922:11:o;16099:410:4:-;16289:1;16277:9;:13;16273:229;;;-1:-1:-1;;;;;16311:18:4;;;16307:87;;-1:-1:-1;;;;;16350:15:4;;;;;;:9;:15;;;;;:28;;16369:9;;16350:15;:28;;16369:9;;16350:28;:::i;:::-;;;;-1:-1:-1;;16307:87:4;-1:-1:-1;;;;;16412:16:4;;;16408:83;;-1:-1:-1;;;;;16449:13:4;;;;;;:9;:13;;;;;:26;;16466:9;;16449:13;:26;;16466:9;;16449:26;:::i;:::-;;;;-1:-1:-1;;16099:410:4;;;;:::o;9311:942::-;-1:-1:-1;;;;;9391:16:4;;9383:61;;;;-1:-1:-1;;;9383:61:4;;20937:2:20;9383:61:4;;;20919:21:20;;;20956:18;;;20949:30;21015:34;20995:18;;;20988:62;21067:18;;9383:61:4;20735:356:20;9383:61:4;7483:4;7081:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7081:16:4;7507:31;9455:58;;;;-1:-1:-1;;;9455:58:4;;21298:2:20;9455:58:4;;;21280:21:20;21337:2;21317:18;;;21310:30;21376;21356:18;;;21349:58;21424:18;;9455:58:4;21096:352:20;9455:58:4;9526:48;9555:1;9559:2;9563:7;9572:1;9526:20;:48::i;:::-;7483:4;7081:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7081:16:4;7507:31;9664:58;;;;-1:-1:-1;;;9664:58:4;;21298:2:20;9664:58:4;;;21280:21:20;21337:2;21317:18;;;21310:30;21376;21356:18;;;21349:58;21424:18;;9664:58:4;21096:352:20;9664:58:4;-1:-1:-1;;;;;10071:13:4;;;;;;:9;:13;;;;;;;;:18;;10088:1;10071:18;;;10113:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;10113:21:4;;;;;10152:33;10121:7;;10071:13;;10152:33;;10071:13;;10152:33;4107:18:12::1;4033:100:::0;:::o;14514:853:4:-;14668:4;-1:-1:-1;;;;;14689:13:4;;1505:19:0;:23;14685:675:4;;14725:71;;-1:-1:-1;;;14725:71:4;;-1:-1:-1;;;;;14725:36:4;;;;;:71;;736:10:1;;14776:4:4;;14782:7;;14791:4;;14725:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14725:71:4;;;;;;;;-1:-1:-1;;14725:71:4;;;;;;;;;;;;:::i;:::-;;;14721:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14966:6;:13;14983:1;14966:18;14962:328;;15009:60;;-1:-1:-1;;;15009:60:4;;;;;;;:::i;14962:328::-;15240:6;15234:13;15225:6;15221:2;15217:15;15210:38;14721:584;-1:-1:-1;;;;;;14847:51:4;-1:-1:-1;;;14847:51:4;;-1:-1:-1;14840:58:4;;14685:675;-1:-1:-1;15344:4:4;14514:853;;;;;;:::o;14:131:20:-;-1:-1:-1;;;;;;88:32:20;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:20;816:16;;809:27;592:250::o;847:271::-;889:3;927:5;921:12;954:6;949:3;942:19;970:76;1039:6;1032:4;1027:3;1023:14;1016:4;1009:5;1005:16;970:76;:::i;:::-;1100:2;1079:15;-1:-1:-1;;1075:29:20;1066:39;;;;1107:4;1062:50;;847:271;-1:-1:-1;;847:271:20:o;1123:220::-;1272:2;1261:9;1254:21;1235:4;1292:45;1333:2;1322:9;1318:18;1310:6;1292:45;:::i;1348:180::-;1407:6;1460:2;1448:9;1439:7;1435:23;1431:32;1428:52;;;1476:1;1473;1466:12;1428:52;-1:-1:-1;1499:23:20;;1348:180;-1:-1:-1;1348:180:20:o;1741:173::-;1809:20;;-1:-1:-1;;;;;1858:31:20;;1848:42;;1838:70;;1904:1;1901;1894:12;1838:70;1741:173;;;:::o;1919:254::-;1987:6;1995;2048:2;2036:9;2027:7;2023:23;2019:32;2016:52;;;2064:1;2061;2054:12;2016:52;2087:29;2106:9;2087:29;:::i;:::-;2077:39;2163:2;2148:18;;;;2135:32;;-1:-1:-1;;;1919:254:20:o;2360:186::-;2419:6;2472:2;2460:9;2451:7;2447:23;2443:32;2440:52;;;2488:1;2485;2478:12;2440:52;2511:29;2530:9;2511:29;:::i;2551:328::-;2628:6;2636;2644;2697:2;2685:9;2676:7;2672:23;2668:32;2665:52;;;2713:1;2710;2703:12;2665:52;2736:29;2755:9;2736:29;:::i;:::-;2726:39;;2784:38;2818:2;2807:9;2803:18;2784:38;:::i;:::-;2774:48;;2869:2;2858:9;2854:18;2841:32;2831:42;;2551:328;;;;;:::o;2884:127::-;2945:10;2940:3;2936:20;2933:1;2926:31;2976:4;2973:1;2966:15;3000:4;2997:1;2990:15;3016:632;3081:5;3111:18;3152:2;3144:6;3141:14;3138:40;;;3158:18;;:::i;:::-;3233:2;3227:9;3201:2;3287:15;;-1:-1:-1;;3283:24:20;;;3309:2;3279:33;3275:42;3263:55;;;3333:18;;;3353:22;;;3330:46;3327:72;;;3379:18;;:::i;:::-;3419:10;3415:2;3408:22;3448:6;3439:15;;3478:6;3470;3463:22;3518:3;3509:6;3504:3;3500:16;3497:25;3494:45;;;3535:1;3532;3525:12;3494:45;3585:6;3580:3;3573:4;3565:6;3561:17;3548:44;3640:1;3633:4;3624:6;3616;3612:19;3608:30;3601:41;;;;3016:632;;;;;:::o;3653:451::-;3722:6;3775:2;3763:9;3754:7;3750:23;3746:32;3743:52;;;3791:1;3788;3781:12;3743:52;3831:9;3818:23;3864:18;3856:6;3853:30;3850:50;;;3896:1;3893;3886:12;3850:50;3919:22;;3972:4;3964:13;;3960:27;-1:-1:-1;3950:55:20;;4001:1;3998;3991:12;3950:55;4024:74;4090:7;4085:2;4072:16;4067:2;4063;4059:11;4024:74;:::i;4109:118::-;4195:5;4188:13;4181:21;4174:5;4171:32;4161:60;;4217:1;4214;4207:12;4232:315;4297:6;4305;4358:2;4346:9;4337:7;4333:23;4329:32;4326:52;;;4374:1;4371;4364:12;4326:52;4397:29;4416:9;4397:29;:::i;:::-;4387:39;;4476:2;4465:9;4461:18;4448:32;4489:28;4511:5;4489:28;:::i;:::-;4536:5;4526:15;;;4232:315;;;;;:::o;4552:248::-;4620:6;4628;4681:2;4669:9;4660:7;4656:23;4652:32;4649:52;;;4697:1;4694;4687:12;4649:52;-1:-1:-1;;4720:23:20;;;4790:2;4775:18;;;4762:32;;-1:-1:-1;4552:248:20:o;4805:667::-;4900:6;4908;4916;4924;4977:3;4965:9;4956:7;4952:23;4948:33;4945:53;;;4994:1;4991;4984:12;4945:53;5017:29;5036:9;5017:29;:::i;:::-;5007:39;;5065:38;5099:2;5088:9;5084:18;5065:38;:::i;:::-;5055:48;;5150:2;5139:9;5135:18;5122:32;5112:42;;5205:2;5194:9;5190:18;5177:32;5232:18;5224:6;5221:30;5218:50;;;5264:1;5261;5254:12;5218:50;5287:22;;5340:4;5332:13;;5328:27;-1:-1:-1;5318:55:20;;5369:1;5366;5359:12;5318:55;5392:74;5458:7;5453:2;5440:16;5435:2;5431;5427:11;5392:74;:::i;:::-;5382:84;;;4805:667;;;;;;;:::o;5477:260::-;5545:6;5553;5606:2;5594:9;5585:7;5581:23;5577:32;5574:52;;;5622:1;5619;5612:12;5574:52;5645:29;5664:9;5645:29;:::i;:::-;5635:39;;5693:38;5727:2;5716:9;5712:18;5693:38;:::i;:::-;5683:48;;5477:260;;;;;:::o;5742:380::-;5821:1;5817:12;;;;5864;;;5885:61;;5939:4;5931:6;5927:17;5917:27;;5885:61;5992:2;5984:6;5981:14;5961:18;5958:38;5955:161;;6038:10;6033:3;6029:20;6026:1;6019:31;6073:4;6070:1;6063:15;6101:4;6098:1;6091:15;5955:161;;5742:380;;;:::o;7268:245::-;7335:6;7388:2;7376:9;7367:7;7363:23;7359:32;7356:52;;;7404:1;7401;7394:12;7356:52;7436:9;7430:16;7455:28;7477:5;7455:28;:::i;9058:127::-;9119:10;9114:3;9110:20;9107:1;9100:31;9150:4;9147:1;9140:15;9174:4;9171:1;9164:15;9190:125;9255:9;;;9276:10;;;9273:36;;;9289:18;;:::i;10084:168::-;10157:9;;;10188;;10205:15;;;10199:22;;10185:37;10175:71;;10226:18;;:::i;10605:128::-;10672:9;;;10693:11;;;10690:37;;;10707:18;;:::i;11169:135::-;11208:3;11229:17;;;11226:43;;11249:18;;:::i;:::-;-1:-1:-1;11296:1:20;11285:13;;11169:135::o;11435:545::-;11537:2;11532:3;11529:11;11526:448;;;11573:1;11598:5;11594:2;11587:17;11643:4;11639:2;11629:19;11713:2;11701:10;11697:19;11694:1;11690:27;11684:4;11680:38;11749:4;11737:10;11734:20;11731:47;;;-1:-1:-1;11772:4:20;11731:47;11827:2;11822:3;11818:12;11815:1;11811:20;11805:4;11801:31;11791:41;;11882:82;11900:2;11893:5;11890:13;11882:82;;;11945:17;;;11926:1;11915:13;11882:82;;;11886:3;;;11435:545;;;:::o;12156:1352::-;12282:3;12276:10;12309:18;12301:6;12298:30;12295:56;;;12331:18;;:::i;:::-;12360:97;12450:6;12410:38;12442:4;12436:11;12410:38;:::i;:::-;12404:4;12360:97;:::i;:::-;12512:4;;12576:2;12565:14;;12593:1;12588:663;;;;13295:1;13312:6;13309:89;;;-1:-1:-1;13364:19:20;;;13358:26;13309:89;-1:-1:-1;;12113:1:20;12109:11;;;12105:24;12101:29;12091:40;12137:1;12133:11;;;12088:57;13411:81;;12558:944;;12588:663;11382:1;11375:14;;;11419:4;11406:18;;-1:-1:-1;;12624:20:20;;;12742:236;12756:7;12753:1;12750:14;12742:236;;;12845:19;;;12839:26;12824:42;;12937:27;;;;12905:1;12893:14;;;;12772:19;;12742:236;;;12746:3;13006:6;12997:7;12994:19;12991:201;;;13067:19;;;13061:26;-1:-1:-1;;13150:1:20;13146:14;;;13162:3;13142:24;13138:37;13134:42;13119:58;13104:74;;12991:201;-1:-1:-1;;;;;13238:1:20;13222:14;;;13218:22;13205:36;;-1:-1:-1;12156:1352:20:o;13513:422::-;13602:1;13645:5;13602:1;13659:270;13680:7;13670:8;13667:21;13659:270;;;13739:4;13735:1;13731:6;13727:17;13721:4;13718:27;13715:53;;;13748:18;;:::i;:::-;13798:7;13788:8;13784:22;13781:55;;;13818:16;;;;13781:55;13897:22;;;;13857:15;;;;13659:270;;;13663:3;13513:422;;;;;:::o;13940:806::-;13989:5;14019:8;14009:80;;-1:-1:-1;14060:1:20;14074:5;;14009:80;14108:4;14098:76;;-1:-1:-1;14145:1:20;14159:5;;14098:76;14190:4;14208:1;14203:59;;;;14276:1;14271:130;;;;14183:218;;14203:59;14233:1;14224:10;;14247:5;;;14271:130;14308:3;14298:8;14295:17;14292:43;;;14315:18;;:::i;:::-;-1:-1:-1;;14371:1:20;14357:16;;14386:5;;14183:218;;14485:2;14475:8;14472:16;14466:3;14460:4;14457:13;14453:36;14447:2;14437:8;14434:16;14429:2;14423:4;14420:12;14416:35;14413:77;14410:159;;;-1:-1:-1;14522:19:20;;;14554:5;;14410:159;14601:34;14626:8;14620:4;14601:34;:::i;:::-;14671:6;14667:1;14663:6;14659:19;14650:7;14647:32;14644:58;;;14682:18;;:::i;:::-;14720:20;;13940:806;-1:-1:-1;;;13940:806:20:o;14751:131::-;14811:5;14840:36;14867:8;14861:4;14840:36;:::i;15733:1256::-;15957:3;15995:6;15989:13;16021:4;16034:64;16091:6;16086:3;16081:2;16073:6;16069:15;16034:64;:::i;:::-;16161:13;;16120:16;;;;16183:68;16161:13;16120:16;16218:15;;;16183:68;:::i;:::-;16340:13;;16273:20;;;16313:1;;16378:36;16340:13;16378:36;:::i;:::-;16433:1;16450:18;;;16477:141;;;;16632:1;16627:337;;;;16443:521;;16477:141;-1:-1:-1;;16512:24:20;;16498:39;;16589:16;;16582:24;16568:39;;16557:51;;;-1:-1:-1;16477:141:20;;16627:337;16658:6;16655:1;16648:17;16706:2;16703:1;16693:16;16731:1;16745:169;16759:8;16756:1;16753:15;16745:169;;;16841:14;;16826:13;;;16819:37;16884:16;;;;16776:10;;16745:169;;;16749:3;;16945:8;16938:5;16934:20;16927:27;;16443:521;-1:-1:-1;16980:3:20;;15733:1256;-1:-1:-1;;;;;;;;;;15733:1256:20:o;17762:409::-;17964:2;17946:21;;;18003:2;17983:18;;;17976:30;18042:34;18037:2;18022:18;;18015:62;-1:-1:-1;;;18108:2:20;18093:18;;18086:43;18161:3;18146:19;;17762:409::o;19505:401::-;19707:2;19689:21;;;19746:2;19726:18;;;19719:30;19785:34;19780:2;19765:18;;19758:62;-1:-1:-1;;;19851:2:20;19836:18;;19829:35;19896:3;19881:19;;19505:401::o;20316:414::-;20518:2;20500:21;;;20557:2;20537:18;;;20530:30;20596:34;20591:2;20576:18;;20569:62;-1:-1:-1;;;20662:2:20;20647:18;;20640:48;20720:3;20705:19;;20316:414::o;21453:489::-;-1:-1:-1;;;;;21722:15:20;;;21704:34;;21774:15;;21769:2;21754:18;;21747:43;21821:2;21806:18;;21799:34;;;21869:3;21864:2;21849:18;;21842:31;;;21647:4;;21890:46;;21916:19;;21908:6;21890:46;:::i;:::-;21882:54;21453:489;-1:-1:-1;;;;;;21453:489:20:o;21947:249::-;22016:6;22069:2;22057:9;22048:7;22044:23;22040:32;22037:52;;;22085:1;22082;22075:12;22037:52;22117:9;22111:16;22136:30;22160:5;22136:30;:::i
Swarm Source
ipfs://ff1c39dd783efaa43d3da53d3455620551279bfe58ff9d014013591d1f159626
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.