{
  "language": "Solidity",
  "sources": {
    "@chainlink/contracts/src/v0.8/interfaces/AggregatorInterface.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorInterface {\n  function latestAnswer() external view returns (int256);\n\n  function latestTimestamp() external view returns (uint256);\n\n  function latestRound() external view returns (uint256);\n\n  function getAnswer(uint256 roundId) external view returns (int256);\n\n  function getTimestamp(uint256 roundId) external view returns (uint256);\n\n  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);\n\n  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);\n}\n"
    },
    "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./AggregatorInterface.sol\";\nimport \"./AggregatorV3Interface.sol\";\n\ninterface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}\n"
    },
    "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface AggregatorV3Interface {\n  function decimals() external view returns (uint8);\n\n  function description() external view returns (string memory);\n\n  function version() external view returns (uint256);\n\n  function getRoundData(uint80 _roundId)\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n\n  function latestRoundData()\n    external\n    view\n    returns (\n      uint80 roundId,\n      int256 answer,\n      uint256 startedAt,\n      uint256 updatedAt,\n      uint80 answeredInRound\n    );\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n    address private _pendingOwner;\n\n    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n    function __Ownable2Step_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable2Step_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Returns the address of the pending owner.\n     */\n    function pendingOwner() public view virtual returns (address) {\n        return _pendingOwner;\n    }\n\n    /**\n     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual override onlyOwner {\n        _pendingOwner = newOwner;\n        emit OwnershipTransferStarted(owner(), newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual override {\n        delete _pendingOwner;\n        super._transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev The new owner accepts the ownership transfer.\n     */\n    function acceptOwnership() public virtual {\n        address sender = _msgSender();\n        require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n        _transferOwnership(sender);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    function __Ownable_init() internal onlyInitializing {\n        __Ownable_init_unchained();\n    }\n\n    function __Ownable_init_unchained() internal onlyInitializing {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n     * constructor.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = !_initializing;\n        require(\n            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n            \"Initializable: contract is already initialized\"\n        );\n        _initialized = 1;\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: setting the version to 255 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint8 version) {\n        require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n        _initialized = version;\n        _initializing = true;\n        _;\n        _initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        require(!_initializing, \"Initializable: contract is initializing\");\n        if (_initialized != type(uint8).max) {\n            _initialized = type(uint8).max;\n            emit Initialized(type(uint8).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint8) {\n        return _initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _initializing;\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract PausableUpgradeable is Initializable, ContextUpgradeable {\n    /**\n     * @dev Emitted when the pause is triggered by `account`.\n     */\n    event Paused(address account);\n\n    /**\n     * @dev Emitted when the pause is lifted by `account`.\n     */\n    event Unpaused(address account);\n\n    bool private _paused;\n\n    /**\n     * @dev Initializes the contract in unpaused state.\n     */\n    function __Pausable_init() internal onlyInitializing {\n        __Pausable_init_unchained();\n    }\n\n    function __Pausable_init_unchained() internal onlyInitializing {\n        _paused = false;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is not paused.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    modifier whenNotPaused() {\n        _requireNotPaused();\n        _;\n    }\n\n    /**\n     * @dev Modifier to make a function callable only when the contract is paused.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    modifier whenPaused() {\n        _requirePaused();\n        _;\n    }\n\n    /**\n     * @dev Returns true if the contract is paused, and false otherwise.\n     */\n    function paused() public view virtual returns (bool) {\n        return _paused;\n    }\n\n    /**\n     * @dev Throws if the contract is paused.\n     */\n    function _requireNotPaused() internal view virtual {\n        require(!paused(), \"Pausable: paused\");\n    }\n\n    /**\n     * @dev Throws if the contract is not paused.\n     */\n    function _requirePaused() internal view virtual {\n        require(paused(), \"Pausable: not paused\");\n    }\n\n    /**\n     * @dev Triggers stopped state.\n     *\n     * Requirements:\n     *\n     * - The contract must not be paused.\n     */\n    function _pause() internal virtual whenNotPaused {\n        _paused = true;\n        emit Paused(_msgSender());\n    }\n\n    /**\n     * @dev Returns to normal state.\n     *\n     * Requirements:\n     *\n     * - The contract must be paused.\n     */\n    function _unpause() internal virtual whenPaused {\n        _paused = false;\n        emit Unpaused(_msgSender());\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[50] private __gap;\n}\n"
    },
    "@openzeppelin/contracts/access/AccessControl.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n    struct RoleData {\n        mapping(address => bool) members;\n        bytes32 adminRole;\n    }\n\n    mapping(bytes32 => RoleData) private _roles;\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with a standardized message including the required role.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     *\n     * _Available since v4.1._\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n        return _roles[role].members[account];\n    }\n\n    /**\n     * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n     * Overriding this function changes the behavior of the {onlyRole} modifier.\n     *\n     * Format of the revert message is described in {_checkRole}.\n     *\n     * _Available since v4.6._\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Revert with a standard message if `account` is missing `role`.\n     *\n     * The format of the revert reason is given by the following regular expression:\n     *\n     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert(\n                string(\n                    abi.encodePacked(\n                        \"AccessControl: account \",\n                        Strings.toHexString(account),\n                        \" is missing role \",\n                        Strings.toHexString(uint256(role), 32)\n                    )\n                )\n            );\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n        return _roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address account) public virtual override {\n        require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event. Note that unlike {grantRole}, this function doesn't perform any\n     * checks on the calling account.\n     *\n     * May emit a {RoleGranted} event.\n     *\n     * [WARNING]\n     * ====\n     * This function should only be called from the constructor when setting\n     * up the initial roles for the system.\n     *\n     * Using this function in any other way is effectively circumventing the admin\n     * system imposed by {AccessControl}.\n     * ====\n     *\n     * NOTE: This function is deprecated in favor of {_grantRole}.\n     */\n    function _setupRole(bytes32 role, address account) internal virtual {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        _roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual {\n        if (!hasRole(role, account)) {\n            _roles[role].members[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n        }\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual {\n        if (hasRole(role, account)) {\n            _roles[role].members[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/access/IAccessControl.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted signaling this.\n     *\n     * _Available since v3.1._\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call, an admin role\n     * bearer except when using {AccessControl-_setupRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
    },
    "@openzeppelin/contracts/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor() {\n        _transferOwnership(_msgSender());\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
    },
    "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
    },
    "@openzeppelin/contracts/interfaces/IERC1967.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n *\n * _Available since v4.8.3._\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"
    },
    "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/beacon/BeaconProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../Proxy.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements a proxy that gets the implementation address for each call from an {UpgradeableBeacon}.\n *\n * The beacon address is stored in storage slot `uint256(keccak256('eip1967.proxy.beacon')) - 1`, so that it doesn't\n * conflict with the storage layout of the implementation behind the proxy.\n *\n * _Available since v3.4._\n */\ncontract BeaconProxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the proxy with `beacon`.\n     *\n     * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon. This\n     * will typically be an encoded function call, and allows initializing the storage of the proxy like a Solidity\n     * constructor.\n     *\n     * Requirements:\n     *\n     * - `beacon` must be a contract with the interface {IBeacon}.\n     */\n    constructor(address beacon, bytes memory data) payable {\n        _upgradeBeaconToAndCall(beacon, data, false);\n    }\n\n    /**\n     * @dev Returns the current beacon address.\n     */\n    function _beacon() internal view virtual returns (address) {\n        return _getBeacon();\n    }\n\n    /**\n     * @dev Returns the current implementation address of the associated beacon.\n     */\n    function _implementation() internal view virtual override returns (address) {\n        return IBeacon(_getBeacon()).implementation();\n    }\n\n    /**\n     * @dev Changes the proxy to use a new beacon. Deprecated: see {_upgradeBeaconToAndCall}.\n     *\n     * If `data` is nonempty, it's used as data in a delegate call to the implementation returned by the beacon.\n     *\n     * Requirements:\n     *\n     * - `beacon` must be a contract.\n     * - The implementation returned by `beacon` must be a contract.\n     */\n    function _setBeacon(address beacon, bytes memory data) internal virtual {\n        _upgradeBeaconToAndCall(beacon, data, false);\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
    },
    "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/UpgradeableBeacon.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IBeacon.sol\";\nimport \"../../access/Ownable.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This contract is used in conjunction with one or more instances of {BeaconProxy} to determine their\n * implementation contract, which is where they will delegate all function calls.\n *\n * An owner is able to change the implementation the beacon points to, thus upgrading the proxies that use this beacon.\n */\ncontract UpgradeableBeacon is IBeacon, Ownable {\n    address private _implementation;\n\n    /**\n     * @dev Emitted when the implementation returned by the beacon is changed.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Sets the address of the initial implementation, and the deployer account as the owner who can upgrade the\n     * beacon.\n     */\n    constructor(address implementation_) {\n        _setImplementation(implementation_);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function implementation() public view virtual override returns (address) {\n        return _implementation;\n    }\n\n    /**\n     * @dev Upgrades the beacon to a new implementation.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * Requirements:\n     *\n     * - msg.sender must be the owner of the contract.\n     * - `newImplementation` must be a contract.\n     */\n    function upgradeTo(address newImplementation) public virtual onlyOwner {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Sets the implementation contract address for this beacon\n     *\n     * Requirements:\n     *\n     * - `newImplementation` must be a contract.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"UpgradeableBeacon: implementation is not a contract\");\n        _implementation = newImplementation;\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/IERC1967.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n */\nabstract contract ERC1967Upgrade is IERC1967 {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(\n            Address.isContract(IBeacon(newBeacon).implementation()),\n            \"ERC1967: beacon implementation is not a contract\"\n        );\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overridden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"
    },
    "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(ITransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(ITransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(\n        ITransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"
    },
    "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}\n * does not implement this interface directly, and some of its functions are implemented by an internal dispatch\n * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not\n * include them in the ABI so this interface must be used to interact with it.\n */\ninterface ITransparentUpgradeableProxy is IERC1967 {\n    function admin() external view returns (address);\n\n    function implementation() external view returns (address);\n\n    function changeAdmin(address) external;\n\n    function upgradeTo(address) external;\n\n    function upgradeToAndCall(address, bytes memory) external payable;\n}\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n *\n * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not\n * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch\n * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to\n * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the\n * implementation.\n *\n * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler\n * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function\n * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could\n * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     *\n     * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the\n     * implementation provides a function with the same selector.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior\n     */\n    function _fallback() internal virtual override {\n        if (msg.sender == _getAdmin()) {\n            bytes memory ret;\n            bytes4 selector = msg.sig;\n            if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {\n                ret = _dispatchUpgradeTo();\n            } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {\n                ret = _dispatchUpgradeToAndCall();\n            } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {\n                ret = _dispatchChangeAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.admin.selector) {\n                ret = _dispatchAdmin();\n            } else if (selector == ITransparentUpgradeableProxy.implementation.selector) {\n                ret = _dispatchImplementation();\n            } else {\n                revert(\"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n            }\n            assembly {\n                return(add(ret, 0x20), mload(ret))\n            }\n        } else {\n            super._fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function _dispatchAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address admin = _getAdmin();\n        return abi.encode(admin);\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function _dispatchImplementation() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address implementation = _implementation();\n        return abi.encode(implementation);\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _dispatchChangeAdmin() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newAdmin = abi.decode(msg.data[4:], (address));\n        _changeAdmin(newAdmin);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     */\n    function _dispatchUpgradeTo() private returns (bytes memory) {\n        _requireZeroValue();\n\n        address newImplementation = abi.decode(msg.data[4:], (address));\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     */\n    function _dispatchUpgradeToAndCall() private returns (bytes memory) {\n        (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));\n        _upgradeToAndCall(newImplementation, data, true);\n\n        return \"\";\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to\n     * emulate some proxy functions being non-payable while still allowing value to pass through.\n     */\n    function _requireZeroValue() private {\n        require(msg.value == 0);\n    }\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * The default value of {decimals} is 18. To change this, you should override\n * this function so it returns a different value.\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n    mapping(address => uint256) private _balances;\n\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}.\n     *\n     * All two of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor(string memory name_, string memory symbol_) {\n        _name = name_;\n        _symbol = symbol_;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view virtual override returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view virtual override returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the default value returned by this function, unless\n     * it's overridden.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view virtual override returns (uint8) {\n        return 18;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view virtual override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view virtual override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address to, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _transfer(owner, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n     * `transferFrom`. This is semantically equivalent to an infinite approval.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * NOTE: Does not update the allowance if the current allowance\n     * is the maximum `uint256`.\n     *\n     * Requirements:\n     *\n     * - `from` and `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``from``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n        address spender = _msgSender();\n        _spendAllowance(from, spender, amount);\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        _approve(owner, spender, allowance(owner, spender) + addedValue);\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        address owner = _msgSender();\n        uint256 currentAllowance = allowance(owner, spender);\n        require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n        unchecked {\n            _approve(owner, spender, currentAllowance - subtractedValue);\n        }\n\n        return true;\n    }\n\n    /**\n     * @dev Moves `amount` of tokens from `from` to `to`.\n     *\n     * This internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `from` cannot be the zero address.\n     * - `to` cannot be the zero address.\n     * - `from` must have a balance of at least `amount`.\n     */\n    function _transfer(address from, address to, uint256 amount) internal virtual {\n        require(from != address(0), \"ERC20: transfer from the zero address\");\n        require(to != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(from, to, amount);\n\n        uint256 fromBalance = _balances[from];\n        require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n        unchecked {\n            _balances[from] = fromBalance - amount;\n            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n            // decrementing then incrementing.\n            _balances[to] += amount;\n        }\n\n        emit Transfer(from, to, amount);\n\n        _afterTokenTransfer(from, to, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply += amount;\n        unchecked {\n            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n            _balances[account] += amount;\n        }\n        emit Transfer(address(0), account, amount);\n\n        _afterTokenTransfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        uint256 accountBalance = _balances[account];\n        require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n        unchecked {\n            _balances[account] = accountBalance - amount;\n            // Overflow not possible: amount <= accountBalance <= totalSupply.\n            _totalSupply -= amount;\n        }\n\n        emit Transfer(account, address(0), amount);\n\n        _afterTokenTransfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n     *\n     * Does not update the allowance amount in case of infinite allowance.\n     * Revert if not enough allowance is available.\n     *\n     * Might emit an {Approval} event.\n     */\n    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n        uint256 currentAllowance = allowance(owner, spender);\n        if (currentAllowance != type(uint256).max) {\n            require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n            unchecked {\n                _approve(owner, spender, currentAllowance - amount);\n            }\n        }\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n    /**\n     * @dev Hook that is called after any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * has been transferred to `to`.\n     * - when `from` is zero, `amount` tokens have been minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            /// @solidity memory-safe-assembly\n            assembly {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert(errorMessage);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/introspection/ERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
    },
    "@openzeppelin/contracts/utils/math/Math.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Down, // Toward negative infinity\n        Up, // Toward infinity\n        Zero // Toward zero\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds up instead\n     * of rounding down.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b - 1) / b can overflow on addition, so we distribute.\n        return a == 0 ? 0 : (a - 1) / b + 1;\n    }\n\n    /**\n     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n     * with further edits by Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n            // variables such that product = prod1 * 2^256 + prod0.\n            uint256 prod0; // Least significant 256 bits of the product\n            uint256 prod1; // Most significant 256 bits of the product\n            assembly {\n                let mm := mulmod(x, y, not(0))\n                prod0 := mul(x, y)\n                prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n            }\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (prod1 == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return prod0 / denominator;\n            }\n\n            // Make sure the result is less than 2^256. Also prevents denominator == 0.\n            require(denominator > prod1, \"Math: mulDiv overflow\");\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [prod1 prod0].\n            uint256 remainder;\n            assembly {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                prod1 := sub(prod1, gt(remainder, prod0))\n                prod0 := sub(prod0, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n            // See https://cs.stackexchange.com/q/138556/92363.\n\n            // Does not overflow because the denominator cannot be zero at this stage in the function.\n            uint256 twos = denominator & (~denominator + 1);\n            assembly {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [prod1 prod0] by twos.\n                prod0 := div(prod0, twos)\n\n                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from prod1 into prod0.\n            prod0 |= prod1 * twos;\n\n            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv = 1 mod 2^4.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n            // in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2^8\n            inverse *= 2 - denominator * inverse; // inverse mod 2^16\n            inverse *= 2 - denominator * inverse; // inverse mod 2^32\n            inverse *= 2 - denominator * inverse; // inverse mod 2^64\n            inverse *= 2 - denominator * inverse; // inverse mod 2^128\n            inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n            // is no longer required.\n            result = prod0 * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        uint256 result = mulDiv(x, y, denominator);\n        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n            result += 1;\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n     *\n     * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        if (a == 0) {\n            return 0;\n        }\n\n        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n        //\n        // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n        //\n        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n        //\n        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n        uint256 result = 1 << (log2(a) >> 1);\n\n        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n        // into the expected uint128 result.\n        unchecked {\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            result = (result + a / result) >> 1;\n            return min(result, a / result);\n        }\n    }\n\n    /**\n     * @notice Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 128;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 64;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 32;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 16;\n            }\n            if (value >> 8 > 0) {\n                value >>= 8;\n                result += 8;\n            }\n            if (value >> 4 > 0) {\n                value >>= 4;\n                result += 4;\n            }\n            if (value >> 2 > 0) {\n                value >>= 2;\n                result += 2;\n            }\n            if (value >> 1 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256, rounded down, of a positive value.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >> 128 > 0) {\n                value >>= 128;\n                result += 16;\n            }\n            if (value >> 64 > 0) {\n                value >>= 64;\n                result += 8;\n            }\n            if (value >> 32 > 0) {\n                value >>= 32;\n                result += 4;\n            }\n            if (value >> 16 > 0) {\n                value >>= 16;\n                result += 2;\n            }\n            if (value >> 8 > 0) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/math/SafeCast.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n *\n * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing\n * all math on `uint256` and `int256` and then downcasting.\n */\nlibrary SafeCast {\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        require(value <= type(uint248).max, \"SafeCast: value doesn't fit in 248 bits\");\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        require(value <= type(uint240).max, \"SafeCast: value doesn't fit in 240 bits\");\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        require(value <= type(uint232).max, \"SafeCast: value doesn't fit in 232 bits\");\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        require(value <= type(uint224).max, \"SafeCast: value doesn't fit in 224 bits\");\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        require(value <= type(uint216).max, \"SafeCast: value doesn't fit in 216 bits\");\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        require(value <= type(uint208).max, \"SafeCast: value doesn't fit in 208 bits\");\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        require(value <= type(uint200).max, \"SafeCast: value doesn't fit in 200 bits\");\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        require(value <= type(uint192).max, \"SafeCast: value doesn't fit in 192 bits\");\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        require(value <= type(uint184).max, \"SafeCast: value doesn't fit in 184 bits\");\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        require(value <= type(uint176).max, \"SafeCast: value doesn't fit in 176 bits\");\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        require(value <= type(uint168).max, \"SafeCast: value doesn't fit in 168 bits\");\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        require(value <= type(uint160).max, \"SafeCast: value doesn't fit in 160 bits\");\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        require(value <= type(uint152).max, \"SafeCast: value doesn't fit in 152 bits\");\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        require(value <= type(uint144).max, \"SafeCast: value doesn't fit in 144 bits\");\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        require(value <= type(uint136).max, \"SafeCast: value doesn't fit in 136 bits\");\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        require(value <= type(uint128).max, \"SafeCast: value doesn't fit in 128 bits\");\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        require(value <= type(uint120).max, \"SafeCast: value doesn't fit in 120 bits\");\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        require(value <= type(uint112).max, \"SafeCast: value doesn't fit in 112 bits\");\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        require(value <= type(uint104).max, \"SafeCast: value doesn't fit in 104 bits\");\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.2._\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        require(value <= type(uint96).max, \"SafeCast: value doesn't fit in 96 bits\");\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        require(value <= type(uint88).max, \"SafeCast: value doesn't fit in 88 bits\");\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        require(value <= type(uint80).max, \"SafeCast: value doesn't fit in 80 bits\");\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        require(value <= type(uint72).max, \"SafeCast: value doesn't fit in 72 bits\");\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        require(value <= type(uint64).max, \"SafeCast: value doesn't fit in 64 bits\");\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        require(value <= type(uint56).max, \"SafeCast: value doesn't fit in 56 bits\");\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        require(value <= type(uint48).max, \"SafeCast: value doesn't fit in 48 bits\");\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        require(value <= type(uint40).max, \"SafeCast: value doesn't fit in 40 bits\");\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        require(value <= type(uint32).max, \"SafeCast: value doesn't fit in 32 bits\");\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        require(value <= type(uint24).max, \"SafeCast: value doesn't fit in 24 bits\");\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        require(value <= type(uint16).max, \"SafeCast: value doesn't fit in 16 bits\");\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v2.5._\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        require(value <= type(uint8).max, \"SafeCast: value doesn't fit in 8 bits\");\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     *\n     * _Available since v3.0._\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        require(value >= 0, \"SafeCast: value must be positive\");\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 248 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 240 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 232 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 224 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 216 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 208 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 200 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 192 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 184 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 176 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 168 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 160 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 152 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 144 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 136 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 128 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 120 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 112 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 104 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 96 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 88 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 80 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 72 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 64 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 56 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 48 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 40 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 32 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     *\n     * _Available since v4.7._\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 24 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 16 bits\");\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     *\n     * _Available since v3.1._\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        require(downcasted == value, \"SafeCast: value doesn't fit in 8 bits\");\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     *\n     * _Available since v3.0._\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        require(value <= uint256(type(int256).max), \"SafeCast: value doesn't fit in an int256\");\n        return int256(value);\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/math/SignedMath.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n    /**\n     * @dev Returns the largest of two signed numbers.\n     */\n    function max(int256 a, int256 b) internal pure returns (int256) {\n        return a > b ? a : b;\n    }\n\n    /**\n     * @dev Returns the smallest of two signed numbers.\n     */\n    function min(int256 a, int256 b) internal pure returns (int256) {\n        return a < b ? a : b;\n    }\n\n    /**\n     * @dev Returns the average of two signed numbers without overflow.\n     * The result is rounded towards zero.\n     */\n    function average(int256 a, int256 b) internal pure returns (int256) {\n        // Formula from the book \"Hacker's Delight\"\n        int256 x = (a & b) + ((a ^ b) >> 1);\n        return x + (int256(uint256(x) >> 255) & (a ^ b));\n    }\n\n    /**\n     * @dev Returns the absolute unsigned value of a signed value.\n     */\n    function abs(int256 n) internal pure returns (uint256) {\n        unchecked {\n            // must be unchecked in order to support `n = type(int256).min`\n            return uint256(n >= 0 ? n : -n);\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/StorageSlot.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._\n * _Available since v4.9 for `string`, `bytes`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            r.slot := store.slot\n        }\n    }\n}\n"
    },
    "@openzeppelin/contracts/utils/Strings.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n    bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n    uint8 private constant _ADDRESS_LENGTH = 20;\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n     */\n    function toString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            uint256 length = Math.log10(value) + 1;\n            string memory buffer = new string(length);\n            uint256 ptr;\n            /// @solidity memory-safe-assembly\n            assembly {\n                ptr := add(buffer, add(32, length))\n            }\n            while (true) {\n                ptr--;\n                /// @solidity memory-safe-assembly\n                assembly {\n                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n                }\n                value /= 10;\n                if (value == 0) break;\n            }\n            return buffer;\n        }\n    }\n\n    /**\n     * @dev Converts a `int256` to its ASCII `string` decimal representation.\n     */\n    function toString(int256 value) internal pure returns (string memory) {\n        return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n     */\n    function toHexString(uint256 value) internal pure returns (string memory) {\n        unchecked {\n            return toHexString(value, Math.log256(value) + 1);\n        }\n    }\n\n    /**\n     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n     */\n    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n        bytes memory buffer = new bytes(2 * length + 2);\n        buffer[0] = \"0\";\n        buffer[1] = \"x\";\n        for (uint256 i = 2 * length + 1; i > 1; --i) {\n            buffer[i] = _SYMBOLS[value & 0xf];\n            value >>= 4;\n        }\n        require(value == 0, \"Strings: hex length insufficient\");\n        return string(buffer);\n    }\n\n    /**\n     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n     */\n    function toHexString(address addr) internal pure returns (string memory) {\n        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n    }\n\n    /**\n     * @dev Returns true if the two strings are equal.\n     */\n    function equal(string memory a, string memory b) internal pure returns (bool) {\n        return keccak256(bytes(a)) == keccak256(bytes(b));\n    }\n}\n"
    },
    "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlledV8\n * @author Venus\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.8.13)\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\n */\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n    /// @notice Access control manager contract\n    IAccessControlManagerV8 private _accessControlManager;\n\n    /**\n     * @dev This empty reserved space is put in place to allow future versions to add new\n     * variables without shifting down storage in the inheritance chain.\n     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n     */\n    uint256[49] private __gap;\n\n    /// @notice Emitted when access control manager contract address is changed\n    event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\n\n    /// @notice Thrown when the action is prohibited by AccessControlManager\n    error Unauthorized(address sender, address calledContract, string methodSignature);\n\n    function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n        __Ownable2Step_init();\n        __AccessControlled_init_unchained(accessControlManager_);\n    }\n\n    function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n        _setAccessControlManager(accessControlManager_);\n    }\n\n    /**\n     * @notice Sets the address of AccessControlManager\n     * @dev Admin function to set address of AccessControlManager\n     * @param accessControlManager_ The new address of the AccessControlManager\n     * @custom:event Emits NewAccessControlManager event\n     * @custom:access Only Governance\n     */\n    function setAccessControlManager(address accessControlManager_) external onlyOwner {\n        _setAccessControlManager(accessControlManager_);\n    }\n\n    /**\n     * @notice Returns the address of the access control manager contract\n     */\n    function accessControlManager() external view returns (IAccessControlManagerV8) {\n        return _accessControlManager;\n    }\n\n    /**\n     * @dev Internal function to set address of AccessControlManager\n     * @param accessControlManager_ The new address of the AccessControlManager\n     */\n    function _setAccessControlManager(address accessControlManager_) internal {\n        require(address(accessControlManager_) != address(0), \"invalid acess control manager address\");\n        address oldAccessControlManager = address(_accessControlManager);\n        _accessControlManager = IAccessControlManagerV8(accessControlManager_);\n        emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\n    }\n\n    /**\n     * @notice Reverts if the call is not allowed by AccessControlManager\n     * @param signature Method signature\n     */\n    function _checkAccessAllowed(string memory signature) internal view {\n        bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\n\n        if (!isAllowedToCall) {\n            revert Unauthorized(msg.sender, address(this), signature);\n        }\n    }\n}\n"
    },
    "@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlManager\n * @author Venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl extending it in a way to standartize access control within Venus Smart Contract Ecosystem.\n * @notice Access control plays a crucial role in the Venus governance model. It is used to restrict functions so that they can only be called from one\n * account or list of accounts (EOA or Contract Accounts).\n *\n * The implementation of `AccessControlManager`(https://github.com/VenusProtocol/governance-contracts/blob/main/contracts/Governance/AccessControlManager.sol)\n * inherits the [Open Zeppelin AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol)\n * contract as a base for role management logic. There are two role types: admin and granular permissions.\n * \n * ## Granular Roles\n * \n * Granular roles are built by hashing the contract address and its function signature. For example, given contract `Foo` with function `Foo.bar()` which\n * is guarded by ACM, calling `giveRolePermission` for account B do the following:\n * \n * 1. Compute `keccak256(contractFooAddress,functionSignatureBar)`\n * 1. Add the computed role to the roles of account B\n * 1. Account B now can call `ContractFoo.bar()`\n * \n * ## Admin Roles\n * \n * Admin roles allow for an address to call a function signature on any contract guarded by the `AccessControlManager`. This is particularly useful for\n * contracts created by factories.\n * \n * For Admin roles a null address is hashed in place of the contract address (`keccak256(0x0000000000000000000000000000000000000000,functionSignatureBar)`.\n * \n * In the previous example, giving account B the admin role, account B will have permissions to call the `bar()` function on any contract that is guarded by\n * ACM, not only contract A.\n * \n * ## Protocol Integration\n * \n * All restricted functions in Venus Protocol use a hook to ACM in order to check if the caller has the right permission to call the guarded function.\n * `AccessControlledV5` and `AccessControlledV8` abstract contract makes this integration easier. They call ACM's external method\n * `isAllowedToCall(address caller, string functionSig)`. Here is an example of how `setCollateralFactor` function in `Comptroller` is integrated with ACM:\n\n```\n    contract Comptroller is [...] AccessControlledV8 {\n        [...]\n        function setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa) external {\n            _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n            [...]\n        }\n    }\n```\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n    /// @notice Emitted when an account is given a permission to a certain contract function\n    /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n    /// can call any contract function with this signature\n    event PermissionGranted(address account, address contractAddress, string functionSig);\n\n    /// @notice Emitted when an account is revoked a permission to a certain contract function\n    event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n    constructor() {\n        // Grant the contract deployer the default admin role: it will be able\n        // to grant and revoke any roles\n        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n    }\n\n    /**\n     * @notice Gives a function call permission to one single account\n     * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n     * @param contractAddress address of contract for which call permissions will be granted\n     * @dev if contractAddress is zero address, the account can access the specified function\n     *      on **any** contract managed by this ACL\n     * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n     * @param accountToPermit account that will be given access to the contract function\n     * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n     */\n    function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n        bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n        grantRole(role, accountToPermit);\n        emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n    }\n\n    /**\n     * @notice Revokes an account's permission to a particular function call\n     * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n     * \t\tMay emit a {RoleRevoked} event.\n     * @param contractAddress address of contract for which call permissions will be revoked\n     * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n     * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n     */\n    function revokeCallPermission(\n        address contractAddress,\n        string calldata functionSig,\n        address accountToRevoke\n    ) public {\n        bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n        revokeRole(role, accountToRevoke);\n        emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n    }\n\n    /**\n     * @notice Verifies if the given account can call a contract's guarded function\n     * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n     * @param account for which call permissions will be checked\n     * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n     * @return false if the user account cannot call the particular contract function\n     *\n     */\n    function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n        bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n        if (hasRole(role, account)) {\n            return true;\n        } else {\n            role = keccak256(abi.encodePacked(address(0), functionSig));\n            return hasRole(role, account);\n        }\n    }\n\n    /**\n     * @notice Verifies if the given account can call a contract's guarded function\n     * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n     * @param account for which call permissions will be checked against\n     * @param contractAddress address of the restricted contract\n     * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n     * @return false if the user account cannot call the particular contract function\n     */\n    function hasPermission(\n        address account,\n        address contractAddress,\n        string calldata functionSig\n    ) public view returns (bool) {\n        bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n        return hasRole(role, account);\n    }\n}\n"
    },
    "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\n/**\n * @title IAccessControlManagerV8\n * @author Venus\n * @notice Interface implemented by the `AccessControlManagerV8` contract.\n */\ninterface IAccessControlManagerV8 is IAccessControl {\n    function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n    function revokeCallPermission(\n        address contractAddress,\n        string calldata functionSig,\n        address accountToRevoke\n    ) external;\n\n    function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\n\n    function hasPermission(\n        address account,\n        address contractAddress,\n        string calldata functionSig\n    ) external view returns (bool);\n}\n"
    },
    "@venusprotocol/solidity-utilities/contracts/constants.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\nuint256 constant EXP_SCALE = 1e18;\n\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\nuint256 constant MANTISSA_ONE = EXP_SCALE;\n\n/// @dev The approximate number of seconds per year\nuint256 constant SECONDS_PER_YEAR = 31_536_000;\n"
    },
    "@venusprotocol/solidity-utilities/contracts/validators.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Thrown if the supplied value is 0 where it is not allowed\nerror ZeroValueNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n    if (address_ == address(0)) {\n        revert ZeroAddressNotAllowed();\n    }\n}\n\n/// @notice Checks if the provided value is nonzero, reverts otherwise\n/// @param value_ Value to check\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\nfunction ensureNonzeroValue(uint256 value_) pure {\n    if (value_ == 0) {\n        revert ZeroValueNotAllowed();\n    }\n}\n"
    },
    "contracts/hardhat-dependency-compiler/@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport '@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol';\n"
    },
    "contracts/hardhat-dependency-compiler/hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport 'hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol';\n"
    },
    "contracts/hardhat-dependency-compiler/hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity >0.0.0;\nimport 'hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol';\n"
    },
    "contracts/interfaces/FeedRegistryInterface.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface FeedRegistryInterface {\n    function latestRoundDataByName(\n        string memory base,\n        string memory quote\n    )\n        external\n        view\n        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n\n    function decimalsByName(string memory base, string memory quote) external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/IAnkrBNB.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IAnkrBNB {\n    function sharesToBonds(uint256 amount) external view returns (uint256);\n    function decimals() external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/IEtherFiLiquidityPool.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IEtherFiLiquidityPool {\n    function amountForShare(uint256 _share) external view returns (uint256);\n}\n"
    },
    "contracts/interfaces/IPendlePtOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IPendlePtOracle {\n    function getPtToAssetRate(address market, uint32 duration) external view returns (uint256);\n    function getOracleState(\n        address market,\n        uint32 duration\n    )\n        external\n        view\n        returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied);\n}\n"
    },
    "contracts/interfaces/IPStakePool.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IPStakePool {\n    struct Data {\n        uint256 totalWei;\n        uint256 poolTokenSupply;\n    }\n\n    /**\n     * @dev The current exchange rate for converting stkBNB to BNB.\n     */\n    function exchangeRate() external view returns (Data memory);\n}\n"
    },
    "contracts/interfaces/ISFrax.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface ISFrax {\n    function convertToAssets(uint256 shares) external view returns (uint256);\n    function decimals() external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/ISfrxEthFraxOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface ISfrxEthFraxOracle {\n    function getPrices() external view returns (bool _isbadData, uint256 _priceLow, uint256 _priceHigh);\n}\n"
    },
    "contracts/interfaces/IStaderStakeManager.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IStaderStakeManager {\n    function convertBnbXToBnb(uint256 _amount) external view returns (uint256);\n}\n"
    },
    "contracts/interfaces/IStETH.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface IStETH {\n    function getPooledEthByShares(uint256 _sharesAmount) external view returns (uint256);\n    function decimals() external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/ISynclubStakeManager.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface ISynclubStakeManager {\n    function convertSnBnbToBnb(uint256 _amount) external view returns (uint256);\n}\n"
    },
    "contracts/interfaces/IWBETH.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IWBETH {\n    function exchangeRate() external view returns (uint256);\n    function decimals() external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/OracleInterface.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface OracleInterface {\n    function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n    function updatePrice(address vToken) external;\n\n    function updateAssetPrice(address asset) external;\n\n    function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface TwapInterface is OracleInterface {\n    function updateTwap(address asset) external returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n    function validatePriceWithAnchorPrice(\n        address asset,\n        uint256 reporterPrice,\n        uint256 anchorPrice\n    ) external view returns (bool);\n}\n"
    },
    "contracts/interfaces/PublicResolverInterface.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity ^0.8.25;\n\ninterface PublicResolverInterface {\n    function addr(bytes32 node) external view returns (address payable);\n}\n"
    },
    "contracts/interfaces/PythInterface.sol": {
      "content": "// SPDX-License-Identifier: Apache-2.0\n// SPDX-FileCopyrightText: 2021 Pyth Data Foundation\npragma solidity ^0.8.25;\n\ncontract PythStructs {\n    // A price with a degree of uncertainty, represented as a price +- a confidence interval.\n    //\n    // The confidence interval roughly corresponds to the standard error of a normal distribution.\n    // Both the price and confidence are stored in a fixed-point numeric representation,\n    // `x * (10^expo)`, where `expo` is the exponent.\n    //\n    // Please refer to the documentation at https://docs.pyth.network/consumers/best-practices for how\n    // to how this price safely.\n    struct Price {\n        // Price\n        int64 price;\n        // Confidence interval around the price\n        uint64 conf;\n        // Price exponent\n        int32 expo;\n        // Unix timestamp describing when the price was published\n        uint256 publishTime;\n    }\n\n    // PriceFeed represents a current aggregate price from pyth publisher feeds.\n    struct PriceFeed {\n        // The price ID.\n        bytes32 id;\n        // Latest available price\n        Price price;\n        // Latest available exponentially-weighted moving average price\n        Price emaPrice;\n    }\n}\n\n/// @title Consume prices from the Pyth Network (https://pyth.network/).\n/// @dev Please refer to the guidance at https://docs.pyth.network/consumers/best-practices\n/// for how to consume prices safely.\n/// @author Pyth Data Association\ninterface IPyth {\n    /// @dev Emitted when an update for price feed with `id` is processed successfully.\n    /// @param id The Pyth Price Feed ID.\n    /// @param fresh True if the price update is more recent and stored.\n    /// @param chainId ID of the source chain that the batch price update containing this price.\n    /// This value comes from Wormhole, and you can find the corresponding chains\n    /// at https://docs.wormholenetwork.com/wormhole/contracts.\n    /// @param sequenceNumber Sequence number of the batch price update containing this price.\n    /// @param lastPublishTime Publish time of the previously stored price.\n    /// @param publishTime Publish time of the given price update.\n    /// @param price Price of the given price update.\n    /// @param conf Confidence interval of the given price update.\n    event PriceFeedUpdate(\n        bytes32 indexed id,\n        bool indexed fresh,\n        uint16 chainId,\n        uint64 sequenceNumber,\n        uint256 lastPublishTime,\n        uint256 publishTime,\n        int64 price,\n        uint64 conf\n    );\n\n    /// @dev Emitted when a batch price update is processed successfully.\n    /// @param chainId ID of the source chain that the batch price update comes from.\n    /// @param sequenceNumber Sequence number of the batch price update.\n    /// @param batchSize Number of prices within the batch price update.\n    /// @param freshPricesInBatch Number of prices that were more recent and were stored.\n    event BatchPriceFeedUpdate(uint16 chainId, uint64 sequenceNumber, uint256 batchSize, uint256 freshPricesInBatch);\n\n    /// @dev Emitted when a call to `updatePriceFeeds` is processed successfully.\n    /// @param sender Sender of the call (`msg.sender`).\n    /// @param batchCount Number of batches that this function processed.\n    /// @param fee Amount of paid fee for updating the prices.\n    event UpdatePriceFeeds(address indexed sender, uint256 batchCount, uint256 fee);\n\n    /// @notice Returns the period (in seconds) that a price feed is considered valid since its publish time\n    function getValidTimePeriod() external view returns (uint256 validTimePeriod);\n\n    /// @notice Returns the price and confidence interval.\n    /// @dev Reverts if the price has not been updated within the last `getValidTimePeriod()` seconds.\n    /// @param id The Pyth Price Feed ID of which to fetch the price and confidence interval.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPrice(bytes32 id) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price and confidence interval.\n    /// @dev Reverts if the EMA price is not available.\n    /// @param id The Pyth Price Feed ID of which to fetch the EMA price and confidence interval.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPrice(bytes32 id) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the price of a price feed without any sanity checks.\n    /// @dev This function returns the most recent price update in this contract without any recency checks.\n    /// This function is unsafe as the returned price update may be arbitrarily far in the past.\n    ///\n    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is\n    /// sufficiently recent for their application. If you are considering using this function, it may be\n    /// safer / easier to use either `getPrice` or `getPriceNoOlderThan`.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPriceUnsafe(bytes32 id) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the price that is no older than `age` seconds of the current time.\n    /// @dev This function is a sanity-checked version of `getPriceUnsafe` which is useful in\n    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently\n    /// recently.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getPriceNoOlderThan(bytes32 id, uint256 age) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price of a price feed without any sanity checks.\n    /// @dev This function returns the same price as `getEmaPrice` in the case where the price is available.\n    /// However, if the price is not recent this function returns the latest available price.\n    ///\n    /// The returned price can be from arbitrarily far in the past; this function makes no guarantees that\n    /// the returned price is recent or useful for any particular application.\n    ///\n    /// Users of this function should check the `publishTime` in the price to ensure that the returned price is\n    /// sufficiently recent for their application. If you are considering using this function, it may be\n    /// safer / easier to use either `getEmaPrice` or `getEmaPriceNoOlderThan`.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPriceUnsafe(bytes32 id) external view returns (PythStructs.Price memory price);\n\n    /// @notice Returns the exponentially-weighted moving average price that is no older than `age` seconds\n    /// of the current time.\n    /// @dev This function is a sanity-checked version of `getEmaPriceUnsafe` which is useful in\n    /// applications that require a sufficiently-recent price. Reverts if the price wasn't updated sufficiently\n    /// recently.\n    /// @return price - please read the documentation of PythStructs.Price to understand how to use this safely.\n    function getEmaPriceNoOlderThan(bytes32 id, uint256 age) external view returns (PythStructs.Price memory price);\n\n    /// @notice Update price feeds with given update messages.\n    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling\n    /// `getUpdateFee` with the length of the `updateData` array.\n    /// Prices will be updated if they are more recent than the current stored prices.\n    /// The call will succeed even if the update is not the most recent.\n    /// @dev Reverts if the transferred fee is not sufficient or the updateData is invalid.\n    /// @param updateData Array of price update data.\n    function updatePriceFeeds(bytes[] calldata updateData) external payable;\n\n    /// @notice Wrapper around updatePriceFeeds that rejects fast if a price update is not necessary. A price update is\n    /// necessary if the current on-chain publishTime is older than the given publishTime. It relies solely on the\n    /// given `publishTimes` for the price feeds and does not read the actual price\n    /// update publish time within `updateData`.\n    ///\n    /// This method requires the caller to pay a fee in wei; the required fee can be computed by calling\n    /// `getUpdateFee` with the length of the `updateData` array.\n    ///\n    /// `priceIds` and `publishTimes` are two arrays with the same size that correspond to senders known publishTime\n    /// of each priceId when calling this method. If all of price feeds within `priceIds` have updated and have\n    /// a newer or equal publish time than the given publish time, it will reject the transaction to save gas.\n    /// Otherwise, it calls updatePriceFeeds method to update the prices.\n    ///\n    /// @dev Reverts if update is not needed or the transferred fee is not sufficient or the updateData is invalid.\n    /// @param updateData Array of price update data.\n    /// @param priceIds Array of price ids.\n    /// @param publishTimes Array of publishTimes. `publishTimes[i]` corresponds to known `publishTime` of `priceIds[i]`\n    function updatePriceFeedsIfNecessary(\n        bytes[] calldata updateData,\n        bytes32[] calldata priceIds,\n        uint64[] calldata publishTimes\n    ) external payable;\n\n    /// @notice Returns the required fee to update an array of price updates.\n    /// @param updateDataSize Number of price updates.\n    /// @return feeAmount The required fee in Wei.\n    function getUpdateFee(uint256 updateDataSize) external view returns (uint256 feeAmount);\n}\n\nabstract contract AbstractPyth is IPyth {\n    /// @notice Returns the price feed with given id.\n    /// @dev Reverts if the price does not exist.\n    /// @param id The Pyth Price Feed ID of which to fetch the PriceFeed.\n    function queryPriceFeed(bytes32 id) public view virtual returns (PythStructs.PriceFeed memory priceFeed);\n\n    /// @notice Returns true if a price feed with the given id exists.\n    /// @param id The Pyth Price Feed ID of which to check its existence.\n    function priceFeedExists(bytes32 id) public view virtual returns (bool exists);\n\n    function getValidTimePeriod() public view virtual override returns (uint256 validTimePeriod);\n\n    function getPrice(bytes32 id) external view override returns (PythStructs.Price memory price) {\n        return getPriceNoOlderThan(id, getValidTimePeriod());\n    }\n\n    function getEmaPrice(bytes32 id) external view override returns (PythStructs.Price memory price) {\n        return getEmaPriceNoOlderThan(id, getValidTimePeriod());\n    }\n\n    function getPriceUnsafe(bytes32 id) public view override returns (PythStructs.Price memory price) {\n        PythStructs.PriceFeed memory priceFeed = queryPriceFeed(id);\n        return priceFeed.price;\n    }\n\n    function getPriceNoOlderThan(\n        bytes32 id,\n        uint256 age\n    ) public view override returns (PythStructs.Price memory price) {\n        price = getPriceUnsafe(id);\n\n        require(diff(block.timestamp, price.publishTime) <= age, \"no price available which is recent enough\");\n\n        return price;\n    }\n\n    function getEmaPriceUnsafe(bytes32 id) public view override returns (PythStructs.Price memory price) {\n        PythStructs.PriceFeed memory priceFeed = queryPriceFeed(id);\n        return priceFeed.emaPrice;\n    }\n\n    function getEmaPriceNoOlderThan(\n        bytes32 id,\n        uint256 age\n    ) public view override returns (PythStructs.Price memory price) {\n        price = getEmaPriceUnsafe(id);\n\n        require(diff(block.timestamp, price.publishTime) <= age, \"no ema price available which is recent enough\");\n\n        return price;\n    }\n\n    function diff(uint256 x, uint256 y) internal pure returns (uint256) {\n        if (x > y) {\n            return x - y;\n        } else {\n            return y - x;\n        }\n    }\n\n    // Access modifier is overridden to public to be able to call it locally.\n    function updatePriceFeeds(bytes[] calldata updateData) public payable virtual override;\n\n    function updatePriceFeedsIfNecessary(\n        bytes[] calldata updateData,\n        bytes32[] calldata priceIds,\n        uint64[] calldata publishTimes\n    ) external payable override {\n        require(priceIds.length == publishTimes.length, \"priceIds and publishTimes arrays should have same length\");\n\n        bool updateNeeded = false;\n        for (uint256 i = 0; i < priceIds.length; ) {\n            if (!priceFeedExists(priceIds[i]) || queryPriceFeed(priceIds[i]).price.publishTime < publishTimes[i]) {\n                updateNeeded = true;\n                break;\n            }\n            unchecked {\n                i++;\n            }\n        }\n\n        require(updateNeeded, \"no prices in the submitted batch have fresh prices, so this update will have no effect\");\n\n        updatePriceFeeds(updateData);\n    }\n}\n"
    },
    "contracts/interfaces/SIDRegistryInterface.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity ^0.8.25;\n\ninterface SIDRegistryInterface {\n    function resolver(bytes32 node) external view returns (address);\n}\n"
    },
    "contracts/interfaces/VBep20Interface.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface VBep20Interface is IERC20Metadata {\n    /**\n     * @notice Underlying asset for this VToken\n     */\n    function underlying() external view returns (address);\n}\n"
    },
    "contracts/oracles/AnkrBNBOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IAnkrBNB } from \"../interfaces/IAnkrBNB.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\n\n/**\n * @title AnkrBNBOracle\n * @author Venus\n * @notice This oracle fetches the price of ankrBNB asset\n */\ncontract AnkrBNBOracle is CorrelatedTokenOracle {\n    /// @notice This is used as token address of BNB on BSC\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address ankrBNB,\n        address resilientOracle\n    ) CorrelatedTokenOracle(ankrBNB, NATIVE_TOKEN_ADDR, resilientOracle) {}\n\n    /**\n     * @notice Fetches the amount of BNB for 1 ankrBNB\n     * @return amount The amount of BNB for ankrBNB\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return IAnkrBNB(CORRELATED_TOKEN).sharesToBonds(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/BinanceOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/SIDRegistryInterface.sol\";\nimport \"../interfaces/FeedRegistryInterface.sol\";\nimport \"../interfaces/PublicResolverInterface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title BinanceOracle\n * @author Venus\n * @notice This oracle fetches price of assets from Binance.\n */\ncontract BinanceOracle is AccessControlledV8, OracleInterface {\n    /// @notice Used to fetch feed registry address.\n    address public sidRegistryAddress;\n\n    /// @notice Set this as asset address for BNB. This is the underlying address for vBNB\n    address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Max stale period configuration for assets\n    mapping(string => uint256) public maxStalePeriod;\n\n    /// @notice Override symbols to be compatible with Binance feed registry\n    mapping(string => string) public symbols;\n\n    /// @notice Used to fetch price of assets used directly when space ID is not supported by current chain.\n    address public feedRegistryAddress;\n\n    /// @notice Emits when asset stale period is updated.\n    event MaxStalePeriodAdded(string indexed asset, uint256 maxStalePeriod);\n\n    /// @notice Emits when symbol of the asset is updated.\n    event SymbolOverridden(string indexed symbol, string overriddenSymbol);\n\n    /// @notice Emits when address of feed registry is updated.\n    event FeedRegistryUpdated(address indexed oldFeedRegistry, address indexed newFeedRegistry);\n\n    /**\n     * @notice Checks whether an address is null or not\n     */\n    modifier notNullAddress(address someone) {\n        if (someone == address(0)) revert(\"can't be zero address\");\n        _;\n    }\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Sets the contracts required to fetch prices\n     * @param _sidRegistryAddress Address of SID registry\n     * @param _accessControlManager Address of the access control manager contract\n     */\n    function initialize(address _sidRegistryAddress, address _accessControlManager) external initializer {\n        sidRegistryAddress = _sidRegistryAddress;\n        __AccessControlled_init(_accessControlManager);\n    }\n\n    /**\n     * @notice Used to set the max stale period of an asset\n     * @param symbol The symbol of the asset\n     * @param _maxStalePeriod The max stake period\n     */\n    function setMaxStalePeriod(string memory symbol, uint256 _maxStalePeriod) external {\n        _checkAccessAllowed(\"setMaxStalePeriod(string,uint256)\");\n        if (_maxStalePeriod == 0) revert(\"stale period can't be zero\");\n        if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n        maxStalePeriod[symbol] = _maxStalePeriod;\n        emit MaxStalePeriodAdded(symbol, _maxStalePeriod);\n    }\n\n    /**\n     * @notice Used to override a symbol when fetching price\n     * @param symbol The symbol to override\n     * @param overrideSymbol The symbol after override\n     */\n    function setSymbolOverride(string calldata symbol, string calldata overrideSymbol) external {\n        _checkAccessAllowed(\"setSymbolOverride(string,string)\");\n        if (bytes(symbol).length == 0) revert(\"symbol cannot be empty\");\n\n        symbols[symbol] = overrideSymbol;\n        emit SymbolOverridden(symbol, overrideSymbol);\n    }\n\n    /**\n     * @notice Used to set feed registry address when current chain does not support space ID.\n     * @param newfeedRegistryAddress Address of new feed registry.\n     */\n    function setFeedRegistryAddress(\n        address newfeedRegistryAddress\n    ) external notNullAddress(newfeedRegistryAddress) onlyOwner {\n        if (sidRegistryAddress != address(0)) revert(\"sidRegistryAddress must be zero\");\n        emit FeedRegistryUpdated(feedRegistryAddress, newfeedRegistryAddress);\n        feedRegistryAddress = newfeedRegistryAddress;\n    }\n\n    /**\n     * @notice Uses Space ID to fetch the feed registry address\n     * @return feedRegistryAddress Address of binance oracle feed registry.\n     */\n    function getFeedRegistryAddress() public view returns (address) {\n        bytes32 nodeHash = 0x94fe3821e0768eb35012484db4df61890f9a6ca5bfa984ef8ff717e73139faff;\n\n        SIDRegistryInterface sidRegistry = SIDRegistryInterface(sidRegistryAddress);\n        address publicResolverAddress = sidRegistry.resolver(nodeHash);\n        PublicResolverInterface publicResolver = PublicResolverInterface(publicResolverAddress);\n\n        return publicResolver.addr(nodeHash);\n    }\n\n    /**\n     * @notice Gets the price of a asset from the binance oracle\n     * @param asset Address of the asset\n     * @return Price in USD\n     */\n    function getPrice(address asset) public view returns (uint256) {\n        string memory symbol;\n        uint256 decimals;\n\n        if (asset == BNB_ADDR) {\n            symbol = \"BNB\";\n            decimals = 18;\n        } else {\n            IERC20Metadata token = IERC20Metadata(asset);\n            symbol = token.symbol();\n            decimals = token.decimals();\n        }\n\n        string memory overrideSymbol = symbols[symbol];\n\n        if (bytes(overrideSymbol).length != 0) {\n            symbol = overrideSymbol;\n        }\n\n        return _getPrice(symbol, decimals);\n    }\n\n    function _getPrice(string memory symbol, uint256 decimals) internal view returns (uint256) {\n        FeedRegistryInterface feedRegistry;\n\n        if (sidRegistryAddress != address(0)) {\n            // If sidRegistryAddress is available, fetch feedRegistryAddress from sidRegistry\n            feedRegistry = FeedRegistryInterface(getFeedRegistryAddress());\n        } else {\n            // Use feedRegistry directly if sidRegistryAddress is not available\n            feedRegistry = FeedRegistryInterface(feedRegistryAddress);\n        }\n\n        (, int256 answer, , uint256 updatedAt, ) = feedRegistry.latestRoundDataByName(symbol, \"USD\");\n        if (answer <= 0) revert(\"invalid binance oracle price\");\n        if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n        uint256 deltaTime;\n        unchecked {\n            deltaTime = block.timestamp - updatedAt;\n        }\n        if (deltaTime > maxStalePeriod[symbol]) revert(\"binance oracle price expired\");\n\n        uint256 decimalDelta = feedRegistry.decimalsByName(symbol, \"USD\");\n        return (uint256(answer) * (10 ** (18 - decimalDelta))) * (10 ** (18 - decimals));\n    }\n}\n"
    },
    "contracts/oracles/BNBxOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IStaderStakeManager } from \"../interfaces/IStaderStakeManager.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title BNBxOracle\n * @author Venus\n * @notice This oracle fetches the price of BNBx asset\n */\ncontract BNBxOracle is CorrelatedTokenOracle {\n    /// @notice This is used as token address of BNB on BSC\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Address of StakeManager\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IStaderStakeManager public immutable STAKE_MANAGER;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address stakeManager,\n        address bnbx,\n        address resilientOracle\n    ) CorrelatedTokenOracle(bnbx, NATIVE_TOKEN_ADDR, resilientOracle) {\n        ensureNonzeroAddress(stakeManager);\n        STAKE_MANAGER = IStaderStakeManager(stakeManager);\n    }\n\n    /**\n     * @notice Fetches the amount of BNB for 1 BNBx\n     * @return price The amount of BNB for BNBx\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return STAKE_MANAGER.convertBnbXToBnb(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/BoundValidator.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title BoundValidator\n * @author Venus\n * @notice The BoundValidator contract is used to validate prices fetched from two different sources.\n * Each asset has an upper and lower bound ratio set in the config. In order for a price to be valid\n * it must fall within this range of the validator price.\n */\ncontract BoundValidator is AccessControlledV8, BoundValidatorInterface {\n    struct ValidateConfig {\n        /// @notice asset address\n        address asset;\n        /// @notice Upper bound of deviation between reported price and anchor price,\n        /// beyond which the reported price will be invalidated\n        uint256 upperBoundRatio;\n        /// @notice Lower bound of deviation between reported price and anchor price,\n        /// below which the reported price will be invalidated\n        uint256 lowerBoundRatio;\n    }\n\n    /// @notice validation configs by asset\n    mapping(address => ValidateConfig) public validateConfigs;\n\n    /// @notice Emit this event when new validation configs are added\n    event ValidateConfigAdded(address indexed asset, uint256 indexed upperBound, uint256 indexed lowerBound);\n\n    /// @notice Constructor for the implementation contract. Sets immutable variables.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the owner of the contract\n     * @param accessControlManager_ Address of the access control manager contract\n     */\n    function initialize(address accessControlManager_) external initializer {\n        __AccessControlled_init(accessControlManager_);\n    }\n\n    /**\n     * @notice Add multiple validation configs at the same time\n     * @param configs Array of validation configs\n     * @custom:access Only Governance\n     * @custom:error Zero length error is thrown if length of the config array is 0\n     * @custom:event Emits ValidateConfigAdded for each validation config that is successfully set\n     */\n    function setValidateConfigs(ValidateConfig[] memory configs) external {\n        uint256 length = configs.length;\n        if (length == 0) revert(\"invalid validate config length\");\n        for (uint256 i; i < length; ) {\n            setValidateConfig(configs[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice Add a single validation config\n     * @param config Validation config struct\n     * @custom:access Only Governance\n     * @custom:error Null address error is thrown if asset address is null\n     * @custom:error Range error thrown if bound ratio is not positive\n     * @custom:error Range error thrown if lower bound is greater than or equal to upper bound\n     * @custom:event Emits ValidateConfigAdded when a validation config is successfully set\n     */\n    function setValidateConfig(ValidateConfig memory config) public {\n        _checkAccessAllowed(\"setValidateConfig(ValidateConfig)\");\n\n        if (config.asset == address(0)) revert(\"asset can't be zero address\");\n        if (config.upperBoundRatio == 0 || config.lowerBoundRatio == 0) revert(\"bound must be positive\");\n        if (config.upperBoundRatio <= config.lowerBoundRatio) revert(\"upper bound must be higher than lowner bound\");\n        validateConfigs[config.asset] = config;\n        emit ValidateConfigAdded(config.asset, config.upperBoundRatio, config.lowerBoundRatio);\n    }\n\n    /**\n     * @notice Test reported asset price against anchor price\n     * @param asset asset address\n     * @param reportedPrice The price to be tested\n     * @custom:error Missing error thrown if asset config is not set\n     * @custom:error Price error thrown if anchor price is not valid\n     */\n    function validatePriceWithAnchorPrice(\n        address asset,\n        uint256 reportedPrice,\n        uint256 anchorPrice\n    ) public view virtual override returns (bool) {\n        if (validateConfigs[asset].upperBoundRatio == 0) revert(\"validation config not exist\");\n        if (anchorPrice == 0) revert(\"anchor price is not valid\");\n        return _isWithinAnchor(asset, reportedPrice, anchorPrice);\n    }\n\n    /**\n     * @notice Test whether the reported price is within the valid bounds\n     * @param asset Asset address\n     * @param reportedPrice The price to be tested\n     * @param anchorPrice The reported price must be within the the valid bounds of this price\n     */\n    function _isWithinAnchor(address asset, uint256 reportedPrice, uint256 anchorPrice) private view returns (bool) {\n        if (reportedPrice != 0) {\n            // we need to multiply anchorPrice by 1e18 to make the ratio 18 decimals\n            uint256 anchorRatio = (anchorPrice * 1e18) / reportedPrice;\n            uint256 upperBoundAnchorRatio = validateConfigs[asset].upperBoundRatio;\n            uint256 lowerBoundAnchorRatio = validateConfigs[asset].lowerBoundRatio;\n            return anchorRatio <= upperBoundAnchorRatio && anchorRatio >= lowerBoundAnchorRatio;\n        }\n        return false;\n    }\n\n    // BoundValidator is to get inherited, so it's a good practice to add some storage gaps like\n    // OpenZepplin proposed in their contracts: https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n    // solhint-disable-next-line\n    uint256[49] private __gap;\n}\n"
    },
    "contracts/oracles/ChainlinkOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title ChainlinkOracle\n * @author Venus\n * @notice This oracle fetches prices of assets from the Chainlink oracle.\n */\ncontract ChainlinkOracle is AccessControlledV8, OracleInterface {\n    struct TokenConfig {\n        /// @notice Underlying token address, which can't be a null address\n        /// @notice Used to check if a token is supported\n        /// @notice 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB address for native tokens\n        ///         (e.g BNB for BNB chain, ETH for Ethereum network)\n        address asset;\n        /// @notice Chainlink feed address\n        address feed;\n        /// @notice Price expiration period of this asset\n        uint256 maxStalePeriod;\n    }\n\n    /// @notice Set this as asset address for native token on each chain.\n    /// This is the underlying address for vBNB on BNB chain or an underlying asset for a native market on any chain.\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Manually set an override price, useful under extenuating conditions such as price feed failure\n    mapping(address => uint256) public prices;\n\n    /// @notice Token config by assets\n    mapping(address => TokenConfig) public tokenConfigs;\n\n    /// @notice Emit when a price is manually set\n    event PricePosted(address indexed asset, uint256 previousPriceMantissa, uint256 newPriceMantissa);\n\n    /// @notice Emit when a token config is added\n    event TokenConfigAdded(address indexed asset, address feed, uint256 maxStalePeriod);\n\n    modifier notNullAddress(address someone) {\n        if (someone == address(0)) revert(\"can't be zero address\");\n        _;\n    }\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the owner of the contract\n     * @param accessControlManager_ Address of the access control manager contract\n     */\n    function initialize(address accessControlManager_) external initializer {\n        __AccessControlled_init(accessControlManager_);\n    }\n\n    /**\n     * @notice Manually set the price of a given asset\n     * @param asset Asset address\n     * @param price Asset price in 18 decimals\n     * @custom:access Only Governance\n     * @custom:event Emits PricePosted event on succesfully setup of asset price\n     */\n    function setDirectPrice(address asset, uint256 price) external notNullAddress(asset) {\n        _checkAccessAllowed(\"setDirectPrice(address,uint256)\");\n\n        uint256 previousPriceMantissa = prices[asset];\n        prices[asset] = price;\n        emit PricePosted(asset, previousPriceMantissa, price);\n    }\n\n    /**\n     * @notice Add multiple token configs at the same time\n     * @param tokenConfigs_ config array\n     * @custom:access Only Governance\n     * @custom:error Zero length error thrown, if length of the array in parameter is 0\n     */\n    function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n        if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n        uint256 numTokenConfigs = tokenConfigs_.length;\n        for (uint256 i; i < numTokenConfigs; ) {\n            setTokenConfig(tokenConfigs_[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice Add single token config. asset & feed cannot be null addresses and maxStalePeriod must be positive\n     * @param tokenConfig Token config struct\n     * @custom:access Only Governance\n     * @custom:error NotNullAddress error is thrown if asset address is null\n     * @custom:error NotNullAddress error is thrown if token feed address is null\n     * @custom:error Range error is thrown if maxStale period of token is not greater than zero\n     * @custom:event Emits TokenConfigAdded event on succesfully setting of the token config\n     */\n    function setTokenConfig(\n        TokenConfig memory tokenConfig\n    ) public notNullAddress(tokenConfig.asset) notNullAddress(tokenConfig.feed) {\n        _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n\n        if (tokenConfig.maxStalePeriod == 0) revert(\"stale period can't be zero\");\n        tokenConfigs[tokenConfig.asset] = tokenConfig;\n        emit TokenConfigAdded(tokenConfig.asset, tokenConfig.feed, tokenConfig.maxStalePeriod);\n    }\n\n    /**\n     * @notice Gets the price of a asset from the chainlink oracle\n     * @param asset Address of the asset\n     * @return Price in USD from Chainlink or a manually set price for the asset\n     */\n    function getPrice(address asset) public view virtual returns (uint256) {\n        uint256 decimals;\n\n        if (asset == NATIVE_TOKEN_ADDR) {\n            decimals = 18;\n        } else {\n            IERC20Metadata token = IERC20Metadata(asset);\n            decimals = token.decimals();\n        }\n\n        return _getPriceInternal(asset, decimals);\n    }\n\n    /**\n     * @notice Gets the Chainlink price for a given asset\n     * @param asset address of the asset\n     * @param decimals decimals of the asset\n     * @return price Asset price in USD or a manually set price of the asset\n     */\n    function _getPriceInternal(address asset, uint256 decimals) internal view returns (uint256 price) {\n        uint256 tokenPrice = prices[asset];\n        if (tokenPrice != 0) {\n            price = tokenPrice;\n        } else {\n            price = _getChainlinkPrice(asset);\n        }\n\n        uint256 decimalDelta = 18 - decimals;\n        return price * (10 ** decimalDelta);\n    }\n\n    /**\n     * @notice Get the Chainlink price for an asset, revert if token config doesn't exist\n     * @dev The precision of the price feed is used to ensure the returned price has 18 decimals of precision\n     * @param asset Address of the asset\n     * @return price Price in USD, with 18 decimals of precision\n     * @custom:error NotNullAddress error is thrown if the asset address is null\n     * @custom:error Price error is thrown if the Chainlink price of asset is not greater than zero\n     * @custom:error Timing error is thrown if current timestamp is less than the last updatedAt timestamp\n     * @custom:error Timing error is thrown if time difference between current time and last updated time\n     * is greater than maxStalePeriod\n     */\n    function _getChainlinkPrice(\n        address asset\n    ) private view notNullAddress(tokenConfigs[asset].asset) returns (uint256) {\n        TokenConfig memory tokenConfig = tokenConfigs[asset];\n        AggregatorV3Interface feed = AggregatorV3Interface(tokenConfig.feed);\n\n        // note: maxStalePeriod cannot be 0\n        uint256 maxStalePeriod = tokenConfig.maxStalePeriod;\n\n        // Chainlink USD-denominated feeds store answers at 8 decimals, mostly\n        uint256 decimalDelta = 18 - feed.decimals();\n\n        (, int256 answer, , uint256 updatedAt, ) = feed.latestRoundData();\n        if (answer <= 0) revert(\"chainlink price must be positive\");\n        if (block.timestamp < updatedAt) revert(\"updatedAt exceeds block time\");\n\n        uint256 deltaTime;\n        unchecked {\n            deltaTime = block.timestamp - updatedAt;\n        }\n\n        if (deltaTime > maxStalePeriod) revert(\"chainlink price expired\");\n\n        return uint256(answer) * (10 ** decimalDelta);\n    }\n}\n"
    },
    "contracts/oracles/common/CorrelatedTokenOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OracleInterface } from \"../../interfaces/OracleInterface.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @title CorrelatedTokenOracle\n * @notice This oracle fetches the price of a token that is correlated to another token.\n */\nabstract contract CorrelatedTokenOracle is OracleInterface {\n    /// @notice Address of the correlated token\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable CORRELATED_TOKEN;\n\n    /// @notice Address of the underlying token\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable UNDERLYING_TOKEN;\n\n    /// @notice Address of Resilient Oracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    OracleInterface public immutable RESILIENT_ORACLE;\n\n    /// @notice Thrown if the token address is invalid\n    error InvalidTokenAddress();\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(address correlatedToken, address underlyingToken, address resilientOracle) {\n        ensureNonzeroAddress(correlatedToken);\n        ensureNonzeroAddress(underlyingToken);\n        ensureNonzeroAddress(resilientOracle);\n        CORRELATED_TOKEN = correlatedToken;\n        UNDERLYING_TOKEN = underlyingToken;\n        RESILIENT_ORACLE = OracleInterface(resilientOracle);\n    }\n\n    /**\n     * @notice Fetches the price of the correlated token\n     * @param asset Address of the correlated token\n     * @return price The price of the correlated token in scaled decimal places\n     */\n    function getPrice(address asset) external view override returns (uint256) {\n        if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress();\n\n        // get underlying token amount for 1 correlated token scaled by underlying token decimals\n        uint256 underlyingAmount = _getUnderlyingAmount();\n\n        // oracle returns (36 - asset decimal) scaled price\n        uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN);\n\n        IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN);\n        uint256 decimals = token.decimals();\n\n        // underlyingAmount (for 1 correlated token) * underlyingUSDPrice / decimals(correlated token)\n        return (underlyingAmount * underlyingUSDPrice) / (10 ** decimals);\n    }\n\n    /**\n     * @notice Gets the underlying amount for correlated token\n     * @return underlyingAmount Amount of underlying token\n     */\n    function _getUnderlyingAmount() internal view virtual returns (uint256);\n}\n"
    },
    "contracts/oracles/mocks/MockBinanceFeedRegistry.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../../interfaces/FeedRegistryInterface.sol\";\n\ncontract MockBinanceFeedRegistry is FeedRegistryInterface {\n    mapping(string => uint256) public assetPrices;\n\n    function setAssetPrice(string memory base, uint256 price) external {\n        assetPrices[base] = price;\n    }\n\n    function latestRoundDataByName(\n        string memory base,\n        string memory quote\n    )\n        external\n        view\n        override\n        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\n    {\n        quote;\n        return (0, int256(assetPrices[base]), 0, block.timestamp - 10, 0);\n    }\n\n    function decimalsByName(string memory base, string memory quote) external view override returns (uint8) {\n        return 8;\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockBinanceOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { OracleInterface } from \"../../interfaces/OracleInterface.sol\";\n\ncontract MockBinanceOracle is OwnableUpgradeable, OracleInterface {\n    mapping(address => uint256) public assetPrices;\n\n    constructor() {}\n\n    function initialize() public initializer {}\n\n    function setPrice(address asset, uint256 price) external {\n        assetPrices[asset] = price;\n    }\n\n    function getPrice(address token) public view returns (uint256) {\n        return assetPrices[token];\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockChainlinkOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { OracleInterface } from \"../../interfaces/OracleInterface.sol\";\n\ncontract MockChainlinkOracle is OwnableUpgradeable, OracleInterface {\n    mapping(address => uint256) public assetPrices;\n\n    //set price in 6 decimal precision\n    constructor() {}\n\n    function initialize() public initializer {\n        __Ownable_init();\n    }\n\n    function setPrice(address asset, uint256 price) external {\n        assetPrices[asset] = price;\n    }\n\n    //https://compound.finance/docs/prices\n    function getPrice(address token) public view returns (uint256) {\n        return assetPrices[token];\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockPendlePtOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../../interfaces/IPendlePtOracle.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockPendlePtOracle is IPendlePtOracle, Ownable {\n    mapping(address => mapping(uint32 => uint256)) public ptToAssetRate;\n\n    constructor() Ownable() {}\n\n    function setPtToAssetRate(address market, uint32 duration, uint256 rate) external onlyOwner {\n        ptToAssetRate[market][duration] = rate;\n    }\n\n    function getPtToAssetRate(address market, uint32 duration) external view returns (uint256) {\n        return ptToAssetRate[market][duration];\n    }\n\n    function getOracleState(\n        address market,\n        uint32 duration\n    )\n        external\n        view\n        returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied)\n    {\n        return (false, 0, true);\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockPythOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OwnableUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport { IPyth } from \"../PythOracle.sol\";\nimport { OracleInterface } from \"../../interfaces/OracleInterface.sol\";\n\ncontract MockPythOracle is OwnableUpgradeable {\n    mapping(address => uint256) public assetPrices;\n\n    /// @notice the actual pyth oracle address fetch & store the prices\n    IPyth public underlyingPythOracle;\n\n    //set price in 6 decimal precision\n    constructor() {}\n\n    function initialize(address underlyingPythOracle_) public initializer {\n        __Ownable_init();\n        if (underlyingPythOracle_ == address(0)) revert(\"pyth oracle cannot be zero address\");\n        underlyingPythOracle = IPyth(underlyingPythOracle_);\n    }\n\n    function setPrice(address asset, uint256 price) external {\n        assetPrices[asset] = price;\n    }\n\n    //https://compound.finance/docs/prices\n    function getPrice(address token) public view returns (uint256) {\n        return assetPrices[token];\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockSFrxEthFraxOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../../interfaces/ISfrxEthFraxOracle.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockSfrxEthFraxOracle is ISfrxEthFraxOracle, Ownable {\n    bool public isBadData;\n    uint256 public priceLow;\n    uint256 public priceHigh;\n\n    constructor() Ownable() {}\n\n    function setPrices(bool _isBadData, uint256 _priceLow, uint256 _priceHigh) external onlyOwner {\n        isBadData = _isBadData;\n        priceLow = _priceLow;\n        priceHigh = _priceHigh;\n    }\n\n    function getPrices() external view override returns (bool, uint256, uint256) {\n        return (isBadData, priceLow, priceHigh);\n    }\n}\n"
    },
    "contracts/oracles/OneJumpOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { OracleInterface } from \"../interfaces/OracleInterface.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @title OneJumpOracle\n * @author Venus\n * @notice This oracle fetches the price of an asset in through an intermediate asset\n */\ncontract OneJumpOracle is CorrelatedTokenOracle {\n    /// @notice Address of the intermediate oracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    OracleInterface public immutable INTERMEDIATE_ORACLE;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address correlatedToken,\n        address underlyingToken,\n        address resilientOracle,\n        address intermediateOracle\n    ) CorrelatedTokenOracle(correlatedToken, underlyingToken, resilientOracle) {\n        ensureNonzeroAddress(intermediateOracle);\n        INTERMEDIATE_ORACLE = OracleInterface(intermediateOracle);\n    }\n\n    /**\n     * @notice Fetches the amount of the underlying token for 1 correlated token, using the intermediate oracle\n     * @return amount The amount of the underlying token for 1 correlated token scaled by the underlying token decimals\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        uint256 underlyingDecimals = IERC20Metadata(UNDERLYING_TOKEN).decimals();\n        uint256 correlatedDecimals = IERC20Metadata(CORRELATED_TOKEN).decimals();\n\n        uint256 underlyingAmount = INTERMEDIATE_ORACLE.getPrice(CORRELATED_TOKEN);\n\n        return (underlyingAmount * (10 ** correlatedDecimals)) / (10 ** (36 - underlyingDecimals));\n    }\n}\n"
    },
    "contracts/oracles/PendleOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IPendlePtOracle } from \"../interfaces/IPendlePtOracle.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title PendleOracle\n * @author Venus\n * @notice This oracle fetches the price of a pendle token\n */\ncontract PendleOracle is CorrelatedTokenOracle {\n    /// @notice Address of the PT oracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IPendlePtOracle public immutable PT_ORACLE;\n\n    /// @notice Address of the market\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable MARKET;\n\n    /// @notice Twap duration for the oracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    uint32 public immutable TWAP_DURATION;\n\n    /// @notice Thrown if the duration is invalid\n    error InvalidDuration();\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address market,\n        address ptOracle,\n        address ptToken,\n        address underlyingToken,\n        address resilientOracle,\n        uint32 twapDuration\n    ) CorrelatedTokenOracle(ptToken, underlyingToken, resilientOracle) {\n        ensureNonzeroAddress(market);\n        ensureNonzeroAddress(ptOracle);\n        ensureNonzeroValue(twapDuration);\n\n        MARKET = market;\n        PT_ORACLE = IPendlePtOracle(ptOracle);\n        TWAP_DURATION = twapDuration;\n\n        (bool increaseCardinalityRequired, , bool oldestObservationSatisfied) = PT_ORACLE.getOracleState(\n            MARKET,\n            TWAP_DURATION\n        );\n        if (increaseCardinalityRequired || !oldestObservationSatisfied) {\n            revert InvalidDuration();\n        }\n    }\n\n    /**\n     * @notice Fetches the amount of underlying token for 1 pendle token\n     * @return amount The amount of underlying token for pendle token\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\n    }\n}\n"
    },
    "contracts/oracles/PythOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"@openzeppelin/contracts/utils/math/SignedMath.sol\";\nimport \"../interfaces/PythInterface.sol\";\nimport \"../interfaces/OracleInterface.sol\";\nimport \"../interfaces/VBep20Interface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title PythOracle\n * @author Venus\n * @notice PythOracle contract reads prices from actual Pyth oracle contract which accepts, verifies and stores\n * the updated prices from external sources\n */\ncontract PythOracle is AccessControlledV8, OracleInterface {\n    // To calculate 10 ** n(which is a signed type)\n    using SignedMath for int256;\n\n    // To cast int64/int8 types from Pyth to unsigned types\n    using SafeCast for int256;\n\n    struct TokenConfig {\n        bytes32 pythId;\n        address asset;\n        uint64 maxStalePeriod;\n    }\n\n    /// @notice Exponent scale (decimal precision) of prices\n    uint256 public constant EXP_SCALE = 1e18;\n\n    /// @notice Set this as asset address for BNB. This is the underlying for vBNB\n    address public constant BNB_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice The actual pyth oracle address fetch & store the prices\n    IPyth public underlyingPythOracle;\n\n    /// @notice Token configs by asset address\n    mapping(address => TokenConfig) public tokenConfigs;\n\n    /// @notice Emit when setting a new pyth oracle address\n    event PythOracleSet(address indexed oldPythOracle, address indexed newPythOracle);\n\n    /// @notice Emit when a token config is added\n    event TokenConfigAdded(address indexed asset, bytes32 indexed pythId, uint64 indexed maxStalePeriod);\n\n    modifier notNullAddress(address someone) {\n        if (someone == address(0)) revert(\"can't be zero address\");\n        _;\n    }\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor() {\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the owner of the contract and sets required contracts\n     * @param underlyingPythOracle_ Address of the Pyth oracle\n     * @param accessControlManager_ Address of the access control manager contract\n     */\n    function initialize(\n        address underlyingPythOracle_,\n        address accessControlManager_\n    ) external initializer notNullAddress(underlyingPythOracle_) {\n        __AccessControlled_init(accessControlManager_);\n\n        underlyingPythOracle = IPyth(underlyingPythOracle_);\n        emit PythOracleSet(address(0), underlyingPythOracle_);\n    }\n\n    /**\n     * @notice Batch set token configs\n     * @param tokenConfigs_ Token config array\n     * @custom:access Only Governance\n     * @custom:error Zero length error is thrown if length of the array in parameter is 0\n     */\n    function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n        if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n        uint256 numTokenConfigs = tokenConfigs_.length;\n        for (uint256 i; i < numTokenConfigs; ) {\n            setTokenConfig(tokenConfigs_[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice Set the underlying Pyth oracle contract address\n     * @param underlyingPythOracle_ Pyth oracle contract address\n     * @custom:access Only Governance\n     * @custom:error NotNullAddress error thrown if underlyingPythOracle_ address is zero\n     * @custom:event Emits PythOracleSet event with address of Pyth oracle.\n     */\n    function setUnderlyingPythOracle(\n        IPyth underlyingPythOracle_\n    ) external notNullAddress(address(underlyingPythOracle_)) {\n        _checkAccessAllowed(\"setUnderlyingPythOracle(address)\");\n        IPyth oldUnderlyingPythOracle = underlyingPythOracle;\n        underlyingPythOracle = underlyingPythOracle_;\n        emit PythOracleSet(address(oldUnderlyingPythOracle), address(underlyingPythOracle_));\n    }\n\n    /**\n     * @notice Set single token config. `maxStalePeriod` cannot be 0 and `asset` cannot be a null address\n     * @param tokenConfig Token config struct\n     * @custom:access Only Governance\n     * @custom:error Range error is thrown if max stale period is zero\n     * @custom:error NotNullAddress error is thrown if asset address is null\n     */\n    function setTokenConfig(TokenConfig memory tokenConfig) public notNullAddress(tokenConfig.asset) {\n        _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n        if (tokenConfig.maxStalePeriod == 0) revert(\"max stale period cannot be 0\");\n        tokenConfigs[tokenConfig.asset] = tokenConfig;\n        emit TokenConfigAdded(tokenConfig.asset, tokenConfig.pythId, tokenConfig.maxStalePeriod);\n    }\n\n    /**\n     * @notice Gets the price of a asset from the pyth oracle\n     * @param asset Address of the asset\n     * @return Price in USD\n     */\n    function getPrice(address asset) public view returns (uint256) {\n        uint256 decimals;\n\n        if (asset == BNB_ADDR) {\n            decimals = 18;\n        } else {\n            IERC20Metadata token = IERC20Metadata(asset);\n            decimals = token.decimals();\n        }\n\n        return _getPriceInternal(asset, decimals);\n    }\n\n    function _getPriceInternal(address asset, uint256 decimals) internal view returns (uint256) {\n        TokenConfig storage tokenConfig = tokenConfigs[asset];\n        if (tokenConfig.asset == address(0)) revert(\"asset doesn't exist\");\n\n        // if the price is expired after it's compared against `maxStalePeriod`, the following call will revert\n        PythStructs.Price memory priceInfo = underlyingPythOracle.getPriceNoOlderThan(\n            tokenConfig.pythId,\n            tokenConfig.maxStalePeriod\n        );\n\n        uint256 price = int256(priceInfo.price).toUint256();\n\n        if (price == 0) revert(\"invalid pyth oracle price\");\n\n        // the price returned from Pyth is price ** 10^expo, which is the real dollar price of the assets\n        // we need to multiply it by 1e18 to make the price 18 decimals\n        if (priceInfo.expo > 0) {\n            return price * EXP_SCALE * (10 ** int256(priceInfo.expo).toUint256()) * (10 ** (18 - decimals));\n        } else {\n            return ((price * EXP_SCALE) / (10 ** int256(-priceInfo.expo).toUint256())) * (10 ** (18 - decimals));\n        }\n    }\n}\n"
    },
    "contracts/oracles/SequencerChainlinkOracle.sol": {
      "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.25;\n\nimport { ChainlinkOracle } from \"./ChainlinkOracle.sol\";\nimport { AggregatorV3Interface } from \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol\";\n\n/**\n    @title Sequencer Chain Link Oracle\n    @notice Oracle to fetch price using chainlink oracles on L2s with sequencer\n*/\ncontract SequencerChainlinkOracle is ChainlinkOracle {\n    /// @notice L2 Sequencer feed\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    AggregatorV3Interface public immutable sequencer;\n\n    /// @notice L2 Sequencer grace period\n    uint256 public constant GRACE_PERIOD_TIME = 3600;\n\n    /**\n        @notice Contract constructor\n        @param _sequencer L2 sequencer\n        @custom:oz-upgrades-unsafe-allow constructor\n    */\n    constructor(AggregatorV3Interface _sequencer) ChainlinkOracle() {\n        require(address(_sequencer) != address(0), \"zero address\");\n\n        sequencer = _sequencer;\n    }\n\n    /// @inheritdoc ChainlinkOracle\n    function getPrice(address asset) public view override returns (uint) {\n        if (!isSequencerActive()) revert(\"L2 sequencer unavailable\");\n        return super.getPrice(asset);\n    }\n\n    function isSequencerActive() internal view returns (bool) {\n        // answer from oracle is a variable with a value of either 1 or 0\n        //  0: The sequencer is up\n        //  1: The sequencer is down\n        // startedAt: This timestamp indicates when the sequencer changed status\n        (, int256 answer, uint256 startedAt, , ) = sequencer.latestRoundData();\n        if (block.timestamp - startedAt <= GRACE_PERIOD_TIME || answer == 1) return false;\n        return true;\n    }\n}\n"
    },
    "contracts/oracles/SFraxOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ISFrax } from \"../interfaces/ISFrax.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\n\n/**\n * @title SFraxOracle\n * @author Venus\n * @notice This oracle fetches the price of sFrax\n */\ncontract SFraxOracle is CorrelatedTokenOracle {\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address sFrax,\n        address frax,\n        address resilientOracle\n    ) CorrelatedTokenOracle(sFrax, frax, resilientOracle) {}\n\n    /**\n     * @notice Fetches the amount of FRAX for 1 sFrax\n     * @return amount The amount of FRAX for sFrax\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return ISFrax(CORRELATED_TOKEN).convertToAssets(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/SFrxETHOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ISfrxEthFraxOracle } from \"../interfaces/ISfrxEthFraxOracle.sol\";\nimport { ensureNonzeroAddress, ensureNonzeroValue } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { OracleInterface } from \"../interfaces/OracleInterface.sol\";\n\n/**\n * @title SFrxETHOracle\n * @author Venus\n * @notice This oracle fetches the price of sfrxETH\n */\ncontract SFrxETHOracle is AccessControlledV8, OracleInterface {\n    /// @notice Address of SfrxEthFraxOracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    ISfrxEthFraxOracle public immutable SFRXETH_FRAX_ORACLE;\n\n    /// @notice Address of sfrxETH\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable SFRXETH;\n\n    /// @notice Maximum allowed price difference\n    uint256 public maxAllowedPriceDifference;\n\n    /// @notice Emits when the maximum allowed price difference is updated\n    event MaxAllowedPriceDifferenceUpdated(uint256 oldMaxAllowedPriceDifference, uint256 newMaxAllowedPriceDifference);\n\n    /// @notice Thrown if the price data is invalid\n    error BadPriceData();\n\n    /// @notice Thrown if the price difference exceeds the allowed limit\n    error PriceDifferenceExceeded();\n\n    /// @notice Thrown if the token address is invalid\n    error InvalidTokenAddress();\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    /// @custom:error ZeroAddressNotAllowed is thrown when `_sfrxEthFraxOracle` or `_sfrxETH` are the zero address\n    constructor(address _sfrxEthFraxOracle, address _sfrxETH) {\n        ensureNonzeroAddress(_sfrxEthFraxOracle);\n        ensureNonzeroAddress(_sfrxETH);\n\n        SFRXETH_FRAX_ORACLE = ISfrxEthFraxOracle(_sfrxEthFraxOracle);\n        SFRXETH = _sfrxETH;\n\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Sets the contracts required to fetch prices\n     * @param _accessControlManager Address of the access control manager contract\n     * @param _maxAllowedPriceDifference Maximum allowed price difference\n     * @custom:error ZeroValueNotAllowed is thrown if `_maxAllowedPriceDifference` is zero\n     */\n    function initialize(address _accessControlManager, uint256 _maxAllowedPriceDifference) external initializer {\n        ensureNonzeroValue(_maxAllowedPriceDifference);\n\n        __AccessControlled_init(_accessControlManager);\n        maxAllowedPriceDifference = _maxAllowedPriceDifference;\n    }\n\n    /**\n     * @notice Sets the maximum allowed price difference\n     * @param _maxAllowedPriceDifference Maximum allowed price difference\n     * @custom:error ZeroValueNotAllowed is thrown if `_maxAllowedPriceDifference` is zero\n     */\n    function setMaxAllowedPriceDifference(uint256 _maxAllowedPriceDifference) external {\n        _checkAccessAllowed(\"setMaxAllowedPriceDifference(uint256)\");\n        ensureNonzeroValue(_maxAllowedPriceDifference);\n\n        emit MaxAllowedPriceDifferenceUpdated(maxAllowedPriceDifference, _maxAllowedPriceDifference);\n        maxAllowedPriceDifference = _maxAllowedPriceDifference;\n    }\n\n    /**\n     * @notice Fetches the USD price of sfrxETH\n     * @param asset Address of the sfrxETH token\n     * @return price The price scaled by 1e18\n     * @custom:error InvalidTokenAddress is thrown when the `asset` is not the sfrxETH token (`SFRXETH`)\n     * @custom:error BadPriceData is thrown if the `SFRXETH_FRAX_ORACLE` oracle informs it has bad data\n     * @custom:error ZeroValueNotAllowed is thrown if the prices (low or high, in USD) are zero\n     * @custom:error PriceDifferenceExceeded is thrown if priceHigh/priceLow is greater than `maxAllowedPriceDifference`\n     */\n    function getPrice(address asset) external view returns (uint256) {\n        if (asset != SFRXETH) revert InvalidTokenAddress();\n\n        (bool isBadData, uint256 priceLow, uint256 priceHigh) = SFRXETH_FRAX_ORACLE.getPrices();\n\n        if (isBadData) revert BadPriceData();\n\n        // calculate price in USD\n        uint256 priceHighInUSD = (EXP_SCALE ** 2) / priceLow;\n        uint256 priceLowInUSD = (EXP_SCALE ** 2) / priceHigh;\n\n        ensureNonzeroValue(priceHighInUSD);\n        ensureNonzeroValue(priceLowInUSD);\n\n        // validate price difference\n        uint256 difference = (priceHighInUSD * EXP_SCALE) / priceLowInUSD;\n        if (difference > maxAllowedPriceDifference) revert PriceDifferenceExceeded();\n\n        // calculate and return average price\n        return (priceHighInUSD + priceLowInUSD) / 2;\n    }\n}\n"
    },
    "contracts/oracles/SlisBNBOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ISynclubStakeManager } from \"../interfaces/ISynclubStakeManager.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\n\n/**\n * @title SlisBNBOracle\n * @author Venus\n * @notice This oracle fetches the price of slisBNB asset\n */\ncontract SlisBNBOracle is CorrelatedTokenOracle {\n    /// @notice This is used as token address of BNB on BSC\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Address of StakeManager\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    ISynclubStakeManager public immutable STAKE_MANAGER;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address stakeManager,\n        address slisBNB,\n        address resilientOracle\n    ) CorrelatedTokenOracle(slisBNB, NATIVE_TOKEN_ADDR, resilientOracle) {\n        ensureNonzeroAddress(stakeManager);\n        STAKE_MANAGER = ISynclubStakeManager(stakeManager);\n    }\n\n    /**\n     * @notice Fetches the amount of BNB for 1 slisBNB\n     * @return amount The amount of BNB for slisBNB\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return STAKE_MANAGER.convertSnBnbToBnb(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/StkBNBOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IPStakePool } from \"../interfaces/IPStakePool.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title StkBNBOracle\n * @author Venus\n * @notice This oracle fetches the price of stkBNB asset\n */\ncontract StkBNBOracle is CorrelatedTokenOracle {\n    /// @notice This is used as token address of BNB on BSC\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Address of StakePool\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IPStakePool public immutable STAKE_POOL;\n\n    /// @notice Thrown if the pool token supply is zero\n    error PoolTokenSupplyIsZero();\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address stakePool,\n        address stkBNB,\n        address resilientOracle\n    ) CorrelatedTokenOracle(stkBNB, NATIVE_TOKEN_ADDR, resilientOracle) {\n        ensureNonzeroAddress(stakePool);\n        STAKE_POOL = IPStakePool(stakePool);\n    }\n\n    /**\n     * @notice Fetches the amount of BNB for 1 stkBNB\n     * @return price The amount of BNB for stkBNB\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        IPStakePool.Data memory exchangeRateData = STAKE_POOL.exchangeRate();\n\n        if (exchangeRateData.poolTokenSupply == 0) {\n            revert PoolTokenSupplyIsZero();\n        }\n\n        return (exchangeRateData.totalWei * EXP_SCALE) / exchangeRateData.poolTokenSupply;\n    }\n}\n"
    },
    "contracts/oracles/WBETHOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IWBETH } from \"../interfaces/IWBETH.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title WBETHOracle\n * @author Venus\n * @notice This oracle fetches the price of wBETH asset\n */\ncontract WBETHOracle is CorrelatedTokenOracle {\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address wbeth,\n        address eth,\n        address resilientOracle\n    ) CorrelatedTokenOracle(wbeth, eth, resilientOracle) {}\n\n    /**\n     * @notice Fetches the amount of ETH for 1 wBETH\n     * @return amount The amount of ETH for wBETH\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return IWBETH(CORRELATED_TOKEN).exchangeRate();\n    }\n}\n"
    },
    "contracts/oracles/WeETHOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { IEtherFiLiquidityPool } from \"../interfaces/IEtherFiLiquidityPool.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title WeETHOracle\n * @author Venus\n * @notice This oracle fetches the price of weETH\n */\ncontract WeETHOracle is CorrelatedTokenOracle {\n    /// @notice Address of Liqiudity pool\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IEtherFiLiquidityPool public immutable LIQUIDITY_POOL;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address liquidityPool,\n        address weETH,\n        address eETH,\n        address resilientOracle\n    ) CorrelatedTokenOracle(weETH, eETH, resilientOracle) {\n        ensureNonzeroAddress(liquidityPool);\n        LIQUIDITY_POOL = IEtherFiLiquidityPool(liquidityPool);\n    }\n\n    /**\n     * @notice Gets the eETH for 1 weETH\n     * @return amount Amount of eETH\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return LIQUIDITY_POOL.amountForShare(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/WstETHOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { OracleInterface } from \"../interfaces/OracleInterface.sol\";\nimport { IStETH } from \"../interfaces/IStETH.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\n\n/**\n * @title WstETHOracle\n * @author Venus\n * @notice Depending on the equivalence flag price is either based on assumption that 1 stETH = 1 ETH\n *         or the price of stETH/USD (secondary market price) is obtained from the oracle.\n */\ncontract WstETHOracle is OracleInterface {\n    /// @notice A flag assuming 1:1 price equivalence between stETH/ETH\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    bool public immutable ASSUME_STETH_ETH_EQUIVALENCE;\n\n    /// @notice Address of stETH\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    IStETH public immutable STETH;\n\n    /// @notice Address of wstETH\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable WSTETH_ADDRESS;\n\n    /// @notice Address of WETH\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable WETH_ADDRESS;\n\n    /// @notice Address of Resilient Oracle\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    OracleInterface public immutable RESILIENT_ORACLE;\n\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address wstETHAddress,\n        address wETHAddress,\n        address stETHAddress,\n        address resilientOracleAddress,\n        bool assumeEquivalence\n    ) {\n        ensureNonzeroAddress(wstETHAddress);\n        ensureNonzeroAddress(wETHAddress);\n        ensureNonzeroAddress(stETHAddress);\n        ensureNonzeroAddress(resilientOracleAddress);\n        WSTETH_ADDRESS = wstETHAddress;\n        WETH_ADDRESS = wETHAddress;\n        STETH = IStETH(stETHAddress);\n        RESILIENT_ORACLE = OracleInterface(resilientOracleAddress);\n        ASSUME_STETH_ETH_EQUIVALENCE = assumeEquivalence;\n    }\n\n    /**\n     * @notice Gets the USD price of wstETH asset\n     * @dev Depending on the equivalence flag price is either based on assumption that 1 stETH = 1 ETH\n     *      or the price of stETH/USD (secondary market price) is obtained from the oracle\n     * @param asset Address of wstETH\n     * @return wstETH Price in USD scaled by 1e18\n     */\n    function getPrice(address asset) public view returns (uint256) {\n        if (asset != WSTETH_ADDRESS) revert(\"wrong wstETH address\");\n\n        // get stETH amount for 1 wstETH scaled by 1e18\n        uint256 stETHAmount = STETH.getPooledEthByShares(1 ether);\n\n        // price is scaled 1e18 (oracle returns 36 - asset decimal scale)\n        uint256 stETHUSDPrice = RESILIENT_ORACLE.getPrice(ASSUME_STETH_ETH_EQUIVALENCE ? WETH_ADDRESS : address(STETH));\n\n        // stETHAmount (for 1 wstETH) * stETHUSDPrice / 1e18\n        return (stETHAmount * stETHUSDPrice) / EXP_SCALE;\n    }\n}\n"
    },
    "contracts/oracles/WstETHOracleV2.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IStETH } from \"../interfaces/IStETH.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\n\n/**\n * @title WstETHOracleV2\n * @author Venus\n * @notice This oracle fetches the price of wstETH\n */\ncontract WstETHOracleV2 is CorrelatedTokenOracle {\n    /// @notice Constructor for the implementation contract.\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address wstETH,\n        address stETH,\n        address resilientOracle\n    ) CorrelatedTokenOracle(wstETH, stETH, resilientOracle) {}\n\n    /**\n     * @notice Gets the stETH for 1 wstETH\n     * @return amount Amount of stETH\n     */\n    function _getUnderlyingAmount() internal view override returns (uint256) {\n        return IStETH(UNDERLYING_TOKEN).getPooledEthByShares(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/ResilientOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2022 Venus\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport \"./interfaces/VBep20Interface.sol\";\nimport \"./interfaces/OracleInterface.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\n\n/**\n * @title ResilientOracle\n * @author Venus\n * @notice The Resilient Oracle is the main contract that the protocol uses to fetch prices of assets.\n * \n * DeFi protocols are vulnerable to price oracle failures including oracle manipulation and incorrectly\n * reported prices. If only one oracle is used, this creates a single point of failure and opens a vector\n * for attacking the protocol.\n * \n * The Resilient Oracle uses multiple sources and fallback mechanisms to provide accurate prices and protect\n * the protocol from oracle attacks. Currently it includes integrations with Chainlink, Pyth, Binance Oracle\n * and TWAP (Time-Weighted Average Price) oracles. TWAP uses PancakeSwap as the on-chain price source.\n * \n * For every market (vToken) we configure the main, pivot and fallback oracles. The oracles are configured per \n * vToken's underlying asset address. The main oracle oracle is the most trustworthy price source, the pivot \n * oracle is used as a loose sanity checker and the fallback oracle is used as a backup price source. \n * \n * To validate prices returned from two oracles, we use an upper and lower bound ratio that is set for every\n * market. The upper bound ratio represents the deviation between reported price (the price that’s being\n * validated) and the anchor price (the price we are validating against) above which the reported price will\n * be invalidated. The lower bound ratio presents the deviation between reported price and anchor price below\n * which the reported price will be invalidated. So for oracle price to be considered valid the below statement\n * should be true:\n\n```\nanchorRatio = anchorPrice/reporterPrice\nisValid = anchorRatio <= upperBoundAnchorRatio && anchorRatio >= lowerBoundAnchorRatio\n```\n\n * In most cases, Chainlink is used as the main oracle, TWAP or Pyth oracles are used as the pivot oracle depending\n * on which supports the given market and Binance oracle is used as the fallback oracle. For some markets we may\n * use Pyth or TWAP as the main oracle if the token price is not supported by Chainlink or Binance oracles. \n * \n * For a fetched price to be valid it must be positive and not stagnant. If the price is invalid then we consider the\n * oracle to be stagnant and treat it like it's disabled.\n */\ncontract ResilientOracle is PausableUpgradeable, AccessControlledV8, ResilientOracleInterface {\n    /**\n     * @dev Oracle roles:\n     * **main**: The most trustworthy price source\n     * **pivot**: Price oracle used as a loose sanity checker\n     * **fallback**: The backup source when main oracle price is invalidated\n     */\n    enum OracleRole {\n        MAIN,\n        PIVOT,\n        FALLBACK\n    }\n\n    struct TokenConfig {\n        /// @notice asset address\n        address asset;\n        /// @notice `oracles` stores the oracles based on their role in the following order:\n        /// [main, pivot, fallback],\n        /// It can be indexed with the corresponding enum OracleRole value\n        address[3] oracles;\n        /// @notice `enableFlagsForOracles` stores the enabled state\n        /// for each oracle in the same order as `oracles`\n        bool[3] enableFlagsForOracles;\n    }\n\n    uint256 public constant INVALID_PRICE = 0;\n\n    /// @notice Native market address\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable nativeMarket;\n\n    /// @notice VAI address\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address public immutable vai;\n\n    /// @notice Set this as asset address for Native token on each chain.This is the underlying for vBNB (on bsc)\n    /// and can serve as any underlying asset of a market that supports native tokens\n    address public constant NATIVE_TOKEN_ADDR = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB;\n\n    /// @notice Bound validator contract address\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    BoundValidatorInterface public immutable boundValidator;\n\n    mapping(address => TokenConfig) private tokenConfigs;\n\n    event TokenConfigAdded(\n        address indexed asset,\n        address indexed mainOracle,\n        address indexed pivotOracle,\n        address fallbackOracle\n    );\n\n    /// Event emitted when an oracle is set\n    event OracleSet(address indexed asset, address indexed oracle, uint256 indexed role);\n\n    /// Event emitted when an oracle is enabled or disabled\n    event OracleEnabled(address indexed asset, uint256 indexed role, bool indexed enable);\n\n    /**\n     * @notice Checks whether an address is null or not\n     */\n    modifier notNullAddress(address someone) {\n        if (someone == address(0)) revert(\"can't be zero address\");\n        _;\n    }\n\n    /**\n     * @notice Checks whether token config exists by checking whether asset is null address\n     * @dev address can't be null, so it's suitable to be used to check the validity of the config\n     * @param asset asset address\n     */\n    modifier checkTokenConfigExistence(address asset) {\n        if (tokenConfigs[asset].asset == address(0)) revert(\"token config must exist\");\n        _;\n    }\n\n    /// @notice Constructor for the implementation contract. Sets immutable variables.\n    /// @dev nativeMarketAddress can be address(0) if on the chain we do not support native market\n    ///      (e.g vETH on ethereum would not be supported, only vWETH)\n    /// @param nativeMarketAddress The address of a native market (for bsc it would be vBNB address)\n    /// @param vaiAddress The address of the VAI token (if there is VAI on the deployed chain).\n    ///          Set to address(0) of VAI is not existent.\n    /// @param _boundValidator Address of the bound validator contract\n    /// @custom:oz-upgrades-unsafe-allow constructor\n    constructor(\n        address nativeMarketAddress,\n        address vaiAddress,\n        BoundValidatorInterface _boundValidator\n    ) notNullAddress(address(_boundValidator)) {\n        nativeMarket = nativeMarketAddress;\n        vai = vaiAddress;\n        boundValidator = _boundValidator;\n\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the contract admin and sets the BoundValidator contract address\n     * @param accessControlManager_ Address of the access control manager contract\n     */\n    function initialize(address accessControlManager_) external initializer {\n        __AccessControlled_init(accessControlManager_);\n        __Pausable_init();\n    }\n\n    /**\n     * @notice Pauses oracle\n     * @custom:access Only Governance\n     */\n    function pause() external {\n        _checkAccessAllowed(\"pause()\");\n        _pause();\n    }\n\n    /**\n     * @notice Unpauses oracle\n     * @custom:access Only Governance\n     */\n    function unpause() external {\n        _checkAccessAllowed(\"unpause()\");\n        _unpause();\n    }\n\n    /**\n     * @notice Batch sets token configs\n     * @param tokenConfigs_ Token config array\n     * @custom:access Only Governance\n     * @custom:error Throws a length error if the length of the token configs array is 0\n     */\n    function setTokenConfigs(TokenConfig[] memory tokenConfigs_) external {\n        if (tokenConfigs_.length == 0) revert(\"length can't be 0\");\n        uint256 numTokenConfigs = tokenConfigs_.length;\n        for (uint256 i; i < numTokenConfigs; ) {\n            setTokenConfig(tokenConfigs_[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice Sets oracle for a given asset and role.\n     * @dev Supplied asset **must** exist and main oracle may not be null\n     * @param asset Asset address\n     * @param oracle Oracle address\n     * @param role Oracle role\n     * @custom:access Only Governance\n     * @custom:error Null address error if main-role oracle address is null\n     * @custom:error NotNullAddress error is thrown if asset address is null\n     * @custom:error TokenConfigExistance error is thrown if token config is not set\n     * @custom:event Emits OracleSet event with asset address, oracle address and role of the oracle for the asset\n     */\n    function setOracle(\n        address asset,\n        address oracle,\n        OracleRole role\n    ) external notNullAddress(asset) checkTokenConfigExistence(asset) {\n        _checkAccessAllowed(\"setOracle(address,address,uint8)\");\n        if (oracle == address(0) && role == OracleRole.MAIN) revert(\"can't set zero address to main oracle\");\n        tokenConfigs[asset].oracles[uint256(role)] = oracle;\n        emit OracleSet(asset, oracle, uint256(role));\n    }\n\n    /**\n     * @notice Enables/ disables oracle for the input asset. Token config for the input asset **must** exist\n     * @dev Configuration for the asset **must** already exist and the asset cannot be 0 address\n     * @param asset Asset address\n     * @param role Oracle role\n     * @param enable Enabled boolean of the oracle\n     * @custom:access Only Governance\n     * @custom:error NotNullAddress error is thrown if asset address is null\n     * @custom:error TokenConfigExistance error is thrown if token config is not set\n     */\n    function enableOracle(\n        address asset,\n        OracleRole role,\n        bool enable\n    ) external notNullAddress(asset) checkTokenConfigExistence(asset) {\n        _checkAccessAllowed(\"enableOracle(address,uint8,bool)\");\n        tokenConfigs[asset].enableFlagsForOracles[uint256(role)] = enable;\n        emit OracleEnabled(asset, uint256(role), enable);\n    }\n\n    /**\n     * @notice Updates the TWAP pivot oracle price.\n     * @dev This function should always be called before calling getUnderlyingPrice\n     * @param vToken vToken address\n     */\n    function updatePrice(address vToken) external override {\n        address asset = _getUnderlyingAsset(vToken);\n        (address pivotOracle, bool pivotOracleEnabled) = getOracle(asset, OracleRole.PIVOT);\n        if (pivotOracle != address(0) && pivotOracleEnabled) {\n            //if pivot oracle is not TwapOracle it will revert so we need to catch the revert\n            try TwapInterface(pivotOracle).updateTwap(asset) {} catch {}\n        }\n    }\n\n    /**\n     * @notice Updates the pivot oracle price. Currently using TWAP\n     * @dev This function should always be called before calling getPrice\n     * @param asset asset address\n     */\n    function updateAssetPrice(address asset) external {\n        (address pivotOracle, bool pivotOracleEnabled) = getOracle(asset, OracleRole.PIVOT);\n        if (pivotOracle != address(0) && pivotOracleEnabled) {\n            //if pivot oracle is not TwapOracle it will revert so we need to catch the revert\n            try TwapInterface(pivotOracle).updateTwap(asset) {} catch {}\n        }\n    }\n\n    /**\n     * @dev Gets token config by asset address\n     * @param asset asset address\n     * @return tokenConfig Config for the asset\n     */\n    function getTokenConfig(address asset) external view returns (TokenConfig memory) {\n        return tokenConfigs[asset];\n    }\n\n    /**\n     * @notice Gets price of the underlying asset for a given vToken. Validation flow:\n     * - Check if the oracle is paused globally\n     * - Validate price from main oracle against pivot oracle\n     * - Validate price from fallback oracle against pivot oracle if the first validation failed\n     * - Validate price from main oracle against fallback oracle if the second validation failed\n     * In the case that the pivot oracle is not available but main price is available and validation is successful,\n     * main oracle price is returned.\n     * @param vToken vToken address\n     * @return price USD price in scaled decimal places.\n     * @custom:error Paused error is thrown when resilent oracle is paused\n     * @custom:error Invalid resilient oracle price error is thrown if fetched prices from oracle is invalid\n     */\n    function getUnderlyingPrice(address vToken) external view override returns (uint256) {\n        if (paused()) revert(\"resilient oracle is paused\");\n\n        address asset = _getUnderlyingAsset(vToken);\n        return _getPrice(asset);\n    }\n\n    /**\n     * @notice Gets price of the asset\n     * @param asset asset address\n     * @return price USD price in scaled decimal places.\n     * @custom:error Paused error is thrown when resilent oracle is paused\n     * @custom:error Invalid resilient oracle price error is thrown if fetched prices from oracle is invalid\n     */\n    function getPrice(address asset) external view override returns (uint256) {\n        if (paused()) revert(\"resilient oracle is paused\");\n        return _getPrice(asset);\n    }\n\n    /**\n     * @notice Sets/resets single token configs.\n     * @dev main oracle **must not** be a null address\n     * @param tokenConfig Token config struct\n     * @custom:access Only Governance\n     * @custom:error NotNullAddress is thrown if asset address is null\n     * @custom:error NotNullAddress is thrown if main-role oracle address for asset is null\n     * @custom:event Emits TokenConfigAdded event when the asset config is set successfully by the authorized account\n     */\n    function setTokenConfig(\n        TokenConfig memory tokenConfig\n    ) public notNullAddress(tokenConfig.asset) notNullAddress(tokenConfig.oracles[uint256(OracleRole.MAIN)]) {\n        _checkAccessAllowed(\"setTokenConfig(TokenConfig)\");\n\n        tokenConfigs[tokenConfig.asset] = tokenConfig;\n        emit TokenConfigAdded(\n            tokenConfig.asset,\n            tokenConfig.oracles[uint256(OracleRole.MAIN)],\n            tokenConfig.oracles[uint256(OracleRole.PIVOT)],\n            tokenConfig.oracles[uint256(OracleRole.FALLBACK)]\n        );\n    }\n\n    /**\n     * @notice Gets oracle and enabled status by asset address\n     * @param asset asset address\n     * @param role Oracle role\n     * @return oracle Oracle address based on role\n     * @return enabled Enabled flag of the oracle based on token config\n     */\n    function getOracle(address asset, OracleRole role) public view returns (address oracle, bool enabled) {\n        oracle = tokenConfigs[asset].oracles[uint256(role)];\n        enabled = tokenConfigs[asset].enableFlagsForOracles[uint256(role)];\n    }\n\n    function _getPrice(address asset) internal view returns (uint256) {\n        uint256 pivotPrice = INVALID_PRICE;\n\n        // Get pivot oracle price, Invalid price if not available or error\n        (address pivotOracle, bool pivotOracleEnabled) = getOracle(asset, OracleRole.PIVOT);\n        if (pivotOracleEnabled && pivotOracle != address(0)) {\n            try OracleInterface(pivotOracle).getPrice(asset) returns (uint256 pricePivot) {\n                pivotPrice = pricePivot;\n            } catch {}\n        }\n\n        // Compare main price and pivot price, return main price and if validation was successful\n        // note: In case pivot oracle is not available but main price is available and\n        // validation is successful, the main oracle price is returned.\n        (uint256 mainPrice, bool validatedPivotMain) = _getMainOraclePrice(\n            asset,\n            pivotPrice,\n            pivotOracleEnabled && pivotOracle != address(0)\n        );\n        if (mainPrice != INVALID_PRICE && validatedPivotMain) return mainPrice;\n\n        // Compare fallback and pivot if main oracle comparision fails with pivot\n        // Return fallback price when fallback price is validated successfully with pivot oracle\n        (uint256 fallbackPrice, bool validatedPivotFallback) = _getFallbackOraclePrice(asset, pivotPrice);\n        if (fallbackPrice != INVALID_PRICE && validatedPivotFallback) return fallbackPrice;\n\n        // Lastly compare main price and fallback price\n        if (\n            mainPrice != INVALID_PRICE &&\n            fallbackPrice != INVALID_PRICE &&\n            boundValidator.validatePriceWithAnchorPrice(asset, mainPrice, fallbackPrice)\n        ) {\n            return mainPrice;\n        }\n\n        revert(\"invalid resilient oracle price\");\n    }\n\n    /**\n     * @notice Gets a price for the provided asset\n     * @dev This function won't revert when price is 0, because the fallback oracle may still be\n     * able to fetch a correct price\n     * @param asset asset address\n     * @param pivotPrice Pivot oracle price\n     * @param pivotEnabled If pivot oracle is not empty and enabled\n     * @return price USD price in scaled decimals\n     * e.g. asset decimals is 8 then price is returned as 10**18 * 10**(18-8) = 10**28 decimals\n     * @return pivotValidated Boolean representing if the validation of main oracle price\n     * and pivot oracle price were successful\n     * @custom:error Invalid price error is thrown if main oracle fails to fetch price of the asset\n     * @custom:error Invalid price error is thrown if main oracle is not enabled or main oracle\n     * address is null\n     */\n    function _getMainOraclePrice(\n        address asset,\n        uint256 pivotPrice,\n        bool pivotEnabled\n    ) internal view returns (uint256, bool) {\n        (address mainOracle, bool mainOracleEnabled) = getOracle(asset, OracleRole.MAIN);\n        if (mainOracleEnabled && mainOracle != address(0)) {\n            try OracleInterface(mainOracle).getPrice(asset) returns (uint256 mainOraclePrice) {\n                if (!pivotEnabled) {\n                    return (mainOraclePrice, true);\n                }\n                if (pivotPrice == INVALID_PRICE) {\n                    return (mainOraclePrice, false);\n                }\n                return (\n                    mainOraclePrice,\n                    boundValidator.validatePriceWithAnchorPrice(asset, mainOraclePrice, pivotPrice)\n                );\n            } catch {\n                return (INVALID_PRICE, false);\n            }\n        }\n\n        return (INVALID_PRICE, false);\n    }\n\n    /**\n     * @dev This function won't revert when the price is 0 because getPrice checks if price is > 0\n     * @param asset asset address\n     * @return price USD price in 18 decimals\n     * @return pivotValidated Boolean representing if the validation of fallback oracle price\n     * and pivot oracle price were successfull\n     * @custom:error Invalid price error is thrown if fallback oracle fails to fetch price of the asset\n     * @custom:error Invalid price error is thrown if fallback oracle is not enabled or fallback oracle\n     * address is null\n     */\n    function _getFallbackOraclePrice(address asset, uint256 pivotPrice) private view returns (uint256, bool) {\n        (address fallbackOracle, bool fallbackEnabled) = getOracle(asset, OracleRole.FALLBACK);\n        if (fallbackEnabled && fallbackOracle != address(0)) {\n            try OracleInterface(fallbackOracle).getPrice(asset) returns (uint256 fallbackOraclePrice) {\n                if (pivotPrice == INVALID_PRICE) {\n                    return (fallbackOraclePrice, false);\n                }\n                return (\n                    fallbackOraclePrice,\n                    boundValidator.validatePriceWithAnchorPrice(asset, fallbackOraclePrice, pivotPrice)\n                );\n            } catch {\n                return (INVALID_PRICE, false);\n            }\n        }\n\n        return (INVALID_PRICE, false);\n    }\n\n    /**\n     * @dev This function returns the underlying asset of a vToken\n     * @param vToken vToken address\n     * @return asset underlying asset address\n     */\n    function _getUnderlyingAsset(address vToken) private view notNullAddress(vToken) returns (address asset) {\n        if (vToken == nativeMarket) {\n            asset = NATIVE_TOKEN_ADDR;\n        } else if (vToken == vai) {\n            asset = vai;\n        } else {\n            asset = VBep20Interface(vToken).underlying();\n        }\n    }\n}\n"
    },
    "contracts/test/AccessControlManager.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\ncontract AccessControlManagerScenario is AccessControlManager {}\n"
    },
    "contracts/test/BEP20Harness.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract BEP20Harness is ERC20 {\n    uint8 public decimalsInternal = 18;\n\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) {\n        decimalsInternal = decimals_;\n    }\n\n    function faucet(uint256 amount) external {\n        _mint(msg.sender, amount);\n    }\n\n    function decimals() public view virtual override returns (uint8) {\n        return decimalsInternal;\n    }\n}\n"
    },
    "contracts/test/MockAnkrBNB.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IAnkrBNB } from \"../interfaces/IAnkrBNB.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockAnkrBNB is ERC20, Ownable, IAnkrBNB {\n    uint8 private immutable _decimals;\n    uint256 public exchangeRate;\n\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) Ownable() {\n        _decimals = decimals_;\n    }\n\n    function faucet(uint256 amount) external {\n        _mint(msg.sender, amount);\n    }\n\n    function setSharesToBonds(uint256 rate) external onlyOwner {\n        exchangeRate = rate;\n    }\n\n    function sharesToBonds(uint256 amount) external view override returns (uint256) {\n        return (amount * exchangeRate) / (10 ** uint256(_decimals));\n    }\n\n    function decimals() public view virtual override(ERC20, IAnkrBNB) returns (uint8) {\n        return _decimals;\n    }\n}\n"
    },
    "contracts/test/MockEtherFiLiquidityPool.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../interfaces/IEtherFiLiquidityPool.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockEtherFiLiquidityPool is IEtherFiLiquidityPool, Ownable {\n    /// @notice The amount of eETH per weETH scaled by 1e18\n    uint256 public amountPerShare;\n\n    constructor() Ownable() {}\n\n    function setAmountPerShare(uint256 _amountPerShare) external onlyOwner {\n        amountPerShare = _amountPerShare;\n    }\n\n    function amountForShare(uint256 _share) external view override returns (uint256) {\n        return (_share * amountPerShare) / 1e18;\n    }\n}\n"
    },
    "contracts/test/MockPyth.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../interfaces/PythInterface.sol\";\n\ncontract MockPyth is AbstractPyth {\n    mapping(bytes32 => PythStructs.PriceFeed) priceFeeds;\n    uint64 sequenceNumber;\n\n    uint256 singleUpdateFeeInWei;\n    uint256 validTimePeriod;\n\n    constructor(uint256 _validTimePeriod, uint256 _singleUpdateFeeInWei) {\n        singleUpdateFeeInWei = _singleUpdateFeeInWei;\n        validTimePeriod = _validTimePeriod;\n    }\n\n    // simply update price feeds\n    function updatePriceFeedsHarness(PythStructs.PriceFeed[] calldata feeds) external {\n        require(feeds.length > 0, \"feeds length must > 0\");\n        for (uint256 i = 0; i < feeds.length; ) {\n            priceFeeds[feeds[i].id] = feeds[i];\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    // Takes an array of encoded price feeds and stores them.\n    // You can create this data either by calling createPriceFeedData or\n    // by using web3.js or ethers abi utilities.\n    function updatePriceFeeds(bytes[] calldata updateData) public payable override {\n        uint256 requiredFee = getUpdateFee(updateData.length);\n        require(msg.value >= requiredFee, \"Insufficient paid fee amount\");\n\n        if (msg.value > requiredFee) {\n            (bool success, ) = payable(msg.sender).call{ value: msg.value - requiredFee }(\"\");\n            require(success, \"failed to transfer update fee\");\n        }\n\n        uint256 freshPrices = 0;\n\n        // Chain ID is id of the source chain that the price update comes from. Since it is just a mock contract\n        // We set it to 1.\n        uint16 chainId = 1;\n\n        for (uint256 i = 0; i < updateData.length; ) {\n            PythStructs.PriceFeed memory priceFeed = abi.decode(updateData[i], (PythStructs.PriceFeed));\n\n            bool fresh = false;\n            uint256 lastPublishTime = priceFeeds[priceFeed.id].price.publishTime;\n\n            if (lastPublishTime < priceFeed.price.publishTime) {\n                // Price information is more recent than the existing price information.\n                fresh = true;\n                priceFeeds[priceFeed.id] = priceFeed;\n                freshPrices += 1;\n            }\n\n            emit PriceFeedUpdate(\n                priceFeed.id,\n                fresh,\n                chainId,\n                sequenceNumber,\n                priceFeed.price.publishTime,\n                lastPublishTime,\n                priceFeed.price.price,\n                priceFeed.price.conf\n            );\n\n            unchecked {\n                i++;\n            }\n        }\n\n        // In the real contract, the input of this function contains multiple batches that each contain multiple prices.\n        // This event is emitted when a batch is processed. In this mock contract we consider\n        // there is only one batch of prices.\n        // Each batch has (chainId, sequenceNumber) as it's unique identifier. Here chainId\n        // is set to 1 and an increasing sequence number is used.\n        emit BatchPriceFeedUpdate(chainId, sequenceNumber, updateData.length, freshPrices);\n        sequenceNumber += 1;\n\n        // There is only 1 batch of prices\n        emit UpdatePriceFeeds(msg.sender, 1, requiredFee);\n    }\n\n    function queryPriceFeed(bytes32 id) public view override returns (PythStructs.PriceFeed memory priceFeed) {\n        require(priceFeeds[id].id != 0, \"no price feed found for the given price id\");\n        return priceFeeds[id];\n    }\n\n    function priceFeedExists(bytes32 id) public view override returns (bool) {\n        return (priceFeeds[id].id != 0);\n    }\n\n    function getValidTimePeriod() public view override returns (uint256) {\n        return validTimePeriod;\n    }\n\n    function getUpdateFee(uint256 updateDataSize) public view override returns (uint256 feeAmount) {\n        return singleUpdateFeeInWei * updateDataSize;\n    }\n\n    function createPriceFeedUpdateData(\n        bytes32 id,\n        int64 price,\n        uint64 conf,\n        int32 expo,\n        int64 emaPrice,\n        uint64 emaConf,\n        uint64 publishTime\n    ) public pure returns (bytes memory priceFeedData) {\n        PythStructs.PriceFeed memory priceFeed;\n\n        priceFeed.id = id;\n\n        priceFeed.price.price = price;\n        priceFeed.price.conf = conf;\n        priceFeed.price.expo = expo;\n        priceFeed.price.publishTime = publishTime;\n\n        priceFeed.emaPrice.price = emaPrice;\n        priceFeed.emaPrice.conf = emaConf;\n        priceFeed.emaPrice.expo = expo;\n        priceFeed.emaPrice.publishTime = publishTime;\n\n        priceFeedData = abi.encode(priceFeed);\n    }\n}\n"
    },
    "contracts/test/MockSFrax.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { ISFrax } from \"../interfaces/ISFrax.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockSFrax is ERC20, Ownable, ISFrax {\n    uint8 private immutable _decimals;\n    uint256 public exchangeRate;\n\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) Ownable() {\n        _decimals = decimals_;\n    }\n\n    function faucet(uint256 amount) external {\n        _mint(msg.sender, amount);\n    }\n\n    function setRate(uint256 rate) external onlyOwner {\n        exchangeRate = rate;\n    }\n\n    function convertToAssets(uint256 shares) external view override returns (uint256) {\n        return (shares * exchangeRate) / (10 ** uint256(_decimals));\n    }\n\n    function decimals() public view virtual override(ERC20, ISFrax) returns (uint8) {\n        return _decimals;\n    }\n}\n"
    },
    "contracts/test/MockSimpleOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../interfaces/OracleInterface.sol\";\n\ncontract MockSimpleOracle is OracleInterface {\n    mapping(address => uint256) public prices;\n\n    constructor() {\n        //\n    }\n\n    function getUnderlyingPrice(address vToken) external view returns (uint256) {\n        return prices[vToken];\n    }\n\n    function getPrice(address asset) external view returns (uint256) {\n        return prices[asset];\n    }\n\n    function setPrice(address vToken, uint256 price) public {\n        prices[vToken] = price;\n    }\n}\n\ncontract MockBoundValidator is BoundValidatorInterface {\n    mapping(address => bool) public validateResults;\n    bool public twapUpdated;\n\n    constructor() {\n        //\n    }\n\n    function validatePriceWithAnchorPrice(\n        address vToken,\n        uint256 reporterPrice,\n        uint256 anchorPrice\n    ) external view returns (bool) {\n        return validateResults[vToken];\n    }\n\n    function validateAssetPriceWithAnchorPrice(\n        address asset,\n        uint256 reporterPrice,\n        uint256 anchorPrice\n    ) external view returns (bool) {\n        return validateResults[asset];\n    }\n\n    function setValidateResult(address token, bool pass) public {\n        validateResults[token] = pass;\n    }\n}\n"
    },
    "contracts/test/MockV3Aggregator.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol\";\n\n/**\n * @title MockV3Aggregator\n * @notice Based on the FluxAggregator contract\n * @notice Use this contract when you need to test\n * other contract's ability to read data from an\n * aggregator contract, but how the aggregator got\n * its answer is unimportant\n */\ncontract MockV3Aggregator is AggregatorV2V3Interface {\n    uint256 public constant version = 0;\n\n    uint8 public decimals;\n    int256 public latestAnswer;\n    uint256 public latestTimestamp;\n    uint256 public latestRound;\n\n    mapping(uint256 => int256) public getAnswer;\n    mapping(uint256 => uint256) public getTimestamp;\n    mapping(uint256 => uint256) private getStartedAt;\n\n    constructor(uint8 _decimals, int256 _initialAnswer) {\n        decimals = _decimals;\n        updateAnswer(_initialAnswer);\n    }\n\n    function getRoundData(\n        uint80 _roundId\n    )\n        external\n        view\n        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\n    {\n        return (_roundId, getAnswer[_roundId], getStartedAt[_roundId], getTimestamp[_roundId], _roundId);\n    }\n\n    function latestRoundData()\n        external\n        view\n        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)\n    {\n        return (\n            uint80(latestRound),\n            getAnswer[latestRound],\n            getStartedAt[latestRound],\n            getTimestamp[latestRound],\n            uint80(latestRound)\n        );\n    }\n\n    function description() external pure returns (string memory) {\n        return \"v0.6/tests/MockV3Aggregator.sol\";\n    }\n\n    function updateAnswer(int256 _answer) public {\n        latestAnswer = _answer;\n        latestTimestamp = block.timestamp;\n        latestRound++;\n        getAnswer[latestRound] = _answer;\n        getTimestamp[latestRound] = block.timestamp;\n        getStartedAt[latestRound] = block.timestamp;\n    }\n\n    function updateRoundData(uint80 _roundId, int256 _answer, uint256 _timestamp, uint256 _startedAt) public {\n        latestRound = _roundId;\n        latestAnswer = _answer;\n        latestTimestamp = _timestamp;\n        getAnswer[latestRound] = _answer;\n        getTimestamp[latestRound] = _timestamp;\n        getStartedAt[latestRound] = _startedAt;\n    }\n}\n"
    },
    "contracts/test/MockWBETH.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { IWBETH } from \"../interfaces/IWBETH.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockWBETH is ERC20, Ownable, IWBETH {\n    uint8 private immutable _decimals;\n    uint256 public override exchangeRate;\n\n    constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) Ownable() {\n        _decimals = decimals_;\n    }\n\n    function faucet(uint256 amount) external {\n        _mint(msg.sender, amount);\n    }\n\n    function setExchangeRate(uint256 rate) external onlyOwner {\n        exchangeRate = rate;\n    }\n\n    function decimals() public view virtual override(ERC20, IWBETH) returns (uint8) {\n        return _decimals;\n    }\n}\n"
    },
    "contracts/test/PancakePairHarness.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n// a library for performing various math operations\n\nlibrary Math {\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        z = x < y ? x : y;\n    }\n\n    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)\n    function sqrt(uint256 y) internal pure returns (uint256 z) {\n        if (y > 3) {\n            z = y;\n            uint256 x = y / 2 + 1;\n            while (x < z) {\n                z = x;\n                x = (y / x + x) / 2;\n            }\n        } else if (y != 0) {\n            z = 1;\n        }\n    }\n}\n\n// range: [0, 2**112 - 1]\n// resolution: 1 / 2**112\n\nlibrary UQ112x112 {\n    //solhint-disable-next-line state-visibility\n    uint224 constant Q112 = 2 ** 112;\n\n    // encode a uint112 as a UQ112x112\n    function encode(uint112 y) internal pure returns (uint224 z) {\n        z = uint224(y) * Q112; // never overflows\n    }\n\n    // divide a UQ112x112 by a uint112, returning a UQ112x112\n    function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {\n        z = x / uint224(y);\n    }\n}\n\ncontract PancakePairHarness {\n    using UQ112x112 for uint224;\n\n    address public token0;\n    address public token1;\n\n    uint112 private reserve0; // uses single storage slot, accessible via getReserves\n    uint112 private reserve1; // uses single storage slot, accessible via getReserves\n    uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves\n\n    uint256 public price0CumulativeLast;\n    uint256 public price1CumulativeLast;\n    uint256 public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event\n\n    // called once by the factory at time of deployment\n    function initialize(address _token0, address _token1) external {\n        token0 = _token0;\n        token1 = _token1;\n    }\n\n    // update reserves and, on the first call per block, price accumulators\n    function update(uint256 balance0, uint256 balance1, uint112 _reserve0, uint112 _reserve1) external {\n        require(balance0 <= type(uint112).max && balance1 <= type(uint112).max, \"PancakeV2: OVERFLOW\");\n        uint32 blockTimestamp = uint32(block.timestamp % 2 ** 32);\n        unchecked {\n            uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired\n            if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {\n                // * never overflows, and + overflow is desired\n                price0CumulativeLast += uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;\n                price1CumulativeLast += uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;\n            }\n        }\n        reserve0 = uint112(balance0);\n        reserve1 = uint112(balance1);\n        blockTimestampLast = blockTimestamp;\n    }\n\n    function currentBlockTimestamp() external view returns (uint32) {\n        return uint32(block.timestamp % 2 ** 32);\n    }\n\n    function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {\n        _reserve0 = reserve0;\n        _reserve1 = reserve1;\n        _blockTimestampLast = blockTimestampLast;\n    }\n}\n"
    },
    "contracts/test/VBEP20Harness.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"./BEP20Harness.sol\";\n\ncontract VBEP20Harness is BEP20Harness {\n    /**\n     * @notice Underlying asset for this VToken\n     */\n    address public underlying;\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        uint8 decimals,\n        address underlying_\n    ) BEP20Harness(name_, symbol_, decimals) {\n        underlying = underlying_;\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/access/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor (address initialOwner) {\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/interfaces/draft-IERC1822.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/beacon/IBeacon.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {BeaconProxy} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n     * function call, and allows initializating the storage of the proxy like a Solidity constructor.\n     */\n    constructor(address _logic, bytes memory _data) payable {\n        assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.implementation\")) - 1));\n        _upgradeToAndCall(_logic, _data, false);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _implementation() internal view virtual override returns (address impl) {\n        return ERC1967Upgrade._getImplementation();\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/ERC1967/ERC1967Upgrade.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n    // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n    bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function _getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n        StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Perform implementation upgrade\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeTo(address newImplementation) internal {\n        _setImplementation(newImplementation);\n        emit Upgraded(newImplementation);\n    }\n\n    /**\n     * @dev Perform implementation upgrade with additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCall(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _upgradeTo(newImplementation);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(newImplementation, data);\n        }\n    }\n\n    /**\n     * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n     *\n     * Emits an {Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(\n        address newImplementation,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        // Upgrades from old implementations will perform a rollback test. This test requires the new\n        // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n        // this special case will break upgrade paths from old UUPS implementation to new ones.\n        if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n            _setImplementation(newImplementation);\n        } else {\n            try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n                require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n            } catch {\n                revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n            }\n            _upgradeToAndCall(newImplementation, data, forceCall);\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n     * validated in the constructor.\n     */\n    bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _getAdmin() internal view virtual returns (address) {\n        return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the EIP1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n        StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     */\n    function _changeAdmin(address newAdmin) internal {\n        emit AdminChanged(_getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n     */\n    bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Emitted when the beacon is upgraded.\n     */\n    event BeaconUpgraded(address indexed beacon);\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function _getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the EIP1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n        require(Address.isContract(IBeacon(newBeacon).implementation()), \"ERC1967: beacon implementation is not a contract\");\n        StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n    }\n\n    /**\n     * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n     * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n     *\n     * Emits a {BeaconUpgraded} event.\n     */\n    function _upgradeBeaconToAndCall(\n        address newBeacon,\n        bytes memory data,\n        bool forceCall\n    ) internal {\n        _setBeacon(newBeacon);\n        emit BeaconUpgraded(newBeacon);\n        if (data.length > 0 || forceCall) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        }\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/Proxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function\n     * and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internall call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _beforeFallback();\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n     * is empty.\n     */\n    receive() external payable virtual {\n        _fallback();\n    }\n\n    /**\n     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n     * call, or as part of the Solidity `fallback` or `receive` functions.\n     *\n     * If overriden should call `super._beforeFallback()`.\n     */\n    function _beforeFallback() internal virtual {}\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./TransparentUpgradeableProxy.sol\";\nimport \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n\n    constructor (address initialOwner) Ownable(initialOwner) {}\n\n    /**\n     * @dev Returns the current implementation of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"implementation()\")) == 0x5c60da1b\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"5c60da1b\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Returns the current admin of `proxy`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {\n        // We need to manually run the static call since the getter cannot be flagged as view\n        // bytes4(keccak256(\"admin()\")) == 0xf851a440\n        (bool success, bytes memory returndata) = address(proxy).staticcall(hex\"f851a440\");\n        require(success);\n        return abi.decode(returndata, (address));\n    }\n\n    /**\n     * @dev Changes the admin of `proxy` to `newAdmin`.\n     *\n     * Requirements:\n     *\n     * - This contract must be the current admin of `proxy`.\n     */\n    function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {\n        proxy.changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {\n        proxy.upgradeTo(implementation);\n    }\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See\n     * {TransparentUpgradeableProxy-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     */\n    function upgradeAndCall(\n        TransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/TransparentUpgradeableProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(\n        address _logic,\n        address admin_,\n        bytes memory _data\n    ) payable ERC1967Proxy(_logic, _data) {\n        assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n        _changeAdmin(admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function admin() external ifAdmin returns (address admin_) {\n        admin_ = _getAdmin();\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function implementation() external ifAdmin returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {AdminChanged} event.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.\n     */\n    function changeAdmin(address newAdmin) external virtual ifAdmin {\n        _changeAdmin(newAdmin);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n     */\n    function upgradeTo(address newImplementation) external ifAdmin {\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n     */\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n        _upgradeToAndCall(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n     */\n    function _beforeFallback() internal virtual override {\n        require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n        super._beforeFallback();\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0-rc.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(isContract(target), \"Address: delegate call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/utils/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/openzeppelin/utils/StorageSlot.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly {\n            r.slot := slot\n        }\n    }\n}\n"
    },
    "hardhat-deploy/solc_0.8/proxy/OptimizedTransparentUpgradeableProxy.sol": {
      "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../openzeppelin/proxy/ERC1967/ERC1967Proxy.sol\";\n\n/**\n * @dev This contract implements a proxy that is upgradeable by an admin.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches one of the admin functions exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the\n * implementation. If the admin tries to call a function on the implementation it will fail with an error that says\n * \"admin cannot fallback to proxy target\".\n *\n * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing\n * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due\n * to sudden errors when trying to call a function from the proxy implementation.\n *\n * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,\n * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.\n */\ncontract OptimizedTransparentUpgradeableProxy is ERC1967Proxy {\n    address internal immutable _ADMIN;\n\n    /**\n     * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and\n     * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.\n     */\n    constructor(\n        address _logic,\n        address admin_,\n        bytes memory _data\n    ) payable ERC1967Proxy(_logic, _data) {\n        assert(_ADMIN_SLOT == bytes32(uint256(keccak256(\"eip1967.proxy.admin\")) - 1));\n        _ADMIN = admin_;\n\n        // still store it to work with EIP-1967\n        bytes32 slot = _ADMIN_SLOT;\n        // solhint-disable-next-line no-inline-assembly\n        assembly {\n            sstore(slot, admin_)\n        }\n        emit AdminChanged(address(0), admin_);\n    }\n\n    /**\n     * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.\n     */\n    modifier ifAdmin() {\n        if (msg.sender == _getAdmin()) {\n            _;\n        } else {\n            _fallback();\n        }\n    }\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function admin() external ifAdmin returns (address admin_) {\n        admin_ = _getAdmin();\n    }\n\n    /**\n     * @dev Returns the current implementation.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the\n     * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function implementation() external ifAdmin returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.\n     */\n    function upgradeTo(address newImplementation) external ifAdmin {\n        _upgradeToAndCall(newImplementation, bytes(\"\"), false);\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified\n     * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the\n     * proxied contract.\n     *\n     * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.\n     */\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin {\n        _upgradeToAndCall(newImplementation, data, true);\n    }\n\n    /**\n     * @dev Returns the current admin.\n     */\n    function _admin() internal view virtual returns (address) {\n        return _getAdmin();\n    }\n\n    /**\n     * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.\n     */\n    function _beforeFallback() internal virtual override {\n        require(msg.sender != _getAdmin(), \"TransparentUpgradeableProxy: admin cannot fallback to proxy target\");\n        super._beforeFallback();\n    }\n\n    function _getAdmin() internal view virtual override returns (address) {\n        return _ADMIN;\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "mode": "3"
    },
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": ["storageLayout", "abi", "evm.methodIdentifiers", "metadata", "devdoc", "userdoc"],
        "": ["ast"]
      }
    },
    "metadata": {
      "bytecodeHash": "none"
    },
    "detectMissingLibraries": false,
    "forceEVMLA": false,
    "enableEraVMExtensions": false,
    "libraries": {}
  }
}
