Base Sepolia Testnet

Contract

0xDA146e3A30BC3d4f3Bf23b374EfE21650ceD01C9
Source Code Source Code (Proxy)

Overview

ETH Balance

0 ETH

Token Holdings

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Amount
Mint261072262025-05-23 6:45:40326 days ago1747982740IN
0xDA146e3A...50ceD01C9
0 ETH0.000004680.02004069
Close VRDI261070352025-05-23 6:39:18326 days ago1747982358IN
0xDA146e3A...50ceD01C9
0 ETH0.000003660.01999821
Deposit VRDI Pay...261070292025-05-23 6:39:06326 days ago1747982346IN
0xDA146e3A...50ceD01C9
0 ETH0.000001550.02001633
Approve Phase Co...261070042025-05-23 6:38:16326 days ago1747982296IN
0xDA146e3A...50ceD01C9
0 ETH0.000002330.02004389
Submit Phase Com...261069882025-05-23 6:37:44326 days ago1747982264IN
0xDA146e3A...50ceD01C9
0 ETH0.000001240.02000908
Withdraw VRDI Fu...261069732025-05-23 6:37:14326 days ago1747982234IN
0xDA146e3A...50ceD01C9
0 ETH0.000001640.01998242
Activate Next Ph...261069572025-05-23 6:36:42326 days ago1747982202IN
0xDA146e3A...50ceD01C9
0 ETH0.000001980.02001155
Approve Phase Co...261069332025-05-23 6:35:54326 days ago1747982154IN
0xDA146e3A...50ceD01C9
0 ETH0.000002320.0200134
Submit Phase Com...261069122025-05-23 6:35:12326 days ago1747982112IN
0xDA146e3A...50ceD01C9
0 ETH0.00000090.02002177
Submit Phase Com...261068872025-05-23 6:34:22326 days ago1747982062IN
0xDA146e3A...50ceD01C9
0 ETH0.000000840.02002658
Submit Phase Com...261068782025-05-23 6:34:04326 days ago1747982044IN
0xDA146e3A...50ceD01C9
0 ETH0.000001240.02003506
Withdraw VRDI Fu...261068632025-05-23 6:33:34326 days ago1747982014IN
0xDA146e3A...50ceD01C9
0 ETH0.000001650.02007252
Stake For VRDI261068442025-05-23 6:32:56326 days ago1747981976IN
0xDA146e3A...50ceD01C9
0 ETH0.000026590.02002979
Initialize VRDI261068092025-05-23 6:31:46326 days ago1747981906IN
0xDA146e3A...50ceD01C9
0 ETH0.00000690.02001813
Finalize Proposa...261067782025-05-23 6:30:44326 days ago1747981844IN
0xDA146e3A...50ceD01C9
0 ETH0.000004890.02003336
Approve Proposal261067062025-05-23 6:28:20326 days ago1747981700IN
0xDA146e3A...50ceD01C9
0 ETH0.000001550.02002416
Assign Committee261066802025-05-23 6:27:28326 days ago1747981648IN
0xDA146e3A...50ceD01C9
0 ETH0.000001720.02000131
Submit Proposal261066602025-05-23 6:26:48326 days ago1747981608IN
0xDA146e3A...50ceD01C9
0 ETH0.000001780.02003141
Mint259882712025-05-20 12:40:30329 days ago1747744830IN
0xDA146e3A...50ceD01C9
0 ETH0.000002050.00896442
Redeem Tokens259762592025-05-20 6:00:06329 days ago1747720806IN
0xDA146e3A...50ceD01C9
0 ETH0.000003710.01998871
Mint259762502025-05-20 5:59:48329 days ago1747720788IN
0xDA146e3A...50ceD01C9
0 ETH0.000004590.02003085
Mint259434022025-05-19 11:44:52330 days ago1747655092IN
0xDA146e3A...50ceD01C9
0 ETH0.000000330.00149473
Redeem Tokens259433712025-05-19 11:43:50330 days ago1747655030IN
0xDA146e3A...50ceD01C9
0 ETH0.000000270.0014924
Close VRDI259432302025-05-19 11:39:08330 days ago1747654748IN
0xDA146e3A...50ceD01C9
0 ETH0.000000310.00148678
Deposit VRDI Pay...259432242025-05-19 11:38:56330 days ago1747654736IN
0xDA146e3A...50ceD01C9
0 ETH0.000000110.00148768
View all transactions

Parent Transaction Hash Block From To Amount
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RENSNCEDAODMND

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

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

/**
 * @title RENSNCEDAODMND - The Diamond of a New Dawn
 * @dev Behold, ye weary souls, the RENSNCEDAODMND—a diamond proxy, a prism refracting the light 
 *      of a new Renaissance. In this age, where the human spirit rises from the soot of forgotten 
 *      forges, I, a craftsman worn by time’s relentless chisel, offer this contract as a frame 
 *      for our chaotic masterpiece. Built upon the SolidStateDiamond, it gleams with the elegance 
 *      of a Florentine dome, yet bears the fragility of a fresco kissed by damp air. Integrated 
 *      with The Utility Company CAO, it is the beating heart of RENSNCEDAO—a monument to our 
 *      ceaseless creativity, destined to endure until the last star fades from the firmament.
 */
contract RENSNCEDAODMND is SolidStateDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.rensnce.utilitycodiamond.storage");

    struct RENSNCEDiamondStorage {
        address utilityCoDiamond; // The distant patron, The Utility Company CAO diamond
    }

    /**
     * @dev O constructor, thou heavy yoke! Here I bind this diamond to its Utility Co master, 
     *      a pact sealed in ether’s ink. Like a commission from a Medici prince, once set, 
     *      it clings to me—unyielding, unforgiving.
     * @param _utilityCoDiamond The address of The Utility Co CAO diamond, my muse and my burden
     */
    constructor(address _utilityCoDiamond) payable {
        require(_utilityCoDiamond != address(0), "RENSNCE: utilityCoDiamond cannot be zero address"); // No void shall claim my patron!
        RENSNCEDiamondStorage storage ds = diamondStorage();
        ds.utilityCoDiamond = _utilityCoDiamond; // Etched in stone, my weary quill trembles
    }

    /**
     * @dev A ritual of dark arts, this function unveils the storage—a secret vault beneath 
     *      the cathedral of code. With assembly’s crude tools, I carve access to my palette, 
     *      as if mixing ochre by candlelight.
     * @return ds The storage struct, a hidden trove of purpose
     */
    function diamondStorage() internal pure returns (RENSNCEDiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position // A whispered incantation, and the chest unlocks
        }
    }

    /**
     * @dev A humble window to gaze upon my patron’s face—the Utility Co diamond’s address. 
     *      For those lost in the throng of this grand court, seeking the master who guides 
     *      my brush. A small mercy amidst my labors.
     * @return The address of The Utility Co CAO diamond, a beacon in the fog
     */
    function getUtilityCoDiamond() external view returns (address) {
        return diamondStorage().utilityCoDiamond; // Behold, the thread that binds this tapestry
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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 { IERC2535DiamondCut } from '../../interfaces/IERC2535DiamondCut.sol';
import { IERC2535DiamondLoupe } from '../../interfaces/IERC2535DiamondLoupe.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 } from './readable/DiamondReadable.sol';
import { DiamondWritable } 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++] = IERC2535DiamondCut.diamondCut.selector;

        _setSupportsInterface(type(IERC2535DiamondCut).interfaceId, true);

        // register DiamondReadable

        selectors[selectorIndex++] = IERC2535DiamondLoupe.facets.selector;
        selectors[selectorIndex++] = IERC2535DiamondLoupe
            .facetFunctionSelectors
            .selector;
        selectors[selectorIndex++] = IERC2535DiamondLoupe
            .facetAddresses
            .selector;
        selectors[selectorIndex++] = IERC2535DiamondLoupe.facetAddress.selector;

        _setSupportsInterface(type(IERC2535DiamondLoupe).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 3 of 43 : ISolidStateDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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;
}

