Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0xD2c83AB0bee469ab5853c1e60bf8B663094EDca5
Balance 0 ETH
Nonce 1
Code Size 5035 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

5035 bytes
0x60806040523661000b57005b60006100156100aa565b600080357fffffffff000000000000000000000000000000000000000000000000000000001681526020829052604090205490915073ffffffffffffffffffffffffffffffffffffffff16806100865760405162461bcd60e51b815260040161007d90610fb9565b60405180910390fd5b3660008037600080366000845af43d6000803e8080156100a5573d6000f35b3d6000fd5b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c90565b60006100d86100aa565b60010154905060005b845181101561011157610107828683815181106100fa57fe5b6020026020010151610222565b91506001016100e1565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb67384848460405161014593929190610beb565b60405180910390a161015783836103bc565b50505050565b60006101676100aa565b600381015490915073ffffffffffffffffffffffffffffffffffffffff9081169083168114156101a95760405162461bcd60e51b815260040161007d9061121c565b6003820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff85811691821790925560405190918316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b600080826040015151116102485760405162461bcd60e51b815260040161007d90610f5c565b60008260200151600281111561025a57fe5b14156102cb57815173ffffffffffffffffffffffffffffffffffffffff166102945760405162461bcd60e51b815260040161007d90610ea2565b6102ba82600001516040518060600160405280602481526020016113526024913961050a565b6102c4838361052b565b90506103b6565b6001826020015160028111156102dd57fe5b141561034757815173ffffffffffffffffffffffffffffffffffffffff166103175760405162461bcd60e51b815260040161007d90610d8b565b61033d826000015160405180606001604052806027815260200161132b6027913961050a565b6102c483836106f6565b60028260200151600281111561035957fe5b141561039e57815173ffffffffffffffffffffffffffffffffffffffff16156103945760405162461bcd60e51b815260040161007d90610fee565b6102c48383610889565b60405162461bcd60e51b815260040161007d90610eff565b92915050565b73ffffffffffffffffffffffffffffffffffffffff82166103fb578051156103f65760405162461bcd60e51b815260040161007d90610de8565b610506565b600081511161041c5760405162461bcd60e51b815260040161007d9061104b565b73ffffffffffffffffffffffffffffffffffffffff8216301461045b5761045b826040518060600160405280602881526020016113036028913961050a565b6000808373ffffffffffffffffffffffffffffffffffffffff16836040516104839190610bcf565b600060405180830381855af49150503d80600081146104be576040519150601f19603f3d011682016040523d82523d6000602084013e6104c3565b606091505b509150915081610157578051156104ee578060405162461bcd60e51b815260040161007d9190610d14565b60405162461bcd60e51b815260040161007d90610d2e565b5050565b813b81816101575760405162461bcd60e51b815260040161007d9190610d14565b6000806105366100aa565b905060005b8360400151518110156106ed5760008460400151828151811061055a57fe5b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff1680156105cf5760405162461bcd60e51b815260040161007d906110a8565b50604080518082018252865173ffffffffffffffffffffffffffffffffffffffff908116825261ffff89811660208085019182527fffffffff00000000000000000000000000000000000000000000000000000000871660009081528982529586209451855492517fffffffffffffffffffffffff00000000000000000000000000000000000000009093169416939093177fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000919092160217909155600180860180548083018255908452919092206008820401805463ffffffff60079093166004026101000a928302191660e09490941c9190910292909217909155948501940161053b565b50929392505050565b6000806107016100aa565b905060005b8360400151518110156106ed5760008460400151828151811061072557fe5b6020908102919091018101517fffffffff00000000000000000000000000000000000000000000000000000000811660009081529185905260409091205490915073ffffffffffffffffffffffffffffffffffffffff163081141561079c5760405162461bcd60e51b815260040161007d90611162565b855173ffffffffffffffffffffffffffffffffffffffff828116911614156107d65760405162461bcd60e51b815260040161007d90611105565b73ffffffffffffffffffffffffffffffffffffffff81166108095760405162461bcd60e51b815260040161007d90611279565b5084517fffffffff0000000000000000000000000000000000000000000000000000000091909116600090815260208490526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055600101610706565b6000806108946100aa565b905060005b8360400151518110156106ed576000846040015182815181106108b857fe5b6020908102919091018101517fffffffff000000000000000000000000000000000000000000000000000000008116600090815285835260409081902081518083019092525473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910461ffff16938201939093529092509061095c5760405162461bcd60e51b815260040161007d90610e45565b805173ffffffffffffffffffffffffffffffffffffffff163014156109935760405162461bcd60e51b815260040161007d906111bf565b60018703816020015161ffff1614610aab5760008460010160018903815481106109b957fe5b90600052602060002090600891828204019190066004029054906101000a900460e01b90508085600101836020015161ffff16815481106109f657fe5b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c92909202939093179055838201517fffffffff00000000000000000000000000000000000000000000000000000000939093168152908690526040902080547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000061ffff909316929092029190911790555b83600101805480610ab857fe5b6000828152602080822060087fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff948501908104909101805463ffffffff600460078516026101000a02191690559093557fffffffff00000000000000000000000000000000000000000000000000000000909416845290859052604090922080547fffffffffffffffffffff00000000000000000000000000000000000000000000169055509490940193600101610899565b73ffffffffffffffffffffffffffffffffffffffff169052565b60008151808452610b9d8160208601602086016112d6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251610be18184602087016112d6565b9190910192915050565b606080825284518282018190526000919060809081850190602080820287018401818b01875b84811015610ce5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808a8403018652815188840173ffffffffffffffffffffffffffffffffffffffff82511685528582015160038110610c6d57fe5b858701526040918201519185018a9052815190819052908501908a90898601905b80831015610cd05783517fffffffff00000000000000000000000000000000000000000000000000000000168252928701926001929092019190870190610c8e565b50978601979450505090830190600101610c11565b5050610cf38289018b610b6b565b8781036040890152610d05818a610b85565b9b9a5050505050505050505050565b600060208252610d276020830184610b85565b9392505050565b60208082526026908201527f4c69624469616d6f6e644375743a205f696e69742066756e6374696f6e20726560408201527f7665727465640000000000000000000000000000000000000000000000000000606082015260800190565b60208082526034908201527f4c69624469616d6f6e643a2072656d6f7665206661636574206164647265737360408201527f2063616e27742062652061646472657373283029000000000000000000000000606082015260800190565b6020808252603d908201527f4c69624469616d6f6e644375743a205f696e697420697320616464726573732860408201527f302920627574205f63616c6c64617461206973206e6f7420656d707479000000606082015260800190565b60208082526037908201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360408201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606082015260800190565b60208082526031908201527f4c69624469616d6f6e643a20616464206661636574206164647265737320636160408201527f6e27742062652061646472657373283029000000000000000000000000000000606082015260800190565b60208082526027908201527f4c69624469616d6f6e644375743a20496e636f7272656374204661636574437560408201527f74416374696f6e00000000000000000000000000000000000000000000000000606082015260800190565b60208082526028908201527f4c69624469616d6f6e643a204e6f2073656c6563746f727320696e206661636560408201527f7420746f20637574000000000000000000000000000000000000000000000000606082015260800190565b6020808252818101527f4469616d6f6e643a2046756e6374696f6e20646f6573206e6f74206578697374604082015260600190565b60208082526033908201527f4c69624469616d6f6e643a2072656d6f7665206661636574206164647265737360408201527f206d757374206265206164647265737328302900000000000000000000000000606082015260800190565b6020808252603d908201527f4c69624469616d6f6e644375743a205f63616c6c6461746120697320656d707460408201527f7920627574205f696e6974206973206e6f742061646472657373283029000000606082015260800190565b60208082526035908201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60408201527f6e207468617420616c7265616479206578697374730000000000000000000000606082015260800190565b60208082526038908201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60408201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606082015260800190565b6020808252602f908201527f4c69624469616d6f6e644375743a2043616e2774207265706c61636520696d6d60408201527f757461626c652066756e6374696f6e0000000000000000000000000000000000606082015260800190565b6020808252602f908201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560408201527f7461626c652066756e6374696f6e2e0000000000000000000000000000000000606082015260800190565b6020808252602e908201527f50726576696f7573206f776e657220616e64206e6577206f776e6572206d757360408201527f7420626520646966666572656e74000000000000000000000000000000000000606082015260800190565b60208082526038908201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60408201527f6374696f6e207468617420646f65736e27742065786973740000000000000000606082015260800190565b60005b838110156112f15781810151838201526020016112d9565b83811115610157575050600091015256fe4c69624469616d6f6e644375743a205f696e6974206164647265737320686173206e6f20636f64654c69624469616d6f6e643a2072656d6f7665206661636574206d757374206861766520636f64654c69624469616d6f6e643a20616464206661636574206d757374206861766520636f6465a2646970667358221220582f742bbefd962f9cb5c6cfdca42c1b142d616c0d4ad69ae664221c93197e3264736f6c63430007060033

