Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
PublicResolver
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity >=0.8.4; import "../registry/NNS.sol"; import "./profiles/ABIResolver.sol"; import "./profiles/AddrResolver.sol"; import "./profiles/ContentHashResolver.sol"; import "./profiles/DNSResolver.sol"; import "./profiles/InterfaceResolver.sol"; import "./profiles/NameResolver.sol"; import "./profiles/PubkeyResolver.sol"; import "./profiles/TextResolver.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; interface INameWrapper { function ownerOf(uint256 id) external view returns (address); } /** * A simple resolver anyone can use; only allows the owner of a node to set its * address. */ contract PublicResolver is Initializable,ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver { NNS nns; INameWrapper nameWrapper; /** * A mapping of operators. An address that is authorised for an address * may make any changes to the name that the owner could, but may not update * the set of authorisations. * (owner, operator) => approved */ mapping(address => mapping(address => bool)) private _operatorApprovals; // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function __PublicResolver_i(NNS _nns, INameWrapper wrapperAddress) public initializer { __PublicResolver_init(_nns,wrapperAddress); } function __PublicResolver_init(NNS _nns, INameWrapper wrapperAddress) internal onlyInitializing { __PublicResolver_init_unchained(_nns,wrapperAddress); } function __PublicResolver_init_unchained(NNS _nns, INameWrapper wrapperAddress) internal onlyInitializing { nns = _nns; nameWrapper = wrapperAddress; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) external{ require( msg.sender != operator, "ERC1155: setting approval status for self" ); _operatorApprovals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function isAuthorised(bytes32 node) internal override view returns(bool) { address owner = nns.owner(node); if(owner == address(nameWrapper) ){ owner = nameWrapper.ownerOf(uint256(node)); } return owner == msg.sender || isApprovedForAll(owner, msg.sender); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view returns (bool){ return _operatorApprovals[account][operator]; } function multicall(bytes[] calldata data) external returns(bytes[] memory results) { results = new bytes[](data.length); for(uint i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); require(success); results[i] = result; } return results; } function supportsInterface(bytes4 interfaceID) virtual override(ABIResolver, AddrResolver, ContentHashResolver, DNSResolver, InterfaceResolver, NameResolver, PubkeyResolver, TextResolver) public pure returns(bool) { return super.supportsInterface(interfaceID); } }
pragma solidity ^0.8.4; /** * @dev A library for working with mutable byte buffers in Solidity. * * Byte buffers are mutable and expandable, and provide a variety of primitives * for writing to them. At any time you can fetch a bytes object containing the * current contents of the buffer. The bytes object should not be stored between * operations, as it may change due to resizing of the buffer. */ library Buffer { /** * @dev Represents a mutable buffer. Buffers have a current value (buf) and * a capacity. The capacity may be longer than the current value, in * which case it can be extended without the need to allocate more memory. */ struct buffer { bytes buf; uint capacity; } /** * @dev Initializes a buffer with an initial capacity. * @param buf The buffer to initialize. * @param capacity The number of bytes of space to allocate the buffer. * @return The buffer, for chaining. */ function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) { if (capacity % 32 != 0) { capacity += 32 - (capacity % 32); } // Allocate space for the buffer data buf.capacity = capacity; assembly { let ptr := mload(0x40) mstore(buf, ptr) mstore(ptr, 0) mstore(0x40, add(32, add(ptr, capacity))) } return buf; } /** * @dev Initializes a new buffer from an existing bytes object. * Changes to the buffer may mutate the original value. * @param b The bytes object to initialize the buffer with. * @return A new buffer. */ function fromBytes(bytes memory b) internal pure returns(buffer memory) { buffer memory buf; buf.buf = b; buf.capacity = b.length; return buf; } function resize(buffer memory buf, uint capacity) private pure { bytes memory oldbuf = buf.buf; init(buf, capacity); append(buf, oldbuf); } function max(uint a, uint b) private pure returns(uint) { if (a > b) { return a; } return b; } /** * @dev Sets buffer length to 0. * @param buf The buffer to truncate. * @return The original buffer, for chaining.. */ function truncate(buffer memory buf) internal pure returns (buffer memory) { assembly { let bufptr := mload(buf) mstore(bufptr, 0) } return buf; } /** * @dev Writes a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The start offset to write to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes memory data, uint len) internal pure returns(buffer memory) { require(len <= data.length); if (off + len > buf.capacity) { resize(buf, max(buf.capacity, len + off) * 2); } uint dest; uint src; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Start address = buffer address + offset + sizeof(buffer length) dest := add(add(bufptr, 32), off) // Update buffer length if we're extending it if gt(add(len, off), buflen) { mstore(bufptr, add(len, off)) } src := add(data, 32) } // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } return buf; } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @param len The number of bytes to copy. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data, uint len) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, len); } /** * @dev Appends a byte string to a buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, data.length); } /** * @dev Writes a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write the byte at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeUint8(buffer memory buf, uint off, uint8 data) internal pure returns(buffer memory) { if (off >= buf.capacity) { resize(buf, buf.capacity * 2); } assembly { // Memory address of the buffer data let bufptr := mload(buf) // Length of existing buffer data let buflen := mload(bufptr) // Address = buffer address + sizeof(buffer length) + off let dest := add(add(bufptr, off), 32) mstore8(dest, data) // Update buffer length if we extended it if eq(off, buflen) { mstore(bufptr, add(buflen, 1)) } } return buf; } /** * @dev Appends a byte to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) { return writeUint8(buf, buf.buf.length, data); } /** * @dev Writes up to 32 bytes to the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (left-aligned). * @return The original buffer, for chaining. */ function write(buffer memory buf, uint off, bytes32 data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } unchecked { uint mask = (256 ** len) - 1; // Right-align data data = data >> (8 * (32 - len)); assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + sizeof(buffer length) + off + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } } return buf; } /** * @dev Writes a bytes20 to the buffer. Resizes if doing so would exceed the * capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @return The original buffer, for chaining. */ function writeBytes20(buffer memory buf, uint off, bytes20 data) internal pure returns (buffer memory) { return write(buf, off, bytes32(data), 20); } /** * @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chhaining. */ function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, bytes32(data), 20); } /** * @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer, for chaining. */ function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) { return write(buf, buf.buf.length, data, 32); } /** * @dev Writes an integer to the buffer. Resizes if doing so would exceed * the capacity of the buffer. * @param buf The buffer to append to. * @param off The offset to write at. * @param data The data to append. * @param len The number of bytes to write (right-aligned). * @return The original buffer, for chaining. */ function writeInt(buffer memory buf, uint off, uint data, uint len) private pure returns(buffer memory) { if (len + off > buf.capacity) { resize(buf, (len + off) * 2); } uint mask = (256 ** len) - 1; assembly { // Memory address of the buffer data let bufptr := mload(buf) // Address = buffer address + off + sizeof(buffer length) + len let dest := add(add(bufptr, off), len) mstore(dest, or(and(mload(dest), not(mask)), data)) // Update buffer length if we extended it if gt(add(off, len), mload(bufptr)) { mstore(bufptr, add(off, len)) } } return buf; } /** * @dev Appends a byte to the end of the buffer. Resizes if doing so would * exceed the capacity of the buffer. * @param buf The buffer to append to. * @param data The data to append. * @return The original buffer. */ function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) { return writeInt(buf, buf.buf.length, data, len); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
pragma solidity >=0.8.4; abstract contract ResolverBase { bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7; function supportsInterface(bytes4 interfaceID) virtual public pure returns(bool) { return interfaceID == INTERFACE_META_ID; } function isAuthorised(bytes32 node) internal virtual view returns(bool); modifier authorised(bytes32 node) { require(isAuthorised(node)); _; } function bytesToAddress(bytes memory b) internal pure returns(address payable a) { require(b.length == 20); assembly { a := div(mload(add(b, 32)), exp(256, 12)) } } function addressToBytes(address a) internal pure returns(bytes memory b) { b = new bytes(20); assembly { mstore(add(b, 32), mul(a, exp(256, 12))) } } }
pragma solidity ^0.8.4; library BytesUtils { /* * @dev Returns the keccak-256 hash of a byte range. * @param self The byte string to hash. * @param offset The position to start hashing at. * @param len The number of bytes to hash. * @return The hash of the byte range. */ function keccak(bytes memory self, uint offset, uint len) internal pure returns (bytes32 ret) { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) } } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. * @param self The first bytes to compare. * @param other The second bytes to compare. * @return The result of the comparison. */ function compare(bytes memory self, bytes memory other) internal pure returns (int) { return compare(self, 0, self.length, other, 0, other.length); } /* * @dev Returns a positive number if `other` comes lexicographically after * `self`, a negative number if it comes before, or zero if the * contents of the two bytes are equal. Comparison is done per-rune, * on unicode codepoints. * @param self The first bytes to compare. * @param offset The offset of self. * @param len The length of self. * @param other The second bytes to compare. * @param otheroffset The offset of the other string. * @param otherlen The length of the other string. * @return The result of the comparison. */ function compare(bytes memory self, uint offset, uint len, bytes memory other, uint otheroffset, uint otherlen) internal pure returns (int) { uint shortest = len; if (otherlen < len) shortest = otherlen; uint selfptr; uint otherptr; assembly { selfptr := add(self, add(offset, 32)) otherptr := add(other, add(otheroffset, 32)) } for (uint idx = 0; idx < shortest; idx += 32) { uint a; uint b; assembly { a := mload(selfptr) b := mload(otherptr) } if (a != b) { // Mask out irrelevant bytes and check again uint mask; if (shortest > 32) { mask = type(uint256).max; } else { mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); } int diff = int(a & mask) - int(b & mask); if (diff != 0) return diff; } selfptr += 32; otherptr += 32; } return int(len) - int(otherlen); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @param len The number of bytes to compare * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset, uint len) internal pure returns (bool) { return keccak(self, offset, len) == keccak(other, otherOffset, len); } /* * @dev Returns true if the two byte ranges are equal with offsets. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @param otherOffset The offset into the second byte range. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other, uint otherOffset) internal pure returns (bool) { return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); } /* * @dev Compares a range of 'self' to all of 'other' and returns True iff * they are equal. * @param self The first byte range to compare. * @param offset The offset into the first byte range. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, uint offset, bytes memory other) internal pure returns (bool) { return self.length >= offset + other.length && equals(self, offset, other, 0, other.length); } /* * @dev Returns true if the two byte ranges are equal. * @param self The first byte range to compare. * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ function equals(bytes memory self, bytes memory other) internal pure returns(bool) { return self.length == other.length && equals(self, 0, other, 0, self.length); } /* * @dev Returns the 8-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 8 bits of the string, interpreted as an integer. */ function readUint8(bytes memory self, uint idx) internal pure returns (uint8 ret) { return uint8(self[idx]); } /* * @dev Returns the 16-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 16 bits of the string, interpreted as an integer. */ function readUint16(bytes memory self, uint idx) internal pure returns (uint16 ret) { require(idx + 2 <= self.length); assembly { ret := and(mload(add(add(self, 2), idx)), 0xFFFF) } } /* * @dev Returns the 32-bit number at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bits of the string, interpreted as an integer. */ function readUint32(bytes memory self, uint idx) internal pure returns (uint32 ret) { require(idx + 4 <= self.length); assembly { ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes32(bytes memory self, uint idx) internal pure returns (bytes32 ret) { require(idx + 32 <= self.length); assembly { ret := mload(add(add(self, 32), idx)) } } /* * @dev Returns the 32 byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes * @return The specified 32 bytes of the string. */ function readBytes20(bytes memory self, uint idx) internal pure returns (bytes20 ret) { require(idx + 20 <= self.length); assembly { ret := and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) } } /* * @dev Returns the n byte value at the specified index of self. * @param self The byte string. * @param idx The index into the bytes. * @param len The number of bytes. * @return The specified 32 bytes of the string. */ function readBytesN(bytes memory self, uint idx, uint len) internal pure returns (bytes32 ret) { require(len <= 32); require(idx + len <= self.length); assembly { let mask := not(sub(exp(256, sub(32, len)), 1)) ret := and(mload(add(add(self, 32), idx)), mask) } } function memcpy(uint dest, uint src, uint len) private pure { // Copy word-length chunks while possible for (; len >= 32; len -= 32) { assembly { mstore(dest, mload(src)) } dest += 32; src += 32; } // Copy remaining bytes unchecked { uint mask = (256 ** (32 - len)) - 1; assembly { let srcpart := and(mload(src), not(mask)) let destpart := and(mload(dest), mask) mstore(dest, or(destpart, srcpart)) } } } /* * @dev Copies a substring into a new byte string. * @param self The byte string to copy from. * @param offset The offset to start copying at. * @param len The number of bytes to copy. */ function substring(bytes memory self, uint offset, uint len) internal pure returns(bytes memory) { require(offset + len <= self.length); bytes memory ret = new bytes(len); uint dest; uint src; assembly { dest := add(ret, 32) src := add(add(self, 32), offset) } memcpy(dest, src, len); return ret; } // Maps characters from 0x30 to 0x7A to their base32 values. // 0xFF represents invalid characters in that range. bytes constant base32HexTable = hex'00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F'; /** * @dev Decodes unpadded base32 data of up to one word in length. * @param self The data to decode. * @param off Offset into the string to start at. * @param len Number of characters to decode. * @return The decoded data, left aligned. */ function base32HexDecodeWord(bytes memory self, uint off, uint len) internal pure returns(bytes32) { require(len <= 52); uint ret = 0; uint8 decoded; for(uint i = 0; i < len; i++) { bytes1 char = self[off + i]; require(char >= 0x30 && char <= 0x7A); decoded = uint8(base32HexTable[uint(uint8(char)) - 0x30]); require(decoded <= 0x20); if(i == len - 1) { break; } ret = (ret << 5) | decoded; } uint bitlen = len * 5; if(len % 8 == 0) { // Multiple of 8 characters, no padding ret = (ret << 5) | decoded; } else if(len % 8 == 2) { // Two extra characters - 1 byte ret = (ret << 3) | (decoded >> 2); bitlen -= 2; } else if(len % 8 == 4) { // Four extra characters - 2 bytes ret = (ret << 1) | (decoded >> 4); bitlen -= 4; } else if(len % 8 == 5) { // Five extra characters - 3 bytes ret = (ret << 4) | (decoded >> 1); bitlen -= 1; } else if(len % 8 == 7) { // Seven extra characters - 4 bytes ret = (ret << 2) | (decoded >> 3); bitlen -= 3; } else { revert(); } return bytes32(ret << (256 - bitlen)); } }
pragma solidity ^0.8.4; import "./BytesUtils.sol"; import "@ensdomains/buffer/contracts/Buffer.sol"; /** * @dev RRUtils is a library that provides utilities for parsing DNS resource records. */ library RRUtils { using BytesUtils for *; using Buffer for *; /** * @dev Returns the number of bytes in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The length of the DNS name at 'offset', in bytes. */ function nameLength(bytes memory self, uint offset) internal pure returns(uint) { uint idx = offset; while (true) { assert(idx < self.length); uint labelLen = self.readUint8(idx); idx += labelLen + 1; if (labelLen == 0) { break; } } return idx - offset; } /** * @dev Returns a DNS format name at the specified offset of self. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return ret The name. */ function readName(bytes memory self, uint offset) internal pure returns(bytes memory ret) { uint len = nameLength(self, offset); return self.substring(offset, len); } /** * @dev Returns the number of labels in the DNS name at 'offset' in 'self'. * @param self The byte array to read a name from. * @param offset The offset to start reading at. * @return The number of labels in the DNS name at 'offset', in bytes. */ function labelCount(bytes memory self, uint offset) internal pure returns(uint) { uint count = 0; while (true) { assert(offset < self.length); uint labelLen = self.readUint8(offset); offset += labelLen + 1; if (labelLen == 0) { break; } count += 1; } return count; } uint constant RRSIG_TYPE = 0; uint constant RRSIG_ALGORITHM = 2; uint constant RRSIG_LABELS = 3; uint constant RRSIG_TTL = 4; uint constant RRSIG_EXPIRATION = 8; uint constant RRSIG_INCEPTION = 12; uint constant RRSIG_KEY_TAG = 16; uint constant RRSIG_SIGNER_NAME = 18; struct SignedSet { uint16 typeCovered; uint8 algorithm; uint8 labels; uint32 ttl; uint32 expiration; uint32 inception; uint16 keytag; bytes signerName; bytes data; bytes name; } function readSignedSet(bytes memory data) internal pure returns(SignedSet memory self) { self.typeCovered = data.readUint16(RRSIG_TYPE); self.algorithm = data.readUint8(RRSIG_ALGORITHM); self.labels = data.readUint8(RRSIG_LABELS); self.ttl = data.readUint32(RRSIG_TTL); self.expiration = data.readUint32(RRSIG_EXPIRATION); self.inception = data.readUint32(RRSIG_INCEPTION); self.keytag = data.readUint16(RRSIG_KEY_TAG); self.signerName = readName(data, RRSIG_SIGNER_NAME); self.data = data.substring(RRSIG_SIGNER_NAME + self.signerName.length, data.length - RRSIG_SIGNER_NAME - self.signerName.length); } function rrs(SignedSet memory rrset) internal pure returns(RRIterator memory) { return iterateRRs(rrset.data, 0); } /** * @dev An iterator over resource records. */ struct RRIterator { bytes data; uint offset; uint16 dnstype; uint16 class; uint32 ttl; uint rdataOffset; uint nextOffset; } /** * @dev Begins iterating over resource records. * @param self The byte string to read from. * @param offset The offset to start reading at. * @return ret An iterator object. */ function iterateRRs(bytes memory self, uint offset) internal pure returns (RRIterator memory ret) { ret.data = self; ret.nextOffset = offset; next(ret); } /** * @dev Returns true iff there are more RRs to iterate. * @param iter The iterator to check. * @return True iff the iterator has finished. */ function done(RRIterator memory iter) internal pure returns(bool) { return iter.offset >= iter.data.length; } /** * @dev Moves the iterator to the next resource record. * @param iter The iterator to advance. */ function next(RRIterator memory iter) internal pure { iter.offset = iter.nextOffset; if (iter.offset >= iter.data.length) { return; } // Skip the name uint off = iter.offset + nameLength(iter.data, iter.offset); // Read type, class, and ttl iter.dnstype = iter.data.readUint16(off); off += 2; iter.class = iter.data.readUint16(off); off += 2; iter.ttl = iter.data.readUint32(off); off += 4; // Read the rdata uint rdataLength = iter.data.readUint16(off); off += 2; iter.rdataOffset = off; iter.nextOffset = off + rdataLength; } /** * @dev Returns the name of the current record. * @param iter The iterator. * @return A new bytes object containing the owner name from the RR. */ function name(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.offset, nameLength(iter.data, iter.offset)); } /** * @dev Returns the rdata portion of the current record. * @param iter The iterator. * @return A new bytes object containing the RR's RDATA. */ function rdata(RRIterator memory iter) internal pure returns(bytes memory) { return iter.data.substring(iter.rdataOffset, iter.nextOffset - iter.rdataOffset); } uint constant DNSKEY_FLAGS = 0; uint constant DNSKEY_PROTOCOL = 2; uint constant DNSKEY_ALGORITHM = 3; uint constant DNSKEY_PUBKEY = 4; struct DNSKEY { uint16 flags; uint8 protocol; uint8 algorithm; bytes publicKey; } function readDNSKEY(bytes memory data, uint offset, uint length) internal pure returns(DNSKEY memory self) { self.flags = data.readUint16(offset + DNSKEY_FLAGS); self.protocol = data.readUint8(offset + DNSKEY_PROTOCOL); self.algorithm = data.readUint8(offset + DNSKEY_ALGORITHM); self.publicKey = data.substring(offset + DNSKEY_PUBKEY, length - DNSKEY_PUBKEY); } uint constant DS_KEY_TAG = 0; uint constant DS_ALGORITHM = 2; uint constant DS_DIGEST_TYPE = 3; uint constant DS_DIGEST = 4; struct DS { uint16 keytag; uint8 algorithm; uint8 digestType; bytes digest; } function readDS(bytes memory data, uint offset, uint length) internal pure returns(DS memory self) { self.keytag = data.readUint16(offset + DS_KEY_TAG); self.algorithm = data.readUint8(offset + DS_ALGORITHM); self.digestType = data.readUint8(offset + DS_DIGEST_TYPE); self.digest = data.substring(offset + DS_DIGEST, length - DS_DIGEST); } struct NSEC3 { uint8 hashAlgorithm; uint8 flags; uint16 iterations; bytes salt; bytes32 nextHashedOwnerName; bytes typeBitmap; } uint constant NSEC3_HASH_ALGORITHM = 0; uint constant NSEC3_FLAGS = 1; uint constant NSEC3_ITERATIONS = 2; uint constant NSEC3_SALT_LENGTH = 4; uint constant NSEC3_SALT = 5; function readNSEC3(bytes memory data, uint offset, uint length) internal pure returns(NSEC3 memory self) { uint end = offset + length; self.hashAlgorithm = data.readUint8(offset + NSEC3_HASH_ALGORITHM); self.flags = data.readUint8(offset + NSEC3_FLAGS); self.iterations = data.readUint16(offset + NSEC3_ITERATIONS); uint8 saltLength = data.readUint8(offset + NSEC3_SALT_LENGTH); offset = offset + NSEC3_SALT; self.salt = data.substring(offset, saltLength); offset += saltLength; uint8 nextLength = data.readUint8(offset); require(nextLength <= 32); offset += 1; self.nextHashedOwnerName = data.readBytesN(offset, nextLength); offset += nextLength; self.typeBitmap = data.substring(offset, end - offset); } function checkTypeBitmap(NSEC3 memory self, uint16 rrtype) internal pure returns(bool) { return checkTypeBitmap(self.typeBitmap, 0, rrtype); } /** * @dev Checks if a given RR type exists in a type bitmap. * @param bitmap The byte string to read the type bitmap from. * @param offset The offset to start reading at. * @param rrtype The RR type to check for. * @return True if the type is found in the bitmap, false otherwise. */ function checkTypeBitmap(bytes memory bitmap, uint offset, uint16 rrtype) internal pure returns (bool) { uint8 typeWindow = uint8(rrtype >> 8); uint8 windowByte = uint8((rrtype & 0xff) / 8); uint8 windowBitmask = uint8(uint8(1) << (uint8(7) - uint8(rrtype & 0x7))); for (uint off = offset; off < bitmap.length;) { uint8 window = bitmap.readUint8(off); uint8 len = bitmap.readUint8(off + 1); if (typeWindow < window) { // We've gone past our window; it's not here. return false; } else if (typeWindow == window) { // Check this type bitmap if (len <= windowByte) { // Our type is past the end of the bitmap return false; } return (bitmap.readUint8(off + windowByte + 2) & windowBitmask) != 0; } else { // Skip this type bitmap off += len + 2; } } return false; } function compareNames(bytes memory self, bytes memory other) internal pure returns (int) { if (self.equals(other)) { return 0; } uint off; uint otheroff; uint prevoff; uint otherprevoff; uint counts = labelCount(self, 0); uint othercounts = labelCount(other, 0); // Keep removing labels from the front of the name until both names are equal length while (counts > othercounts) { prevoff = off; off = progress(self, off); counts--; } while (othercounts > counts) { otherprevoff = otheroff; otheroff = progress(other, otheroff); othercounts--; } // Compare the last nonequal labels to each other while (counts > 0 && !self.equals(off, other, otheroff)) { prevoff = off; off = progress(self, off); otherprevoff = otheroff; otheroff = progress(other, otheroff); counts -= 1; } if (off == 0) { return -1; } if(otheroff == 0) { return 1; } return self.compare(prevoff + 1, self.readUint8(prevoff), other, otherprevoff + 1, other.readUint8(otherprevoff)); } /** * @dev Compares two serial numbers using RFC1982 serial number math. */ function serialNumberGte(uint32 i1, uint32 i2) internal pure returns(bool) { return int32(i1) - int32(i2) >= 0; } function progress(bytes memory body, uint off) internal pure returns(uint) { return off + 1 + body.readUint8(off); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract ABIResolver is ResolverBase { bytes4 constant private ABI_INTERFACE_ID = 0x2203ab56; event ABIChanged(bytes32 indexed node, uint256 indexed contentType); mapping(bytes32=>mapping(uint256=>bytes)) abis; /** * Sets the ABI associated with an ENS node. * Nodes may have one ABI of each content type. To remove an ABI, set it to * the empty string. * @param node The node to update. * @param contentType The content type of the ABI * @param data The ABI data. */ function setABI(bytes32 node, uint256 contentType, bytes calldata data) external authorised(node) { // Content types must be powers of 2 require(((contentType - 1) & contentType) == 0); abis[node][contentType] = data; emit ABIChanged(node, contentType); } /** * Returns the ABI associated with an ENS node. * Defined in EIP205. * @param node The ENS node to query * @param contentTypes A bitwise OR of the ABI formats accepted by the caller. * @return contentType The content type of the return value * @return data The ABI data */ function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory) { mapping(uint256=>bytes) storage abiset = abis[node]; for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) { if ((contentType & contentTypes) != 0 && abiset[contentType].length > 0) { return (contentType, abiset[contentType]); } } return (0, bytes("")); } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == ABI_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract AddrResolver is ResolverBase { bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de; bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06; uint constant private COIN_TYPE_ETH = 60; event AddrChanged(bytes32 indexed node, address a); event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress); mapping(bytes32=>mapping(uint=>bytes)) _addresses; /** * Sets the address associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param a The address to set. */ function setAddr(bytes32 node, address a) external authorised(node) { setAddr(node, COIN_TYPE_ETH, addressToBytes(a)); } /** * Returns the address associated with an ENS node. * @param node The ENS node to query. * @return The associated address. */ function addr(bytes32 node) public view returns (address payable) { bytes memory a = addr(node, COIN_TYPE_ETH); if(a.length == 0) { return payable(0); } return bytesToAddress(a); } function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) { emit AddressChanged(node, coinType, a); if(coinType == COIN_TYPE_ETH) { emit AddrChanged(node, bytesToAddress(a)); } _addresses[node][coinType] = a; } function addr(bytes32 node, uint coinType) public view returns(bytes memory) { return _addresses[node][coinType]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract ContentHashResolver is ResolverBase { bytes4 constant private CONTENT_HASH_INTERFACE_ID = 0xbc1c58d1; event ContenthashChanged(bytes32 indexed node, bytes hash); mapping(bytes32=>bytes) hashes; /** * Sets the contenthash associated with an ENS node. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The contenthash to set */ function setContenthash(bytes32 node, bytes calldata hash) external authorised(node) { hashes[node] = hash; emit ContenthashChanged(node, hash); } /** * Returns the contenthash associated with an ENS node. * @param node The ENS node to query. * @return The associated contenthash. */ function contenthash(bytes32 node) external view returns (bytes memory) { return hashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == CONTENT_HASH_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "../../dnssec-oracle/RRUtils.sol"; abstract contract DNSResolver is ResolverBase { using RRUtils for *; using BytesUtils for bytes; bytes4 constant private DNS_RECORD_INTERFACE_ID = 0xa8fa5682; bytes4 constant private DNS_ZONE_INTERFACE_ID = 0x5c47637c; // DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated. event DNSRecordChanged(bytes32 indexed node, bytes name, uint16 resource, bytes record); // DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted. event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource); // DNSZoneCleared is emitted whenever a given node's zone information is cleared. event DNSZoneCleared(bytes32 indexed node); // DNSZonehashChanged is emitted whenever a given node's zone hash is updated. event DNSZonehashChanged(bytes32 indexed node, bytes lastzonehash, bytes zonehash); // Zone hashes for the domains. // A zone hash is an EIP-1577 content hash in binary format that should point to a // resource containing a single zonefile. // node => contenthash mapping(bytes32=>bytes) private zonehashes; // Version the mapping for each zone. This allows users who have lost // track of their entries to effectively delete an entire zone by bumping // the version number. // node => version mapping(bytes32=>uint256) private versions; // The records themselves. Stored as binary RRSETs // node => version => name => resource => data mapping(bytes32=>mapping(uint256=>mapping(bytes32=>mapping(uint16=>bytes)))) private records; // Count of number of entries for a given name. Required for DNS resolvers // when resolving wildcards. // node => version => name => number of records mapping(bytes32=>mapping(uint256=>mapping(bytes32=>uint16))) private nameEntriesCount; /** * Set one or more DNS records. Records are supplied in wire-format. * Records with the same node/name/resource must be supplied one after the * other to ensure the data is updated correctly. For example, if the data * was supplied: * a.example.com IN A 1.2.3.4 * a.example.com IN A 5.6.7.8 * www.example.com IN CNAME a.example.com. * then this would store the two A records for a.example.com correctly as a * single RRSET, however if the data was supplied: * a.example.com IN A 1.2.3.4 * www.example.com IN CNAME a.example.com. * a.example.com IN A 5.6.7.8 * then this would store the first A record, the CNAME, then the second A * record which would overwrite the first. * * @param node the namehash of the node for which to set the records * @param data the DNS wire format records to set */ function setDNSRecords(bytes32 node, bytes calldata data) external authorised(node) { uint16 resource = 0; uint256 offset = 0; bytes memory name; bytes memory value; bytes32 nameHash; // Iterate over the data to add the resource records for (RRUtils.RRIterator memory iter = data.iterateRRs(0); !iter.done(); iter.next()) { if (resource == 0) { resource = iter.dnstype; name = iter.name(); nameHash = keccak256(abi.encodePacked(name)); value = bytes(iter.rdata()); } else { bytes memory newName = iter.name(); if (resource != iter.dnstype || !name.equals(newName)) { setDNSRRSet(node, name, resource, data, offset, iter.offset - offset, value.length == 0); resource = iter.dnstype; offset = iter.offset; name = newName; nameHash = keccak256(name); value = bytes(iter.rdata()); } } } if (name.length > 0) { setDNSRRSet(node, name, resource, data, offset, data.length - offset, value.length == 0); } } /** * Obtain a DNS record. * @param node the namehash of the node for which to fetch the record * @param name the keccak-256 hash of the fully-qualified name for which to fetch the record * @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types * @return the DNS record in wire format if present, otherwise empty */ function dnsRecord(bytes32 node, bytes32 name, uint16 resource) public view returns (bytes memory) { return records[node][versions[node]][name][resource]; } /** * Check if a given node has records. * @param node the namehash of the node for which to check the records * @param name the namehash of the node for which to check the records */ function hasDNSRecords(bytes32 node, bytes32 name) public view returns (bool) { return (nameEntriesCount[node][versions[node]][name] != 0); } /** * Clear all information for a DNS zone. * @param node the namehash of the node for which to clear the zone */ function clearDNSZone(bytes32 node) public authorised(node) { versions[node]++; emit DNSZoneCleared(node); } /** * setZonehash sets the hash for the zone. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param hash The zonehash to set */ function setZonehash(bytes32 node, bytes calldata hash) external authorised(node) { bytes memory oldhash = zonehashes[node]; zonehashes[node] = hash; emit DNSZonehashChanged(node, oldhash, hash); } /** * zonehash obtains the hash for the zone. * @param node The ENS node to query. * @return The associated contenthash. */ function zonehash(bytes32 node) external view returns (bytes memory) { return zonehashes[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == DNS_RECORD_INTERFACE_ID || interfaceID == DNS_ZONE_INTERFACE_ID || super.supportsInterface(interfaceID); } function setDNSRRSet( bytes32 node, bytes memory name, uint16 resource, bytes memory data, uint256 offset, uint256 size, bool deleteRecord) private { uint256 version = versions[node]; bytes32 nameHash = keccak256(name); bytes memory rrData = data.substring(offset, size); if (deleteRecord) { if (records[node][version][nameHash][resource].length != 0) { nameEntriesCount[node][version][nameHash]--; } delete(records[node][version][nameHash][resource]); emit DNSRecordDeleted(node, name, resource); } else { if (records[node][version][nameHash][resource].length == 0) { nameEntriesCount[node][version][nameHash]++; } records[node][version][nameHash][resource] = rrData; emit DNSRecordChanged(node, name, resource, rrData); } } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; import "./AddrResolver.sol"; abstract contract InterfaceResolver is ResolverBase, AddrResolver { bytes4 constant private INTERFACE_INTERFACE_ID = bytes4(keccak256("interfaceImplementer(bytes32,bytes4)")); bytes4 private constant INTERFACE_META_ID = 0x01ffc9a7; event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer); mapping(bytes32=>mapping(bytes4=>address)) interfaces; /** * Sets an interface associated with a name. * Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support. * @param node The node to update. * @param interfaceID The EIP 165 interface ID. * @param implementer The address of a contract that implements this interface for this node. */ function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external authorised(node) { interfaces[node][interfaceID] = implementer; emit InterfaceChanged(node, interfaceID, implementer); } /** * Returns the address of a contract that implements the specified interface for this name. * If an implementer has not been set for this interfaceID and name, the resolver will query * the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that * contract implements EIP165 and returns `true` for the specified interfaceID, its address * will be returned. * @param node The ENS node to query. * @param interfaceID The EIP 165 interface ID to check for. * @return The address that implements this interface, or 0 if the interface is unsupported. */ function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address) { address implementer = interfaces[node][interfaceID]; if(implementer != address(0)) { return implementer; } address a = addr(node); if(a == address(0)) { return address(0); } (bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", INTERFACE_META_ID)); if(!success || returnData.length < 32 || returnData[31] == 0) { // EIP 165 not supported by target return address(0); } (success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID)); if(!success || returnData.length < 32 || returnData[31] == 0) { // Specified interface not supported by target return address(0); } return a; } function supportsInterface(bytes4 interfaceID) virtual override(AddrResolver, ResolverBase) public pure returns(bool) { return interfaceID == INTERFACE_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract NameResolver is ResolverBase { bytes4 constant private NAME_INTERFACE_ID = 0x691f3431; event NameChanged(bytes32 indexed node, string name); mapping(bytes32=>string) names; /** * Sets the name associated with an ENS node, for reverse records. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param name The name to set. */ function setName(bytes32 node, string calldata name) external authorised(node) { names[node] = name; emit NameChanged(node, name); } /** * Returns the name associated with an ENS node, for reverse records. * Defined in EIP181. * @param node The ENS node to query. * @return The associated name. */ function name(bytes32 node) external view returns (string memory) { return names[node]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == NAME_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract PubkeyResolver is ResolverBase { bytes4 constant private PUBKEY_INTERFACE_ID = 0xc8690233; event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y); struct PublicKey { bytes32 x; bytes32 y; } mapping(bytes32=>PublicKey) pubkeys; /** * Sets the SECP256k1 public key associated with an ENS node. * @param node The ENS node to query * @param x the X coordinate of the curve point for the public key. * @param y the Y coordinate of the curve point for the public key. */ function setPubkey(bytes32 node, bytes32 x, bytes32 y) external authorised(node) { pubkeys[node] = PublicKey(x, y); emit PubkeyChanged(node, x, y); } /** * Returns the SECP256k1 public key associated with an ENS node. * Defined in EIP 619. * @param node The ENS node to query * @return x The X coordinate of the curve point for the public key. * @return y The Y coordinate of the curve point for the public key. */ function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y) { return (pubkeys[node].x, pubkeys[node].y); } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == PUBKEY_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; import "../ResolverBase.sol"; abstract contract TextResolver is ResolverBase { bytes4 constant private TEXT_INTERFACE_ID = 0x59d1d43c; event TextChanged(bytes32 indexed node, string indexed indexedKey, string key); mapping(bytes32=>mapping(string=>string)) texts; /** * Sets the text data associated with an ENS node and key. * May only be called by the owner of that node in the ENS registry. * @param node The node to update. * @param key The key to set. * @param value The text data value to set. */ function setText(bytes32 node, string calldata key, string calldata value) external authorised(node) { texts[node][key] = value; emit TextChanged(node, key, key); } /** * Returns the text data associated with an ENS node and key. * @param node The ENS node to query. * @param key The text data key to query. * @return The associated text data. */ function text(bytes32 node, string calldata key) external view returns (string memory) { return texts[node][key]; } function supportsInterface(bytes4 interfaceID) virtual override public pure returns(bool) { return interfaceID == TEXT_INTERFACE_ID || super.supportsInterface(interfaceID); } }
pragma solidity >=0.8.4; interface NNS { // Logged when the owner of a node assigns a new owner to a subnode. event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); // Logged when the owner of a node transfers ownership to a new account. event Transfer(bytes32 indexed node, address owner); // Logged when the resolver for a node changes. event NewResolver(bytes32 indexed node, address resolver); // Logged when the TTL of a node changes event NewTTL(bytes32 indexed node, uint64 ttl); // Logged when an operator is added or removed. event ApprovalForAll(address indexed owner, address indexed operator, bool approved); function setRecord(bytes32 node, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeRecord(bytes32 node, bytes32 label, address owner, address resolver, uint64 ttl) external virtual; function setSubnodeOwner(bytes32 node, bytes32 label, address owner) external virtual returns(bytes32); function setResolver(bytes32 node, address resolver) external virtual; function setOwner(bytes32 node, address owner) external virtual; function setTTL(bytes32 node, uint64 ttl) external virtual; function setApprovalForAll(address operator, bool approved) external virtual; function owner(bytes32 node) external virtual view returns (address); function resolver(bytes32 node) external virtual view returns (address); function ttl(bytes32 node) external virtual view returns (uint64); function recordExists(bytes32 node) external virtual view returns (bool); function isApprovedForAll(address owner, address operator) external virtual view returns (bool); }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"contentType","type":"uint256"}],"name":"ABIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"a","type":"address"}],"name":"AddrChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"coinType","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"newAddress","type":"bytes"}],"name":"AddressChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"hash","type":"bytes"}],"name":"ContenthashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"record","type":"bytes"}],"name":"DNSRecordChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"name","type":"bytes"},{"indexed":false,"internalType":"uint16","name":"resource","type":"uint16"}],"name":"DNSRecordDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"DNSZoneCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"lastzonehash","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"zonehash","type":"bytes"}],"name":"DNSZonehashChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"indexed":false,"internalType":"address","name":"implementer","type":"address"}],"name":"InterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"x","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"PubkeyChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"string","name":"indexedKey","type":"string"},{"indexed":false,"internalType":"string","name":"key","type":"string"}],"name":"TextChanged","type":"event"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentTypes","type":"uint256"}],"name":"ABI","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract NNS","name":"_nns","type":"address"},{"internalType":"contract INameWrapper","name":"wrapperAddress","type":"address"}],"name":"__PublicResolver_i","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"addr","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"}],"name":"addr","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"clearDNSZone","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"contenthash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"},{"internalType":"uint16","name":"resource","type":"uint16"}],"name":"dnsRecord","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"name","type":"bytes32"}],"name":"hasDNSRecords","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"interfaceImplementer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"pubkey","outputs":[{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"contentType","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setABI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint256","name":"coinType","type":"uint256"},{"internalType":"bytes","name":"a","type":"bytes"}],"name":"setAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"a","type":"address"}],"name":"setAddr","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":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setContenthash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setDNSRecords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes4","name":"interfaceID","type":"bytes4"},{"internalType":"address","name":"implementer","type":"address"}],"name":"setInterface","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"x","type":"bytes32"},{"internalType":"bytes32","name":"y","type":"bytes32"}],"name":"setPubkey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setText","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes","name":"hash","type":"bytes"}],"name":"setZonehash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"string","name":"key","type":"string"}],"name":"text","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"zonehash","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612892806100206000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806377372213116100f9578063bc1c58d111610097578063d5fa2b0011610071578063d5fa2b0014610411578063e59d895d14610424578063e985e9c514610437578063f1cb7e061461047357600080fd5b8063bc1c58d1146103ae578063c8690233146103c1578063ce3decdc146103fe57600080fd5b8063a22cb465116100d3578063a22cb46514610355578063a8fa568214610368578063ac9650d81461037b578063ad5780af1461039b57600080fd5b8063773722131461031c5780638b95dd711461032f57806394a9dc7c1461034257600080fd5b8063304e6ade1161016657806359d1d43c1161014057806359d1d43c146102c35780635c98042b146102e3578063623195b0146102f6578063691f34311461030957600080fd5b8063304e6ade1461025d5780633b3b57de146102705780634cbf6ba41461028357600080fd5b806301ffc9a7146101ae5780630af179d7146101d657806310f13a8c146101eb578063124a319c146101fe5780632203ab561461022957806329cd62ea1461024a575b600080fd5b6101c16101bc366004611ea6565b610486565b60405190151581526020015b60405180910390f35b6101e96101e4366004611f03565b610497565b005b6101e96101f9366004611f4f565b610685565b61021161020c366004611fc9565b610733565b6040516001600160a01b0390911681526020016101cd565b61023c610237366004611ff5565b61096b565b6040516101cd929190612067565b6101e9610258366004612080565b610a86565b6101e961026b366004611f03565b610b06565b61021161027e3660046120ac565b610b65565b6101c1610291366004611ff5565b600091825260076020908152604080842060058352818520548552825280842092845291905290205461ffff16151590565b6102d66102d1366004611f03565b610b97565b6040516101cd91906120c5565b6102d66102f13660046120ac565b610c5c565b6101e96103043660046120d8565b610cfe565b6102d66103173660046120ac565b610d81565b6101e961032a366004611f03565b610d9e565b6101e961033d366004612141565b610dfd565b6101e961035036600461221a565b610ec3565b6101e9610363366004612253565b610fdd565b6102d6610376366004612286565b6110b3565b61038e6103893660046122c6565b6110f6565b6040516101cd919061233b565b6101e96103a93660046120ac565b611211565b6102d66103bc3660046120ac565b611272565b6103e96103cf3660046120ac565b6000908152600a6020526040902080546001909101549091565b604080519283526020830191909152016101cd565b6101e961040c366004611f03565b61128f565b6101e961041f36600461239d565b61139b565b6101e96104323660046123c2565b6113bd565b6101c161044536600461221a565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205460ff1690565b6102d6610481366004611ff5565b61144a565b6000610491826114f8565b92915050565b826104a18161151d565b6104aa57600080fd5b6000806060806000806104f760008a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506116569050565b90505b80515160208201511015610620578561ffff1660000361055f5780604001519550610524816116b7565b93508360405160200161053791906123f7565b604051602081830303815290604052805190602001209150610558816116d8565b9250610612565b600061056a826116b7565b9050816040015161ffff168761ffff1614158061058e575061058c85826116f4565b155b15610610576105e98b86898d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505060208801518c91506105e1908290612429565b8a5115611712565b81604001519650816020015195508094508480519060200120925061060d826116d8565b93505b505b61061b81611951565b6104fa565b5082511561067a5761067a8984878b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061067291508290508e612429565b885115611712565b505050505050505050565b8461068f8161151d565b61069857600080fd5b8282600b600089815260200190815260200160002087876040516106bd92919061243c565b908152602001604051809103902091826106d89291906124d4565b5084846040516106e992919061243c565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a755087876040516107239291906125bd565b60405180910390a3505050505050565b60008281526008602090815260408083206001600160e01b0319851684529091528120546001600160a01b0316801561076d579050610491565b600061077885610b65565b90506001600160a01b03811661079357600092505050610491565b6040516301ffc9a760e01b602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516107eb91906123f7565b600060405180830381855afa9150503d8060008114610826576040519150601f19603f3d011682016040523d82523d6000602084013e61082b565b606091505b509150915081158061083e575060208151105b80610868575080601f81518110610857576108576125d1565b01602001516001600160f81b031916155b1561087a576000945050505050610491565b6040516001600160e01b0319871660248201526001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516108d091906123f7565b600060405180830381855afa9150503d806000811461090b576040519150601f19603f3d011682016040523d82523d6000602084013e610910565b606091505b509092509050811580610924575060208151105b8061094e575080601f8151811061093d5761093d6125d1565b01602001516001600160f81b031916155b15610960576000945050505050610491565b509095945050505050565b600082815260016020819052604082206060915b848111610a6657808516158015906109af5750600081815260208390526040812080546109ab9061244c565b9050115b15610a5e57808260008381526020019081526020016000208080546109d39061244c565b80601f01602080910402602001604051908101604052809291908181526020018280546109ff9061244c565b8015610a4c5780601f10610a2157610100808354040283529160200191610a4c565b820191906000526020600020905b815481529060010190602001808311610a2f57829003601f168201915b50505050509050935093505050610a7f565b60011b61097f565b5060006040518060200160405280600081525092509250505b9250929050565b82610a908161151d565b610a9957600080fd5b60408051808201825284815260208082018581526000888152600a83528490209251835551600190920191909155815185815290810184905285917f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e4691015b60405180910390a250505050565b82610b108161151d565b610b1957600080fd5b6000848152600360205260409020610b328385836124d4565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d75788484604051610af89291906125bd565b600080610b7383603c61144a565b90508051600003610b875750600092915050565b610b9081611a39565b9392505050565b6060600b60008581526020019081526020016000208383604051610bbc92919061243c565b90815260200160405180910390208054610bd59061244c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c019061244c565b8015610c4e5780601f10610c2357610100808354040283529160200191610c4e565b820191906000526020600020905b815481529060010190602001808311610c3157829003601f168201915b505050505090509392505050565b6000818152600460205260409020805460609190610c799061244c565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061244c565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b50505050509050919050565b83610d088161151d565b610d1157600080fd5b83610d1d600182612429565b1615610d2857600080fd5b60008581526001602090815260408083208784529091529020610d4c8385836124d4565b50604051849086907faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe390600090a35050505050565b6000818152600960205260409020805460609190610c799061244c565b82610da88161151d565b610db157600080fd5b6000848152600960205260409020610dca8385836124d4565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051610af89291906125bd565b82610e078161151d565b610e1057600080fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af7528484604051610e42929190612067565b60405180910390a2603c8303610e9957837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2610e7d84611a39565b6040516001600160a01b03909116815260200160405180910390a25b60008481526002602090815260408083208684529091529020610ebc83826125e7565b5050505050565b600054610100900460ff1615808015610ee35750600054600160ff909116105b80610efd5750303b158015610efd575060005460ff166001145b610f655760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610f88576000805461ff0019166101001790555b610f928383611a58565b8015610fd8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03821633036110475760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610f5c565b336000818152600e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000838152600660209081526040808320600583528184205484528252808320858452825280832061ffff851684529091529020805460609190610bd59061244c565b60608167ffffffffffffffff8111156111115761111161212b565b60405190808252806020026020018201604052801561114457816020015b606081526020019060019003908161112f5790505b50905060005b8281101561120a5760008030868685818110611168576111686125d1565b905060200281019061117a91906126a7565b60405161118892919061243c565b600060405180830381855af49150503d80600081146111c3576040519150601f19603f3d011682016040523d82523d6000602084013e6111c8565b606091505b5091509150816111d757600080fd5b808484815181106111ea576111ea6125d1565b602002602001018190525050508080611202906126ee565b91505061114a565b5092915050565b8061121b8161151d565b61122457600080fd5b600082815260056020526040812080549161123e836126ee565b909155505060405182907fb757169b8492ca2f1c6619d9d76ce22803035c3b1d5f6930dffe7b127c1a198390600090a25050565b6000818152600360205260409020805460609190610c799061244c565b826112998161151d565b6112a257600080fd5b600084815260046020526040812080546112bb9061244c565b80601f01602080910402602001604051908101604052809291908181526020018280546112e79061244c565b80156113345780601f1061130957610100808354040283529160200191611334565b820191906000526020600020905b81548152906001019060200180831161131757829003601f168201915b5050506000888152600460205260409020929350611357915085905086836124d4565b50847f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f8582868660405161138c93929190612707565b60405180910390a25050505050565b816113a58161151d565b6113ae57600080fd5b610fd883603c61033d85611a8d565b826113c78161151d565b6113d057600080fd5b60008481526008602090815260408083206001600160e01b031987168085529083529281902080546001600160a01b0319166001600160a01b038716908117909155905190815286917f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa910160405180910390a350505050565b600082815260026020908152604080832084845290915290208054606091906114729061244c565b80601f016020809104026020016040519081016040528092919081815260200182805461149e9061244c565b80156114eb5780601f106114c0576101008083540402835291602001916114eb565b820191906000526020600020905b8154815290600101906020018083116114ce57829003601f168201915b5050505050905092915050565b60006001600160e01b03198216631674750f60e21b1480610491575061049182611abd565b600c546040516302571be360e01b81526004810183905260009182916001600160a01b03909116906302571be390602401602060405180830381865afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f9190612737565b600d549091506001600160a01b039081169082160361161857600d546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156115f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116159190612737565b90505b6001600160a01b038116331480610b9057506001600160a01b0381166000908152600e6020908152604080832033845290915290205460ff16610b90565b6116a46040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c0810182905261049181611951565b60208101518151606091610491916116cf9082611ae2565b84519190611b44565b60a081015160c0820151606091610491916116cf908290612429565b600081518351148015610b905750610b908360008460008751611bbb565b60008781526005602090815260408220548851918901919091209091611739878787611b44565b905083156118425760008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152902080546117799061244c565b1590506117cd5760008a815260076020908152604080832086845282528083208584529091528120805461ffff16916117b183612754565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152812061180391611e33565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a604051611835929190612772565b60405180910390a2611945565b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461187a9061244c565b90506000036118d05760008a815260076020908152604080832086845282528083208584529091528120805461ffff16916118b483612798565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152902061190782826125e7565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a8460405161193c939291906127b9565b60405180910390a25b50505050505050505050565b60c081015160208201819052815151116119685750565b600061197c82600001518360200151611ae2565b826020015161198b91906127e8565b825190915061199a9082611bde565b61ffff1660408301526119ae6002826127e8565b82519091506119bd9082611bde565b61ffff1660608301526119d16002826127e8565b82519091506119e09082611c06565b63ffffffff1660808301526119f66004826127e8565b8251909150600090611a089083611bde565b61ffff169050611a196002836127e8565b60a084018190529150611a2c81836127e8565b60c0909301929092525050565b60008151601414611a4957600080fd5b5060200151600160601b900490565b600054610100900460ff16611a7f5760405162461bcd60e51b8152600401610f5c906127fb565b611a898282611c30565b5050565b604080516014808252818301909252606091602082018180368337505050600160601b9290920260208301525090565b60006001600160e01b0319821663c869023360e01b1480610491575061049182611c85565b6000815b83518110611af657611af6612846565b6000611b028583611caa565b60ff169050611b128160016127e8565b611b1c90836127e8565b915080600003611b2c5750611b32565b50611ae6565b611b3c8382612429565b949350505050565b8251606090611b5383856127e8565b1115611b5e57600080fd5b60008267ffffffffffffffff811115611b7957611b7961212b565b6040519080825280601f01601f191660200182016040528015611ba3576020820181803683370190505b50905060208082019086860101610960828287611cce565b6000611bc8848484611d24565b611bd3878785611d24565b149695505050505050565b8151600090611bee8360026127e8565b1115611bf957600080fd5b50016002015161ffff1690565b8151600090611c168360046127e8565b1115611c2157600080fd5b50016004015163ffffffff1690565b600054610100900460ff16611c575760405162461bcd60e51b8152600401610f5c906127fb565b600c80546001600160a01b039384166001600160a01b031991821617909155600d8054929093169116179055565b60006001600160e01b0319821663691f343160e01b1480610491575061049182611d48565b6000828281518110611cbe57611cbe6125d1565b016020015160f81c905092915050565b60208110611d065781518352611ce56020846127e8565b9250611cf26020836127e8565b9150611cff602082612429565b9050611cce565b905182516020929092036101000a6000190180199091169116179052565b8251600090611d3383856127e8565b1115611d3e57600080fd5b5091016020012090565b60006001600160e01b031982166304928c6760e21b148061049157506104918260006001600160e01b0319821663547d2b4160e11b1480611d9957506001600160e01b03198216631711d8df60e21b145b8061049157506104918260006001600160e01b0319821663bc1c58d160e01b148061049157506104918260006001600160e01b03198216631d9dabef60e11b1480611df457506001600160e01b031982166378e5bf0360e11b145b8061049157506104918260006001600160e01b03198216631101d5ab60e11b148061049157506301ffc9a760e01b6001600160e01b0319831614610491565b508054611e3f9061244c565b6000825580601f10611e4f575050565b601f016020900490600052602060002090810190611e6d9190611e70565b50565b5b80821115611e855760008155600101611e71565b5090565b80356001600160e01b031981168114611ea157600080fd5b919050565b600060208284031215611eb857600080fd5b610b9082611e89565b60008083601f840112611ed357600080fd5b50813567ffffffffffffffff811115611eeb57600080fd5b602083019150836020828501011115610a7f57600080fd5b600080600060408486031215611f1857600080fd5b83359250602084013567ffffffffffffffff811115611f3657600080fd5b611f4286828701611ec1565b9497909650939450505050565b600080600080600060608688031215611f6757600080fd5b85359450602086013567ffffffffffffffff80821115611f8657600080fd5b611f9289838a01611ec1565b90965094506040880135915080821115611fab57600080fd5b50611fb888828901611ec1565b969995985093965092949392505050565b60008060408385031215611fdc57600080fd5b82359150611fec60208401611e89565b90509250929050565b6000806040838503121561200857600080fd5b50508035926020909101359150565b60005b8381101561203257818101518382015260200161201a565b50506000910152565b60008151808452612053816020860160208601612017565b601f01601f19169290920160200192915050565b828152604060208201526000611b3c604083018461203b565b60008060006060848603121561209557600080fd5b505081359360208301359350604090920135919050565b6000602082840312156120be57600080fd5b5035919050565b602081526000610b90602083018461203b565b600080600080606085870312156120ee57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561211357600080fd5b61211f87828801611ec1565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561215657600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561217c57600080fd5b818601915086601f83011261219057600080fd5b8135818111156121a2576121a261212b565b604051601f8201601f19908116603f011681019083821181831017156121ca576121ca61212b565b816040528281528960208487010111156121e357600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6001600160a01b0381168114611e6d57600080fd5b6000806040838503121561222d57600080fd5b823561223881612205565b9150602083013561224881612205565b809150509250929050565b6000806040838503121561226657600080fd5b823561227181612205565b91506020830135801515811461224857600080fd5b60008060006060848603121561229b57600080fd5b8335925060208401359150604084013561ffff811681146122bb57600080fd5b809150509250925092565b600080602083850312156122d957600080fd5b823567ffffffffffffffff808211156122f157600080fd5b818501915085601f83011261230557600080fd5b81358181111561231457600080fd5b8660208260051b850101111561232957600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561239057603f1988860301845261237e85835161203b565b94509285019290850190600101612362565b5092979650505050505050565b600080604083850312156123b057600080fd5b82359150602083013561224881612205565b6000806000606084860312156123d757600080fd5b833592506123e760208501611e89565b915060408401356122bb81612205565b60008251612409818460208701612017565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561049157610491612413565b8183823760009101908152919050565b600181811c9082168061246057607f821691505b60208210810361248057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610fd857600081815260208120601f850160051c810160208610156124ad5750805b601f850160051c820191505b818110156124cc578281556001016124b9565b505050505050565b67ffffffffffffffff8311156124ec576124ec61212b565b612500836124fa835461244c565b83612486565b6000601f841160018114612534576000851561251c5750838201355b600019600387901b1c1916600186901b178355610ebc565b600083815260209020601f19861690835b828110156125655786850135825560209485019460019092019101612545565b50868210156125825760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611b3c602083018486612594565b634e487b7160e01b600052603260045260246000fd5b815167ffffffffffffffff8111156126015761260161212b565b6126158161260f845461244c565b84612486565b602080601f83116001811461264a57600084156126325750858301515b600019600386901b1c1916600185901b1785556124cc565b600085815260208120601f198616915b828110156126795788860151825594840194600190910190840161265a565b50858210156126975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808335601e198436030181126126be57600080fd5b83018035915067ffffffffffffffff8211156126d957600080fd5b602001915036819003821315610a7f57600080fd5b60006001820161270057612700612413565b5060010190565b60408152600061271a604083018661203b565b828103602084015261272d818587612594565b9695505050505050565b60006020828403121561274957600080fd5b8151610b9081612205565b600061ffff82168061276857612768612413565b6000190192915050565b604081526000612785604083018561203b565b905061ffff831660208301529392505050565b600061ffff8083168181036127af576127af612413565b6001019392505050565b6060815260006127cc606083018661203b565b61ffff85166020840152828103604084015261272d818561203b565b8082018082111561049157610491612413565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052600160045260246000fdfea2646970667358221220e30d7475a0a1ea044e380733e79e6529f4100781bc14b1fffe4616b82fa011ca64736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806377372213116100f9578063bc1c58d111610097578063d5fa2b0011610071578063d5fa2b0014610411578063e59d895d14610424578063e985e9c514610437578063f1cb7e061461047357600080fd5b8063bc1c58d1146103ae578063c8690233146103c1578063ce3decdc146103fe57600080fd5b8063a22cb465116100d3578063a22cb46514610355578063a8fa568214610368578063ac9650d81461037b578063ad5780af1461039b57600080fd5b8063773722131461031c5780638b95dd711461032f57806394a9dc7c1461034257600080fd5b8063304e6ade1161016657806359d1d43c1161014057806359d1d43c146102c35780635c98042b146102e3578063623195b0146102f6578063691f34311461030957600080fd5b8063304e6ade1461025d5780633b3b57de146102705780634cbf6ba41461028357600080fd5b806301ffc9a7146101ae5780630af179d7146101d657806310f13a8c146101eb578063124a319c146101fe5780632203ab561461022957806329cd62ea1461024a575b600080fd5b6101c16101bc366004611ea6565b610486565b60405190151581526020015b60405180910390f35b6101e96101e4366004611f03565b610497565b005b6101e96101f9366004611f4f565b610685565b61021161020c366004611fc9565b610733565b6040516001600160a01b0390911681526020016101cd565b61023c610237366004611ff5565b61096b565b6040516101cd929190612067565b6101e9610258366004612080565b610a86565b6101e961026b366004611f03565b610b06565b61021161027e3660046120ac565b610b65565b6101c1610291366004611ff5565b600091825260076020908152604080842060058352818520548552825280842092845291905290205461ffff16151590565b6102d66102d1366004611f03565b610b97565b6040516101cd91906120c5565b6102d66102f13660046120ac565b610c5c565b6101e96103043660046120d8565b610cfe565b6102d66103173660046120ac565b610d81565b6101e961032a366004611f03565b610d9e565b6101e961033d366004612141565b610dfd565b6101e961035036600461221a565b610ec3565b6101e9610363366004612253565b610fdd565b6102d6610376366004612286565b6110b3565b61038e6103893660046122c6565b6110f6565b6040516101cd919061233b565b6101e96103a93660046120ac565b611211565b6102d66103bc3660046120ac565b611272565b6103e96103cf3660046120ac565b6000908152600a6020526040902080546001909101549091565b604080519283526020830191909152016101cd565b6101e961040c366004611f03565b61128f565b6101e961041f36600461239d565b61139b565b6101e96104323660046123c2565b6113bd565b6101c161044536600461221a565b6001600160a01b039182166000908152600e6020908152604080832093909416825291909152205460ff1690565b6102d6610481366004611ff5565b61144a565b6000610491826114f8565b92915050565b826104a18161151d565b6104aa57600080fd5b6000806060806000806104f760008a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506116569050565b90505b80515160208201511015610620578561ffff1660000361055f5780604001519550610524816116b7565b93508360405160200161053791906123f7565b604051602081830303815290604052805190602001209150610558816116d8565b9250610612565b600061056a826116b7565b9050816040015161ffff168761ffff1614158061058e575061058c85826116f4565b155b15610610576105e98b86898d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505060208801518c91506105e1908290612429565b8a5115611712565b81604001519650816020015195508094508480519060200120925061060d826116d8565b93505b505b61061b81611951565b6104fa565b5082511561067a5761067a8984878b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061067291508290508e612429565b885115611712565b505050505050505050565b8461068f8161151d565b61069857600080fd5b8282600b600089815260200190815260200160002087876040516106bd92919061243c565b908152602001604051809103902091826106d89291906124d4565b5084846040516106e992919061243c565b6040518091039020867fd8c9334b1a9c2f9da342a0a2b32629c1a229b6445dad78947f674b44444a755087876040516107239291906125bd565b60405180910390a3505050505050565b60008281526008602090815260408083206001600160e01b0319851684529091528120546001600160a01b0316801561076d579050610491565b600061077885610b65565b90506001600160a01b03811661079357600092505050610491565b6040516301ffc9a760e01b602482015260009081906001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516107eb91906123f7565b600060405180830381855afa9150503d8060008114610826576040519150601f19603f3d011682016040523d82523d6000602084013e61082b565b606091505b509150915081158061083e575060208151105b80610868575080601f81518110610857576108576125d1565b01602001516001600160f81b031916155b1561087a576000945050505050610491565b6040516001600160e01b0319871660248201526001600160a01b0384169060440160408051601f198184030181529181526020820180516001600160e01b03166301ffc9a760e01b179052516108d091906123f7565b600060405180830381855afa9150503d806000811461090b576040519150601f19603f3d011682016040523d82523d6000602084013e610910565b606091505b509092509050811580610924575060208151105b8061094e575080601f8151811061093d5761093d6125d1565b01602001516001600160f81b031916155b15610960576000945050505050610491565b509095945050505050565b600082815260016020819052604082206060915b848111610a6657808516158015906109af5750600081815260208390526040812080546109ab9061244c565b9050115b15610a5e57808260008381526020019081526020016000208080546109d39061244c565b80601f01602080910402602001604051908101604052809291908181526020018280546109ff9061244c565b8015610a4c5780601f10610a2157610100808354040283529160200191610a4c565b820191906000526020600020905b815481529060010190602001808311610a2f57829003601f168201915b50505050509050935093505050610a7f565b60011b61097f565b5060006040518060200160405280600081525092509250505b9250929050565b82610a908161151d565b610a9957600080fd5b60408051808201825284815260208082018581526000888152600a83528490209251835551600190920191909155815185815290810184905285917f1d6f5e03d3f63eb58751986629a5439baee5079ff04f345becb66e23eb154e4691015b60405180910390a250505050565b82610b108161151d565b610b1957600080fd5b6000848152600360205260409020610b328385836124d4565b50837fe379c1624ed7e714cc0937528a32359d69d5281337765313dba4e081b72d75788484604051610af89291906125bd565b600080610b7383603c61144a565b90508051600003610b875750600092915050565b610b9081611a39565b9392505050565b6060600b60008581526020019081526020016000208383604051610bbc92919061243c565b90815260200160405180910390208054610bd59061244c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c019061244c565b8015610c4e5780601f10610c2357610100808354040283529160200191610c4e565b820191906000526020600020905b815481529060010190602001808311610c3157829003601f168201915b505050505090509392505050565b6000818152600460205260409020805460609190610c799061244c565b80601f0160208091040260200160405190810160405280929190818152602001828054610ca59061244c565b8015610cf25780601f10610cc757610100808354040283529160200191610cf2565b820191906000526020600020905b815481529060010190602001808311610cd557829003601f168201915b50505050509050919050565b83610d088161151d565b610d1157600080fd5b83610d1d600182612429565b1615610d2857600080fd5b60008581526001602090815260408083208784529091529020610d4c8385836124d4565b50604051849086907faa121bbeef5f32f5961a2a28966e769023910fc9479059ee3495d4c1a696efe390600090a35050505050565b6000818152600960205260409020805460609190610c799061244c565b82610da88161151d565b610db157600080fd5b6000848152600960205260409020610dca8385836124d4565b50837fb7d29e911041e8d9b843369e890bcb72c9388692ba48b65ac54e7214c4c348f78484604051610af89291906125bd565b82610e078161151d565b610e1057600080fd5b837f65412581168e88a1e60c6459d7f44ae83ad0832e670826c05a4e2476b57af7528484604051610e42929190612067565b60405180910390a2603c8303610e9957837f52d7d861f09ab3d26239d492e8968629f95e9e318cf0b73bfddc441522a15fd2610e7d84611a39565b6040516001600160a01b03909116815260200160405180910390a25b60008481526002602090815260408083208684529091529020610ebc83826125e7565b5050505050565b600054610100900460ff1615808015610ee35750600054600160ff909116105b80610efd5750303b158015610efd575060005460ff166001145b610f655760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff191660011790558015610f88576000805461ff0019166101001790555b610f928383611a58565b8015610fd8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b6001600160a01b03821633036110475760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b6064820152608401610f5c565b336000818152600e602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000838152600660209081526040808320600583528184205484528252808320858452825280832061ffff851684529091529020805460609190610bd59061244c565b60608167ffffffffffffffff8111156111115761111161212b565b60405190808252806020026020018201604052801561114457816020015b606081526020019060019003908161112f5790505b50905060005b8281101561120a5760008030868685818110611168576111686125d1565b905060200281019061117a91906126a7565b60405161118892919061243c565b600060405180830381855af49150503d80600081146111c3576040519150601f19603f3d011682016040523d82523d6000602084013e6111c8565b606091505b5091509150816111d757600080fd5b808484815181106111ea576111ea6125d1565b602002602001018190525050508080611202906126ee565b91505061114a565b5092915050565b8061121b8161151d565b61122457600080fd5b600082815260056020526040812080549161123e836126ee565b909155505060405182907fb757169b8492ca2f1c6619d9d76ce22803035c3b1d5f6930dffe7b127c1a198390600090a25050565b6000818152600360205260409020805460609190610c799061244c565b826112998161151d565b6112a257600080fd5b600084815260046020526040812080546112bb9061244c565b80601f01602080910402602001604051908101604052809291908181526020018280546112e79061244c565b80156113345780601f1061130957610100808354040283529160200191611334565b820191906000526020600020905b81548152906001019060200180831161131757829003601f168201915b5050506000888152600460205260409020929350611357915085905086836124d4565b50847f8f15ed4b723ef428f250961da8315675b507046737e19319fc1a4d81bfe87f8582868660405161138c93929190612707565b60405180910390a25050505050565b816113a58161151d565b6113ae57600080fd5b610fd883603c61033d85611a8d565b826113c78161151d565b6113d057600080fd5b60008481526008602090815260408083206001600160e01b031987168085529083529281902080546001600160a01b0319166001600160a01b038716908117909155905190815286917f7c69f06bea0bdef565b709e93a147836b0063ba2dd89f02d0b7e8d931e6a6daa910160405180910390a350505050565b600082815260026020908152604080832084845290915290208054606091906114729061244c565b80601f016020809104026020016040519081016040528092919081815260200182805461149e9061244c565b80156114eb5780601f106114c0576101008083540402835291602001916114eb565b820191906000526020600020905b8154815290600101906020018083116114ce57829003601f168201915b5050505050905092915050565b60006001600160e01b03198216631674750f60e21b1480610491575061049182611abd565b600c546040516302571be360e01b81526004810183905260009182916001600160a01b03909116906302571be390602401602060405180830381865afa15801561156b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158f9190612737565b600d549091506001600160a01b039081169082160361161857600d546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156115f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116159190612737565b90505b6001600160a01b038116331480610b9057506001600160a01b0381166000908152600e6020908152604080832033845290915290205460ff16610b90565b6116a46040518060e001604052806060815260200160008152602001600061ffff168152602001600061ffff168152602001600063ffffffff16815260200160008152602001600081525090565b82815260c0810182905261049181611951565b60208101518151606091610491916116cf9082611ae2565b84519190611b44565b60a081015160c0820151606091610491916116cf908290612429565b600081518351148015610b905750610b908360008460008751611bbb565b60008781526005602090815260408220548851918901919091209091611739878787611b44565b905083156118425760008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152902080546117799061244c565b1590506117cd5760008a815260076020908152604080832086845282528083208584529091528120805461ffff16916117b183612754565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152812061180391611e33565b897f03528ed0c2a3ebc993b12ce3c16bb382f9c7d88ef7d8a1bf290eaf35955a12078a8a604051611835929190612772565b60405180910390a2611945565b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c1684529091529020805461187a9061244c565b90506000036118d05760008a815260076020908152604080832086845282528083208584529091528120805461ffff16916118b483612798565b91906101000a81548161ffff021916908361ffff160217905550505b60008a81526006602090815260408083208684528252808320858452825280832061ffff8c168452909152902061190782826125e7565b50897f52a608b3303a48862d07a73d82fa221318c0027fbbcfb1b2329bface3f19ff2b8a8a8460405161193c939291906127b9565b60405180910390a25b50505050505050505050565b60c081015160208201819052815151116119685750565b600061197c82600001518360200151611ae2565b826020015161198b91906127e8565b825190915061199a9082611bde565b61ffff1660408301526119ae6002826127e8565b82519091506119bd9082611bde565b61ffff1660608301526119d16002826127e8565b82519091506119e09082611c06565b63ffffffff1660808301526119f66004826127e8565b8251909150600090611a089083611bde565b61ffff169050611a196002836127e8565b60a084018190529150611a2c81836127e8565b60c0909301929092525050565b60008151601414611a4957600080fd5b5060200151600160601b900490565b600054610100900460ff16611a7f5760405162461bcd60e51b8152600401610f5c906127fb565b611a898282611c30565b5050565b604080516014808252818301909252606091602082018180368337505050600160601b9290920260208301525090565b60006001600160e01b0319821663c869023360e01b1480610491575061049182611c85565b6000815b83518110611af657611af6612846565b6000611b028583611caa565b60ff169050611b128160016127e8565b611b1c90836127e8565b915080600003611b2c5750611b32565b50611ae6565b611b3c8382612429565b949350505050565b8251606090611b5383856127e8565b1115611b5e57600080fd5b60008267ffffffffffffffff811115611b7957611b7961212b565b6040519080825280601f01601f191660200182016040528015611ba3576020820181803683370190505b50905060208082019086860101610960828287611cce565b6000611bc8848484611d24565b611bd3878785611d24565b149695505050505050565b8151600090611bee8360026127e8565b1115611bf957600080fd5b50016002015161ffff1690565b8151600090611c168360046127e8565b1115611c2157600080fd5b50016004015163ffffffff1690565b600054610100900460ff16611c575760405162461bcd60e51b8152600401610f5c906127fb565b600c80546001600160a01b039384166001600160a01b031991821617909155600d8054929093169116179055565b60006001600160e01b0319821663691f343160e01b1480610491575061049182611d48565b6000828281518110611cbe57611cbe6125d1565b016020015160f81c905092915050565b60208110611d065781518352611ce56020846127e8565b9250611cf26020836127e8565b9150611cff602082612429565b9050611cce565b905182516020929092036101000a6000190180199091169116179052565b8251600090611d3383856127e8565b1115611d3e57600080fd5b5091016020012090565b60006001600160e01b031982166304928c6760e21b148061049157506104918260006001600160e01b0319821663547d2b4160e11b1480611d9957506001600160e01b03198216631711d8df60e21b145b8061049157506104918260006001600160e01b0319821663bc1c58d160e01b148061049157506104918260006001600160e01b03198216631d9dabef60e11b1480611df457506001600160e01b031982166378e5bf0360e11b145b8061049157506104918260006001600160e01b03198216631101d5ab60e11b148061049157506301ffc9a760e01b6001600160e01b0319831614610491565b508054611e3f9061244c565b6000825580601f10611e4f575050565b601f016020900490600052602060002090810190611e6d9190611e70565b50565b5b80821115611e855760008155600101611e71565b5090565b80356001600160e01b031981168114611ea157600080fd5b919050565b600060208284031215611eb857600080fd5b610b9082611e89565b60008083601f840112611ed357600080fd5b50813567ffffffffffffffff811115611eeb57600080fd5b602083019150836020828501011115610a7f57600080fd5b600080600060408486031215611f1857600080fd5b83359250602084013567ffffffffffffffff811115611f3657600080fd5b611f4286828701611ec1565b9497909650939450505050565b600080600080600060608688031215611f6757600080fd5b85359450602086013567ffffffffffffffff80821115611f8657600080fd5b611f9289838a01611ec1565b90965094506040880135915080821115611fab57600080fd5b50611fb888828901611ec1565b969995985093965092949392505050565b60008060408385031215611fdc57600080fd5b82359150611fec60208401611e89565b90509250929050565b6000806040838503121561200857600080fd5b50508035926020909101359150565b60005b8381101561203257818101518382015260200161201a565b50506000910152565b60008151808452612053816020860160208601612017565b601f01601f19169290920160200192915050565b828152604060208201526000611b3c604083018461203b565b60008060006060848603121561209557600080fd5b505081359360208301359350604090920135919050565b6000602082840312156120be57600080fd5b5035919050565b602081526000610b90602083018461203b565b600080600080606085870312156120ee57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561211357600080fd5b61211f87828801611ec1565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60008060006060848603121561215657600080fd5b8335925060208401359150604084013567ffffffffffffffff8082111561217c57600080fd5b818601915086601f83011261219057600080fd5b8135818111156121a2576121a261212b565b604051601f8201601f19908116603f011681019083821181831017156121ca576121ca61212b565b816040528281528960208487010111156121e357600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b6001600160a01b0381168114611e6d57600080fd5b6000806040838503121561222d57600080fd5b823561223881612205565b9150602083013561224881612205565b809150509250929050565b6000806040838503121561226657600080fd5b823561227181612205565b91506020830135801515811461224857600080fd5b60008060006060848603121561229b57600080fd5b8335925060208401359150604084013561ffff811681146122bb57600080fd5b809150509250925092565b600080602083850312156122d957600080fd5b823567ffffffffffffffff808211156122f157600080fd5b818501915085601f83011261230557600080fd5b81358181111561231457600080fd5b8660208260051b850101111561232957600080fd5b60209290920196919550909350505050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561239057603f1988860301845261237e85835161203b565b94509285019290850190600101612362565b5092979650505050505050565b600080604083850312156123b057600080fd5b82359150602083013561224881612205565b6000806000606084860312156123d757600080fd5b833592506123e760208501611e89565b915060408401356122bb81612205565b60008251612409818460208701612017565b9190910192915050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561049157610491612413565b8183823760009101908152919050565b600181811c9082168061246057607f821691505b60208210810361248057634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610fd857600081815260208120601f850160051c810160208610156124ad5750805b601f850160051c820191505b818110156124cc578281556001016124b9565b505050505050565b67ffffffffffffffff8311156124ec576124ec61212b565b612500836124fa835461244c565b83612486565b6000601f841160018114612534576000851561251c5750838201355b600019600387901b1c1916600186901b178355610ebc565b600083815260209020601f19861690835b828110156125655786850135825560209485019460019092019101612545565b50868210156125825760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000611b3c602083018486612594565b634e487b7160e01b600052603260045260246000fd5b815167ffffffffffffffff8111156126015761260161212b565b6126158161260f845461244c565b84612486565b602080601f83116001811461264a57600084156126325750858301515b600019600386901b1c1916600185901b1785556124cc565b600085815260208120601f198616915b828110156126795788860151825594840194600190910190840161265a565b50858210156126975787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808335601e198436030181126126be57600080fd5b83018035915067ffffffffffffffff8211156126d957600080fd5b602001915036819003821315610a7f57600080fd5b60006001820161270057612700612413565b5060010190565b60408152600061271a604083018661203b565b828103602084015261272d818587612594565b9695505050505050565b60006020828403121561274957600080fd5b8151610b9081612205565b600061ffff82168061276857612768612413565b6000190192915050565b604081526000612785604083018561203b565b905061ffff831660208301529392505050565b600061ffff8083168181036127af576127af612413565b6001019392505050565b6060815260006127cc606083018661203b565b61ffff85166020840152828103604084015261272d818561203b565b8082018082111561049157610491612413565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b634e487b7160e01b600052600160045260246000fdfea2646970667358221220e30d7475a0a1ea044e380733e79e6529f4100781bc14b1fffe4616b82fa011ca64736f6c63430008110033
Deployed Bytecode Sourcemap
643:2759:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3126:274;;;;;;:::i;:::-;;:::i;:::-;;;546:14:16;;539:22;521:41;;509:2;494:18;3126:274:3;;;;;;;;2877:1263:10;;;;;;:::i;:::-;;:::i;:::-;;582:184:14;;;;;;:::i;:::-;;:::i;1730:953:11:-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;2620:32:16;;;2602:51;;2590:2;2575:18;1730:953:11;2456:203:16;1204:454:7;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;621:169:13:-;;;;;;:::i;:::-;;:::i;514:166:9:-;;;;;;:::i;:::-;;:::i;981:228:8:-;;;;;;:::i;:::-;;:::i;4924:153:10:-;;;;;;:::i;:::-;4996:4;5020:22;;;:16;:22;;;;;;;;5043:8;:14;;;;;;5020:38;;;;;;;:44;;;;;;;;;;;:49;;;4924:153;983:127:14;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5943:109:10:-;;;;;;:::i;:::-;;:::i;591:292:7:-;;;;;;:::i;:::-;;:::i;853:101:12:-;;;;;;:::i;:::-;;:::i;501:152::-;;;;;;:::i;:::-;;:::i;1215:286:8:-;;;;;;:::i;:::-;;:::i;1321:150:3:-;;;;;;:::i;:::-;;:::i;1903:318::-;;;;;;:::i;:::-;;:::i;4542:168:10:-;;;;;;:::i;:::-;;:::i;2754:366:3:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5216:128:10:-;;;;;;:::i;:::-;;:::i;847:108:9:-;;;;;;:::i;:::-;;:::i;1095:133:13:-;;;;;;:::i;:::-;1148:9;1188:13;;;:7;:13;;;;;:15;;1205;;;;;1188;;1095:133;;;;;10421:25:16;;;10477:2;10462:18;;10455:34;;;;10394:18;1095:133:13;10247:248:16;5564:225:10;;;;;;:::i;:::-;;:::i;690:132:8:-;;;;;;:::i;:::-;;:::i;867:226:11:-;;;;;;:::i;:::-;;:::i;2600:148:3:-;;;;;;:::i;:::-;-1:-1:-1;;;;;2704:27:3;;;2682:4;2704:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;2600:148;1507:127:8;;;;;;:::i;:::-;;:::i;3126:274:3:-;3334:4;3357:36;3381:11;3357:23;:36::i;:::-;3350:43;3126:274;-1:-1:-1;;3126:274:3:o;2877:1263:10:-;2955:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;2971:15:10::1;3000:14:::0;3028:17:::1;3055:18:::0;3083:16:::1;3175:30:::0;3208:18:::1;3224:1;3208:4;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;3208:15:10;;:18;-1:-1:-1;;3208:15:10::1;:18:::0;-1:-1:-1;3208:18:10:i:1;:::-;3175:51;;3170:821;4282:9:6::0;;:16;4267:11;;;;:31;;3170:821:10::1;;3273:8;:13;;3285:1;3273:13:::0;3269:712:::1;;3317:4;:12;;;3306:23;;3354:11;:4;:9;:11::i;:::-;3347:18;;3421:4;3404:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;3394:33;;;;;;3383:44;;3459:12;:4;:10;:12::i;:::-;3445:27;;3269:712;;;3511:20;3534:11;:4;:9;:11::i;:::-;3511:34;;3579:4;:12;;;3567:24;;:8;:24;;;;:49;;;-1:-1:-1::0;3596:20:10::1;:4:::0;3608:7;3596:11:::1;:20::i;:::-;3595:21;3567:49;3563:404;;;3640:88;3652:4;3658;3664:8;3674:4;;3640:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;;3688:11:10::1;::::0;::::1;::::0;3680:6;;-1:-1:-1;3688:20:10::1;::::0;3680:6;;3688:20:::1;:::i;:::-;3710:12:::0;;:17;3640:11:::1;:88::i;:::-;3761:4;:12;;;3750:23;;3804:4;:11;;;3795:20;;3844:7;3837:14;;3894:4;3884:15;;;;;;3873:26;;3935:12;:4;:10;:12::i;:::-;3921:27;;3563:404;3493:488;3269:712;3242:11;:4;:9;:11::i;:::-;3170:821;;;-1:-1:-1::0;4004:11:10;;:15;4000:134:::1;;4035:88;4047:4;4053;4059:8;4069:4;;4035:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;4075:6:10;;-1:-1:-1;4083:20:10::1;::::0;-1:-1:-1;4075:6:10;;-1:-1:-1;4083:4:10;:20:::1;:::i;:::-;4105:12:::0;;:17;4035:11:::1;:88::i;:::-;2961:1179;;;;;2877:1263:::0;;;;:::o;582:184:14:-;677:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;712:5:14::1;;693;:11;699:4;693:11;;;;;;;;;;;705:3;;693:16;;;;;;;:::i;:::-;;;;;;;;;;;;;:24;;;;;;;:::i;:::-;;750:3;;732:27;;;;;;;:::i;:::-;;;;;;;;744:4;732:27;755:3;;732:27;;;;;;;:::i;:::-;;;;;;;;582:184:::0;;;;;;:::o;1730:953:11:-;1817:7;1858:16;;;:10;:16;;;;;;;;-1:-1:-1;;;;;;1858:29:11;;;;;;;;;;-1:-1:-1;;;;;1858:29:11;1900:25;;1897:73;;1948:11;-1:-1:-1;1941:18:11;;1897:73;1980:9;1992:10;1997:4;1992;:10::i;:::-;1980:22;-1:-1:-1;;;;;;2015:15:11;;2012:62;;2061:1;2046:17;;;;;;2012:62;2139:71;;-1:-1:-1;;;2139:71:11;;;15571:52:16;2085:12:11;;;;-1:-1:-1;;;;;2126:12:11;;;15544:18:16;;2139:71:11;;;-1:-1:-1;;2139:71:11;;;;;;;;;;;;;;-1:-1:-1;;;;;2139:71:11;-1:-1:-1;;;2139:71:11;;;2126:85;;;2139:71;2126:85;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2084:127;;;;2225:7;2224:8;:34;;;;2256:2;2236:10;:17;:22;2224:34;:57;;;;2262:10;2273:2;2262:14;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;2262:14:11;:19;2224:57;2221:151;;;2359:1;2344:17;;;;;;;;2221:151;2419:65;;-1:-1:-1;;;;;;15589:33:16;;2419:65:11;;;15571:52:16;-1:-1:-1;;;;;2406:12:11;;;15544:18:16;;2419:65:11;;;-1:-1:-1;;2419:65:11;;;;;;;;;;;;;;-1:-1:-1;;;;;2419:65:11;-1:-1:-1;;;2419:65:11;;;2406:79;;;2419:65;2406:79;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2382:103:11;;-1:-1:-1;2382:103:11;-1:-1:-1;2498:8:11;;;:34;;;2530:2;2510:10;:17;:22;2498:34;:57;;;;2536:10;2547:2;2536:14;;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;2536:14:11;:19;2498:57;2495:163;;;2645:1;2630:17;;;;;;;;2495:163;-1:-1:-1;2675:1:11;;1730:953;-1:-1:-1;;;;;1730:953:11:o;1204:454:7:-;1276:7;1350:10;;;:4;:10;;;;;;;1285:12;;1371:249;1416:12;1401:11;:27;1371:249;;1468:26;;;1467:33;;;;:67;;-1:-1:-1;1533:1:7;1504:19;;;;;;;;;;:26;;;;;:::i;:::-;;;:30;1467:67;1463:147;;;1562:11;1575:6;:19;1582:11;1575:19;;;;;;;;;;;1554:41;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1463:147;1446:1;1430:17;1371:249;;;;1638:1;1641:9;;;;;;;;;;;;1630:21;;;;;1204:454;;;;;;:::o;621:169:13:-;696:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;728:15:13::1;::::0;;;;::::1;::::0;;;;;::::1;::::0;;::::1;::::0;;;-1:-1:-1;712:13:13;;;:7:::1;:13:::0;;;;;:31;;;;;::::1;::::0;;::::1;::::0;;;;758:25;;10421::16;;;10462:18;;;10455:34;;;712:13:13;;758:25:::1;::::0;10394:18:16;758:25:13::1;;;;;;;;621:169:::0;;;;:::o;514:166:9:-;593:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;609:12:9::1;::::0;;;:6:::1;:12;::::0;;;;:19:::1;624:4:::0;;609:12;:19:::1;:::i;:::-;;662:4;643:30;668:4;;643:30;;;;;;;:::i;981:228:8:-:0;1030:15;1057:14;1074:25;1079:4;270:2;1074:4;:25::i;:::-;1057:42;;1112:1;:8;1124:1;1112:13;1109:60;;-1:-1:-1;1156:1:8;;981:228;-1:-1:-1;;981:228:8:o;1109:60::-;1185:17;1200:1;1185:14;:17::i;:::-;1178:24;981:228;-1:-1:-1;;;981:228:8:o;983:127:14:-;1055:13;1087:5;:11;1093:4;1087:11;;;;;;;;;;;1099:3;;1087:16;;;;;;;:::i;:::-;;;;;;;;;;;;;1080:23;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;983:127;;;;;:::o;5943:109:10:-;6029:16;;;;:10;:16;;;;;6022:23;;5998:12;;6029:16;6022:23;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5943:109;;;:::o;591:292:7:-;683:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;773:11:7;754:15:::1;768:1;773:11:::0;754:15:::1;:::i;:::-;753:31;752:38:::0;744:47:::1;;;::::0;::::1;;802:10;::::0;;;:4:::1;:10;::::0;;;;;;;:23;;;;;;;;:30:::1;828:4:::0;;802:23;:30:::1;:::i;:::-;-1:-1:-1::0;847:29:7::1;::::0;864:11;;858:4;;847:29:::1;::::0;;;::::1;591:292:::0;;;;;:::o;853:101:12:-;936:11;;;;:5;:11;;;;;929:18;;904:13;;936:11;929:18;;;:::i;501:152::-;574:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;590:11:12::1;::::0;;;:5:::1;:11;::::0;;;;:18:::1;604:4:::0;;590:11;:18:::1;:::i;:::-;;635:4;623:23;641:4;;623:23;;;;;;;:::i;1215:286:8:-:0;1295:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;1331:4:8::1;1316:33;1337:8;1347:1;1316:33;;;;;;;:::i;:::-;;;;;;;;270:2;1362:8;:25:::0;1359:96:::1;;1420:4;1408:36;1426:17;1441:1;1426:14;:17::i;:::-;1408:36;::::0;-1:-1:-1;;;;;2620:32:16;;;2602:51;;2590:2;2575:18;1408:36:8::1;;;;;;;1359:96;1464:16;::::0;;;:10:::1;:16;::::0;;;;;;;:26;;;;;;;;:30:::1;1493:1:::0;1464:26;:30:::1;:::i;:::-;;1215:286:::0;;;;:::o;1321:150:3:-;3111:19:1;3134:13;;;;;;3133:14;;3179:34;;;;-1:-1:-1;3197:12:1;;3212:1;3197:12;;;;:16;3179:34;3178:108;;;-1:-1:-1;3258:4:1;1476:19:2;:23;;;3219:66:1;;-1:-1:-1;3268:12:1;;;;;:17;3219:66;3157:201;;;;-1:-1:-1;;;3157:201:1;;18998:2:16;3157:201:1;;;18980:21:16;19037:2;19017:18;;;19010:30;19076:34;19056:18;;;19049:62;-1:-1:-1;;;19127:18:16;;;19120:44;19181:19;;3157:201:1;;;;;;;;;3368:12;:16;;-1:-1:-1;;3368:16:1;3383:1;3368:16;;;3394:65;;;;3428:13;:20;;-1:-1:-1;;3428:20:1;;;;;3394:65;1422:42:3::1;1444:4;1449:14;1422:21;:42::i;:::-;3483:14:1::0;3479:99;;;3529:5;3513:21;;-1:-1:-1;;3513:21:1;;;3553:14;;-1:-1:-1;19363:36:16;;3553:14:1;;19351:2:16;19336:18;3553:14:1;;;;;;;3479:99;3101:483;1321:150:3;;:::o;1903:318::-;-1:-1:-1;;;;;2002:22:3;;:10;:22;1981:110;;;;-1:-1:-1;;;1981:110:3;;19612:2:16;1981:110:3;;;19594:21:16;19651:2;19631:18;;;19624:30;19690:34;19670:18;;;19663:62;-1:-1:-1;;;19741:18:16;;;19734:39;19790:19;;1981:110:3;19410:405:16;1981:110:3;2121:10;2102:30;;;;:18;:30;;;;;;;;-1:-1:-1;;;;;2102:40:3;;;;;;;;;;;;:51;;-1:-1:-1;;2102:51:3;;;;;;;;;;2168:46;;521:41:16;;;2102:40:3;;2121:10;2168:46;;494:18:16;2168:46:3;;;;;;;1903:318;;:::o;4542:168:10:-;4658:13;;;;:7;:13;;;;;;;;4672:8;:14;;;;;;4658:29;;;;;;;:35;;;;;;;;:45;;;;;;;;;;4651:52;;4627:12;;4658:45;4651:52;;;:::i;2754:366:3:-;2813:22;2869:4;2857:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2847:34;;2895:6;2891:199;2907:15;;;2891:199;;;2944:12;;2989:4;3008;;3013:1;3008:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;2981:35;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2943:73;;;;3038:7;3030:16;;;;;;3073:6;3060:7;3068:1;3060:10;;;;;;;;:::i;:::-;;;;;;:19;;;;2929:161;;2924:3;;;;;:::i;:::-;;;;2891:199;;;;2754:366;;;;:::o;5216:128:10:-;5270:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;5286:14:10::1;::::0;;;:8:::1;:14;::::0;;;;:16;;;::::1;::::0;::::1;:::i;:::-;::::0;;;-1:-1:-1;;5317:20:10::1;::::0;5332:4;;5317:20:::1;::::0;;;::::1;5216:128:::0;;:::o;847:108:9:-;936:12;;;;:6;:12;;;;;929:19;;905:12;;936;929:19;;;:::i;5564:225:10:-;5640:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;5656:20:10::1;5679:16:::0;;;:10:::1;:16;::::0;;;;5656:39;;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;5705:16:10::1;::::0;;;:10:::1;:16;::::0;;;;5656:39;;-1:-1:-1;5705:23:10::1;::::0;-1:-1:-1;5724:4:10;;-1:-1:-1;5724:4:10;5705:16;:23:::1;:::i;:::-;;5762:4;5743:39;5768:7;5777:4;;5743:39;;;;;;;;:::i;:::-;;;;;;;;5646:143;5564:225:::0;;;;:::o;690:132:8:-;752:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;768:47:8::1;776:4;270:2;797:17;812:1;797:14;:17::i;867:226:11:-:0;964:4;396:18:4;409:4;396:12;:18::i;:::-;388:27;;;;;;980:16:11::1;::::0;;;:10:::1;:16;::::0;;;;;;;-1:-1:-1;;;;;;980:29:11;::::1;::::0;;;;;;;;;;:43;;-1:-1:-1;;;;;;980:43:11::1;-1:-1:-1::0;;;;;980:43:11;::::1;::::0;;::::1;::::0;;;1038:48;;2602:51:16;;;980:16:11;;1038:48:::1;::::0;2575:18:16;1038:48:11::1;;;;;;;867:226:::0;;;;:::o;1507:127:8:-;1601:16;;;;:10;:16;;;;;;;;:26;;;;;;;;1594:33;;1570:12;;1601:26;1594:33;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1507:127;;;;:::o;1116:186:14:-;1200:4;-1:-1:-1;;;;;;1223:32:14;;-1:-1:-1;;;1223:32:14;;:72;;;1259:36;1283:11;1259:23;:36::i;2227:306:3:-;2326:3;;:15;;-1:-1:-1;;;2326:15:3;;;;;21318:25:16;;;2294:4:3;;;;-1:-1:-1;;;;;2326:3:3;;;;:9;;21291:18:16;;2326:15:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2371:11;;2310:31;;-1:-1:-1;;;;;;2371:11:3;;;2354:29;;;;2351:101;;2407:11;;:34;;-1:-1:-1;;;2407:34:3;;;;;21318:25:16;;;-1:-1:-1;;;;;2407:11:3;;;;:19;;21291:18:16;;2407:34:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2399:42;;2351:101;-1:-1:-1;;;;;2468:19:3;;2477:10;2468:19;;:58;;-1:-1:-1;;;;;;2704:27:3;;2682:4;2704:27;;;:18;:27;;;;;;;;2515:10;2704:37;;;;;;;;;;2491:35;2600:148;3831:182:6;3906:21;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3906:21:6;3939:15;;;3964:14;;;:23;;;3997:9;3939:3;3997:4;:9::i;5286:166::-;5397:11;;;;5421:9;;5346:12;;5377:68;;5410:34;;5397:11;5410:10;:34::i;:::-;5377:9;;;:68;:19;:68::i;5625:172::-;5737:16;;;;5755:15;;;;5686:12;;5717:73;;5755:34;;5737:16;;5755:34;:::i;4897:176:5:-;4974:4;5012:5;:12;4997:4;:11;:27;:69;;;;;5028:38;5035:4;5041:1;5044:5;5051:1;5054:4;:11;5028:6;:38::i;6326:965:10:-;6544:15;6562:14;;;:8;:14;;;;;;;;6605:15;;;;;;;;;6562:14;;6652:28;:4;6667:6;6675:4;6652:14;:28::i;:::-;6630:50;;6694:12;6690:595;;;6726:13;;;;:7;:13;;;;;;;;:22;;;;;;;;:32;;;;;;;;:42;;;;;;;;;;:49;;;;;:::i;:::-;:54;;-1:-1:-1;6722:136:10;;6800:22;;;;:16;:22;;;;;;;;:31;;;;;;;;:41;;;;;;;;:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;6722:136;6878:13;;;;:7;:13;;;;;;;;:22;;;;;;;;:32;;;;;;;;:42;;;;;;;;;;6871:50;;;:::i;:::-;6957:4;6940:38;6963:4;6969:8;6940:38;;;;;;;:::i;:::-;;;;;;;;6690:595;;;7013:13;;;;:7;:13;;;;;;;;:22;;;;;;;;:32;;;;;;;;:42;;;;;;;;;;:49;;;;;:::i;:::-;;;7066:1;7013:54;7009:136;;7087:22;;;;:16;:22;;;;;;;;:31;;;;;;;;:41;;;;;;;;:43;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;7009:136;7158:13;;;;:7;:13;;;;;;;;:22;;;;;;;;:32;;;;;;;;:42;;;;;;;;;;:51;7203:6;7158:42;:51;:::i;:::-;;7245:4;7228:46;7251:4;7257:8;7267:6;7228:46;;;;;;;;:::i;:::-;;;;;;;;6690:595;6534:757;;;6326:965;;;;;;;:::o;4428:682:6:-;4504:15;;;;4490:11;;;:29;;;4548:9;;:16;-1:-1:-1;4529:68:6;;4428:682;:::o;4529:68::-;4632:8;4657:34;4668:4;:9;;;4679:4;:11;;;4657:10;:34::i;:::-;4643:4;:11;;;:48;;;;:::i;:::-;4754:9;;4632:59;;-1:-1:-1;4754:25:6;;4632:59;4754:20;:25::i;:::-;4739:40;;:12;;;:40;4789:8;4796:1;4789:8;;:::i;:::-;4820:9;;4789:8;;-1:-1:-1;4820:25:6;;4789:8;4820:20;:25::i;:::-;4807:38;;:10;;;:38;4855:8;4862:1;4855:8;;:::i;:::-;4884:9;;4855:8;;-1:-1:-1;4884:25:6;;4855:8;4884:20;:25::i;:::-;4873:36;;:8;;;:36;4919:8;4926:1;4919:8;;:::i;:::-;4983:9;;4919:8;;-1:-1:-1;4964:16:6;;4983:25;;4919:8;4983:20;:25::i;:::-;4964:44;;;-1:-1:-1;5018:8:6;5025:1;5018:8;;:::i;:::-;5036:16;;;:22;;;5018:8;-1:-1:-1;5086:17:6;5092:11;5018:8;5086:17;:::i;:::-;5068:15;;;;:35;;;;-1:-1:-1;;4428:682:6:o;439:204:4:-;501:17;538:1;:8;550:2;538:14;530:23;;;;;;-1:-1:-1;608:2:4;601:10;595:17;-1:-1:-1;;;591:36:4;;;439:204::o;1481:173:3:-;4910:13:1;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:1;;;;;;;:::i;:::-;1595:52:3::1;1627:4;1632:14;1595:31;:52::i;:::-;1481:173:::0;;:::o;649:189:4:-;736:13;;;746:2;736:13;;;;;;;;;706:14;;736:13;;;;;;;;-1:-1:-1;;;;;;801:20:4;;;;796:2;789:10;;782:40;-1:-1:-1;801:20:4;649:189::o;1234:188:13:-;1318:4;-1:-1:-1;;;;;;1341:34:13;;-1:-1:-1;;;1341:34:13;;:74;;;1379:36;1403:11;1379:23;:36::i;534:367:6:-;608:4;635:6;651:215;691:4;:11;685:3;:17;678:25;;;;:::i;:::-;717:13;733:19;:4;748:3;733:14;:19::i;:::-;717:35;;;-1:-1:-1;773:12:6;717:35;784:1;773:12;:::i;:::-;766:19;;;;:::i;:::-;;;803:8;815:1;803:13;799:57;;836:5;;;799:57;664:202;651:215;;;882:12;888:6;882:3;:12;:::i;:::-;875:19;534:367;-1:-1:-1;;;;534:367:6:o;8723:393:5:-;8854:11;;8806:12;;8838;8847:3;8838:6;:12;:::i;:::-;:27;;8830:36;;;;;;8877:16;8906:3;8896:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8896:14:5;-1:-1:-1;8877:33:5;-1:-1:-1;8998:2:5;8989:12;;;;9021:26;;;;9066:22;8989:12;9021:26;9084:3;9066:6;:22::i;3261:209::-;3380:4;3432:31;3439:5;3446:11;3459:3;3432:6;:31::i;:::-;3403:25;3410:4;3416:6;3424:3;3403:6;:25::i;:::-;:60;;3261:209;-1:-1:-1;;;;;;3261:209:5:o;5681:223::-;5794:11;;5753:10;;5783:7;:3;5789:1;5783:7;:::i;:::-;:22;;5775:31;;;;;;-1:-1:-1;5856:22:5;5870:1;5856:22;5850:29;5881:6;5846:42;;5681:223::o;6148:227::-;6261:11;;6220:10;;6250:7;:3;6256:1;6250:7;:::i;:::-;:22;;6242:31;;;;;;-1:-1:-1;6323:22:5;6337:1;6323:22;6317:29;6348:10;6313:46;;6148:227::o;1660:171:3:-;4910:13:1;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:1;;;;;;;:::i;:::-;1776:3:3::1;:10:::0;;-1:-1:-1;;;;;1776:10:3;;::::1;-1:-1:-1::0;;;;;;1776:10:3;;::::1;;::::0;;;1796:11:::1;:28:::0;;;;;::::1;::::0;::::1;;::::0;;1660:171::o;960:186:12:-;1044:4;-1:-1:-1;;;;;;1067:32:12;;-1:-1:-1;;;1067:32:12;;:72;;;1103:36;1127:11;1103:23;:36::i;5315:122:5:-;5386:9;5420:4;5425:3;5420:9;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;5315:122:5;;;;:::o;7898:605::-;8032:2;8025:3;:9;8018:165;;8101:10;;8088:24;;8139:10;8147:2;8095:4;8139:10;:::i;:::-;;-1:-1:-1;8163:9:5;8170:2;8163:9;;:::i;:::-;;-1:-1:-1;8036:9:5;8043:2;8036:9;;:::i;:::-;;;8018:165;;;8344:10;;8403:11;;8270:2;:8;;;;8262:3;:17;-1:-1:-1;;8261:23:5;8356:9;;8340:26;;;8399:22;;8451:21;8438:35;;7898:605::o;305:238::-;433:11;;386;;417:12;426:3;417:6;:12;:::i;:::-;:27;;409:36;;;;;;-1:-1:-1;495:26:5;;509:2;495:26;485:42;;305:238::o;2689:219:11:-;2801:4;-1:-1:-1;;;;;;2824:37:11;;-1:-1:-1;;;2824:37:11;;:77;;;2865:36;2889:11;6142:4:10;-1:-1:-1;;;;;;6165:38:10;;-1:-1:-1;;;6165:38:10;;:93;;-1:-1:-1;;;;;;;6222:36:10;;-1:-1:-1;;;6222:36:10;6165:93;:148;;;;6277:36;6301:11;1045:4:9;-1:-1:-1;;;;;;1068:40:9;;-1:-1:-1;;;1068:40:9;;:80;;;1112:36;1136:11;1724:4:8;-1:-1:-1;;;;;;1747:32:8;;-1:-1:-1;;;1747:32:8;;:71;;-1:-1:-1;;;;;;;1783:35:8;;-1:-1:-1;;;1783:35:8;1747:71;:111;;;;1822:36;1846:11;1748:4:7;-1:-1:-1;;;;;;1771:31:7;;-1:-1:-1;;;1771:31:7;;:71;;-1:-1:-1;;;;;;;;;;221:32:4;;;1806:36:7;123:137:4;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;;;;;;;;;;;;;;;;;;:::o;14:173:16:-;81:20;;-1:-1:-1;;;;;;130:32:16;;120:43;;110:71;;177:1;174;167:12;110:71;14:173;;;:::o;192:184::-;250:6;303:2;291:9;282:7;278:23;274:32;271:52;;;319:1;316;309:12;271:52;342:28;360:9;342:28;:::i;573:347::-;624:8;634:6;688:3;681:4;673:6;669:17;665:27;655:55;;706:1;703;696:12;655:55;-1:-1:-1;729:20:16;;772:18;761:30;;758:50;;;804:1;801;794:12;758:50;841:4;833:6;829:17;817:29;;893:3;886:4;877:6;869;865:19;861:30;858:39;855:59;;;910:1;907;900:12;925:477;1004:6;1012;1020;1073:2;1061:9;1052:7;1048:23;1044:32;1041:52;;;1089:1;1086;1079:12;1041:52;1125:9;1112:23;1102:33;;1186:2;1175:9;1171:18;1158:32;1213:18;1205:6;1202:30;1199:50;;;1245:1;1242;1235:12;1199:50;1284:58;1334:7;1325:6;1314:9;1310:22;1284:58;:::i;:::-;925:477;;1361:8;;-1:-1:-1;1258:84:16;;-1:-1:-1;;;;925:477:16:o;1407:787::-;1508:6;1516;1524;1532;1540;1593:2;1581:9;1572:7;1568:23;1564:32;1561:52;;;1609:1;1606;1599:12;1561:52;1645:9;1632:23;1622:33;;1706:2;1695:9;1691:18;1678:32;1729:18;1770:2;1762:6;1759:14;1756:34;;;1786:1;1783;1776:12;1756:34;1825:58;1875:7;1866:6;1855:9;1851:22;1825:58;:::i;:::-;1902:8;;-1:-1:-1;1799:84:16;-1:-1:-1;1990:2:16;1975:18;;1962:32;;-1:-1:-1;2006:16:16;;;2003:36;;;2035:1;2032;2025:12;2003:36;;2074:60;2126:7;2115:8;2104:9;2100:24;2074:60;:::i;:::-;1407:787;;;;-1:-1:-1;1407:787:16;;-1:-1:-1;2153:8:16;;2048:86;1407:787;-1:-1:-1;;;1407:787:16:o;2199:252::-;2266:6;2274;2327:2;2315:9;2306:7;2302:23;2298:32;2295:52;;;2343:1;2340;2333:12;2295:52;2379:9;2366:23;2356:33;;2408:37;2441:2;2430:9;2426:18;2408:37;:::i;:::-;2398:47;;2199:252;;;;;:::o;2664:248::-;2732:6;2740;2793:2;2781:9;2772:7;2768:23;2764:32;2761:52;;;2809:1;2806;2799:12;2761:52;-1:-1:-1;;2832:23:16;;;2902:2;2887:18;;;2874:32;;-1:-1:-1;2664:248:16:o;2917:250::-;3002:1;3012:113;3026:6;3023:1;3020:13;3012:113;;;3102:11;;;3096:18;3083:11;;;3076:39;3048:2;3041:10;3012:113;;;-1:-1:-1;;3159:1:16;3141:16;;3134:27;2917:250::o;3172:270::-;3213:3;3251:5;3245:12;3278:6;3273:3;3266:19;3294:76;3363:6;3356:4;3351:3;3347:14;3340:4;3333:5;3329:16;3294:76;:::i;:::-;3424:2;3403:15;-1:-1:-1;;3399:29:16;3390:39;;;;3431:4;3386:50;;3172:270;-1:-1:-1;;3172:270:16:o;3447:288::-;3622:6;3611:9;3604:25;3665:2;3660;3649:9;3645:18;3638:30;3585:4;3685:44;3725:2;3714:9;3710:18;3702:6;3685:44;:::i;3740:316::-;3817:6;3825;3833;3886:2;3874:9;3865:7;3861:23;3857:32;3854:52;;;3902:1;3899;3892:12;3854:52;-1:-1:-1;;3925:23:16;;;3995:2;3980:18;;3967:32;;-1:-1:-1;4046:2:16;4031:18;;;4018:32;;3740:316;-1:-1:-1;3740:316:16:o;4061:180::-;4120:6;4173:2;4161:9;4152:7;4148:23;4144:32;4141:52;;;4189:1;4186;4179:12;4141:52;-1:-1:-1;4212:23:16;;4061:180;-1:-1:-1;4061:180:16:o;5206:219::-;5355:2;5344:9;5337:21;5318:4;5375:44;5415:2;5404:9;5400:18;5392:6;5375:44;:::i;5652:545::-;5740:6;5748;5756;5764;5817:2;5805:9;5796:7;5792:23;5788:32;5785:52;;;5833:1;5830;5823:12;5785:52;5869:9;5856:23;5846:33;;5926:2;5915:9;5911:18;5898:32;5888:42;;5981:2;5970:9;5966:18;5953:32;6008:18;6000:6;5997:30;5994:50;;;6040:1;6037;6030:12;5994:50;6079:58;6129:7;6120:6;6109:9;6105:22;6079:58;:::i;:::-;5652:545;;;;-1:-1:-1;6156:8:16;-1:-1:-1;;;;5652:545:16:o;6202:127::-;6263:10;6258:3;6254:20;6251:1;6244:31;6294:4;6291:1;6284:15;6318:4;6315:1;6308:15;6334:1057;6420:6;6428;6436;6489:2;6477:9;6468:7;6464:23;6460:32;6457:52;;;6505:1;6502;6495:12;6457:52;6541:9;6528:23;6518:33;;6598:2;6587:9;6583:18;6570:32;6560:42;;6653:2;6642:9;6638:18;6625:32;6676:18;6717:2;6709:6;6706:14;6703:34;;;6733:1;6730;6723:12;6703:34;6771:6;6760:9;6756:22;6746:32;;6816:7;6809:4;6805:2;6801:13;6797:27;6787:55;;6838:1;6835;6828:12;6787:55;6874:2;6861:16;6896:2;6892;6889:10;6886:36;;;6902:18;;:::i;:::-;6977:2;6971:9;6945:2;7031:13;;-1:-1:-1;;7027:22:16;;;7051:2;7023:31;7019:40;7007:53;;;7075:18;;;7095:22;;;7072:46;7069:72;;;7121:18;;:::i;:::-;7161:10;7157:2;7150:22;7196:2;7188:6;7181:18;7236:7;7231:2;7226;7222;7218:11;7214:20;7211:33;7208:53;;;7257:1;7254;7247:12;7208:53;7313:2;7308;7304;7300:11;7295:2;7287:6;7283:15;7270:46;7358:1;7353:2;7348;7340:6;7336:15;7332:24;7325:35;7379:6;7369:16;;;;;;;6334:1057;;;;;:::o;7396:136::-;-1:-1:-1;;;;;7476:31:16;;7466:42;;7456:70;;7522:1;7519;7512:12;7537:430;7637:6;7645;7698:2;7686:9;7677:7;7673:23;7669:32;7666:52;;;7714:1;7711;7704:12;7666:52;7753:9;7740:23;7772:36;7802:5;7772:36;:::i;:::-;7827:5;-1:-1:-1;7884:2:16;7869:18;;7856:32;7897:38;7856:32;7897:38;:::i;:::-;7954:7;7944:17;;;7537:430;;;;;:::o;7972:421::-;8037:6;8045;8098:2;8086:9;8077:7;8073:23;8069:32;8066:52;;;8114:1;8111;8104:12;8066:52;8153:9;8140:23;8172:36;8202:5;8172:36;:::i;:::-;8227:5;-1:-1:-1;8284:2:16;8269:18;;8256:32;8326:15;;8319:23;8307:36;;8297:64;;8357:1;8354;8347:12;8398:408;8474:6;8482;8490;8543:2;8531:9;8522:7;8518:23;8514:32;8511:52;;;8559:1;8556;8549:12;8511:52;8595:9;8582:23;8572:33;;8652:2;8641:9;8637:18;8624:32;8614:42;;8706:2;8695:9;8691:18;8678:32;8750:6;8743:5;8739:18;8732:5;8729:29;8719:57;;8772:1;8769;8762:12;8719:57;8795:5;8785:15;;;8398:408;;;;;:::o;8811:626::-;8908:6;8916;8969:2;8957:9;8948:7;8944:23;8940:32;8937:52;;;8985:1;8982;8975:12;8937:52;9025:9;9012:23;9054:18;9095:2;9087:6;9084:14;9081:34;;;9111:1;9108;9101:12;9081:34;9149:6;9138:9;9134:22;9124:32;;9194:7;9187:4;9183:2;9179:13;9175:27;9165:55;;9216:1;9213;9206:12;9165:55;9256:2;9243:16;9282:2;9274:6;9271:14;9268:34;;;9298:1;9295;9288:12;9268:34;9351:7;9346:2;9336:6;9333:1;9329:14;9325:2;9321:23;9317:32;9314:45;9311:65;;;9372:1;9369;9362:12;9311:65;9403:2;9395:11;;;;;9425:6;;-1:-1:-1;8811:626:16;;-1:-1:-1;;;;8811:626:16:o;9442:800::-;9602:4;9631:2;9671;9660:9;9656:18;9701:2;9690:9;9683:21;9724:6;9759;9753:13;9790:6;9782;9775:22;9828:2;9817:9;9813:18;9806:25;;9890:2;9880:6;9877:1;9873:14;9862:9;9858:30;9854:39;9840:53;;9928:2;9920:6;9916:15;9949:1;9959:254;9973:6;9970:1;9967:13;9959:254;;;10066:2;10062:7;10050:9;10042:6;10038:22;10034:36;10029:3;10022:49;10094:39;10126:6;10117;10111:13;10094:39;:::i;:::-;10084:49;-1:-1:-1;10191:12:16;;;;10156:15;;;;9995:1;9988:9;9959:254;;;-1:-1:-1;10230:6:16;;9442:800;-1:-1:-1;;;;;;;9442:800:16:o;10500:320::-;10568:6;10576;10629:2;10617:9;10608:7;10604:23;10600:32;10597:52;;;10645:1;10642;10635:12;10597:52;10681:9;10668:23;10658:33;;10741:2;10730:9;10726:18;10713:32;10754:36;10784:5;10754:36;:::i;10825:392::-;10901:6;10909;10917;10970:2;10958:9;10949:7;10945:23;10941:32;10938:52;;;10986:1;10983;10976:12;10938:52;11022:9;11009:23;10999:33;;11051:37;11084:2;11073:9;11069:18;11051:37;:::i;:::-;11041:47;;11138:2;11127:9;11123:18;11110:32;11151:36;11181:5;11151:36;:::i;11625:287::-;11754:3;11792:6;11786:13;11808:66;11867:6;11862:3;11855:4;11847:6;11843:17;11808:66;:::i;:::-;11890:16;;;;;11625:287;-1:-1:-1;;11625:287:16:o;11917:127::-;11978:10;11973:3;11969:20;11966:1;11959:31;12009:4;12006:1;11999:15;12033:4;12030:1;12023:15;12049:128;12116:9;;;12137:11;;;12134:37;;;12151:18;;:::i;12182:273::-;12367:6;12359;12354:3;12341:33;12323:3;12393:16;;12418:13;;;12393:16;12182:273;-1:-1:-1;12182:273:16:o;12460:380::-;12539:1;12535:12;;;;12582;;;12603:61;;12657:4;12649:6;12645:17;12635:27;;12603:61;12710:2;12702:6;12699:14;12679:18;12676:38;12673:161;;12756:10;12751:3;12747:20;12744:1;12737:31;12791:4;12788:1;12781:15;12819:4;12816:1;12809:15;12673:161;;12460:380;;;:::o;12971:545::-;13073:2;13068:3;13065:11;13062:448;;;13109:1;13134:5;13130:2;13123:17;13179:4;13175:2;13165:19;13249:2;13237:10;13233:19;13230:1;13226:27;13220:4;13216:38;13285:4;13273:10;13270:20;13267:47;;;-1:-1:-1;13308:4:16;13267:47;13363:2;13358:3;13354:12;13351:1;13347:20;13341:4;13337:31;13327:41;;13418:82;13436:2;13429:5;13426:13;13418:82;;;13481:17;;;13462:1;13451:13;13418:82;;;13422:3;;;12971:545;;;:::o;13692:1206::-;13816:18;13811:3;13808:27;13805:53;;;13838:18;;:::i;:::-;13867:94;13957:3;13917:38;13949:4;13943:11;13917:38;:::i;:::-;13911:4;13867:94;:::i;:::-;13987:1;14012:2;14007:3;14004:11;14029:1;14024:616;;;;14684:1;14701:3;14698:93;;;-1:-1:-1;14757:19:16;;;14744:33;14698:93;-1:-1:-1;;13649:1:16;13645:11;;;13641:24;13637:29;13627:40;13673:1;13669:11;;;13624:57;14804:78;;13997:895;;14024:616;12918:1;12911:14;;;12955:4;12942:18;;-1:-1:-1;;14060:17:16;;;14161:9;14183:229;14197:7;14194:1;14191:14;14183:229;;;14286:19;;;14273:33;14258:49;;14393:4;14378:20;;;;14346:1;14334:14;;;;14213:12;14183:229;;;14187:3;14440;14431:7;14428:16;14425:159;;;14564:1;14560:6;14554:3;14548;14545:1;14541:11;14537:21;14533:34;14529:39;14516:9;14511:3;14507:19;14494:33;14490:79;14482:6;14475:95;14425:159;;;14627:1;14621:3;14618:1;14614:11;14610:19;14604:4;14597:33;13997:895;;13692:1206;;;:::o;14903:267::-;14992:6;14987:3;14980:19;15044:6;15037:5;15030:4;15025:3;15021:14;15008:43;-1:-1:-1;15096:1:16;15071:16;;;15089:4;15067:27;;;15060:38;;;;15152:2;15131:15;;;-1:-1:-1;;15127:29:16;15118:39;;;15114:50;;14903:267::o;15175:247::-;15334:2;15323:9;15316:21;15297:4;15354:62;15412:2;15401:9;15397:18;15389:6;15381;15354:62;:::i;15634:127::-;15695:10;15690:3;15686:20;15683:1;15676:31;15726:4;15723:1;15716:15;15750:4;15747:1;15740:15;17441:1350;17565:3;17559:10;17592:18;17584:6;17581:30;17578:56;;;17614:18;;:::i;:::-;17643:97;17733:6;17693:38;17725:4;17719:11;17693:38;:::i;:::-;17687:4;17643:97;:::i;:::-;17795:4;;17859:2;17848:14;;17876:1;17871:663;;;;18578:1;18595:6;18592:89;;;-1:-1:-1;18647:19:16;;;18641:26;18592:89;-1:-1:-1;;13649:1:16;13645:11;;;13641:24;13637:29;13627:40;13673:1;13669:11;;;13624:57;18694:81;;17841:944;;17871:663;12918:1;12911:14;;;12955:4;12942:18;;-1:-1:-1;;17907:20:16;;;18025:236;18039:7;18036:1;18033:14;18025:236;;;18128:19;;;18122:26;18107:42;;18220:27;;;;18188:1;18176:14;;;;18055:19;;18025:236;;;18029:3;18289:6;18280:7;18277:19;18274:201;;;18350:19;;;18344:26;-1:-1:-1;;18433:1:16;18429:14;;;18445:3;18425:24;18421:37;18417:42;18402:58;18387:74;;18274:201;-1:-1:-1;;;;;18521:1:16;18505:14;;;18501:22;18488:36;;-1:-1:-1;17441:1350:16:o;19820:521::-;19897:4;19903:6;19963:11;19950:25;20057:2;20053:7;20042:8;20026:14;20022:29;20018:43;19998:18;19994:68;19984:96;;20076:1;20073;20066:12;19984:96;20103:33;;20155:20;;;-1:-1:-1;20198:18:16;20187:30;;20184:50;;;20230:1;20227;20220:12;20184:50;20263:4;20251:17;;-1:-1:-1;20294:14:16;20290:27;;;20280:38;;20277:58;;;20331:1;20328;20321:12;20622:135;20661:3;20682:17;;;20679:43;;20702:18;;:::i;:::-;-1:-1:-1;20749:1:16;20738:13;;20622:135::o;20762:405::-;20965:2;20954:9;20947:21;20928:4;20991:44;21031:2;21020:9;21016:18;21008:6;20991:44;:::i;:::-;21083:9;21075:6;21071:22;21066:2;21055:9;21051:18;21044:50;21111;21154:6;21146;21138;21111:50;:::i;:::-;21103:58;20762:405;-1:-1:-1;;;;;;20762:405:16:o;21354:256::-;21424:6;21477:2;21465:9;21456:7;21452:23;21448:32;21445:52;;;21493:1;21490;21483:12;21445:52;21525:9;21519:16;21544:36;21574:5;21544:36;:::i;21797:181::-;21835:3;21879:6;21872:5;21868:18;21905:7;21895:41;;21916:18;;:::i;:::-;-1:-1:-1;;21952:20:16;;21797:181;-1:-1:-1;;21797:181:16:o;21983:299::-;22156:2;22145:9;22138:21;22119:4;22176:44;22216:2;22205:9;22201:18;22193:6;22176:44;:::i;:::-;22168:52;;22268:6;22260;22256:19;22251:2;22240:9;22236:18;22229:47;21983:299;;;;;:::o;22287:197::-;22325:3;22353:6;22394:2;22387:5;22383:14;22421:2;22412:7;22409:15;22406:41;;22427:18;;:::i;:::-;22476:1;22463:15;;22287:197;-1:-1:-1;;;22287:197:16:o;22489:459::-;22708:2;22697:9;22690:21;22671:4;22734:44;22774:2;22763:9;22759:18;22751:6;22734:44;:::i;:::-;22826:6;22818;22814:19;22809:2;22798:9;22794:18;22787:47;22882:9;22874:6;22870:22;22865:2;22854:9;22850:18;22843:50;22910:32;22935:6;22927;22910:32;:::i;22953:125::-;23018:9;;;23039:10;;;23036:36;;;23052:18;;:::i;23083:407::-;23285:2;23267:21;;;23324:2;23304:18;;;23297:30;23363:34;23358:2;23343:18;;23336:62;-1:-1:-1;;;23429:2:16;23414:18;;23407:41;23480:3;23465:19;;23083:407::o;23495:127::-;23556:10;23551:3;23547:20;23544:1;23537:31;23587:4;23584:1;23577:15;23611:4;23608:1;23601:15
Swarm Source
ipfs://e30d7475a0a1ea044e380733e79e6529f4100781bc14b1fffe4616b82fa011ca
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.