Sepolia Testnet

Token

Project Apidom ()
ERC-1155

Overview

Max Total Supply

0

Holders

31

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x3324d4129de9cdb54e54fe16789e64d978abfa05
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# 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 Source Code Verified (Exact Match)

Contract Name:
UniversalDiamond

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 37 : UniversalDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import {SolidStateDiamond} from "@solidstate/contracts/proxy/diamond/SolidStateDiamond.sol";

/**
 * @title UniversalDiamond "Diamond" proxy implementation based on SolidState Diamond Reference
 */
contract UniversalDiamond is SolidStateDiamond {
    string public name = "Project Apidom";
}

File 2 of 37 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../../interfaces/IERC173.sol';

interface IOwnable is IERC173 {}

File 3 of 37 : IOwnableInternal.sol
// 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;
}

File 5 of 37 : ISafeOwnableInternal.sol
// 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;
    }
}

File 8 of 37 : OwnableStorage.sol
// 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;
    }
}

File 11 of 37 : SafeOwnableStorage.sol
// 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);
}

File 13 of 37 : IERC165Internal.sol
// 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;
}

File 15 of 37 : IERC173Internal.sol
// 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
    );
}

File 16 of 37 : ERC165Base.sol
// 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;
    }
}

File 18 of 37 : ERC165BaseStorage.sol
// 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
        }
    }
}

File 19 of 37 : IERC165Base.sol
// 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 {}

File 20 of 37 : IERC165BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { IERC165Internal } from '../../../interfaces/IERC165Internal.sol';

interface IERC165BaseInternal is IERC165Internal {
    error ERC165Base__InvalidInterfaceId();
}

File 21 of 37 : DiamondBase.sol
// 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]));
    }
}

File 22 of 37 : DiamondBaseStorage.sol
// 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
        }
    }
}

File 23 of 37 : IDiamondBase.sol
// 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;
}

File 26 of 37 : ISolidStateDiamond.sol
// 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();
    }
}

File 30 of 37 : DiamondWritable.sol
// 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;
}

File 33 of 37 : IDiamondWritableInternal.sol
// 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;
    }
}

File 34 of 37 : IProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IProxy {
    error Proxy__ImplementationIsNotContract();

    fallback() external payable;
}

File 35 of 37 : Proxy.sol
// 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);
    }
}

Settings
{
  "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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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"}]