Verified Source Code Full Match

Compiler: v0.7.6+commit.7338295f EVM: istanbul Optimization: Yes (9999 runs)
Kernel.sol 52 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "./interfaces/IDiamondCut.sol";
import "./interfaces/IDiamondLoupe.sol";
import "./libraries/LibDiamond.sol";
import "./libraries/LibOwnership.sol";
import "./libraries/LibDiamondStorage.sol";
import "./interfaces/IERC165.sol";
import "./interfaces/IERC173.sol";

contract Kernel {
    constructor(IDiamondCut.FacetCut[] memory _diamondCut, address _owner) payable {
        require(_owner != address(0), "owner must not be 0x0");

        LibDiamond.diamondCut(_diamondCut, address(0), new bytes(0));
        LibOwnership.setContractOwner(_owner);

        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        // adding ERC165 data
        ds.supportedInterfaces[type(IERC165).interfaceId] = true;
        ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
        ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
        ds.supportedInterfaces[type(IERC173).interfaceId] = true;
    }

    // Find facet for function that is called and execute the
    // function if a facet is found and return any value.
    fallback() external payable {
        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        address facet = address(bytes20(ds.facets[msg.sig].facetAddress));
        require(facet != address(0), "Diamond: Function does not exist");

        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return (0, returndatasize())
            }
        }
    }

    receive() external payable {}
}
IERC165.sol 13 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

