Feature Tip: Add private address tag to any address under My Name Tag !
ERC-1155
NFT
Overview
Max Total Supply
3,071 PEPECOINCOLLABS
Holders
1,400
Market
Volume (24H)
0.0792 ETH
Min Price (24H)
$94.40 @ 0.039300 ETH
Max Price (24H)
$95.96 @ 0.039949 ETH
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
PepecoinXFrens
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Frensware // Factory contract for the Pepecoin x Frens collaboration collection pragma solidity ^0.8.20; import {ERC1155} from "@rari-capital/solmate/src/tokens/ERC1155.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; import {IERC1155MetadataURI} from "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol"; import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {Counters} from "@openzeppelin/contracts/utils/Counters.sol"; contract PepecoinXFrens is ERC1155, Ownable, Pausable, ReentrancyGuard { using Counters for Counters.Counter; using Strings for uint256; Counters.Counter private _tokenIds; string private contractMetadataURI; string private _name; string private _symbol; string private baseURI; mapping(uint256 => bytes32) public merkleRoots; mapping(uint256 => string) private tokenURIs; mapping(uint256 => uint256) public maxSupply; mapping(uint256 => uint256) public totalSupply; mapping(uint256 => uint256) public mintFees; enum TokenAvailability { CLAIM_ONLY, MINT_ONLY, BOTH } mapping(uint256 => TokenAvailability) public tokenAvailability; mapping(uint256 => bool) public isFrozen; mapping(uint256 => mapping(address => bool)) public whitelist; mapping(address => mapping(uint256 => bool)) private _hasClaimed; event tokenMinted( address indexed account, uint256 indexed id, uint256 amount ); constructor( string memory name_, string memory symbol_, address initialOwner ) ERC1155() Ownable(initialOwner) { _name = name_; _symbol = symbol_; transferOwnership(initialOwner); } function claim(uint256 id, bytes32[] calldata merkleProof) external nonReentrant { require(tokenAvailability[id] == TokenAvailability.CLAIM_ONLY || tokenAvailability[id] == TokenAvailability.BOTH, "Token not available for claiming"); require(!_hasClaimed[msg.sender][id], "NFT already claimed"); require(totalSupply[id] < maxSupply[id], "Max supply reached"); bytes32 leaf = keccak256(abi.encodePacked(msg.sender)); require( MerkleProof.verify(merkleProof, merkleRoots[id], leaf), "Invalid proof" ); _hasClaimed[msg.sender][id] = true; _mint(msg.sender, id, 1, ""); totalSupply[id] += 1; emit tokenMinted(msg.sender, id, 1); } function mint(uint256 id, uint256 amount) external payable nonReentrant { require(tokenAvailability[id] == TokenAvailability.MINT_ONLY || tokenAvailability[id] == TokenAvailability.BOTH, "Token not available for minting"); require(!isFrozen[id], "Token is frozen"); require( totalSupply[id] + amount <= maxSupply[id], "Exceeds max supply" ); uint256 requiredFee = mintFees[id] * amount; require(msg.value >= requiredFee, "Insufficient fee"); _mint(msg.sender, id, amount, ""); totalSupply[id] += amount; emit tokenMinted(msg.sender, id, amount); } function introduceNewToken( uint256 initialOwnerAmount, uint256 newMaxSupply, string calldata newURI, bytes32 newMerkleRoot, uint256 newMintFee, TokenAvailability availabilityMode ) external onlyOwner { _tokenIds.increment(); uint256 newTokenId = _tokenIds.current(); require(bytes(newURI).length > 0, "URI must be set"); require(initialOwnerAmount <= newMaxSupply, "Initial amount cannot exceed max supply"); tokenURIs[newTokenId] = newURI; merkleRoots[newTokenId] = newMerkleRoot; mintFees[newTokenId] = newMintFee; maxSupply[newTokenId] = newMaxSupply; tokenAvailability[newTokenId] = availabilityMode; if (initialOwnerAmount > 0) { _mint(owner(), newTokenId, initialOwnerAmount, ""); totalSupply[newTokenId] = initialOwnerAmount; } } function setTokenAvailability(uint256 tokenId, TokenAvailability availabilityMode) external onlyOwner { require(!isFrozen[tokenId], "Token is frozen"); tokenAvailability[tokenId] = availabilityMode; } function setBaseURI(string memory newBaseURI) public onlyOwner { baseURI = newBaseURI; } function uri(uint256 id) public view virtual override returns (string memory) { return tokenURIs[id]; } function batchAddToWhitelist(uint256 tokenId, address[] calldata addresses) public onlyOwner { require(!isFrozen[tokenId], "Token frozen"); for (uint256 i = 0; i < addresses.length; i++) { whitelist[tokenId][addresses[i]] = true; } } function basedUri(uint256 id) public view returns (string memory) { require(bytes(baseURI).length > 0, "baseURI not set"); return string(abi.encodePacked(baseURI, id.toString(), ".json")); } function contractURI() public view returns (string memory) { return contractMetadataURI; } function setContractURI(string memory newContractURI) public onlyOwner { contractMetadataURI = newContractURI; } function updateTokenURI(uint256 tokenId, string calldata newURI) external onlyOwner { tokenURIs[tokenId] = newURI; } function freeze(uint256 tokenId) public onlyOwner { require(!isFrozen[tokenId], "ID already frozen"); isFrozen[tokenId] = true; } function getUserBalances(address user) public view returns (uint256[] memory, uint256[] memory) { uint256 tokenCount = _tokenIds.current(); uint256[] memory ids = new uint256[](tokenCount); uint256[] memory balances = new uint256[](tokenCount); for (uint256 i = 0; i < tokenCount; i++) { uint256 balance = balanceOf[user][i]; if (balance > 0) { ids[i] = i; balances[i] = balance; } } return (ids, balances); } function eligibleForClaim( uint256 id, address user, bytes32[] calldata merkleProof ) external view returns (bool) { if (_hasClaimed[user][id]) { return false; // Has already claimed } bytes32 leaf = keccak256(abi.encodePacked(user)); return MerkleProof.verify(merkleProof, merkleRoots[id], leaf); } function whitelistClaim(uint256 tokenId) external nonReentrant { require(whitelist[tokenId][msg.sender], "Not whitelisted"); require(!_hasClaimed[msg.sender][tokenId], "Already claimed"); require(totalSupply[tokenId] < maxSupply[tokenId], "Max supply reached"); _hasClaimed[msg.sender][tokenId] = true; _mint(msg.sender, tokenId, 1, ""); totalSupply[tokenId] += 1; emit tokenMinted(msg.sender, tokenId, 1); } function burn( address account, uint256 id, uint256 amount ) public { require( account == msg.sender || isApprovedForAll[account][msg.sender], "Caller is not owner nor approved" ); require( balanceOf[account][id] >= amount, "Burn amount exceeds balance" ); _burn(account, id, amount); // Use the internal _burn function totalSupply[id] -= amount; emit TransferSingle(msg.sender, account, address(0), id, amount); } function setMerkleRoot(uint256 id, bytes32 newMerkleRoot) external onlyOwner { merkleRoots[id] = newMerkleRoot; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function mailbox() external onlyOwner nonReentrant { uint256 balance = address(this).balance; require(balance > 0, "No ETH to withdraw"); payable(owner()).transfer(balance); } function setApprovalForAll(address operator, bool approved) public override(ERC1155) { super.setApprovalForAll(operator, approved); } function supportsInterface(bytes4 interfaceId) public view override(ERC1155) returns (bool) { return super.supportsInterface(interfaceId); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.20; /** * @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 is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @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._positions[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 cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 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 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[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._positions[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 (last updated v5.0.0) (utils/Strings.sol) pragma solidity ^0.8.20; import {Math} from "./math/Math.sol"; import {SignedMath} from "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant HEX_DIGITS = "0123456789abcdef"; uint8 private constant ADDRESS_LENGTH = 20; /** * @dev The `value` string doesn't fit in the specified `length`. */ error StringsInsufficientHexLength(uint256 value, uint256 length); /** * @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), HEX_DIGITS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toStringSigned(int256 value) internal pure returns (string memory) { return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); } /** * @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) { uint256 localValue = value; bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_DIGITS[localValue & 0xf]; localValue >>= 4; } if (localValue != 0) { revert StringsInsufficientHexLength(value, length); } 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); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.20; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the Merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates Merkle trees that are safe * against this attack out of the box. */ library MerkleProof { /** *@dev The multiproof provided is not valid. */ error MerkleProofInvalidMultiproof(); /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details. */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the Merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. if (leavesLen + proofLen != totalHashes + 1) { revert MerkleProofInvalidMultiproof(); } // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { if (proofPos != proofLen) { revert MerkleProofInvalidMultiproof(); } unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Sorts the pair (a, b) and hashes the result. */ function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } /** * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory. */ function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.20; import {IERC1155} from "../IERC1155.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. */ interface IERC1155MetadataURI is IERC1155 { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) public virtual { require(ids.length == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); // Storing these outside the loop saves ~15 gas per iteration. uint256 id; uint256 amount; for (uint256 i = 0; i < ids.length; ) { id = ids[i]; amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] calldata owners, uint256[] calldata ids) public view virtual returns (uint256[] memory balances) { require(owners.length == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < owners.length; ++i) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal virtual { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { ++i; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal virtual { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155TokenReceiver { function onERC1155Received( address, address, uint256, uint256, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155Received.selector; } function onERC1155BatchReceived( address, address, uint256[] calldata, uint256[] calldata, bytes calldata ) external virtual returns (bytes4) { return ERC1155TokenReceiver.onERC1155BatchReceived.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.20; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol) pragma solidity ^0.8.20; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Muldiv operation overflow. */ error MathOverflowedMulDiv(); enum Rounding { Floor, // Toward negative infinity Ceil, // Toward positive infinity Trunc, // Toward zero Expand // Away from zero } /** * @dev Returns the addition of two unsigned integers, with an overflow flag. */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the subtraction of two unsigned integers, with an overflow flag. */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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 towards infinity instead * of rounding towards zero. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { if (b == 0) { // Guarantee the same behavior as in a regular Solidity division. return a / b; } // (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 = x * y; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. if (denominator <= prod1) { revert MathOverflowedMulDiv(); } /////////////////////////////////////////////// // 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. uint256 twos = denominator & (0 - denominator); 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 (unsignedRoundsUp(rounding) && 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 * towards zero. * * 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 + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10 of a positive value rounded towards zero. * 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 + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256 of a positive value rounded towards zero. * 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 256, 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 + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); } } /** * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. */ function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { return uint8(rounding) % 2 == 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the value of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155Received} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `value` amount. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments. * * Requirements: * * - `ids` and `values` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @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); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"tokenMinted","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"basedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"batchAddToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"eligibleForClaim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserBalances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"initialOwnerAmount","type":"uint256"},{"internalType":"uint256","name":"newMaxSupply","type":"uint256"},{"internalType":"string","name":"newURI","type":"string"},{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"},{"internalType":"uint256","name":"newMintFee","type":"uint256"},{"internalType":"enum PepecoinXFrens.TokenAvailability","name":"availabilityMode","type":"uint8"}],"name":"introduceNewToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isFrozen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mailbox","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"merkleRoots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mintFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newContractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"enum PepecoinXFrens.TokenAvailability","name":"availabilityMode","type":"uint8"}],"name":"setTokenAvailability","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":"","type":"uint256"}],"name":"tokenAvailability","outputs":[{"internalType":"enum PepecoinXFrens.TokenAvailability","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newURI","type":"string"}],"name":"updateTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"whitelistClaim","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801562000010575f80fd5b5060405162005d1c38038062005d1c83398181016040528101906200003691906200052d565b805f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000aa575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620000a19190620005d5565b60405180910390fd5b620000bb816200011c60201b60201c565b505f600260146101000a81548160ff02191690831515021790555060016003819055508260069081620000ef919062000827565b50816007908162000101919062000827565b506200011381620001df60201b60201c565b5050506200090b565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620001ef6200027660201b60201c565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362000262575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620002599190620005d5565b60405180910390fd5b62000273816200011c60201b60201c565b50565b620002866200031860201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620002ac6200031f60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16146200031657620002d86200031860201b60201c565b6040517f118cdaa70000000000000000000000000000000000000000000000000000000081526004016200030d9190620005d5565b60405180910390fd5b565b5f33905090565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b620003a88262000360565b810181811067ffffffffffffffff82111715620003ca57620003c962000370565b5b80604052505050565b5f620003de62000347565b9050620003ec82826200039d565b919050565b5f67ffffffffffffffff8211156200040e576200040d62000370565b5b620004198262000360565b9050602081019050919050565b5f5b838110156200044557808201518184015260208101905062000428565b5f8484015250505050565b5f620004666200046084620003f1565b620003d3565b9050828152602081018484840111156200048557620004846200035c565b5b6200049284828562000426565b509392505050565b5f82601f830112620004b157620004b062000358565b5b8151620004c384826020860162000450565b91505092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f620004f782620004cc565b9050919050565b6200050981620004eb565b811462000514575f80fd5b50565b5f815190506200052781620004fe565b92915050565b5f805f6060848603121562000547576200054662000350565b5b5f84015167ffffffffffffffff81111562000567576200056662000354565b5b62000575868287016200049a565b935050602084015167ffffffffffffffff81111562000599576200059862000354565b5b620005a7868287016200049a565b9250506040620005ba8682870162000517565b9150509250925092565b620005cf81620004eb565b82525050565b5f602082019050620005ea5f830184620005c4565b92915050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806200063f57607f821691505b602082108103620006555762000654620005fa565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302620006b97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200067c565b620006c586836200067c565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f6200070f620007096200070384620006dd565b620006e6565b620006dd565b9050919050565b5f819050919050565b6200072a83620006ef565b62000742620007398262000716565b84845462000688565b825550505050565b5f90565b620007586200074a565b620007658184846200071f565b505050565b5b818110156200078c57620007805f826200074e565b6001810190506200076b565b5050565b601f821115620007db57620007a5816200065b565b620007b0846200066d565b81016020851015620007c0578190505b620007d8620007cf856200066d565b8301826200076a565b50505b505050565b5f82821c905092915050565b5f620007fd5f1984600802620007e0565b1980831691505092915050565b5f620008178383620007ec565b9150826002028217905092915050565b6200083282620005f0565b67ffffffffffffffff8111156200084e576200084d62000370565b5b6200085a825462000627565b6200086782828562000790565b5f60209050601f8311600181146200089d575f841562000888578287015190505b6200089485826200080a565b86555062000903565b601f198416620008ad866200065b565b5f5b82811015620008d657848901518255600182019150602085019450602081019050620008af565b86831015620008f65784890151620008f2601f891682620007ec565b8355505b6001600288020188555050505b505050505050565b61540380620009195f395ff3fe608060405260043610610223575f3560e01c806381b2c2b011610122578063bd85b039116100aa578063ec15a8901161006e578063ec15a89014610856578063f242432a1461087e578063f2fde38b146108a6578063f5298aca146108ce578063f649b7ff146108f657610223565b8063bd85b03914610776578063d5438eae146107b2578063d7a78db8146107c8578063e8a3d485146107f0578063e985e9c51461081a57610223565b806394ee5d62116100f157806394ee5d621461066f57806395d89b41146106ab578063a0894799146106d5578063a22cb46514610711578063abd3f6121461073957610223565b806381b2c2b0146105a5578063869f7594146105e15780638da5cb5b1461061d578063938e3d7b1461064757610223565b8063271cacbf116101b05780634f442306116101745780634f442306146104c557806355f804b3146105015780635c975abb14610529578063715018a61461055357806371c5ecb11461056957610223565b8063271cacbf146103d55780632eb2c2d6146103fd5780632f52ebb7146104255780634b25bfce1461044d5780634e1273f41461048957610223565b806318712c21116101f757806318712c211461030557806318e97fd11461032d5780631b2ef1ca1461035557806321b12b611461037157806322af00d41461039957610223565b8062fdd58e1461022757806301ffc9a71461026357806306fdde031461029f5780630e89341c146102c9575b5f80fd5b348015610232575f80fd5b5061024d60048036038101906102489190613396565b61091e565b60405161025a91906133e3565b60405180910390f35b34801561026e575f80fd5b5061028960048036038101906102849190613451565b61093d565b6040516102969190613496565b60405180910390f35b3480156102aa575f80fd5b506102b361094e565b6040516102c09190613539565b60405180910390f35b3480156102d4575f80fd5b506102ef60048036038101906102ea9190613559565b6109de565b6040516102fc9190613539565b60405180910390f35b348015610310575f80fd5b5061032b600480360381019061032691906135b7565b610a7f565b005b348015610338575f80fd5b50610353600480360381019061034e9190613656565b610aa1565b005b61036f600480360381019061036a91906136b3565b610acf565b005b34801561037c575f80fd5b5061039760048036038101906103929190613714565b610d74565b005b3480156103a4575f80fd5b506103bf60048036038101906103ba9190613559565b610e16565b6040516103cc91906133e3565b60405180910390f35b3480156103e0575f80fd5b506103fb60048036038101906103f691906137a7565b610e2b565b005b348015610408575f80fd5b50610423600480360381019061041e91906138ae565b610f42565b005b348015610430575f80fd5b5061044b600480360381019061044691906139da565b611388565b005b348015610458575f80fd5b50610473600480360381019061046e9190613a37565b611725565b6040516104809190613496565b60405180910390f35b348015610494575f80fd5b506104af60048036038101906104aa9190613a75565b61174f565b6040516104bc9190613baa565b60405180910390f35b3480156104d0575f80fd5b506104eb60048036038101906104e69190613559565b6118b3565b6040516104f89190613c3d565b60405180910390f35b34801561050c575f80fd5b5061052760048036038101906105229190613d7e565b6118d0565b005b348015610534575f80fd5b5061053d6118eb565b60405161054a9190613496565b60405180910390f35b34801561055e575f80fd5b50610567611901565b005b348015610574575f80fd5b5061058f600480360381019061058a9190613559565b611914565b60405161059c9190613dd4565b60405180910390f35b3480156105b0575f80fd5b506105cb60048036038101906105c69190613559565b611929565b6040516105d89190613539565b60405180910390f35b3480156105ec575f80fd5b5061060760048036038101906106029190613559565b6119ad565b60405161061491906133e3565b60405180910390f35b348015610628575f80fd5b506106316119c2565b60405161063e9190613dfc565b60405180910390f35b348015610652575f80fd5b5061066d60048036038101906106689190613d7e565b6119ea565b005b34801561067a575f80fd5b5061069560048036038101906106909190613e15565b611a05565b6040516106a29190613496565b60405180910390f35b3480156106b6575f80fd5b506106bf611afe565b6040516106cc9190613539565b60405180910390f35b3480156106e0575f80fd5b506106fb60048036038101906106f69190613559565b611b8e565b6040516107089190613496565b60405180910390f35b34801561071c575f80fd5b5061073760048036038101906107329190613eb0565b611bab565b005b348015610744575f80fd5b5061075f600480360381019061075a9190613eee565b611bb9565b60405161076d929190613f19565b60405180910390f35b348015610781575f80fd5b5061079c60048036038101906107979190613559565b611d26565b6040516107a991906133e3565b60405180910390f35b3480156107bd575f80fd5b506107c6611d3b565b005b3480156107d3575f80fd5b506107ee60048036038101906107e99190613559565b611de7565b005b3480156107fb575f80fd5b50610804611e79565b6040516108119190613539565b60405180910390f35b348015610825575f80fd5b50610840600480360381019061083b9190613f4e565b611f09565b60405161084d9190613496565b60405180910390f35b348015610861575f80fd5b5061087c60048036038101906108779190613559565b611f33565b005b348015610889575f80fd5b506108a4600480360381019061089f9190613f8c565b6121d2565b005b3480156108b1575f80fd5b506108cc60048036038101906108c79190613eee565b612571565b005b3480156108d9575f80fd5b506108f460048036038101906108ef9190614022565b6125f5565b005b348015610901575f80fd5b5061091c60048036038101906109179190614072565b612832565b005b5f602052815f5260405f20602052805f5260405f205f91509150505481565b5f610947826129be565b9050919050565b60606006805461095d90614149565b80601f016020809104026020016040519081016040528092919081815260200182805461098990614149565b80156109d45780601f106109ab576101008083540402835291602001916109d4565b820191905f5260205f20905b8154815290600101906020018083116109b757829003601f168201915b5050505050905090565b6060600a5f8381526020019081526020015f2080546109fc90614149565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2890614149565b8015610a735780601f10610a4a57610100808354040283529160200191610a73565b820191905f5260205f20905b815481529060010190602001808311610a5657829003601f168201915b50505050509050919050565b610a87612a4f565b8060095f8481526020019081526020015f20819055505050565b610aa9612a4f565b8181600a5f8681526020019081526020015f209182610ac9929190614320565b50505050565b610ad7612ad6565b60016002811115610aeb57610aea613bca565b5b600e5f8481526020019081526020015f205f9054906101000a900460ff166002811115610b1b57610b1a613bca565b5b1480610b675750600280811115610b3557610b34613bca565b5b600e5f8481526020019081526020015f205f9054906101000a900460ff166002811115610b6557610b64613bca565b5b145b610ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9d90614437565b60405180910390fd5b600f5f8381526020019081526020015f205f9054906101000a900460ff1615610c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bfb9061449f565b60405180910390fd5b600b5f8381526020019081526020015f205481600c5f8581526020019081526020015f2054610c3391906144ea565b1115610c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6b90614567565b60405180910390fd5b5f81600d5f8581526020019081526020015f2054610c929190614585565b905080341015610cd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cce90614610565b60405180910390fd5b610cf133848460405180602001604052805f815250612b25565b81600c5f8581526020019081526020015f205f828254610d1191906144ea565b92505081905550823373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb7484604051610d5f91906133e3565b60405180910390a350610d70612d65565b5050565b610d7c612a4f565b600f5f8381526020019081526020015f205f9054906101000a900460ff1615610dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd19061449f565b60405180910390fd5b80600e5f8481526020019081526020015f205f6101000a81548160ff02191690836002811115610e0d57610e0c613bca565b5b02179055505050565b600d602052805f5260405f205f915090505481565b610e33612a4f565b600f5f8481526020019081526020015f205f9054906101000a900460ff1615610e91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8890614678565b60405180910390fd5b5f5b82829050811015610f3c57600160105f8681526020019081526020015f205f858585818110610ec557610ec4614696565b5b9050602002016020810190610eda9190613eee565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508080610f34906146c3565b915050610e93565b50505050565b838390508686905014610f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8190614754565b60405180910390fd5b8773ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611045575060015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107b906147bc565b60405180910390fd5b5f805f5b88889050811015611198578888828181106110a6576110a5614696565b5b9050602002013592508686828181106110c2576110c1614696565b5b905060200201359150815f808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f82825461112591906147da565b92505081905550815f808c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f82825461118691906144ea565b92505081905550806001019050611088565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516112139493929190614875565b60405180910390a45f8973ffffffffffffffffffffffffffffffffffffffff163b1461130c5763bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168973ffffffffffffffffffffffffffffffffffffffff1663bc197c81338d8c8c8c8c8c8c6040518963ffffffff1660e01b81526004016112a79897969594939291906148ea565b6020604051808303815f875af11580156112c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e7919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461133d565b5f73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b61137c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611373906149df565b60405180910390fd5b50505050505050505050565b611390612ad6565b5f60028111156113a3576113a2613bca565b5b600e5f8581526020019081526020015f205f9054906101000a900460ff1660028111156113d3576113d2613bca565b5b148061141f57506002808111156113ed576113ec613bca565b5b600e5f8581526020019081526020015f205f9054906101000a900460ff16600281111561141d5761141c613bca565b5b145b61145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145590614a47565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f9054906101000a900460ff16156114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614aaf565b60405180910390fd5b600b5f8481526020019081526020015f2054600c5f8581526020019081526020015f20541061155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614b17565b60405180910390fd5b5f3360405160200161156d9190614b7a565b6040516020818303038152906040528051906020012090506115e18383808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060095f8781526020019081526020015f205483612d6f565b611620576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161790614bde565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f6101000a81548160ff02191690831515021790555061169f3385600160405180602001604052805f815250612b25565b6001600c5f8681526020019081526020015f205f8282546116c091906144ea565b92505081905550833373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb74600160405161170f9190614c35565b60405180910390a350611720612d65565b505050565b6010602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b6060828290508585905014611799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179090614754565b60405180910390fd5b8484905067ffffffffffffffff8111156117b6576117b5613c5a565b5b6040519080825280602002602001820160405280156117e45781602001602082028036833780820191505090505b5090505f5b858590508110156118aa575f8087878481811061180957611808614696565b5b905060200201602081019061181e9190613eee565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f85858481811061186b5761186a614696565b5b9050602002013581526020019081526020015f205482828151811061189357611892614696565b5b6020026020010181815250508060010190506117e9565b50949350505050565b600e602052805f5260405f205f915054906101000a900460ff1681565b6118d8612a4f565b80600890816118e79190614c4e565b5050565b5f600260149054906101000a900460ff16905090565b611909612a4f565b6119125f612d85565b565b6009602052805f5260405f205f915090505481565b60605f6008805461193990614149565b90501161197b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197290614d67565b60405180910390fd5b600861198683612e48565b604051602001611997929190614e89565b6040516020818303038152906040529050919050565b600b602052805f5260405f205f915090505481565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6119f2612a4f565b8060059081611a019190614c4e565b5050565b5f60115f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f9054906101000a900460ff1615611a6c575f9050611af6565b5f84604051602001611a7e9190614b7a565b604051602081830303815290604052805190602001209050611af28484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060095f8981526020019081526020015f205483612d6f565b9150505b949350505050565b606060078054611b0d90614149565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3990614149565b8015611b845780601f10611b5b57610100808354040283529160200191611b84565b820191905f5260205f20905b815481529060010190602001808311611b6757829003601f168201915b5050505050905090565b600f602052805f5260405f205f915054906101000a900460ff1681565b611bb58282612f12565b5050565b6060805f611bc7600461300a565b90505f8167ffffffffffffffff811115611be457611be3613c5a565b5b604051908082528060200260200182016040528015611c125781602001602082028036833780820191505090505b5090505f8267ffffffffffffffff811115611c3057611c2f613c5a565b5b604051908082528060200260200182016040528015611c5e5781602001602082028036833780820191505090505b5090505f5b83811015611d17575f805f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205490505f811115611d035781848381518110611cd657611cd5614696565b5b60200260200101818152505080838381518110611cf657611cf5614696565b5b6020026020010181815250505b508080611d0f906146c3565b915050611c63565b50818194509450505050915091565b600c602052805f5260405f205f915090505481565b611d43612a4f565b611d4b612ad6565b5f4790505f8111611d91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8890614f01565b60405180910390fd5b611d996119c2565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611ddb573d5f803e3d5ffd5b5050611de5612d65565b565b611def612a4f565b600f5f8281526020019081526020015f205f9054906101000a900460ff1615611e4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4490614f69565b60405180910390fd5b6001600f5f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b606060058054611e8890614149565b80601f0160208091040260200160405190810160405280929190818152602001828054611eb490614149565b8015611eff5780601f10611ed657610100808354040283529160200191611eff565b820191905f5260205f20905b815481529060010190602001808311611ee257829003601f168201915b5050505050905090565b6001602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b611f3b612ad6565b60105f8281526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fca90614fd1565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8281526020019081526020015f205f9054906101000a900460ff161561206c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206390615039565b60405180910390fd5b600b5f8281526020019081526020015f2054600c5f8381526020019081526020015f2054106120d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c790614b17565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555061214f3382600160405180602001604052805f815250612b25565b6001600c5f8381526020019081526020015f205f82825461217091906144ea565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb7460016040516121bf9190614c35565b60405180910390a36121cf612d65565b50565b8573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061228d575060015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c3906147bc565b60405180910390fd5b825f808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f82825461232691906147da565b92505081905550825f808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f82825461238791906144ea565b925050819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051612404929190615057565b60405180910390a45f8573ffffffffffffffffffffffffffffffffffffffff163b146124f95763f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168573ffffffffffffffffffffffffffffffffffffffff1663f23a6e613389888888886040518763ffffffff1660e01b81526004016124949695949392919061507e565b6020604051808303815f875af11580156124b0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124d4919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461252a565b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612569576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612560906149df565b60405180910390fd5b505050505050565b612579612a4f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125e9575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016125e09190613dfc565b60405180910390fd5b6125f281612d85565b50565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806126b0575060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6126ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e690615122565b60405180910390fd5b805f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f2054101561277d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127749061518a565b60405180910390fd5b612788838383613016565b80600c5f8481526020019081526020015f205f8282546127a891906147da565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051612825929190615057565b60405180910390a4505050565b61283a612a4f565b61284460046130fa565b5f61284f600461300a565b90505f8686905011612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d906151f2565b60405180910390fd5b868811156128d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d090615280565b60405180910390fd5b8585600a5f8481526020019081526020015f2091826128f9929190614320565b508360095f8381526020019081526020015f208190555082600d5f8381526020019081526020015f208190555086600b5f8381526020019081526020015f208190555081600e5f8381526020019081526020015f205f6101000a81548160ff0219169083600281111561296f5761296e613bca565b5b02179055505f8811156129b45761299d6129876119c2565b828a60405180602001604052805f815250612b25565b87600c5f8381526020019081526020015f20819055505b5050505050505050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612a18575063d9b67a2660e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612a485750630e89341c60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b612a5761310e565b73ffffffffffffffffffffffffffffffffffffffff16612a756119c2565b73ffffffffffffffffffffffffffffffffffffffff1614612ad457612a9861310e565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612acb9190613dfc565b60405180910390fd5b565b600260035403612b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b12906152e8565b60405180910390fd5b6002600381905550565b815f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f828254612b7f91906144ea565b925050819055508373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628686604051612bfc929190615057565b60405180910390a45f8473ffffffffffffffffffffffffffffffffffffffff163b14612cef5763f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168473ffffffffffffffffffffffffffffffffffffffff1663f23a6e61335f8787876040518663ffffffff1660e01b8152600401612c8a959493929190615348565b6020604051808303815f875af1158015612ca6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cca919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612d20565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b612d5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d56906149df565b60405180910390fd5b50505050565b6001600381905550565b5f82612d7b8584613115565b1490509392505050565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f6001612e5684613169565b0190505f8167ffffffffffffffff811115612e7457612e73613c5a565b5b6040519080825280601f01601f191660200182016040528015612ea65781602001600182028036833780820191505090505b5090505f82602001820190505b600115612f07578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612efc57612efb6153a0565b5b0494505f8503612eb3575b819350505050919050565b8060015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612ffe9190613496565b60405180910390a35050565b5f815f01549050919050565b805f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f82825461307091906147da565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516130ed929190615057565b60405180910390a4505050565b6001815f015f828254019250508190555050565b5f33905090565b5f808290505f5b845181101561315e576131498286838151811061313c5761313b614696565b5b60200260200101516132ba565b91508080613156906146c3565b91505061311c565b508091505092915050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106131c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816131bb576131ba6153a0565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613202576d04ee2d6d415b85acef810000000083816131f8576131f76153a0565b5b0492506020810190505b662386f26fc10000831061323157662386f26fc100008381613227576132266153a0565b5b0492506010810190505b6305f5e100831061325a576305f5e10083816132505761324f6153a0565b5b0492506008810190505b612710831061327f576127108381613275576132746153a0565b5b0492506004810190505b606483106132a25760648381613298576132976153a0565b5b0492506002810190505b600a83106132b1576001810190505b80915050919050565b5f8183106132d1576132cc82846132e4565b6132dc565b6132db83836132e4565b5b905092915050565b5f825f528160205260405f20905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61333282613309565b9050919050565b61334281613328565b811461334c575f80fd5b50565b5f8135905061335d81613339565b92915050565b5f819050919050565b61337581613363565b811461337f575f80fd5b50565b5f813590506133908161336c565b92915050565b5f80604083850312156133ac576133ab613301565b5b5f6133b98582860161334f565b92505060206133ca85828601613382565b9150509250929050565b6133dd81613363565b82525050565b5f6020820190506133f65f8301846133d4565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613430816133fc565b811461343a575f80fd5b50565b5f8135905061344b81613427565b92915050565b5f6020828403121561346657613465613301565b5b5f6134738482850161343d565b91505092915050565b5f8115159050919050565b6134908161347c565b82525050565b5f6020820190506134a95f830184613487565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156134e65780820151818401526020810190506134cb565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61350b826134af565b61351581856134b9565b93506135258185602086016134c9565b61352e816134f1565b840191505092915050565b5f6020820190508181035f8301526135518184613501565b905092915050565b5f6020828403121561356e5761356d613301565b5b5f61357b84828501613382565b91505092915050565b5f819050919050565b61359681613584565b81146135a0575f80fd5b50565b5f813590506135b18161358d565b92915050565b5f80604083850312156135cd576135cc613301565b5b5f6135da85828601613382565b92505060206135eb858286016135a3565b9150509250929050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613616576136156135f5565b5b8235905067ffffffffffffffff811115613633576136326135f9565b5b60208301915083600182028301111561364f5761364e6135fd565b5b9250929050565b5f805f6040848603121561366d5761366c613301565b5b5f61367a86828701613382565b935050602084013567ffffffffffffffff81111561369b5761369a613305565b5b6136a786828701613601565b92509250509250925092565b5f80604083850312156136c9576136c8613301565b5b5f6136d685828601613382565b92505060206136e785828601613382565b9150509250929050565b600381106136fd575f80fd5b50565b5f8135905061370e816136f1565b92915050565b5f806040838503121561372a57613729613301565b5b5f61373785828601613382565b925050602061374885828601613700565b9150509250929050565b5f8083601f840112613767576137666135f5565b5b8235905067ffffffffffffffff811115613784576137836135f9565b5b6020830191508360208202830111156137a05761379f6135fd565b5b9250929050565b5f805f604084860312156137be576137bd613301565b5b5f6137cb86828701613382565b935050602084013567ffffffffffffffff8111156137ec576137eb613305565b5b6137f886828701613752565b92509250509250925092565b5f8083601f840112613819576138186135f5565b5b8235905067ffffffffffffffff811115613836576138356135f9565b5b602083019150836020820283011115613852576138516135fd565b5b9250929050565b5f8083601f84011261386e5761386d6135f5565b5b8235905067ffffffffffffffff81111561388b5761388a6135f9565b5b6020830191508360018202830111156138a7576138a66135fd565b5b9250929050565b5f805f805f805f8060a0898b0312156138ca576138c9613301565b5b5f6138d78b828c0161334f565b98505060206138e88b828c0161334f565b975050604089013567ffffffffffffffff81111561390957613908613305565b5b6139158b828c01613804565b9650965050606089013567ffffffffffffffff81111561393857613937613305565b5b6139448b828c01613804565b9450945050608089013567ffffffffffffffff81111561396757613966613305565b5b6139738b828c01613859565b92509250509295985092959890939650565b5f8083601f84011261399a576139996135f5565b5b8235905067ffffffffffffffff8111156139b7576139b66135f9565b5b6020830191508360208202830111156139d3576139d26135fd565b5b9250929050565b5f805f604084860312156139f1576139f0613301565b5b5f6139fe86828701613382565b935050602084013567ffffffffffffffff811115613a1f57613a1e613305565b5b613a2b86828701613985565b92509250509250925092565b5f8060408385031215613a4d57613a4c613301565b5b5f613a5a85828601613382565b9250506020613a6b8582860161334f565b9150509250929050565b5f805f8060408587031215613a8d57613a8c613301565b5b5f85013567ffffffffffffffff811115613aaa57613aa9613305565b5b613ab687828801613752565b9450945050602085013567ffffffffffffffff811115613ad957613ad8613305565b5b613ae587828801613804565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613b2581613363565b82525050565b5f613b368383613b1c565b60208301905092915050565b5f602082019050919050565b5f613b5882613af3565b613b628185613afd565b9350613b6d83613b0d565b805f5b83811015613b9d578151613b848882613b2b565b9750613b8f83613b42565b925050600181019050613b70565b5085935050505092915050565b5f6020820190508181035f830152613bc28184613b4e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110613c0857613c07613bca565b5b50565b5f819050613c1882613bf7565b919050565b5f613c2782613c0b565b9050919050565b613c3781613c1d565b82525050565b5f602082019050613c505f830184613c2e565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613c90826134f1565b810181811067ffffffffffffffff82111715613caf57613cae613c5a565b5b80604052505050565b5f613cc16132f8565b9050613ccd8282613c87565b919050565b5f67ffffffffffffffff821115613cec57613ceb613c5a565b5b613cf5826134f1565b9050602081019050919050565b828183375f83830152505050565b5f613d22613d1d84613cd2565b613cb8565b905082815260208101848484011115613d3e57613d3d613c56565b5b613d49848285613d02565b509392505050565b5f82601f830112613d6557613d646135f5565b5b8135613d75848260208601613d10565b91505092915050565b5f60208284031215613d9357613d92613301565b5b5f82013567ffffffffffffffff811115613db057613daf613305565b5b613dbc84828501613d51565b91505092915050565b613dce81613584565b82525050565b5f602082019050613de75f830184613dc5565b92915050565b613df681613328565b82525050565b5f602082019050613e0f5f830184613ded565b92915050565b5f805f8060608587031215613e2d57613e2c613301565b5b5f613e3a87828801613382565b9450506020613e4b8782880161334f565b935050604085013567ffffffffffffffff811115613e6c57613e6b613305565b5b613e7887828801613985565b925092505092959194509250565b613e8f8161347c565b8114613e99575f80fd5b50565b5f81359050613eaa81613e86565b92915050565b5f8060408385031215613ec657613ec5613301565b5b5f613ed38582860161334f565b9250506020613ee485828601613e9c565b9150509250929050565b5f60208284031215613f0357613f02613301565b5b5f613f108482850161334f565b91505092915050565b5f6040820190508181035f830152613f318185613b4e565b90508181036020830152613f458184613b4e565b90509392505050565b5f8060408385031215613f6457613f63613301565b5b5f613f718582860161334f565b9250506020613f828582860161334f565b9150509250929050565b5f805f805f8060a08789031215613fa657613fa5613301565b5b5f613fb389828a0161334f565b9650506020613fc489828a0161334f565b9550506040613fd589828a01613382565b9450506060613fe689828a01613382565b935050608087013567ffffffffffffffff81111561400757614006613305565b5b61401389828a01613859565b92509250509295509295509295565b5f805f6060848603121561403957614038613301565b5b5f6140468682870161334f565b935050602061405786828701613382565b925050604061406886828701613382565b9150509250925092565b5f805f805f805f60c0888a03121561408d5761408c613301565b5b5f61409a8a828b01613382565b97505060206140ab8a828b01613382565b965050604088013567ffffffffffffffff8111156140cc576140cb613305565b5b6140d88a828b01613601565b955095505060606140eb8a828b016135a3565b93505060806140fc8a828b01613382565b92505060a061410d8a828b01613700565b91505092959891949750929550565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061416057607f821691505b6020821081036141735761417261411c565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026141df7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826141a4565b6141e986836141a4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61422461421f61421a84613363565b614201565b613363565b9050919050565b5f819050919050565b61423d8361420a565b6142516142498261422b565b8484546141b0565b825550505050565b5f90565b614265614259565b614270818484614234565b505050565b5b81811015614293576142885f8261425d565b600181019050614276565b5050565b601f8211156142d8576142a981614183565b6142b284614195565b810160208510156142c1578190505b6142d56142cd85614195565b830182614275565b50505b505050565b5f82821c905092915050565b5f6142f85f19846008026142dd565b1980831691505092915050565b5f61431083836142e9565b9150826002028217905092915050565b61432a8383614179565b67ffffffffffffffff81111561434357614342613c5a565b5b61434d8254614149565b614358828285614297565b5f601f831160018114614385575f8415614373578287013590505b61437d8582614305565b8655506143e4565b601f19841661439386614183565b5f5b828110156143ba57848901358255600182019150602085019450602081019050614395565b868310156143d757848901356143d3601f8916826142e9565b8355505b6001600288020188555050505b50505050505050565b7f546f6b656e206e6f7420617661696c61626c6520666f72206d696e74696e67005f82015250565b5f614421601f836134b9565b915061442c826143ed565b602082019050919050565b5f6020820190508181035f83015261444e81614415565b9050919050565b7f546f6b656e2069732066726f7a656e00000000000000000000000000000000005f82015250565b5f614489600f836134b9565b915061449482614455565b602082019050919050565b5f6020820190508181035f8301526144b68161447d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6144f482613363565b91506144ff83613363565b9250828201905080821115614517576145166144bd565b5b92915050565b7f45786365656473206d617820737570706c7900000000000000000000000000005f82015250565b5f6145516012836134b9565b915061455c8261451d565b602082019050919050565b5f6020820190508181035f83015261457e81614545565b9050919050565b5f61458f82613363565b915061459a83613363565b92508282026145a881613363565b915082820484148315176145bf576145be6144bd565b5b5092915050565b7f496e73756666696369656e7420666565000000000000000000000000000000005f82015250565b5f6145fa6010836134b9565b9150614605826145c6565b602082019050919050565b5f6020820190508181035f830152614627816145ee565b9050919050565b7f546f6b656e2066726f7a656e00000000000000000000000000000000000000005f82015250565b5f614662600c836134b9565b915061466d8261462e565b602082019050919050565b5f6020820190508181035f83015261468f81614656565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6146cd82613363565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036146ff576146fe6144bd565b5b600182019050919050565b7f4c454e4754485f4d49534d4154434800000000000000000000000000000000005f82015250565b5f61473e600f836134b9565b91506147498261470a565b602082019050919050565b5f6020820190508181035f83015261476b81614732565b9050919050565b7f4e4f545f415554484f52495a45440000000000000000000000000000000000005f82015250565b5f6147a6600e836134b9565b91506147b182614772565b602082019050919050565b5f6020820190508181035f8301526147d38161479a565b9050919050565b5f6147e482613363565b91506147ef83613363565b9250828203905081811115614807576148066144bd565b5b92915050565b5f80fd5b82818337505050565b5f6148258385613afd565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156148585761485761480d565b5b602083029250614869838584614811565b82840190509392505050565b5f6040820190508181035f83015261488e81868861481a565b905081810360208301526148a381848661481a565b905095945050505050565b5f82825260208201905092915050565b5f6148c983856148ae565b93506148d6838584613d02565b6148df836134f1565b840190509392505050565b5f60a0820190506148fd5f83018b613ded565b61490a602083018a613ded565b818103604083015261491d81888a61481a565b9050818103606083015261493281868861481a565b905081810360808301526149478184866148be565b90509998505050505050505050565b5f8151905061496481613427565b92915050565b5f6020828403121561497f5761497e613301565b5b5f61498c84828501614956565b91505092915050565b7f554e534146455f524543495049454e54000000000000000000000000000000005f82015250565b5f6149c96010836134b9565b91506149d482614995565b602082019050919050565b5f6020820190508181035f8301526149f6816149bd565b9050919050565b7f546f6b656e206e6f7420617661696c61626c6520666f7220636c61696d696e675f82015250565b5f614a316020836134b9565b9150614a3c826149fd565b602082019050919050565b5f6020820190508181035f830152614a5e81614a25565b9050919050565b7f4e465420616c726561647920636c61696d6564000000000000000000000000005f82015250565b5f614a996013836134b9565b9150614aa482614a65565b602082019050919050565b5f6020820190508181035f830152614ac681614a8d565b9050919050565b7f4d617820737570706c79207265616368656400000000000000000000000000005f82015250565b5f614b016012836134b9565b9150614b0c82614acd565b602082019050919050565b5f6020820190508181035f830152614b2e81614af5565b9050919050565b5f8160601b9050919050565b5f614b4b82614b35565b9050919050565b5f614b5c82614b41565b9050919050565b614b74614b6f82613328565b614b52565b82525050565b5f614b858284614b63565b60148201915081905092915050565b7f496e76616c69642070726f6f66000000000000000000000000000000000000005f82015250565b5f614bc8600d836134b9565b9150614bd382614b94565b602082019050919050565b5f6020820190508181035f830152614bf581614bbc565b9050919050565b5f819050919050565b5f614c1f614c1a614c1584614bfc565b614201565b613363565b9050919050565b614c2f81614c05565b82525050565b5f602082019050614c485f830184614c26565b92915050565b614c57826134af565b67ffffffffffffffff811115614c7057614c6f613c5a565b5b614c7a8254614149565b614c85828285614297565b5f60209050601f831160018114614cb6575f8415614ca4578287015190505b614cae8582614305565b865550614d15565b601f198416614cc486614183565b5f5b82811015614ceb57848901518255600182019150602085019450602081019050614cc6565b86831015614d085784890151614d04601f8916826142e9565b8355505b6001600288020188555050505b505050505050565b7f62617365555249206e6f742073657400000000000000000000000000000000005f82015250565b5f614d51600f836134b9565b9150614d5c82614d1d565b602082019050919050565b5f6020820190508181035f830152614d7e81614d45565b9050919050565b5f81905092915050565b5f8154614d9b81614149565b614da58186614d85565b9450600182165f8114614dbf5760018114614dd457614e06565b60ff1983168652811515820286019350614e06565b614ddd85614183565b5f5b83811015614dfe57815481890152600182019150602081019050614ddf565b838801955050505b50505092915050565b5f614e19826134af565b614e238185614d85565b9350614e338185602086016134c9565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f614e73600583614d85565b9150614e7e82614e3f565b600582019050919050565b5f614e948285614d8f565b9150614ea08284614e0f565b9150614eab82614e67565b91508190509392505050565b7f4e6f2045544820746f20776974686472617700000000000000000000000000005f82015250565b5f614eeb6012836134b9565b9150614ef682614eb7565b602082019050919050565b5f6020820190508181035f830152614f1881614edf565b9050919050565b7f494420616c72656164792066726f7a656e0000000000000000000000000000005f82015250565b5f614f536011836134b9565b9150614f5e82614f1f565b602082019050919050565b5f6020820190508181035f830152614f8081614f47565b9050919050565b7f4e6f742077686974656c697374656400000000000000000000000000000000005f82015250565b5f614fbb600f836134b9565b9150614fc682614f87565b602082019050919050565b5f6020820190508181035f830152614fe881614faf565b9050919050565b7f416c726561647920636c61696d656400000000000000000000000000000000005f82015250565b5f615023600f836134b9565b915061502e82614fef565b602082019050919050565b5f6020820190508181035f83015261505081615017565b9050919050565b5f60408201905061506a5f8301856133d4565b61507760208301846133d4565b9392505050565b5f60a0820190506150915f830189613ded565b61509e6020830188613ded565b6150ab60408301876133d4565b6150b860608301866133d4565b81810360808301526150cb8184866148be565b9050979650505050505050565b7f43616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665645f82015250565b5f61510c6020836134b9565b9150615117826150d8565b602082019050919050565b5f6020820190508181035f83015261513981615100565b9050919050565b7f4275726e20616d6f756e7420657863656564732062616c616e636500000000005f82015250565b5f615174601b836134b9565b915061517f82615140565b602082019050919050565b5f6020820190508181035f8301526151a181615168565b9050919050565b7f555249206d7573742062652073657400000000000000000000000000000000005f82015250565b5f6151dc600f836134b9565b91506151e7826151a8565b602082019050919050565b5f6020820190508181035f830152615209816151d0565b9050919050565b7f496e697469616c20616d6f756e742063616e6e6f7420657863656564206d61785f8201527f20737570706c7900000000000000000000000000000000000000000000000000602082015250565b5f61526a6027836134b9565b915061527582615210565b604082019050919050565b5f6020820190508181035f8301526152978161525e565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6152d2601f836134b9565b91506152dd8261529e565b602082019050919050565b5f6020820190508181035f8301526152ff816152c6565b9050919050565b5f81519050919050565b5f61531a82615306565b61532481856148ae565b93506153348185602086016134c9565b61533d816134f1565b840191505092915050565b5f60a08201905061535b5f830188613ded565b6153686020830187613ded565b61537560408301866133d4565b61538260608301856133d4565b81810360808301526153948184615310565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212203308cc927bb7d837b8b0def943e234ae7a0ada6206ea1b60272533c1de09fe4c64736f6c63430008140033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000006942013379d195323e17cd2616435dce819c1fa9000000000000000000000000000000000000000000000000000000000000001050657065636f696e2078204672656e7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f50455045434f494e434f4c4c4142530000000000000000000000000000000000
Deployed Bytecode
0x608060405260043610610223575f3560e01c806381b2c2b011610122578063bd85b039116100aa578063ec15a8901161006e578063ec15a89014610856578063f242432a1461087e578063f2fde38b146108a6578063f5298aca146108ce578063f649b7ff146108f657610223565b8063bd85b03914610776578063d5438eae146107b2578063d7a78db8146107c8578063e8a3d485146107f0578063e985e9c51461081a57610223565b806394ee5d62116100f157806394ee5d621461066f57806395d89b41146106ab578063a0894799146106d5578063a22cb46514610711578063abd3f6121461073957610223565b806381b2c2b0146105a5578063869f7594146105e15780638da5cb5b1461061d578063938e3d7b1461064757610223565b8063271cacbf116101b05780634f442306116101745780634f442306146104c557806355f804b3146105015780635c975abb14610529578063715018a61461055357806371c5ecb11461056957610223565b8063271cacbf146103d55780632eb2c2d6146103fd5780632f52ebb7146104255780634b25bfce1461044d5780634e1273f41461048957610223565b806318712c21116101f757806318712c211461030557806318e97fd11461032d5780631b2ef1ca1461035557806321b12b611461037157806322af00d41461039957610223565b8062fdd58e1461022757806301ffc9a71461026357806306fdde031461029f5780630e89341c146102c9575b5f80fd5b348015610232575f80fd5b5061024d60048036038101906102489190613396565b61091e565b60405161025a91906133e3565b60405180910390f35b34801561026e575f80fd5b5061028960048036038101906102849190613451565b61093d565b6040516102969190613496565b60405180910390f35b3480156102aa575f80fd5b506102b361094e565b6040516102c09190613539565b60405180910390f35b3480156102d4575f80fd5b506102ef60048036038101906102ea9190613559565b6109de565b6040516102fc9190613539565b60405180910390f35b348015610310575f80fd5b5061032b600480360381019061032691906135b7565b610a7f565b005b348015610338575f80fd5b50610353600480360381019061034e9190613656565b610aa1565b005b61036f600480360381019061036a91906136b3565b610acf565b005b34801561037c575f80fd5b5061039760048036038101906103929190613714565b610d74565b005b3480156103a4575f80fd5b506103bf60048036038101906103ba9190613559565b610e16565b6040516103cc91906133e3565b60405180910390f35b3480156103e0575f80fd5b506103fb60048036038101906103f691906137a7565b610e2b565b005b348015610408575f80fd5b50610423600480360381019061041e91906138ae565b610f42565b005b348015610430575f80fd5b5061044b600480360381019061044691906139da565b611388565b005b348015610458575f80fd5b50610473600480360381019061046e9190613a37565b611725565b6040516104809190613496565b60405180910390f35b348015610494575f80fd5b506104af60048036038101906104aa9190613a75565b61174f565b6040516104bc9190613baa565b60405180910390f35b3480156104d0575f80fd5b506104eb60048036038101906104e69190613559565b6118b3565b6040516104f89190613c3d565b60405180910390f35b34801561050c575f80fd5b5061052760048036038101906105229190613d7e565b6118d0565b005b348015610534575f80fd5b5061053d6118eb565b60405161054a9190613496565b60405180910390f35b34801561055e575f80fd5b50610567611901565b005b348015610574575f80fd5b5061058f600480360381019061058a9190613559565b611914565b60405161059c9190613dd4565b60405180910390f35b3480156105b0575f80fd5b506105cb60048036038101906105c69190613559565b611929565b6040516105d89190613539565b60405180910390f35b3480156105ec575f80fd5b5061060760048036038101906106029190613559565b6119ad565b60405161061491906133e3565b60405180910390f35b348015610628575f80fd5b506106316119c2565b60405161063e9190613dfc565b60405180910390f35b348015610652575f80fd5b5061066d60048036038101906106689190613d7e565b6119ea565b005b34801561067a575f80fd5b5061069560048036038101906106909190613e15565b611a05565b6040516106a29190613496565b60405180910390f35b3480156106b6575f80fd5b506106bf611afe565b6040516106cc9190613539565b60405180910390f35b3480156106e0575f80fd5b506106fb60048036038101906106f69190613559565b611b8e565b6040516107089190613496565b60405180910390f35b34801561071c575f80fd5b5061073760048036038101906107329190613eb0565b611bab565b005b348015610744575f80fd5b5061075f600480360381019061075a9190613eee565b611bb9565b60405161076d929190613f19565b60405180910390f35b348015610781575f80fd5b5061079c60048036038101906107979190613559565b611d26565b6040516107a991906133e3565b60405180910390f35b3480156107bd575f80fd5b506107c6611d3b565b005b3480156107d3575f80fd5b506107ee60048036038101906107e99190613559565b611de7565b005b3480156107fb575f80fd5b50610804611e79565b6040516108119190613539565b60405180910390f35b348015610825575f80fd5b50610840600480360381019061083b9190613f4e565b611f09565b60405161084d9190613496565b60405180910390f35b348015610861575f80fd5b5061087c60048036038101906108779190613559565b611f33565b005b348015610889575f80fd5b506108a4600480360381019061089f9190613f8c565b6121d2565b005b3480156108b1575f80fd5b506108cc60048036038101906108c79190613eee565b612571565b005b3480156108d9575f80fd5b506108f460048036038101906108ef9190614022565b6125f5565b005b348015610901575f80fd5b5061091c60048036038101906109179190614072565b612832565b005b5f602052815f5260405f20602052805f5260405f205f91509150505481565b5f610947826129be565b9050919050565b60606006805461095d90614149565b80601f016020809104026020016040519081016040528092919081815260200182805461098990614149565b80156109d45780601f106109ab576101008083540402835291602001916109d4565b820191905f5260205f20905b8154815290600101906020018083116109b757829003601f168201915b5050505050905090565b6060600a5f8381526020019081526020015f2080546109fc90614149565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2890614149565b8015610a735780601f10610a4a57610100808354040283529160200191610a73565b820191905f5260205f20905b815481529060010190602001808311610a5657829003601f168201915b50505050509050919050565b610a87612a4f565b8060095f8481526020019081526020015f20819055505050565b610aa9612a4f565b8181600a5f8681526020019081526020015f209182610ac9929190614320565b50505050565b610ad7612ad6565b60016002811115610aeb57610aea613bca565b5b600e5f8481526020019081526020015f205f9054906101000a900460ff166002811115610b1b57610b1a613bca565b5b1480610b675750600280811115610b3557610b34613bca565b5b600e5f8481526020019081526020015f205f9054906101000a900460ff166002811115610b6557610b64613bca565b5b145b610ba6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b9d90614437565b60405180910390fd5b600f5f8381526020019081526020015f205f9054906101000a900460ff1615610c04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bfb9061449f565b60405180910390fd5b600b5f8381526020019081526020015f205481600c5f8581526020019081526020015f2054610c3391906144ea565b1115610c74576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6b90614567565b60405180910390fd5b5f81600d5f8581526020019081526020015f2054610c929190614585565b905080341015610cd7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cce90614610565b60405180910390fd5b610cf133848460405180602001604052805f815250612b25565b81600c5f8581526020019081526020015f205f828254610d1191906144ea565b92505081905550823373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb7484604051610d5f91906133e3565b60405180910390a350610d70612d65565b5050565b610d7c612a4f565b600f5f8381526020019081526020015f205f9054906101000a900460ff1615610dda576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dd19061449f565b60405180910390fd5b80600e5f8481526020019081526020015f205f6101000a81548160ff02191690836002811115610e0d57610e0c613bca565b5b02179055505050565b600d602052805f5260405f205f915090505481565b610e33612a4f565b600f5f8481526020019081526020015f205f9054906101000a900460ff1615610e91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8890614678565b60405180910390fd5b5f5b82829050811015610f3c57600160105f8681526020019081526020015f205f858585818110610ec557610ec4614696565b5b9050602002016020810190610eda9190613eee565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508080610f34906146c3565b915050610e93565b50505050565b838390508686905014610f8a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8190614754565b60405180910390fd5b8773ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611045575060015f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b611084576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161107b906147bc565b60405180910390fd5b5f805f5b88889050811015611198578888828181106110a6576110a5614696565b5b9050602002013592508686828181106110c2576110c1614696565b5b905060200201359150815f808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f82825461112591906147da565b92505081905550815f808c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f82825461118691906144ea565b92505081905550806001019050611088565b508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b6040516112139493929190614875565b60405180910390a45f8973ffffffffffffffffffffffffffffffffffffffff163b1461130c5763bc197c8160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168973ffffffffffffffffffffffffffffffffffffffff1663bc197c81338d8c8c8c8c8c8c6040518963ffffffff1660e01b81526004016112a79897969594939291906148ea565b6020604051808303815f875af11580156112c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e7919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461133d565b5f73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614155b61137c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611373906149df565b60405180910390fd5b50505050505050505050565b611390612ad6565b5f60028111156113a3576113a2613bca565b5b600e5f8581526020019081526020015f205f9054906101000a900460ff1660028111156113d3576113d2613bca565b5b148061141f57506002808111156113ed576113ec613bca565b5b600e5f8581526020019081526020015f205f9054906101000a900460ff16600281111561141d5761141c613bca565b5b145b61145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145590614a47565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f9054906101000a900460ff16156114f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114ee90614aaf565b60405180910390fd5b600b5f8481526020019081526020015f2054600c5f8581526020019081526020015f20541061155b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155290614b17565b60405180910390fd5b5f3360405160200161156d9190614b7a565b6040516020818303038152906040528051906020012090506115e18383808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060095f8781526020019081526020015f205483612d6f565b611620576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161790614bde565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f6101000a81548160ff02191690831515021790555061169f3385600160405180602001604052805f815250612b25565b6001600c5f8681526020019081526020015f205f8282546116c091906144ea565b92505081905550833373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb74600160405161170f9190614c35565b60405180910390a350611720612d65565b505050565b6010602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b6060828290508585905014611799576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179090614754565b60405180910390fd5b8484905067ffffffffffffffff8111156117b6576117b5613c5a565b5b6040519080825280602002602001820160405280156117e45781602001602082028036833780820191505090505b5090505f5b858590508110156118aa575f8087878481811061180957611808614696565b5b905060200201602081019061181e9190613eee565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f85858481811061186b5761186a614696565b5b9050602002013581526020019081526020015f205482828151811061189357611892614696565b5b6020026020010181815250508060010190506117e9565b50949350505050565b600e602052805f5260405f205f915054906101000a900460ff1681565b6118d8612a4f565b80600890816118e79190614c4e565b5050565b5f600260149054906101000a900460ff16905090565b611909612a4f565b6119125f612d85565b565b6009602052805f5260405f205f915090505481565b60605f6008805461193990614149565b90501161197b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161197290614d67565b60405180910390fd5b600861198683612e48565b604051602001611997929190614e89565b6040516020818303038152906040529050919050565b600b602052805f5260405f205f915090505481565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6119f2612a4f565b8060059081611a019190614c4e565b5050565b5f60115f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f9054906101000a900460ff1615611a6c575f9050611af6565b5f84604051602001611a7e9190614b7a565b604051602081830303815290604052805190602001209050611af28484808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f8201169050808301925050505050505060095f8981526020019081526020015f205483612d6f565b9150505b949350505050565b606060078054611b0d90614149565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3990614149565b8015611b845780601f10611b5b57610100808354040283529160200191611b84565b820191905f5260205f20905b815481529060010190602001808311611b6757829003601f168201915b5050505050905090565b600f602052805f5260405f205f915054906101000a900460ff1681565b611bb58282612f12565b5050565b6060805f611bc7600461300a565b90505f8167ffffffffffffffff811115611be457611be3613c5a565b5b604051908082528060200260200182016040528015611c125781602001602082028036833780820191505090505b5090505f8267ffffffffffffffff811115611c3057611c2f613c5a565b5b604051908082528060200260200182016040528015611c5e5781602001602082028036833780820191505090505b5090505f5b83811015611d17575f805f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205490505f811115611d035781848381518110611cd657611cd5614696565b5b60200260200101818152505080838381518110611cf657611cf5614696565b5b6020026020010181815250505b508080611d0f906146c3565b915050611c63565b50818194509450505050915091565b600c602052805f5260405f205f915090505481565b611d43612a4f565b611d4b612ad6565b5f4790505f8111611d91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d8890614f01565b60405180910390fd5b611d996119c2565b73ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015611ddb573d5f803e3d5ffd5b5050611de5612d65565b565b611def612a4f565b600f5f8281526020019081526020015f205f9054906101000a900460ff1615611e4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4490614f69565b60405180910390fd5b6001600f5f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b606060058054611e8890614149565b80601f0160208091040260200160405190810160405280929190818152602001828054611eb490614149565b8015611eff5780601f10611ed657610100808354040283529160200191611eff565b820191905f5260205f20905b815481529060010190602001808311611ee257829003601f168201915b5050505050905090565b6001602052815f5260405f20602052805f5260405f205f915091509054906101000a900460ff1681565b611f3b612ad6565b60105f8281526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611fd3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fca90614fd1565b60405180910390fd5b60115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8281526020019081526020015f205f9054906101000a900460ff161561206c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161206390615039565b60405180910390fd5b600b5f8281526020019081526020015f2054600c5f8381526020019081526020015f2054106120d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c790614b17565b60405180910390fd5b600160115f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555061214f3382600160405180602001604052805f815250612b25565b6001600c5f8381526020019081526020015f205f82825461217091906144ea565b92505081905550803373ffffffffffffffffffffffffffffffffffffffff167f654aa85b2af57b53beb55f7fe31413e8d6d5ab5411a0c0c7fe975140f96abb7460016040516121bf9190614c35565b60405180910390a36121cf612d65565b50565b8573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061228d575060015f8773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c3906147bc565b60405180910390fd5b825f808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f82825461232691906147da565b92505081905550825f808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8681526020019081526020015f205f82825461238791906144ea565b925050819055508473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051612404929190615057565b60405180910390a45f8573ffffffffffffffffffffffffffffffffffffffff163b146124f95763f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168573ffffffffffffffffffffffffffffffffffffffff1663f23a6e613389888888886040518763ffffffff1660e01b81526004016124949695949392919061507e565b6020604051808303815f875af11580156124b0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124d4919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461252a565b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b612569576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612560906149df565b60405180910390fd5b505050505050565b612579612a4f565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036125e9575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016125e09190613dfc565b60405180910390fd5b6125f281612d85565b50565b3373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614806126b0575060015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff165b6126ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e690615122565b60405180910390fd5b805f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f2054101561277d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127749061518a565b60405180910390fd5b612788838383613016565b80600c5f8481526020019081526020015f205f8282546127a891906147da565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051612825929190615057565b60405180910390a4505050565b61283a612a4f565b61284460046130fa565b5f61284f600461300a565b90505f8686905011612896576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161288d906151f2565b60405180910390fd5b868811156128d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d090615280565b60405180910390fd5b8585600a5f8481526020019081526020015f2091826128f9929190614320565b508360095f8381526020019081526020015f208190555082600d5f8381526020019081526020015f208190555086600b5f8381526020019081526020015f208190555081600e5f8381526020019081526020015f205f6101000a81548160ff0219169083600281111561296f5761296e613bca565b5b02179055505f8811156129b45761299d6129876119c2565b828a60405180602001604052805f815250612b25565b87600c5f8381526020019081526020015f20819055505b5050505050505050565b5f6301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612a18575063d9b67a2660e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612a485750630e89341c60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b612a5761310e565b73ffffffffffffffffffffffffffffffffffffffff16612a756119c2565b73ffffffffffffffffffffffffffffffffffffffff1614612ad457612a9861310e565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612acb9190613dfc565b60405180910390fd5b565b600260035403612b1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b12906152e8565b60405180910390fd5b6002600381905550565b815f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8581526020019081526020015f205f828254612b7f91906144ea565b925050819055508373ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628686604051612bfc929190615057565b60405180910390a45f8473ffffffffffffffffffffffffffffffffffffffff163b14612cef5763f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168473ffffffffffffffffffffffffffffffffffffffff1663f23a6e61335f8787876040518663ffffffff1660e01b8152600401612c8a959493929190615348565b6020604051808303815f875af1158015612ca6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612cca919061496a565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614612d20565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614155b612d5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d56906149df565b60405180910390fd5b50505050565b6001600381905550565b5f82612d7b8584613115565b1490509392505050565b5f60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60605f6001612e5684613169565b0190505f8167ffffffffffffffff811115612e7457612e73613c5a565b5b6040519080825280601f01601f191660200182016040528015612ea65781602001600182028036833780820191505090505b5090505f82602001820190505b600115612f07578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581612efc57612efb6153a0565b5b0494505f8503612eb3575b819350505050919050565b8060015f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612ffe9190613496565b60405180910390a35050565b5f815f01549050919050565b805f808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8481526020019081526020015f205f82825461307091906147da565b925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6285856040516130ed929190615057565b60405180910390a4505050565b6001815f015f828254019250508190555050565b5f33905090565b5f808290505f5b845181101561315e576131498286838151811061313c5761313b614696565b5b60200260200101516132ba565b91508080613156906146c3565b91505061311c565b508091505092915050565b5f805f90507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106131c5577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816131bb576131ba6153a0565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310613202576d04ee2d6d415b85acef810000000083816131f8576131f76153a0565b5b0492506020810190505b662386f26fc10000831061323157662386f26fc100008381613227576132266153a0565b5b0492506010810190505b6305f5e100831061325a576305f5e10083816132505761324f6153a0565b5b0492506008810190505b612710831061327f576127108381613275576132746153a0565b5b0492506004810190505b606483106132a25760648381613298576132976153a0565b5b0492506002810190505b600a83106132b1576001810190505b80915050919050565b5f8183106132d1576132cc82846132e4565b6132dc565b6132db83836132e4565b5b905092915050565b5f825f528160205260405f20905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61333282613309565b9050919050565b61334281613328565b811461334c575f80fd5b50565b5f8135905061335d81613339565b92915050565b5f819050919050565b61337581613363565b811461337f575f80fd5b50565b5f813590506133908161336c565b92915050565b5f80604083850312156133ac576133ab613301565b5b5f6133b98582860161334f565b92505060206133ca85828601613382565b9150509250929050565b6133dd81613363565b82525050565b5f6020820190506133f65f8301846133d4565b92915050565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b613430816133fc565b811461343a575f80fd5b50565b5f8135905061344b81613427565b92915050565b5f6020828403121561346657613465613301565b5b5f6134738482850161343d565b91505092915050565b5f8115159050919050565b6134908161347c565b82525050565b5f6020820190506134a95f830184613487565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156134e65780820151818401526020810190506134cb565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61350b826134af565b61351581856134b9565b93506135258185602086016134c9565b61352e816134f1565b840191505092915050565b5f6020820190508181035f8301526135518184613501565b905092915050565b5f6020828403121561356e5761356d613301565b5b5f61357b84828501613382565b91505092915050565b5f819050919050565b61359681613584565b81146135a0575f80fd5b50565b5f813590506135b18161358d565b92915050565b5f80604083850312156135cd576135cc613301565b5b5f6135da85828601613382565b92505060206135eb858286016135a3565b9150509250929050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f840112613616576136156135f5565b5b8235905067ffffffffffffffff811115613633576136326135f9565b5b60208301915083600182028301111561364f5761364e6135fd565b5b9250929050565b5f805f6040848603121561366d5761366c613301565b5b5f61367a86828701613382565b935050602084013567ffffffffffffffff81111561369b5761369a613305565b5b6136a786828701613601565b92509250509250925092565b5f80604083850312156136c9576136c8613301565b5b5f6136d685828601613382565b92505060206136e785828601613382565b9150509250929050565b600381106136fd575f80fd5b50565b5f8135905061370e816136f1565b92915050565b5f806040838503121561372a57613729613301565b5b5f61373785828601613382565b925050602061374885828601613700565b9150509250929050565b5f8083601f840112613767576137666135f5565b5b8235905067ffffffffffffffff811115613784576137836135f9565b5b6020830191508360208202830111156137a05761379f6135fd565b5b9250929050565b5f805f604084860312156137be576137bd613301565b5b5f6137cb86828701613382565b935050602084013567ffffffffffffffff8111156137ec576137eb613305565b5b6137f886828701613752565b92509250509250925092565b5f8083601f840112613819576138186135f5565b5b8235905067ffffffffffffffff811115613836576138356135f9565b5b602083019150836020820283011115613852576138516135fd565b5b9250929050565b5f8083601f84011261386e5761386d6135f5565b5b8235905067ffffffffffffffff81111561388b5761388a6135f9565b5b6020830191508360018202830111156138a7576138a66135fd565b5b9250929050565b5f805f805f805f8060a0898b0312156138ca576138c9613301565b5b5f6138d78b828c0161334f565b98505060206138e88b828c0161334f565b975050604089013567ffffffffffffffff81111561390957613908613305565b5b6139158b828c01613804565b9650965050606089013567ffffffffffffffff81111561393857613937613305565b5b6139448b828c01613804565b9450945050608089013567ffffffffffffffff81111561396757613966613305565b5b6139738b828c01613859565b92509250509295985092959890939650565b5f8083601f84011261399a576139996135f5565b5b8235905067ffffffffffffffff8111156139b7576139b66135f9565b5b6020830191508360208202830111156139d3576139d26135fd565b5b9250929050565b5f805f604084860312156139f1576139f0613301565b5b5f6139fe86828701613382565b935050602084013567ffffffffffffffff811115613a1f57613a1e613305565b5b613a2b86828701613985565b92509250509250925092565b5f8060408385031215613a4d57613a4c613301565b5b5f613a5a85828601613382565b9250506020613a6b8582860161334f565b9150509250929050565b5f805f8060408587031215613a8d57613a8c613301565b5b5f85013567ffffffffffffffff811115613aaa57613aa9613305565b5b613ab687828801613752565b9450945050602085013567ffffffffffffffff811115613ad957613ad8613305565b5b613ae587828801613804565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b613b2581613363565b82525050565b5f613b368383613b1c565b60208301905092915050565b5f602082019050919050565b5f613b5882613af3565b613b628185613afd565b9350613b6d83613b0d565b805f5b83811015613b9d578151613b848882613b2b565b9750613b8f83613b42565b925050600181019050613b70565b5085935050505092915050565b5f6020820190508181035f830152613bc28184613b4e565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60038110613c0857613c07613bca565b5b50565b5f819050613c1882613bf7565b919050565b5f613c2782613c0b565b9050919050565b613c3781613c1d565b82525050565b5f602082019050613c505f830184613c2e565b92915050565b5f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b613c90826134f1565b810181811067ffffffffffffffff82111715613caf57613cae613c5a565b5b80604052505050565b5f613cc16132f8565b9050613ccd8282613c87565b919050565b5f67ffffffffffffffff821115613cec57613ceb613c5a565b5b613cf5826134f1565b9050602081019050919050565b828183375f83830152505050565b5f613d22613d1d84613cd2565b613cb8565b905082815260208101848484011115613d3e57613d3d613c56565b5b613d49848285613d02565b509392505050565b5f82601f830112613d6557613d646135f5565b5b8135613d75848260208601613d10565b91505092915050565b5f60208284031215613d9357613d92613301565b5b5f82013567ffffffffffffffff811115613db057613daf613305565b5b613dbc84828501613d51565b91505092915050565b613dce81613584565b82525050565b5f602082019050613de75f830184613dc5565b92915050565b613df681613328565b82525050565b5f602082019050613e0f5f830184613ded565b92915050565b5f805f8060608587031215613e2d57613e2c613301565b5b5f613e3a87828801613382565b9450506020613e4b8782880161334f565b935050604085013567ffffffffffffffff811115613e6c57613e6b613305565b5b613e7887828801613985565b925092505092959194509250565b613e8f8161347c565b8114613e99575f80fd5b50565b5f81359050613eaa81613e86565b92915050565b5f8060408385031215613ec657613ec5613301565b5b5f613ed38582860161334f565b9250506020613ee485828601613e9c565b9150509250929050565b5f60208284031215613f0357613f02613301565b5b5f613f108482850161334f565b91505092915050565b5f6040820190508181035f830152613f318185613b4e565b90508181036020830152613f458184613b4e565b90509392505050565b5f8060408385031215613f6457613f63613301565b5b5f613f718582860161334f565b9250506020613f828582860161334f565b9150509250929050565b5f805f805f8060a08789031215613fa657613fa5613301565b5b5f613fb389828a0161334f565b9650506020613fc489828a0161334f565b9550506040613fd589828a01613382565b9450506060613fe689828a01613382565b935050608087013567ffffffffffffffff81111561400757614006613305565b5b61401389828a01613859565b92509250509295509295509295565b5f805f6060848603121561403957614038613301565b5b5f6140468682870161334f565b935050602061405786828701613382565b925050604061406886828701613382565b9150509250925092565b5f805f805f805f60c0888a03121561408d5761408c613301565b5b5f61409a8a828b01613382565b97505060206140ab8a828b01613382565b965050604088013567ffffffffffffffff8111156140cc576140cb613305565b5b6140d88a828b01613601565b955095505060606140eb8a828b016135a3565b93505060806140fc8a828b01613382565b92505060a061410d8a828b01613700565b91505092959891949750929550565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061416057607f821691505b6020821081036141735761417261411c565b5b50919050565b5f82905092915050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026141df7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826141a4565b6141e986836141a4565b95508019841693508086168417925050509392505050565b5f819050919050565b5f61422461421f61421a84613363565b614201565b613363565b9050919050565b5f819050919050565b61423d8361420a565b6142516142498261422b565b8484546141b0565b825550505050565b5f90565b614265614259565b614270818484614234565b505050565b5b81811015614293576142885f8261425d565b600181019050614276565b5050565b601f8211156142d8576142a981614183565b6142b284614195565b810160208510156142c1578190505b6142d56142cd85614195565b830182614275565b50505b505050565b5f82821c905092915050565b5f6142f85f19846008026142dd565b1980831691505092915050565b5f61431083836142e9565b9150826002028217905092915050565b61432a8383614179565b67ffffffffffffffff81111561434357614342613c5a565b5b61434d8254614149565b614358828285614297565b5f601f831160018114614385575f8415614373578287013590505b61437d8582614305565b8655506143e4565b601f19841661439386614183565b5f5b828110156143ba57848901358255600182019150602085019450602081019050614395565b868310156143d757848901356143d3601f8916826142e9565b8355505b6001600288020188555050505b50505050505050565b7f546f6b656e206e6f7420617661696c61626c6520666f72206d696e74696e67005f82015250565b5f614421601f836134b9565b915061442c826143ed565b602082019050919050565b5f6020820190508181035f83015261444e81614415565b9050919050565b7f546f6b656e2069732066726f7a656e00000000000000000000000000000000005f82015250565b5f614489600f836134b9565b915061449482614455565b602082019050919050565b5f6020820190508181035f8301526144b68161447d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6144f482613363565b91506144ff83613363565b9250828201905080821115614517576145166144bd565b5b92915050565b7f45786365656473206d617820737570706c7900000000000000000000000000005f82015250565b5f6145516012836134b9565b915061455c8261451d565b602082019050919050565b5f6020820190508181035f83015261457e81614545565b9050919050565b5f61458f82613363565b915061459a83613363565b92508282026145a881613363565b915082820484148315176145bf576145be6144bd565b5b5092915050565b7f496e73756666696369656e7420666565000000000000000000000000000000005f82015250565b5f6145fa6010836134b9565b9150614605826145c6565b602082019050919050565b5f6020820190508181035f830152614627816145ee565b9050919050565b7f546f6b656e2066726f7a656e00000000000000000000000000000000000000005f82015250565b5f614662600c836134b9565b915061466d8261462e565b602082019050919050565b5f6020820190508181035f83015261468f81614656565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6146cd82613363565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036146ff576146fe6144bd565b5b600182019050919050565b7f4c454e4754485f4d49534d4154434800000000000000000000000000000000005f82015250565b5f61473e600f836134b9565b91506147498261470a565b602082019050919050565b5f6020820190508181035f83015261476b81614732565b9050919050565b7f4e4f545f415554484f52495a45440000000000000000000000000000000000005f82015250565b5f6147a6600e836134b9565b91506147b182614772565b602082019050919050565b5f6020820190508181035f8301526147d38161479a565b9050919050565b5f6147e482613363565b91506147ef83613363565b9250828203905081811115614807576148066144bd565b5b92915050565b5f80fd5b82818337505050565b5f6148258385613afd565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8311156148585761485761480d565b5b602083029250614869838584614811565b82840190509392505050565b5f6040820190508181035f83015261488e81868861481a565b905081810360208301526148a381848661481a565b905095945050505050565b5f82825260208201905092915050565b5f6148c983856148ae565b93506148d6838584613d02565b6148df836134f1565b840190509392505050565b5f60a0820190506148fd5f83018b613ded565b61490a602083018a613ded565b818103604083015261491d81888a61481a565b9050818103606083015261493281868861481a565b905081810360808301526149478184866148be565b90509998505050505050505050565b5f8151905061496481613427565b92915050565b5f6020828403121561497f5761497e613301565b5b5f61498c84828501614956565b91505092915050565b7f554e534146455f524543495049454e54000000000000000000000000000000005f82015250565b5f6149c96010836134b9565b91506149d482614995565b602082019050919050565b5f6020820190508181035f8301526149f6816149bd565b9050919050565b7f546f6b656e206e6f7420617661696c61626c6520666f7220636c61696d696e675f82015250565b5f614a316020836134b9565b9150614a3c826149fd565b602082019050919050565b5f6020820190508181035f830152614a5e81614a25565b9050919050565b7f4e465420616c726561647920636c61696d6564000000000000000000000000005f82015250565b5f614a996013836134b9565b9150614aa482614a65565b602082019050919050565b5f6020820190508181035f830152614ac681614a8d565b9050919050565b7f4d617820737570706c79207265616368656400000000000000000000000000005f82015250565b5f614b016012836134b9565b9150614b0c82614acd565b602082019050919050565b5f6020820190508181035f830152614b2e81614af5565b9050919050565b5f8160601b9050919050565b5f614b4b82614b35565b9050919050565b5f614b5c82614b41565b9050919050565b614b74614b6f82613328565b614b52565b82525050565b5f614b858284614b63565b60148201915081905092915050565b7f496e76616c69642070726f6f66000000000000000000000000000000000000005f82015250565b5f614bc8600d836134b9565b9150614bd382614b94565b602082019050919050565b5f6020820190508181035f830152614bf581614bbc565b9050919050565b5f819050919050565b5f614c1f614c1a614c1584614bfc565b614201565b613363565b9050919050565b614c2f81614c05565b82525050565b5f602082019050614c485f830184614c26565b92915050565b614c57826134af565b67ffffffffffffffff811115614c7057614c6f613c5a565b5b614c7a8254614149565b614c85828285614297565b5f60209050601f831160018114614cb6575f8415614ca4578287015190505b614cae8582614305565b865550614d15565b601f198416614cc486614183565b5f5b82811015614ceb57848901518255600182019150602085019450602081019050614cc6565b86831015614d085784890151614d04601f8916826142e9565b8355505b6001600288020188555050505b505050505050565b7f62617365555249206e6f742073657400000000000000000000000000000000005f82015250565b5f614d51600f836134b9565b9150614d5c82614d1d565b602082019050919050565b5f6020820190508181035f830152614d7e81614d45565b9050919050565b5f81905092915050565b5f8154614d9b81614149565b614da58186614d85565b9450600182165f8114614dbf5760018114614dd457614e06565b60ff1983168652811515820286019350614e06565b614ddd85614183565b5f5b83811015614dfe57815481890152600182019150602081019050614ddf565b838801955050505b50505092915050565b5f614e19826134af565b614e238185614d85565b9350614e338185602086016134c9565b80840191505092915050565b7f2e6a736f6e0000000000000000000000000000000000000000000000000000005f82015250565b5f614e73600583614d85565b9150614e7e82614e3f565b600582019050919050565b5f614e948285614d8f565b9150614ea08284614e0f565b9150614eab82614e67565b91508190509392505050565b7f4e6f2045544820746f20776974686472617700000000000000000000000000005f82015250565b5f614eeb6012836134b9565b9150614ef682614eb7565b602082019050919050565b5f6020820190508181035f830152614f1881614edf565b9050919050565b7f494420616c72656164792066726f7a656e0000000000000000000000000000005f82015250565b5f614f536011836134b9565b9150614f5e82614f1f565b602082019050919050565b5f6020820190508181035f830152614f8081614f47565b9050919050565b7f4e6f742077686974656c697374656400000000000000000000000000000000005f82015250565b5f614fbb600f836134b9565b9150614fc682614f87565b602082019050919050565b5f6020820190508181035f830152614fe881614faf565b9050919050565b7f416c726561647920636c61696d656400000000000000000000000000000000005f82015250565b5f615023600f836134b9565b915061502e82614fef565b602082019050919050565b5f6020820190508181035f83015261505081615017565b9050919050565b5f60408201905061506a5f8301856133d4565b61507760208301846133d4565b9392505050565b5f60a0820190506150915f830189613ded565b61509e6020830188613ded565b6150ab60408301876133d4565b6150b860608301866133d4565b81810360808301526150cb8184866148be565b9050979650505050505050565b7f43616c6c6572206973206e6f74206f776e6572206e6f7220617070726f7665645f82015250565b5f61510c6020836134b9565b9150615117826150d8565b602082019050919050565b5f6020820190508181035f83015261513981615100565b9050919050565b7f4275726e20616d6f756e7420657863656564732062616c616e636500000000005f82015250565b5f615174601b836134b9565b915061517f82615140565b602082019050919050565b5f6020820190508181035f8301526151a181615168565b9050919050565b7f555249206d7573742062652073657400000000000000000000000000000000005f82015250565b5f6151dc600f836134b9565b91506151e7826151a8565b602082019050919050565b5f6020820190508181035f830152615209816151d0565b9050919050565b7f496e697469616c20616d6f756e742063616e6e6f7420657863656564206d61785f8201527f20737570706c7900000000000000000000000000000000000000000000000000602082015250565b5f61526a6027836134b9565b915061527582615210565b604082019050919050565b5f6020820190508181035f8301526152978161525e565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c005f82015250565b5f6152d2601f836134b9565b91506152dd8261529e565b602082019050919050565b5f6020820190508181035f8301526152ff816152c6565b9050919050565b5f81519050919050565b5f61531a82615306565b61532481856148ae565b93506153348185602086016134c9565b61533d816134f1565b840191505092915050565b5f60a08201905061535b5f830188613ded565b6153686020830187613ded565b61537560408301866133d4565b61538260608301856133d4565b81810360808301526153948184615310565b90509695505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffdfea26469706673582212203308cc927bb7d837b8b0def943e234ae7a0ada6206ea1b60272533c1de09fe4c64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000006942013379d195323e17cd2616435dce819c1fa9000000000000000000000000000000000000000000000000000000000000001050657065636f696e2078204672656e7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f50455045434f494e434f4c4c4142530000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): Pepecoin x Frens
Arg [1] : symbol_ (string): PEPECOINCOLLABS
Arg [2] : initialOwner (address): 0x6942013379d195323E17CD2616435DcE819c1fA9
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000006942013379d195323e17cd2616435dce819c1fa9
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [4] : 50657065636f696e2078204672656e7300000000000000000000000000000000
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [6] : 50455045434f494e434f4c4c4142530000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.