Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
UniversalResolver
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.17 <0.9.0;
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {LowLevelCallUtils} from "./LowLevelCallUtils.sol";
import {ENS} from "../registry/ENS.sol";
import {IExtendedResolver} from "../resolvers/profiles/IExtendedResolver.sol";
import {Resolver, INameResolver, IAddrResolver} from "../resolvers/Resolver.sol";
import {NameEncoder} from "./NameEncoder.sol";
import {BytesUtils} from "../wrapper/BytesUtils.sol";
import {HexUtils} from "./HexUtils.sol";
error OffchainLookup(
address sender,
string[] urls,
bytes callData,
bytes4 callbackFunction,
bytes extraData
);
struct MulticallData {
bytes name;
bytes[] data;
string[] gateways;
bytes4 callbackFunction;
address resolver;
bytes metaData;
bool[] failures;
}
struct OffchainLookupCallData {
address sender;
string[] urls;
bytes callData;
}
struct OffchainLookupExtraData {
bytes4 callbackFunction;
bytes data;
}
interface BatchGateway {
function query(
OffchainLookupCallData[] memory data
) external returns (bool[] memory failures, bytes[] memory responses);
}
/**
* The Universal Resolver is a contract that handles the work of resolving a name entirely onchain,
* making it possible to make a single smart contract call to resolve an ENS name.
*/
contract UniversalResolver is ERC165, Ownable {
using Address for address;
using NameEncoder for string;
using BytesUtils for bytes;
using HexUtils for bytes;
string[] public batchGatewayURLs;
ENS public immutable registry;
constructor(address _registry, string[] memory _urls) {
registry = ENS(_registry);
batchGatewayURLs = _urls;
}
function setGatewayURLs(string[] memory _urls) public onlyOwner {
batchGatewayURLs = _urls;
}
/**
* @dev Performs ENS name resolution for the supplied name and resolution data.
* @param name The name to resolve, in normalised and DNS-encoded form.
* @param data The resolution data, as specified in ENSIP-10.
* @return The result of resolving the name.
*/
function resolve(
bytes calldata name,
bytes memory data
) external view returns (bytes memory, address) {
return
_resolveSingle(
name,
data,
batchGatewayURLs,
this.resolveSingleCallback.selector,
""
);
}
function resolve(
bytes calldata name,
bytes[] memory data
) external view returns (bytes[] memory, address) {
return resolve(name, data, batchGatewayURLs);
}
function resolve(
bytes calldata name,
bytes memory data,
string[] memory gateways
) external view returns (bytes memory, address) {
return
_resolveSingle(
name,
data,
gateways,
this.resolveSingleCallback.selector,
""
);
}
function resolve(
bytes calldata name,
bytes[] memory data,
string[] memory gateways
) public view returns (bytes[] memory, address) {
return
_resolve(name, data, gateways, this.resolveCallback.selector, "");
}
function _resolveSingle(
bytes calldata name,
bytes memory data,
string[] memory gateways,
bytes4 callbackFunction,
bytes memory metaData
) public view returns (bytes memory, address) {
bytes[] memory dataArr = new bytes[](1);
dataArr[0] = data;
(bytes[] memory results, address resolver) = _resolve(
name,
dataArr,
gateways,
callbackFunction,
metaData
);
return (results[0], resolver);
}
function _resolve(
bytes calldata name,
bytes[] memory data,
string[] memory gateways,
bytes4 callbackFunction,
bytes memory metaData
) internal view returns (bytes[] memory results, address resolverAddress) {
(Resolver resolver, ) = findResolver(name);
resolverAddress = address(resolver);
if (resolverAddress == address(0)) {
return (results, address(0));
}
results = _multicall(
MulticallData(
name,
data,
gateways,
callbackFunction,
resolverAddress,
metaData,
new bool[](data.length)
)
);
}
function reverse(
bytes calldata reverseName
) external view returns (string memory, address, address, address) {
return reverse(reverseName, batchGatewayURLs);
}
/**
* @dev Performs ENS name reverse resolution for the supplied reverse name.
* @param reverseName The reverse name to resolve, in normalised and DNS-encoded form. e.g. b6E040C9ECAaE172a89bD561c5F73e1C48d28cd9.addr.reverse
* @return The resolved name, the resolved address, the reverse resolver address, and the resolver address.
*/
function reverse(
bytes calldata reverseName,
string[] memory gateways
) public view returns (string memory, address, address, address) {
bytes memory encodedCall = abi.encodeCall(
INameResolver.name,
reverseName.namehash(0)
);
(
bytes memory resolvedReverseData,
address reverseResolverAddress
) = _resolveSingle(
reverseName,
encodedCall,
gateways,
this.reverseCallback.selector,
""
);
return
getForwardDataFromReverse(
resolvedReverseData,
reverseResolverAddress,
gateways
);
}
function getForwardDataFromReverse(
bytes memory resolvedReverseData,
address reverseResolverAddress,
string[] memory gateways
) internal view returns (string memory, address, address, address) {
string memory resolvedName = abi.decode(resolvedReverseData, (string));
(bytes memory encodedName, bytes32 namehash) = resolvedName
.dnsEncodeName();
bytes memory encodedCall = abi.encodeCall(IAddrResolver.addr, namehash);
bytes memory metaData = abi.encode(
resolvedName,
reverseResolverAddress
);
(bytes memory resolvedData, address resolverAddress) = this
._resolveSingle(
encodedName,
encodedCall,
gateways,
this.reverseCallback.selector,
metaData
);
address resolvedAddress = abi.decode(resolvedData, (address));
return (
resolvedName,
resolvedAddress,
reverseResolverAddress,
resolverAddress
);
}
function resolveSingleCallback(
bytes calldata response,
bytes calldata extraData
) external view returns (bytes memory, address) {
(bytes[] memory results, address resolver, , ) = _resolveCallback(
response,
extraData,
this.resolveSingleCallback.selector
);
return (results[0], resolver);
}
function resolveCallback(
bytes calldata response,
bytes calldata extraData
) external view returns (bytes[] memory, address) {
(bytes[] memory results, address resolver, , ) = _resolveCallback(
response,
extraData,
this.resolveCallback.selector
);
return (results, resolver);
}
function reverseCallback(
bytes calldata response,
bytes calldata extraData
) external view returns (string memory, address, address, address) {
(
bytes[] memory resolvedData,
address resolverAddress,
string[] memory gateways,
bytes memory metaData
) = _resolveCallback(
response,
extraData,
this.reverseCallback.selector
);
if (metaData.length > 0) {
(string memory resolvedName, address reverseResolverAddress) = abi
.decode(metaData, (string, address));
address resolvedAddress = abi.decode(resolvedData[0], (address));
return (
resolvedName,
resolvedAddress,
reverseResolverAddress,
resolverAddress
);
}
return
getForwardDataFromReverse(
resolvedData[0],
resolverAddress,
gateways
);
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override returns (bool) {
return
interfaceId == type(IExtendedResolver).interfaceId ||
super.supportsInterface(interfaceId);
}
function _resolveCallback(
bytes calldata response,
bytes calldata extraData,
bytes4 callbackFunction
)
internal
view
returns (bytes[] memory, address, string[] memory, bytes memory)
{
MulticallData memory multicallData;
multicallData.callbackFunction = callbackFunction;
(bool[] memory failures, bytes[] memory responses) = abi.decode(
response,
(bool[], bytes[])
);
OffchainLookupExtraData[] memory extraDatas;
(
multicallData.resolver,
multicallData.gateways,
multicallData.metaData,
extraDatas
) = abi.decode(
extraData,
(address, string[], bytes, OffchainLookupExtraData[])
);
require(responses.length <= extraDatas.length);
multicallData.data = new bytes[](extraDatas.length);
multicallData.failures = new bool[](extraDatas.length);
uint256 offchainCount = 0;
for (uint256 i = 0; i < extraDatas.length; i++) {
if (extraDatas[i].callbackFunction == bytes4(0)) {
// This call did not require an offchain lookup; use the previous input data.
multicallData.data[i] = extraDatas[i].data;
} else {
if (failures[offchainCount]) {
multicallData.failures[i] = true;
multicallData.data[i] = responses[offchainCount];
} else {
multicallData.data[i] = abi.encodeWithSelector(
extraDatas[i].callbackFunction,
responses[offchainCount],
extraDatas[i].data
);
}
offchainCount = offchainCount + 1;
}
}
return (
_multicall(multicallData),
multicallData.resolver,
multicallData.gateways,
multicallData.metaData
);
}
/**
* @dev Makes a call to `target` with `data`. If the call reverts with an `OffchainLookup` error, wraps
* the error with the data necessary to continue the request where it left off.
* @param target The address to call.
* @param data The data to call `target` with.
* @return offchain Whether the call reverted with an `OffchainLookup` error.
* @return returnData If `target` did not revert, contains the return data from the call to `target`. Otherwise, contains a `OffchainLookupCallData` struct.
* @return extraData If `target` did not revert, is empty. Otherwise, contains a `OffchainLookupExtraData` struct.
* @return result Whether the call succeeded.
*/
function callWithOffchainLookupPropagation(
address target,
bytes memory data
)
internal
view
returns (
bool offchain,
bytes memory returnData,
OffchainLookupExtraData memory extraData,
bool result
)
{
result = LowLevelCallUtils.functionStaticCall(address(target), data);
uint256 size = LowLevelCallUtils.returnDataSize();
if (result) {
return (
false,
LowLevelCallUtils.readReturnData(0, size),
extraData,
true
);
}
// Failure
if (size >= 4) {
bytes memory errorId = LowLevelCallUtils.readReturnData(0, 4);
// Offchain lookup. Decode the revert message and create our own that nests it.
bytes memory revertData = LowLevelCallUtils.readReturnData(
4,
size - 4
);
if (bytes4(errorId) == OffchainLookup.selector) {
(
address wrappedSender,
string[] memory wrappedUrls,
bytes memory wrappedCallData,
bytes4 wrappedCallbackFunction,
bytes memory wrappedExtraData
) = abi.decode(
revertData,
(address, string[], bytes, bytes4, bytes)
);
if (wrappedSender == target) {
returnData = abi.encode(
OffchainLookupCallData(
wrappedSender,
wrappedUrls,
wrappedCallData
)
);
extraData = OffchainLookupExtraData(
wrappedCallbackFunction,
wrappedExtraData
);
return (true, returnData, extraData, false);
}
} else {
returnData = revertData;
return (false, returnData, extraData, false);
}
}
}
/**
* @dev Finds a resolver by recursively querying the registry, starting at the longest name and progressively
* removing labels until it finds a result.
* @param name The name to resolve, in DNS-encoded and normalised form.
* @return The Resolver responsible for this name, and the namehash of the full name.
*/
function findResolver(
bytes calldata name
) public view returns (Resolver, bytes32) {
(address resolver, bytes32 labelhash) = findResolver(name, 0);
return (Resolver(resolver), labelhash);
}
function findResolver(
bytes calldata name,
uint256 offset
) internal view returns (address, bytes32) {
uint256 labelLength = uint256(uint8(name[offset]));
if (labelLength == 0) {
return (address(0), bytes32(0));
}
uint256 nextLabel = offset + labelLength + 1;
bytes32 labelHash;
if (
labelLength == 66 &&
// 0x5b == '['
name[offset + 1] == 0x5b &&
// 0x5d == ']'
name[nextLabel - 1] == 0x5d
) {
// Encrypted label
(labelHash, ) = bytes(name[offset + 2:nextLabel - 1])
.hexStringToBytes32(0, 64);
} else {
labelHash = keccak256(name[offset + 1:nextLabel]);
}
(address parentresolver, bytes32 parentnode) = findResolver(
name,
nextLabel
);
bytes32 node = keccak256(abi.encodePacked(parentnode, labelHash));
address resolver = registry.resolver(node);
if (resolver != address(0)) {
return (resolver, node);
}
return (parentresolver, node);
}
function _hasExtendedResolver(
address resolver
) internal view returns (bool) {
try
Resolver(resolver).supportsInterface(
type(IExtendedResolver).interfaceId
)
returns (bool supported) {
return supported;
} catch {
return false;
}
}
function _multicall(
MulticallData memory multicallData
) internal view returns (bytes[] memory results) {
uint256 length = multicallData.data.length;
uint256 offchainCount = 0;
OffchainLookupCallData[]
memory callDatas = new OffchainLookupCallData[](length);
OffchainLookupExtraData[]
memory extraDatas = new OffchainLookupExtraData[](length);
results = new bytes[](length);
bool isCallback = multicallData.name.length == 0;
bool hasExtendedResolver = _hasExtendedResolver(multicallData.resolver);
for (uint256 i = 0; i < length; i++) {
bytes memory item = multicallData.data[i];
bool failure = multicallData.failures[i];
if (failure) {
results[i] = item;
continue;
}
if (!isCallback && hasExtendedResolver) {
item = abi.encodeCall(
IExtendedResolver.resolve,
(multicallData.name, item)
);
}
(
bool offchain,
bytes memory returnData,
OffchainLookupExtraData memory extraData,
bool success
) = callWithOffchainLookupPropagation(multicallData.resolver, item);
if (offchain) {
callDatas[offchainCount] = abi.decode(
returnData,
(OffchainLookupCallData)
);
extraDatas[i] = extraData;
offchainCount += 1;
continue;
}
if (success && hasExtendedResolver) {
// if this is a successful resolve() call, unwrap the result
returnData = abi.decode(returnData, (bytes));
}
results[i] = returnData;
extraDatas[i].data = multicallData.data[i];
}
if (offchainCount == 0) {
return results;
}
// Trim callDatas if offchain data exists
assembly {
mstore(callDatas, offchainCount)
}
revert OffchainLookup(
address(this),
multicallData.gateways,
abi.encodeWithSelector(BatchGateway.query.selector, callDatas),
multicallData.callbackFunction,
abi.encode(
multicallData.resolver,
multicallData.gateways,
multicallData.metaData,
extraDatas
)
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}pragma solidity >=0.8.4;
interface ENS {
// 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;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(
address owner,
address operator
) external view returns (bool);
}//SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import "./profiles/IABIResolver.sol";
import "./profiles/IAddressResolver.sol";
import "./profiles/IAddrResolver.sol";
import "./profiles/IContentHashResolver.sol";
import "./profiles/IDNSRecordResolver.sol";
import "./profiles/IDNSZoneResolver.sol";
import "./profiles/IInterfaceResolver.sol";
import "./profiles/INameResolver.sol";
import "./profiles/IPubkeyResolver.sol";
import "./profiles/ITextResolver.sol";
import "./profiles/IExtendedResolver.sol";
/**
* A generic resolver interface which includes all the functions including the ones deprecated
*/
interface Resolver is
IERC165,
IABIResolver,
IAddressResolver,
IAddrResolver,
IContentHashResolver,
IDNSRecordResolver,
IDNSZoneResolver,
IInterfaceResolver,
INameResolver,
IPubkeyResolver,
ITextResolver,
IExtendedResolver
{
/* Deprecated events */
event ContentChanged(bytes32 indexed node, bytes32 hash);
function setABI(
bytes32 node,
uint256 contentType,
bytes calldata data
) external;
function setAddr(bytes32 node, address addr) external;
function setAddr(bytes32 node, uint256 coinType, bytes calldata a) external;
function setContenthash(bytes32 node, bytes calldata hash) external;
function setDnsrr(bytes32 node, bytes calldata data) external;
function setName(bytes32 node, string calldata _name) external;
function setPubkey(bytes32 node, bytes32 x, bytes32 y) external;
function setText(
bytes32 node,
string calldata key,
string calldata value
) external;
function setInterface(
bytes32 node,
bytes4 interfaceID,
address implementer
) external;
function multicall(
bytes[] calldata data
) external returns (bytes[] memory results);
function multicallWithNodeCheck(
bytes32 nodehash,
bytes[] calldata data
) external returns (bytes[] memory results);
/* Deprecated functions */
function content(bytes32 node) external view returns (bytes32);
function multihash(bytes32 node) external view returns (bytes memory);
function setContent(bytes32 node, bytes32 hash) external;
function setMultihash(bytes32 node, bytes calldata hash) external;
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IABIResolver {
event ABIChanged(bytes32 indexed node, uint256 indexed 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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/**
* Interface for the legacy (ETH-only) addr function.
*/
interface IAddrResolver {
event AddrChanged(bytes32 indexed node, address a);
/**
* Returns the address associated with an ENS node.
* @param node The ENS node to query.
* @return The associated address.
*/
function addr(bytes32 node) external view returns (address payable);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
/**
* Interface for the new (multicoin) addr function.
*/
interface IAddressResolver {
event AddressChanged(
bytes32 indexed node,
uint256 coinType,
bytes newAddress
);
function addr(
bytes32 node,
uint256 coinType
) external view returns (bytes memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IContentHashResolver {
event ContenthashChanged(bytes32 indexed node, bytes 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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IDNSRecordResolver {
// 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);
/**
* 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
) external view returns (bytes memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IDNSZoneResolver {
// DNSZonehashChanged is emitted whenever a given node's zone hash is updated.
event DNSZonehashChanged(
bytes32 indexed node,
bytes lastzonehash,
bytes zonehash
);
/**
* 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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
interface IExtendedResolver {
function resolve(
bytes memory name,
bytes memory data
) external view returns (bytes memory);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IInterfaceResolver {
event InterfaceChanged(
bytes32 indexed node,
bytes4 indexed interfaceID,
address 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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface INameResolver {
event NameChanged(bytes32 indexed node, string 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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface IPubkeyResolver {
event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 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);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
interface ITextResolver {
event TextChanged(
bytes32 indexed node,
string indexed indexedKey,
string key,
string value
);
/**
* 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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
library HexUtils {
/**
* @dev Attempts to parse bytes32 from a hex string
* @param str The string to parse
* @param idx The offset to start parsing at
* @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.
*/
function hexStringToBytes32(
bytes memory str,
uint256 idx,
uint256 lastIdx
) internal pure returns (bytes32 r, bool valid) {
valid = true;
assembly {
// check that the index to read to is not past the end of the string
if gt(lastIdx, mload(str)) {
revert(0, 0)
}
function getHex(c) -> ascii {
// chars 48-57: 0-9
if and(gt(c, 47), lt(c, 58)) {
ascii := sub(c, 48)
leave
}
// chars 65-70: A-F
if and(gt(c, 64), lt(c, 71)) {
ascii := add(sub(c, 65), 10)
leave
}
// chars 97-102: a-f
if and(gt(c, 96), lt(c, 103)) {
ascii := add(sub(c, 97), 10)
leave
}
// invalid char
ascii := 0xff
}
let ptr := add(str, 32)
for {
let i := idx
} lt(i, lastIdx) {
i := add(i, 2)
} {
let byte1 := getHex(byte(0, mload(add(ptr, i))))
let byte2 := getHex(byte(0, mload(add(ptr, add(i, 1)))))
// if either byte is invalid, set invalid and break loop
if or(eq(byte1, 0xff), eq(byte2, 0xff)) {
valid := false
break
}
let combined := or(shl(4, byte1), byte2)
r := or(shl(8, r), combined)
}
}
}
/**
* @dev Attempts to parse an address from a hex string
* @param str The string to parse
* @param idx The offset to start parsing at
* @param lastIdx The (exclusive) last index in `str` to consider. Use `str.length` to scan the whole string.
*/
function hexToAddress(
bytes memory str,
uint256 idx,
uint256 lastIdx
) internal pure returns (address, bool) {
if (lastIdx - idx < 40) return (address(0x0), false);
(bytes32 r, bool valid) = hexStringToBytes32(str, idx, lastIdx);
return (address(uint160(uint256(r))), valid);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
library LowLevelCallUtils {
using Address for address;
/**
* @dev Makes a static call to the specified `target` with `data`. Return data can be fetched with
* `returnDataSize` and `readReturnData`.
* @param target The address to staticcall.
* @param data The data to pass to the call.
* @return success True if the call succeeded, or false if it reverts.
*/
function functionStaticCall(
address target,
bytes memory data
) internal view returns (bool success) {
require(
target.isContract(),
"LowLevelCallUtils: static call to non-contract"
);
assembly {
success := staticcall(
gas(),
target,
add(data, 32),
mload(data),
0,
0
)
}
}
/**
* @dev Returns the size of the return data of the most recent external call.
*/
function returnDataSize() internal pure returns (uint256 len) {
assembly {
len := returndatasize()
}
}
/**
* @dev Reads return data from the most recent external call.
* @param offset Offset into the return data.
* @param length Number of bytes to return.
*/
function readReturnData(
uint256 offset,
uint256 length
) internal pure returns (bytes memory data) {
data = new bytes(length);
assembly {
returndatacopy(add(data, 32), offset, length)
}
}
/**
* @dev Reverts with the return data from the most recent external call.
*/
function propagateRevert() internal pure {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {BytesUtils} from "../wrapper/BytesUtils.sol";
library NameEncoder {
using BytesUtils for bytes;
function dnsEncodeName(
string memory name
) internal pure returns (bytes memory dnsName, bytes32 node) {
uint8 labelLength = 0;
bytes memory bytesName = bytes(name);
uint256 length = bytesName.length;
dnsName = new bytes(length + 2);
node = 0;
if (length == 0) {
dnsName[0] = 0;
return (dnsName, node);
}
// use unchecked to save gas since we check for an underflow
// and we check for the length before the loop
unchecked {
for (uint256 i = length - 1; i >= 0; i--) {
if (bytesName[i] == ".") {
dnsName[i + 1] = bytes1(labelLength);
node = keccak256(
abi.encodePacked(
node,
bytesName.keccak(i + 1, labelLength)
)
);
labelLength = 0;
} else {
labelLength += 1;
dnsName[i + 1] = bytesName[i];
}
if (i == 0) {
break;
}
}
}
node = keccak256(
abi.encodePacked(node, bytesName.keccak(0, labelLength))
);
dnsName[0] = bytes1(labelLength);
return (dnsName, node);
}
}//SPDX-License-Identifier: MIT
pragma solidity ~0.8.17;
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,
uint256 offset,
uint256 len
) internal pure returns (bytes32 ret) {
require(offset + len <= self.length);
assembly {
ret := keccak256(add(add(self, 32), offset), len)
}
}
/**
* @dev Returns the ENS namehash of a DNS-encoded name.
* @param self The DNS-encoded name to hash.
* @param offset The offset at which to start hashing.
* @return The namehash of the name.
*/
function namehash(
bytes memory self,
uint256 offset
) internal pure returns (bytes32) {
(bytes32 labelhash, uint256 newOffset) = readLabel(self, offset);
if (labelhash == bytes32(0)) {
require(offset == self.length - 1, "namehash: Junk at end of name");
return bytes32(0);
}
return
keccak256(abi.encodePacked(namehash(self, newOffset), labelhash));
}
/**
* @dev Returns the keccak-256 hash of a DNS-encoded label, and the offset to the start of the next label.
* @param self The byte string to read a label from.
* @param idx The index to read a label at.
* @return labelhash The hash of the label at the specified index, or 0 if it is the last label.
* @return newIdx The index of the start of the next label.
*/
function readLabel(
bytes memory self,
uint256 idx
) internal pure returns (bytes32 labelhash, uint256 newIdx) {
require(idx < self.length, "readLabel: Index out of bounds");
uint256 len = uint256(uint8(self[idx]));
if (len > 0) {
labelhash = keccak(self, idx + 1, len);
} else {
labelhash = bytes32(0);
}
newIdx = idx + len + 1;
}
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1500
},
"remappings": [],
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_registry","type":"address"},{"internalType":"string[]","name":"_urls","type":"string[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"string[]","name":"urls","type":"string[]"},{"internalType":"bytes","name":"callData","type":"bytes"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"OffchainLookup","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"},{"internalType":"bytes4","name":"callbackFunction","type":"bytes4"},{"internalType":"bytes","name":"metaData","type":"bytes"}],"name":"_resolveSingle","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"batchGatewayURLs","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"}],"name":"findResolver","outputs":[{"internalType":"contract Resolver","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"resolve","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes[]","name":"data","type":"bytes[]"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"resolve","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"name","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"resolve","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"resolveCallback","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"resolveSingleCallback","outputs":[{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"reverseName","type":"bytes"},{"internalType":"string[]","name":"gateways","type":"string[]"}],"name":"reverse","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"reverseName","type":"bytes"}],"name":"reverse","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"reverseCallback","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string[]","name":"_urls","type":"string[]"}],"name":"setGatewayURLs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b506040516200373a3803806200373a8339810160408190526200003491620001da565b6200003f336200006a565b6001600160a01b038216608052805162000061906001906020840190620000ba565b5050506200049c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000105579160200282015b82811115620001055782518290620000f49082620003d0565b5091602001919060010190620000db565b506200011392915062000117565b5090565b80821115620001135760006200012e828262000138565b5060010162000117565b508054620001469062000341565b6000825580601f1062000157575050565b601f0160209004906000526020600020908101906200017791906200017a565b50565b5b808211156200011357600081556001016200017b565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620001d257620001d262000191565b604052919050565b6000806040808486031215620001ef57600080fd5b83516001600160a01b03811681146200020757600080fd5b602085810151919450906001600160401b03808211156200022757600080fd5b8187019150601f88818401126200023d57600080fd5b82518281111562000252576200025262000191565b8060051b62000263868201620001a7565b918252848101860191868101908c8411156200027e57600080fd5b87870192505b838310156200032e578251868111156200029e5760008081fd5b8701603f81018e13620002b15760008081fd5b8881015187811115620002c857620002c862000191565b620002db818801601f19168b01620001a7565b8181528f8c838501011115620002f15760008081fd5b60005b8281101562000311578381018d01518282018d01528b01620002f4565b5060009181018b0191909152835250918701919087019062000284565b8099505050505050505050509250929050565b600181811c908216806200035657607f821691505b6020821081036200037757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003cb57600081815260208120601f850160051c81016020861015620003a65750805b601f850160051c820191505b81811015620003c757828155600101620003b2565b5050505b505050565b81516001600160401b03811115620003ec57620003ec62000191565b6200040481620003fd845462000341565b846200037d565b602080601f8311600181146200043c5760008415620004235750858301515b600019600386901b1c1916600185901b178555620003c7565b600085815260208120601f198616915b828110156200046d578886015182559484019460019091019084016200044c565b50858210156200048c5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161327b620004bf600039600081816101ea01526113b9015261327b6000f3fe608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102e6578063ec11c823146102f9578063f2fde38b1461030c57600080fd5b8063b241d0d3146102c0578063b4a85801146102d357600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a057600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612091565b61031f565b60405190151581526020015b60405180910390f35b6101766101713660046122b1565b610356565b60405161015a92919061238f565b61019761019236600461243a565b61038b565b60405161015a9291906124a3565b6101b86101b3366004612518565b610479565b60405161015a9493929190612584565b6101d0610546565b005b6101976101e03660046125c0565b61055a565b61020c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461261f565b610582565b6101d06102563660046126e5565b610618565b610176610269366004612722565b610637565b61028161027c366004612781565b610730565b604080516001600160a01b03909316835260208301919091520161015a565b6102b36102ae3660046127c3565b610751565b60405161015a91906127dc565b6101b86102ce3660046127ef565b6107fd565b6101976102e1366004612518565b6108ee565b6101766102f4366004612518565b610932565b6101b8610307366004612781565b610996565b6101d061031a366004612863565b610a8b565b60006001600160e01b03198216639061b92360e01b148061035057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600061037e8686868663e0a8541260e01b60405180602001604052806000815250610582565b9150915094509492505050565b6060600061046c8585856001805480602002602001604051908101604052809291908181526020016000905b828210156104635783829060005260206000200180546103d690612880565b80601f016020809104026020016040519081016040528092919081815260200182805461040290612880565b801561044f5780601f106104245761010080835404028352916020019161044f565b820191906000526020600020905b81548152906001019060200180831161043257829003601f168201915b5050505050815260200190600101906103b7565b5050505061055a565b915091505b935093915050565b606060008080808080806104978c8c8c8c636dc4fb7360e01b610b20565b935093509350935060008151111561050957600080828060200190518101906104c091906128ff565b915091506000866000815181106104d9576104d9612951565b60200260200101518060200190518101906104f49190612967565b929a50919850965092945061053b9350505050565b61052e8460008151811061051f5761051f612951565b60200260200101518484610e94565b9750975097509750505050505b945094509450949050565b61054e610ff5565b610558600061104f565b565b6060600061037e8686868663b4a8580160e01b604051806020016040528060008152506110b7565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059e57905050905086816000815181106105c9576105c9612951565b60200260200101819052506000806105e58b8b858b8b8b6110b7565b91509150816000815181106105fc576105fc612951565b602002602001015181945094505050505b965096945050505050565b610620610ff5565b8051610633906001906020840190611fbe565b5050565b6060600061046c8585856001805480602002602001604051908101604052809291908181526020016000905b8282101561070f57838290600052602060002001805461068290612880565b80601f01602080910402602001604051908101604052809291908181526020018280546106ae90612880565b80156106fb5780601f106106d0576101008083540402835291602001916106fb565b820191906000526020600020905b8154815290600101906020018083116106de57829003601f168201915b505050505081526020019060010190610663565b5050505063e0a8541260e01b60405180602001604052806000815250610582565b600080600080610742868660006111ba565b909450925050505b9250929050565b6001818154811061076157600080fd5b90600052602060002001600091509050805461077c90612880565b80601f01602080910402602001604051908101604052809291908181526020018280546107a890612880565b80156107f55780601f106107ca576101008083540402835291602001916107f5565b820191906000526020600020905b8154815290600101906020018083116107d857829003601f168201915b505050505081565b6060600080600080610849600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506114569050565b60405160240161085b91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108cb908b908b9086908c90636dc4fb7360e01b90610582565b915091506108da82828a610e94565b965096509650965050505093509350935093565b606060008080610921888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b20565b50919a909950975050505050505050565b606060008080610965888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b20565b5050915091508160008151811061097e5761097e612951565b60200260200101518193509350505094509492505050565b60606000806000610a7986866001805480602002602001604051908101604052809291908181526020016000905b82821015610a705783829060005260206000200180546109e390612880565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0f90612880565b8015610a5c5780601f10610a3157610100808354040283529160200191610a5c565b820191906000526020600020905b815481529060010190602001808311610a3f57829003601f168201915b5050505050815260200190600101906109c4565b505050506107fd565b93509350935093505b92959194509250565b610a93610ff5565b6001600160a01b038116610b145760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b1d8161104f565b50565b60606000606080610b7a6040518060e0016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610b998b8d018d612992565b90925090506060610bac8a8c018c612a4a565b60a088019190915260408701919091526001600160a01b039091166080860152805183519192501015610bde57600080fd5b805167ffffffffffffffff811115610bf857610bf86120f7565b604051908082528060200260200182016040528015610c2b57816020015b6060815260200190600190039081610c165790505b506020850152805167ffffffffffffffff811115610c4b57610c4b6120f7565b604051908082528060200260200182016040528015610c74578160200160208202803683370190505b5060c08501526000805b8251811015610e62578251600090849083908110610c9e57610c9e612951565b6020026020010151600001516001600160e01b03191603610cfd57828181518110610ccb57610ccb612951565b60200260200101516020015186602001518281518110610ced57610ced612951565b6020026020010181905250610e50565b848281518110610d0f57610d0f612951565b602002602001015115610d865760018660c001518281518110610d3457610d34612951565b602002602001019015159081151581525050838281518110610d5857610d58612951565b602002602001015186602001518281518110610d7657610d76612951565b6020026020010181905250610e42565b828181518110610d9857610d98612951565b602002602001015160000151848381518110610db657610db6612951565b6020026020010151848381518110610dd057610dd0612951565b602002602001015160200151604051602401610ded929190612ba9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e3657610e36612951565b60200260200101819052505b610e4d826001612bed565b91505b80610e5a81612c00565b915050610c7e565b50610e6c85611515565b856080015186604001518760a001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610eb09190612c19565b9050600080610ebe83611913565b91509150600081604051602401610ed791815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f319187918e910161238f565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610f80959493929190612ca3565b600060405180830381865afa158015610f9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc591908101906128ff565b91509150600082806020019051810190610fdf9190612967565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b0b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60606000806110c68989610730565b5091508190506001600160a01b0381166110e457506000905061060d565b604080516101006020601f8c01819004028201810190925260e081018a81526111ac928291908d908d9081908501838280828437600092019190915250505090825250602081018a9052604081018990526001600160e01b0319881660608201526001600160a01b038516608082015260a08101879052895160c09091019067ffffffffffffffff81111561117b5761117b6120f7565b6040519080825280602002602001820160405280156111a4578160200160208202803683370190505b509052611515565b925050965096945050505050565b60008060008585858181106111d1576111d1612951565b919091013560f81c91505060008190036111f2575060009150819050610471565b60006111fe8286612bed565b611209906001612bed565b9050600082604214801561124f57508787611225886001612bed565b81811061123457611234612951565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b801561128d57508787611263600185612d0c565b81811061127257611272612951565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b15611305576112fd600060408a8a6112a68b6002612bed565b906112b2600189612d0c565b926112bf93929190612d1f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611b3c9050565b509050611337565b8787611312886001612bed565b61131e92859290612d1f565b60405161132c929190612d49565b604051809103902090505b6000806113458a8a866111ba565b9150915060008184604051602001611367929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630178b8bf90602401602060405180830381865afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114249190612967565b90506001600160a01b038116156114445797509550610471945050505050565b50919a91995090975050505050505050565b60008060006114658585611c0d565b9092509050816114d7576001855161147d9190612d0c565b84146114cb5760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b0b565b50600091506103509050565b6114e18582611456565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561153a5761153a6120f7565b60405190808252806020026020018201604052801561159857816020015b611585604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816115585790505b50905060008367ffffffffffffffff8111156115b6576115b66120f7565b6040519080825280602002602001820160405280156115fc57816020015b6040805180820190915260008152606060208201528152602001906001900390816115d45790505b5090508367ffffffffffffffff811115611618576116186120f7565b60405190808252806020026020018201604052801561164b57816020015b60608152602001906001900390816116365790505b508651516080880151919650159060009061166590611cc4565b905060005b868110156118575760008960200151828151811061168a5761168a612951565b6020026020010151905060008a60c0015183815181106116ac576116ac612951565b6020026020010151905080156116e157818a84815181106116cf576116cf612951565b60200260200101819052505050611845565b841580156116ec5750835b15611732578a5160405161170591908490602401612ba9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b17905291505b6000806000806117468f6080015187611d3a565b935093509350935083156117bb57828060200190518101906117689190612dd9565b8b8d8151811061177a5761177a612951565b6020026020010181905250818a888151811061179857611798612951565b60209081029190910101526117ae60018d612bed565b9b50505050505050611845565b8080156117c55750875b156117e157828060200190518101906117de9190612c19565b92505b828e88815181106117f4576117f4612951565b60200260200101819052508e60200151878151811061181557611815612951565b60200260200101518a888151811061182f5761182f612951565b6020026020010151602001819052505050505050505b8061184f81612c00565b91505061166a565b508460000361186b57505050505050919050565b84845230886040015163a780bab660e01b8660405160240161188d9190612ed4565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050508a606001518b608001518c604001518d60a00151896040516020016118e89493929190612f36565b60408051601f1981840301815290829052630556f18360e41b8252610b0b9594939291600401612fea565b80516060906000908190849061192a816002612bed565b67ffffffffffffffff811115611942576119426120f7565b6040519080825280601f01601f19166020018201604052801561196c576020820181803683370190505b509450600093508084036119b157600060f81b8560008151811061199257611992612951565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b8281815181106119c9576119c9612951565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611a8b578360f81b868260010181518110611a2f57611a2f612951565b60200101906001600160f81b031916908160001a90535084611a58846001840160ff8816611eb3565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611adb565b600184019350828181518110611aa357611aa3612951565b602001015160f81c60f81b868260010181518110611ac357611ac3612951565b60200101906001600160f81b031916908160001a9053505b8015611aea57600019016119b7565b5083611afb83600060ff8716611eb3565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b8560008151811061199257611992612951565b8251600090600190831115611b5057600080fd5b611ba1565b6000603a8210602f83111615611b6d5750602f190190565b60478210604083111615611b8357506036190190565b60678210606083111615611b9957506056190190565b5060ff919050565b60208501845b84811015611c0357611bbe8183015160001a611b55565b611bd06001830184015160001a611b55565b60ff811460ff83141715611be957600094505050611c03565b60049190911b1760089490941b9390931792600201611ba7565b5050935093915050565b60008083518310611c605760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b0b565b6000848481518110611c7457611c74612951565b016020015160f81c90508015611ca057611c9985611c93866001612bed565b83611eb3565b9250611ca5565b600092505b611caf8185612bed565b611cba906001612bed565b9150509250929050565b6040516301ffc9a760e01b8152639061b92360e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015611d2e575060408051601f3d908101601f19168201909252611d2b9181019061301e565b60015b61035057506000919050565b60408051808201909152600080825260606020830181905290916000611d608686611ed7565b90503d8115611d86576000611d76600083611f69565b909550935060019150610a829050565b60048110611ea9576000611d9c60006004611f69565b90506000611db46004611daf8186612d0c565b611f69565b9050630556f18360e41b611dc78361303b565b6001600160e01b03191603611e9557600080600080600085806020019051810190611df29190613073565b945094509450945094508d6001600160a01b0316856001600160a01b031603611e8b576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611e499190613123565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b50909950975060009650610a8295505050505050565b5050505050611ea6565b600096509450859250610a82915050565b50505b5092959194509250565b8251600090611ec28385612bed565b1115611ecd57600080fd5b5091016020012090565b60006001600160a01b0383163b611f565760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b0b565b600080835160208501865afa9392505050565b60608167ffffffffffffffff811115611f8457611f846120f7565b6040519080825280601f01601f191660200182016040528015611fae576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612004579160200282015b828111156120045782518290611ff49082613185565b5091602001919060010190611fde565b50612010929150612014565b5090565b808211156120105760006120288282612031565b50600101612014565b50805461203d90612880565b6000825580601f1061204d575050565b601f016020900490600052602060002090810190610b1d91905b808211156120105760008155600101612067565b6001600160e01b031981168114610b1d57600080fd5b6000602082840312156120a357600080fd5b81356120ae8161207b565b9392505050565b60008083601f8401126120c757600080fd5b50813567ffffffffffffffff8111156120df57600080fd5b60208301915083602082850101111561074a57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612130576121306120f7565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561215f5761215f6120f7565b604052919050565b600067ffffffffffffffff821115612181576121816120f7565b50601f01601f191660200190565b60006121a261219d84612167565b612136565b90508281528383830111156121b657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126121de57600080fd5b6120ae8383356020850161218f565b600067ffffffffffffffff821115612207576122076120f7565b5060051b60200190565b600082601f83011261222257600080fd5b8135602061223261219d836121ed565b82815260059290921b8401810191818101908684111561225157600080fd5b8286015b848110156122a657803567ffffffffffffffff8111156122755760008081fd5b8701603f810189136122875760008081fd5b61229889868301356040840161218f565b845250918301918301612255565b509695505050505050565b600080600080606085870312156122c757600080fd5b843567ffffffffffffffff808211156122df57600080fd5b6122eb888389016120b5565b9096509450602087013591508082111561230457600080fd5b612310888389016121cd565b9350604087013591508082111561232657600080fd5b5061233387828801612211565b91505092959194509250565b60005b8381101561235a578181015183820152602001612342565b50506000910152565b6000815180845261237b81602086016020860161233f565b601f01601f19169290920160200192915050565b6040815260006123a26040830185612363565b90506001600160a01b03831660208301529392505050565b600082601f8301126123cb57600080fd5b813560206123db61219d836121ed565b82815260059290921b840181019181810190868411156123fa57600080fd5b8286015b848110156122a657803567ffffffffffffffff81111561241e5760008081fd5b61242c8986838b01016121cd565b8452509183019183016123fe565b60008060006040848603121561244f57600080fd5b833567ffffffffffffffff8082111561246757600080fd5b612473878388016120b5565b9095509350602086013591508082111561248c57600080fd5b50612499868287016123ba565b9150509250925092565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156124fa57605f198887030185526124e8868351612363565b955093820193908201906001016124cc565b50508394506001600160a01b03871681870152505050509392505050565b6000806000806040858703121561252e57600080fd5b843567ffffffffffffffff8082111561254657600080fd5b612552888389016120b5565b9096509450602087013591508082111561256b57600080fd5b50612578878288016120b5565b95989497509550505050565b6080815260006125976080830187612363565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156125d657600080fd5b843567ffffffffffffffff808211156125ee57600080fd5b6125fa888389016120b5565b9096509450602087013591508082111561261357600080fd5b612310888389016123ba565b60008060008060008060a0878903121561263857600080fd5b863567ffffffffffffffff8082111561265057600080fd5b61265c8a838b016120b5565b9098509650602089013591508082111561267557600080fd5b6126818a838b016121cd565b9550604089013591508082111561269757600080fd5b6126a38a838b01612211565b9450606089013591506126b58261207b565b909250608088013590808211156126cb57600080fd5b506126d889828a016121cd565b9150509295509295509295565b6000602082840312156126f757600080fd5b813567ffffffffffffffff81111561270e57600080fd5b61271a84828501612211565b949350505050565b60008060006040848603121561273757600080fd5b833567ffffffffffffffff8082111561274f57600080fd5b61275b878388016120b5565b9095509350602086013591508082111561277457600080fd5b50612499868287016121cd565b6000806020838503121561279457600080fd5b823567ffffffffffffffff8111156127ab57600080fd5b6127b7858286016120b5565b90969095509350505050565b6000602082840312156127d557600080fd5b5035919050565b6020815260006120ae6020830184612363565b60008060006040848603121561280457600080fd5b833567ffffffffffffffff8082111561281c57600080fd5b612828878388016120b5565b9095509350602086013591508082111561284157600080fd5b5061249986828701612211565b6001600160a01b0381168114610b1d57600080fd5b60006020828403121561287557600080fd5b81356120ae8161284e565b600181811c9082168061289457607f821691505b6020821081036128b457634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126128cb57600080fd5b81516128d961219d82612167565b8181528460208386010111156128ee57600080fd5b61271a82602083016020870161233f565b6000806040838503121561291257600080fd5b825167ffffffffffffffff81111561292957600080fd5b612935858286016128ba565b92505060208301516129468161284e565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561297957600080fd5b81516120ae8161284e565b8015158114610b1d57600080fd5b600080604083850312156129a557600080fd5b823567ffffffffffffffff808211156129bd57600080fd5b818501915085601f8301126129d157600080fd5b813560206129e161219d836121ed565b82815260059290921b84018101918181019089841115612a0057600080fd5b948201945b83861015612a27578535612a1881612984565b82529482019490820190612a05565b96505086013592505080821115612a3d57600080fd5b50611cba858286016123ba565b60008060008060808587031215612a6057600080fd5b612a6a853561284e565b84359350602085013567ffffffffffffffff80821115612a8957600080fd5b612a9588838901612211565b94506040870135915080821115612aab57600080fd5b612ab7888389016121cd565b93506060870135915080821115612acd57600080fd5b818701915087601f830112612ae157600080fd5b8135612aef61219d826121ed565b8082825260208201915060208360051b86010192508a831115612b1157600080fd5b602085015b83811015612b99578481351115612b2c57600080fd5b803586016040818e03601f19011215612b4457600080fd5b612b4c61210d565b6020820135612b5a8161207b565b8152604082013587811115612b6e57600080fd5b612b7d8f6020838601016121cd565b6020830152508085525050602083019250602081019050612b16565b50979a9699509497505050505050565b604081526000612bbc6040830185612363565b8281036020840152612bce8185612363565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035057610350612bd7565b600060018201612c1257612c12612bd7565b5060010190565b600060208284031215612c2b57600080fd5b815167ffffffffffffffff811115612c4257600080fd5b61271a848285016128ba565b600081518084526020808501808196508360051b8101915082860160005b85811015612c96578284038952612c84848351612363565b98850198935090840190600101612c6c565b5091979650505050505050565b60a081526000612cb660a0830188612363565b8281036020840152612cc88188612363565b90508281036040840152612cdc8187612c4e565b90506001600160e01b0319851660608401528281036080840152612d008185612363565b98975050505050505050565b8181038181111561035057610350612bd7565b60008085851115612d2f57600080fd5b83861115612d3c57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f830112612d6a57600080fd5b81516020612d7a61219d836121ed565b82815260059290921b84018101918181019086841115612d9957600080fd5b8286015b848110156122a657805167ffffffffffffffff811115612dbd5760008081fd5b612dcb8986838b01016128ba565b845250918301918301612d9d565b600060208284031215612deb57600080fd5b815167ffffffffffffffff80821115612e0357600080fd5b9083019060608286031215612e1757600080fd5b604051606081018181108382111715612e3257612e326120f7565b6040528251612e408161284e565b8152602083015182811115612e5457600080fd5b612e6087828601612d59565b602083015250604083015182811115612e7857600080fd5b612e84878286016128ba565b60408301525095945050505050565b6001600160a01b0381511682526000602082015160606020850152612ebb6060850182612c4e565b905060408301518482036040860152612bce8282612363565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612f2957603f19888603018452612f17858351612e93565b94509285019290850190600101612efb565b5092979650505050505050565b6001600160a01b038516815260006020608081840152612f596080840187612c4e565b604084820381860152612f6c8288612363565b915084820360608601528186518084528484019150848160051b85010185890160005b83811015612fd857868303601f19018552815180516001600160e01b0319168452880151888401879052612fc587850182612363565b9589019593505090870190600101612f8f565b50909c9b505050505050505050505050565b6001600160a01b038616815260a06020820152600061300c60a0830187612c4e565b8281036040840152612cdc8187612363565b60006020828403121561303057600080fd5b81516120ae81612984565b6000815160208301516001600160e01b03198082169350600483101561306b5780818460040360031b1b83161693505b505050919050565b600080600080600060a0868803121561308b57600080fd5b85516130968161284e565b602087015190955067ffffffffffffffff808211156130b457600080fd5b6130c089838a01612d59565b955060408801519150808211156130d657600080fd5b6130e289838a016128ba565b9450606088015191506130f48261207b565b60808801519193508082111561310957600080fd5b50613116888289016128ba565b9150509295509295909350565b6020815260006120ae6020830184612e93565b601f82111561318057600081815260208120601f850160051c8101602086101561315d5750805b601f850160051c820191505b8181101561317c57828155600101613169565b5050505b505050565b815167ffffffffffffffff81111561319f5761319f6120f7565b6131b3816131ad8454612880565b84613136565b602080601f8311600181146131e857600084156131d05750858301515b600019600386901b1c1916600185901b17855561317c565b600085815260208120601f198616915b82811015613217578886015182559484019460019091019084016131f8565b50858210156132355787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220628a6e5e37bdf043eae6c5d6779dabf3e6a460a412186cfff5e080a8914cbe4e64736f6c6343000811003300000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003868747470733a2f2f756e6976657273616c2d6f6666636861696e2d756e777261707065722e656e732d63662e776f726b6572732e6465762f0000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101365760003560e01c80638e5ea8df116100b2578063b241d0d311610081578063e0a8541211610066578063e0a85412146102e6578063ec11c823146102f9578063f2fde38b1461030c57600080fd5b8063b241d0d3146102c0578063b4a85801146102d357600080fd5b80638e5ea8df146102485780639061b9231461025b578063a1cbcbaf1461026e578063a6b16419146102a057600080fd5b8063715018a6116101095780637b103999116100ee5780637b103999146101e55780638da5cb5b146102245780638e25a0f31461023557600080fd5b8063715018a6146101c857806376286c00146101d257600080fd5b806301ffc9a71461013b5780630667cfea14610163578063206c74c9146101845780636dc4fb73146101a5575b600080fd5b61014e610149366004612091565b61031f565b60405190151581526020015b60405180910390f35b6101766101713660046122b1565b610356565b60405161015a92919061238f565b61019761019236600461243a565b61038b565b60405161015a9291906124a3565b6101b86101b3366004612518565b610479565b60405161015a9493929190612584565b6101d0610546565b005b6101976101e03660046125c0565b61055a565b61020c7f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e81565b6040516001600160a01b03909116815260200161015a565b6000546001600160a01b031661020c565b61017661024336600461261f565b610582565b6101d06102563660046126e5565b610618565b610176610269366004612722565b610637565b61028161027c366004612781565b610730565b604080516001600160a01b03909316835260208301919091520161015a565b6102b36102ae3660046127c3565b610751565b60405161015a91906127dc565b6101b86102ce3660046127ef565b6107fd565b6101976102e1366004612518565b6108ee565b6101766102f4366004612518565b610932565b6101b8610307366004612781565b610996565b6101d061031a366004612863565b610a8b565b60006001600160e01b03198216639061b92360e01b148061035057506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600061037e8686868663e0a8541260e01b60405180602001604052806000815250610582565b9150915094509492505050565b6060600061046c8585856001805480602002602001604051908101604052809291908181526020016000905b828210156104635783829060005260206000200180546103d690612880565b80601f016020809104026020016040519081016040528092919081815260200182805461040290612880565b801561044f5780601f106104245761010080835404028352916020019161044f565b820191906000526020600020905b81548152906001019060200180831161043257829003601f168201915b5050505050815260200190600101906103b7565b5050505061055a565b915091505b935093915050565b606060008080808080806104978c8c8c8c636dc4fb7360e01b610b20565b935093509350935060008151111561050957600080828060200190518101906104c091906128ff565b915091506000866000815181106104d9576104d9612951565b60200260200101518060200190518101906104f49190612967565b929a50919850965092945061053b9350505050565b61052e8460008151811061051f5761051f612951565b60200260200101518484610e94565b9750975097509750505050505b945094509450949050565b61054e610ff5565b610558600061104f565b565b6060600061037e8686868663b4a8580160e01b604051806020016040528060008152506110b7565b6040805160018082528183019092526060916000918291816020015b606081526020019060019003908161059e57905050905086816000815181106105c9576105c9612951565b60200260200101819052506000806105e58b8b858b8b8b6110b7565b91509150816000815181106105fc576105fc612951565b602002602001015181945094505050505b965096945050505050565b610620610ff5565b8051610633906001906020840190611fbe565b5050565b6060600061046c8585856001805480602002602001604051908101604052809291908181526020016000905b8282101561070f57838290600052602060002001805461068290612880565b80601f01602080910402602001604051908101604052809291908181526020018280546106ae90612880565b80156106fb5780601f106106d0576101008083540402835291602001916106fb565b820191906000526020600020905b8154815290600101906020018083116106de57829003601f168201915b505050505081526020019060010190610663565b5050505063e0a8541260e01b60405180602001604052806000815250610582565b600080600080610742868660006111ba565b909450925050505b9250929050565b6001818154811061076157600080fd5b90600052602060002001600091509050805461077c90612880565b80601f01602080910402602001604051908101604052809291908181526020018280546107a890612880565b80156107f55780601f106107ca576101008083540402835291602001916107f5565b820191906000526020600020905b8154815290600101906020018083116107d857829003601f168201915b505050505081565b6060600080600080610849600089898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092939250506114569050565b60405160240161085b91815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f691f3431000000000000000000000000000000000000000000000000000000001790528151908101909152600080825291925081906108cb908b908b9086908c90636dc4fb7360e01b90610582565b915091506108da82828a610e94565b965096509650965050505093509350935093565b606060008080610921888888887fb4a8580100000000000000000000000000000000000000000000000000000000610b20565b50919a909950975050505050505050565b606060008080610965888888887fe0a8541200000000000000000000000000000000000000000000000000000000610b20565b5050915091508160008151811061097e5761097e612951565b60200260200101518193509350505094509492505050565b60606000806000610a7986866001805480602002602001604051908101604052809291908181526020016000905b82821015610a705783829060005260206000200180546109e390612880565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0f90612880565b8015610a5c5780601f10610a3157610100808354040283529160200191610a5c565b820191906000526020600020905b815481529060010190602001808311610a3f57829003601f168201915b5050505050815260200190600101906109c4565b505050506107fd565b93509350935093505b92959194509250565b610a93610ff5565b6001600160a01b038116610b145760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610b1d8161104f565b50565b60606000606080610b7a6040518060e0016040528060608152602001606081526020016060815260200160006001600160e01b031916815260200160006001600160a01b0316815260200160608152602001606081525090565b6001600160e01b031986166060820152600080610b998b8d018d612992565b90925090506060610bac8a8c018c612a4a565b60a088019190915260408701919091526001600160a01b039091166080860152805183519192501015610bde57600080fd5b805167ffffffffffffffff811115610bf857610bf86120f7565b604051908082528060200260200182016040528015610c2b57816020015b6060815260200190600190039081610c165790505b506020850152805167ffffffffffffffff811115610c4b57610c4b6120f7565b604051908082528060200260200182016040528015610c74578160200160208202803683370190505b5060c08501526000805b8251811015610e62578251600090849083908110610c9e57610c9e612951565b6020026020010151600001516001600160e01b03191603610cfd57828181518110610ccb57610ccb612951565b60200260200101516020015186602001518281518110610ced57610ced612951565b6020026020010181905250610e50565b848281518110610d0f57610d0f612951565b602002602001015115610d865760018660c001518281518110610d3457610d34612951565b602002602001019015159081151581525050838281518110610d5857610d58612951565b602002602001015186602001518281518110610d7657610d76612951565b6020026020010181905250610e42565b828181518110610d9857610d98612951565b602002602001015160000151848381518110610db657610db6612951565b6020026020010151848381518110610dd057610dd0612951565b602002602001015160200151604051602401610ded929190612ba9565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b03838183161783525050505086602001518281518110610e3657610e36612951565b60200260200101819052505b610e4d826001612bed565b91505b80610e5a81612c00565b915050610c7e565b50610e6c85611515565b856080015186604001518760a001519850985098509850505050505095509550955095915050565b606060008060008087806020019051810190610eb09190612c19565b9050600080610ebe83611913565b91509150600081604051602401610ed791815260200190565b60408051601f19818403018152918152602080830180516001600160e01b03167f3b3b57de000000000000000000000000000000000000000000000000000000001790529051919250600091610f319187918e910161238f565b6040516020818303038152906040529050600080306001600160a01b0316638e25a0f387868f636dc4fb7360e01b886040518663ffffffff1660e01b8152600401610f80959493929190612ca3565b600060405180830381865afa158015610f9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fc591908101906128ff565b91509150600082806020019051810190610fdf9190612967565b979f979e50909b50959950505050505050505050565b6000546001600160a01b031633146105585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b0b565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60606000806110c68989610730565b5091508190506001600160a01b0381166110e457506000905061060d565b604080516101006020601f8c01819004028201810190925260e081018a81526111ac928291908d908d9081908501838280828437600092019190915250505090825250602081018a9052604081018990526001600160e01b0319881660608201526001600160a01b038516608082015260a08101879052895160c09091019067ffffffffffffffff81111561117b5761117b6120f7565b6040519080825280602002602001820160405280156111a4578160200160208202803683370190505b509052611515565b925050965096945050505050565b60008060008585858181106111d1576111d1612951565b919091013560f81c91505060008190036111f2575060009150819050610471565b60006111fe8286612bed565b611209906001612bed565b9050600082604214801561124f57508787611225886001612bed565b81811061123457611234612951565b9050013560f81c60f81b6001600160f81b031916605b60f81b145b801561128d57508787611263600185612d0c565b81811061127257611272612951565b9050013560f81c60f81b6001600160f81b031916605d60f81b145b15611305576112fd600060408a8a6112a68b6002612bed565b906112b2600189612d0c565b926112bf93929190612d1f565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929493925050611b3c9050565b509050611337565b8787611312886001612bed565b61131e92859290612d1f565b60405161132c929190612d49565b604051809103902090505b6000806113458a8a866111ba565b9150915060008184604051602001611367929190918252602082015260400190565b60408051601f198184030181529082905280516020909101207f0178b8bf0000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b037f00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e1690630178b8bf90602401602060405180830381865afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114249190612967565b90506001600160a01b038116156114445797509550610471945050505050565b50919a91995090975050505050505050565b60008060006114658585611c0d565b9092509050816114d7576001855161147d9190612d0c565b84146114cb5760405162461bcd60e51b815260206004820152601d60248201527f6e616d65686173683a204a756e6b20617420656e64206f66206e616d650000006044820152606401610b0b565b50600091506103509050565b6114e18582611456565b6040805160208101929092528101839052606001604051602081830303815290604052805190602001209250505092915050565b6020810151516060906000808267ffffffffffffffff81111561153a5761153a6120f7565b60405190808252806020026020018201604052801561159857816020015b611585604051806060016040528060006001600160a01b0316815260200160608152602001606081525090565b8152602001906001900390816115585790505b50905060008367ffffffffffffffff8111156115b6576115b66120f7565b6040519080825280602002602001820160405280156115fc57816020015b6040805180820190915260008152606060208201528152602001906001900390816115d45790505b5090508367ffffffffffffffff811115611618576116186120f7565b60405190808252806020026020018201604052801561164b57816020015b60608152602001906001900390816116365790505b508651516080880151919650159060009061166590611cc4565b905060005b868110156118575760008960200151828151811061168a5761168a612951565b6020026020010151905060008a60c0015183815181106116ac576116ac612951565b6020026020010151905080156116e157818a84815181106116cf576116cf612951565b60200260200101819052505050611845565b841580156116ec5750835b15611732578a5160405161170591908490602401612ba9565b60408051601f198184030181529190526020810180516001600160e01b0316639061b92360e01b17905291505b6000806000806117468f6080015187611d3a565b935093509350935083156117bb57828060200190518101906117689190612dd9565b8b8d8151811061177a5761177a612951565b6020026020010181905250818a888151811061179857611798612951565b60209081029190910101526117ae60018d612bed565b9b50505050505050611845565b8080156117c55750875b156117e157828060200190518101906117de9190612c19565b92505b828e88815181106117f4576117f4612951565b60200260200101819052508e60200151878151811061181557611815612951565b60200260200101518a888151811061182f5761182f612951565b6020026020010151602001819052505050505050505b8061184f81612c00565b91505061166a565b508460000361186b57505050505050919050565b84845230886040015163a780bab660e01b8660405160240161188d9190612ed4565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b0383818316178352505050508a606001518b608001518c604001518d60a00151896040516020016118e89493929190612f36565b60408051601f1981840301815290829052630556f18360e41b8252610b0b9594939291600401612fea565b80516060906000908190849061192a816002612bed565b67ffffffffffffffff811115611942576119426120f7565b6040519080825280601f01601f19166020018201604052801561196c576020820181803683370190505b509450600093508084036119b157600060f81b8560008151811061199257611992612951565b60200101906001600160f81b031916908160001a905350505050915091565b60001981015b8281815181106119c9576119c9612951565b01602001517fff00000000000000000000000000000000000000000000000000000000000000167f2e0000000000000000000000000000000000000000000000000000000000000003611a8b578360f81b868260010181518110611a2f57611a2f612951565b60200101906001600160f81b031916908160001a90535084611a58846001840160ff8816611eb3565b60408051602081019390935282015260600160405160208183030381529060405280519060200120945060009350611adb565b600184019350828181518110611aa357611aa3612951565b602001015160f81c60f81b868260010181518110611ac357611ac3612951565b60200101906001600160f81b031916908160001a9053505b8015611aea57600019016119b7565b5083611afb83600060ff8716611eb3565b6040805160208101939093528201526060016040516020818303038152906040528051906020012093508260f81b8560008151811061199257611992612951565b8251600090600190831115611b5057600080fd5b611ba1565b6000603a8210602f83111615611b6d5750602f190190565b60478210604083111615611b8357506036190190565b60678210606083111615611b9957506056190190565b5060ff919050565b60208501845b84811015611c0357611bbe8183015160001a611b55565b611bd06001830184015160001a611b55565b60ff811460ff83141715611be957600094505050611c03565b60049190911b1760089490941b9390931792600201611ba7565b5050935093915050565b60008083518310611c605760405162461bcd60e51b815260206004820152601e60248201527f726561644c6162656c3a20496e646578206f7574206f6620626f756e647300006044820152606401610b0b565b6000848481518110611c7457611c74612951565b016020015160f81c90508015611ca057611c9985611c93866001612bed565b83611eb3565b9250611ca5565b600092505b611caf8185612bed565b611cba906001612bed565b9150509250929050565b6040516301ffc9a760e01b8152639061b92360e01b60048201526000906001600160a01b038316906301ffc9a790602401602060405180830381865afa925050508015611d2e575060408051601f3d908101601f19168201909252611d2b9181019061301e565b60015b61035057506000919050565b60408051808201909152600080825260606020830181905290916000611d608686611ed7565b90503d8115611d86576000611d76600083611f69565b909550935060019150610a829050565b60048110611ea9576000611d9c60006004611f69565b90506000611db46004611daf8186612d0c565b611f69565b9050630556f18360e41b611dc78361303b565b6001600160e01b03191603611e9557600080600080600085806020019051810190611df29190613073565b945094509450945094508d6001600160a01b0316856001600160a01b031603611e8b576040518060600160405280866001600160a01b0316815260200185815260200184815250604051602001611e499190613123565b60408051601f198184030181528282019091526001600160e01b03199093168152602081019190915260019b50909950975060009650610a8295505050505050565b5050505050611ea6565b600096509450859250610a82915050565b50505b5092959194509250565b8251600090611ec28385612bed565b1115611ecd57600080fd5b5091016020012090565b60006001600160a01b0383163b611f565760405162461bcd60e51b815260206004820152602e60248201527f4c6f774c6576656c43616c6c5574696c733a207374617469632063616c6c207460448201527f6f206e6f6e2d636f6e74726163740000000000000000000000000000000000006064820152608401610b0b565b600080835160208501865afa9392505050565b60608167ffffffffffffffff811115611f8457611f846120f7565b6040519080825280601f01601f191660200182016040528015611fae576020820181803683370190505b5090508183602083013e92915050565b828054828255906000526020600020908101928215612004579160200282015b828111156120045782518290611ff49082613185565b5091602001919060010190611fde565b50612010929150612014565b5090565b808211156120105760006120288282612031565b50600101612014565b50805461203d90612880565b6000825580601f1061204d575050565b601f016020900490600052602060002090810190610b1d91905b808211156120105760008155600101612067565b6001600160e01b031981168114610b1d57600080fd5b6000602082840312156120a357600080fd5b81356120ae8161207b565b9392505050565b60008083601f8401126120c757600080fd5b50813567ffffffffffffffff8111156120df57600080fd5b60208301915083602082850101111561074a57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612130576121306120f7565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561215f5761215f6120f7565b604052919050565b600067ffffffffffffffff821115612181576121816120f7565b50601f01601f191660200190565b60006121a261219d84612167565b612136565b90508281528383830111156121b657600080fd5b828260208301376000602084830101529392505050565b600082601f8301126121de57600080fd5b6120ae8383356020850161218f565b600067ffffffffffffffff821115612207576122076120f7565b5060051b60200190565b600082601f83011261222257600080fd5b8135602061223261219d836121ed565b82815260059290921b8401810191818101908684111561225157600080fd5b8286015b848110156122a657803567ffffffffffffffff8111156122755760008081fd5b8701603f810189136122875760008081fd5b61229889868301356040840161218f565b845250918301918301612255565b509695505050505050565b600080600080606085870312156122c757600080fd5b843567ffffffffffffffff808211156122df57600080fd5b6122eb888389016120b5565b9096509450602087013591508082111561230457600080fd5b612310888389016121cd565b9350604087013591508082111561232657600080fd5b5061233387828801612211565b91505092959194509250565b60005b8381101561235a578181015183820152602001612342565b50506000910152565b6000815180845261237b81602086016020860161233f565b601f01601f19169290920160200192915050565b6040815260006123a26040830185612363565b90506001600160a01b03831660208301529392505050565b600082601f8301126123cb57600080fd5b813560206123db61219d836121ed565b82815260059290921b840181019181810190868411156123fa57600080fd5b8286015b848110156122a657803567ffffffffffffffff81111561241e5760008081fd5b61242c8986838b01016121cd565b8452509183019183016123fe565b60008060006040848603121561244f57600080fd5b833567ffffffffffffffff8082111561246757600080fd5b612473878388016120b5565b9095509350602086013591508082111561248c57600080fd5b50612499868287016123ba565b9150509250925092565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b838110156124fa57605f198887030185526124e8868351612363565b955093820193908201906001016124cc565b50508394506001600160a01b03871681870152505050509392505050565b6000806000806040858703121561252e57600080fd5b843567ffffffffffffffff8082111561254657600080fd5b612552888389016120b5565b9096509450602087013591508082111561256b57600080fd5b50612578878288016120b5565b95989497509550505050565b6080815260006125976080830187612363565b6001600160a01b0395861660208401529385166040830152509216606090920191909152919050565b600080600080606085870312156125d657600080fd5b843567ffffffffffffffff808211156125ee57600080fd5b6125fa888389016120b5565b9096509450602087013591508082111561261357600080fd5b612310888389016123ba565b60008060008060008060a0878903121561263857600080fd5b863567ffffffffffffffff8082111561265057600080fd5b61265c8a838b016120b5565b9098509650602089013591508082111561267557600080fd5b6126818a838b016121cd565b9550604089013591508082111561269757600080fd5b6126a38a838b01612211565b9450606089013591506126b58261207b565b909250608088013590808211156126cb57600080fd5b506126d889828a016121cd565b9150509295509295509295565b6000602082840312156126f757600080fd5b813567ffffffffffffffff81111561270e57600080fd5b61271a84828501612211565b949350505050565b60008060006040848603121561273757600080fd5b833567ffffffffffffffff8082111561274f57600080fd5b61275b878388016120b5565b9095509350602086013591508082111561277457600080fd5b50612499868287016121cd565b6000806020838503121561279457600080fd5b823567ffffffffffffffff8111156127ab57600080fd5b6127b7858286016120b5565b90969095509350505050565b6000602082840312156127d557600080fd5b5035919050565b6020815260006120ae6020830184612363565b60008060006040848603121561280457600080fd5b833567ffffffffffffffff8082111561281c57600080fd5b612828878388016120b5565b9095509350602086013591508082111561284157600080fd5b5061249986828701612211565b6001600160a01b0381168114610b1d57600080fd5b60006020828403121561287557600080fd5b81356120ae8161284e565b600181811c9082168061289457607f821691505b6020821081036128b457634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126128cb57600080fd5b81516128d961219d82612167565b8181528460208386010111156128ee57600080fd5b61271a82602083016020870161233f565b6000806040838503121561291257600080fd5b825167ffffffffffffffff81111561292957600080fd5b612935858286016128ba565b92505060208301516129468161284e565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561297957600080fd5b81516120ae8161284e565b8015158114610b1d57600080fd5b600080604083850312156129a557600080fd5b823567ffffffffffffffff808211156129bd57600080fd5b818501915085601f8301126129d157600080fd5b813560206129e161219d836121ed565b82815260059290921b84018101918181019089841115612a0057600080fd5b948201945b83861015612a27578535612a1881612984565b82529482019490820190612a05565b96505086013592505080821115612a3d57600080fd5b50611cba858286016123ba565b60008060008060808587031215612a6057600080fd5b612a6a853561284e565b84359350602085013567ffffffffffffffff80821115612a8957600080fd5b612a9588838901612211565b94506040870135915080821115612aab57600080fd5b612ab7888389016121cd565b93506060870135915080821115612acd57600080fd5b818701915087601f830112612ae157600080fd5b8135612aef61219d826121ed565b8082825260208201915060208360051b86010192508a831115612b1157600080fd5b602085015b83811015612b99578481351115612b2c57600080fd5b803586016040818e03601f19011215612b4457600080fd5b612b4c61210d565b6020820135612b5a8161207b565b8152604082013587811115612b6e57600080fd5b612b7d8f6020838601016121cd565b6020830152508085525050602083019250602081019050612b16565b50979a9699509497505050505050565b604081526000612bbc6040830185612363565b8281036020840152612bce8185612363565b95945050505050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561035057610350612bd7565b600060018201612c1257612c12612bd7565b5060010190565b600060208284031215612c2b57600080fd5b815167ffffffffffffffff811115612c4257600080fd5b61271a848285016128ba565b600081518084526020808501808196508360051b8101915082860160005b85811015612c96578284038952612c84848351612363565b98850198935090840190600101612c6c565b5091979650505050505050565b60a081526000612cb660a0830188612363565b8281036020840152612cc88188612363565b90508281036040840152612cdc8187612c4e565b90506001600160e01b0319851660608401528281036080840152612d008185612363565b98975050505050505050565b8181038181111561035057610350612bd7565b60008085851115612d2f57600080fd5b83861115612d3c57600080fd5b5050820193919092039150565b8183823760009101908152919050565b600082601f830112612d6a57600080fd5b81516020612d7a61219d836121ed565b82815260059290921b84018101918181019086841115612d9957600080fd5b8286015b848110156122a657805167ffffffffffffffff811115612dbd5760008081fd5b612dcb8986838b01016128ba565b845250918301918301612d9d565b600060208284031215612deb57600080fd5b815167ffffffffffffffff80821115612e0357600080fd5b9083019060608286031215612e1757600080fd5b604051606081018181108382111715612e3257612e326120f7565b6040528251612e408161284e565b8152602083015182811115612e5457600080fd5b612e6087828601612d59565b602083015250604083015182811115612e7857600080fd5b612e84878286016128ba565b60408301525095945050505050565b6001600160a01b0381511682526000602082015160606020850152612ebb6060850182612c4e565b905060408301518482036040860152612bce8282612363565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612f2957603f19888603018452612f17858351612e93565b94509285019290850190600101612efb565b5092979650505050505050565b6001600160a01b038516815260006020608081840152612f596080840187612c4e565b604084820381860152612f6c8288612363565b915084820360608601528186518084528484019150848160051b85010185890160005b83811015612fd857868303601f19018552815180516001600160e01b0319168452880151888401879052612fc587850182612363565b9589019593505090870190600101612f8f565b50909c9b505050505050505050505050565b6001600160a01b038616815260a06020820152600061300c60a0830187612c4e565b8281036040840152612cdc8187612363565b60006020828403121561303057600080fd5b81516120ae81612984565b6000815160208301516001600160e01b03198082169350600483101561306b5780818460040360031b1b83161693505b505050919050565b600080600080600060a0868803121561308b57600080fd5b85516130968161284e565b602087015190955067ffffffffffffffff808211156130b457600080fd5b6130c089838a01612d59565b955060408801519150808211156130d657600080fd5b6130e289838a016128ba565b9450606088015191506130f48261207b565b60808801519193508082111561310957600080fd5b50613116888289016128ba565b9150509295509295909350565b6020815260006120ae6020830184612e93565b601f82111561318057600081815260208120601f850160051c8101602086101561315d5750805b601f850160051c820191505b8181101561317c57828155600101613169565b5050505b505050565b815167ffffffffffffffff81111561319f5761319f6120f7565b6131b3816131ad8454612880565b84613136565b602080601f8311600181146131e857600084156131d05750858301515b600019600386901b1c1916600185901b17855561317c565b600085815260208120601f198616915b82811015613217578886015182559484019460019091019084016131f8565b50858210156132355787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220628a6e5e37bdf043eae6c5d6779dabf3e6a460a412186cfff5e080a8914cbe4e64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003868747470733a2f2f756e6976657273616c2d6f6666636861696e2d756e777261707065722e656e732d63662e776f726b6572732e6465762f0000000000000000
-----Decoded View---------------
Arg [0] : _registry (address): 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
Arg [1] : _urls (string[]): https://universal-offchain-unwrapper.ens-cf.workers.dev/
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000c2e074ec69a0dfb2997ba6c7d2e1e
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000038
Arg [5] : 68747470733a2f2f756e6976657273616c2d6f6666636861696e2d756e777261
Arg [6] : 707065722e656e732d63662e776f726b6572732e6465762f0000000000000000
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
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.