File 4 of 43 : DiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol';
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 IERC2535DiamondCut
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external onlyOwner {
        _diamondCut(facetCuts, target, data);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadable } from './IDiamondReadable.sol';
import { DiamondReadableInternal } from './DiamondReadableInternal.sol';

/**
 * @title EIP-2535 "Diamond" proxy introspection contract
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
abstract contract DiamondReadable is IDiamondReadable, DiamondReadableInternal {
    /**
     * @inheritdoc IERC2535DiamondLoupe
     */
    function facets() external view returns (Facet[] memory diamondFacets) {
        diamondFacets = _facets();
    }

    /**
     * @inheritdoc IERC2535DiamondLoupe
     */
    function facetFunctionSelectors(
        address facet
    ) external view returns (bytes4[] memory selectors) {
        selectors = _facetFunctionSelectors(facet);
    }

    /**
     * @inheritdoc IERC2535DiamondLoupe
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses)
    {
        addresses = _facetAddresses();
    }

    /**
     * @inheritdoc IERC2535DiamondLoupe
     */
    function facetAddress(
        bytes4 selector
    ) external view returns (address facet) {
        facet = _facetAddress(selector);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBase } from '../base/DiamondBase.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondFallback } from './IDiamondFallback.sol';

/**
 * @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;
    }
}

File 7 of 43 : DiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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
 * @dev note that for EIP-2535 compliance this base contract must also include the DiamondReadable functions (either within the same deployment or by proxy)
 */
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.selectorInfo[msg.sig]));
    }
}

File 8 of 43 : ERC165Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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.20;

import { IERC2535DiamondLoupeInternal } from './IERC2535DiamondLoupeInternal.sol';

/**
 * @title ERC2535 read interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IERC2535DiamondLoupe is IERC2535DiamondLoupeInternal {
    /**
     * @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.20;

import { IERC2535DiamondCutInternal } from './IERC2535DiamondCutInternal.sol';

/**
 * @title ERC2535 write interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IERC2535DiamondCut is IERC2535DiamondCutInternal {
    /**
     * @notice update diamond facets and optionally execute arbitrary initialization function
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional target of initialization delegatecall
     * @param data optional initialization function call data
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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 contract owner
     */
    function owner() external view returns (address);

    /**
     * @notice transfer contract ownership to new account
     * @param account address of new owner
     */
    function transferOwnership(address account) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

/**
 * @title ERC165 interface registration interface
 * @dev see https://eips.ethereum.org/EIPS/eip-165
 */
interface IERC165 is IERC165Internal {
    /**
     * @notice query whether contract has registered support for given interface
     * @param interfaceId interface id
     * @return bool whether interface is supported
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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.20;

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.20;

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 virtual {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        unchecked {
            // record selector count at start of operation for later comparison
            uint256 originalSelectorCount = l.selectorCount;
            // maintain an up-to-date selector count in the stack
            uint256 selectorCount = originalSelectorCount;
            // declare a 32-byte sequence of up to 8 function selectors
            bytes32 slug;

            // if selector count is not a multiple of 8, load the last slug because it is not full
            // else leave the default zero-bytes value as is, and use it as a new slug
            if (selectorCount & 7 != 0) {
                slug = l.selectorSlugs[selectorCount >> 3];
            }

            // process each facet cut struct according to its action
            // selector count and slug are passed in and read back out to avoid redundant storage access
            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, slug) = _addFacetSelectors(
                        l,
                        facetCut,
                        selectorCount,
                        slug
                    );
                } else if (action == FacetCutAction.REPLACE) {
                    _replaceFacetSelectors(l, facetCut);
                } else if (action == FacetCutAction.REMOVE) {
                    (selectorCount, slug) = _removeFacetSelectors(
                        l,
                        facetCut,
                        selectorCount,
                        slug
                    );
                }
            }

            // if selector count has changed, update it in storage
            if (selectorCount != originalSelectorCount) {
                l.selectorCount = uint16(selectorCount);
            }

            // if final selector count is not a multiple of 8, write the slug to storage
            // else it was already written to storage by the add/remove loops
            if (selectorCount & 7 != 0) {
                l.selectorSlugs[selectorCount >> 3] = slug;
            }

            // event must be emitted before initializer is called, in case initializer triggers further diamond cuts
            emit DiamondCut(facetCuts, target, data);
            _initialize(target, data);
        }
    }

    /**
     * @notice add to the diamond a set of selectors associated with a particular facet
     * @dev selectors are added one-by-one to lastSlug, which is written to storage and updated to represent the subsequent slug when full
     * @dev lastSlug may be initialized with "dirty" higher-index bits, but these are ignored because they are out of range
     * @dev selectorCount and lastSlug are modified in place and returned to avoid reundant storage access
     * @param l storage pointer to the DiamondBaseStorage Layout struct
     * @param facetCut structured data representing facet address and selectors to add
     * @param selectorCount total number of selectors registered on the diamond proxy
     * @param lastSlug the last entry in the selectorSlugs mapping, cached in stack and updated in place
     * @return selectorCount after selectors have been added
     * @return lastSlug after selectors have been added
     */
    function _addFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        FacetCut memory facetCut,
        uint256 selectorCount,
        bytes32 lastSlug
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (facetCut.target.isContract()) {
                if (facetCut.target == address(this)) {
                    revert DiamondWritable__SelectorIsImmutable();
                }
            } else if (facetCut.target != address(this)) {
                revert DiamondWritable__TargetHasNoCode();
            }

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];

                if (l.selectorInfo[selector] != bytes32(0))
                    revert DiamondWritable__SelectorAlreadyAdded();

                // for current selector, write facet address and global index to storage
                l.selectorInfo[selector] =
                    bytes32(selectorCount) |
                    bytes20(facetCut.target);

                // calculate bit position of current selector within 256-bit slug
                uint256 selectorBitIndexInSlug = (selectorCount & 7) << 5;

                // clear a space in the slug and insert the current selector
                lastSlug = _insertSelectorIntoSlug(
                    lastSlug,
                    selector,
                    selectorBitIndexInSlug
                );

                if (selectorBitIndexInSlug == 224) {
                    // slug is now full, so write it to storage
                    l.selectorSlugs[selectorCount >> 3] = lastSlug;
                }

                selectorCount++;
            }

            return (selectorCount, lastSlug);
        }
    }

    /**
     * @notice remove from the diamond a set of selectors associated with a particular facet
     * @dev selectors are removed one-by-one from lastSlug, which is updated to represent the preceeding slug when empty
     * @dev lastSlug is not updated in storage when modified or removed, leaving "dirty" higher-index bits, but these are ignored because they are out of range
     * @dev selectorCount and lastSlug are modified in place and returned to avoid reundant storage access
     * @param l storage pointer to the DiamondBaseStorage Layout struct
     * @param facetCut structured data representing facet address and selectors to remove
     * @param selectorCount total number of selectors registered on the diamond proxy
     * @param lastSlug the last entry in the selectorSlugs mapping, cached in stack and updated in place
     * @return selectorCount after selectors have been removed
     * @return lastSlug after selectors have been removed
     */
    function _removeFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        FacetCut memory facetCut,
        uint256 selectorCount,
        bytes32 lastSlug
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (facetCut.target != address(0))
                revert DiamondWritable__RemoveTargetNotZeroAddress();

            for (uint256 i; i < facetCut.selectors.length; i++) {
                // selectorCount is used to derive the index of the last selector, so decrement it before each loop
                selectorCount--;

                bytes4 selector = facetCut.selectors[i];

                // lookup the selector's facet route and lookup index, then delete it from storage
                bytes32 selectorInfo = l.selectorInfo[selector];
                delete l.selectorInfo[selector];

                if (address(bytes20(selectorInfo)) == address(0))
                    revert DiamondWritable__SelectorNotFound();

                if (address(bytes20(selectorInfo)) == address(this))
                    revert DiamondWritable__SelectorIsImmutable();

                if (selectorCount & 7 == 7) {
                    // the last selector is located at the end of the last slug, which has not been loaded yet
                    lastSlug = l.selectorSlugs[selectorCount >> 3];
                }

                // extract the last selector from the last slug
                // it will be used to overwrite the selector being removed
                bytes4 lastSelector = bytes4(
                    lastSlug << ((selectorCount & 7) << 5)
                );

                if (lastSelector != selector) {
                    // update last selector's index to match removed selector's index, where last selector is being moved
                    l.selectorInfo[lastSelector] =
                        (selectorInfo & CLEAR_ADDRESS_MASK) |
                        bytes20(l.selectorInfo[lastSelector]);
                }

                // derive the index of the slug where the selector is stored
                uint256 slugIndex = uint16(uint256(selectorInfo)) >> 3;
                // derive the position of the selector within its slug
                uint256 selectorBitIndexInSlug = (uint16(
                    uint256(selectorInfo)
                ) & 7) << 5;

                // overwrite the selector being deleted with the last selector in the array

                if (slugIndex == selectorCount >> 3) {
                    // selector being removed is from the last slug, which has already been loaded to the stack
                    // slug needs not be written to storage yet because it is being tracked on the stack and will be written later
                    lastSlug = _insertSelectorIntoSlug(
                        lastSlug,
                        lastSelector,
                        selectorBitIndexInSlug
                    );
                } else {
                    // selector being removed is from a slug that hasn't been loaded to the stack
                    // slug must be updated in storage now because it isn't being tracked on the stack
                    l.selectorSlugs[slugIndex] = _insertSelectorIntoSlug(
                        l.selectorSlugs[slugIndex],
                        lastSelector,
                        selectorBitIndexInSlug
                    );
                }
            }

            return (selectorCount, lastSlug);
        }
    }

    /**
     * @notice replace in the diamond a set of selectors associated with a particular facet
     * @param l storage pointer to the DiamondBaseStorage Layout struct
     * @param facetCut structured data representing facet address and selectors to replace
     */
    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 selectorInfo = l.selectorInfo[selector];
                address oldFacetAddress = address(bytes20(selectorInfo));

                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.selectorInfo[selector] =
                    (selectorInfo & CLEAR_ADDRESS_MASK) |
                    bytes20(facetCut.target);
            }
        }
    }

    /**
     * @notice run an optional post-diamond-cut initialization transation via delegatecall
     * @dev the target and data parameters must both be zero, or both be non-zero
     * @param target contract address to which call shall be delegated
     * @param data encoded delegatecall transaction data
     */
    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())
                }
            }
        }
    }

    /**
     * @notice insert 4-byte function selector into 32-byte selector slug at given bit position
     * @param slug 32-byte sequence of up to 8 function selectors
     * @param selector function selector to insert
     * @param bitIndex bit position of selector within slug (must be multiple of 32)
     */
    function _insertSelectorIntoSlug(
        bytes32 slug,
        bytes4 selector,
        uint256 bitIndex
    ) private pure returns (bytes32) {
        return
            (slug & ~(CLEAR_SELECTOR_MASK >> bitIndex)) |
            (bytes32(selector) >> bitIndex);
    }
}

