Accounts
0x28...3a42
0x28...3a42

0x28...3a42

$500
This contract's source code is verified!
Contract Metadata
Compiler
0.8.24+commit.e11b9ed9
Language
Solidity
Contract Source Code
File 1 of 16: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}
Contract Source Code
File 2 of 16: Diamond.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces
import {IDiamond} from "./IDiamond.sol";

// libraries

// contracts
import {Proxy} from "./proxy/Proxy.sol";
import {DiamondCutBase} from "./facets/cut/DiamondCutBase.sol";
import {DiamondLoupeBase} from "./facets/loupe/DiamondLoupeBase.sol";
import {IntrospectionBase} from "./facets/introspection/IntrospectionBase.sol";
import {Initializable} from "./facets/initializable/Initializable.sol";

contract Diamond is
  IDiamond,
  Proxy,
  DiamondCutBase,
  DiamondLoupeBase,
  IntrospectionBase,
  Initializable
{
  struct InitParams {
    FacetCut[] baseFacets;
    address init;
    bytes initData;
  }

  constructor(InitParams memory initDiamondCut) initializer {
    _diamondCut(
      initDiamondCut.baseFacets,
      initDiamondCut.init,
      initDiamondCut.initData
    );
  }

  receive() external payable {}

  // =============================================================
  //                           Internal
  // =============================================================
  function _getImplementation()
    internal
    view
    virtual
    override
    returns (address facet)
  {
    facet = _facetAddress(msg.sig);
    if (facet == address(0)) revert Diamond_UnsupportedFunction();
  }
}
Contract Source Code
File 3 of 16: DiamondCutBase.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.24;

// interfaces
import {IDiamondCutBase} from "contracts/src/diamond/facets/cut/IDiamondCut.sol";
import {IDiamond} from "contracts/src/diamond/IDiamond.sol";

// libraries
import {DiamondCutStorage} from "./DiamondCutStorage.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

