Token
ERC-1155
Overview
Max Total Supply
0
Holders
2
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Loading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
OmniscapeDiamond
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import {SolidStateDiamond} from "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol";
/**
* @title OmniscapeDiamond "Diamond" proxy implementation based on SolidState Diamond Reference
*/
contract OmniscapeDiamond is SolidStateDiamond {
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173 } from '../../interfaces/IERC173.sol';
interface IOwnable is IERC173 {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173Internal } from '../../interfaces/IERC173Internal.sol';
interface IOwnableInternal is IERC173Internal {
error Ownable__NotOwner();
error Ownable__NotTransitiveOwner();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IOwnable } from './IOwnable.sol';
interface ISafeOwnable is IOwnable {
/**
* @notice get the nominated owner who has permission to call acceptOwnership
*/
function nomineeOwner() external view returns (address);
/**
* @notice accept transfer of contract ownership
*/
function acceptOwnership() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IOwnableInternal } from './IOwnableInternal.sol';
interface ISafeOwnableInternal is IOwnableInternal {
error SafeOwnable__NotNomineeOwner();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173 } from '../../interfaces/IERC173.sol';
import { IOwnable } from './IOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
/**
* @title Ownership access control based on ERC173
*/
abstract contract Ownable is IOwnable, OwnableInternal {
/**
* @inheritdoc IERC173
*/
function owner() public view virtual returns (address) {
return _owner();
}
/**
* @inheritdoc IERC173
*/
function transferOwnership(address account) public virtual onlyOwner {
_transferOwnership(account);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173 } from '../../interfaces/IERC173.sol';
import { AddressUtils } from '../../utils/AddressUtils.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';
abstract contract OwnableInternal is IOwnableInternal {
using AddressUtils for address;
modifier onlyOwner() {
if (msg.sender != _owner()) revert Ownable__NotOwner();
_;
}
modifier onlyTransitiveOwner() {
if (msg.sender != _transitiveOwner())
revert Ownable__NotTransitiveOwner();
_;
}
function _owner() internal view virtual returns (address) {
return OwnableStorage.layout().owner;
}
function _transitiveOwner() internal view virtual returns (address owner) {
owner = _owner();
while (owner.isContract()) {
try IERC173(owner).owner() returns (address transitiveOwner) {
owner = transitiveOwner;
} catch {
break;
}
}
}
function _transferOwnership(address account) internal virtual {
_setOwner(account);
}
function _setOwner(address account) internal virtual {
OwnableStorage.Layout storage l = OwnableStorage.layout();
emit OwnershipTransferred(l.owner, account);
l.owner = account;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
library OwnableStorage {
struct Layout {
address owner;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.Ownable');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { Ownable } from './Ownable.sol';
import { ISafeOwnable } from './ISafeOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableInternal } from './SafeOwnableInternal.sol';
/**
* @title Ownership access control based on ERC173 with ownership transfer safety check
*/
abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal {
/**
* @inheritdoc ISafeOwnable
*/
function nomineeOwner() public view virtual returns (address) {
return _nomineeOwner();
}
/**
* @inheritdoc ISafeOwnable
*/
function acceptOwnership() public virtual onlyNomineeOwner {
_acceptOwnership();
}
function _transferOwnership(
address account
) internal virtual override(OwnableInternal, SafeOwnableInternal) {
super._transferOwnership(account);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';
abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
modifier onlyNomineeOwner() {
if (msg.sender != _nomineeOwner())
revert SafeOwnable__NotNomineeOwner();
_;
}
/**
* @notice get the nominated owner who has permission to call acceptOwnership
*/
function _nomineeOwner() internal view virtual returns (address) {
return SafeOwnableStorage.layout().nomineeOwner;
}
/**
* @notice accept transfer of contract ownership
*/
function _acceptOwnership() internal virtual {
_setOwner(msg.sender);
delete SafeOwnableStorage.layout().nomineeOwner;
}
/**
* @notice set nominee owner, granting permission to call acceptOwnership
*/
function _transferOwnership(address account) internal virtual override {
SafeOwnableStorage.layout().nomineeOwner = account;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
library SafeOwnableStorage {
struct Layout {
address nomineeOwner;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.SafeOwnable');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC165Internal } from './IERC165Internal.sol';
/**
* @title ERC165 interface registration interface
* @dev see https://eips.ethereum.org/EIPS/eip-165
*/
interface IERC165 is IERC165Internal {
/**
* @notice query whether contract has registered support for given interface
* @param interfaceId interface id
* @return bool whether interface is supported
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC165Internal } from './IERC165Internal.sol';
/**
* @title ERC165 interface registration interface
*/
interface IERC165Internal {
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173Internal } from './IERC173Internal.sol';
/**
* @title Contract ownership standard interface
* @dev see https://eips.ethereum.org/EIPS/eip-173
*/
interface IERC173 is IERC173Internal {
/**
* @notice get the ERC173 contract owner
* @return conrtact owner
*/
function owner() external view returns (address);
/**
* @notice transfer contract ownership to new account
* @param account address of new owner
*/
function transferOwnership(address account) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC173 interface needed by internal functions
*/
interface IERC173Internal {
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165Base } from './IERC165Base.sol';
import { ERC165BaseInternal } from './ERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';
/**
* @title ERC165 implementation
*/
abstract contract ERC165Base is IERC165Base, ERC165BaseInternal {
/**
* @inheritdoc IERC165
*/
function supportsInterface(bytes4 interfaceId) public view returns (bool) {
return _supportsInterface(interfaceId);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
import { ERC165BaseStorage } from './ERC165BaseStorage.sol';
/**
* @title ERC165 implementation
*/
abstract contract ERC165BaseInternal is IERC165BaseInternal {
/**
* @notice indicates whether an interface is already supported based on the interfaceId
* @param interfaceId id of interface to check
* @return bool indicating whether interface is supported
*/
function _supportsInterface(
bytes4 interfaceId
) internal view returns (bool) {
return ERC165BaseStorage.layout().supportedInterfaces[interfaceId];
}
/**
* @notice sets status of interface support
* @param interfaceId id of interface to set status for
* @param status boolean indicating whether interface will be set as supported
*/
function _setSupportsInterface(bytes4 interfaceId, bool status) internal {
if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
library ERC165BaseStorage {
struct Layout {
mapping(bytes4 => bool) supportedInterfaces;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.ERC165Base');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';
interface IERC165Base is IERC165, IERC165BaseInternal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';
interface IERC165BaseInternal is IERC165Internal {
error ERC165Base__InvalidInterfaceId();
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { Proxy } from '../../Proxy.sol';
import { IDiamondBase } from './IDiamondBase.sol';
import { DiamondBaseStorage } from './DiamondBaseStorage.sol';
/**
* @title EIP-2535 "Diamond" proxy base contract
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
abstract contract DiamondBase is IDiamondBase, Proxy {
/**
* @inheritdoc Proxy
*/
function _getImplementation()
internal
view
virtual
override
returns (address implementation)
{
// inline storage layout retrieval uses less gas
DiamondBaseStorage.Layout storage l;
bytes32 slot = DiamondBaseStorage.STORAGE_SLOT;
assembly {
l.slot := slot
}
implementation = address(bytes20(l.facets[msg.sig]));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
*/
library DiamondBaseStorage {
struct Layout {
// function selector => (facet address, selector slot position)
mapping(bytes4 => bytes32) facets;
// total number of selectors registered
uint16 selectorCount;
// array of selector slots with 8 selectors per slot
mapping(uint256 => bytes32) selectorSlots;
address fallbackAddress;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.DiamondBase');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IProxy } from '../../IProxy.sol';
interface IDiamondBase is IProxy {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBase } from '../base/DiamondBase.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondFallback } from './IDiamondFallback.sol';
// TODO: DiamondFallback interface
/**
* @title Fallback feature for EIP-2535 "Diamond" proxy
*/
abstract contract DiamondFallback is
IDiamondFallback,
OwnableInternal,
DiamondBase
{
/**
* @inheritdoc IDiamondFallback
*/
function getFallbackAddress()
external
view
returns (address fallbackAddress)
{
fallbackAddress = _getFallbackAddress();
}
/**
* @inheritdoc IDiamondFallback
*/
function setFallbackAddress(address fallbackAddress) external onlyOwner {
_setFallbackAddress(fallbackAddress);
}
/**
* @inheritdoc DiamondBase
* @notice query custom fallback address is no implementation is found
*/
function _getImplementation()
internal
view
virtual
override
returns (address implementation)
{
implementation = super._getImplementation();
if (implementation == address(0)) {
implementation = _getFallbackAddress();
}
}
/**
* @notice query the address of the fallback implementation
* @return fallbackAddress address of fallback implementation
*/
function _getFallbackAddress()
internal
view
virtual
returns (address fallbackAddress)
{
fallbackAddress = DiamondBaseStorage.layout().fallbackAddress;
}
/**
* @notice set the address of the fallback implementation
* @param fallbackAddress address of fallback implementation
*/
function _setFallbackAddress(address fallbackAddress) internal virtual {
DiamondBaseStorage.layout().fallbackAddress = fallbackAddress;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IDiamondBase } from '../base/IDiamondBase.sol';
interface IDiamondFallback is IDiamondBase {
/**
* @notice query the address of the fallback implementation
* @return fallbackAddress address of fallback implementation
*/
function getFallbackAddress()
external
view
returns (address fallbackAddress);
/**
* @notice set the address of the fallback implementation
* @param fallbackAddress address of fallback implementation
*/
function setFallbackAddress(address fallbackAddress) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol';
import { IERC165 } from '../../interfaces/IERC165.sol';
import { IDiamondBase } from './base/IDiamondBase.sol';
import { IDiamondFallback } from './fallback/IDiamondFallback.sol';
import { IDiamondReadable } from './readable/IDiamondReadable.sol';
import { IDiamondWritable } from './writable/IDiamondWritable.sol';
interface ISolidStateDiamond is
IDiamondBase,
IDiamondFallback,
IDiamondReadable,
IDiamondWritable,
ISafeOwnable,
IERC165
{
receive() external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadable } from './IDiamondReadable.sol';
/**
* @title EIP-2535 "Diamond" proxy introspection contract
* @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
*/
abstract contract DiamondReadable is IDiamondReadable {
/**
* @inheritdoc IDiamondReadable
*/
function facets() external view returns (Facet[] memory diamondFacets) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
diamondFacets = new Facet[](l.selectorCount);
uint8[] memory numFacetSelectors = new uint8[](l.selectorCount);
uint256 numFacets;
uint256 selectorIndex;
// loop through function selectors
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
bytes32 slot = l.selectorSlots[slotIndex];
for (
uint256 selectorSlotIndex;
selectorSlotIndex < 8;
selectorSlotIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
address facet = address(bytes20(l.facets[selector]));
bool continueLoop;
for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
if (diamondFacets[facetIndex].target == facet) {
diamondFacets[facetIndex].selectors[
numFacetSelectors[facetIndex]
] = selector;
// probably will never have more than 256 functions from one facet contract
require(numFacetSelectors[facetIndex] < 255);
numFacetSelectors[facetIndex]++;
continueLoop = true;
break;
}
}
if (continueLoop) {
continue;
}
diamondFacets[numFacets].target = facet;
diamondFacets[numFacets].selectors = new bytes4[](
l.selectorCount
);
diamondFacets[numFacets].selectors[0] = selector;
numFacetSelectors[numFacets] = 1;
numFacets++;
}
}
for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
uint256 numSelectors = numFacetSelectors[facetIndex];
bytes4[] memory selectors = diamondFacets[facetIndex].selectors;
// setting the number of selectors
assembly {
mstore(selectors, numSelectors)
}
}
// setting the number of facets
assembly {
mstore(diamondFacets, numFacets)
}
}
/**
* @inheritdoc IDiamondReadable
*/
function facetFunctionSelectors(
address facet
) external view returns (bytes4[] memory selectors) {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
selectors = new bytes4[](l.selectorCount);
uint256 numSelectors;
uint256 selectorIndex;
// loop through function selectors
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
bytes32 slot = l.selectorSlots[slotIndex];
for (
uint256 selectorSlotIndex;
selectorSlotIndex < 8;
selectorSlotIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
if (facet == address(bytes20(l.facets[selector]))) {
selectors[numSelectors] = selector;
numSelectors++;
}
}
}
// set the number of selectors in the array
assembly {
mstore(selectors, numSelectors)
}
}
/**
* @inheritdoc IDiamondReadable
*/
function facetAddresses()
external
view
returns (address[] memory addresses)
{
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
addresses = new address[](l.selectorCount);
uint256 numFacets;
uint256 selectorIndex;
for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
bytes32 slot = l.selectorSlots[slotIndex];
for (
uint256 selectorSlotIndex;
selectorSlotIndex < 8;
selectorSlotIndex++
) {
selectorIndex++;
if (selectorIndex > l.selectorCount) {
break;
}
bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
address facet = address(bytes20(l.facets[selector]));
bool continueLoop;
for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
if (facet == addresses[facetIndex]) {
continueLoop = true;
break;
}
}
if (continueLoop) {
continue;
}
addresses[numFacets] = facet;
numFacets++;
}
}
// set the number of facet addresses in the array
assembly {
mstore(addresses, numFacets)
}
}
/**
* @inheritdoc IDiamondReadable
*/
function facetAddress(
bytes4 selector
) external view returns (address facet) {
facet = address(bytes20(DiamondBaseStorage.layout().facets[selector]));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Diamond proxy introspection interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IDiamondReadable {
struct Facet {
address target;
bytes4[] selectors;
}
/**
* @notice get all facets and their selectors
* @return diamondFacets array of structured facet data
*/
function facets() external view returns (Facet[] memory diamondFacets);
/**
* @notice get all selectors for given facet address
* @param facet address of facet to query
* @return selectors array of function selectors
*/
function facetFunctionSelectors(
address facet
) external view returns (bytes4[] memory selectors);
/**
* @notice get addresses of all facets used by diamond
* @return addresses array of facet addresses
*/
function facetAddresses()
external
view
returns (address[] memory addresses);
/**
* @notice get the address of the facet associated with given selector
* @param selector function selector to query
* @return facet facet address (zero address if not found)
*/
function facetAddress(
bytes4 selector
) external view returns (address facet);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IOwnable, Ownable, OwnableInternal } from '../../access/ownable/Ownable.sol';
import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol';
import { IERC165 } from '../../interfaces/IERC165.sol';
import { IERC173 } from '../../interfaces/IERC173.sol';
import { ERC165Base, ERC165BaseStorage } from '../../introspection/ERC165/base/ERC165Base.sol';
import { DiamondBase } from './base/DiamondBase.sol';
import { DiamondFallback, IDiamondFallback } from './fallback/DiamondFallback.sol';
import { DiamondReadable, IDiamondReadable } from './readable/DiamondReadable.sol';
import { DiamondWritable, IDiamondWritable } from './writable/DiamondWritable.sol';
import { ISolidStateDiamond } from './ISolidStateDiamond.sol';
/**
* @title SolidState "Diamond" proxy reference implementation
*/
abstract contract SolidStateDiamond is
ISolidStateDiamond,
DiamondBase,
DiamondFallback,
DiamondReadable,
DiamondWritable,
SafeOwnable,
ERC165Base
{
constructor() {
bytes4[] memory selectors = new bytes4[](12);
uint256 selectorIndex;
// register DiamondFallback
selectors[selectorIndex++] = IDiamondFallback
.getFallbackAddress
.selector;
selectors[selectorIndex++] = IDiamondFallback
.setFallbackAddress
.selector;
_setSupportsInterface(type(IDiamondFallback).interfaceId, true);
// register DiamondWritable
selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector;
_setSupportsInterface(type(IDiamondWritable).interfaceId, true);
// register DiamondReadable
selectors[selectorIndex++] = IDiamondReadable.facets.selector;
selectors[selectorIndex++] = IDiamondReadable
.facetFunctionSelectors
.selector;
selectors[selectorIndex++] = IDiamondReadable.facetAddresses.selector;
selectors[selectorIndex++] = IDiamondReadable.facetAddress.selector;
_setSupportsInterface(type(IDiamondReadable).interfaceId, true);
// register ERC165
selectors[selectorIndex++] = IERC165.supportsInterface.selector;
_setSupportsInterface(type(IERC165).interfaceId, true);
// register SafeOwnable
selectors[selectorIndex++] = Ownable.owner.selector;
selectors[selectorIndex++] = SafeOwnable.nomineeOwner.selector;
selectors[selectorIndex++] = Ownable.transferOwnership.selector;
selectors[selectorIndex++] = SafeOwnable.acceptOwnership.selector;
_setSupportsInterface(type(IERC173).interfaceId, true);
// diamond cut
FacetCut[] memory facetCuts = new FacetCut[](1);
facetCuts[0] = FacetCut({
target: address(this),
action: FacetCutAction.ADD,
selectors: selectors
});
_diamondCut(facetCuts, address(0), '');
// set owner
_setOwner(msg.sender);
}
receive() external payable {}
function _transferOwnership(
address account
) internal virtual override(OwnableInternal, SafeOwnable) {
super._transferOwnership(account);
}
/**
* @inheritdoc DiamondFallback
*/
function _getImplementation()
internal
view
override(DiamondBase, DiamondFallback)
returns (address implementation)
{
implementation = super._getImplementation();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { IDiamondWritable } from './IDiamondWritable.sol';
import { DiamondWritableInternal } from './DiamondWritableInternal.sol';
/**
* @title EIP-2535 "Diamond" proxy update contract
*/
abstract contract DiamondWritable is
IDiamondWritable,
DiamondWritableInternal,
OwnableInternal
{
/**
* @inheritdoc IDiamondWritable
*/
function diamondCut(
FacetCut[] calldata facetCuts,
address target,
bytes calldata data
) external onlyOwner {
_diamondCut(facetCuts, target, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { AddressUtils } from '../../../utils/AddressUtils.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';
abstract contract DiamondWritableInternal is IDiamondWritableInternal {
using AddressUtils for address;
bytes32 private constant CLEAR_ADDRESS_MASK =
bytes32(uint256(0xffffffffffffffffffffffff));
bytes32 private constant CLEAR_SELECTOR_MASK =
bytes32(uint256(0xffffffff << 224));
/**
* @notice update functions callable on Diamond proxy
* @param facetCuts array of structured Diamond facet update data
* @param target optional recipient of initialization delegatecall
* @param data optional initialization call data
*/
function _diamondCut(
FacetCut[] memory facetCuts,
address target,
bytes memory data
) internal {
DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();
unchecked {
uint256 originalSelectorCount = l.selectorCount;
uint256 selectorCount = originalSelectorCount;
bytes32 selectorSlot;
// Check if last selector slot is not full
if (selectorCount & 7 > 0) {
// get last selectorSlot
selectorSlot = l.selectorSlots[selectorCount >> 3];
}
for (uint256 i; i < facetCuts.length; i++) {
FacetCut memory facetCut = facetCuts[i];
FacetCutAction action = facetCut.action;
if (facetCut.selectors.length == 0)
revert DiamondWritable__SelectorNotSpecified();
if (action == FacetCutAction.ADD) {
(selectorCount, selectorSlot) = _addFacetSelectors(
l,
selectorCount,
selectorSlot,
facetCut
);
} else if (action == FacetCutAction.REPLACE) {
_replaceFacetSelectors(l, facetCut);
} else if (action == FacetCutAction.REMOVE) {
(selectorCount, selectorSlot) = _removeFacetSelectors(
l,
selectorCount,
selectorSlot,
facetCut
);
}
}
if (selectorCount != originalSelectorCount) {
l.selectorCount = uint16(selectorCount);
}
// If last selector slot is not full
if (selectorCount & 7 > 0) {
l.selectorSlots[selectorCount >> 3] = selectorSlot;
}
emit DiamondCut(facetCuts, target, data);
_initialize(target, data);
}
}
function _addFacetSelectors(
DiamondBaseStorage.Layout storage l,
uint256 selectorCount,
bytes32 selectorSlot,
FacetCut memory facetCut
) internal returns (uint256, bytes32) {
unchecked {
if (
facetCut.target != address(this) &&
!facetCut.target.isContract()
) revert DiamondWritable__TargetHasNoCode();
for (uint256 i; i < facetCut.selectors.length; i++) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
if (address(bytes20(oldFacet)) != address(0))
revert DiamondWritable__SelectorAlreadyAdded();
// add facet for selector
l.facets[selector] =
bytes20(facetCut.target) |
bytes32(selectorCount);
uint256 selectorInSlotPosition = (selectorCount & 7) << 5;
// clear selector position in slot and add selector
selectorSlot =
(selectorSlot &
~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |
(bytes32(selector) >> selectorInSlotPosition);
// if slot is full then write it to storage
if (selectorInSlotPosition == 224) {
l.selectorSlots[selectorCount >> 3] = selectorSlot;
selectorSlot = 0;
}
selectorCount++;
}
return (selectorCount, selectorSlot);
}
}
function _removeFacetSelectors(
DiamondBaseStorage.Layout storage l,
uint256 selectorCount,
bytes32 selectorSlot,
FacetCut memory facetCut
) internal returns (uint256, bytes32) {
unchecked {
if (facetCut.target != address(0))
revert DiamondWritable__RemoveTargetNotZeroAddress();
uint256 selectorSlotCount = selectorCount >> 3;
uint256 selectorInSlotIndex = selectorCount & 7;
for (uint256 i; i < facetCut.selectors.length; i++) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
if (address(bytes20(oldFacet)) == address(0))
revert DiamondWritable__SelectorNotFound();
if (address(bytes20(oldFacet)) == address(this))
revert DiamondWritable__SelectorIsImmutable();
if (selectorSlot == 0) {
selectorSlotCount--;
selectorSlot = l.selectorSlots[selectorSlotCount];
selectorInSlotIndex = 7;
} else {
selectorInSlotIndex--;
}
bytes4 lastSelector;
uint256 oldSelectorsSlotCount;
uint256 oldSelectorInSlotPosition;
// adding a block here prevents stack too deep error
{
// replace selector with last selector in l.facets
lastSelector = bytes4(
selectorSlot << (selectorInSlotIndex << 5)
);
if (lastSelector != selector) {
// update last selector slot position info
l.facets[lastSelector] =
(oldFacet & CLEAR_ADDRESS_MASK) |
bytes20(l.facets[lastSelector]);
}
delete l.facets[selector];
uint256 oldSelectorCount = uint16(uint256(oldFacet));
oldSelectorsSlotCount = oldSelectorCount >> 3;
oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;
}
if (oldSelectorsSlotCount != selectorSlotCount) {
bytes32 oldSelectorSlot = l.selectorSlots[
oldSelectorsSlotCount
];
// clears the selector we are deleting and puts the last selector in its place.
oldSelectorSlot =
(oldSelectorSlot &
~(CLEAR_SELECTOR_MASK >>
oldSelectorInSlotPosition)) |
(bytes32(lastSelector) >> oldSelectorInSlotPosition);
// update storage with the modified slot
l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
} else {
// clears the selector we are deleting and puts the last selector in its place.
selectorSlot =
(selectorSlot &
~(CLEAR_SELECTOR_MASK >>
oldSelectorInSlotPosition)) |
(bytes32(lastSelector) >> oldSelectorInSlotPosition);
}
if (selectorInSlotIndex == 0) {
delete l.selectorSlots[selectorSlotCount];
selectorSlot = 0;
}
}
selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex;
return (selectorCount, selectorSlot);
}
}
function _replaceFacetSelectors(
DiamondBaseStorage.Layout storage l,
FacetCut memory facetCut
) internal {
unchecked {
if (!facetCut.target.isContract())
revert DiamondWritable__TargetHasNoCode();
for (uint256 i; i < facetCut.selectors.length; i++) {
bytes4 selector = facetCut.selectors[i];
bytes32 oldFacet = l.facets[selector];
address oldFacetAddress = address(bytes20(oldFacet));
if (oldFacetAddress == address(0))
revert DiamondWritable__SelectorNotFound();
if (oldFacetAddress == address(this))
revert DiamondWritable__SelectorIsImmutable();
if (oldFacetAddress == facetCut.target)
revert DiamondWritable__ReplaceTargetIsIdentical();
// replace old facet address
l.facets[selector] =
(oldFacet & CLEAR_ADDRESS_MASK) |
bytes20(facetCut.target);
}
}
}
function _initialize(address target, bytes memory data) private {
if ((target == address(0)) != (data.length == 0))
revert DiamondWritable__InvalidInitializationParameters();
if (target != address(0)) {
if (target != address(this)) {
if (!target.isContract())
revert DiamondWritable__TargetHasNoCode();
}
(bool success, ) = target.delegatecall(data);
if (!success) {
assembly {
returndatacopy(0, 0, returndatasize())
revert(0, returndatasize())
}
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';
/**
* @title Diamond proxy upgrade interface
* @dev see https://eips.ethereum.org/EIPS/eip-2535
*/
interface IDiamondWritable is IDiamondWritableInternal {
/**
* @notice update diamond facets and optionally execute arbitrary initialization function
* @param facetCuts array of structured Diamond facet update data
* @param target optional target of initialization delegatecall
* @param data optional initialization function call data
*/
function diamondCut(
FacetCut[] calldata facetCuts,
address target,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
interface IDiamondWritableInternal {
enum FacetCutAction {
ADD,
REPLACE,
REMOVE
}
event DiamondCut(FacetCut[] facetCuts, address target, bytes data);
error DiamondWritable__InvalidInitializationParameters();
error DiamondWritable__RemoveTargetNotZeroAddress();
error DiamondWritable__ReplaceTargetIsIdentical();
error DiamondWritable__SelectorAlreadyAdded();
error DiamondWritable__SelectorIsImmutable();
error DiamondWritable__SelectorNotFound();
error DiamondWritable__SelectorNotSpecified();
error DiamondWritable__TargetHasNoCode();
struct FacetCut {
address target;
FacetCutAction action;
bytes4[] selectors;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
interface IProxy {
error Proxy__ImplementationIsNotContract();
fallback() external payable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { AddressUtils } from '../utils/AddressUtils.sol';
import { IProxy } from './IProxy.sol';
/**
* @title Base proxy contract
*/
abstract contract Proxy is IProxy {
using AddressUtils for address;
/**
* @notice delegate all calls to implementation contract
* @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts
* @dev memory location in use by assembly may be unsafe in other contexts
*/
fallback() external payable virtual {
address implementation = _getImplementation();
if (!implementation.isContract())
revert Proxy__ImplementationIsNotContract();
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(
gas(),
implementation,
0,
calldatasize(),
0,
0
)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @notice get logic implementation address
* @return implementation address
*/
function _getImplementation() internal virtual returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { UintUtils } from './UintUtils.sol';
library AddressUtils {
using UintUtils for uint256;
error AddressUtils__InsufficientBalance();
error AddressUtils__NotContract();
error AddressUtils__SendValueFailed();
function toString(address account) internal pure returns (string memory) {
return uint256(uint160(account)).toHexString(20);
}
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable account, uint256 amount) internal {
(bool success, ) = account.call{ value: amount }('');
if (!success) revert AddressUtils__SendValueFailed();
}
function functionCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionCall(target, data, 'AddressUtils: failed low-level call');
}
function functionCall(
address target,
bytes memory data,
string memory error
) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, error);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
'AddressUtils: failed low-level call with value'
);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) internal returns (bytes memory) {
if (value > address(this).balance)
revert AddressUtils__InsufficientBalance();
return _functionCallWithValue(target, data, value, error);
}
/**
* @notice execute arbitrary external call with limited gas usage and amount of copied return data
* @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License)
* @param target recipient of call
* @param gasAmount gas allowance for call
* @param value native token value to include in call
* @param maxCopy maximum number of bytes to copy from return data
* @param data encoded call data
* @return success whether call is successful
* @return returnData copied return data
*/
function excessivelySafeCall(
address target,
uint256 gasAmount,
uint256 value,
uint16 maxCopy,
bytes memory data
) internal returns (bool success, bytes memory returnData) {
returnData = new bytes(maxCopy);
assembly {
// execute external call via assembly to avoid automatic copying of return data
success := call(
gasAmount,
target,
value,
add(data, 0x20),
mload(data),
0,
0
)
// determine whether to limit amount of data to copy
let toCopy := returndatasize()
if gt(toCopy, maxCopy) {
toCopy := maxCopy
}
// store the length of the copied bytes
mstore(returnData, toCopy)
// copy the bytes from returndata[0:toCopy]
returndatacopy(add(returnData, 0x20), 0, toCopy)
}
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) private returns (bytes memory) {
if (!isContract(target)) revert AddressUtils__NotContract();
(bool success, bytes memory returnData) = target.call{ value: value }(
data
);
if (success) {
return returnData;
} else if (returnData.length > 0) {
assembly {
let returnData_size := mload(returnData)
revert(add(32, returnData), returnData_size)
}
} else {
revert(error);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title utility functions for uint256 operations
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
*/
library UintUtils {
error UintUtils__InsufficientHexLength();
bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';
function add(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? sub(a, -b) : a + uint256(b);
}
function sub(uint256 a, int256 b) internal pure returns (uint256) {
return b < 0 ? add(a, -b) : a - uint256(b);
}
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0';
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0x00';
}
uint256 length = 0;
for (uint256 temp = value; temp != 0; temp >>= 8) {
unchecked {
length++;
}
}
return toHexString(value, length);
}
function toHexString(
uint256 value,
uint256 length
) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = '0';
buffer[1] = 'x';
unchecked {
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
}
if (value != 0) revert UintUtils__InsufficientHexLength();
return string(buffer);
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Base__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b506000600c67ffffffffffffffff81111562000032576200003162001987565b5b604051908082528060200260200182016040528015620000615781602001602082028036833780820191505090505b5090506000632c40805960e01b8282806200007c90620019ef565b93508151811062000092576200009162001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050639142376560e01b828280620000f490620019ef565b9350815181106200010a576200010962001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620001897fbd02b73c0000000000000000000000000000000000000000000000000000000060016200080b60201b60201c565b631f931c1c60e01b8282806200019f90620019ef565b935081518110620001b557620001b462001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620002347f1f931c1c0000000000000000000000000000000000000000000000000000000060016200080b60201b60201c565b637a0ed62760e01b8282806200024a90620019ef565b93508151811062000260576200025f62001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063adfca15e60e01b828280620002c290620019ef565b935081518110620002d857620002d762001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506352ef6b2c60e01b8282806200033a90620019ef565b93508151811062000350576200034f62001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063cdffacc660e01b828280620003b290620019ef565b935081518110620003c857620003c762001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620004477f48e2b0930000000000000000000000000000000000000000000000000000000060016200080b60201b60201c565b6301ffc9a760e01b8282806200045d90620019ef565b93508151811062000473576200047262001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620004f27f01ffc9a70000000000000000000000000000000000000000000000000000000060016200080b60201b60201c565b638da5cb5b60e01b8282806200050890620019ef565b9350815181106200051e576200051d62001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050638ab5150a60e01b8282806200058090620019ef565b93508151811062000596576200059562001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063f2fde38b60e01b828280620005f890620019ef565b9350815181106200060e576200060d62001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506379ba509760e01b8282806200067090620019ef565b93508151811062000686576200068562001a3c565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620007057f7f5828d00000000000000000000000000000000000000000000000000000000060016200080b60201b60201c565b6000600167ffffffffffffffff81111562000725576200072462001987565b5b6040519080825280602002602001820160405280156200076257816020015b6200074e6200193b565b815260200190600190039081620007445790505b50905060405180606001604052803073ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620007a357620007a262001a6b565b5b81526020018481525081600081518110620007c357620007c262001a3c565b5b6020026020010181905250620007f181600060405180602001604052806000815250620008ee60201b60201c565b620008023362000b7860201b60201c565b50505062001ea1565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036200086b576040517fb0a19dd500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806200088162000c5660201b620010341760201c565b6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006200090562000c8360201b620010611760201c565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156200095257836002016000600384901c81526020019081526020016000205490505b60005b875181101562000acb57600088828151811062000977576200097662001a3c565b5b60200260200101519050600081602001519050600082604001515103620009ca576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006002811115620009e157620009e062001a6b565b5b816002811115620009f757620009f662001a6b565b5b0362000a1f5762000a118786868562000cb060201b60201c565b809550819650505062000abb565b6001600281111562000a365762000a3562001a6b565b5b81600281111562000a4c5762000a4b62001a6b565b5b0362000a6a5762000a64878362000f7860201b60201c565b62000aba565b60028081111562000a805762000a7f62001a6b565b5b81600281111562000a965762000a9562001a6b565b5b0362000ab95762000ab0878686856200124460201b60201c565b80955081965050505b5b5b5050808060010191505062000955565b5082821462000af457818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111562000b205780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405162000b559392919062001dfb565b60405180910390a162000b6f86866200173860201b60201c565b50505050505050565b600062000b8f620018fb60201b6200108e1760201c565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415801562000d21575062000d1f836000015173ffffffffffffffffffffffffffffffffffffffff166200192860201b620003681760201c565b155b1562000d59576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83604001515181101562000f685760008460400151828151811062000d865762000d8562001a3c565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff161462000e52576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e0810362000f4f57878a600201600060038c901c8152602001908152602001600020819055506000801b97505b8880600101995050505050808060010191505062000d5c565b5084849150915094509492505050565b62000fa8816000015173ffffffffffffffffffffffffffffffffffffffff166200192860201b620003681760201c565b62000fdf576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8160400151518110156200123f576000826040015182815181106200100c576200100b62001a3c565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620010dd576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362001143576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620011ad576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505062000fe2565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614620012b2576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b8560400151518110156200171d57600086604001518281518110620012f057620012ef62001a3c565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603620013bc576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff160362001425576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b89036200145b578480600190039550508a60020160008681526020019081526020016000205498506007935062001465565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161462001588578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214620016905760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050620016e1565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b600087036200170a578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050620012c6565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151514620017a9576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620018f7573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161462001876576200183e8273ffffffffffffffffffffffffffffffffffffffff166200192860201b620003681760201c565b62001875576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516200189f919062001e88565b600060405180830381855af49150503d8060008114620018dc576040519150601f19603f3d011682016040523d82523d6000602084013e620018e1565b606091505b5050905080620018f5573d6000803e3d6000fd5b505b5050565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b600080823b905060008111915050919050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600060028111156200197a576200197962001a6b565b5b8152602001606081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000620019fc82620019e5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362001a315762001a30620019b6565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001af38262001ac6565b9050919050565b62001b058162001ae6565b82525050565b6003811062001b1f5762001b1e62001a6b565b5b50565b600081905062001b328262001b0b565b919050565b600062001b448262001b22565b9050919050565b62001b568162001b37565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62001bbf8162001b88565b82525050565b600062001bd3838362001bb4565b60208301905092915050565b6000602082019050919050565b600062001bf98262001b5c565b62001c05818562001b67565b935062001c128362001b78565b8060005b8381101562001c4957815162001c2d888262001bc5565b975062001c3a8362001bdf565b92505060018101905062001c16565b5085935050505092915050565b600060608301600083015162001c70600086018262001afa565b50602083015162001c85602086018262001b4b565b506040830151848203604086015262001c9f828262001bec565b9150508091505092915050565b600062001cba838362001c56565b905092915050565b6000602082019050919050565b600062001cdc8262001a9a565b62001ce8818562001aa5565b93508360208202850162001cfc8562001ab6565b8060005b8581101562001d3e578484038952815162001d1c858262001cac565b945062001d298362001cc2565b925060208a0199505060018101905062001d00565b50829750879550505050505092915050565b62001d5b8162001ae6565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b8381101562001d9d57808201518184015260208101905062001d80565b60008484015250505050565b6000601f19601f8301169050919050565b600062001dc78262001d61565b62001dd3818562001d6c565b935062001de581856020860162001d7d565b62001df08162001da9565b840191505092915050565b6000606082019050818103600083015262001e17818662001ccf565b905062001e28602083018562001d50565b818103604083015262001e3c818462001dba565b9050949350505050565b600081905092915050565b600062001e5e8262001d61565b62001e6a818562001e46565b935062001e7c81856020860162001d7d565b80840191505092915050565b600062001e96828462001e51565b915081905092915050565b612fb48062001eb16000396000f3fe6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146102375780638da5cb5b14610262578063914237651461028d578063adfca15e146102b6578063cdffacc6146102f3578063f2fde38b14610330576100b2565b806301ffc9a7146101395780631f931c1c146101765780632c4080591461019f57806352ef6b2c146101ca57806379ba5097146101f55780637a0ed6271461020c576100b2565b366100b257005b60006100bc610359565b90506100dd8173ffffffffffffffffffffffffffffffffffffffff16610368565b610113576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e8060008114610134573d6000f35b3d6000fd5b34801561014557600080fd5b50610160600480360381019061015b919061237a565b61037b565b60405161016d91906123c2565b60405180910390f35b34801561018257600080fd5b5061019d600480360381019061019891906124f6565b61038d565b005b3480156101ab57600080fd5b506101b461045b565b6040516101c1919061259a565b60405180910390f35b3480156101d657600080fd5b506101df61046a565b6040516101ec9190612673565b60405180910390f35b34801561020157600080fd5b5061020a6106cb565b005b34801561021857600080fd5b50610221610741565b60405161022e9190612852565b60405180910390f35b34801561024357600080fd5b5061024c610ca2565b604051610259919061259a565b60405180910390f35b34801561026e57600080fd5b50610277610cb1565b604051610284919061259a565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190612874565b610cc0565b005b3480156102c257600080fd5b506102dd60048036038101906102d89190612874565b610d38565b6040516102ea9190612910565b60405180910390f35b3480156102ff57600080fd5b5061031a6004803603810190610315919061237a565b610f55565b604051610327919061259a565b60405180910390f35b34801561033c57600080fd5b5061035760048036038101906103529190612874565b610fbc565b005b60006103636110bb565b905090565b600080823b905060008111915050919050565b600061038682611109565b9050919050565b61039561117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103f9576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104548585906104099190612be3565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506111ad565b5050505050565b60006104656113e8565b905090565b60606000610476611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156104a8576104a7612943565b5b6040519080825280602002602001820160405280156104d65781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff168210156106c157600084600201600083815260200190815260200160002054905060005b60088110156106ac57838061052e90612c31565b9450508560010160009054906101000a900461ffff1661ffff1684116106ac576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b8881101561062a578a81815181106105d4576105d3612c79565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610617576001915061062a565b808061062290612c31565b9150506105b9565b50801561063957505050610699565b818a898151811061064d5761064c612c79565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061069290612c31565b9850505050505b80806106a490612c31565b91505061051a565b505080806106b990612c31565b9150506104df565b5081845250505090565b6106d361141b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610737576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073f61144e565b565b6060600061074d611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561077f5761077e612943565b5b6040519080825280602002602001820160405280156107b857816020015b6107a56122de565b81526020019060019003908161079d5790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156107ed576107ec612943565b5b60405190808252806020026020018201604052801561081b5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610c2e57600085600201600083815260200190815260200160002054905060005b6008811015610c1957838061087390612c31565b9450508660010160009054906101000a900461ffff1661ffff168411610c19576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610a6a578273ffffffffffffffffffffffffffffffffffffffff168c82815181106109305761092f612c79565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610a5757838c828151811061096b5761096a612c79565b5b6020026020010151602001518b838151811061098a57610989612c79565b5b602002602001015160ff16815181106109a6576109a5612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610a0757610a06612c79565b5b602002602001015160ff1610610a1c57600080fd5b898181518110610a2f57610a2e612c79565b5b602002602001018051809190610a4490612cb5565b60ff1660ff168152505060019150610a6a565b8080610a6290612c31565b9150506108fe565b508015610a7957505050610c06565b818b8981518110610a8d57610a8c612c79565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610afb57610afa612943565b5b604051908082528060200260200182016040528015610b295781602001602082028036833780820191505090505b508b8981518110610b3d57610b3c612c79565b5b602002602001015160200181905250828b8981518110610b6057610b5f612c79565b5b602002602001015160200151600081518110610b7f57610b7e612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610be057610bdf612c79565b5b602002602001019060ff16908160ff16815250508780610bff90612c31565b9850505050505b8080610c1190612c31565b91505061085f565b50508080610c2690612c31565b915050610824565b5060005b82811015610c97576000848281518110610c4f57610c4e612c79565b5b602002602001015160ff1690506000878381518110610c7157610c70612c79565b5b602002602001015160200151905081815250508080610c8f90612c31565b915050610c32565b508185525050505090565b6000610cac61141b565b905090565b6000610cbb61117a565b905090565b610cc861117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d2c576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d3581611487565b50565b60606000610d44611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610d7657610d75612943565b5b604051908082528060200260200182016040528015610da45781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff16821015610f4957600084600201600083815260200190815260200160002054905060005b6008811015610f34578380610dfc90612c31565b9450508560010160009054906101000a900461ffff1661ffff168411610f34576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610f205780888781518110610ec557610ec4612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610f1c90612c31565b9650505b508080610f2c90612c31565b915050610de8565b50508080610f4190612c31565b915050610dad565b50818452505050919050565b6000610f5f611061565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b610fc461117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611028576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611031816114d4565b50565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b60006110c56114e0565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611106576111036113e8565b90505b90565b6000611113611034565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b600061118461108e565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006111b7611061565b905060008160010160009054906101000a900461ffff1661ffff169050600081905060008060078316111561120357836002016000600384901c81526020019081526020016000205490505b60005b875181101561134757600088828151811061122457611223612c79565b5b60200260200101519050600081602001519050600082604001515103611276576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561128a57611289612cde565b5b81600281111561129d5761129c612cde565b5b036112bb576112ae8786868561158c565b8095508196505050611338565b600160028111156112cf576112ce612cde565b5b8160028111156112e2576112e1612cde565b5b036112f6576112f1878361183e565b611337565b60028081111561130957611308612cde565b5b81600281111561131c5761131b612cde565b5b036113365761132d87868685611af4565b80955081965050505b5b5b50508080600101915050611206565b5082821461136f57818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111561139a5780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113cd93929190612ee6565b60405180910390a16113df8686611fda565b50505050505050565b60006113f2611061565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611425612187565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611457336121b4565b61145f612187565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b80611490611061565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6114dd81612285565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156115ef57506115ed836000015173ffffffffffffffffffffffffffffffffffffffff16610368565b155b15611626576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83604001515181101561182e5760008460400151828151811061164f5761164e612c79565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff161461171a576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e0810361181657878a600201600060038c901c8152602001908152602001600020819055506000801b97505b88806001019950505050508080600101915050611629565b5084849150915094509492505050565b611861816000015173ffffffffffffffffffffffffffffffffffffffff16610368565b611897576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611aef576000826040015182815181106118c0576118bf612c79565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611990576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119f5576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a5e576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061189a565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611b61576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b856040015151811015611fbf57600086604001518281518110611b9b57611b9a612c79565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611c66576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611cce576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611d02578480600190039550508a600201600086815260200190815260200160002054985060079350611d0c565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611e2e578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214611f345760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050611f85565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703611fad578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611b75565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151461204a576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612183573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612107576120d08273ffffffffffffffffffffffffffffffffffffffff16610368565b612106576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161212e9190612f67565b600060405180830381855af49150503d8060008114612169576040519150601f19603f3d011682016040523d82523d6000602084013e61216e565b606091505b5050905080612181573d6000803e3d6000fd5b505b5050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b60006121be61108e565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61228e81612291565b50565b8061229a612187565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61235781612322565b811461236257600080fd5b50565b6000813590506123748161234e565b92915050565b6000602082840312156123905761238f612318565b5b600061239e84828501612365565b91505092915050565b60008115159050919050565b6123bc816123a7565b82525050565b60006020820190506123d760008301846123b3565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612402576124016123dd565b5b8235905067ffffffffffffffff81111561241f5761241e6123e2565b5b60208301915083602082028301111561243b5761243a6123e7565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061246d82612442565b9050919050565b61247d81612462565b811461248857600080fd5b50565b60008135905061249a81612474565b92915050565b60008083601f8401126124b6576124b56123dd565b5b8235905067ffffffffffffffff8111156124d3576124d26123e2565b5b6020830191508360018202830111156124ef576124ee6123e7565b5b9250929050565b60008060008060006060868803121561251257612511612318565b5b600086013567ffffffffffffffff8111156125305761252f61231d565b5b61253c888289016123ec565b9550955050602061254f8882890161248b565b935050604086013567ffffffffffffffff8111156125705761256f61231d565b5b61257c888289016124a0565b92509250509295509295909350565b61259481612462565b82525050565b60006020820190506125af600083018461258b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6125ea81612462565b82525050565b60006125fc83836125e1565b60208301905092915050565b6000602082019050919050565b6000612620826125b5565b61262a81856125c0565b9350612635836125d1565b8060005b8381101561266657815161264d88826125f0565b975061265883612608565b925050600181019050612639565b5085935050505092915050565b6000602082019050818103600083015261268d8184612615565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6126f681612322565b82525050565b600061270883836126ed565b60208301905092915050565b6000602082019050919050565b600061272c826126c1565b61273681856126cc565b9350612741836126dd565b8060005b8381101561277257815161275988826126fc565b975061276483612714565b925050600181019050612745565b5085935050505092915050565b600060408301600083015161279760008601826125e1565b50602083015184820360208601526127af8282612721565b9150508091505092915050565b60006127c8838361277f565b905092915050565b6000602082019050919050565b60006127e882612695565b6127f281856126a0565b935083602082028501612804856126b1565b8060005b85811015612840578484038952815161282185826127bc565b945061282c836127d0565b925060208a01995050600181019050612808565b50829750879550505050505092915050565b6000602082019050818103600083015261286c81846127dd565b905092915050565b60006020828403121561288a57612889612318565b5b60006128988482850161248b565b91505092915050565b600082825260208201905092915050565b60006128bd826126c1565b6128c781856128a1565b93506128d2836126dd565b8060005b838110156129035781516128ea88826126fc565b97506128f583612714565b9250506001810190506128d6565b5085935050505092915050565b6000602082019050818103600083015261292a81846128b2565b905092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61297b82612932565b810181811067ffffffffffffffff8211171561299a57612999612943565b5b80604052505050565b60006129ad61230e565b90506129b98282612972565b919050565b600067ffffffffffffffff8211156129d9576129d8612943565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612a0157600080fd5b50565b600081359050612a13816129f4565b92915050565b600067ffffffffffffffff821115612a3457612a33612943565b5b602082029050602081019050919050565b6000612a58612a5384612a19565b6129a3565b90508083825260208201905060208402830185811115612a7b57612a7a6123e7565b5b835b81811015612aa45780612a908882612365565b845260208401935050602081019050612a7d565b5050509392505050565b600082601f830112612ac357612ac26123dd565b5b8135612ad3848260208601612a45565b91505092915050565b600060608284031215612af257612af16129ea565b5b612afc60606129a3565b90506000612b0c8482850161248b565b6000830152506020612b2084828501612a04565b602083015250604082013567ffffffffffffffff811115612b4457612b436129ef565b5b612b5084828501612aae565b60408301525092915050565b6000612b6f612b6a846129be565b6129a3565b90508083825260208201905060208402830185811115612b9257612b916123e7565b5b835b81811015612bd957803567ffffffffffffffff811115612bb757612bb66123dd565b5b808601612bc48982612adc565b85526020850194505050602081019050612b94565b5050509392505050565b6000612bf0368484612b5c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000612c3c82612c27565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c6e57612c6d612bf8565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612cc082612ca8565b915060ff8203612cd357612cd2612bf8565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612d4a57612d49612cde565b5b50565b6000819050612d5b82612d39565b919050565b6000612d6b82612d4d565b9050919050565b612d7b81612d60565b82525050565b6000606083016000830151612d9960008601826125e1565b506020830151612dac6020860182612d72565b5060408301518482036040860152612dc48282612721565b9150508091505092915050565b6000612ddd8383612d81565b905092915050565b6000602082019050919050565b6000612dfd82612d0d565b612e078185612d18565b935083602082028501612e1985612d29565b8060005b85811015612e555784840389528151612e368582612dd1565b9450612e4183612de5565b925060208a01995050600181019050612e1d565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612ea1578082015181840152602081019050612e86565b60008484015250505050565b6000612eb882612e67565b612ec28185612e72565b9350612ed2818560208601612e83565b612edb81612932565b840191505092915050565b60006060820190508181036000830152612f008186612df2565b9050612f0f602083018561258b565b8181036040830152612f218184612ead565b9050949350505050565b600081905092915050565b6000612f4182612e67565b612f4b8185612f2b565b9350612f5b818560208601612e83565b80840191505092915050565b6000612f738284612f36565b91508190509291505056fea2646970667358221220cea866a50491875db0db97ebcb0109da80c9a02578afcc3b44b2d7b74eca5c4064736f6c63430008110033
Deployed Bytecode
0x6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146102375780638da5cb5b14610262578063914237651461028d578063adfca15e146102b6578063cdffacc6146102f3578063f2fde38b14610330576100b2565b806301ffc9a7146101395780631f931c1c146101765780632c4080591461019f57806352ef6b2c146101ca57806379ba5097146101f55780637a0ed6271461020c576100b2565b366100b257005b60006100bc610359565b90506100dd8173ffffffffffffffffffffffffffffffffffffffff16610368565b610113576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e8060008114610134573d6000f35b3d6000fd5b34801561014557600080fd5b50610160600480360381019061015b919061237a565b61037b565b60405161016d91906123c2565b60405180910390f35b34801561018257600080fd5b5061019d600480360381019061019891906124f6565b61038d565b005b3480156101ab57600080fd5b506101b461045b565b6040516101c1919061259a565b60405180910390f35b3480156101d657600080fd5b506101df61046a565b6040516101ec9190612673565b60405180910390f35b34801561020157600080fd5b5061020a6106cb565b005b34801561021857600080fd5b50610221610741565b60405161022e9190612852565b60405180910390f35b34801561024357600080fd5b5061024c610ca2565b604051610259919061259a565b60405180910390f35b34801561026e57600080fd5b50610277610cb1565b604051610284919061259a565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190612874565b610cc0565b005b3480156102c257600080fd5b506102dd60048036038101906102d89190612874565b610d38565b6040516102ea9190612910565b60405180910390f35b3480156102ff57600080fd5b5061031a6004803603810190610315919061237a565b610f55565b604051610327919061259a565b60405180910390f35b34801561033c57600080fd5b5061035760048036038101906103529190612874565b610fbc565b005b60006103636110bb565b905090565b600080823b905060008111915050919050565b600061038682611109565b9050919050565b61039561117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103f9576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104548585906104099190612be3565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506111ad565b5050505050565b60006104656113e8565b905090565b60606000610476611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156104a8576104a7612943565b5b6040519080825280602002602001820160405280156104d65781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff168210156106c157600084600201600083815260200190815260200160002054905060005b60088110156106ac57838061052e90612c31565b9450508560010160009054906101000a900461ffff1661ffff1684116106ac576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b8881101561062a578a81815181106105d4576105d3612c79565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610617576001915061062a565b808061062290612c31565b9150506105b9565b50801561063957505050610699565b818a898151811061064d5761064c612c79565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061069290612c31565b9850505050505b80806106a490612c31565b91505061051a565b505080806106b990612c31565b9150506104df565b5081845250505090565b6106d361141b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610737576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61073f61144e565b565b6060600061074d611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561077f5761077e612943565b5b6040519080825280602002602001820160405280156107b857816020015b6107a56122de565b81526020019060019003908161079d5790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156107ed576107ec612943565b5b60405190808252806020026020018201604052801561081b5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610c2e57600085600201600083815260200190815260200160002054905060005b6008811015610c1957838061087390612c31565b9450508660010160009054906101000a900461ffff1661ffff168411610c19576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610a6a578273ffffffffffffffffffffffffffffffffffffffff168c82815181106109305761092f612c79565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610a5757838c828151811061096b5761096a612c79565b5b6020026020010151602001518b838151811061098a57610989612c79565b5b602002602001015160ff16815181106109a6576109a5612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610a0757610a06612c79565b5b602002602001015160ff1610610a1c57600080fd5b898181518110610a2f57610a2e612c79565b5b602002602001018051809190610a4490612cb5565b60ff1660ff168152505060019150610a6a565b8080610a6290612c31565b9150506108fe565b508015610a7957505050610c06565b818b8981518110610a8d57610a8c612c79565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610afb57610afa612943565b5b604051908082528060200260200182016040528015610b295781602001602082028036833780820191505090505b508b8981518110610b3d57610b3c612c79565b5b602002602001015160200181905250828b8981518110610b6057610b5f612c79565b5b602002602001015160200151600081518110610b7f57610b7e612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610be057610bdf612c79565b5b602002602001019060ff16908160ff16815250508780610bff90612c31565b9850505050505b8080610c1190612c31565b91505061085f565b50508080610c2690612c31565b915050610824565b5060005b82811015610c97576000848281518110610c4f57610c4e612c79565b5b602002602001015160ff1690506000878381518110610c7157610c70612c79565b5b602002602001015160200151905081815250508080610c8f90612c31565b915050610c32565b508185525050505090565b6000610cac61141b565b905090565b6000610cbb61117a565b905090565b610cc861117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d2c576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d3581611487565b50565b60606000610d44611061565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610d7657610d75612943565b5b604051908082528060200260200182016040528015610da45781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff16821015610f4957600084600201600083815260200190815260200160002054905060005b6008811015610f34578380610dfc90612c31565b9450508560010160009054906101000a900461ffff1661ffff168411610f34576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610f205780888781518110610ec557610ec4612c79565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610f1c90612c31565b9650505b508080610f2c90612c31565b915050610de8565b50508080610f4190612c31565b915050610dad565b50818452505050919050565b6000610f5f611061565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b610fc461117a565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611028576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611031816114d4565b50565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b60006110c56114e0565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611106576111036113e8565b90505b90565b6000611113611034565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b600061118461108e565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006111b7611061565b905060008160010160009054906101000a900461ffff1661ffff169050600081905060008060078316111561120357836002016000600384901c81526020019081526020016000205490505b60005b875181101561134757600088828151811061122457611223612c79565b5b60200260200101519050600081602001519050600082604001515103611276576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561128a57611289612cde565b5b81600281111561129d5761129c612cde565b5b036112bb576112ae8786868561158c565b8095508196505050611338565b600160028111156112cf576112ce612cde565b5b8160028111156112e2576112e1612cde565b5b036112f6576112f1878361183e565b611337565b60028081111561130957611308612cde565b5b81600281111561131c5761131b612cde565b5b036113365761132d87868685611af4565b80955081965050505b5b5b50508080600101915050611206565b5082821461136f57818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111561139a5780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516113cd93929190612ee6565b60405180910390a16113df8686611fda565b50505050505050565b60006113f2611061565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611425612187565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611457336121b4565b61145f612187565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b80611490611061565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6114dd81612285565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156115ef57506115ed836000015173ffffffffffffffffffffffffffffffffffffffff16610368565b155b15611626576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83604001515181101561182e5760008460400151828151811061164f5761164e612c79565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff161461171a576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e0810361181657878a600201600060038c901c8152602001908152602001600020819055506000801b97505b88806001019950505050508080600101915050611629565b5084849150915094509492505050565b611861816000015173ffffffffffffffffffffffffffffffffffffffff16610368565b611897576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611aef576000826040015182815181106118c0576118bf612c79565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611990576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119f5576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a5e576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061189a565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611b61576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b856040015151811015611fbf57600086604001518281518110611b9b57611b9a612c79565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611c66576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611cce576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611d02578480600190039550508a600201600086815260200190815260200160002054985060079350611d0c565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611e2e578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214611f345760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050611f85565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703611fad578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611b75565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151461204a576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612183573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612107576120d08273ffffffffffffffffffffffffffffffffffffffff16610368565b612106576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161212e9190612f67565b600060405180830381855af49150503d8060008114612169576040519150601f19603f3d011682016040523d82523d6000602084013e61216e565b606091505b5050905080612181573d6000803e3d6000fd5b505b5050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b60006121be61108e565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61228e81612291565b50565b8061229a612187565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61235781612322565b811461236257600080fd5b50565b6000813590506123748161234e565b92915050565b6000602082840312156123905761238f612318565b5b600061239e84828501612365565b91505092915050565b60008115159050919050565b6123bc816123a7565b82525050565b60006020820190506123d760008301846123b3565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f840112612402576124016123dd565b5b8235905067ffffffffffffffff81111561241f5761241e6123e2565b5b60208301915083602082028301111561243b5761243a6123e7565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061246d82612442565b9050919050565b61247d81612462565b811461248857600080fd5b50565b60008135905061249a81612474565b92915050565b60008083601f8401126124b6576124b56123dd565b5b8235905067ffffffffffffffff8111156124d3576124d26123e2565b5b6020830191508360018202830111156124ef576124ee6123e7565b5b9250929050565b60008060008060006060868803121561251257612511612318565b5b600086013567ffffffffffffffff8111156125305761252f61231d565b5b61253c888289016123ec565b9550955050602061254f8882890161248b565b935050604086013567ffffffffffffffff8111156125705761256f61231d565b5b61257c888289016124a0565b92509250509295509295909350565b61259481612462565b82525050565b60006020820190506125af600083018461258b565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6125ea81612462565b82525050565b60006125fc83836125e1565b60208301905092915050565b6000602082019050919050565b6000612620826125b5565b61262a81856125c0565b9350612635836125d1565b8060005b8381101561266657815161264d88826125f0565b975061265883612608565b925050600181019050612639565b5085935050505092915050565b6000602082019050818103600083015261268d8184612615565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6126f681612322565b82525050565b600061270883836126ed565b60208301905092915050565b6000602082019050919050565b600061272c826126c1565b61273681856126cc565b9350612741836126dd565b8060005b8381101561277257815161275988826126fc565b975061276483612714565b925050600181019050612745565b5085935050505092915050565b600060408301600083015161279760008601826125e1565b50602083015184820360208601526127af8282612721565b9150508091505092915050565b60006127c8838361277f565b905092915050565b6000602082019050919050565b60006127e882612695565b6127f281856126a0565b935083602082028501612804856126b1565b8060005b85811015612840578484038952815161282185826127bc565b945061282c836127d0565b925060208a01995050600181019050612808565b50829750879550505050505092915050565b6000602082019050818103600083015261286c81846127dd565b905092915050565b60006020828403121561288a57612889612318565b5b60006128988482850161248b565b91505092915050565b600082825260208201905092915050565b60006128bd826126c1565b6128c781856128a1565b93506128d2836126dd565b8060005b838110156129035781516128ea88826126fc565b97506128f583612714565b9250506001810190506128d6565b5085935050505092915050565b6000602082019050818103600083015261292a81846128b2565b905092915050565b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61297b82612932565b810181811067ffffffffffffffff8211171561299a57612999612943565b5b80604052505050565b60006129ad61230e565b90506129b98282612972565b919050565b600067ffffffffffffffff8211156129d9576129d8612943565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612a0157600080fd5b50565b600081359050612a13816129f4565b92915050565b600067ffffffffffffffff821115612a3457612a33612943565b5b602082029050602081019050919050565b6000612a58612a5384612a19565b6129a3565b90508083825260208201905060208402830185811115612a7b57612a7a6123e7565b5b835b81811015612aa45780612a908882612365565b845260208401935050602081019050612a7d565b5050509392505050565b600082601f830112612ac357612ac26123dd565b5b8135612ad3848260208601612a45565b91505092915050565b600060608284031215612af257612af16129ea565b5b612afc60606129a3565b90506000612b0c8482850161248b565b6000830152506020612b2084828501612a04565b602083015250604082013567ffffffffffffffff811115612b4457612b436129ef565b5b612b5084828501612aae565b60408301525092915050565b6000612b6f612b6a846129be565b6129a3565b90508083825260208201905060208402830185811115612b9257612b916123e7565b5b835b81811015612bd957803567ffffffffffffffff811115612bb757612bb66123dd565b5b808601612bc48982612adc565b85526020850194505050602081019050612b94565b5050509392505050565b6000612bf0368484612b5c565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000612c3c82612c27565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612c6e57612c6d612bf8565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612cc082612ca8565b915060ff8203612cd357612cd2612bf8565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612d4a57612d49612cde565b5b50565b6000819050612d5b82612d39565b919050565b6000612d6b82612d4d565b9050919050565b612d7b81612d60565b82525050565b6000606083016000830151612d9960008601826125e1565b506020830151612dac6020860182612d72565b5060408301518482036040860152612dc48282612721565b9150508091505092915050565b6000612ddd8383612d81565b905092915050565b6000602082019050919050565b6000612dfd82612d0d565b612e078185612d18565b935083602082028501612e1985612d29565b8060005b85811015612e555784840389528151612e368582612dd1565b9450612e4183612de5565b925060208a01995050600181019050612e1d565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612ea1578082015181840152602081019050612e86565b60008484015250505050565b6000612eb882612e67565b612ec28185612e72565b9350612ed2818560208601612e83565b612edb81612932565b840191505092915050565b60006060820190508181036000830152612f008186612df2565b9050612f0f602083018561258b565b8181036040830152612f218184612ead565b9050949350505050565b600081905092915050565b6000612f4182612e67565b612f4b8185612f2b565b9350612f5b818560208601612e83565b80840191505092915050565b6000612f738284612f36565b91508190509291505056fea2646970667358221220cea866a50491875db0db97ebcb0109da80c9a02578afcc3b44b2d7b74eca5c4064736f6c63430008110033
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.