60806040526040518060400160405280600e81526020017f50726f6a65637420417069646f6d000000000000000000000000000000000000815250600090816200004a919062001c48565b503480156200005857600080fd5b506000600c67ffffffffffffffff811115620000795762000078620019d9565b5b604051908082528060200260200182016040528015620000a85781602001602082028036833780820191505090505b5090506000632c40805960e01b828280620000c39062001d5e565b935081518110620000d957620000d862001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050639142376560e01b8282806200013b9062001d5e565b93508151811062000151576200015062001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620001d07fbd02b73c0000000000000000000000000000000000000000000000000000000060016200085260201b60201c565b631f931c1c60e01b828280620001e69062001d5e565b935081518110620001fc57620001fb62001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506200027b7f1f931c1c0000000000000000000000000000000000000000000000000000000060016200085260201b60201c565b637a0ed62760e01b828280620002919062001d5e565b935081518110620002a757620002a662001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063adfca15e60e01b828280620003099062001d5e565b9350815181106200031f576200031e62001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506352ef6b2c60e01b828280620003819062001d5e565b93508151811062000397576200039662001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063cdffacc660e01b828280620003f99062001d5e565b9350815181106200040f576200040e62001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506200048e7f48e2b0930000000000000000000000000000000000000000000000000000000060016200085260201b60201c565b6301ffc9a760e01b828280620004a49062001d5e565b935081518110620004ba57620004b962001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050620005397f01ffc9a70000000000000000000000000000000000000000000000000000000060016200085260201b60201c565b638da5cb5b60e01b8282806200054f9062001d5e565b93508151811062000565576200056462001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681525050638ab5150a60e01b828280620005c79062001d5e565b935081518110620005dd57620005dc62001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505063f2fde38b60e01b8282806200063f9062001d5e565b93508151811062000655576200065462001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506379ba509760e01b828280620006b79062001d5e565b935081518110620006cd57620006cc62001dab565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506200074c7f7f5828d00000000000000000000000000000000000000000000000000000000060016200085260201b60201c565b6000600167ffffffffffffffff8111156200076c576200076b620019d9565b5b604051908082528060200260200182016040528015620007a957816020015b6200079562001982565b8152602001906001900390816200078b5790505b50905060405180606001604052803073ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620007ea57620007e962001dda565b5b815260200184815250816000815181106200080a576200080962001dab565b5b602002602001018190525062000838816000604051806020016040528060008152506200093560201b60201c565b620008493362000bbf60201b60201c565b50505062002210565b63ffffffff60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603620008b2576040517fb0a19dd500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80620008c862000c9d60201b620011081760201c565b6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60006200094c62000cca60201b620011351760201c565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156200099957836002016000600384901c81526020019081526020016000205490505b60005b875181101562000b12576000888281518110620009be57620009bd62001dab565b5b6020026020010151905060008160200151905060008260400151510362000a11576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111562000a285762000a2762001dda565b5b81600281111562000a3e5762000a3d62001dda565b5b0362000a665762000a588786868562000cf760201b60201c565b809550819650505062000b02565b6001600281111562000a7d5762000a7c62001dda565b5b81600281111562000a935762000a9262001dda565b5b0362000ab15762000aab878362000fbf60201b60201c565b62000b01565b60028081111562000ac75762000ac662001dda565b5b81600281111562000add5762000adc62001dda565b5b0362000b005762000af7878686856200128b60201b60201c565b80955081965050505b5b5b505080806001019150506200099c565b5082821462000b3b57818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111562000b675780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405162000b9c939291906200216a565b60405180910390a162000bb686866200177f60201b60201c565b50505050505050565b600062000bd66200194260201b620011621760201c565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415801562000d68575062000d66836000015173ffffffffffffffffffffffffffffffffffffffff166200196f60201b620003ae1760201c565b155b1562000da0576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b83604001515181101562000faf5760008460400151828151811062000dcd5762000dcc62001dab565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff161462000e99576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e0810362000f9657878a600201600060038c901c8152602001908152602001600020819055506000801b97505b8880600101995050505050808060010191505062000da3565b5084849150915094509492505050565b62000fef816000015173ffffffffffffffffffffffffffffffffffffffff166200196f60201b620003ae1760201c565b62001026576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015620012865760008260400151828151811062001053576200105262001dab565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160362001124576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200118a576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620011f4576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505062001029565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614620012f9576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b856040015151811015620017645760008660400151828151811062001337576200133662001dab565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff160362001403576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff16036200146c576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903620014a2578480600190039550508a600201600086815260200190815260200160002054985060079350620014ac565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614620015cf578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b915050878214620016d75760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f6002016000858152602001908152602001600020819055505062001728565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b6000870362001751578d6002016000898152602001908152602001600020600090556000801b9b505b505050505080806001019150506200130d565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151514620017f0576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200193e573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620018bd57620018858273ffffffffffffffffffffffffffffffffffffffff166200196f60201b620003ae1760201c565b620018bc576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051620018e69190620021f7565b600060405180830381855af49150503d806000811462001923576040519150601f19603f3d011682016040523d82523d6000602084013e62001928565b606091505b50509050806200193c573d6000803e3d6000fd5b505b5050565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b600080823b905060008111915050919050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160006002811115620019c157620019c062001dda565b5b8152602001606081525090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168062001a5057607f821691505b60208210810362001a665762001a6562001a08565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830262001ad07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262001a91565b62001adc868362001a91565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b600062001b2962001b2362001b1d8462001af4565b62001afe565b62001af4565b9050919050565b6000819050919050565b62001b458362001b08565b62001b5d62001b548262001b30565b84845462001a9e565b825550505050565b600090565b62001b7462001b65565b62001b8181848462001b3a565b505050565b5b8181101562001ba95762001b9d60008262001b6a565b60018101905062001b87565b5050565b601f82111562001bf85762001bc28162001a6c565b62001bcd8462001a81565b8101602085101562001bdd578190505b62001bf562001bec8562001a81565b83018262001b86565b50505b505050565b600082821c905092915050565b600062001c1d6000198460080262001bfd565b1980831691505092915050565b600062001c38838362001c0a565b9150826002028217905092915050565b62001c5382620019ce565b67ffffffffffffffff81111562001c6f5762001c6e620019d9565b5b62001c7b825462001a37565b62001c8882828562001bad565b600060209050601f83116001811462001cc0576000841562001cab578287015190505b62001cb7858262001c2a565b86555062001d27565b601f19841662001cd08662001a6c565b60005b8281101562001cfa5784890151825560018201915060208501945060208101905062001cd3565b8683101562001d1a578489015162001d16601f89168262001c0a565b8355505b6001600288020188555050505b505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062001d6b8262001af4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820362001da05762001d9f62001d2f565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062001e628262001e35565b9050919050565b62001e748162001e55565b82525050565b6003811062001e8e5762001e8d62001dda565b5b50565b600081905062001ea18262001e7a565b919050565b600062001eb38262001e91565b9050919050565b62001ec58162001ea6565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b62001f2e8162001ef7565b82525050565b600062001f42838362001f23565b60208301905092915050565b6000602082019050919050565b600062001f688262001ecb565b62001f74818562001ed6565b935062001f818362001ee7565b8060005b8381101562001fb857815162001f9c888262001f34565b975062001fa98362001f4e565b92505060018101905062001f85565b5085935050505092915050565b600060608301600083015162001fdf600086018262001e69565b50602083015162001ff4602086018262001eba565b50604083015184820360408601526200200e828262001f5b565b9150508091505092915050565b600062002029838362001fc5565b905092915050565b6000602082019050919050565b60006200204b8262001e09565b62002057818562001e14565b9350836020820285016200206b8562001e25565b8060005b85811015620020ad57848403895281516200208b85826200201b565b9450620020988362002031565b925060208a019950506001810190506200206f565b50829750879550505050505092915050565b620020ca8162001e55565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156200210c578082015181840152602081019050620020ef565b60008484015250505050565b6000601f19601f8301169050919050565b60006200213682620020d0565b620021428185620020db565b935062002154818560208601620020ec565b6200215f8162002118565b840191505092915050565b600060608201905081810360008301526200218681866200203e565b9050620021976020830185620020bf565b8181036040830152620021ab818462002129565b9050949350505050565b600081905092915050565b6000620021cd82620020d0565b620021d98185620021b5565b9350620021eb818560208601620020ec565b80840191505092915050565b6000620022058284620021c0565b915081905092915050565b61315f80620022206000396000f3fe6080604052600436106100c65760003560e01c80637a0ed6271161007f578063914237651161005957806391423765146102d3578063adfca15e146102fc578063cdffacc614610339578063f2fde38b14610376576100cd565b80637a0ed627146102525780638ab5150a1461027d5780638da5cb5b146102a8576100cd565b806301ffc9a71461015457806306fdde03146101915780631f931c1c146101bc5780632c408059146101e557806352ef6b2c1461021057806379ba50971461023b576100cd565b366100cd57005b60006100d761039f565b90506100f88173ffffffffffffffffffffffffffffffffffffffff166103ae565b61012e576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e806000811461014f573d6000f35b3d6000fd5b34801561016057600080fd5b5061017b6004803603810190610176919061244e565b6103c1565b6040516101889190612496565b60405180910390f35b34801561019d57600080fd5b506101a66103d3565b6040516101b39190612541565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de919061267c565b610461565b005b3480156101f157600080fd5b506101fa61052f565b6040516102079190612720565b60405180910390f35b34801561021c57600080fd5b5061022561053e565b60405161023291906127f9565b60405180910390f35b34801561024757600080fd5b5061025061079f565b005b34801561025e57600080fd5b50610267610815565b60405161027491906129d8565b60405180910390f35b34801561028957600080fd5b50610292610d76565b60405161029f9190612720565b60405180910390f35b3480156102b457600080fd5b506102bd610d85565b6040516102ca9190612720565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f591906129fa565b610d94565b005b34801561030857600080fd5b50610323600480360381019061031e91906129fa565b610e0c565b6040516103309190612a96565b60405180910390f35b34801561034557600080fd5b50610360600480360381019061035b919061244e565b611029565b60405161036d9190612720565b60405180910390f35b34801561038257600080fd5b5061039d600480360381019061039891906129fa565b611090565b005b60006103a961118f565b905090565b600080823b905060008111915050919050565b60006103cc826111dd565b9050919050565b600080546103e090612ae7565b80601f016020809104026020016040519081016040528092919081815260200182805461040c90612ae7565b80156104595780601f1061042e57610100808354040283529160200191610459565b820191906000526020600020905b81548152906001019060200180831161043c57829003601f168201915b505050505081565b61046961124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104cd576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105288585906104dd9190612db8565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611281565b5050505050565b60006105396114bc565b905090565b6060600061054a611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561057c5761057b612b18565b5b6040519080825280602002602001820160405280156105aa5781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561079557600084600201600083815260200190815260200160002054905060005b600881101561078057838061060290612e06565b9450508560010160009054906101000a900461ffff1661ffff168411610780576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b888110156106fe578a81815181106106a8576106a7612e4e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106eb57600191506106fe565b80806106f690612e06565b91505061068d565b50801561070d5750505061076d565b818a898151811061072157610720612e4e565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061076690612e06565b9850505050505b808061077890612e06565b9150506105ee565b5050808061078d90612e06565b9150506105b3565b5081845250505090565b6107a76114ef565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080b576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610813611522565b565b60606000610821611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561085357610852612b18565b5b60405190808252806020026020018201604052801561088c57816020015b6108796123b2565b8152602001906001900390816108715790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156108c1576108c0612b18565b5b6040519080825280602002602001820160405280156108ef5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610d0257600085600201600083815260200190815260200160002054905060005b6008811015610ced57838061094790612e06565b9450508660010160009054906101000a900461ffff1661ffff168411610ced576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610b3e578273ffffffffffffffffffffffffffffffffffffffff168c8281518110610a0457610a03612e4e565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610b2b57838c8281518110610a3f57610a3e612e4e565b5b6020026020010151602001518b8381518110610a5e57610a5d612e4e565b5b602002602001015160ff1681518110610a7a57610a79612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610adb57610ada612e4e565b5b602002602001015160ff1610610af057600080fd5b898181518110610b0357610b02612e4e565b5b602002602001018051809190610b1890612e8a565b60ff1660ff168152505060019150610b3e565b8080610b3690612e06565b9150506109d2565b508015610b4d57505050610cda565b818b8981518110610b6157610b60612e4e565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610bcf57610bce612b18565b5b604051908082528060200260200182016040528015610bfd5781602001602082028036833780820191505090505b508b8981518110610c1157610c10612e4e565b5b602002602001015160200181905250828b8981518110610c3457610c33612e4e565b5b602002602001015160200151600081518110610c5357610c52612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610cb457610cb3612e4e565b5b602002602001019060ff16908160ff16815250508780610cd390612e06565b9850505050505b8080610ce590612e06565b915050610933565b50508080610cfa90612e06565b9150506108f8565b5060005b82811015610d6b576000848281518110610d2357610d22612e4e565b5b602002602001015160ff1690506000878381518110610d4557610d44612e4e565b5b602002602001015160200151905081815250508080610d6390612e06565b915050610d06565b508185525050505090565b6000610d806114ef565b905090565b6000610d8f61124e565b905090565b610d9c61124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e00576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e098161155b565b50565b60606000610e18611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610e4a57610e49612b18565b5b604051908082528060200260200182016040528015610e785781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561101d57600084600201600083815260200190815260200160002054905060005b6008811015611008578380610ed090612e06565b9450508560010160009054906101000a900461ffff1661ffff168411611008576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610ff45780888781518110610f9957610f98612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610ff090612e06565b9650505b50808061100090612e06565b915050610ebc565b5050808061101590612e06565b915050610e81565b50818452505050919050565b6000611033611135565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b61109861124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110fc576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611105816115a8565b50565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b60006111996115b4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111da576111d76114bc565b90505b90565b60006111e7611108565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6000611258611162565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061128b611135565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156112d757836002016000600384901c81526020019081526020016000205490505b60005b875181101561141b5760008882815181106112f8576112f7612e4e565b5b6020026020010151905060008160200151905060008260400151510361134a576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561135e5761135d612eb3565b5b81600281111561137157611370612eb3565b5b0361138f5761138287868685611660565b809550819650505061140c565b600160028111156113a3576113a2612eb3565b5b8160028111156113b6576113b5612eb3565b5b036113ca576113c58783611912565b61140b565b6002808111156113dd576113dc612eb3565b5b8160028111156113f0576113ef612eb3565b5b0361140a5761140187868685611bc8565b80955081965050505b5b5b505080806001019150506112da565b5082821461144357818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111561146e5780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516114a193929190613091565b60405180910390a16114b386866120ae565b50505050505050565b60006114c6611135565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006114f961225b565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61152b33612288565b61153361225b565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b80611564611135565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115b181612359565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156116c357506116c1836000015173ffffffffffffffffffffffffffffffffffffffff166103ae565b155b156116fa576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8360400151518110156119025760008460400151828151811061172357611722612e4e565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff16146117ee576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e081036118ea57878a600201600060038c901c8152602001908152602001600020819055506000801b97505b888060010199505050505080806001019150506116fd565b5084849150915094509492505050565b611935816000015173ffffffffffffffffffffffffffffffffffffffff166103ae565b61196b576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611bc35760008260400151828151811061199457611993612e4e565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a64576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac9576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b32576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061196e565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611c35576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b85604001515181101561209357600086604001518281518110611c6f57611c6e612e4e565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d3a576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611da2576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611dd6578480600190039550508a600201600086815260200190815260200160002054985060079350611de0565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611f02578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b9150508782146120085760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050612059565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703612081578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611c49565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151461211e576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612257573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146121db576121a48273ffffffffffffffffffffffffffffffffffffffff166103ae565b6121da576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516122029190613112565b600060405180830381855af49150503d806000811461223d576040519150601f19603f3d011682016040523d82523d6000602084013e612242565b606091505b5050905080612255573d6000803e3d6000fd5b505b5050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b6000612292611162565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61236281612365565b50565b8061236e61225b565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61242b816123f6565b811461243657600080fd5b50565b60008135905061244881612422565b92915050565b600060208284031215612464576124636123ec565b5b600061247284828501612439565b91505092915050565b60008115159050919050565b6124908161247b565b82525050565b60006020820190506124ab6000830184612487565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124eb5780820151818401526020810190506124d0565b60008484015250505050565b6000601f19601f8301169050919050565b6000612513826124b1565b61251d81856124bc565b935061252d8185602086016124cd565b612536816124f7565b840191505092915050565b6000602082019050818103600083015261255b8184612508565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261258857612587612563565b5b8235905067ffffffffffffffff8111156125a5576125a4612568565b5b6020830191508360208202830111156125c1576125c061256d565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006125f3826125c8565b9050919050565b612603816125e8565b811461260e57600080fd5b50565b600081359050612620816125fa565b92915050565b60008083601f84011261263c5761263b612563565b5b8235905067ffffffffffffffff81111561265957612658612568565b5b6020830191508360018202830111156126755761267461256d565b5b9250929050565b600080600080600060608688031215612698576126976123ec565b5b600086013567ffffffffffffffff8111156126b6576126b56123f1565b5b6126c288828901612572565b955095505060206126d588828901612611565b935050604086013567ffffffffffffffff8111156126f6576126f56123f1565b5b61270288828901612626565b92509250509295509295909350565b61271a816125e8565b82525050565b60006020820190506127356000830184612711565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612770816125e8565b82525050565b60006127828383612767565b60208301905092915050565b6000602082019050919050565b60006127a68261273b565b6127b08185612746565b93506127bb83612757565b8060005b838110156127ec5781516127d38882612776565b97506127de8361278e565b9250506001810190506127bf565b5085935050505092915050565b60006020820190508181036000830152612813818461279b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61287c816123f6565b82525050565b600061288e8383612873565b60208301905092915050565b6000602082019050919050565b60006128b282612847565b6128bc8185612852565b93506128c783612863565b8060005b838110156128f85781516128df8882612882565b97506128ea8361289a565b9250506001810190506128cb565b5085935050505092915050565b600060408301600083015161291d6000860182612767565b506020830151848203602086015261293582826128a7565b9150508091505092915050565b600061294e8383612905565b905092915050565b6000602082019050919050565b600061296e8261281b565b6129788185612826565b93508360208202850161298a85612837565b8060005b858110156129c657848403895281516129a78582612942565b94506129b283612956565b925060208a0199505060018101905061298e565b50829750879550505050505092915050565b600060208201905081810360008301526129f28184612963565b905092915050565b600060208284031215612a1057612a0f6123ec565b5b6000612a1e84828501612611565b91505092915050565b600082825260208201905092915050565b6000612a4382612847565b612a4d8185612a27565b9350612a5883612863565b8060005b83811015612a89578151612a708882612882565b9750612a7b8361289a565b925050600181019050612a5c565b5085935050505092915050565b60006020820190508181036000830152612ab08184612a38565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612aff57607f821691505b602082108103612b1257612b11612ab8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612b50826124f7565b810181811067ffffffffffffffff82111715612b6f57612b6e612b18565b5b80604052505050565b6000612b826123e2565b9050612b8e8282612b47565b919050565b600067ffffffffffffffff821115612bae57612bad612b18565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612bd657600080fd5b50565b600081359050612be881612bc9565b92915050565b600067ffffffffffffffff821115612c0957612c08612b18565b5b602082029050602081019050919050565b6000612c2d612c2884612bee565b612b78565b90508083825260208201905060208402830185811115612c5057612c4f61256d565b5b835b81811015612c795780612c658882612439565b845260208401935050602081019050612c52565b5050509392505050565b600082601f830112612c9857612c97612563565b5b8135612ca8848260208601612c1a565b91505092915050565b600060608284031215612cc757612cc6612bbf565b5b612cd16060612b78565b90506000612ce184828501612611565b6000830152506020612cf584828501612bd9565b602083015250604082013567ffffffffffffffff811115612d1957612d18612bc4565b5b612d2584828501612c83565b60408301525092915050565b6000612d44612d3f84612b93565b612b78565b90508083825260208201905060208402830185811115612d6757612d6661256d565b5b835b81811015612dae57803567ffffffffffffffff811115612d8c57612d8b612563565b5b808601612d998982612cb1565b85526020850194505050602081019050612d69565b5050509392505050565b6000612dc5368484612d31565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000612e1182612dfc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e4357612e42612dcd565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612e9582612e7d565b915060ff8203612ea857612ea7612dcd565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612f1f57612f1e612eb3565b5b50565b6000819050612f3082612f0e565b919050565b6000612f4082612f22565b9050919050565b612f5081612f35565b82525050565b6000606083016000830151612f6e6000860182612767565b506020830151612f816020860182612f47565b5060408301518482036040860152612f9982826128a7565b9150508091505092915050565b6000612fb28383612f56565b905092915050565b6000602082019050919050565b6000612fd282612ee2565b612fdc8185612eed565b935083602082028501612fee85612efe565b8060005b8581101561302a578484038952815161300b8582612fa6565b945061301683612fba565b925060208a01995050600181019050612ff2565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60006130638261303c565b61306d8185613047565b935061307d8185602086016124cd565b613086816124f7565b840191505092915050565b600060608201905081810360008301526130ab8186612fc7565b90506130ba6020830185612711565b81810360408301526130cc8184613058565b9050949350505050565b600081905092915050565b60006130ec8261303c565b6130f681856130d6565b93506131068185602086016124cd565b80840191505092915050565b600061311e82846130e1565b91508190509291505056fea26469706673582212208c4451da782c4e3c6c52575917e8a4cefed2ccd8b32cad357fc8284f795c308264736f6c63430008110033