abstract contract DiamondCutBase is IDiamondCutBase {
  using EnumerableSet for EnumerableSet.AddressSet;
  using EnumerableSet for EnumerableSet.Bytes32Set;

  /// @dev Performs a diamond cut.
  function _diamondCut(
    IDiamond.FacetCut[] memory facetCuts,
    address init,
    bytes memory initPayload
  ) internal {
    if (facetCuts.length == 0) revert DiamondCut_InvalidFacetCutLength();

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

      _validateFacetCut(facetCut);

      if (facetCut.action == IDiamond.FacetCutAction.Add) {
        _addFacet(facetCut.facetAddress, facetCut.functionSelectors);
      } else if (facetCut.action == IDiamond.FacetCutAction.Replace) {
        _replaceFacet(facetCut.facetAddress, facetCut.functionSelectors);
      } else if (facetCut.action == IDiamond.FacetCutAction.Remove) {
        _removeFacet(facetCut.facetAddress, facetCut.functionSelectors);
      }
    }

    emit DiamondCut(facetCuts, init, initPayload);

    _initializeDiamondCut(facetCuts, init, initPayload);
  }

  ///@notice Add a new facet to the diamond
  ///@param facet The facet to add
  ///@param selectors The selectors for the facet
  function _addFacet(address facet, bytes4[] memory selectors) internal {
    DiamondCutStorage.Layout storage ds = DiamondCutStorage.layout();

    // add facet to diamond storage
    if (!ds.facets.contains(facet)) ds.facets.add(facet);

    uint256 selectorCount = selectors.length;

    // add selectors to diamond storage
    for (uint256 i; i < selectorCount; ) {
      bytes4 selector = selectors[i];

      if (selector == bytes4(0)) {
        revert DiamondCut_InvalidSelector();
      }

      if (ds.facetBySelector[selector] != address(0)) {
        revert DiamondCut_FunctionAlreadyExists(selector);
      }

      ds.facetBySelector[selector] = facet;
      ds.selectorsByFacet[facet].add(selector);

      unchecked {
        i++;
      }
    }
  }

  ///@notice Remove a facet from the diamond
  ///@param facet The facet to remove
  ///@param selectors The selectors for the facet
  function _removeFacet(address facet, bytes4[] memory selectors) internal {
    DiamondCutStorage.Layout storage ds = DiamondCutStorage.layout();

    if (facet == address(this)) revert DiamondCut_ImmutableFacet();

    if (!ds.facets.contains(facet)) revert DiamondCut_InvalidFacet(facet);

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

      if (selector == bytes4(0)) {
        revert DiamondCut_InvalidSelector();
      }

      if (ds.facetBySelector[selector] != facet) {
        revert DiamondCut_InvalidFacetRemoval(facet, selector);
      }

      delete ds.facetBySelector[selector];

      ds.selectorsByFacet[facet].remove(selector);
    }

    if (ds.selectorsByFacet[facet].length() == 0) {
      ds.facets.remove(facet);
    }
  }

  /// @notice Replace a facet on the diamond
  /// @param facet The new facet
  /// @param selectors The selectors for the facet
  function _replaceFacet(address facet, bytes4[] memory selectors) internal {
    DiamondCutStorage.Layout storage ds = DiamondCutStorage.layout();

    if (facet == address(this)) revert DiamondCut_ImmutableFacet();

    if (!ds.facets.contains(facet)) ds.facets.add(facet);

    uint256 selectorCount = selectors.length;

    for (uint256 i; i < selectorCount; ) {
      bytes4 selector = selectors[i];

      if (selector == bytes4(0)) {
        revert DiamondCut_InvalidSelector();
      }

      address oldFacet = ds.facetBySelector[selector];

      if (oldFacet == address(this)) revert DiamondCut_ImmutableFacet();

      if (oldFacet == address(0)) {
        revert DiamondCut_FunctionDoesNotExist(facet);
      }

      if (oldFacet == facet) {
        revert DiamondCut_FunctionFromSameFacetAlreadyExists(selector);
      }

      // overwrite selector to new facet
      ds.facetBySelector[selector] = facet;

      ds.selectorsByFacet[oldFacet].remove(selector);

      ds.selectorsByFacet[facet].add(selector);

      if (ds.selectorsByFacet[oldFacet].length() == 0) {
        ds.facets.remove(oldFacet);
      }

      unchecked {
        i++;
      }
    }
  }

  /// @notice Validate a facet cut
  /// @param facetCut The facet cut to validate
  function _validateFacetCut(IDiamond.FacetCut memory facetCut) internal view {
    if (facetCut.facetAddress == address(0)) {
      revert DiamondCut_InvalidFacet(facetCut.facetAddress);
    }

    if (
      facetCut.facetAddress != address(this) &&
      facetCut.facetAddress.code.length == 0
    ) {
      revert DiamondCut_InvalidFacet(facetCut.facetAddress);
    }

    if (facetCut.functionSelectors.length == 0) {
      revert DiamondCut_InvalidFacetSelectors(facetCut.facetAddress);
    }
  }

  /// @notice Initialize Diamond Cut Payload
  /// @param init The init address
  /// @param initPayload The init payload
  function _initializeDiamondCut(
    IDiamond.FacetCut[] memory,
    address init,
    bytes memory initPayload
  ) internal {
    if (init == address(0)) return;

    if (init.code.length == 0) {
      revert DiamondCut_InvalidContract(init);
    }

    Address.functionDelegateCall(init, initPayload);
  }
}
Contract Source Code
File 4 of 16: DiamondCutStorage.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

// contracts

library DiamondCutStorage {
  // keccak256(abi.encode(uint256(keccak256("diamond.facets.cut.storage")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 internal constant STORAGE_SLOT =
    0xc6b63261e9313602f31108199c5a3f80ebd1f09ec3eaeb70561a2265ce2fc900;

  /// @notice Facet cut struct
  /// @param facet Set of facets
  /// @param facetBySelector Mapping of function selectors to their facet
  /// @param selectorsByFacet Mapping of facet to function selectors
  struct Layout {
    EnumerableSet.AddressSet facets;
    mapping(bytes4 selector => address facet) facetBySelector;
    mapping(address => EnumerableSet.Bytes32Set) selectorsByFacet;
  }

  function layout() internal pure returns (Layout storage ds) {
    bytes32 slot = STORAGE_SLOT;
    assembly {
      ds.slot := slot
    }
  }
}
Contract Source Code
File 5 of 16: DiamondLoupeBase.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces
import {IDiamondLoupeBase} from "./IDiamondLoupe.sol";

// libraries
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {DiamondCutStorage} from "../cut/DiamondCutStorage.sol";

// contracts

