creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "@synthetixio/core-contracts/contracts/errors/AccessError.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title Library for access related errors.\n */\nlibrary AccessError {\n    /**\n     * @dev Thrown when an address tries to perform an unauthorized action.\n     * @param addr The address that attempts the action.\n     */\n    error Unauthorized(address addr);\n}\n"
      },
      "@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\nimport \"../errors/AccessError.sol\";\n\nlibrary OwnableStorage {\n    bytes32 private constant _SLOT_OWNABLE_STORAGE =\n        keccak256(abi.encode(\"io.synthetix.core-contracts.Ownable\"));\n\n    struct Data {\n        address owner;\n        address nominatedOwner;\n    }\n\n    function load() internal pure returns (Data storage store) {\n        bytes32 s = _SLOT_OWNABLE_STORAGE;\n        assembly {\n            store.slot := s\n        }\n    }\n\n    function onlyOwner() internal view {\n        if (msg.sender != getOwner()) {\n            revert AccessError.Unauthorized(msg.sender);\n        }\n    }\n\n    function getOwner() internal view returns (address) {\n        return OwnableStorage.load().owner;\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/ERC2771Context.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\n/* solhint-disable meta-transactions/no-msg-sender */\n/* solhint-disable meta-transactions/no-msg-data */\n\nlibrary ERC2771Context {\n    // This is the trusted-multicall-forwarder. The address is constant due to CREATE2.\n    address private constant TRUSTED_FORWARDER = 0xE2C5658cC5C448B48141168f3e475dF8f65A1e3e;\n\n    function _msgSender() internal view returns (address sender) {\n        if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n            // The assembly code is more direct than the Solidity version using `abi.decode`.\n            /// @solidity memory-safe-assembly\n            assembly {\n                sender := shr(96, calldataload(sub(calldatasize(), 20)))\n            }\n        } else {\n            return msg.sender;\n        }\n    }\n\n    function _msgData() internal view returns (bytes calldata) {\n        if (isTrustedForwarder(msg.sender) && msg.data.length >= 20) {\n            return msg.data[:msg.data.length - 20];\n        } else {\n            return msg.data;\n        }\n    }\n\n    function isTrustedForwarder(address forwarder) internal pure returns (bool) {\n        return forwarder == TRUSTED_FORWARDER;\n    }\n\n    function trustedForwarder() internal pure returns (address) {\n        return TRUSTED_FORWARDER;\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * Utilities that convert numeric types avoiding silent overflows.\n */\nimport \"./SafeCast/SafeCastU32.sol\";\nimport \"./SafeCast/SafeCastI32.sol\";\nimport \"./SafeCast/SafeCastI24.sol\";\nimport \"./SafeCast/SafeCastU56.sol\";\nimport \"./SafeCast/SafeCastI56.sol\";\nimport \"./SafeCast/SafeCastU64.sol\";\nimport \"./SafeCast/SafeCastI64.sol\";\nimport \"./SafeCast/SafeCastI128.sol\";\nimport \"./SafeCast/SafeCastI256.sol\";\nimport \"./SafeCast/SafeCastU128.sol\";\nimport \"./SafeCast/SafeCastU160.sol\";\nimport \"./SafeCast/SafeCastU256.sol\";\nimport \"./SafeCast/SafeCastAddress.sol\";\nimport \"./SafeCast/SafeCastBytes32.sol\";\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastAddress.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastAddress {\n    function toBytes32(address x) internal pure returns (bytes32) {\n        return bytes32(uint256(uint160(x)));\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastBytes32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastBytes32 {\n    function toAddress(bytes32 x) internal pure returns (address) {\n        return address(uint160(uint256(x)));\n    }\n\n    function toUint(bytes32 x) internal pure returns (uint) {\n        return uint(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI128.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI128 {\n    error OverflowInt128ToUint128();\n    error OverflowInt128ToInt32();\n\n    function toUint(int128 x) internal pure returns (uint128) {\n        // ----------------<==============o==============>-----------------\n        // ----------------xxxxxxxxxxxxxxxo===============>----------------\n        if (x < 0) {\n            revert OverflowInt128ToUint128();\n        }\n\n        return uint128(x);\n    }\n\n    function to256(int128 x) internal pure returns (int256) {\n        return int256(x);\n    }\n\n    function to32(int128 x) internal pure returns (int32) {\n        // ----------------<==============o==============>-----------------\n        // ----------------xxxxxxxxxxxx<==o==>xxxxxxxxxxxx-----------------\n        if (x < int(type(int32).min) || x > int(type(int32).max)) {\n            revert OverflowInt128ToInt32();\n        }\n\n        return int32(x);\n    }\n\n    function zero() internal pure returns (int128) {\n        return int128(0);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI24.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI24 {\n    function to256(int24 x) internal pure returns (int256) {\n        return int256(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI256.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI256 {\n    error OverflowInt256ToUint256();\n    error OverflowInt256ToInt128();\n    error OverflowInt256ToInt24();\n\n    function to128(int256 x) internal pure returns (int128) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxx<==============o==============>xxxxxxxxxxxxx----\n        if (x < int256(type(int128).min) || x > int256(type(int128).max)) {\n            revert OverflowInt256ToInt128();\n        }\n\n        return int128(x);\n    }\n\n    function to24(int256 x) internal pure returns (int24) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxxxxxxxxxx<======o=======>xxxxxxxxxxxxxxxxxxxx----\n        if (x < int256(type(int24).min) || x > int256(type(int24).max)) {\n            revert OverflowInt256ToInt24();\n        }\n\n        return int24(x);\n    }\n\n    function toUint(int256 x) internal pure returns (uint256) {\n        // ----<==========================o===========================>----\n        // ----xxxxxxxxxxxxxxxxxxxxxxxxxxxo===============================>\n        if (x < 0) {\n            revert OverflowInt256ToUint256();\n        }\n\n        return uint256(x);\n    }\n\n    function zero() internal pure returns (int256) {\n        return int256(0);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI32 {\n    error OverflowInt32ToUint32();\n\n    function toUint(int32 x) internal pure returns (uint32) {\n        // ----------------------<========o========>----------------------\n        // ----------------------xxxxxxxxxo=========>----------------------\n        if (x < 0) {\n            revert OverflowInt32ToUint32();\n        }\n\n        return uint32(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI56.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI56 {\n    error OverflowInt56ToInt24();\n\n    function to24(int56 x) internal pure returns (int24) {\n        // ----------------------<========o========>-----------------------\n        // ----------------------xxx<=====o=====>xxx-----------------------\n        if (x < int(type(int24).min) || x > int(type(int24).max)) {\n            revert OverflowInt56ToInt24();\n        }\n\n        return int24(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastI64.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastI64 {\n    error OverflowInt64ToUint64();\n\n    function toUint(int64 x) internal pure returns (uint64) {\n        // ----------------------<========o========>----------------------\n        // ----------------------xxxxxxxxxo=========>----------------------\n        if (x < 0) {\n            revert OverflowInt64ToUint64();\n        }\n\n        return uint64(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU128.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU128 {\n    error OverflowUint128ToInt128();\n\n    function to256(uint128 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n\n    function toInt(uint128 x) internal pure returns (int128) {\n        // -------------------------------o===============>----------------\n        // ----------------<==============o==============>x----------------\n        if (x > uint128(type(int128).max)) {\n            revert OverflowUint128ToInt128();\n        }\n\n        return int128(x);\n    }\n\n    function toBytes32(uint128 x) internal pure returns (bytes32) {\n        return bytes32(uint256(x));\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU160.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU160 {\n    function to256(uint160 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU256.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU256 {\n    error OverflowUint256ToUint128();\n    error OverflowUint256ToInt256();\n    error OverflowUint256ToUint64();\n    error OverflowUint256ToUint32();\n    error OverflowUint256ToUint160();\n\n    function to128(uint256 x) internal pure returns (uint128) {\n        // -------------------------------o===============================>\n        // -------------------------------o===============>xxxxxxxxxxxxxxxx\n        if (x > type(uint128).max) {\n            revert OverflowUint256ToUint128();\n        }\n\n        return uint128(x);\n    }\n\n    function to64(uint256 x) internal pure returns (uint64) {\n        // -------------------------------o===============================>\n        // -------------------------------o======>xxxxxxxxxxxxxxxxxxxxxxxxx\n        if (x > type(uint64).max) {\n            revert OverflowUint256ToUint64();\n        }\n\n        return uint64(x);\n    }\n\n    function to32(uint256 x) internal pure returns (uint32) {\n        // -------------------------------o===============================>\n        // -------------------------------o===>xxxxxxxxxxxxxxxxxxxxxxxxxxxx\n        if (x > type(uint32).max) {\n            revert OverflowUint256ToUint32();\n        }\n\n        return uint32(x);\n    }\n\n    function to160(uint256 x) internal pure returns (uint160) {\n        // -------------------------------o===============================>\n        // -------------------------------o==================>xxxxxxxxxxxxx\n        if (x > type(uint160).max) {\n            revert OverflowUint256ToUint160();\n        }\n\n        return uint160(x);\n    }\n\n    function toBytes32(uint256 x) internal pure returns (bytes32) {\n        return bytes32(x);\n    }\n\n    function toInt(uint256 x) internal pure returns (int256) {\n        // -------------------------------o===============================>\n        // ----<==========================o===========================>xxxx\n        if (x > uint256(type(int256).max)) {\n            revert OverflowUint256ToInt256();\n        }\n\n        return int256(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU32.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU32 {\n    error OverflowUint32ToInt32();\n\n    function toInt(uint32 x) internal pure returns (int32) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint32(type(int32).max)) {\n            revert OverflowUint32ToInt32();\n        }\n\n        return int32(x);\n    }\n\n    function to256(uint32 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n\n    function to56(uint32 x) internal pure returns (uint56) {\n        return uint56(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU56.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU56 {\n    error OverflowUint56ToInt56();\n\n    function toInt(uint56 x) internal pure returns (int56) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint56(type(int56).max)) {\n            revert OverflowUint56ToInt56();\n        }\n\n        return int56(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SafeCast/SafeCastU64.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title See SafeCast.sol.\n */\nlibrary SafeCastU64 {\n    error OverflowUint64ToInt64();\n\n    function toInt(uint64 x) internal pure returns (int64) {\n        // -------------------------------o=========>----------------------\n        // ----------------------<========o========>x----------------------\n        if (x > uint64(type(int64).max)) {\n            revert OverflowUint64ToInt64();\n        }\n\n        return int64(x);\n    }\n\n    function to256(uint64 x) internal pure returns (uint256) {\n        return uint256(x);\n    }\n}\n"
      },
      "@synthetixio/core-contracts/contracts/utils/SetUtil.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\nimport \"./SafeCast.sol\";\n\nlibrary SetUtil {\n    using SafeCastAddress for address;\n    using SafeCastBytes32 for bytes32;\n    using SafeCastU256 for uint256;\n\n    // ----------------------------------------\n    // Uint support\n    // ----------------------------------------\n\n    struct UintSet {\n        Bytes32Set raw;\n    }\n\n    function add(UintSet storage set, uint value) internal {\n        add(set.raw, value.toBytes32());\n    }\n\n    function remove(UintSet storage set, uint value) internal {\n        remove(set.raw, value.toBytes32());\n    }\n\n    function replace(UintSet storage set, uint value, uint newValue) internal {\n        replace(set.raw, value.toBytes32(), newValue.toBytes32());\n    }\n\n    function contains(UintSet storage set, uint value) internal view returns (bool) {\n        return contains(set.raw, value.toBytes32());\n    }\n\n    function length(UintSet storage set) internal view returns (uint) {\n        return length(set.raw);\n    }\n\n    function valueAt(UintSet storage set, uint position) internal view returns (uint) {\n        return valueAt(set.raw, position).toUint();\n    }\n\n    function positionOf(UintSet storage set, uint value) internal view returns (uint) {\n        return positionOf(set.raw, value.toBytes32());\n    }\n\n    function values(UintSet storage set) internal view returns (uint[] memory) {\n        bytes32[] memory store = values(set.raw);\n        uint[] memory result;\n\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // ----------------------------------------\n    // Address support\n    // ----------------------------------------\n\n    struct AddressSet {\n        Bytes32Set raw;\n    }\n\n    function add(AddressSet storage set, address value) internal {\n        add(set.raw, value.toBytes32());\n    }\n\n    function remove(AddressSet storage set, address value) internal {\n        remove(set.raw, value.toBytes32());\n    }\n\n    function replace(AddressSet storage set, address value, address newValue) internal {\n        replace(set.raw, value.toBytes32(), newValue.toBytes32());\n    }\n\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return contains(set.raw, value.toBytes32());\n    }\n\n    function length(AddressSet storage set) internal view returns (uint) {\n        return length(set.raw);\n    }\n\n    function valueAt(AddressSet storage set, uint position) internal view returns (address) {\n        return valueAt(set.raw, position).toAddress();\n    }\n\n    function positionOf(AddressSet storage set, address value) internal view returns (uint) {\n        return positionOf(set.raw, value.toBytes32());\n    }\n\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = values(set.raw);\n        address[] memory result;\n\n        assembly {\n            result := store\n        }\n\n        return result;\n    }\n\n    // ----------------------------------------\n    // Core bytes32 support\n    // ----------------------------------------\n\n    error PositionOutOfBounds();\n    error ValueNotInSet();\n    error ValueAlreadyInSet();\n\n    struct Bytes32Set {\n        bytes32[] _values;\n        mapping(bytes32 => uint) _positions; // Position zero is never used.\n    }\n\n    function add(Bytes32Set storage set, bytes32 value) internal {\n        if (contains(set, value)) {\n            revert ValueAlreadyInSet();\n        }\n\n        set._values.push(value);\n        set._positions[value] = set._values.length;\n    }\n\n    function remove(Bytes32Set storage set, bytes32 value) internal {\n        uint position = set._positions[value];\n        if (position == 0) {\n            revert ValueNotInSet();\n        }\n\n        uint index = position - 1;\n        uint lastIndex = set._values.length - 1;\n\n        // If the element being deleted is not the last in the values,\n        // move the last element to its position.\n        if (index != lastIndex) {\n            bytes32 lastValue = set._values[lastIndex];\n\n            set._values[index] = lastValue;\n            set._positions[lastValue] = position;\n        }\n\n        // Remove the last element in the values.\n        set._values.pop();\n        delete set._positions[value];\n    }\n\n    function replace(Bytes32Set storage set, bytes32 value, bytes32 newValue) internal {\n        if (!contains(set, value)) {\n            revert ValueNotInSet();\n        }\n\n        if (contains(set, newValue)) {\n            revert ValueAlreadyInSet();\n        }\n\n        uint position = set._positions[value];\n        delete set._positions[value];\n\n        uint index = position - 1;\n\n        set._values[index] = newValue;\n        set._positions[newValue] = position;\n    }\n\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    function length(Bytes32Set storage set) internal view returns (uint) {\n        return set._values.length;\n    }\n\n    function valueAt(Bytes32Set storage set, uint position) internal view returns (bytes32) {\n        if (position == 0 || position > set._values.length) {\n            revert PositionOutOfBounds();\n        }\n\n        uint index = position - 1;\n\n        return set._values[index];\n    }\n\n    function positionOf(Bytes32Set storage set, bytes32 value) internal view returns (uint) {\n        if (!contains(set, value)) {\n            revert ValueNotInSet();\n        }\n\n        return set._positions[value];\n    }\n\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        return set._values;\n    }\n}\n"
      },
      "@synthetixio/core-modules/contracts/interfaces/IFeatureFlagModule.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\n/**\n * @title Module for granular enabling and disabling of system features and functions.\n *\n * Interface functions that are controlled by a feature flag simply need to add this line to their body:\n * `FeatureFlag.ensureAccessToFeature(FLAG_ID);`\n *\n * If such a line is not present in a function, then it is not controlled by a feature flag.\n *\n * If a feature flag is set and then removed forever, consider deleting the line mentioned above from the function's body.\n */\ninterface IFeatureFlagModule {\n    /**\n     * @notice Emitted when general access has been given or removed for a feature.\n     * @param feature The bytes32 id of the feature.\n     * @param allowAll True if the feature was allowed for everyone and false if it is only allowed for those included in the allowlist.\n     */\n    event FeatureFlagAllowAllSet(bytes32 indexed feature, bool allowAll);\n\n    /**\n     * @notice Emitted when general access has been blocked for a feature.\n     * @param feature The bytes32 id of the feature.\n     * @param denyAll True if the feature was blocked for everyone and false if it is only allowed for those included in the allowlist or if allowAll is set to true.\n     */\n    event FeatureFlagDenyAllSet(bytes32 indexed feature, bool denyAll);\n\n    /**\n     * @notice Emitted when an address was given access to a feature.\n     * @param feature The bytes32 id of the feature.\n     * @param account The address that was given access to the feature.\n     */\n    event FeatureFlagAllowlistAdded(bytes32 indexed feature, address account);\n\n    /**\n     * @notice Emitted when access to a feature has been removed from an address.\n     * @param feature The bytes32 id of the feature.\n     * @param account The address that no longer has access to the feature.\n     */\n    event FeatureFlagAllowlistRemoved(bytes32 indexed feature, address account);\n\n    /**\n     * @notice Emitted when the list of addresses which can block a feature has been updated\n     * @param feature The bytes32 id of the feature.\n     * @param deniers The list of addresses which are allowed to block a feature\n     */\n    event FeatureFlagDeniersReset(bytes32 indexed feature, address[] deniers);\n\n    /**\n     * @notice Enables or disables free access to a feature.\n     * @param feature The bytes32 id of the feature.\n     * @param allowAll True to allow anyone to use the feature, false to fallback to the allowlist.\n     */\n    function setFeatureFlagAllowAll(bytes32 feature, bool allowAll) external;\n\n    /**\n     * @notice Enables or disables free access to a feature.\n     * @param feature The bytes32 id of the feature.\n     * @param denyAll True to allow noone to use the feature, false to fallback to the allowlist.\n     */\n    function setFeatureFlagDenyAll(bytes32 feature, bool denyAll) external;\n\n    /**\n     * @notice Allows an address to use a feature.\n     * @dev This function does nothing if the specified account is already on the allowlist.\n     * @param feature The bytes32 id of the feature.\n     * @param account The address that is allowed to use the feature.\n     */\n    function addToFeatureFlagAllowlist(bytes32 feature, address account) external;\n\n    /**\n     * @notice Disallows an address from using a feature.\n     * @dev This function does nothing if the specified account is already on the allowlist.\n     * @param feature The bytes32 id of the feature.\n     * @param account The address that is disallowed from using the feature.\n     */\n    function removeFromFeatureFlagAllowlist(bytes32 feature, address account) external;\n\n    /**\n     * @notice Sets addresses which can disable a feature (but not enable it). Overwrites any preexisting data.\n     * @param feature The bytes32 id of the feature.\n     * @param deniers The addresses which should have the ability to unilaterally disable the feature\n     */\n    function setDeniers(bytes32 feature, address[] memory deniers) external;\n\n    /**\n     * @notice Gets the list of address which can block a feature\n     * @param feature The bytes32 id of the feature.\n     */\n    function getDeniers(bytes32 feature) external view returns (address[] memory);\n\n    /**\n     * @notice Determines if the given feature is freely allowed to all users.\n     * @param feature The bytes32 id of the feature.\n     * @return True if anyone is allowed to use the feature, false if per-user control is used.\n     */\n    function getFeatureFlagAllowAll(bytes32 feature) external view returns (bool);\n\n    /**\n     * @notice Determines if the given feature is denied to all users.\n     * @param feature The bytes32 id of the feature.\n     * @return True if noone is allowed to use the feature.\n     */\n    function getFeatureFlagDenyAll(bytes32 feature) external view returns (bool);\n\n    /**\n     * @notice Returns a list of addresses that are allowed to use the specified feature.\n     * @param feature The bytes32 id of the feature.\n     * @return The queried list of addresses.\n     */\n    function getFeatureFlagAllowlist(bytes32 feature) external view returns (address[] memory);\n\n    /**\n     * @notice Determines if an address can use the specified feature.\n     * @param feature The bytes32 id of the feature.\n     * @param account The address that is being queried for access to the feature.\n     * @return A boolean with the response to the query.\n     */\n    function isFeatureAllowed(bytes32 feature, address account) external view returns (bool);\n}\n"
      },
      "@synthetixio/core-modules/contracts/modules/FeatureFlagModule.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\nimport \"@synthetixio/core-contracts/contracts/ownership/OwnableStorage.sol\";\nimport \"../storage/FeatureFlag.sol\";\n\nimport \"../interfaces/IFeatureFlagModule.sol\";\n\n/**\n * @title Module for granular enabling and disabling of system features and functions.\n * See IFeatureFlagModule.\n */\ncontract FeatureFlagModule is IFeatureFlagModule {\n    using SetUtil for SetUtil.AddressSet;\n    using FeatureFlag for FeatureFlag.Data;\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function setFeatureFlagAllowAll(bytes32 feature, bool allowAll) external override {\n        OwnableStorage.onlyOwner();\n        FeatureFlag.load(feature).allowAll = allowAll;\n\n        if (allowAll) {\n            FeatureFlag.load(feature).denyAll = false;\n        }\n\n        emit FeatureFlagAllowAllSet(feature, allowAll);\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function setFeatureFlagDenyAll(bytes32 feature, bool denyAll) external override {\n        FeatureFlag.Data storage flag = FeatureFlag.load(feature);\n\n        if (!denyAll || !flag.isDenier(ERC2771Context._msgSender())) {\n            OwnableStorage.onlyOwner();\n        }\n\n        flag.denyAll = denyAll;\n\n        emit FeatureFlagDenyAllSet(feature, denyAll);\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function addToFeatureFlagAllowlist(bytes32 feature, address account) external override {\n        OwnableStorage.onlyOwner();\n\n        SetUtil.AddressSet storage permissionedAddresses = FeatureFlag\n            .load(feature)\n            .permissionedAddresses;\n\n        if (!permissionedAddresses.contains(account)) {\n            permissionedAddresses.add(account);\n            emit FeatureFlagAllowlistAdded(feature, account);\n        }\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function removeFromFeatureFlagAllowlist(bytes32 feature, address account) external override {\n        OwnableStorage.onlyOwner();\n\n        SetUtil.AddressSet storage permissionedAddresses = FeatureFlag\n            .load(feature)\n            .permissionedAddresses;\n\n        if (permissionedAddresses.contains(account)) {\n            FeatureFlag.load(feature).permissionedAddresses.remove(account);\n            emit FeatureFlagAllowlistRemoved(feature, account);\n        }\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function setDeniers(bytes32 feature, address[] memory deniers) external override {\n        OwnableStorage.onlyOwner();\n        FeatureFlag.Data storage flag = FeatureFlag.load(feature);\n\n        // resize array (its really dumb how you have to do this)\n        uint storageLen = flag.deniers.length;\n        for (uint i = storageLen; i > deniers.length; i--) {\n            flag.deniers.pop();\n        }\n\n        for (uint i = 0; i < deniers.length; i++) {\n            if (i >= storageLen) {\n                flag.deniers.push(deniers[i]);\n            } else {\n                flag.deniers[i] = deniers[i];\n            }\n        }\n\n        emit FeatureFlagDeniersReset(feature, deniers);\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function getDeniers(bytes32 feature) external view override returns (address[] memory) {\n        FeatureFlag.Data storage flag = FeatureFlag.load(feature);\n        address[] memory addrs = new address[](flag.deniers.length);\n        for (uint i = 0; i < addrs.length; i++) {\n            addrs[i] = flag.deniers[i];\n        }\n\n        return addrs;\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function getFeatureFlagAllowAll(bytes32 feature) external view override returns (bool) {\n        return FeatureFlag.load(feature).allowAll;\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function getFeatureFlagDenyAll(bytes32 feature) external view override returns (bool) {\n        return FeatureFlag.load(feature).denyAll;\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function getFeatureFlagAllowlist(\n        bytes32 feature\n    ) external view override returns (address[] memory) {\n        return FeatureFlag.load(feature).permissionedAddresses.values();\n    }\n\n    /**\n     * @inheritdoc IFeatureFlagModule\n     */\n    function isFeatureAllowed(\n        bytes32 feature,\n        address account\n    ) external view override returns (bool) {\n        return FeatureFlag.hasAccess(feature, account);\n    }\n}\n"
      },
      "@synthetixio/core-modules/contracts/storage/FeatureFlag.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\nimport \"@synthetixio/core-contracts/contracts/utils/SetUtil.sol\";\nimport \"@synthetixio/core-contracts/contracts/utils/ERC2771Context.sol\";\n\nlibrary FeatureFlag {\n    using SetUtil for SetUtil.AddressSet;\n\n    error FeatureUnavailable(bytes32 which);\n\n    struct Data {\n        bytes32 name;\n        bool allowAll;\n        bool denyAll;\n        SetUtil.AddressSet permissionedAddresses;\n        address[] deniers;\n    }\n\n    function load(bytes32 featureName) internal pure returns (Data storage store) {\n        bytes32 s = keccak256(abi.encode(\"io.synthetix.core-modules.FeatureFlag\", featureName));\n        assembly {\n            store.slot := s\n        }\n    }\n\n    function ensureAccessToFeature(bytes32 feature) internal view {\n        if (!hasAccess(feature, ERC2771Context._msgSender())) {\n            revert FeatureUnavailable(feature);\n        }\n    }\n\n    function hasAccess(bytes32 feature, address value) internal view returns (bool) {\n        Data storage store = FeatureFlag.load(feature);\n\n        if (store.denyAll) {\n            return false;\n        }\n\n        return store.allowAll || store.permissionedAddresses.contains(value);\n    }\n\n    function isDenier(Data storage self, address possibleDenier) internal view returns (bool) {\n        for (uint i = 0; i < self.deniers.length; i++) {\n            if (self.deniers[i] == possibleDenier) {\n                return true;\n            }\n        }\n\n        return false;\n    }\n}\n"
      },
      "contracts/modules/core/FeatureFlagModule.sol": {
        "content": "//SPDX-License-Identifier: MIT\npragma solidity >=0.8.11 <0.9.0;\n\nimport {FeatureFlagModule as BaseFeatureFlagModule} from \"@synthetixio/core-modules/contracts/modules/FeatureFlagModule.sol\";\n\n/**\n * @title Module that allows disabling certain system features.\n *\n * Users will not be able to interact with certain functions associated to disabled features.\n */\n// solhint-disable-next-line no-empty-blocks\ncontract FeatureFlagModule is BaseFeatureFlagModule {\n\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}