Deployed Bytecode

0x6080604052600436106100c65760003560e01c80637a0ed6271161007f578063914237651161005957806391423765146102d3578063adfca15e146102fc578063cdffacc614610339578063f2fde38b14610376576100cd565b80637a0ed627146102525780638ab5150a1461027d5780638da5cb5b146102a8576100cd565b806301ffc9a71461015457806306fdde03146101915780631f931c1c146101bc5780632c408059146101e557806352ef6b2c1461021057806379ba50971461023b576100cd565b366100cd57005b60006100d761039f565b90506100f88173ffffffffffffffffffffffffffffffffffffffff166103ae565b61012e576040517f87c9fc3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3660008037600080366000845af43d6000803e806000811461014f573d6000f35b3d6000fd5b34801561016057600080fd5b5061017b6004803603810190610176919061244e565b6103c1565b6040516101889190612496565b60405180910390f35b34801561019d57600080fd5b506101a66103d3565b6040516101b39190612541565b60405180910390f35b3480156101c857600080fd5b506101e360048036038101906101de919061267c565b610461565b005b3480156101f157600080fd5b506101fa61052f565b6040516102079190612720565b60405180910390f35b34801561021c57600080fd5b5061022561053e565b60405161023291906127f9565b60405180910390f35b34801561024757600080fd5b5061025061079f565b005b34801561025e57600080fd5b50610267610815565b60405161027491906129d8565b60405180910390f35b34801561028957600080fd5b50610292610d76565b60405161029f9190612720565b60405180910390f35b3480156102b457600080fd5b506102bd610d85565b6040516102ca9190612720565b60405180910390f35b3480156102df57600080fd5b506102fa60048036038101906102f591906129fa565b610d94565b005b34801561030857600080fd5b50610323600480360381019061031e91906129fa565b610e0c565b6040516103309190612a96565b60405180910390f35b34801561034557600080fd5b50610360600480360381019061035b919061244e565b611029565b60405161036d9190612720565b60405180910390f35b34801561038257600080fd5b5061039d600480360381019061039891906129fa565b611090565b005b60006103a961118f565b905090565b600080823b905060008111915050919050565b60006103cc826111dd565b9050919050565b600080546103e090612ae7565b80601f016020809104026020016040519081016040528092919081815260200182805461040c90612ae7565b80156104595780601f1061042e57610100808354040283529160200191610459565b820191906000526020600020905b81548152906001019060200180831161043c57829003601f168201915b505050505081565b61046961124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104cd576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105288585906104dd9190612db8565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611281565b5050505050565b60006105396114bc565b905090565b6060600061054a611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561057c5761057b612b18565b5b6040519080825280602002602001820160405280156105aa5781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561079557600084600201600083815260200190815260200160002054905060005b600881101561078057838061060290612e06565b9450508560010160009054906101000a900461ffff1661ffff168411610780576000600582901b83901b90506000876000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b888110156106fe578a81815181106106a8576106a7612e4e565b5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036106eb57600191506106fe565b80806106f690612e06565b91505061068d565b50801561070d5750505061076d565b818a898151811061072157610720612e4e565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050878061076690612e06565b9850505050505b808061077890612e06565b9150506105ee565b5050808061078d90612e06565b9150506105b3565b5081845250505090565b6107a76114ef565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461080b576040517fefd1052d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610813611522565b565b60606000610821611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff81111561085357610852612b18565b5b60405190808252806020026020018201604052801561088c57816020015b6108796123b2565b8152602001906001900390816108715790505b50915060008160010160009054906101000a900461ffff1661ffff1667ffffffffffffffff8111156108c1576108c0612b18565b5b6040519080825280602002602001820160405280156108ef5781602001602082028036833780820191505090505b50905060008060005b8460010160009054906101000a900461ffff1661ffff16821015610d0257600085600201600083815260200190815260200160002054905060005b6008811015610ced57838061094790612e06565b9450508660010160009054906101000a900461ffff1661ffff168411610ced576000600582901b83901b90506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c90506000805b88811015610b3e578273ffffffffffffffffffffffffffffffffffffffff168c8281518110610a0457610a03612e4e565b5b60200260200101516000015173ffffffffffffffffffffffffffffffffffffffff1603610b2b57838c8281518110610a3f57610a3e612e4e565b5b6020026020010151602001518b8381518110610a5e57610a5d612e4e565b5b602002602001015160ff1681518110610a7a57610a79612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152505060ff8a8281518110610adb57610ada612e4e565b5b602002602001015160ff1610610af057600080fd5b898181518110610b0357610b02612e4e565b5b602002602001018051809190610b1890612e8a565b60ff1660ff168152505060019150610b3e565b8080610b3690612e06565b9150506109d2565b508015610b4d57505050610cda565b818b8981518110610b6157610b60612e4e565b5b60200260200101516000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508960010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610bcf57610bce612b18565b5b604051908082528060200260200182016040528015610bfd5781602001602082028036833780820191505090505b508b8981518110610c1157610c10612e4e565b5b602002602001015160200181905250828b8981518110610c3457610c33612e4e565b5b602002602001015160200151600081518110610c5357610c52612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250506001898981518110610cb457610cb3612e4e565b5b602002602001019060ff16908160ff16815250508780610cd390612e06565b9850505050505b8080610ce590612e06565b915050610933565b50508080610cfa90612e06565b9150506108f8565b5060005b82811015610d6b576000848281518110610d2357610d22612e4e565b5b602002602001015160ff1690506000878381518110610d4557610d44612e4e565b5b602002602001015160200151905081815250508080610d6390612e06565b915050610d06565b508185525050505090565b6000610d806114ef565b905090565b6000610d8f61124e565b905090565b610d9c61124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e00576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e098161155b565b50565b60606000610e18611135565b90508060010160009054906101000a900461ffff1661ffff1667ffffffffffffffff811115610e4a57610e49612b18565b5b604051908082528060200260200182016040528015610e785781602001602082028036833780820191505090505b50915060008060005b8360010160009054906101000a900461ffff1661ffff1682101561101d57600084600201600083815260200190815260200160002054905060005b6008811015611008578380610ed090612e06565b9450508560010160009054906101000a900461ffff1661ffff168411611008576000600582901b83901b9050866000016000827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c73ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1603610ff45780888781518110610f9957610f98612e4e565b5b60200260200101907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815250508580610ff090612e06565b9650505b50808061100090612e06565b915050610ebc565b5050808061101590612e06565b915050610e81565b50818452505050919050565b6000611033611135565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9050919050565b61109861124e565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146110fc576040517f2f7a8ee100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611105816115a8565b50565b6000807ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d890508091505090565b6000807f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b60006111996115b4565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036111da576111d76114bc565b90505b90565b60006111e7611108565b6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6000611258611162565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061128b611135565b905060008160010160009054906101000a900461ffff1661ffff16905060008190506000806007831611156112d757836002016000600384901c81526020019081526020016000205490505b60005b875181101561141b5760008882815181106112f8576112f7612e4e565b5b6020026020010151905060008160200151905060008260400151510361134a576040517feb6c3aeb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600281111561135e5761135d612eb3565b5b81600281111561137157611370612eb3565b5b0361138f5761138287868685611660565b809550819650505061140c565b600160028111156113a3576113a2612eb3565b5b8160028111156113b6576113b5612eb3565b5b036113ca576113c58783611912565b61140b565b6002808111156113dd576113dc612eb3565b5b8160028111156113f0576113ef612eb3565b5b0361140a5761140187868685611bc8565b80955081965050505b5b5b505080806001019150506112da565b5082821461144357818460010160006101000a81548161ffff021916908361ffff1602179055505b600060078316111561146e5780846002016000600385901c8152602001908152602001600020819055505b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516114a193929190613091565b60405180910390a16114b386866120ae565b50505050505050565b60006114c6611135565b60030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006114f961225b565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61152b33612288565b61153361225b565b60000160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055565b80611564611135565b60030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6115b181612359565b50565b60008060007f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93905080915081600001600080357fffffffff00000000000000000000000000000000000000000000000000000000167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000205460601c9250505090565b6000803073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16141580156116c357506116c1836000015173ffffffffffffffffffffffffffffffffffffffff166103ae565b155b156116fa576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8360400151518110156119025760008460400151828151811061172357611722612e4e565b5b602002602001015190506000886000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff16146117ee576040517f92474ee200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8760001b866000015160601b6bffffffffffffffffffffffff191617896000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055506000600560078a16901b905080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c19891617975060e081036118ea57878a600201600060038c901c8152602001908152602001600020819055506000801b97505b888060010199505050505080806001019150506116fd565b5084849150915094509492505050565b611935816000015173ffffffffffffffffffffffffffffffffffffffff166103ae565b61196b576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b816040015151811015611bc35760008260400151828151811061199457611993612e4e565b5b602002602001015190506000846000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002054905060008160601c9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611a64576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ac9576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611b32576040517f617557e600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846000015160601b6bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b831617866000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002081905550505050808060010191505061196e565b505050565b600080600073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff1614611c35576040517feacd242400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600386901c9050600060078716905060005b85604001515181101561209357600086604001518281518110611c6f57611c6e612e4e565b5b6020026020010151905060008a6000016000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020549050600073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611d3a576040517f6fc4b52e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168160601c73ffffffffffffffffffffffffffffffffffffffff1603611da2576040517fe983573100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000801b8903611dd6578480600190039550508a600201600086815260200190815260200160002054985060079350611de0565b8380600190039450505b6000806000600587901b8c901b9250847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614611f02578d6000016000847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020546bffffffffffffffffffffffff19166bffffffffffffffffffffffff60001b8516178e6000016000857bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001908152602001600020819055505b8d6000016000867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191681526020019081526020016000206000905560008460001c61ffff169050600381901c9250600560078216901b9150508782146120085760008e600201600084815260200190815260200160002054905081847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c827fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198216179050808f60020160008581526020019081526020016000208190555050612059565b80837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c817fffffffff0000000000000000000000000000000000000000000000000000000060001b901c198d16179b505b60008703612081578d6002016000898152602001908152602001600020600090556000801b9b505b50505050508080600101915050611c49565b5080600383901b179650868693509350505094509492505050565b60008151141515600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151461211e576040517f26df4ccd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612257573073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146121db576121a48273ffffffffffffffffffffffffffffffffffffffff166103ae565b6121da576040517ff77172ac00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60008273ffffffffffffffffffffffffffffffffffffffff16826040516122029190613112565b600060405180830381855af49150503d806000811461223d576040519150601f19603f3d011682016040523d82523d6000602084013e612242565b606091505b5050905080612255573d6000803e3d6000fd5b505b5050565b6000807f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789090508091505090565b6000612292611162565b90508173ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b61236281612365565b50565b8061236e61225b565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6040518060400160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61242b816123f6565b811461243657600080fd5b50565b60008135905061244881612422565b92915050565b600060208284031215612464576124636123ec565b5b600061247284828501612439565b91505092915050565b60008115159050919050565b6124908161247b565b82525050565b60006020820190506124ab6000830184612487565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156124eb5780820151818401526020810190506124d0565b60008484015250505050565b6000601f19601f8301169050919050565b6000612513826124b1565b61251d81856124bc565b935061252d8185602086016124cd565b612536816124f7565b840191505092915050565b6000602082019050818103600083015261255b8184612508565b905092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261258857612587612563565b5b8235905067ffffffffffffffff8111156125a5576125a4612568565b5b6020830191508360208202830111156125c1576125c061256d565b5b9250929050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006125f3826125c8565b9050919050565b612603816125e8565b811461260e57600080fd5b50565b600081359050612620816125fa565b92915050565b60008083601f84011261263c5761263b612563565b5b8235905067ffffffffffffffff81111561265957612658612568565b5b6020830191508360018202830111156126755761267461256d565b5b9250929050565b600080600080600060608688031215612698576126976123ec565b5b600086013567ffffffffffffffff8111156126b6576126b56123f1565b5b6126c288828901612572565b955095505060206126d588828901612611565b935050604086013567ffffffffffffffff8111156126f6576126f56123f1565b5b61270288828901612626565b92509250509295509295909350565b61271a816125e8565b82525050565b60006020820190506127356000830184612711565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b612770816125e8565b82525050565b60006127828383612767565b60208301905092915050565b6000602082019050919050565b60006127a68261273b565b6127b08185612746565b93506127bb83612757565b8060005b838110156127ec5781516127d38882612776565b97506127de8361278e565b9250506001810190506127bf565b5085935050505092915050565b60006020820190508181036000830152612813818461279b565b905092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61287c816123f6565b82525050565b600061288e8383612873565b60208301905092915050565b6000602082019050919050565b60006128b282612847565b6128bc8185612852565b93506128c783612863565b8060005b838110156128f85781516128df8882612882565b97506128ea8361289a565b9250506001810190506128cb565b5085935050505092915050565b600060408301600083015161291d6000860182612767565b506020830151848203602086015261293582826128a7565b9150508091505092915050565b600061294e8383612905565b905092915050565b6000602082019050919050565b600061296e8261281b565b6129788185612826565b93508360208202850161298a85612837565b8060005b858110156129c657848403895281516129a78582612942565b94506129b283612956565b925060208a0199505060018101905061298e565b50829750879550505050505092915050565b600060208201905081810360008301526129f28184612963565b905092915050565b600060208284031215612a1057612a0f6123ec565b5b6000612a1e84828501612611565b91505092915050565b600082825260208201905092915050565b6000612a4382612847565b612a4d8185612a27565b9350612a5883612863565b8060005b83811015612a89578151612a708882612882565b9750612a7b8361289a565b925050600181019050612a5c565b5085935050505092915050565b60006020820190508181036000830152612ab08184612a38565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680612aff57607f821691505b602082108103612b1257612b11612ab8565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612b50826124f7565b810181811067ffffffffffffffff82111715612b6f57612b6e612b18565b5b80604052505050565b6000612b826123e2565b9050612b8e8282612b47565b919050565b600067ffffffffffffffff821115612bae57612bad612b18565b5b602082029050602081019050919050565b600080fd5b600080fd5b60038110612bd657600080fd5b50565b600081359050612be881612bc9565b92915050565b600067ffffffffffffffff821115612c0957612c08612b18565b5b602082029050602081019050919050565b6000612c2d612c2884612bee565b612b78565b90508083825260208201905060208402830185811115612c5057612c4f61256d565b5b835b81811015612c795780612c658882612439565b845260208401935050602081019050612c52565b5050509392505050565b600082601f830112612c9857612c97612563565b5b8135612ca8848260208601612c1a565b91505092915050565b600060608284031215612cc757612cc6612bbf565b5b612cd16060612b78565b90506000612ce184828501612611565b6000830152506020612cf584828501612bd9565b602083015250604082013567ffffffffffffffff811115612d1957612d18612bc4565b5b612d2584828501612c83565b60408301525092915050565b6000612d44612d3f84612b93565b612b78565b90508083825260208201905060208402830185811115612d6757612d6661256d565b5b835b81811015612dae57803567ffffffffffffffff811115612d8c57612d8b612563565b5b808601612d998982612cb1565b85526020850194505050602081019050612d69565b5050509392505050565b6000612dc5368484612d31565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000819050919050565b6000612e1182612dfc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e4357612e42612dcd565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060ff82169050919050565b6000612e9582612e7d565b915060ff8203612ea857612ea7612dcd565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60038110612f1f57612f1e612eb3565b5b50565b6000819050612f3082612f0e565b919050565b6000612f4082612f22565b9050919050565b612f5081612f35565b82525050565b6000606083016000830151612f6e6000860182612767565b506020830151612f816020860182612f47565b5060408301518482036040860152612f9982826128a7565b9150508091505092915050565b6000612fb28383612f56565b905092915050565b6000602082019050919050565b6000612fd282612ee2565b612fdc8185612eed565b935083602082028501612fee85612efe565b8060005b8581101561302a578484038952815161300b8582612fa6565b945061301683612fba565b925060208a01995050600181019050612ff2565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b60006130638261303c565b61306d8185613047565b935061307d8185602086016124cd565b613086816124f7565b840191505092915050565b600060608201905081810360008301526130ab8186612fc7565b90506130ba6020830185612711565b81810360408301526130cc8184613058565b9050949350505050565b600081905092915050565b60006130ec8261303c565b6130f681856130d6565b93506131068185602086016124cd565b80840191505092915050565b600061311e82846130e1565b91508190509291505056fea26469706673582212208c4451da782c4e3c6c52575917e8a4cefed2ccd8b32cad357fc8284f795c308264736f6c63430008110033

[ 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.