ETH Price: $2,944.31 (-3.57%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

More Info

Private Name Tags

ContractCreator

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...242466012026-01-16 10:10:236 days ago1768558223IN
Scapes: SCAPE Token
0 ETH0.000002730.04224425
Set Approval For...242335222026-01-14 14:25:238 days ago1768400723IN
Scapes: SCAPE Token
0 ETH0.000144452.23399332
Make Offer242290132026-01-13 23:18:118 days ago1768346291IN
Scapes: SCAPE Token
0 ETH0.000132492.18490853
Set Approval For...242232512026-01-13 3:55:599 days ago1768276559IN
Scapes: SCAPE Token
0 ETH0.000034620.53549275
Make Offer241302372025-12-31 4:31:3522 days ago1767155495IN
Scapes: SCAPE Token
0 ETH0.000123022.02840077
Set Approval For...241273422025-12-30 18:49:1123 days ago1767120551IN
Scapes: SCAPE Token
0 ETH0.000035910.5552926
Set Approval For...241086542025-12-28 4:11:2325 days ago1766895083IN
Scapes: SCAPE Token
0 ETH0.000131212.02916534
Set Approval For...240847102025-12-24 19:56:3528 days ago1766606195IN
Scapes: SCAPE Token
0 ETH0.000131062.02687691
Safe Transfer Fr...240553502025-12-20 17:36:5933 days ago1766252219IN
Scapes: SCAPE Token
0 ETH0.000149992.0249425
Set Approval For...240265842025-12-16 17:12:3537 days ago1765905155IN
Scapes: SCAPE Token
0 ETH0.000064721.00094509
Set Approval For...240264792025-12-16 16:51:2337 days ago1765903883IN
Scapes: SCAPE Token
0 ETH0.000133842.0698095
Set Approval For...240004822025-12-13 1:42:3540 days ago1765590155IN
Scapes: SCAPE Token
0 ETH0.000023090.53993248
Set Approval For...239999852025-12-13 0:03:1140 days ago1765584191IN
Scapes: SCAPE Token
0 ETH0.000022280.52124162
Set Approval For...239961912025-12-12 11:16:1141 days ago1765538171IN
Scapes: SCAPE Token
0 ETH0.00013482.08476724
Set Approval For...239825462025-12-10 13:15:5943 days ago1765372559IN
Scapes: SCAPE Token
0 ETH0.000139582.15868646
Set Approval For...239425622025-12-04 22:16:5948 days ago1764886619IN
Scapes: SCAPE Token
0 ETH0.000087232.04054619
Set Approval For...238947202025-11-28 4:13:2355 days ago1764303203IN
Scapes: SCAPE Token
0 ETH0.000131872.03945445
Set Approval For...238914582025-11-27 17:13:3556 days ago1764263615IN
Scapes: SCAPE Token
0 ETH0.00000850.13159721
Set Approval For...238645342025-11-23 22:22:2359 days ago1763936543IN
Scapes: SCAPE Token
0 ETH0.00013462.0816275
Set Approval For...238571512025-11-22 21:29:1160 days ago1763846951IN
Scapes: SCAPE Token
0 ETH0.00006921.07027373
Safe Transfer Fr...238555422025-11-22 16:01:4761 days ago1763827307IN
Scapes: SCAPE Token
0 ETH0.000055270.64392653
Safe Transfer Fr...238267312025-11-18 14:56:2365 days ago1763477783IN
Scapes: SCAPE Token
0 ETH0.000101251.47301982
Safe Transfer Fr...238267292025-11-18 14:55:5965 days ago1763477759IN
Scapes: SCAPE Token
0 ETH0.000137091.51258639
Safe Transfer Fr...238155142025-11-17 1:07:2366 days ago1763341643IN
Scapes: SCAPE Token
0 ETH0.000145122.09494562
Set Approval For...237849972025-11-12 18:40:5971 days ago1762972859IN
Scapes: SCAPE Token
0 ETH0.000129412.0013486
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer224340662025-05-07 20:21:11259 days ago1746649271
Scapes: SCAPE Token
0.025 ETH
Transfer224340662025-05-07 20:21:11259 days ago1746649271
Scapes: SCAPE Token
0.475 ETH
Transfer195557712024-03-31 18:53:23662 days ago1711911203
Scapes: SCAPE Token
0.0075 ETH
Transfer195557712024-03-31 18:53:23662 days ago1711911203
Scapes: SCAPE Token
0.1425 ETH
Transfer195557692024-03-31 18:52:59662 days ago1711911179
Scapes: SCAPE Token
0.0075 ETH
Transfer195557692024-03-31 18:52:59662 days ago1711911179
Scapes: SCAPE Token
0.1425 ETH
Transfer187995122023-12-16 15:27:47768 days ago1702740467
Scapes: SCAPE Token
0.011 ETH
Transfer187995122023-12-16 15:27:47768 days ago1702740467
Scapes: SCAPE Token
0.209 ETH
Transfer187106012023-12-04 4:24:47780 days ago1701663887
Scapes: SCAPE Token
0.1 ETH
Transfer187096752023-12-04 1:18:47780 days ago1701652727
Scapes: SCAPE Token
0.1 ETH
Transfer179158932023-08-14 21:52:59891 days ago1692049979
Scapes: SCAPE Token
0.0055 ETH
Transfer179158932023-08-14 21:52:59891 days ago1692049979
Scapes: SCAPE Token
0.1045 ETH
Transfer176008042023-07-01 17:52:47936 days ago1688233967
Scapes: SCAPE Token
0.00925 ETH
Transfer176008042023-07-01 17:52:47936 days ago1688233967
Scapes: SCAPE Token
0.17575 ETH
Transfer175372892023-06-22 19:38:47944 days ago1687462727
Scapes: SCAPE Token
0.0075 ETH
Transfer175372892023-06-22 19:38:47944 days ago1687462727
Scapes: SCAPE Token
0.1425 ETH
Transfer174737842023-06-13 21:36:11953 days ago1686692171
Scapes: SCAPE Token
0.0075 ETH
Transfer174737842023-06-13 21:36:11953 days ago1686692171
Scapes: SCAPE Token
0.1425 ETH
Transfer173523802023-05-27 19:10:11971 days ago1685214611
Scapes: SCAPE Token
0.0111 ETH
Transfer173523802023-05-27 19:10:11971 days ago1685214611
Scapes: SCAPE Token
0.2109 ETH
Transfer172965912023-05-19 22:48:47978 days ago1684536527
Scapes: SCAPE Token
0.011 ETH
Transfer172965912023-05-19 22:48:47978 days ago1684536527
Scapes: SCAPE Token
0.209 ETH
Transfer169563422023-04-01 19:21:351027 days ago1680376895
Scapes: SCAPE Token
0.0125 ETH
Transfer169563422023-04-01 19:21:351027 days ago1680376895
Scapes: SCAPE Token
0.2375 ETH
Transfer167149322023-02-26 20:58:231060 days ago1677445103
Scapes: SCAPE Token
0.0145 ETH
View All Internal Transactions
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Scapes

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 33 : Scapes.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

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

/**
 * @title  Scapes
 * @notice Welcome home.
 * @author akuti.eth, jalil.eth | scapes.eth
 * @dev    This is a Diamond Contract following EIP-2535.
 *         To view its ABI and interact with functions,
 *         use an EIP-2535 compatible explorer.
 */
contract Scapes is SolidStateDiamond {
    /**
     *
     *    ____ _____ ___    ___   ____ ____
     *   / __// ___// _ |  / _ \ / __// __/
     *  _\ \ / /__ / __ | / ___// _/ _\ \
     * /___/ \___//_/ |_|/_/   /___//___/
     *
     *
     * This journey began on September 24th, 2021,
     * when the original PunkScapes smart contract went live.
     * The mission was simple: Create "10,000 homes for the CryptoPunks."
     *
     * But as we received more and more love from other communities,
     * it became clear that we wanted to become a HOME FOR EVERYONE.
     * From this realization, we embarked on a mission
     * to build a world centered around that idea.
     *
     * The metadata and art of PunkScapes
     * was originally hosted on the Interplanetary File System (IPFS).
     * But we soon realized, in order to fulfill their true potential,
     * they needed to go fully onchain.
     *
     * As time passed,
     * we felt the weight of our old contract,
     * and knew it was time to move on.
     *
     * So, on the 20th of December,
     * we burned the old world to the ground,
     * leaving behind only ashes and memories.
     * From those ashes, we built a new world,
     * one that would be our home for all time.
     *
     * And thus, the Scapes were created.
     *
     * Welcome home.
     */
}

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

pragma solidity ^0.8.8;

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

interface IOwnable is IERC173 {}

File 3 of 33 : IOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

interface ISafeOwnable is IOwnable {
    /**
     * @notice get the nominated owner who has permission to call acceptOwnership
     */
    function nomineeOwner() external view returns (address);

    /**
     * @notice accept transfer of contract ownership
     */
    function acceptOwnership() external;
}

File 5 of 33 : ISafeOwnableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

interface ISafeOwnableInternal is IOwnableInternal {
    error SafeOwnable__NotNomineeOwner();
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IERC173 } from '../../interfaces/IERC173.sol';
import { IOwnable } from './IOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';

/**
 * @title Ownership access control based on ERC173
 */
abstract contract Ownable is IOwnable, OwnableInternal {
    using OwnableStorage for OwnableStorage.Layout;

    /**
     * @inheritdoc IERC173
     */
    function owner() public view virtual returns (address) {
        return _owner();
    }

    /**
     * @inheritdoc IERC173
     */
    function transferOwnership(address account) public virtual onlyOwner {
        _transferOwnership(account);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

abstract contract OwnableInternal is IOwnableInternal {
    using AddressUtils for address;
    using OwnableStorage for OwnableStorage.Layout;

    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) {
        address owner = _owner();

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

        return owner;
    }

    function _transferOwnership(address account) internal virtual {
        OwnableStorage.layout().setOwner(account);
        emit OwnershipTransferred(msg.sender, account);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library OwnableStorage {
    struct Layout {
        address owner;
    }

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

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

    function setOwner(Layout storage l, address owner) internal {
        l.owner = owner;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Ownable, OwnableStorage } from './Ownable.sol';
import { ISafeOwnable } from './ISafeOwnable.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { SafeOwnableInternal } from './SafeOwnableInternal.sol';

/**
 * @title Ownership access control based on ERC173 with ownership transfer safety check
 */
abstract contract SafeOwnable is ISafeOwnable, Ownable, SafeOwnableInternal {
    /**
     * @inheritdoc ISafeOwnable
     */
    function nomineeOwner() public view virtual returns (address) {
        return _nomineeOwner();
    }

    /**
     * @inheritdoc ISafeOwnable
     */
    function acceptOwnership() public virtual onlyNomineeOwner {
        _acceptOwnership();
    }

    function _transferOwnership(
        address account
    ) internal virtual override(OwnableInternal, SafeOwnableInternal) {
        super._transferOwnership(account);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnableInternal } from './ISafeOwnableInternal.sol';
import { OwnableInternal } from './OwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';
import { SafeOwnableStorage } from './SafeOwnableStorage.sol';

abstract contract SafeOwnableInternal is ISafeOwnableInternal, OwnableInternal {
    using OwnableStorage for OwnableStorage.Layout;
    using SafeOwnableStorage for SafeOwnableStorage.Layout;

    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 {
        OwnableStorage.Layout storage l = OwnableStorage.layout();
        emit OwnershipTransferred(l.owner, msg.sender);
        l.setOwner(msg.sender);
        SafeOwnableStorage.layout().setNomineeOwner(address(0));
    }

    /**
     * @notice set nominee owner, granting permission to call acceptOwnership
     */
    function _transferOwnership(address account) internal virtual override {
        SafeOwnableStorage.layout().setNomineeOwner(account);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library SafeOwnableStorage {
    struct Layout {
        address nomineeOwner;
    }

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

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

    function setNomineeOwner(Layout storage l, address nomineeOwner) internal {
        l.nomineeOwner = nomineeOwner;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title Contract ownership standard interface
 * @dev see https://eips.ethereum.org/EIPS/eip-173
 */
interface IERC173 is IERC173Internal {
    /**
     * @notice get the ERC173 contract owner
     * @return conrtact owner
     */
    function owner() external view returns (address);

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

File 14 of 33 : IERC173Internal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title ERC165 implementation
 */
abstract contract ERC165 is IERC165 {
    using ERC165Storage for ERC165Storage.Layout;

    /**
     * @inheritdoc IERC165
     */
    function supportsInterface(bytes4 interfaceId) public view returns (bool) {
        return ERC165Storage.layout().isSupportedInterface(interfaceId);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

library ERC165Storage {
    error ERC165Storage__InvalidInterfaceId();

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

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

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

    function isSupportedInterface(
        Layout storage l,
        bytes4 interfaceId
    ) internal view returns (bool) {
        return l.supportedInterfaces[interfaceId];
    }

    function setSupportedInterface(
        Layout storage l,
        bytes4 interfaceId,
        bool status
    ) internal {
        if (interfaceId == 0xffffffff)
            revert ERC165Storage__InvalidInterfaceId();
        l.supportedInterfaces[interfaceId] = status;
    }
}

File 17 of 33 : DiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { Proxy } from '../../Proxy.sol';
import { IDiamondBase } from './IDiamondBase.sol';
import { DiamondBaseStorage } from './DiamondBaseStorage.sol';

/**
 * @title EIP-2535 "Diamond" proxy base contract
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
abstract contract DiamondBase is IDiamondBase, Proxy {
    /**
     * @inheritdoc Proxy
     */
    function _getImplementation()
        internal
        view
        virtual
        override
        returns (address implementation)
    {
        // inline storage layout retrieval uses less gas
        DiamondBaseStorage.Layout storage l;
        bytes32 slot = DiamondBaseStorage.STORAGE_SLOT;
        assembly {
            l.slot := slot
        }

        implementation = address(bytes20(l.facets[msg.sig]));
    }
}

File 18 of 33 : DiamondBaseStorage.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

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

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

File 19 of 33 : IDiamondBase.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

interface IDiamondBase is IProxy {}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

// TODO: DiamondFallback interface

/**
 * @title Fallback feature for EIP-2535 "Diamond" proxy
 */
abstract contract DiamondFallback is
    IDiamondFallback,
    OwnableInternal,
    DiamondBase
{
    /**
     * @inheritdoc IDiamondFallback
     */
    function getFallbackAddress()
        external
        view
        returns (address fallbackAddress)
    {
        fallbackAddress = _getFallbackAddress();
    }

    /**
     * @inheritdoc IDiamondFallback
     */
    function setFallbackAddress(address fallbackAddress) external onlyOwner {
        _setFallbackAddress(fallbackAddress);
    }

    /**
     * @inheritdoc DiamondBase
     * @notice query custom fallback address is no implementation is found
     */
    function _getImplementation()
        internal
        view
        virtual
        override
        returns (address implementation)
    {
        implementation = super._getImplementation();

        if (implementation == address(0)) {
            implementation = _getFallbackAddress();
        }
    }

    /**
     * @notice query the address of the fallback implementation
     * @return fallbackAddress address of fallback implementation
     */
    function _getFallbackAddress()
        internal
        view
        virtual
        returns (address fallbackAddress)
    {
        fallbackAddress = DiamondBaseStorage.layout().fallbackAddress;
    }

    /**
     * @notice set the address of the fallback implementation
     * @param fallbackAddress address of fallback implementation
     */
    function _setFallbackAddress(address fallbackAddress) internal virtual {
        DiamondBaseStorage.layout().fallbackAddress = fallbackAddress;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IDiamondBase } from '../base/IDiamondBase.sol';

interface IDiamondFallback is IDiamondBase {
    /**
     * @notice query the address of the fallback implementation
     * @return fallbackAddress address of fallback implementation
     */
    function getFallbackAddress()
        external
        view
        returns (address fallbackAddress);

    /**
     * @notice set the address of the fallback implementation
     * @param fallbackAddress address of fallback implementation
     */
    function setFallbackAddress(address fallbackAddress) external;
}

File 22 of 33 : ISolidStateDiamond.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { ISafeOwnable } from '../../access/ownable/ISafeOwnable.sol';
import { IERC165 } from '../../interfaces/IERC165.sol';
import { IDiamondBase } from './base/IDiamondBase.sol';
import { IDiamondFallback } from './fallback/IDiamondFallback.sol';
import { IDiamondReadable } from './readable/IDiamondReadable.sol';
import { IDiamondWritable } from './writable/IDiamondWritable.sol';

interface ISolidStateDiamond is
    IDiamondBase,
    IDiamondFallback,
    IDiamondReadable,
    IDiamondWritable,
    ISafeOwnable,
    IERC165
{
    receive() external payable;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

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

        diamondFacets = new Facet[](l.selectorCount);

        uint8[] memory numFacetSelectors = new uint8[](l.selectorCount);
        uint256 numFacets;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

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

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

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (diamondFacets[facetIndex].target == facet) {
                        diamondFacets[facetIndex].selectors[
                            numFacetSelectors[facetIndex]
                        ] = selector;
                        // probably will never have more than 256 functions from one facet contract
                        require(numFacetSelectors[facetIndex] < 255);
                        numFacetSelectors[facetIndex]++;
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                diamondFacets[numFacets].target = facet;
                diamondFacets[numFacets].selectors = new bytes4[](
                    l.selectorCount
                );
                diamondFacets[numFacets].selectors[0] = selector;
                numFacetSelectors[numFacets] = 1;
                numFacets++;
            }
        }

        for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
            uint256 numSelectors = numFacetSelectors[facetIndex];
            bytes4[] memory selectors = diamondFacets[facetIndex].selectors;

            // setting the number of selectors
            assembly {
                mstore(selectors, numSelectors)
            }
        }

        // setting the number of facets
        assembly {
            mstore(diamondFacets, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetFunctionSelectors(
        address facet
    ) external view returns (bytes4[] memory selectors) {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        selectors = new bytes4[](l.selectorCount);

        uint256 numSelectors;
        uint256 selectorIndex;

        // loop through function selectors
        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

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

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

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));

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

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

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses)
    {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

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

        for (uint256 slotIndex; selectorIndex < l.selectorCount; slotIndex++) {
            bytes32 slot = l.selectorSlots[slotIndex];

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

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

                bytes4 selector = bytes4(slot << (selectorSlotIndex << 5));
                address facet = address(bytes20(l.facets[selector]));

                bool continueLoop;

                for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
                    if (facet == addresses[facetIndex]) {
                        continueLoop = true;
                        break;
                    }
                }

                if (continueLoop) {
                    continue;
                }

                addresses[numFacets] = facet;
                numFacets++;
            }
        }

        // set the number of facet addresses in the array
        assembly {
            mstore(addresses, numFacets)
        }
    }

    /**
     * @inheritdoc IDiamondReadable
     */
    function facetAddress(
        bytes4 selector
    ) external view returns (address facet) {
        facet = address(bytes20(DiamondBaseStorage.layout().facets[selector]));
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

/**
 * @title Diamond proxy introspection interface
 * @dev see https://eips.ethereum.org/EIPS/eip-2535
 */
interface IDiamondReadable {
    struct Facet {
        address target;
        bytes4[] selectors;
    }

    /**
     * @notice get all facets and their selectors
     * @return diamondFacets array of structured facet data
     */
    function facets() external view returns (Facet[] memory diamondFacets);

    /**
     * @notice get all selectors for given facet address
     * @param facet address of facet to query
     * @return selectors array of function selectors
     */
    function facetFunctionSelectors(
        address facet
    ) external view returns (bytes4[] memory selectors);

    /**
     * @notice get addresses of all facets used by diamond
     * @return addresses array of facet addresses
     */
    function facetAddresses()
        external
        view
        returns (address[] memory addresses);

    /**
     * @notice get the address of the facet associated with given selector
     * @param selector function selector to query
     * @return facet facet address (zero address if not found)
     */
    function facetAddress(
        bytes4 selector
    ) external view returns (address facet);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { IOwnable, Ownable, OwnableInternal, OwnableStorage } from '../../access/ownable/Ownable.sol';
import { ISafeOwnable, SafeOwnable } from '../../access/ownable/SafeOwnable.sol';
import { IERC173 } from '../../interfaces/IERC173.sol';
import { ERC165, IERC165, ERC165Storage } from '../../introspection/ERC165.sol';
import { DiamondBase, DiamondBaseStorage } from './base/DiamondBase.sol';
import { DiamondFallback, IDiamondFallback } from './fallback/DiamondFallback.sol';
import { DiamondReadable, IDiamondReadable } from './readable/DiamondReadable.sol';
import { DiamondWritable, IDiamondWritable } from './writable/DiamondWritable.sol';
import { ISolidStateDiamond } from './ISolidStateDiamond.sol';

/**
 * @title SolidState "Diamond" proxy reference implementation
 */
abstract contract SolidStateDiamond is
    ISolidStateDiamond,
    DiamondBase,
    DiamondFallback,
    DiamondReadable,
    DiamondWritable,
    SafeOwnable,
    ERC165
{
    using DiamondBaseStorage for DiamondBaseStorage.Layout;
    using ERC165Storage for ERC165Storage.Layout;
    using OwnableStorage for OwnableStorage.Layout;

    constructor() {
        ERC165Storage.Layout storage erc165 = ERC165Storage.layout();
        bytes4[] memory selectors = new bytes4[](12);
        uint256 selectorIndex;

        // register DiamondFallback

        selectors[selectorIndex++] = IDiamondFallback
            .getFallbackAddress
            .selector;
        selectors[selectorIndex++] = IDiamondFallback
            .setFallbackAddress
            .selector;

        erc165.setSupportedInterface(type(IDiamondFallback).interfaceId, true);

        // register DiamondWritable

        selectors[selectorIndex++] = IDiamondWritable.diamondCut.selector;

        erc165.setSupportedInterface(type(IDiamondWritable).interfaceId, true);

        // register DiamondReadable

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

        erc165.setSupportedInterface(type(IDiamondReadable).interfaceId, true);

        // register ERC165

        selectors[selectorIndex++] = IERC165.supportsInterface.selector;

        erc165.setSupportedInterface(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;

        erc165.setSupportedInterface(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

        OwnableStorage.layout().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 26 of 33 : DiamondWritable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

import { OwnableInternal } from '../../../access/ownable/OwnableInternal.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.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
{
    using DiamondBaseStorage for DiamondBaseStorage.Layout;

    /**
     * @inheritdoc IDiamondWritable
     */
    function diamondCut(
        FacetCut[] calldata facetCuts,
        address target,
        bytes calldata data
    ) external onlyOwner {
        _diamondCut(facetCuts, target, data);
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import { AddressUtils } from '../../../utils/AddressUtils.sol';
import { DiamondBaseStorage } from '../base/DiamondBaseStorage.sol';
import { IDiamondWritableInternal } from './IDiamondWritableInternal.sol';

abstract contract DiamondWritableInternal is IDiamondWritableInternal {
    using AddressUtils for address;

    bytes32 private constant CLEAR_ADDRESS_MASK =
        bytes32(uint256(0xffffffffffffffffffffffff));
    bytes32 private constant CLEAR_SELECTOR_MASK =
        bytes32(uint256(0xffffffff << 224));

    /**
     * @notice update functions callable on Diamond proxy
     * @param facetCuts array of structured Diamond facet update data
     * @param target optional recipient of initialization delegatecall
     * @param data optional initialization call data
     */
    function _diamondCut(
        FacetCut[] memory facetCuts,
        address target,
        bytes memory data
    ) internal {
        DiamondBaseStorage.Layout storage l = DiamondBaseStorage.layout();

        unchecked {
            uint256 originalSelectorCount = l.selectorCount;
            uint256 selectorCount = originalSelectorCount;
            bytes32 selectorSlot;

            // Check if last selector slot is not full
            if (selectorCount & 7 > 0) {
                // get last selectorSlot
                selectorSlot = l.selectorSlots[selectorCount >> 3];
            }

            for (uint256 i; i < facetCuts.length; i++) {
                FacetCut memory facetCut = facetCuts[i];
                FacetCutAction action = facetCut.action;

                if (facetCut.selectors.length == 0)
                    revert DiamondWritable__SelectorNotSpecified();

                if (action == FacetCutAction.ADD) {
                    (selectorCount, selectorSlot) = _addFacetSelectors(
                        l,
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                } else if (action == FacetCutAction.REPLACE) {
                    _replaceFacetSelectors(l, facetCut);
                } else if (action == FacetCutAction.REMOVE) {
                    (selectorCount, selectorSlot) = _removeFacetSelectors(
                        l,
                        selectorCount,
                        selectorSlot,
                        facetCut
                    );
                }
            }

            if (selectorCount != originalSelectorCount) {
                l.selectorCount = uint16(selectorCount);
            }

            // If last selector slot is not full
            if (selectorCount & 7 > 0) {
                l.selectorSlots[selectorCount >> 3] = selectorSlot;
            }

            emit DiamondCut(facetCuts, target, data);
            _initialize(target, data);
        }
    }

    function _addFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (
                facetCut.target != address(this) &&
                !facetCut.target.isContract()
            ) revert DiamondWritable__TargetHasNoCode();

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

                if (address(bytes20(oldFacet)) != address(0))
                    revert DiamondWritable__SelectorAlreadyAdded();

                // add facet for selector
                l.facets[selector] =
                    bytes20(facetCut.target) |
                    bytes32(selectorCount);
                uint256 selectorInSlotPosition = (selectorCount & 7) << 5;

                // clear selector position in slot and add selector
                selectorSlot =
                    (selectorSlot &
                        ~(CLEAR_SELECTOR_MASK >> selectorInSlotPosition)) |
                    (bytes32(selector) >> selectorInSlotPosition);

                // if slot is full then write it to storage
                if (selectorInSlotPosition == 224) {
                    l.selectorSlots[selectorCount >> 3] = selectorSlot;
                    selectorSlot = 0;
                }

                selectorCount++;
            }

            return (selectorCount, selectorSlot);
        }
    }

    function _removeFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        uint256 selectorCount,
        bytes32 selectorSlot,
        FacetCut memory facetCut
    ) internal returns (uint256, bytes32) {
        unchecked {
            if (facetCut.target != address(0))
                revert DiamondWritable__RemoveTargetNotZeroAddress();

            uint256 selectorSlotCount = selectorCount >> 3;
            uint256 selectorInSlotIndex = selectorCount & 7;

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

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

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

                if (selectorSlot == 0) {
                    selectorSlotCount--;
                    selectorSlot = l.selectorSlots[selectorSlotCount];
                    selectorInSlotIndex = 7;
                } else {
                    selectorInSlotIndex--;
                }

                bytes4 lastSelector;
                uint256 oldSelectorsSlotCount;
                uint256 oldSelectorInSlotPosition;

                // adding a block here prevents stack too deep error
                {
                    // replace selector with last selector in l.facets
                    lastSelector = bytes4(
                        selectorSlot << (selectorInSlotIndex << 5)
                    );

                    if (lastSelector != selector) {
                        // update last selector slot position info
                        l.facets[lastSelector] =
                            (oldFacet & CLEAR_ADDRESS_MASK) |
                            bytes20(l.facets[lastSelector]);
                    }

                    delete l.facets[selector];
                    uint256 oldSelectorCount = uint16(uint256(oldFacet));
                    oldSelectorsSlotCount = oldSelectorCount >> 3;
                    oldSelectorInSlotPosition = (oldSelectorCount & 7) << 5;
                }

                if (oldSelectorsSlotCount != selectorSlotCount) {
                    bytes32 oldSelectorSlot = l.selectorSlots[
                        oldSelectorsSlotCount
                    ];

                    // clears the selector we are deleting and puts the last selector in its place.
                    oldSelectorSlot =
                        (oldSelectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);

                    // update storage with the modified slot
                    l.selectorSlots[oldSelectorsSlotCount] = oldSelectorSlot;
                } else {
                    // clears the selector we are deleting and puts the last selector in its place.
                    selectorSlot =
                        (selectorSlot &
                            ~(CLEAR_SELECTOR_MASK >>
                                oldSelectorInSlotPosition)) |
                        (bytes32(lastSelector) >> oldSelectorInSlotPosition);
                }

                if (selectorInSlotIndex == 0) {
                    delete l.selectorSlots[selectorSlotCount];
                    selectorSlot = 0;
                }
            }

            selectorCount = (selectorSlotCount << 3) | selectorInSlotIndex;

            return (selectorCount, selectorSlot);
        }
    }

    function _replaceFacetSelectors(
        DiamondBaseStorage.Layout storage l,
        FacetCut memory facetCut
    ) internal {
        unchecked {
            if (!facetCut.target.isContract())
                revert DiamondWritable__TargetHasNoCode();

            for (uint256 i; i < facetCut.selectors.length; i++) {
                bytes4 selector = facetCut.selectors[i];
                bytes32 oldFacet = l.facets[selector];
                address oldFacetAddress = address(bytes20(oldFacet));

                if (oldFacetAddress == address(0))
                    revert DiamondWritable__SelectorNotFound();
                if (oldFacetAddress == address(this))
                    revert DiamondWritable__SelectorIsImmutable();
                if (oldFacetAddress == facetCut.target)
                    revert DiamondWritable__ReplaceTargetIsIdentical();

                // replace old facet address
                l.facets[selector] =
                    (oldFacet & CLEAR_ADDRESS_MASK) |
                    bytes20(facetCut.target);
            }
        }
    }

    function _initialize(address target, bytes memory data) private {
        if ((target == address(0)) != (data.length == 0))
            revert DiamondWritable__InvalidInitializationParameters();

        if (target != address(0)) {
            if (target != address(this)) {
                if (!target.isContract())
                    revert DiamondWritable__TargetHasNoCode();
            }

            (bool success, ) = target.delegatecall(data);

            if (!success) {
                assembly {
                    returndatacopy(0, 0, returndatasize())
                    revert(0, returndatasize())
                }
            }
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

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

File 29 of 33 : IDiamondWritableInternal.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IDiamondWritableInternal {
    enum FacetCutAction {
        ADD,
        REPLACE,
        REMOVE
    }

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

    error DiamondWritable__InvalidInitializationParameters();
    error DiamondWritable__RemoveTargetNotZeroAddress();
    error DiamondWritable__ReplaceTargetIsIdentical();
    error DiamondWritable__SelectorAlreadyAdded();
    error DiamondWritable__SelectorIsImmutable();
    error DiamondWritable__SelectorNotFound();
    error DiamondWritable__SelectorNotSpecified();
    error DiamondWritable__TargetHasNoCode();

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

File 30 of 33 : IProxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

interface IProxy {
    error Proxy__ImplementationIsNotContract();

    fallback() external payable;
}

File 31 of 33 : Proxy.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

/**
 * @title Base proxy contract
 */
abstract contract Proxy is IProxy {
    using AddressUtils for address;

    /**
     * @notice delegate all calls to implementation contract
     * @dev reverts if implementation address contains no code, for compatibility with metamorphic contracts
     * @dev memory location in use by assembly may be unsafe in other contexts
     */
    fallback() external payable virtual {
        address implementation = _getImplementation();

        if (!implementation.isContract())
            revert Proxy__ImplementationIsNotContract();

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(
                gas(),
                implementation,
                0,
                calldatasize(),
                0,
                0
            )
            returndatacopy(0, 0, returndatasize())

            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @notice get logic implementation address
     * @return implementation address
     */
    function _getImplementation() internal virtual returns (address);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

library AddressUtils {
    using UintUtils for uint256;

    error AddressUtils__InsufficientBalance();
    error AddressUtils__NotContract();
    error AddressUtils__SendValueFailed();

    function toString(address account) internal pure returns (string memory) {
        return uint256(uint160(account)).toHexString(20);
    }

    function isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function sendValue(address payable account, uint256 amount) internal {
        (bool success, ) = account.call{ value: amount }('');
        if (!success) revert AddressUtils__SendValueFailed();
    }

    function functionCall(
        address target,
        bytes memory data
    ) internal returns (bytes memory) {
        return
            functionCall(target, data, 'AddressUtils: failed low-level call');
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory error
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, error);
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return
            functionCallWithValue(
                target,
                data,
                value,
                'AddressUtils: failed low-level call with value'
            );
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) internal returns (bytes memory) {
        if (value > address(this).balance)
            revert AddressUtils__InsufficientBalance();
        return _functionCallWithValue(target, data, value, error);
    }

    /**
     * @notice execute arbitrary external call with limited gas usage and amount of copied return data
     * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License)
     * @param target recipient of call
     * @param gasAmount gas allowance for call
     * @param value native token value to include in call
     * @param maxCopy maximum number of bytes to copy from return data
     * @param data encoded call data
     * @return success whether call is successful
     * @return returnData copied return data
     */
    function excessivelySafeCall(
        address target,
        uint256 gasAmount,
        uint256 value,
        uint16 maxCopy,
        bytes memory data
    ) internal returns (bool success, bytes memory returnData) {
        returnData = new bytes(maxCopy);

        assembly {
            // execute external call via assembly to avoid automatic copying of return data
            success := call(
                gasAmount,
                target,
                value,
                add(data, 0x20),
                mload(data),
                0,
                0
            )

            // determine whether to limit amount of data to copy
            let toCopy := returndatasize()

            if gt(toCopy, maxCopy) {
                toCopy := maxCopy
            }

            // store the length of the copied bytes
            mstore(returnData, toCopy)

            // copy the bytes from returndata[0:toCopy]
            returndatacopy(add(returnData, 0x20), 0, toCopy)
        }
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory error
    ) private returns (bytes memory) {
        if (!isContract(target)) revert AddressUtils__NotContract();

        (bool success, bytes memory returnData) = target.call{ value: value }(
            data
        );

        if (success) {
            return returnData;
        } else if (returnData.length > 0) {
            assembly {
                let returnData_size := mload(returnData)
                revert(add(32, returnData), returnData_size)
            }
        } else {
            revert(error);
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.8;

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

    bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';

    function add(uint256 a, int256 b) internal pure returns (uint256) {
        return b < 0 ? sub(a, -b) : a + uint256(b);
    }

    function sub(uint256 a, int256 b) internal pure returns (uint256) {
        return b < 0 ? add(a, -b) : a - uint256(b);
    }

    function toString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return '0';
        }

        uint256 temp = value;
        uint256 digits;

        while (temp != 0) {
            digits++;
            temp /= 10;
        }

        bytes memory buffer = new bytes(digits);

        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }

        return string(buffer);
    }

    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return '0x00';
        }

        uint256 length = 0;

        for (uint256 temp = value; temp != 0; temp >>= 8) {
            unchecked {
                length++;
            }
        }

        return toHexString(value, length);
    }

    function toHexString(
        uint256 value,
        uint256 length
    ) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = '0';
        buffer[1] = 'x';

        unchecked {
            for (uint256 i = 2 * length + 1; i > 1; --i) {
                buffer[i] = HEX_SYMBOLS[value & 0xf];
                value >>= 4;
            }
        }

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

        return string(buffer);
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"DiamondWritable__InvalidInitializationParameters","type":"error"},{"inputs":[],"name":"DiamondWritable__RemoveTargetNotZeroAddress","type":"error"},{"inputs":[],"name":"DiamondWritable__ReplaceTargetIsIdentical","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorAlreadyAdded","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorIsImmutable","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotFound","type":"error"},{"inputs":[],"name":"DiamondWritable__SelectorNotSpecified","type":"error"},{"inputs":[],"name":"DiamondWritable__TargetHasNoCode","type":"error"},{"inputs":[],"name":"ERC165Storage__InvalidInterfaceId","type":"error"},{"inputs":[],"name":"Ownable__NotOwner","type":"error"},{"inputs":[],"name":"Ownable__NotTransitiveOwner","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"inputs":[],"name":"SafeOwnable__NotNomineeOwner","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"enum IDiamondWritableInternal.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondWritableInternal.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facet","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes4[]","name":"selectors","type":"bytes4[]"}],"internalType":"struct IDiamondReadable.Facet[]","name":"diamondFacets","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFallbackAddress","outputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nomineeOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fallbackAddress","type":"address"}],"name":"setFallbackAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b506000620000296200050060201b62000b9e1760201c565b60408051600c8082526101a082019092529192506000919060208201610180803683370190505090506000632c40805960e01b8282620000698162000db7565b9350815181106200007e576200007e62000ddf565b6001600160e01b031990921660209283029190910190910152639142376560e01b8282620000ac8162000db7565b935081518110620000c157620000c162000ddf565b6001600160e01b0319909216602092830291909101820152620000fb908490632f40adcf60e21b9060019062000bc262000524821b17901c565b6307e4c70760e21b8282620001108162000db7565b93508151811062000125576200012562000ddf565b6001600160e01b03199092166020928302919091018201526200015f9084906307e4c70760e21b9060019062000bc262000524821b17901c565b637a0ed62760e01b8282620001748162000db7565b93508151811062000189576200018962000ddf565b6001600160e01b0319909216602092830291909101909101526356fe50af60e11b8282620001b78162000db7565b935081518110620001cc57620001cc62000ddf565b6001600160e01b0319909216602092830291909101909101526314bbdacb60e21b8282620001fa8162000db7565b9350815181106200020f576200020f62000ddf565b6001600160e01b0319909216602092830291909101909101526366ffd66360e11b82826200023d8162000db7565b93508151811062000252576200025262000ddf565b6001600160e01b03199092166020928302919091018201526200028c9084906348e2b09360e01b9060019062000bc262000524821b17901c565b6301ffc9a760e01b8282620002a18162000db7565b935081518110620002b657620002b662000ddf565b6001600160e01b0319909216602092830291909101820152620002f09084906301ffc9a760e01b9060019062000bc262000524821b17901c565b638da5cb5b60e01b8282620003058162000db7565b9350815181106200031a576200031a62000ddf565b6001600160e01b03199092166020928302919091019091015263455a8a8560e11b8282620003488162000db7565b9350815181106200035d576200035d62000ddf565b6001600160e01b03199092166020928302919091019091015263f2fde38b60e01b82826200038b8162000db7565b935081518110620003a057620003a062000ddf565b6001600160e01b0319909216602092830291909101909101526379ba509760e01b8282620003ce8162000db7565b935081518110620003e357620003e362000ddf565b6001600160e01b03199092166020928302919091018201526200041d9084906307f5828d60e41b9060019062000bc262000524821b17901c565b604080516001808252818301909252600091816020015b6040805160608082018352600080835260208301529181019190915281526020019060019003908162000434579050506040805160608101909152308152909150602081016000815260200184815250816000815181106200049a576200049a62000ddf565b6020026020010181905250620004c8816000604051806020016040528060008152506200057e60201b60201c565b620004f633620004e26200075a60201b62000c1b1760201c565b6200077e60201b62000c3f1790919060201c565b5050505062000f84565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003620005505760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b6000620005956200079b60201b62000c5c1760201c565b600181015490915061ffff811690819060009060071615620005c95750600381901c60009081526002840160205260409020545b60005b8751811015620006c8576000888281518110620005ed57620005ed62000ddf565b60200260200101519050600081602001519050816040015151600003620006275760405163eb6c3aeb60e01b815260040160405180910390fd5b60008160028111156200063e576200063e62000df5565b036200065d576200065287868685620007bf565b9095509350620006bd565b600181600281111562000674576200067462000df5565b036200068c576200068687836200091e565b620006bd565b6002816002811115620006a357620006a362000df5565b03620006bd57620006b78786868562000a84565b90955093505b5050600101620005cc565b50828214620006e55760018401805461ffff191661ffff84161790555b60078216156200070857600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb6738787876040516200073d9392919062000e5f565b60405180910390a162000751868662000cb0565b50505050505050565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b805160009081906001600160a01b03163014801590620007ff5750620007fd83600001516001600160a01b031662000db160201b620002ad1760201c565b155b156200081e57604051633ddc5cab60e21b815260040160405180910390fd5b60005b83604001515181101562000911576000846040015182815181106200084a576200084a62000ddf565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c156200089757604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036200090157600389901c600090815260028b0160205260408120989098555b5050506001958601950162000821565b5093959294509192505050565b6200094181600001516001600160a01b031662000db160201b620002ad1760201c565b6200095f57604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101562000a7f576000826040015182815181106200098b576200098b62000ddf565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80620009d8576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160362000a025760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b03160362000a39576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166001600160601b039190911617905560010162000962565b505050565b805160009081906001600160a01b03161562000ab357604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101562000c9c5760008660400151828151811062000ae85762000ae862000ddf565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c62000b34576040516337e25a9760e11b815260040160405180910390fd5b30606082901c0362000b595760405163e983573160e01b815260040160405180910390fd5b600089900362000b8757600019909401600081815260028c0160205260409020549850936007935062000b8f565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161462000be2576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166001600160601b0386161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b1687821462000c4757600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c17905562000c6b565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000362000c8a57600088815260028f01602052604081208190559b505b50506001909301925062000abf915050565b5060039190911b1796939550929350505050565b8051156001600160a01b038316151462000cdd576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b0382161562000dad576001600160a01b038216301462000d3b5762000d1d826001600160a01b031662000db160201b620002ad1760201c565b62000d3b57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b03168260405162000d57919062000f66565b600060405180830381855af49150503d806000811462000d94576040519150601f19603f3d011682016040523d82523d6000602084013e62000d99565b606091505b505090508062000a7f573d6000803e3d6000fd5b5050565b3b151590565b60006001820162000dd857634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b60005b8381101562000e2857818101518382015260200162000e0e565b50506000910152565b6000815180845262000e4b81602086016020860162000e0b565b601f01601f19169290920160200192915050565b60006060808301818452808751808352608092508286019150828160051b8701016020808b0160005b8481101562000f3457898403607f19018652815180516001600160a01b0316855283810151898601906003811062000ed057634e487b7160e01b600052602160045260246000fd5b868601526040918201519186018a905281519081905290840190600090898701905b8083101562000f1e5783516001600160e01b031916825292860192600192909201919086019062000ef2565b5097850197955050509082019060010162000e88565b50506001600160a01b038a1690880152868103604088015262000f58818962000e31565b9a9950505050505050505050565b6000825162000f7a81846020870162000e0b565b9190910192915050565b611bb38062000f946000396000f3fe6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146101e75780638da5cb5b146101fc5780639142376514610211578063adfca15e14610231578063cdffacc61461025e578063f2fde38b1461027e576100b2565b806301ffc9a71461010c5780631f931c1c146101415780632c4080591461016157806352ef6b2c1461018e57806379ba5097146101b05780637a0ed627146101c5576100b2565b366100b257005b60006100bc61029e565b90506001600160a01b0381163b6100e6576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610105573d6000f35b3d6000fd5b005b34801561011857600080fd5b5061012c610127366004611566565b6102b3565b60405190151581526020015b60405180910390f35b34801561014d57600080fd5b5061010a61015c3660046115e8565b6102e8565b34801561016d57600080fd5b50610176610372565b6040516001600160a01b039091168152602001610138565b34801561019a57600080fd5b506101a361037c565b604051610138919061169a565b3480156101bc57600080fd5b5061010a61051f565b3480156101d157600080fd5b506101da610562565b604051610138919061172c565b3480156101f357600080fd5b5061017661098a565b34801561020857600080fd5b50610176610994565b34801561021d57600080fd5b5061010a61022c3660046117a9565b61099e565b34801561023d57600080fd5b5061025161024c3660046117a9565b6109e3565b60405161013891906117c4565b34801561026a57600080fd5b50610176610279366004611566565b610b2f565b34801561028a57600080fd5b5061010a6102993660046117a9565b610b5c565b60006102a8610c80565b905090565b3b151590565b60006102e2826102c1610b9e565b906001600160e01b0319166000908152602091909152604090205460ff1690565b92915050565b6102f0610ccc565b6001600160a01b0316336001600160a01b03161461032157604051632f7a8ee160e01b815260040160405180910390fd5b61036b61032e858761189a565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ce592505050565b5050505050565b60006102a8610e93565b60606000610388610c5c565b600181015490915061ffff1667ffffffffffffffff8111156103ac576103ac611806565b6040519080825280602002602001820160405280156103d5578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610517576000818152600285016020526040812054905b60088110156105025783610414816119e4565b600188015490955061ffff168511905061050257600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156104a5578a818151811061046a5761046a6119fd565b60200260200101516001600160a01b0316836001600160a01b03160361049357600191506104a5565b8061049d816119e4565b915050610450565b5080156104b4575050506104f0565b818a89815181106104c7576104c76119fd565b6001600160a01b0390921660209283029190910190910152876104e9816119e4565b9850505050505b806104fa816119e4565b915050610401565b5050808061050f906119e4565b9150506103de565b505082525090565b610527610eaf565b6001600160a01b0316336001600160a01b0316146105585760405163efd1052d60e01b815260040160405180910390fd5b610560610ed7565b565b6060600061056e610c5c565b600181015490915061ffff1667ffffffffffffffff81111561059257610592611806565b6040519080825280602002602001820160405280156105d857816020015b6040805180820190915260008152606060208201528152602001906001900390816105b05790505b50600182015490925060009061ffff1667ffffffffffffffff81111561060057610600611806565b604051908082528060200260200182016040528015610629578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610918576000818152600286016020526040812054905b60088110156109035783610668816119e4565b600189015490955061ffff168511905061090357600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156107c157826001600160a01b03168c82815181106106c8576106c86119fd565b6020026020010151600001516001600160a01b0316036107af57838c82815181106106f5576106f56119fd565b6020026020010151602001518b8381518110610713576107136119fd565b602002602001015160ff168151811061072e5761072e6119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610764576107646119fd565b602002602001015160ff161061077957600080fd5b89818151811061078b5761078b6119fd565b6020026020010180518091906107a090611a13565b60ff16905250600191506107c1565b806107b9816119e4565b9150506106a4565b5080156107d0575050506108f1565b818b89815181106107e3576107e36119fd565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561081c5761081c611806565b604051908082528060200260200182016040528015610845578160200160208202803683370190505b508b8981518110610858576108586119fd565b602002602001015160200181905250828b898151811061087a5761087a6119fd565b602002602001015160200151600081518110610898576108986119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106108ce576108ce6119fd565b60ff90921660209283029190910190910152876108ea816119e4565b9850505050505b806108fb816119e4565b915050610655565b50508080610910906119e4565b915050610632565b5060005b8281101561097f576000848281518110610938576109386119fd565b602002602001015160ff1690506000878381518110610959576109596119fd565b602002602001015160200151905081815250508080610977906119e4565b91505061091c565b508185525050505090565b60006102a8610eaf565b60006102a8610ccc565b6109a6610ccc565b6001600160a01b0316336001600160a01b0316146109d757604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f54565b50565b606060006109ef610c5c565b600181015490915061ffff1667ffffffffffffffff811115610a1357610a13611806565b604051908082528060200260200182016040528015610a3c578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610b25576000818152600285016020526040812054905b6008811015610b105783610a7b816119e4565b600188015490955061ffff1685119050610b1057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610afd5780888781518110610ad657610ad66119fd565b6001600160e01b03199092166020928302919091019091015285610af9816119e4565b9650505b5080610b08816119e4565b915050610a68565b50508080610b1d906119e4565b915050610a45565b5050825250919050565b6000610b39610c5c565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610b64610ccc565b6001600160a01b0316336001600160a01b031614610b9557604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f81565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003610bed5760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610cc9576102a8610e93565b90565b6000610cd6610c1b565b546001600160a01b0316919050565b6000610cef610c5c565b600181015490915061ffff811690819060009060071615610d225750600381901c60009081526002840160205260409020545b60005b8751811015610e07576000888281518110610d4257610d426119fd565b60200260200101519050600081602001519050816040015151600003610d7b5760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610d8f57610d8f611a32565b03610daa57610da087868685610f8a565b9095509350610dfd565b6001816002811115610dbe57610dbe611a32565b03610dd257610dcd87836110c9565b610dfd565b6002816002811115610de657610de6611a32565b03610dfd57610df787868685611214565b90955093505b5050600101610d25565b50828214610e235760018401805461ffff191661ffff84161790555b6007821615610e4557600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610e7893929190611a98565b60405180910390a1610e8a8686611437565b50505050505050565b6000610e9d610c5c565b600301546001600160a01b0316919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610cd6565b6000610ee1610c1b565b805460405191925033916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3610f278133610c3f565b6109e060007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b90610c3f565b80610f5d610c5c565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b6109e08161151b565b805160009081906001600160a01b03163014801590610fb2575082516001600160a01b03163b155b15610fd057604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156110bc57600084604001518281518110610ff857610ff86119fd565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561104457604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036110ad57600389901c600090815260028b0160205260408120989098555b50505060019586019501610fd3565b5093959294509192505050565b80516001600160a01b03163b6110f257604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101561120f5760008260400151828151811061111a5761111a6119fd565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80611166576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160361118f5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b0316036111c5576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016110f5565b505050565b805160009081906001600160a01b03161561124257604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561142357600086604001518281518110611273576112736119fd565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c6112be576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112e25760405163e983573160e01b815260040160405180910390fd5b600089900361130e57600019909401600081815260028c01602052604090205498509360079350611316565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161461136d576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146113d057600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556113f4565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361141257600088815260028f01602052604081208190559b505b50506001909301925061124e915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611463576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611517576001600160a01b03821630146114aa576001600160a01b0382163b6114aa57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516114c49190611b61565b600060405180830381855af49150503d80600081146114ff576040519150601f19603f3d011682016040523d82523d6000602084013e611504565b606091505b505090508061120f573d6000803e3d6000fd5b5050565b6109e0816109e0817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610f4e565b80356001600160e01b03198116811461156157600080fd5b919050565b60006020828403121561157857600080fd5b61158182611549565b9392505050565b80356001600160a01b038116811461156157600080fd5b60008083601f8401126115b157600080fd5b50813567ffffffffffffffff8111156115c957600080fd5b6020830191508360208285010111156115e157600080fd5b9250929050565b60008060008060006060868803121561160057600080fd5b853567ffffffffffffffff8082111561161857600080fd5b818801915088601f83011261162c57600080fd5b81358181111561163b57600080fd5b8960208260051b850101111561165057600080fd5b6020830197508096505061166660208901611588565b9450604088013591508082111561167c57600080fd5b506116898882890161159f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160a01b0316835292840192918401916001016116b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156117215781516001600160e01b031916875295820195908201906001016116fb565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561179b57888303603f19018552815180516001600160a01b03168452870151878401879052611788878501826116e7565b9588019593505090860190600101611753565b509098975050505050505050565b6000602082840312156117bb57600080fd5b61158182611588565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160e01b031916835292840192918401916001016117e0565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561183f5761183f611806565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561186e5761186e611806565b604052919050565b600067ffffffffffffffff82111561189057611890611806565b5060051b60200190565b60006118ad6118a884611876565b611845565b83815260208082019190600586811b8601368111156118cb57600080fd5b865b818110156119c157803567ffffffffffffffff808211156118ee5760008081fd5b818a019150606082360312156119045760008081fd5b61190c61181c565b61191583611588565b815286830135600381106119295760008081fd5b81880152604083810135838111156119415760008081fd5b939093019236601f85011261195857600092508283fd5b833592506119686118a884611876565b83815292871b840188019288810190368511156119855760008081fd5b948901945b848610156119aa5761199b86611549565b8252948901949089019061198a565b9183019190915250885250509483019483016118cd565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016119f6576119f66119ce565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611a2957611a296119ce565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611a63578181015183820152602001611a4b565b50506000910152565b60008151808452611a84816020860160208601611a48565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611b3157898703607f19018652825180516001600160a01b031688528481015160038110611b0257634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611b1e898901826116e7565b9750509483019491830191600101611ac2565b5050506001600160a01b0389169087015250508381036040850152611b568186611a6c565b979650505050505050565b60008251611b73818460208701611a48565b919091019291505056fea2646970667358221220e6ba1a829f238e956234ed1df418dca0ea2a0c19e82b065a572653d163f5504264736f6c63430008100033

Deployed Bytecode

0x6080604052600436106100ab5760003560e01c80638ab5150a116100645780638ab5150a146101e75780638da5cb5b146101fc5780639142376514610211578063adfca15e14610231578063cdffacc61461025e578063f2fde38b1461027e576100b2565b806301ffc9a71461010c5780631f931c1c146101415780632c4080591461016157806352ef6b2c1461018e57806379ba5097146101b05780637a0ed627146101c5576100b2565b366100b257005b60006100bc61029e565b90506001600160a01b0381163b6100e6576040516321f27f0d60e21b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610105573d6000f35b3d6000fd5b005b34801561011857600080fd5b5061012c610127366004611566565b6102b3565b60405190151581526020015b60405180910390f35b34801561014d57600080fd5b5061010a61015c3660046115e8565b6102e8565b34801561016d57600080fd5b50610176610372565b6040516001600160a01b039091168152602001610138565b34801561019a57600080fd5b506101a361037c565b604051610138919061169a565b3480156101bc57600080fd5b5061010a61051f565b3480156101d157600080fd5b506101da610562565b604051610138919061172c565b3480156101f357600080fd5b5061017661098a565b34801561020857600080fd5b50610176610994565b34801561021d57600080fd5b5061010a61022c3660046117a9565b61099e565b34801561023d57600080fd5b5061025161024c3660046117a9565b6109e3565b60405161013891906117c4565b34801561026a57600080fd5b50610176610279366004611566565b610b2f565b34801561028a57600080fd5b5061010a6102993660046117a9565b610b5c565b60006102a8610c80565b905090565b3b151590565b60006102e2826102c1610b9e565b906001600160e01b0319166000908152602091909152604090205460ff1690565b92915050565b6102f0610ccc565b6001600160a01b0316336001600160a01b03161461032157604051632f7a8ee160e01b815260040160405180910390fd5b61036b61032e858761189a565b8484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610ce592505050565b5050505050565b60006102a8610e93565b60606000610388610c5c565b600181015490915061ffff1667ffffffffffffffff8111156103ac576103ac611806565b6040519080825280602002602001820160405280156103d5578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610517576000818152600285016020526040812054905b60088110156105025783610414816119e4565b600188015490955061ffff168511905061050257600581901b82901b6001600160e01b0319811660009081526020889052604081205460601c90805b888110156104a5578a818151811061046a5761046a6119fd565b60200260200101516001600160a01b0316836001600160a01b03160361049357600191506104a5565b8061049d816119e4565b915050610450565b5080156104b4575050506104f0565b818a89815181106104c7576104c76119fd565b6001600160a01b0390921660209283029190910190910152876104e9816119e4565b9850505050505b806104fa816119e4565b915050610401565b5050808061050f906119e4565b9150506103de565b505082525090565b610527610eaf565b6001600160a01b0316336001600160a01b0316146105585760405163efd1052d60e01b815260040160405180910390fd5b610560610ed7565b565b6060600061056e610c5c565b600181015490915061ffff1667ffffffffffffffff81111561059257610592611806565b6040519080825280602002602001820160405280156105d857816020015b6040805180820190915260008152606060208201528152602001906001900390816105b05790505b50600182015490925060009061ffff1667ffffffffffffffff81111561060057610600611806565b604051908082528060200260200182016040528015610629578160200160208202803683370190505b50905060008060005b600185015461ffff16821015610918576000818152600286016020526040812054905b60088110156109035783610668816119e4565b600189015490955061ffff168511905061090357600581901b82901b6001600160e01b0319811660009081526020899052604081205460601c90805b888110156107c157826001600160a01b03168c82815181106106c8576106c86119fd565b6020026020010151600001516001600160a01b0316036107af57838c82815181106106f5576106f56119fd565b6020026020010151602001518b8381518110610713576107136119fd565b602002602001015160ff168151811061072e5761072e6119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060ff8a8281518110610764576107646119fd565b602002602001015160ff161061077957600080fd5b89818151811061078b5761078b6119fd565b6020026020010180518091906107a090611a13565b60ff16905250600191506107c1565b806107b9816119e4565b9150506106a4565b5080156107d0575050506108f1565b818b89815181106107e3576107e36119fd565b60209081029190910101516001600160a01b03909116905260018a015461ffff1667ffffffffffffffff81111561081c5761081c611806565b604051908082528060200260200182016040528015610845578160200160208202803683370190505b508b8981518110610858576108586119fd565b602002602001015160200181905250828b898151811061087a5761087a6119fd565b602002602001015160200151600081518110610898576108986119fd565b60200260200101906001600160e01b03191690816001600160e01b0319168152505060018989815181106108ce576108ce6119fd565b60ff90921660209283029190910190910152876108ea816119e4565b9850505050505b806108fb816119e4565b915050610655565b50508080610910906119e4565b915050610632565b5060005b8281101561097f576000848281518110610938576109386119fd565b602002602001015160ff1690506000878381518110610959576109596119fd565b602002602001015160200151905081815250508080610977906119e4565b91505061091c565b508185525050505090565b60006102a8610eaf565b60006102a8610ccc565b6109a6610ccc565b6001600160a01b0316336001600160a01b0316146109d757604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f54565b50565b606060006109ef610c5c565b600181015490915061ffff1667ffffffffffffffff811115610a1357610a13611806565b604051908082528060200260200182016040528015610a3c578160200160208202803683370190505b50915060008060005b600184015461ffff16821015610b25576000818152600285016020526040812054905b6008811015610b105783610a7b816119e4565b600188015490955061ffff1685119050610b1057600581901b82901b6001600160e01b0319811660009081526020889052604090205460601c6001600160a01b038a1603610afd5780888781518110610ad657610ad66119fd565b6001600160e01b03199092166020928302919091019091015285610af9816119e4565b9650505b5080610b08816119e4565b915050610a68565b50508080610b1d906119e4565b915050610a45565b5050825250919050565b6000610b39610c5c565b6001600160e01b0319909216600090815260209290925250604090205460601c90565b610b64610ccc565b6001600160a01b0316336001600160a01b031614610b9557604051632f7a8ee160e01b815260040160405180910390fd5b6109e081610f81565b7f326d0c59a7612f6a9919e2a8ee333c80ba689d8ba2634de89c85cbb04832e70590565b6001600160e01b03198083169003610bed5760405163f31e8ca960e01b815260040160405180910390fd5b6001600160e01b03199190911660009081526020929092526040909120805460ff1916911515919091179055565b7f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090565b81546001600160a01b0319166001600160a01b0391909116179055565b7f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc9390565b600080356001600160e01b03191681527f177481ac65e4292921c69f62d1cc7f57541261e5d61c8175cf4e36a01c9bfc93602052604090205460601c80610cc9576102a8610e93565b90565b6000610cd6610c1b565b546001600160a01b0316919050565b6000610cef610c5c565b600181015490915061ffff811690819060009060071615610d225750600381901c60009081526002840160205260409020545b60005b8751811015610e07576000888281518110610d4257610d426119fd565b60200260200101519050600081602001519050816040015151600003610d7b5760405163eb6c3aeb60e01b815260040160405180910390fd5b6000816002811115610d8f57610d8f611a32565b03610daa57610da087868685610f8a565b9095509350610dfd565b6001816002811115610dbe57610dbe611a32565b03610dd257610dcd87836110c9565b610dfd565b6002816002811115610de657610de6611a32565b03610dfd57610df787868685611214565b90955093505b5050600101610d25565b50828214610e235760018401805461ffff191661ffff84161790555b6007821615610e4557600382901c600090815260028501602052604090208190555b7f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673878787604051610e7893929190611a98565b60405180910390a1610e8a8686611437565b50505050505050565b6000610e9d610c5c565b600301546001600160a01b0316919050565b60007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610cd6565b6000610ee1610c1b565b805460405191925033916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3610f278133610c3f565b6109e060007f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce66178905b90610c3f565b80610f5d610c5c565b60030180546001600160a01b0319166001600160a01b039290921691909117905550565b6109e08161151b565b805160009081906001600160a01b03163014801590610fb2575082516001600160a01b03163b155b15610fd057604051633ddc5cab60e21b815260040160405180910390fd5b60005b8360400151518110156110bc57600084604001518281518110610ff857610ff86119fd565b6020908102919091018101516001600160e01b031981166000908152918a9052604090912054909150606081901c1561104457604051634923a77160e11b815260040160405180910390fd5b85516001600160e01b0319838116600081815260208d90526040902060609390931b6001600160601b0319168b1790925560058a901b60e090811692831c91831c199990991617978190036110ad57600389901c600090815260028b0160205260408120989098555b50505060019586019501610fd3565b5093959294509192505050565b80516001600160a01b03163b6110f257604051633ddc5cab60e21b815260040160405180910390fd5b60005b81604001515181101561120f5760008260400151828151811061111a5761111a6119fd565b6020908102919091018101516001600160e01b03198116600090815291869052604090912054909150606081901c80611166576040516337e25a9760e11b815260040160405180910390fd5b306001600160a01b0382160361118f5760405163e983573160e01b815260040160405180910390fd5b84600001516001600160a01b0316816001600160a01b0316036111c5576040516330baabf360e11b815260040160405180910390fd5b5083516001600160e01b031992909216600090815260208690526040902060609290921b6001600160601b0319166bffffffffffffffffffffffff919091161790556001016110f5565b505050565b805160009081906001600160a01b03161561124257604051633ab3490960e21b815260040160405180910390fd5b600385901c6007861660005b85604001515181101561142357600086604001518281518110611273576112736119fd565b6020908102919091018101516001600160e01b031981166000908152918c9052604090912054909150606081901c6112be576040516337e25a9760e11b815260040160405180910390fd5b30606082901c036112e25760405163e983573160e01b815260040160405180910390fd5b600089900361130e57600019909401600081815260028c01602052604090205498509360079350611316565b600019909301925b600584901b89901b6000806001600160e01b03198084169086161461136d576001600160e01b03198316600090815260208f90526040902080546001600160601b0319166bffffffffffffffffffffffff86161790555b50506001600160e01b03198316600090815260208d90526040812055611fff600383901c1660e0600584901b168782146113d057600082815260028f016020526040902080546001600160e01b031980841c19909116908516831c1790556113f4565b80836001600160e01b031916901c816001600160e01b031960001b901c198d16179b505b8660000361141257600088815260028f01602052604081208190559b505b50506001909301925061124e915050565b5060039190911b1796939550929350505050565b8051156001600160a01b0383161514611463576040516326df4ccd60e01b815260040160405180910390fd5b6001600160a01b03821615611517576001600160a01b03821630146114aa576001600160a01b0382163b6114aa57604051633ddc5cab60e21b815260040160405180910390fd5b6000826001600160a01b0316826040516114c49190611b61565b600060405180830381855af49150503d80600081146114ff576040519150601f19603f3d011682016040523d82523d6000602084013e611504565b606091505b505090508061120f573d6000803e3d6000fd5b5050565b6109e0816109e0817f24aa1f7b31fd188a8d3ecfb06bc55c806040e59b03bd4396283442fce6617890610f4e565b80356001600160e01b03198116811461156157600080fd5b919050565b60006020828403121561157857600080fd5b61158182611549565b9392505050565b80356001600160a01b038116811461156157600080fd5b60008083601f8401126115b157600080fd5b50813567ffffffffffffffff8111156115c957600080fd5b6020830191508360208285010111156115e157600080fd5b9250929050565b60008060008060006060868803121561160057600080fd5b853567ffffffffffffffff8082111561161857600080fd5b818801915088601f83011261162c57600080fd5b81358181111561163b57600080fd5b8960208260051b850101111561165057600080fd5b6020830197508096505061166660208901611588565b9450604088013591508082111561167c57600080fd5b506116898882890161159f565b969995985093965092949392505050565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160a01b0316835292840192918401916001016116b6565b50909695505050505050565b600081518084526020808501945080840160005b838110156117215781516001600160e01b031916875295820195908201906001016116fb565b509495945050505050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b8381101561179b57888303603f19018552815180516001600160a01b03168452870151878401879052611788878501826116e7565b9588019593505090860190600101611753565b509098975050505050505050565b6000602082840312156117bb57600080fd5b61158182611588565b6020808252825182820181905260009190848201906040850190845b818110156116db5783516001600160e01b031916835292840192918401916001016117e0565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561183f5761183f611806565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561186e5761186e611806565b604052919050565b600067ffffffffffffffff82111561189057611890611806565b5060051b60200190565b60006118ad6118a884611876565b611845565b83815260208082019190600586811b8601368111156118cb57600080fd5b865b818110156119c157803567ffffffffffffffff808211156118ee5760008081fd5b818a019150606082360312156119045760008081fd5b61190c61181c565b61191583611588565b815286830135600381106119295760008081fd5b81880152604083810135838111156119415760008081fd5b939093019236601f85011261195857600092508283fd5b833592506119686118a884611876565b83815292871b840188019288810190368511156119855760008081fd5b948901945b848610156119aa5761199b86611549565b8252948901949089019061198a565b9183019190915250885250509483019483016118cd565b5092979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016119f6576119f66119ce565b5060010190565b634e487b7160e01b600052603260045260246000fd5b600060ff821660ff8103611a2957611a296119ce565b60010192915050565b634e487b7160e01b600052602160045260246000fd5b60005b83811015611a63578181015183820152602001611a4b565b50506000910152565b60008151808452611a84816020860160208601611a48565b601f01601f19169290920160200192915050565b6000606080830181845280875180835260808601915060808160051b87010192506020808a016000805b84811015611b3157898703607f19018652825180516001600160a01b031688528481015160038110611b0257634e487b7160e01b84526021600452602484fd5b88860152604090810151908801899052611b1e898901826116e7565b9750509483019491830191600101611ac2565b5050506001600160a01b0389169087015250508381036040850152611b568186611a6c565b979650505050505050565b60008251611b73818460208701611a48565b919091019291505056fea2646970667358221220e6ba1a829f238e956234ed1df418dca0ea2a0c19e82b065a572653d163f5504264736f6c63430008100033

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

OVERVIEW

[Welcome home. 10.000 composable places stored on the Ethereum Blockchain.](https://scapes.xyz/scapes)

Loading...
Loading
[ Download: CSV Export  ]
[ 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.