{
  "contractName": "LibDiamondCut",
  "abi": [
    {
      "anonymous": false,
      "inputs": [
        {
          "components": [
            {
              "internalType": "address",
              "name": "facetAddress",
              "type": "address"
            },
            {
              "internalType": "bytes4[]",
              "name": "functionSelectors",
              "type": "bytes4[]"
            }
          ],
          "indexed": false,
          "internalType": "struct IDiamondCut.Facet[]",
          "name": "_diamondCut",
          "type": "tuple[]"
        },
        {
          "indexed": false,
          "internalType": "address",
          "name": "_init",
          "type": "address"
        },
        {
          "indexed": false,
          "internalType": "bytes",
          "name": "_calldata",
          "type": "bytes"
        }
      ],
      "name": "DiamondCut",
      "type": "event"
    }
  ],
  "bytecode": "0x60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a3c055dec4f8098c9d571fc490a0cea054ea38d297822d77bff41cd40ecf2d9b64736f6c63430007010033",
  "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fdfea2646970667358221220a3c055dec4f8098c9d571fc490a0cea054ea38d297822d77bff41cd40ecf2d9b64736f6c63430007010033",
  "linkReferences": {},
  "deployedLinkReferences": {},
  "metadata": "{\"compiler\":{\"version\":\"0.7.1+commit.f4a555be\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"facetAddress\",\"type\":\"address\"},{\"internalType\":\"bytes4[]\",\"name\":\"functionSelectors\",\"type\":\"bytes4[]\"}],\"indexed\":false,\"internalType\":\"struct IDiamondCut.Facet[]\",\"name\":\"_diamondCut\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_init\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_calldata\",\"type\":\"bytes\"}],\"name\":\"DiamondCut\",\"type\":\"event\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"solc_0.7/diamond/libraries/LibDiamondCut.sol\":\"LibDiamondCut\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":2000},\"remappings\":[]},\"sources\":{\"solc_0.7/diamond/interfaces/IDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.1;\\npragma experimental ABIEncoderV2;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\\n/******************************************************************************/\\n\\ninterface IDiamondCut {\\n    struct Facet {\\n        address facetAddress;\\n        bytes4[] functionSelectors;\\n    }\\n\\n    /// @notice Add/replace/remove any number of functions and optionally execute\\n    ///         a function with delegatecall\\n    /// @param _diamondCut Contains the facet addresses and function selectors\\n    /// @param _init The address of the contract or facet to execute _calldata\\n    /// @param _calldata A function call, including function selector and arguments\\n    ///                  _calldata is executed with delegatecall on _init\\n    function diamondCut(\\n        Facet[] calldata _diamondCut,\\n        address _init,\\n        bytes calldata _calldata\\n    ) external;\\n\\n    event DiamondCut(Facet[] _diamondCut, address _init, bytes _calldata);\\n}\\n\",\"keccak256\":\"0xba9cbedda8b486e17512639ee5ca6a4de1638b55c26b130e61cbbaa632acdef5\",\"license\":\"MIT\"},\"solc_0.7/diamond/libraries/LibDiamondCut.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.1;\\npragma experimental ABIEncoderV2;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\\n*\\n* Implementation of internal diamondCut function.\\n/******************************************************************************/\\n\\nimport \\\"./LibDiamondStorage.sol\\\";\\nimport \\\"../interfaces/IDiamondCut.sol\\\";\\n\\nlibrary LibDiamondCut {\\n    event DiamondCut(IDiamondCut.Facet[] _diamondCut, address _init, bytes _calldata);\\n\\n    // Non-standard internal function version of diamondCut\\n    // This code is almost the same as externalCut, except it is using\\n    // 'Facet[] memory _diamondCut' instead of 'Facet[] calldata _diamondCut'\\n    // and it DOES issue the DiamondCut event\\n    // The code is duplicated to prevent copying calldata to memory which\\n    // causes a Solidity error for a two dimensional array.\\n    function diamondCut(IDiamondCut.Facet[] memory _diamondCut) internal {\\n        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();\\n        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {\\n            address newFacetAddress = _diamondCut[facetIndex].facetAddress;\\n            // add or replace function\\n            if (newFacetAddress != address(0)) {\\n                uint256 facetAddressPosition = ds.facetFunctionSelectors[newFacetAddress].facetAddressPosition;\\n                // add new facet address if it does not exist\\n                if (facetAddressPosition == 0 && ds.facetFunctionSelectors[newFacetAddress].functionSelectors.length == 0) {\\n                    hasContractCode(newFacetAddress, \\\"LibDiamondCut: New facet has no code\\\");\\n                    facetAddressPosition = ds.facetAddresses.length;\\n                    ds.facetAddresses.push(newFacetAddress);\\n                    ds.facetFunctionSelectors[newFacetAddress].facetAddressPosition = uint16(facetAddressPosition);\\n                }\\n                // add or replace selectors\\n                for (uint256 selectorIndex; selectorIndex < _diamondCut[facetIndex].functionSelectors.length; selectorIndex++) {\\n                    bytes4 selector = _diamondCut[facetIndex].functionSelectors[selectorIndex];\\n                    address oldFacet = ds.selectorToFacetAndPosition[selector].facetAddress;\\n                    // add\\n                    if (oldFacet == address(0)) {\\n                        addSelector(newFacetAddress, selector);\\n                    } else {\\n                        // replace\\n                        if (oldFacet != newFacetAddress) {\\n                            removeSelector(selector);\\n                            addSelector(newFacetAddress, selector);\\n                        }\\n                    }\\n                }\\n            } else {\\n                // remove selectors\\n                for (uint256 selectorIndex; selectorIndex < _diamondCut[facetIndex].functionSelectors.length; selectorIndex++) {\\n                    removeSelector(_diamondCut[facetIndex].functionSelectors[selectorIndex]);\\n                }\\n            }\\n        }\\n        emit DiamondCut(_diamondCut, address(0), new bytes(0));\\n    }\\n\\n    function addSelector(address _newFacet, bytes4 _selector) internal {\\n        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();\\n        uint256 selectorPosition = ds.facetFunctionSelectors[_newFacet].functionSelectors.length;\\n        ds.facetFunctionSelectors[_newFacet].functionSelectors.push(_selector);\\n        ds.selectorToFacetAndPosition[_selector].facetAddress = _newFacet;\\n        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = uint16(selectorPosition);\\n    }\\n\\n    function removeSelector(bytes4 _selector) internal {\\n        LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage();\\n        address oldFacet = ds.selectorToFacetAndPosition[_selector].facetAddress;\\n        // if function does not exist then do nothing and return\\n        if (oldFacet == address(0)) {\\n            return;\\n        }\\n        // replace selector with last selector, then delete last selector\\n        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;\\n        uint256 lastSelectorPosition = ds.facetFunctionSelectors[oldFacet].functionSelectors.length - 1;\\n        bytes4 lastSelector = ds.facetFunctionSelectors[oldFacet].functionSelectors[lastSelectorPosition];\\n        // if not the same then replace _selector with lastSelector\\n        if (lastSelector != _selector) {\\n            ds.facetFunctionSelectors[oldFacet].functionSelectors[selectorPosition] = lastSelector;\\n            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint16(selectorPosition);\\n        }\\n        // delete the last selector\\n        ds.facetFunctionSelectors[oldFacet].functionSelectors.pop();\\n        delete ds.selectorToFacetAndPosition[_selector];\\n\\n        // if no more selectors for facet address then delete the facet address\\n        if (lastSelectorPosition == 0) {\\n            // replace facet address with last facet address and delete last facet address\\n            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;\\n            address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];\\n            uint256 facetAddressPosition = ds.facetFunctionSelectors[oldFacet].facetAddressPosition;\\n            if (oldFacet != lastFacetAddress) {\\n                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;\\n                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = uint16(facetAddressPosition);\\n            }\\n            ds.facetAddresses.pop();\\n            delete ds.facetFunctionSelectors[oldFacet];\\n        }\\n    }\\n\\n    function hasContractCode(address _contract, string memory _errorMessage) internal view {\\n        uint256 contractSize;\\n        assembly {\\n            contractSize := extcodesize(_contract)\\n        }\\n        require(contractSize > 0, _errorMessage);\\n    }\\n}\\n\",\"keccak256\":\"0x2b0552b7626a43189f62e6b8e7ac6e257a0d6ebe6f03a44d2da12c931a96155b\",\"license\":\"MIT\"},\"solc_0.7/diamond/libraries/LibDiamondStorage.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.7.1;\\npragma experimental ABIEncoderV2;\\n\\n/******************************************************************************\\\\\\n* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)\\n/******************************************************************************/\\n\\nlibrary LibDiamondStorage {\\n    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256(\\\"diamond.standard.diamond.storage\\\");\\n\\n    struct FacetAddressAndPosition {\\n        address facetAddress;\\n        uint16 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array\\n    }\\n\\n    struct FacetFunctionSelectors {\\n        bytes4[] functionSelectors;\\n        uint16 facetAddressPosition; // position of facetAddress in facetAddresses array\\n    }\\n\\n    struct DiamondStorage {\\n        // owner of the contract\\n        address contractOwner;\\n        // maps function selector to the facet address and        \\n        // the position of the selector in the facetFunctionSelectors.selectors array\\n        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;\\n        // maps facet addresses to function selectors\\n        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;\\n        // facet addresses\\n        address[] facetAddresses;\\n        // Used to query if a contract implements an interface.\\n        // Used to implement ERC-165.\\n        mapping(bytes4 => bool) supportedInterfaces;\\n    }\\n\\n    function diamondStorage() internal pure returns (DiamondStorage storage ds) {\\n        bytes32 position = DIAMOND_STORAGE_POSITION;\\n        assembly {\\n            ds.slot := position\\n        }\\n    }\\n}\\n\",\"keccak256\":\"0xe775d2cb83a52f9bc6341b6331acd86527a7870dca3193cfcad3db6206017ed2\",\"license\":\"MIT\"}},\"version\":1}",
  "contractFilepath": "solc_0.7/diamond/libraries/LibDiamondCut.sol",
  "methodIdentifiers": {},
  "gasEstimates": {
    "creation": {
      "codeDepositCost": "17200",
      "executionCost": "97",
      "totalCost": "17297"
    },
    "internal": {
      "addSelector(address,bytes4)": "infinite",
      "diamondCut(struct IDiamondCut.Facet memory[] memory)": "infinite",
      "hasContractCode(address,string memory)": "infinite",
      "removeSelector(bytes4)": "infinite"
    }
  },
  "storageLayout": {
    "storage": [],
    "types": null
  },
  "userdoc": {
    "kind": "user",
    "methods": {},
    "version": 1
  },
  "devdoc": {
    "kind": "dev",
    "methods": {},
    "version": 1
  }
}