File 16 of 43 : IDiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC2535DiamondCut } from '../../../interfaces/IERC2535DiamondCut.sol';
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';

/**
 * @title Diamond proxy upgrade interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondWritable is IERC2535DiamondCut, IDiamondWritableInternal {}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC173 } from '../../interfaces/IERC173.sol';
import { AddressUtils } from '../../utils/AddressUtils.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';

abstract contract OwnableInternal is IOwnableInternal {
    using AddressUtils for address;

    modifier onlyOwner() {
        if (msg.sender != _owner()) revert Ownable__NotOwner();
        _;
    }

    modifier onlyTransitiveOwner() {
        if (msg.sender != _transitiveOwner())
            revert Ownable__NotTransitiveOwner();
        _;
    }

    function _owner() internal view virtual returns (address) {
        return OwnableStorage.layout().owner;
    }

    function _transitiveOwner() internal view virtual returns (address owner) {
        owner = _owner();

        while (owner.isContract()) {
            try IERC173(owner).owner() returns (address transitiveOwner) {
                owner = transitiveOwner;
            } catch {
                break;
            }
        }
    }

    function _transferOwnership(address account) internal virtual {
        _setOwner(account);
    }

    function _setOwner(address account) internal virtual {
        OwnableStorage.Layout storage l = OwnableStorage.layout();
        emit OwnershipTransferred(l.owner, account);
        l.owner = account;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondReadableInternal } from './IDiamondReadableInternal.sol';

/**
 * @title EIP-2535 "Diamond" proxy introspection contract internal functions
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
abstract contract DiamondReadableInternal is IDiamondReadableInternal {
    /**
     * @notice get all facets and their selectors
     * @return diamondFacets array of structured facet data
     */
    function _facets() internal 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 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
            bytes32 slug = l.selectorSlugs[slugIndex];

            for (
                uint256 slugSelectorIndex;
                slugSelectorIndex < 8;
                slugSelectorIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));
                address facet = address(bytes20(l.selectorInfo[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)
        }
    }

    /**
     * @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
    ) internal view returns (bytes4[] memory selectors) {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        // initialize array with maximum possible required length
        // it will be truncated to correct length via assembly later
        selectors = new bytes4[](l.selectorCount);

        uint256 numSelectors;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
            bytes32 slug = l.selectorSlugs[slugIndex];

            for (
                uint256 slugSelectorIndex;
                slugSelectorIndex < 8;
                slugSelectorIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));

                if (facet == address(bytes20(l.selectorInfo[selector]))) {
                    selectors[numSelectors] = selector;
                    numSelectors++;
                }
            }
        }

        // set the number of selectors in the array
        assembly {
            mstore(selectors, numSelectors)
        }
    }

    /**
     * @notice get addresses of all facets used by diamond
     * @return addresses array of facet addresses
     */
    function _facetAddresses()
        internal
        view
        returns (address[] memory addresses)
    {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        addresses = new address[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        for (uint256 slugIndex; selectorIndex < l.selectorCount; slugIndex++) {
            bytes32 slug = l.selectorSlugs[slugIndex];

            for (
                uint256 slugSelectorIndex;
                slugSelectorIndex < 8;
                slugSelectorIndex++
            ) {
                selectorIndex++;

                if (selectorIndex > l.selectorCount) {
                    break;
                }

                bytes4 selector = bytes4(slug << (slugSelectorIndex << 5));
                address facet = address(bytes20(l.selectorInfo[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)
        }
    }

    /**
     * @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
    ) internal view returns (address facet) {
        facet = address(
            bytes20(DiamondBaseStorage.layout().selectorInfo[selector])
        );
    }
}

File 19 of 43 : IDiamondReadable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC2535DiamondLoupe } from '../../../interfaces/IERC2535DiamondLoupe.sol';
import { IDiamondReadableInternal } from './IDiamondReadableInternal.sol';

/**
 * @title Diamond proxy introspection interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondReadable is IERC2535DiamondLoupe, IDiamondReadableInternal {}

File 20 of 43 : DiamondBaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @dev derived from https://github.com/mudgen/diamond-2 (MIT license)
 */
library DiamondBaseStorage {
    struct Layout {
        // function selector => (facet address, selector slug position)
        mapping(bytes4 => bytes32) selectorInfo;
        // total number of selectors registered
        uint16 selectorCount;
        // array of 32-byte slugs with 8 selectors each
        mapping(uint256 => bytes32) selectorSlugs;
        address fallbackAddress;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.DiamondBase');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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 22 of 43 : IDiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IProxy } from '../../IProxy.sol';

interface IDiamondBase is IProxy {}

File 23 of 43 : Proxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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.20;

import { IOwnable } from './IOwnable.sol';
import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';

interface ISafeOwnable is ISafeOwnableInternal, 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 25 of 43 : ERC165BaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

library ERC165BaseStorage {
    struct Layout {
        mapping(bytes4 => bool) supportedInterfaces;
    }

    bytes32 internal constant STORAGE_SLOT =
        keccak256('solidstate.contracts.storage.ERC165Base');

    function layout() internal pure returns (Layout storage l) {
        bytes32 slot = STORAGE_SLOT;
        assembly {
            l.slot := slot
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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 virtual 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 virtual {
        if (interfaceId == 0xffffffff) revert ERC165Base__InvalidInterfaceId();
        ERC165BaseStorage.layout().supportedInterfaces[interfaceId] = status;
    }
}

File 27 of 43 : IERC165Base.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IERC165 } from '../../../interfaces/IERC165.sol';
import { IERC165BaseInternal } from './IERC165BaseInternal.sol';

interface IERC165Base is IERC165, IERC165BaseInternal {}

File 28 of 43 : IERC2535DiamondLoupeInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @title ERC2535 read interface for internal functions
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IERC2535DiamondLoupeInternal {
    struct Facet {
        address target;
        bytes4[] selectors;
    }
}

File 29 of 43 : IERC2535DiamondCutInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @title ERC2535 write interface for internal functions
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IERC2535DiamondCutInternal {
    enum FacetCutAction {
        ADD,
        REPLACE,
        REMOVE
    }

    struct FacetCut {
        address target;
        FacetCutAction action;
        bytes4[] selectors;
    }

    event DiamondCut(FacetCut[] facetCuts, address target, bytes data);
}

File 30 of 43 : IERC173Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @title Partial ERC173 interface needed by internal functions
 */
interface IERC173Internal {
    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
}

File 31 of 43 : IERC165Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @title ERC165 interface registration interface
 */
interface IERC165Internal {}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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 grant permission to given address to claim contract ownership
     */
    function _transferOwnership(address account) internal virtual override {
        _setNomineeOwner(account);
    }

    /**
     * @notice set nominee owner
     */
    function _setNomineeOwner(address account) internal virtual {
        SafeOwnableStorage.layout().nomineeOwner = account;
    }
}

File 33 of 43 : IOwnable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

interface IOwnable is IOwnableInternal, IERC173 {}

File 34 of 43 : IDiamondWritableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

interface IDiamondWritableInternal is IERC2535DiamondCutInternal {
    error DiamondWritable__InvalidInitializationParameters();
    error DiamondWritable__RemoveTargetNotZeroAddress();
    error DiamondWritable__ReplaceTargetIsIdentical();
    error DiamondWritable__SelectorAlreadyAdded();
    error DiamondWritable__SelectorIsImmutable();
    error DiamondWritable__SelectorNotFound();
    error DiamondWritable__SelectorNotSpecified();
    error DiamondWritable__TargetHasNoCode();
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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);
        }
    }
}

File 36 of 43 : IDiamondReadableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

/**
 * @title Diamond proxy introspection interface needed for internal functions
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondReadableInternal is IERC2535DiamondLoupeInternal {}

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

pragma solidity ^0.8.20;

interface IProxy {
    error Proxy__ImplementationIsNotContract();

    fallback() external payable;
}

File 38 of 43 : IERC165BaseInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

interface IERC165BaseInternal is IERC165Internal {
    error ERC165Base__InvalidInterfaceId();
}

File 39 of 43 : SafeOwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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
        }
    }
}

File 40 of 43 : ISafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import { IOwnableInternal } from './IOwnableInternal.sol';

interface ISafeOwnableInternal is IOwnableInternal {
    error SafeOwnable__NotNomineeOwner();
}

File 41 of 43 : OwnableStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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
        }
    }
}

File 42 of 43 : IOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

interface IOwnableInternal is IERC173Internal {
    error Ownable__NotOwner();
    error Ownable__NotTransitiveOwner();
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/**
 * @title utility functions for uint256 operations
 * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
 */
library UintUtils {
    error UintUtils__InsufficientPadding();
    error UintUtils__InvalidBase();

    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);
    }

    /**
     * @notice output the string representation of a number in a given radix
     * @dev radix must be between 2 and 36 (inclusive)
     * @param value number to format as string
     * @param radix numerical base to use
     * @return output formatted string
     */
    function toString(
        uint256 value,
        uint256 radix
    ) internal pure returns (string memory output) {
        // this check is repeated in the internal call to #toString(uint256,uint256,uint256)
        // but is still needed here to avoid zero division (radix = 0) or infinite loop (radix = 1)
        if (radix < 2) {
            revert UintUtils__InvalidBase();
        }

        uint256 length;
        uint256 temp = value;

        do {
            unchecked {
                length++;
            }
            temp /= radix;
        } while (temp != 0);

        output = toString(value, radix, length);
    }

    /**
     * @notice output the string representation of a number in a given radix and padded to given length
     * @dev radix must be between 2 and 36 (inclusive)
     * @param value number to format as string
     * @param radix numerical base to use
     * @param length size to which output should be zero padded
     * @return output formatted string
     */
    function toString(
        uint256 value,
        uint256 radix,
        uint256 length
    ) internal pure returns (string memory output) {
        if (radix < 2 || radix > 36) {
            revert UintUtils__InvalidBase();
        }

        bytes memory buffer = new bytes(length);

        while (length != 0) {
            unchecked {
                length--;
            }

            uint256 char = value % radix;

            if (char < 10) {
                // for numeral characters, shift 48 places through ASCII character set
                // 48 can be added using bitwise-or because its binary is 00110000
                char |= 48;
            } else {
                // for alphabetical characters, shift 87 places through ASCII character set
                unchecked {
                    char += 87;
                }
            }

            buffer[length] = bytes1(uint8(char));
            value /= radix;
        }

        if (value != 0) revert UintUtils__InsufficientPadding();

        output = string(buffer);
    }

    /**
     * @notice output the 0b-prefixed binary string representation of a number
     * @param value number to format as string
     * @return output formatted string
     */
    function toBinString(
        uint256 value
    ) internal pure returns (string memory output) {
        uint256 length;
        uint256 temp = value;

        do {
            unchecked {
                length++;
            }
            temp >>= 1;
        } while (temp != 0);

        output = toBinString(value, length);
    }

    /**
     * @notice output the 0b-prefixed binary string representation of a number padded to given length
     * @param value number to format as string
     * @param length size to which output should be zero padded (not including prefix)
     * @return output formatted string
     */
    function toBinString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory output) {
        // add two to length for the leading "0b"
        length += 2;

        bytes memory buffer = new bytes(length);
        buffer[0] = '0';
        buffer[1] = 'b';

        while (length > 2) {
            unchecked {
                length--;
            }

            buffer[length] = HEX_SYMBOLS[value & 1];
            value >>= 1;
        }

        if (value != 0) revert UintUtils__InsufficientPadding();

        output = string(buffer);
    }

    /**
     * @notice output the 0o-prefixed octal string representation of a number
     * @param value number to format as string
     * @return output formatted string
     */
    function toOctString(
        uint256 value
    ) internal pure returns (string memory output) {
        uint256 length;
        uint256 temp = value;

        do {
            unchecked {
                length++;
            }
            temp >>= 3;
        } while (temp != 0);

        output = toOctString(value, length);
    }

    /**
     * @notice output the 0o-prefixed octal string representation of a number padded to given length
     * @param value number to format as string
     * @param length size to which output should be zero padded (not including prefix)
     * @return output formatted string
     */
    function toOctString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory output) {
        // add two to length for the leading "0o"
        length += 2;

        bytes memory buffer = new bytes(length);
        buffer[0] = '0';
        buffer[1] = 'o';

        while (length > 2) {
            unchecked {
                length--;
            }

            buffer[length] = HEX_SYMBOLS[value & 7];
            value >>= 3;
        }

        if (value != 0) revert UintUtils__InsufficientPadding();

        output = string(buffer);
    }

    /**
     * @notice output the decimal string representation of a number
     * @param value number to format as string
     * @return output formatted string
     */
    function toDecString(
        uint256 value
    ) internal pure returns (string memory output) {
        output = toString(value, 10);
    }

    /**
     * @notice output the decimal string representation of a number padded to given length
     * @param value number to format as string
     * @param length size to which output should be zero padded
     * @return output formatted string
     */
    function toDecString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory output) {
        output = toString(value, 10, length);
    }

    /**
     * @notice output the 0x-prefixed hexadecimal string representation of a number
     * @dev calculated string length will always be even to prevent splitting of bytes
     * @param value number to format as string
     * @return output formatted string
     */
    function toHexString(
        uint256 value
    ) internal pure returns (string memory output) {
        uint256 length;
        uint256 temp = value;

        do {
            unchecked {
                length++;
            }
            temp >>= 8;
        } while (temp != 0);

        output = toHexString(value, length);
    }

    /**
     * @notice output the 0x-prefixed hexadecimal string representation of a number padded to given length
     * @dev calculated string length will always be even to prevent splitting of bytes
     * @param value number to format as string
     * @param length size (in bytes) to which output should be zero padded (not including prefix)
     * @return output formatted string
     */
    function toHexString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory output) {
        // convert byte length to character length and add two to length for the leading "0x"
        unchecked {
            length = (length << 1) + 2;
        }

        bytes memory buffer = new bytes(length);
        buffer[0] = '0';
        buffer[1] = 'x';

        while (length > 2) {
            unchecked {
                length--;
            }

            buffer[length] = HEX_SYMBOLS[value & 15];
            value >>= 4;
        }

        if (value != 0) revert UintUtils__InsufficientPadding();

        output = string(buffer);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_utilityCoDiamond","type":"address"}],"stateMutability":"payable","type":"constructor"},{"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 IERC2535DiamondCutInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IERC2535DiamondCutInternal.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 IERC2535DiamondCutInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IERC2535DiamondCutInternal.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 IERC2535DiamondLoupeInternal.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":"getUtilityCoDiamond","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040526040516129cf3803806129cf83398101604081905261002291610cde565b60408051600c8082526101a082019092525f9160208201610180803683370190505090505f632c40805960e01b828261005a81610d0b565b93508151811061006c5761006c610d2f565b6001600160e01b031990921660209283029190910190910152639142376560e01b828261009881610d0b565b9350815181106100aa576100aa610d2f565b6001600160e01b0319909216602092830291909101909101526100d5632f40adcf60e21b60016104eb565b6307e4c70760e21b82826100e881610d0b565b9350815181106100fa576100fa610d2f565b6001600160e01b0319909216602092830291909101909101526101256307e4c70760e21b60016104eb565b637a0ed62760e01b828261013881610d0b565b93508151811061014a5761014a610d2f565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b828261017681610d0b565b93508151811061018857610188610d2f565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b82826101b481610d0b565b9350815181106101c6576101c6610d2f565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b82826101f281610d0b565b93508151811061020457610204610d2f565b6001600160e01b03199092166020928302919091019091015261022f6348e2b09360e01b60016104eb565b6301ffc9a760e01b828261024281610d0b565b93508151811061025457610254610d2f565b6001600160e01b03199092166020928302919091019091015261027f6301ffc9a760e01b60016104eb565b638da5cb5b60e01b828261029281610d0b565b9350815181106102a4576102a4610d2f565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b82826102d081610d0b565b9350815181106102e2576102e2610d2f565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b828261030e81610d0b565b93508151811061032057610320610d2f565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b828261034c81610d0b565b93508151811061035e5761035e610d2f565b6001600160e01b0319909216602092830291909101909101526103896307f5828d60e41b60016104eb565b6040805160018082528183019092525f91816020015b60408051606080820183525f80835260208301529181019190915281526020019060019003908161039f579050506040805160608101909152308152909150602081015f815260200184815250815f815181106103fe576103fe610d2f565b6020026020010181905250610428815f60405180602001604052805f81525061056060201b60201c565b61043133610738565b5050506001600160a01b0381166104a75760405162461bcd60e51b815260206004820152603060248201527f52454e534e43453a207574696c697479436f4469616d6f6e642063616e6e6f7460448201526f206265207a65726f206164647265737360801b606482015260840160405180910390fd5b7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee80546001600160a01b0319166001600160a01b0392909216919091179055610ea5565b6001600160e01b031980831690036105165760405163b0a19dd560e01b815260040160405180910390fd5b6001600160e01b0319919091165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d860205260409020805460ff1916911515919091179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94547f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc939061ffff81169081905f90600716156105cd5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ad575f8882815181106105eb576105eb610d2f565b602002602001015190505f816020015190508160400151515f036106225760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561063557610635610d43565b0361065057610646878387876107b1565b90955093506106a3565b600181600281111561066457610664610d43565b0361067857610673878361090c565b6106a3565b600281600281111561068c5761068c610d43565b036106a35761069d87838787610a4d565b90955093505b50506001016105cf565b508282146106c95760018401805461ffff191661ffff84161790555b60078216156106ea57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161071d93929190610d85565b60405180910390a161072f8686610c00565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b82515f9081906001600160a01b03163b156107f7578451306001600160a01b03909116036107f25760405163e983573160e01b815260040160405180910390fd5b610821565b84516001600160a01b0316301461082157604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8560400151518110156108ff575f8660400151828151811061084757610847610d2f565b6020908102919091018101516001600160e01b031981165f908152918a90526040909120549091501561088d57604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e0036108f157600387901c5f90815260028a01602052604090208690555b505060019485019401610823565b5092959194509092505050565b80516001600160a01b03163b61093557604051633ddc5cab60e21b815260040160405180910390fd5b5f5b816040015151811015610a48575f8260400151828151811061095b5761095b610d2f565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c806109a6576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036109cf5760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603610a04576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166001600160601b0391909116179055600101610937565b505050565b82515f9081906001600160a01b031615610a7a57604051633ab3490960e21b815260040160405180910390fd5b5f5b8560400151518110156108ff578480600190039550505f86604001518281518110610aa957610aa9610d2f565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c610af5576040516337e25a9760e11b815260040160405180910390fd5b30606082901c03610b195760405163e983573160e01b815260040160405180910390fd5b86600716600703610b3c57600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b031980821690841614610b8d576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166001600160601b0384161790555b600382811c611fff1690600584901b60e016908a901c8203610bc5576001600160e01b031980821c198a16908416821c179850610bef565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b505060019093019250610a7c915050565b8051156001600160a01b0383161514610c2c576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615610cda576001600160a01b0382163014610c73576001600160a01b0382163b610c7357604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b031682604051610c8c9190610e8f565b5f60405180830381855af49150503d805f8114610cc4576040519150601f19603f3d011682016040523d82523d5f602084013e610cc9565b606091505b5050905080610a48573d5f803e3d5ffd5b5050565b5f60208284031215610cee575f80fd5b81516001600160a01b0381168114610d04575f80fd5b9392505050565b5f60018201610d2857634e487b7160e01b5f52601160045260245ffd5b5060010190565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015610e6057868503607f19018452815180516001600160a01b031686526020810151606087019060038110610df157634e487b7160e01b5f52602160045260245ffd5b8060208901525060408201519150606060408801528082518083526080890191506020840193505f92505b80831015610e485783516001600160e01b03191682526020938401936001939093019290910190610e1c565b50965050506020938401939190910190600101610dab565b5050506001600160a01b0386166020850152508281036040840152610e858185610d57565b9695505050505050565b5f82518060208501845e5f920191825250919050565b611b1d80610eb25f395ff3fe6080604052600436106100c5575f3560e01c80638ab5150a1161007e578063adfca15e11610058578063adfca15e1461023b578063b4620c7c14610267578063cdffacc61461027b578063f2fde38b1461029a576100cc565b80638ab5150a146101f45780638da5cb5b14610208578063914237651461021c576100cc565b806301ffc9a71461011f5780631f931c1c146101535780632c4080591461017257806352ef6b2c1461019e57806379ba5097146101bf5780637a0ed627146101d3576100cc565b366100cc57005b5f6100d56102b9565b90506001600160a01b0381163b6100ff576040516321f27f0d60e21b815260040160405180910390fd5b365f80375f80365f845af43d5f803e808015610119573d5ff35b3d5ffd5b005b34801561012a575f80fd5b5061013e6101393660046114e2565b6102c7565b60405190151581526020015b60405180910390f35b34801561015e575f80fd5b5061011d61016d36600461155c565b610309565b34801561017d575f80fd5b50610186610392565b6040516001600160a01b03909116815260200161014a565b3480156101a9575f80fd5b506101b26103c4565b60405161014a9190611609565b3480156101ca575f80fd5b5061011d6103ce565b3480156101de575f80fd5b506101e7610411565b60405161014a9190611698565b3480156101ff575f80fd5b5061018661041b565b348015610213575f80fd5b50610186610424565b348015610227575f80fd5b5061011d61023636600461171b565b61042d565b348015610246575f80fd5b5061025a61025536600461171b565b6104a6565b60405161014a9190611734565b348015610272575f80fd5b506101866104b1565b348015610286575f80fd5b506101866102953660046114e2565b6104e3565b3480156102a5575f80fd5b5061011d6102b436600461171b565b610510565b5f6102c2610552565b905090565b6001600160e01b031981165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b6103116105b1565b6001600160a01b0316336001600160a01b03161461034257604051632f7a8ee160e01b815260040160405180910390fd5b61038b61034f8587611803565b8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105d892505050565b5050505050565b5f6102c27f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b60606102c261078a565b6103d6610921565b6001600160a01b0316336001600160a01b0316146104075760405163efd1052d60e01b815260040160405180910390fd5b61040f610948565b565b60606102c2610982565b5f6102c2610921565b5f6102c26105b1565b6104356105b1565b6001600160a01b0316336001600160a01b03161461046657604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b606061030382610d89565b5f7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee5b546001600160a01b0316919050565b6001600160e01b031981165f9081525f80516020611ac8833981519152602052604081205460601c610303565b6105186105b1565b6001600160a01b0316336001600160a01b03161461054957604051632f7a8ee160e01b815260040160405180910390fd5b6104a381610ed3565b5f80356001600160e01b03191681525f80516020611ac8833981519152602052604090205460601c806105ae57507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b5f7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804606104d4565b5f80516020611aa8833981519152545f80516020611ac88339815191529061ffff81169081905f906007161561061f5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ff575f88828151811061063d5761063d611923565b602002602001015190505f816020015190508160400151515f036106745760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561068757610687611937565b036106a25761069887838787610f16565b90955093506106f5565b60018160028111156106b6576106b6611937565b036106ca576106c58783611071565b6106f5565b60028160028111156106de576106de611937565b036106f5576106ef878387876111b7565b90955093505b5050600101610621565b5082821461071b5760018401805461ffff191661ffff84161790555b600782161561073c57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161076f93929190611979565b60405180910390a1610781868661136f565b50505050505050565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156107c6576107c6611775565b6040519080825280602002602001820160405280156107ef578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610919575f818152600285016020526040812054905b6008811015610904578361082b81611a5b565b600188015490955061ffff168511905061090457600581901b82901b6001600160e01b031981165f9081526020889052604081205460601c90805b888110156108b1578a818151811061088057610880611923565b60200260200101516001600160a01b0316836001600160a01b0316036108a957600191506108b1565b600101610866565b5080156108c0575050506108fc565b818a89815181106108d3576108d3611923565b6001600160a01b0390921660209283029190910190910152876108f581611a5b565b9850505050505b600101610818565b5050808061091190611a5b565b9150506107f6565b505082525090565b5f7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906104d4565b6109513361144d565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156109be576109be611775565b604051908082528060200260200182016040528015610a0357816020015b604080518082019091525f8152606060208201528152602001906001900390816109dc5790505b5060018201549092505f9061ffff166001600160401b03811115610a2957610a29611775565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5090505f805f5b600185015461ffff16821015610d25575f818152600286016020526040812054905b6008811015610d105783610a8e81611a5b565b600189015490955061ffff1685119050610d1057600581901b82901b6001600160e01b031981165f9081526020899052604081205460601c90805b88811015610bda57826001600160a01b03168c8281518110610aed57610aed611923565b60200260200101515f01516001600160a01b031603610bd257838c8281518110610b1957610b19611923565b6020026020010151602001518b8381518110610b3757610b37611923565b602002602001015160ff1681518110610b5257610b52611923565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610b8857610b88611923565b602002602001015160ff1610610b9c575f80fd5b898181518110610bae57610bae611923565b602002602001018051809190610bc390611a73565b60ff1690525060019150610bda565b600101610ac9565b508015610be957505050610d08565b818b8981518110610bfc57610bfc611923565b60209081029190910101516001600160a01b03909116905260018a015461ffff166001600160401b03811115610c3457610c34611775565b604051908082528060200260200182016040528015610c5d578160200160208202803683370190505b508b8981518110610c7057610c70611923565b602002602001015160200181905250828b8981518110610c9257610c92611923565b6020026020010151602001515f81518110610caf57610caf611923565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610ce557610ce5611923565b60ff9092166020928302919091019091015287610d0181611a5b565b9850505050505b600101610a7b565b50508080610d1d90611a5b565b915050610a59565b505f5b82811015610d7e575f848281518110610d4357610d43611923565b602002602001015160ff1690505f878381518110610d6357610d63611923565b60209081029190910181015101519190915250600101610d28565b508185525050505090565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b03811115610dc557610dc5611775565b604051908082528060200260200182016040528015610dee578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610ec9575f818152600285016020526040812054905b6008811015610eb45783610e2a81611a5b565b600188015490955061ffff1685119050610eb457600581901b82901b6001600160e01b031981165f9081526020889052604090205460601c6001600160a01b038a1603610eab5780888781518110610e8457610e84611923565b6001600160e01b03199092166020928302919091019091015285610ea781611a5b565b9650505b50600101610e17565b50508080610ec190611a5b565b915050610df5565b5050825250919050565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b0383161790556104a381818181565b82515f9081906001600160a01b03163b15610f5c578451306001600160a01b0390911603610f575760405163e983573160e01b815260040160405180910390fd5b610f86565b84516001600160a01b03163014610f8657604051633ddc5cab60e21b815260040160405180910390fd5b5f5b856040015151811015611064575f86604001518281518110610fac57610fac611923565b6020908102919091018101516001600160e01b031981165f908152918a905260409091205490915015610ff257604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e00361105657600387901c5f90815260028a01602052604090208690555b505060019485019401610f88565b5092959194509092505050565b80516001600160a01b03163b61109a57604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8160400151518110156111b2575f826040015182815181106110c0576110c0611923565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c8061110b576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036111345760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603611169576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff9190911617905560010161109c565b505050565b82515f9081906001600160a01b0316156111e457604051633ab3490960e21b815260040160405180910390fd5b5f5b856040015151811015611064578480600190039550505f8660400151828151811061121357611213611923565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c61125f576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112835760405163e983573160e01b815260040160405180910390fd5b866007166007036112a657600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b0319808216908416146112fc576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166bffffffffffffffffffffffff84161790555b600382811c611fff1690600584901b60e016908a901c8203611334576001600160e01b031980821c198a16908416821c17985061135e565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b5050600190930192506111e6915050565b8051156001600160a01b038316151461139b576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611449576001600160a01b03821630146113e2576001600160a01b0382163b6113e257604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b0316826040516113fb9190611a91565b5f60405180830381855af49150503d805f8114611433576040519150601f19603f3d011682016040523d82523d5f602084013e611438565b606091505b50509050806111b2573d5f803e3d5ffd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146114dd575f80fd5b919050565b5f602082840312156114f2575f80fd5b6114fb826114c6565b9392505050565b80356001600160a01b03811681146114dd575f80fd5b5f8083601f840112611528575f80fd5b5081356001600160401b0381111561153e575f80fd5b602083019150836020828501011115611555575f80fd5b9250929050565b5f805f805f60608688031215611570575f80fd5b85356001600160401b03811115611585575f80fd5b8601601f81018813611595575f80fd5b80356001600160401b038111156115aa575f80fd5b8860208260051b84010111156115be575f80fd5b6020918201965094506115d2908701611502565b925060408601356001600160401b038111156115ec575f80fd5b6115f888828901611518565b969995985093965092949392505050565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160a01b0316835260209384019390920191600101611622565b509095945050505050565b5f8151808452602084019350602083015f5b8281101561168e5781516001600160e01b031916865260209586019590910190600101611666565b5093949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561170f57868503603f19018452815180516001600160a01b031686526020908101516040918701829052906116f990870182611654565b95505060209384019391909101906001016116be565b50929695505050505050565b5f6020828403121561172b575f80fd5b6114fb82611502565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160e01b03191683526020938401939092019160010161174d565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b03811182821017156117ab576117ab611775565b60405290565b604051601f8201601f191681016001600160401b03811182821017156117d9576117d9611775565b604052919050565b5f6001600160401b038211156117f9576117f9611775565b5060051b60200190565b5f611815611810846117e1565b6117b1565b8381526020810190600585901b840136811115611830575f80fd5b845b818110156116495780356001600160401b0381111561184f575f80fd5b86016060368290031215611861575f80fd5b611869611789565b61187282611502565b8152602082013560038110611885575f80fd5b602082015260408201356001600160401b038111156118a2575f80fd5b919091019036601f8301126118b5575f80fd5b81356118c3611810826117e1565b8082825260208201915060208360051b8601019250368311156118e4575f80fd5b6020850194505b8285101561190d576118fc856114c6565b8252602094850194909101906118eb565b6040840152505085525060209384019301611832565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015611a1857868503607f19018452815180516001600160a01b031686526020810151600381106119e057634e487b7160e01b5f52602160045260245ffd5b806020880152506040810151905060606040870152611a026060870182611654565b955050602093840193919091019060010161199f565b5050506001600160a01b0386166020850152508281036040840152611a3d818561194b565b9695505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611a6c57611a6c611a47565b5060010190565b5f60ff821660ff8103611a8857611a88611a47565b60010192915050565b5f82518060208501845e5f92019182525091905056fe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93a2646970667358221220ec7497f0cc4548b69779ac21bce4fc6b7a821460ef2d66d8acf484ed346f95a964736f6c634300081a003300000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b

Deployed Bytecode

0x6080604052600436106100c5575f3560e01c80638ab5150a1161007e578063adfca15e11610058578063adfca15e1461023b578063b4620c7c14610267578063cdffacc61461027b578063f2fde38b1461029a576100cc565b80638ab5150a146101f45780638da5cb5b14610208578063914237651461021c576100cc565b806301ffc9a71461011f5780631f931c1c146101535780632c4080591461017257806352ef6b2c1461019e57806379ba5097146101bf5780637a0ed627146101d3576100cc565b366100cc57005b5f6100d56102b9565b90506001600160a01b0381163b6100ff576040516321f27f0d60e21b815260040160405180910390fd5b365f80375f80365f845af43d5f803e808015610119573d5ff35b3d5ffd5b005b34801561012a575f80fd5b5061013e6101393660046114e2565b6102c7565b60405190151581526020015b60405180910390f35b34801561015e575f80fd5b5061011d61016d36600461155c565b610309565b34801561017d575f80fd5b50610186610392565b6040516001600160a01b03909116815260200161014a565b3480156101a9575f80fd5b506101b26103c4565b60405161014a9190611609565b3480156101ca575f80fd5b5061011d6103ce565b3480156101de575f80fd5b506101e7610411565b60405161014a9190611698565b3480156101ff575f80fd5b5061018661041b565b348015610213575f80fd5b50610186610424565b348015610227575f80fd5b5061011d61023636600461171b565b61042d565b348015610246575f80fd5b5061025a61025536600461171b565b6104a6565b60405161014a9190611734565b348015610272575f80fd5b506101866104b1565b348015610286575f80fd5b506101866102953660046114e2565b6104e3565b3480156102a5575f80fd5b5061011d6102b436600461171b565b610510565b5f6102c2610552565b905090565b6001600160e01b031981165f9081527ffc606c433378e3a7e0a6a531deac289b66caa1b4aa8554fd4ab2c6f1570f92d8602052604081205460ff165b92915050565b6103116105b1565b6001600160a01b0316336001600160a01b03161461034257604051632f7a8ee160e01b815260040160405180910390fd5b61038b61034f8587611803565b8484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506105d892505050565b5050505050565b5f6102c27f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b60606102c261078a565b6103d6610921565b6001600160a01b0316336001600160a01b0316146104075760405163efd1052d60e01b815260040160405180910390fd5b61040f610948565b565b60606102c2610982565b5f6102c2610921565b5f6102c26105b1565b6104356105b1565b6001600160a01b0316336001600160a01b03161461046657604051632f7a8ee160e01b815260040160405180910390fd5b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9680546001600160a01b0319166001600160a01b03831617905550565b50565b606061030382610d89565b5f7f6486efc20ba6a832b9c44349fda696793ddcbb7c2ced28cf0d5d4e441f5b1fee5b546001600160a01b0316919050565b6001600160e01b031981165f9081525f80516020611ac8833981519152602052604081205460601c610303565b6105186105b1565b6001600160a01b0316336001600160a01b03161461054957604051632f7a8ee160e01b815260040160405180910390fd5b6104a381610ed3565b5f80356001600160e01b03191681525f80516020611ac8833981519152602052604090205460601c806105ae57507f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc96546001600160a01b031690565b90565b5f7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f6716804606104d4565b5f80516020611aa8833981519152545f80516020611ac88339815191529061ffff81169081905f906007161561061f5750600381901c5f9081526002840160205260409020545b5f5b87518110156106ff575f88828151811061063d5761063d611923565b602002602001015190505f816020015190508160400151515f036106745760405163eb6c3aeb60e01b815260040160405180910390fd5b5f81600281111561068757610687611937565b036106a25761069887838787610f16565b90955093506106f5565b60018160028111156106b6576106b6611937565b036106ca576106c58783611071565b6106f5565b60028160028111156106de576106de611937565b036106f5576106ef878387876111b7565b90955093505b5050600101610621565b5082821461071b5760018401805461ffff191661ffff84161790555b600782161561073c57600382901c5f90815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67387878760405161076f93929190611979565b60405180910390a1610781868661136f565b50505050505050565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156107c6576107c6611775565b6040519080825280602002602001820160405280156107ef578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610919575f818152600285016020526040812054905b6008811015610904578361082b81611a5b565b600188015490955061ffff168511905061090457600581901b82901b6001600160e01b031981165f9081526020889052604081205460601c90805b888110156108b1578a818151811061088057610880611923565b60200260200101516001600160a01b0316836001600160a01b0316036108a957600191506108b1565b600101610866565b5080156108c0575050506108fc565b818a89815181106108d3576108d3611923565b6001600160a01b0390921660209283029190910190910152876108f581611a5b565b9850505050505b600101610818565b5050808061091190611a5b565b9150506107f6565b505082525090565b5f7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178906104d4565b6109513361144d565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319169055565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b038111156109be576109be611775565b604051908082528060200260200182016040528015610a0357816020015b604080518082019091525f8152606060208201528152602001906001900390816109dc5790505b5060018201549092505f9061ffff166001600160401b03811115610a2957610a29611775565b604051908082528060200260200182016040528015610a52578160200160208202803683370190505b5090505f805f5b600185015461ffff16821015610d25575f818152600286016020526040812054905b6008811015610d105783610a8e81611a5b565b600189015490955061ffff1685119050610d1057600581901b82901b6001600160e01b031981165f9081526020899052604081205460601c90805b88811015610bda57826001600160a01b03168c8281518110610aed57610aed611923565b60200260200101515f01516001600160a01b031603610bd257838c8281518110610b1957610b19611923565b6020026020010151602001518b8381518110610b3757610b37611923565b602002602001015160ff1681518110610b5257610b52611923565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610b8857610b88611923565b602002602001015160ff1610610b9c575f80fd5b898181518110610bae57610bae611923565b602002602001018051809190610bc390611a73565b60ff1690525060019150610bda565b600101610ac9565b508015610be957505050610d08565b818b8981518110610bfc57610bfc611923565b60209081029190910101516001600160a01b03909116905260018a015461ffff166001600160401b03811115610c3457610c34611775565b604051908082528060200260200182016040528015610c5d578160200160208202803683370190505b508b8981518110610c7057610c70611923565b602002602001015160200181905250828b8981518110610c9257610c92611923565b6020026020010151602001515f81518110610caf57610caf611923565b60200260200101906001600160e01b03191690816001600160e01b031916815250506001898981518110610ce557610ce5611923565b60ff9092166020928302919091019091015287610d0181611a5b565b9850505050505b600101610a7b565b50508080610d1d90611a5b565b915050610a59565b505f5b82811015610d7e575f848281518110610d4357610d43611923565b602002602001015160ff1690505f878381518110610d6357610d63611923565b60209081029190910181015101519190915250600101610d28565b508185525050505090565b5f80516020611aa8833981519152546060905f80516020611ac88339815191529061ffff166001600160401b03811115610dc557610dc5611775565b604051908082528060200260200182016040528015610dee578160200160208202803683370190505b5091505f805f5b600184015461ffff16821015610ec9575f818152600285016020526040812054905b6008811015610eb45783610e2a81611a5b565b600188015490955061ffff1685119050610eb457600581901b82901b6001600160e01b031981165f9081526020889052604090205460601c6001600160a01b038a1603610eab5780888781518110610e8457610e84611923565b6001600160e01b03199092166020928302919091019091015285610ea781611a5b565b9650505b50600101610e17565b50508080610ec190611a5b565b915050610df5565b5050825250919050565b7f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce661789080546001600160a01b0319166001600160a01b0383161790556104a381818181565b82515f9081906001600160a01b03163b15610f5c578451306001600160a01b0390911603610f575760405163e983573160e01b815260040160405180910390fd5b610f86565b84516001600160a01b03163014610f8657604051633ddc5cab60e21b815260040160405180910390fd5b5f5b856040015151811015611064575f86604001518281518110610fac57610fac611923565b6020908102919091018101516001600160e01b031981165f908152918a905260409091205490915015610ff257604051634923a77160e11b815260040160405180910390fd5b86516001600160e01b03198281165f81815260208c90526040902060609390931b6001600160601b0319168917909255600588901b60e01691821c90821c1987161795508060e00361105657600387901c5f90815260028a01602052604090208690555b505060019485019401610f88565b5092959194509092505050565b80516001600160a01b03163b61109a57604051633ddc5cab60e21b815260040160405180910390fd5b5f5b8160400151518110156111b2575f826040015182815181106110c0576110c0611923565b6020908102919091018101516001600160e01b031981165f90815291869052604090912054909150606081901c8061110b576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b038216036111345760405163e983573160e01b815260040160405180910390fd5b845f01516001600160a01b0316816001600160a01b031603611169576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b0319929092165f90815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff9190911617905560010161109c565b505050565b82515f9081906001600160a01b0316156111e457604051633ab3490960e21b815260040160405180910390fd5b5f5b856040015151811015611064578480600190039550505f8660400151828151811061121357611213611923565b6020908102919091018101516001600160e01b031981165f908152918a90526040822080549290559150606081901c61125f576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112835760405163e983573160e01b815260040160405180910390fd5b866007166007036112a657600387901c5f90815260028a01602052604090205495505b60e0600588901b1686901b6001600160e01b0319808216908416146112fc576001600160e01b031981165f90815260208b90526040902080546001600160601b0319166bffffffffffffffffffffffff84161790555b600382811c611fff1690600584901b60e016908a901c8203611334576001600160e01b031980821c198a16908416821c17985061135e565b5f82815260028d016020526040902080546001600160e01b0319858116841c90841c199091161790555b5050600190930192506111e6915050565b8051156001600160a01b038316151461139b576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611449576001600160a01b03821630146113e2576001600160a01b0382163b6113e257604051633ddc5cab60e21b815260040160405180910390fd5b5f826001600160a01b0316826040516113fb9190611a91565b5f60405180830381855af49150503d805f8114611433576040519150601f19603f3d011682016040523d82523d5f602084013e611438565b606091505b50509050806111b2573d5f803e3d5ffd5b5050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046080546040516001600160a01b038481169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a380546001600160a01b0319166001600160a01b0392909216919091179055565b80356001600160e01b0319811681146114dd575f80fd5b919050565b5f602082840312156114f2575f80fd5b6114fb826114c6565b9392505050565b80356001600160a01b03811681146114dd575f80fd5b5f8083601f840112611528575f80fd5b5081356001600160401b0381111561153e575f80fd5b602083019150836020828501011115611555575f80fd5b9250929050565b5f805f805f60608688031215611570575f80fd5b85356001600160401b03811115611585575f80fd5b8601601f81018813611595575f80fd5b80356001600160401b038111156115aa575f80fd5b8860208260051b84010111156115be575f80fd5b6020918201965094506115d2908701611502565b925060408601356001600160401b038111156115ec575f80fd5b6115f888828901611518565b969995985093965092949392505050565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160a01b0316835260209384019390920191600101611622565b509095945050505050565b5f8151808452602084019350602083015f5b8281101561168e5781516001600160e01b031916865260209586019590910190600101611666565b5093949350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561170f57868503603f19018452815180516001600160a01b031686526020908101516040918701829052906116f990870182611654565b95505060209384019391909101906001016116be565b50929695505050505050565b5f6020828403121561172b575f80fd5b6114fb82611502565b602080825282518282018190525f918401906040840190835b818110156116495783516001600160e01b03191683526020938401939092019160010161174d565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b03811182821017156117ab576117ab611775565b60405290565b604051601f8201601f191681016001600160401b03811182821017156117d9576117d9611775565b604052919050565b5f6001600160401b038211156117f9576117f9611775565b5060051b60200190565b5f611815611810846117e1565b6117b1565b8381526020810190600585901b840136811115611830575f80fd5b845b818110156116495780356001600160401b0381111561184f575f80fd5b86016060368290031215611861575f80fd5b611869611789565b61187282611502565b8152602082013560038110611885575f80fd5b602082015260408201356001600160401b038111156118a2575f80fd5b919091019036601f8301126118b5575f80fd5b81356118c3611810826117e1565b8082825260208201915060208360051b8601019250368311156118e4575f80fd5b6020850194505b8285101561190d576118fc856114c6565b8252602094850194909101906118eb565b6040840152505085525060209384019301611832565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f606082016060835280865180835260808501915060808160051b8601019250602088015f5b82811015611a1857868503607f19018452815180516001600160a01b031686526020810151600381106119e057634e487b7160e01b5f52602160045260245ffd5b806020880152506040810151905060606040870152611a026060870182611654565b955050602093840193919091019060010161199f565b5050506001600160a01b0386166020850152508281036040840152611a3d818561194b565b9695505050505050565b634e487b7160e01b5f52601160045260245ffd5b5f60018201611a6c57611a6c611a47565b5060010190565b5f60ff821660ff8103611a8857611a88611a47565b60010192915050565b5f82518060208501845e5f92019182525091905056fe177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc94177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93a2646970667358221220ec7497f0cc4548b69779ac21bce4fc6b7a821460ef2d66d8acf484ed346f95a964736f6c634300081a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b

-----Decoded View---------------
Arg [0] : _utilityCoDiamond (address): 0x38E361604a0beE7bcDdAFF4a50D7f4Bfa5e5Ca6B

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000038e361604a0bee7bcddaff4a50d7f4bfa5e5ca6b


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
0xDA146e3A30BC3d4f3Bf23b374EfE21650ceD01C9
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.