abstract contract DiamondLoupeBase is IDiamondLoupeBase {
  using EnumerableSet for EnumerableSet.AddressSet;
  using EnumerableSet for EnumerableSet.Bytes32Set;

  function _facetSelectors(
    address facet
  ) internal view returns (bytes4[] memory selectors) {
    EnumerableSet.Bytes32Set storage facetSelectors_ = DiamondCutStorage
      .layout()
      .selectorsByFacet[facet];
    uint256 selectorCount = facetSelectors_.length();

    selectors = new bytes4[](selectorCount);
    for (uint256 i; i < selectorCount; ) {
      selectors[i] = bytes4(facetSelectors_.at(i));

      unchecked {
        i++;
      }
    }
  }

  function _facetAddresses() internal view returns (address[] memory) {
    return DiamondCutStorage.layout().facets.values();
  }

  function _facetAddress(
    bytes4 selector
  ) internal view returns (address facetAddress) {
    return DiamondCutStorage.layout().facetBySelector[selector];
  }

  function _facets() internal view returns (Facet[] memory facets) {
    address[] memory facetAddresses = _facetAddresses();
    uint256 facetCount = facetAddresses.length;
    facets = new Facet[](facetCount);

    for (uint256 i; i < facetCount; ) {
      address facetAddress = facetAddresses[i];
      bytes4[] memory selectors = _facetSelectors(facetAddress);
      facets[i] = Facet({facet: facetAddress, selectors: selectors});

      unchecked {
        i++;
      }
    }
  }
}
Contract Source Code
File 6 of 16: EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.20;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position is the index of the value in the `values` array plus 1.
        // Position 0 is used to mean a value is not in the set.
        mapping(bytes32 value => uint256) _positions;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._positions[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We cache the value's position to prevent multiple reads from the same storage slot
        uint256 position = set._positions[value];

        if (position != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 valueIndex = position - 1;
            uint256 lastIndex = set._values.length - 1;

            if (valueIndex != lastIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the lastValue to the index where the value to delete is
                set._values[valueIndex] = lastValue;
                // Update the tracked position of the lastValue (that was just moved)
                set._positions[lastValue] = position;
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the tracked position for the deleted slot
            delete set._positions[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._positions[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}
Contract Source Code
File 7 of 16: IDiamond.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries

// contracts

interface IDiamond {
  /// @notice Thrown when calling a function that was not registered in the diamond.
  error Diamond_UnsupportedFunction();

  /// @notice Add/replace/remove any number of functions and optionally execute
  /// @param Add Facets to add functions to.
  /// @param Replace Facets to replace functions in.
  /// @param Remove Facets to remove functions from.
  enum FacetCutAction {
    Add,
    Replace,
    Remove
  }

  /// @notice Execute a diamond cut
  /// @param facetAddress Facet to cut.
  /// @param action Enum of type FacetCutAction.
  /// @param functionSelectors Array of function selectors.
  struct FacetCut {
    address facetAddress;
    FacetCutAction action;
    bytes4[] functionSelectors;
  }
}
Contract Source Code
File 8 of 16: IDiamondCut.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces
import {IDiamond} from "contracts/src/diamond/IDiamond.sol";

// libraries

// contracts

interface IDiamondCutBase {
  error DiamondCut_InvalidSelector();
  error DiamondCut_InvalidFacetCutLength();
  error DiamondCut_FunctionAlreadyExists(bytes4 selector);
  error DiamondCut_FunctionFromSameFacetAlreadyExists(bytes4 selector);
  error DiamondCut_InvalidFacetRemoval(address facet, bytes4 selector);
  error DiamondCut_FunctionDoesNotExist(address facet);
  error DiamondCut_InvalidFacetCutAction();
  error DiamondCut_InvalidFacet(address facet);
  error DiamondCut_InvalidFacetSelectors(address facet);
  error DiamondCut_ImmutableFacet();
  error DiamondCut_InvalidContract(address init);

  /// @notice Event emitted when facets are added/removed/replaced
  /// @param facetCuts Facet addresses and function selectors.
  /// @param init Address of contract or facet to execute initPayload.
  /// @param initPayload A function call, including function selector and arguments.
  event DiamondCut(
    IDiamond.FacetCut[] facetCuts,
    address init,
    bytes initPayload
  );
}

interface IDiamondCut is IDiamondCutBase {
  /// @notice Add/replace/remove any number of functions and optionally execute a function with delegatecall
  /// @param facetCuts Facet addresses and function selectors.
  /// @param init Address of contract or facet to execute initPayload.
  /// @param initPayload A function call, including function selector and arguments. Executed with delegatecall on init address.
  function diamondCut(
    IDiamond.FacetCut[] calldata facetCuts,
    address init,
    bytes calldata initPayload
  ) external;
}
Contract Source Code
File 9 of 16: IDiamondLoupe.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries

// contracts
interface IDiamondLoupeBase {
  struct Facet {
    address facet;
    bytes4[] selectors;
  }
}

/**
 * @title IDiamondLoupe
 * @notice A loupe is a small magnifying glass used to look at diamonds.
 *         See [EIP-2535](https://eips.ethereum.org/EIPS/eip-2535).
 */
interface IDiamondLoupe is IDiamondLoupeBase {
  /**
   * @notice Gets all facet addresses and the selectors of supported functions.
   * @return facetInfo An array of Facet structs.
   */
  function facets() external view returns (Facet[] memory);

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

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

  /**
   * @notice Gets the facet that supports the given selector.
   * @dev If facet is not found return address(0).
   * @param selector The function selector.
   * @return facetAddress The facet address.
   */
  function facetAddress(bytes4 selector) external view returns (address);
}
Contract Source Code
File 10 of 16: IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
Contract Source Code
File 11 of 16: IProxy.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries

// contracts

interface IProxy {
  error Proxy__ImplementationIsNotContract();

  fallback() external payable;
}
Contract Source Code
File 12 of 16: Initializable.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.23;

import {InitializableStorage} from "./InitializableStorage.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

error Initializable_AlreadyInitialized(uint32 version);
error Initializable_NotInInitializingState();
error Initializable_InInitializingState();

abstract contract Initializable {
  event Initialized(uint32 version);

  modifier initializer() {
    InitializableStorage.Layout storage s = InitializableStorage.layout();

    bool isTopLevelCall = !s.initializing;
    if (isTopLevelCall ? s.version >= 1 : _isNotConstructor()) {
      revert Initializable_AlreadyInitialized(s.version);
    }
    s.version = 1;
    if (isTopLevelCall) {
      s.initializing = true;
    }
    _;
    if (isTopLevelCall) {
      s.initializing = false;
      emit Initialized(1);
    }
  }

  modifier reinitializer(uint32 version) {
    InitializableStorage.Layout storage s = InitializableStorage.layout();

    if (s.initializing || s.version >= version) {
      revert Initializable_AlreadyInitialized(s.version);
    }
    s.version = version;
    s.initializing = true;
    _;
    s.initializing = false;
    emit Initialized(version);
  }

  modifier onlyInitializing() {
    if (!InitializableStorage.layout().initializing)
      revert Initializable_NotInInitializingState();
    _;
  }

  function _getInitializedVersion()
    internal
    view
    virtual
    returns (uint32 version)
  {
    version = InitializableStorage.layout().version;
  }

  function _nextVersion() internal view returns (uint32) {
    return InitializableStorage.layout().version + 1;
  }

  function _disableInitializers() internal {
    InitializableStorage.Layout storage s = InitializableStorage.layout();
    if (s.initializing) revert Initializable_InInitializingState();

    if (s.version < type(uint32).max) {
      s.version = type(uint32).max;
      emit Initialized(type(uint32).max);
    }
  }

  function _isNotConstructor() private view returns (bool) {
    return address(this).code.length != 0;
  }
}
Contract Source Code
File 13 of 16: InitializableStorage.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries

// contracts

library InitializableStorage {
  // keccak256(abi.encode(uint256(keccak256("diamond.facets.initializable.storage")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 internal constant STORAGE_SLOT =
    0x59b501c3653afc186af7d48dda36cf6732bd21629a6295693664240a6ef52000;

  struct Layout {
    uint32 version;
    bool initializing;
  }

  function layout() internal pure returns (Layout storage s) {
    bytes32 slot = STORAGE_SLOT;
    assembly {
      s.slot := slot
    }
  }
}
Contract Source Code
File 14 of 16: IntrospectionBase.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces
import {IIntrospectionBase} from "./IERC165.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

// libraries
import {IntrospectionStorage} from "./IntrospectionStorage.sol";

abstract contract IntrospectionBase is IIntrospectionBase {
  function __IntrospectionBase_init() internal {
    _addInterface(type(IERC165).interfaceId);
  }

  function _addInterface(bytes4 interfaceId) internal {
    if (!_supportsInterface(interfaceId)) {
      IntrospectionStorage.layout().supportedInterfaces[interfaceId] = true;
    } else {
      revert Introspection_AlreadySupported();
    }
    emit InterfaceAdded(interfaceId);
  }

  function _removeInterface(bytes4 interfaceId) internal {
    if (_supportsInterface(interfaceId)) {
      IntrospectionStorage.layout().supportedInterfaces[interfaceId] = false;
    } else {
      revert Introspection_NotSupported();
    }
    emit InterfaceRemoved(interfaceId);
  }

  function _supportsInterface(bytes4 interfaceId) internal view returns (bool) {
    return
      IntrospectionStorage.layout().supportedInterfaces[interfaceId] == true;
  }
}
Contract Source Code
File 15 of 16: IntrospectionStorage.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces

// libraries

// contracts

library IntrospectionStorage {
  // keccak256(abi.encode(uint256(keccak256("diamond.facets.introspection.storage")) - 1)) & ~bytes32(uint256(0xff))
  bytes32 internal constant STORAGE_SLOT =
    0x81088bbc801e045ea3e7620779ab349988f58afbdfba10dff983df3f33522b00;

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

  function layout() internal pure returns (Layout storage ds) {
    bytes32 slot = STORAGE_SLOT;
    assembly {
      ds.slot := slot
    }
  }
}
Contract Source Code
File 16 of 16: Proxy.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.23;

// interfaces
import {IProxy} from "./IProxy.sol";

// libraries
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

// contracts

abstract contract Proxy is IProxy {
  fallback() external payable {
    _fallback();
  }

  function _fallback() internal {
    address facet = _getImplementation();

    if (facet.code.length == 0) revert Proxy__ImplementationIsNotContract();

    // solhint-disable-next-line no-inline-assembly
    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())
      }
    }
  }

  function _getImplementation() internal virtual returns (address);
}
Settings
{
  "compilationTarget": {
    "contracts/src/diamond/Diamond.sol": "Diamond"
  },
  "evmVersion": "paris",
  "libraries": {},
  "metadata": {
    "appendCBOR": false,
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [
    ":@openzeppelin/=lib/@openzeppelin/",
    ":@prb/math/=lib/@prb/math/src/",
    ":@prb/test/=lib/@prb/test/src/",
    ":account-abstraction/=lib/account-abstraction/contracts/",
    ":base64/=lib/base64/",
    ":ds-test/=lib/ds-test/src/",
    ":forge-std/=lib/forge-std/src/",
    ":hardhat-deploy/=lib/hardhat-deploy/"
  ]
}
ABI
[{"inputs":[{"components":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamond.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamond.FacetCut[]","name":"baseFacets","type":"tuple[]"},{"internalType":"address","name":"init","type":"address"},{"internalType":"bytes","name":"initData","type":"bytes"}],"internalType":"struct Diamond.InitParams","name":"initDiamondCut","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"DiamondCut_FunctionAlreadyExists","type":"error"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"DiamondCut_FunctionDoesNotExist","type":"error"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"DiamondCut_FunctionFromSameFacetAlreadyExists","type":"error"},{"inputs":[],"name":"DiamondCut_ImmutableFacet","type":"error"},{"inputs":[{"internalType":"address","name":"init","type":"address"}],"name":"DiamondCut_InvalidContract","type":"error"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"DiamondCut_InvalidFacet","type":"error"},{"inputs":[],"name":"DiamondCut_InvalidFacetCutAction","type":"error"},{"inputs":[],"name":"DiamondCut_InvalidFacetCutLength","type":"error"},{"inputs":[{"internalType":"address","name":"facet","type":"address"},{"internalType":"bytes4","name":"selector","type":"bytes4"}],"name":"DiamondCut_InvalidFacetRemoval","type":"error"},{"inputs":[{"internalType":"address","name":"facet","type":"address"}],"name":"DiamondCut_InvalidFacetSelectors","type":"error"},{"inputs":[],"name":"DiamondCut_InvalidSelector","type":"error"},{"inputs":[],"name":"Diamond_UnsupportedFunction","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"uint32","name":"version","type":"uint32"}],"name":"Initializable_AlreadyInitialized","type":"error"},{"inputs":[],"name":"Proxy__ImplementationIsNotContract","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamond.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamond.FacetCut[]","name":"facetCuts","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"init","type":"address"},{"indexed":false,"internalType":"bytes","name":"initPayload","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"version","type":"uint32"}],"name":"Initialized","type":"event"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]