interface IERC165 {
    /// @notice Query if a contract implements an interface
    /// @param interfaceId The interface identifier, as specified in ERC-165
    /// @dev Interface identification is specified in ERC-165. This function
    ///  uses less than 30,000 gas.
    /// @return `true` if the contract implements `interfaceID` and
    ///  `interfaceID` is not 0xffffffff, `false` otherwise
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
IERC173.sol 19 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;

/// @title ERC-173 Contract Ownership Standard
///  Note: the ERC-165 identifier for this interface is 0x7f5828d0
/* is ERC165 */
interface IERC173 {
    /// @dev This emits when ownership of a contract changes.
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Get the address of the owner
    /// @return owner_ The address of the owner.
    function owner() external view returns (address owner_);

    /// @notice Set the address of the new owner of the contract
    /// @dev Set _newOwner to address(0) to renounce any ownership.
    /// @param _newOwner The address of the new owner of the contract
    function transferOwnership(address _newOwner) external;
}
LibDiamond.sol 168 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "../interfaces/IDiamondCut.sol";
import "./LibDiamondStorage.sol";

library LibDiamond {
    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    // Internal function version of diamondCut
    // This code is almost the same as the external diamondCut,
    // except it is using 'Facet[] memory _diamondCut' instead of
    // 'Facet[] calldata _diamondCut'.
    // The code is duplicated to prevent copying calldata to memory which
    // causes an error for a two dimensional array.
    function diamondCut(
        IDiamondCut.FacetCut[] memory _diamondCut,
        address _init,
        bytes memory _calldata
    ) internal {
        uint256 selectorCount = LibDiamondStorage.diamondStorage().selectors.length;

        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            selectorCount = executeDiamondCut(selectorCount, _diamondCut[facetIndex]);
        }

        emit DiamondCut(_diamondCut, _init, _calldata);

        initializeDiamondCut(_init, _calldata);
    }

    // executeDiamondCut takes one single FacetCut action and executes it
    // if FacetCutAction can't be identified, it reverts
    function executeDiamondCut(uint256 selectorCount, IDiamondCut.FacetCut memory cut) internal returns (uint256) {
        require(cut.functionSelectors.length > 0, "LibDiamond: No selectors in facet to cut");

        if (cut.action == IDiamondCut.FacetCutAction.Add) {
            require(cut.facetAddress != address(0), "LibDiamond: add facet address can't be address(0)");
            enforceHasContractCode(cut.facetAddress, "LibDiamond: add facet must have code");

            return _handleAddCut(selectorCount, cut);
        }

        if (cut.action == IDiamondCut.FacetCutAction.Replace) {
            require(cut.facetAddress != address(0), "LibDiamond: remove facet address can't be address(0)");
            enforceHasContractCode(cut.facetAddress, "LibDiamond: remove facet must have code");

            return _handleReplaceCut(selectorCount, cut);
        }

        if (cut.action == IDiamondCut.FacetCutAction.Remove) {
            require(cut.facetAddress == address(0), "LibDiamond: remove facet address must be address(0)");

            return _handleRemoveCut(selectorCount, cut);
        }

        revert("LibDiamondCut: Incorrect FacetCutAction");
    }

    // _handleAddCut executes a cut with the type Add
    // it reverts if the selector already exists
    function _handleAddCut(uint256 selectorCount, IDiamondCut.FacetCut memory cut) internal returns (uint256) {
        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        for (uint256 selectorIndex; selectorIndex < cut.functionSelectors.length; selectorIndex++) {
            bytes4 selector = cut.functionSelectors[selectorIndex];

            address oldFacetAddress = ds.facets[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");

            ds.facets[selector] = LibDiamondStorage.Facet(
                cut.facetAddress,
                uint16(selectorCount)
            );
            ds.selectors.push(selector);

            selectorCount++;
        }

        return selectorCount;
    }

    // _handleReplaceCut executes a cut with the type Replace
    // it does not allow replacing immutable functions
    // it does not allow replacing with the same function
    // it does not allow replacing a function that does not exist
    function _handleReplaceCut(uint256 selectorCount, IDiamondCut.FacetCut memory cut) internal returns (uint256) {
        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        for (uint256 selectorIndex; selectorIndex < cut.functionSelectors.length; selectorIndex++) {
            bytes4 selector = cut.functionSelectors[selectorIndex];

            address oldFacetAddress = ds.facets[selector].facetAddress;

            // only useful if immutable functions exist
            require(oldFacetAddress != address(this), "LibDiamondCut: Can't replace immutable function");
            require(oldFacetAddress != cut.facetAddress, "LibDiamondCut: Can't replace function with same function");
            require(oldFacetAddress != address(0), "LibDiamondCut: Can't replace function that doesn't exist");

            // replace old facet address
            ds.facets[selector].facetAddress = cut.facetAddress;
        }

        return selectorCount;
    }

    // _handleRemoveCut executes a cut with the type Remove
    // for efficiency, the selector to be deleted is replaced with the last one and then the last one is popped
    // it reverts if the function doesn't exist or it's immutable
    function _handleRemoveCut(uint256 selectorCount, IDiamondCut.FacetCut memory cut) internal returns (uint256) {
        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        for (uint256 selectorIndex; selectorIndex < cut.functionSelectors.length; selectorIndex++) {
            bytes4 selector = cut.functionSelectors[selectorIndex];

            LibDiamondStorage.Facet memory oldFacet = ds.facets[selector];

            require(oldFacet.facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
            require(oldFacet.facetAddress != address(this), "LibDiamondCut: Can't remove immutable function.");

            // replace selector with last selector
            if (oldFacet.selectorPosition != selectorCount - 1) {
                bytes4 lastSelector = ds.selectors[selectorCount - 1];
                ds.selectors[oldFacet.selectorPosition] = lastSelector;
                ds.facets[lastSelector].selectorPosition = oldFacet.selectorPosition;
            }

            // delete last selector
            ds.selectors.pop();
            delete ds.facets[selector];

            selectorCount--;
        }

        return selectorCount;
    }

    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but _calldata is not empty");
            return;
        }

        require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
        if (_init != address(this)) {
            enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
        }

        (bool success, bytes memory error) = _init.delegatecall(_calldata);
        if (!success) {
            if (error.length > 0) {
                // bubble up the error
                revert(string(error));
            } else {
                revert("LibDiamondCut: _init function reverted");
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}
IDiamondCut.sol 28 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

interface IDiamondCut {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
LibOwnership.sol 33 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

import "./LibDiamondStorage.sol";

library LibOwnership {
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function setContractOwner(address _newOwner) internal {
        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();

        address previousOwner = ds.contractOwner;
        require(previousOwner != _newOwner, "Previous owner and new owner must be different");

        ds.contractOwner = _newOwner;

        emit OwnershipTransferred(previousOwner, _newOwner);
    }

    function contractOwner() internal view returns (address contractOwner_) {
        contractOwner_ = LibDiamondStorage.diamondStorage().contractOwner;
    }

    function enforceIsContractOwner() view internal {
        require(msg.sender == LibDiamondStorage.diamondStorage().contractOwner, "Must be contract owner");
    }

    modifier onlyOwner {
        require(msg.sender == LibDiamondStorage.diamondStorage().contractOwner, "Must be contract owner");
        _;
    }
}
IDiamondLoupe.sol 34 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

// A loupe is a small magnifying glass used to look at diamonds.
// These functions look at diamonds
interface IDiamondLoupe {
    /// These functions are expected to be called frequently
    /// by tools.

    struct Facet {
        address facetAddress;
        bytes4[] functionSelectors;
    }

    /// @notice Gets all facet addresses and their four byte function selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_);

    /// @notice Gets all the function selectors supported by a specific facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_);

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}
LibDiamondStorage.sol 31 lines
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;

library LibDiamondStorage {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    struct Facet {
        address facetAddress;
        uint16 selectorPosition;
    }

    struct DiamondStorage {
        // function selector => facet address and selector position in selectors array
        mapping(bytes4 => Facet) facets;
        bytes4[] selectors;

        // ERC165
        mapping(bytes4 => bool) supportedInterfaces;

        // owner of the contract
        address contractOwner;
    }

    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }
}

Recent Transactions

No transactions found for this address