{
  "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/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/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/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"
    },
    "@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/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/IAccountant.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IAccountant {\n    function getRateSafe() external view returns (uint256);\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/IAsBNB.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IAsBNB {\n    function minter() external view returns (address);\n    function decimals() external view returns (uint8);\n}\n"
    },
    "contracts/interfaces/IAsBNBMinter.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IAsBNBMinter {\n    function convertToTokens(uint256 amount) external view returns (uint256);\n}\n"
    },
    "contracts/interfaces/ICappedOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface ICappedOracle {\n    function updateSnapshot() external;\n}\n"
    },
    "contracts/interfaces/IERC4626.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\ninterface IERC4626 {\n    function convertToAssets(uint256 shares) 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\n    function getPtToSyRate(address market, uint32 duration) external view returns (uint256);\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"
    },
    "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/IZkETH.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface IZkETH {\n    function LSTPerToken() 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 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/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/lib/Transient.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\nlibrary Transient {\n    /**\n     * @notice Cache the asset price into transient storage\n     * @param key address of the asset\n     * @param value asset price\n     */\n    function cachePrice(bytes32 cacheSlot, address key, uint256 value) internal {\n        bytes32 slot = keccak256(abi.encode(cacheSlot, key));\n        assembly (\"memory-safe\") {\n            tstore(slot, value)\n        }\n    }\n\n    /**\n     * @notice Read cached price from transient storage\n     * @param key address of the asset\n     * @return value cached asset price\n     */\n    function readCachedPrice(bytes32 cacheSlot, address key) internal view returns (uint256 value) {\n        bytes32 slot = keccak256(abi.encode(cacheSlot, key));\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\n    }\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    constructor(\n        address ankrBNB,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            ankrBNB,\n            NATIVE_TOKEN_ADDR,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {}\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() public view override returns (uint256) {\n        return IAnkrBNB(CORRELATED_TOKEN).sharesToBonds(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/AsBNBOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IAsBNB } from \"../interfaces/IAsBNB.sol\";\nimport { IAsBNBMinter } from \"../interfaces/IAsBNBMinter.sol\";\nimport { EXP_SCALE } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title asBNBOracle\n * @author Venus\n * @notice This oracle fetches the price of asBNB asset\n */\ncontract AsBNBOracle is CorrelatedTokenOracle {\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address asBNB,\n        address slisBNB,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            asBNB,\n            slisBNB,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {}\n\n    /**\n     * @notice Fetches the amount of slisBNB for 1 asBNB\n     * @return price The amount of slisBNB for asBNB\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        IAsBNBMinter minter = IAsBNBMinter(IAsBNB(CORRELATED_TOKEN).minter());\n        return minter.convertToTokens(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 _acm Address of the access control manager contract\n     */\n    function initialize(address _sidRegistryAddress, address _acm) external initializer {\n        sidRegistryAddress = _sidRegistryAddress;\n        __AccessControlled_init(_acm);\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    IStaderStakeManager public immutable STAKE_MANAGER;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address stakeManager,\n        address bnbx,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            bnbx,\n            NATIVE_TOKEN_ADDR,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\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() public 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; ++i) {\n            setValidateConfig(configs[i]);\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 successfully 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; ++i) {\n            setTokenConfig(tokenConfigs_[i]);\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 successfully 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, ResilientOracleInterface } from \"../../interfaces/OracleInterface.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { SECONDS_PER_YEAR } from \"@venusprotocol/solidity-utilities/contracts/constants.sol\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\nimport { ICappedOracle } from \"../../interfaces/ICappedOracle.sol\";\nimport { IAccessControlManagerV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.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, ICappedOracle {\n    /// @notice Address of the correlated token\n    address public immutable CORRELATED_TOKEN;\n\n    /// @notice Address of the underlying token\n    address public immutable UNDERLYING_TOKEN;\n\n    /// @notice Address of Resilient Oracle\n    ResilientOracleInterface public immutable RESILIENT_ORACLE;\n\n    /// @notice Address of the AccessControlManager contract\n    IAccessControlManagerV8 public immutable ACCESS_CONTROL_MANAGER;\n\n    //// @notice Growth rate percentage in seconds. Ex: 1e18 is 100%\n    uint256 public growthRatePerSecond;\n\n    /// @notice Snapshot update interval\n    uint256 public snapshotInterval;\n\n    /// @notice Last stored snapshot maximum exchange rate\n    uint256 public snapshotMaxExchangeRate;\n\n    /// @notice Last stored snapshot timestamp\n    uint256 public snapshotTimestamp;\n\n    /// @notice Gap to add when updating the snapshot\n    uint256 public snapshotGap;\n\n    /// @notice Emitted when the snapshot is updated\n    event SnapshotUpdated(uint256 indexed maxExchangeRate, uint256 indexed timestamp);\n\n    /// @notice Emitted when the growth rate is updated\n    event GrowthRateUpdated(\n        uint256 indexed oldGrowthRatePerSecond,\n        uint256 indexed newGrowthRatePerSecond,\n        uint256 indexed oldSnapshotInterval,\n        uint256 newSnapshotInterval\n    );\n\n    /// @notice Emitted when the snapshot gap is updated\n    event SnapshotGapUpdated(uint256 indexed oldSnapshotGap, uint256 indexed newSnapshotGap);\n\n    /// @notice Thrown if the token address is invalid\n    error InvalidTokenAddress();\n\n    /// @notice Thrown if the growth rate is invalid\n    error InvalidGrowthRate();\n\n    /// @notice Thrown if the initial snapshot is invalid\n    error InvalidInitialSnapshot();\n\n    /// @notice Thrown if the max snapshot exchange rate is invalid\n    error InvalidSnapshotMaxExchangeRate();\n\n    /// @notice @notice Thrown when the action is prohibited by AccessControlManager\n    error Unauthorized(address sender, address calledContract, string methodSignature);\n\n    /**\n     * @notice Constructor for the implementation contract.\n     * @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid\n     * @custom:error InvalidInitialSnapshot error is thrown if the initial snapshot values are invalid\n     */\n    constructor(\n        address _correlatedToken,\n        address _underlyingToken,\n        address _resilientOracle,\n        uint256 _annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 _initialSnapshotMaxExchangeRate,\n        uint256 _initialSnapshotTimestamp,\n        address _accessControlManager,\n        uint256 _snapshotGap\n    ) {\n        growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;\n\n        if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))\n            revert InvalidGrowthRate();\n\n        if ((_initialSnapshotMaxExchangeRate == 0 || _initialSnapshotTimestamp == 0) && _snapshotInterval > 0) {\n            revert InvalidInitialSnapshot();\n        }\n\n        ensureNonzeroAddress(_correlatedToken);\n        ensureNonzeroAddress(_underlyingToken);\n        ensureNonzeroAddress(_resilientOracle);\n        ensureNonzeroAddress(_accessControlManager);\n\n        CORRELATED_TOKEN = _correlatedToken;\n        UNDERLYING_TOKEN = _underlyingToken;\n        RESILIENT_ORACLE = ResilientOracleInterface(_resilientOracle);\n        snapshotInterval = _snapshotInterval;\n\n        snapshotMaxExchangeRate = _initialSnapshotMaxExchangeRate;\n        snapshotTimestamp = _initialSnapshotTimestamp;\n        snapshotGap = _snapshotGap;\n\n        ACCESS_CONTROL_MANAGER = IAccessControlManagerV8(_accessControlManager);\n    }\n\n    /**\n     * @notice Directly sets the snapshot exchange rate and timestamp\n     * @param _snapshotMaxExchangeRate The exchange rate to set\n     * @param _snapshotTimestamp The timestamp to set\n     * @custom:event Emits SnapshotUpdated event on successful update of the snapshot\n     */\n    function setSnapshot(uint256 _snapshotMaxExchangeRate, uint256 _snapshotTimestamp) external {\n        _checkAccessAllowed(\"setSnapshot(uint256,uint256)\");\n\n        snapshotMaxExchangeRate = _snapshotMaxExchangeRate;\n        snapshotTimestamp = _snapshotTimestamp;\n\n        emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);\n    }\n\n    /**\n     * @notice Sets the growth rate and snapshot interval\n     * @param _annualGrowthRate The annual growth rate to set\n     * @param _snapshotInterval The snapshot interval to set\n     * @custom:error InvalidGrowthRate error is thrown if the growth rate is invalid\n     * @custom:event Emits GrowthRateUpdated event on successful update of the growth rate\n     */\n    function setGrowthRate(uint256 _annualGrowthRate, uint256 _snapshotInterval) external {\n        _checkAccessAllowed(\"setGrowthRate(uint256,uint256)\");\n        uint256 oldGrowthRatePerSecond = growthRatePerSecond;\n\n        growthRatePerSecond = _annualGrowthRate / SECONDS_PER_YEAR;\n\n        if ((growthRatePerSecond == 0 && _snapshotInterval > 0) || (growthRatePerSecond > 0 && _snapshotInterval == 0))\n            revert InvalidGrowthRate();\n\n        emit GrowthRateUpdated(oldGrowthRatePerSecond, growthRatePerSecond, snapshotInterval, _snapshotInterval);\n\n        snapshotInterval = _snapshotInterval;\n    }\n\n    /**\n     * @notice Sets the snapshot gap\n     * @param _snapshotGap The snapshot gap to set\n     * @custom:event Emits SnapshotGapUpdated event on successful update of the snapshot gap\n     */\n    function setSnapshotGap(uint256 _snapshotGap) external {\n        _checkAccessAllowed(\"setSnapshotGap(uint256)\");\n\n        emit SnapshotGapUpdated(snapshotGap, _snapshotGap);\n\n        snapshotGap = _snapshotGap;\n    }\n\n    /**\n     * @notice Returns if the price is capped\n     * @return isCapped Boolean indicating if the price is capped\n     */\n    function isCapped() external view virtual returns (bool) {\n        if (snapshotInterval == 0) {\n            return false;\n        }\n\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\n        if (maxAllowedExchangeRate == 0) {\n            return false;\n        }\n\n        uint256 exchangeRate = getUnderlyingAmount();\n\n        return exchangeRate > maxAllowedExchangeRate;\n    }\n\n    /**\n     * @notice Updates the snapshot price and timestamp\n     * @custom:event Emits SnapshotUpdated event on successful update of the snapshot\n     * @custom:error InvalidSnapshotMaxExchangeRate error is thrown if the max snapshot exchange rate is zero\n     */\n    function updateSnapshot() public override {\n        if (block.timestamp - snapshotTimestamp < snapshotInterval || snapshotInterval == 0) return;\n\n        uint256 exchangeRate = getUnderlyingAmount();\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\n\n        snapshotMaxExchangeRate =\n            (exchangeRate > maxAllowedExchangeRate ? maxAllowedExchangeRate : exchangeRate) +\n            snapshotGap;\n        snapshotTimestamp = block.timestamp;\n\n        if (snapshotMaxExchangeRate == 0) revert InvalidSnapshotMaxExchangeRate();\n\n        RESILIENT_ORACLE.updateAssetPrice(UNDERLYING_TOKEN);\n        emit SnapshotUpdated(snapshotMaxExchangeRate, snapshotTimestamp);\n    }\n\n    /**\n     * @notice Fetches the price of the token\n     * @param asset Address of the token\n     * @return price The price of the token in scaled decimal places. It can be capped\n     * to a maximum value taking into account the growth rate\n     * @custom:error InvalidTokenAddress error is thrown if the token address is invalid\n     */\n    function getPrice(address asset) public view override returns (uint256) {\n        if (asset != CORRELATED_TOKEN) revert InvalidTokenAddress();\n\n        uint256 exchangeRate = getUnderlyingAmount();\n\n        if (snapshotInterval == 0) {\n            return _calculatePrice(exchangeRate);\n        }\n\n        uint256 maxAllowedExchangeRate = getMaxAllowedExchangeRate();\n\n        uint256 finalExchangeRate = (exchangeRate > maxAllowedExchangeRate && maxAllowedExchangeRate != 0)\n            ? maxAllowedExchangeRate\n            : exchangeRate;\n\n        return _calculatePrice(finalExchangeRate);\n    }\n\n    /**\n     * @notice Gets the maximum allowed exchange rate for token\n     * @return maxExchangeRate Maximum allowed exchange rate\n     */\n    function getMaxAllowedExchangeRate() public view returns (uint256) {\n        uint256 timeElapsed = block.timestamp - snapshotTimestamp;\n        uint256 maxExchangeRate = snapshotMaxExchangeRate +\n            (snapshotMaxExchangeRate * growthRatePerSecond * timeElapsed) /\n            1e18;\n        return maxExchangeRate;\n    }\n\n    /**\n     * @notice Gets the underlying amount for correlated token\n     * @return underlyingAmount Amount of underlying token\n     */\n    function getUnderlyingAmount() public view virtual returns (uint256);\n\n    /**\n     * @notice Fetches price of the token based on an underlying exchange rate\n     * @param exchangeRate The underlying exchange rate to use\n     * @return price The price of the token in scaled decimal places\n     */\n    function _calculatePrice(uint256 exchangeRate) internal view returns (uint256) {\n        uint256 underlyingUSDPrice = RESILIENT_ORACLE.getPrice(UNDERLYING_TOKEN);\n\n        IERC20Metadata token = IERC20Metadata(CORRELATED_TOKEN);\n        uint256 decimals = token.decimals();\n\n        return (exchangeRate * underlyingUSDPrice) / (10 ** decimals);\n    }\n\n    /**\n     * @notice Reverts if the call is not allowed by AccessControlManager\n     * @param signature Method signature\n     * @custom:error Unauthorized error is thrown if the call is not allowed\n     */\n    function _checkAccessAllowed(string memory signature) internal view {\n        bool isAllowedToCall = ACCESS_CONTROL_MANAGER.isAllowedToCall(msg.sender, signature);\n\n        if (!isAllowedToCall) {\n            revert Unauthorized(msg.sender, address(this), signature);\n        }\n    }\n}\n"
    },
    "contracts/oracles/ERC4626Oracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IERC4626 } from \"../interfaces/IERC4626.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title ERC4626Oracle\n * @author Venus\n * @notice This oracle fetches the price of ERC4626 tokens\n */\ncontract ERC4626Oracle is CorrelatedTokenOracle {\n    uint256 public immutable ONE_CORRELATED_TOKEN;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address correlatedToken,\n        address underlyingToken,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            correlatedToken,\n            underlyingToken,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\n        ONE_CORRELATED_TOKEN = 10 ** IERC4626(correlatedToken).decimals();\n    }\n\n    /**\n     * @notice Fetches the amount of underlying token for 1 correlated token\n     * @return amount The amount of underlying token for correlated token\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return IERC4626(CORRELATED_TOKEN).convertToAssets(ONE_CORRELATED_TOKEN);\n    }\n}\n"
    },
    "contracts/oracles/EtherfiAccountantOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { IAccountant } from \"../interfaces/IAccountant.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title EtherfiAccountantOracle\n * @author Venus\n * @notice This oracle fetches the price of any Ether.fi asset that uses\n * Accountant contracts to derive the underlying price\n */\ncontract EtherfiAccountantOracle is CorrelatedTokenOracle {\n    /// @notice Address of Accountant\n    IAccountant public immutable ACCOUNTANT;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address accountant,\n        address correlatedToken,\n        address underlyingToken,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            correlatedToken,\n            underlyingToken,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\n        ensureNonzeroAddress(accountant);\n        ACCOUNTANT = IAccountant(accountant);\n    }\n\n    /**\n     * @notice Fetches the conversion rate from the ACCOUNTANT contract\n     * @return amount Amount of WBTC\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return ACCOUNTANT.getRateSafe();\n    }\n}\n"
    },
    "contracts/oracles/mocks/MockAccountant.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../../interfaces/IAccountant.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockAccountant is IAccountant, Ownable {\n    uint256 public rate;\n\n    constructor() Ownable() {}\n\n    function setRate(uint256 _rate) external onlyOwner {\n        rate = _rate;\n    }\n\n    function getRateSafe() external view override returns (uint256) {\n        return rate;\n    }\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    mapping(address => mapping(uint32 => uint256)) public ptToSyRate;\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 setPtToSyRate(address market, uint32 duration, uint256 rate) external onlyOwner {\n        ptToSyRate[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 getPtToSyRate(address market, uint32 duration) external view returns (uint256) {\n        return ptToSyRate[market][duration];\n    }\n\n    function getOracleState(\n        address /* market */,\n        uint32 /* duration */\n    )\n        external\n        pure\n        returns (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied)\n    {\n        return (false, 0, true);\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    OracleInterface public immutable INTERMEDIATE_ORACLE;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address correlatedToken,\n        address underlyingToken,\n        address resilientOracle,\n        address intermediateOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            correlatedToken,\n            underlyingToken,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\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() public 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\";\nimport { IERC20Metadata } from \"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\";\n\n/**\n * @title PendleOracle\n * @author Venus\n * @notice This oracle fetches the price of a pendle token\n * @dev As a base price the oracle uses either the price of the Pendle\n * market's asset (in this case PT_TO_ASSET rate should be used) or\n * the price of the Pendle market's interest bearing token (e.g. wstETH\n * for stETH; in this case PT_TO_SY rate should be used). Technically,\n * interest bearing token is different from standardized yield (SY) token,\n * but since SY is a wrapper around an interest bearing token, we can safely\n * assume the prices of the two are equal. This is not always true for asset\n * price though: using PT_TO_ASSET rate assumes that the yield token can\n * be seamlessly redeemed for the underlying asset. In reality, this might\n * not always be the case. For more details, see\n * https://docs.pendle.finance/Developers/Contracts/StandardizedYield\n */\ncontract PendleOracle is CorrelatedTokenOracle {\n    struct ConstructorParams {\n        /// @notice Pendle market\n        address market;\n        /// @notice Pendle oracle\n        address ptOracle;\n        /// @notice Either PT_TO_ASSET or PT_TO_SY\n        RateKind rateKind;\n        /// @notice Pendle PT token\n        address ptToken;\n        /// @notice Underlying token, can be either the market's asset or the interest bearing token\n        address underlyingToken;\n        /// @notice Resilient oracle to get the underlying token price from\n        address resilientOracle;\n        /// @notice TWAP duration to call Pendle oracle with\n        uint32 twapDuration;\n        /// @notice Annual growth rate of the underlying token\n        uint256 annualGrowthRate;\n        /// @notice Snapshot interval for the oracle\n        uint256 snapshotInterval;\n        /// @notice Initial exchange rate of the underlying token\n        uint256 initialSnapshotMaxExchangeRate;\n        /// @notice Initial timestamp of the underlying token\n        uint256 initialSnapshotTimestamp;\n        /// @notice Access control manager\n        address accessControlManager;\n        /// @notice Gap to add when updating the snapshot\n        uint256 snapshotGap;\n    }\n\n    /// @notice Which asset to use as a base for the returned PT\n    /// price. Can be either a standardized yield token (SY), in\n    /// this case PT/SY price is returned, or the Pendle\n    /// market's asset directly.\n    enum RateKind {\n        PT_TO_ASSET,\n        PT_TO_SY\n    }\n\n    /// @notice Address of the PT oracle\n    IPendlePtOracle public immutable PT_ORACLE;\n\n    /// @notice Whether to use PT/SY (standardized yield token) rate\n    /// or PT/market asset rate\n    RateKind public immutable RATE_KIND;\n\n    /// @notice Address of the market\n    address public immutable MARKET;\n\n    /// @notice Twap duration for the oracle\n    uint32 public immutable TWAP_DURATION;\n\n    /// @notice Decimals of the underlying token\n    /// @dev We make an assumption that the underlying decimals will\n    /// not change throughout the lifetime of the Pendle market\n    uint8 public immutable UNDERLYING_DECIMALS;\n\n    /// @notice Thrown if the duration is invalid\n    error InvalidDuration();\n\n    /**\n     * @notice Constructor for the implementation contract.\n     * @custom:error InvalidDuration Thrown if the duration is invalid\n     */\n    constructor(\n        ConstructorParams memory params\n    )\n        CorrelatedTokenOracle(\n            params.ptToken,\n            params.underlyingToken,\n            params.resilientOracle,\n            params.annualGrowthRate,\n            params.snapshotInterval,\n            params.initialSnapshotMaxExchangeRate,\n            params.initialSnapshotTimestamp,\n            params.accessControlManager,\n            params.snapshotGap\n        )\n    {\n        ensureNonzeroAddress(params.market);\n        ensureNonzeroAddress(params.ptOracle);\n        ensureNonzeroValue(params.twapDuration);\n\n        MARKET = params.market;\n        PT_ORACLE = IPendlePtOracle(params.ptOracle);\n        RATE_KIND = params.rateKind;\n        TWAP_DURATION = params.twapDuration;\n        UNDERLYING_DECIMALS = IERC20Metadata(UNDERLYING_TOKEN).decimals();\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    /// @notice Fetches the amount of underlying token for 1 PT\n    /// @return amount The amount of underlying token (either the market's asset\n    /// or the yield token) for 1 PT, adjusted for decimals such that the result\n    /// has the same precision as the underlying token\n    function getUnderlyingAmount() public view override returns (uint256) {\n        uint256 rate;\n        if (RATE_KIND == RateKind.PT_TO_SY) {\n            rate = PT_ORACLE.getPtToSyRate(MARKET, TWAP_DURATION);\n        } else {\n            rate = PT_ORACLE.getPtToAssetRate(MARKET, TWAP_DURATION);\n        }\n        return ((10 ** UNDERLYING_DECIMALS) * rate) / 1e18;\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    constructor(\n        address sFrax,\n        address frax,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            sFrax,\n            frax,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {}\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() public 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 _acm 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 _acm, uint256 _maxAllowedPriceDifference) external initializer {\n        ensureNonzeroValue(_maxAllowedPriceDifference);\n\n        __AccessControlled_init(_acm);\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    ISynclubStakeManager public immutable STAKE_MANAGER;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address stakeManager,\n        address slisBNB,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            slisBNB,\n            NATIVE_TOKEN_ADDR,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\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() public 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    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    constructor(\n        address stakePool,\n        address stkBNB,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            stkBNB,\n            NATIVE_TOKEN_ADDR,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\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     * @custom:error PoolTokenSupplyIsZero error is thrown if the pool token supply is zero\n     */\n    function getUnderlyingAmount() public 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    constructor(\n        address wbeth,\n        address eth,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            wbeth,\n            eth,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {}\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() public view override returns (uint256) {\n        return IWBETH(CORRELATED_TOKEN).exchangeRate();\n    }\n}\n"
    },
    "contracts/oracles/WeETHAccountantOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\nimport { IAccountant } from \"../interfaces/IAccountant.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title WeETHAccountantOracle\n * @author Venus\n * @notice This oracle fetches the price of Ether.fi tokens based on an `Accountant` contract (i.e. weETHs and weETHk)\n */\ncontract WeETHAccountantOracle is CorrelatedTokenOracle {\n    /// @notice Address of Accountant\n    IAccountant public immutable ACCOUNTANT;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address accountant,\n        address weethLRT,\n        address weth,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            weethLRT,\n            weth,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\n        ensureNonzeroAddress(accountant);\n        ACCOUNTANT = IAccountant(accountant);\n    }\n\n    /**\n     * @notice Gets the WETH for 1 weETH LRT\n     * @return amount Amount of WETH\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return ACCOUNTANT.getRateSafe();\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    IEtherFiLiquidityPool public immutable LIQUIDITY_POOL;\n\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address liquidityPool,\n        address weETH,\n        address eETH,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            weETH,\n            eETH,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\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() public 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\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.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 Address of stETH\n    IStETH public immutable STETH;\n\n    /// @notice Constructor for the implementation contract.\n    /// @dev The underlyingToken must be correlated so that 1 underlyingToken is equal to 1 stETH, because\n    /// getUnderlyingAmount() implicitly assumes that\n    constructor(\n        address stETH,\n        address wstETH,\n        address underlyingToken,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            wstETH,\n            underlyingToken,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {\n        ensureNonzeroAddress(stETH);\n        STETH = IStETH(stETH);\n    }\n\n    /**\n     * @notice Gets the amount of underlyingToken for 1 wstETH, assuming that 1 underlyingToken is equivalent to 1 stETH\n     * @return amount Amount of underlyingToken\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return STETH.getPooledEthByShares(EXP_SCALE);\n    }\n}\n"
    },
    "contracts/oracles/ZkETHOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IZkETH } from \"../interfaces/IZkETH.sol\";\nimport { CorrelatedTokenOracle } from \"./common/CorrelatedTokenOracle.sol\";\n\n/**\n * @title ZkETHOracle\n * @author Venus\n * @notice This oracle fetches the price of zkETH\n */\ncontract ZkETHOracle is CorrelatedTokenOracle {\n    /// @notice Constructor for the implementation contract.\n    constructor(\n        address zkETH,\n        address rzkETH,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 _snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 _snapshotGap\n    )\n        CorrelatedTokenOracle(\n            zkETH,\n            rzkETH,\n            resilientOracle,\n            annualGrowthRate,\n            _snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            _snapshotGap\n        )\n    {}\n\n    /**\n     * @notice Gets the amount of rzkETH for 1 zkETH\n     * @return amount Amount of rzkETH\n     */\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return IZkETH(CORRELATED_TOKEN).LSTPerToken();\n    }\n}\n"
    },
    "contracts/ReferenceOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\n// SPDX-FileCopyrightText: 2025 Venus\npragma solidity 0.8.25;\n\nimport { Ownable2StepUpgradeable } from \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { ResilientOracleInterface, OracleInterface } from \"./interfaces/OracleInterface.sol\";\n\n/**\n * @title ReferenceOracle\n * @author Venus\n * @notice Reference oracle is the oracle that is not used for production but required for\n * price monitoring. This oracle contains some extra configurations for assets required to\n * compute reference prices of their derivative assets (OneJump, ERC4626, Pendle, etc.)\n */\ncontract ReferenceOracle is Ownable2StepUpgradeable, OracleInterface {\n    struct ExternalPrice {\n        /// @notice asset address\n        address asset;\n        /// @notice price of the asset from an external source\n        uint256 price;\n    }\n\n    /// @notice Slot to temporarily store price information from external sources\n    /// like CMC/Coingecko, useful to compute prices of derivative assets based on\n    /// prices of the base assets with no on chain price information\n    bytes32 public constant PRICES_SLOT = keccak256(abi.encode(\"venus-protocol/oracle/ReferenceOracle/prices\"));\n\n    /// @notice Resilient oracle address\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    ResilientOracleInterface public immutable RESILIENT_ORACLE;\n\n    /// @notice Oracle configuration for assets\n    mapping(address => OracleInterface) public oracles;\n\n    /// @notice Event emitted when an oracle is set\n    event OracleConfigured(address indexed asset, address indexed oracle);\n\n    /**\n     * @notice Constructor for the implementation contract. Sets immutable variables.\n     * @param resilientOracle Resilient oracle address\n     * @custom:error ZeroAddressNotAllowed is thrown if resilient oracle address is null\n     * @custom:oz-upgrades-unsafe-allow constructor\n     */\n    constructor(ResilientOracleInterface resilientOracle) {\n        ensureNonzeroAddress(address(resilientOracle));\n        RESILIENT_ORACLE = resilientOracle;\n        _disableInitializers();\n    }\n\n    /**\n     * @notice Initializes the contract admin\n     */\n    function initialize() external initializer {\n        __Ownable2Step_init();\n    }\n\n    /**\n     * @notice Sets an oracle to use for a specific asset\n     * @dev The production resilientOracle will be used if zero address is passed\n     * @param asset Asset address\n     * @param oracle Oracle address\n     * @custom:access Only owner\n     * @custom:error ZeroAddressNotAllowed is thrown if asset address is null\n     * @custom:event Emits OracleConfigured event\n     */\n    function setOracle(address asset, OracleInterface oracle) external onlyOwner {\n        ensureNonzeroAddress(asset);\n        oracles[asset] = OracleInterface(oracle);\n        emit OracleConfigured(asset, address(oracle));\n    }\n\n    /**\n     * @notice Gets price of the asset assuming other assets have the defined price\n     * @param asset asset address\n     * @param externalPrices an array of prices for other assets\n     * @return USD price in scaled decimal places\n     */\n    function getPriceAssuming(address asset, ExternalPrice[] memory externalPrices) external returns (uint256) {\n        uint256 externalPricesCount = externalPrices.length;\n        for (uint256 i = 0; i < externalPricesCount; ++i) {\n            _storeExternalPrice(externalPrices[i].asset, externalPrices[i].price);\n        }\n        return _getPrice(asset);\n    }\n\n    /**\n     * @notice Gets price of the asset\n     * @param asset asset address\n     * @return USD price in scaled decimal places\n     */\n    function getPrice(address asset) external view override returns (uint256) {\n        return _getPrice(asset);\n    }\n\n    function _storeExternalPrice(address asset, uint256 price) internal {\n        bytes32 slot = keccak256(abi.encode(PRICES_SLOT, asset));\n        // solhint-disable-next-line no-inline-assembly\n        assembly (\"memory-safe\") {\n            tstore(slot, price)\n        }\n    }\n\n    function _getPrice(address asset) internal view returns (uint256) {\n        uint256 externalPrice = _loadExternalPrice(asset);\n        if (externalPrice != 0) {\n            return externalPrice;\n        }\n        OracleInterface oracle = oracles[asset];\n        if (oracle != OracleInterface(address(0))) {\n            return oracle.getPrice(asset);\n        }\n        return RESILIENT_ORACLE.getPrice(asset);\n    }\n\n    function _loadExternalPrice(address asset) internal view returns (uint256 value) {\n        bytes32 slot = keccak256(abi.encode(PRICES_SLOT, asset));\n        // solhint-disable-next-line no-inline-assembly\n        assembly (\"memory-safe\") {\n            value := tload(slot)\n        }\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 { PausableUpgradeable } from \"@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol\";\nimport { VBep20Interface } from \"./interfaces/VBep20Interface.sol\";\nimport { OracleInterface, ResilientOracleInterface, BoundValidatorInterface } from \"./interfaces/OracleInterface.sol\";\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { ICappedOracle } from \"./interfaces/ICappedOracle.sol\";\nimport { Transient } from \"./lib/Transient.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.\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, other oracles are used as the pivot oracle depending\n * on which supports the given market and Binance oracle is used as the fallback oracle.\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        /// @notice `cachingEnabled` is a flag that indicates whether the asset price should be cached\n        bool cachingEnabled;\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 Slot to cache the asset's price, used for transient storage\n    /// custom:storage-location erc7201:venus-protocol/oracle/ResilientOracle/cache\n    /// keccak256(abi.encode(uint256(keccak256(\"venus-protocol/oracle/ResilientOracle/cache\")) - 1))\n    ///   & ~bytes32(uint256(0xff))\n    bytes32 public constant CACHE_SLOT = 0x4e99ec55972332f5e0ef9c6623192c0401b609161bffae64d9ccdd7ad6cc7800;\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    /// Event emitted when an asset cachingEnabled flag is set\n    event CachedEnabled(address indexed asset, bool indexed enabled);\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; ++i) {\n            setTokenConfig(tokenConfigs_[i]);\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     * @custom:event Emits OracleEnabled event with asset address, role of the oracle and enabled flag\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 capped main oracle snapshot.\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        _updateAssetPrice(asset);\n    }\n\n    /**\n     * @notice Updates the capped main oracle snapshot.\n     * @dev This function should always be called before calling getPrice\n     * @param asset asset address\n     */\n    function updateAssetPrice(address asset) external {\n        _updateAssetPrice(asset);\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     * @custom:event Emits CachedEnabled event when the asset cachingEnabled flag is set successfully\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        emit CachedEnabled(tokenConfig.asset, tokenConfig.cachingEnabled);\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    /**\n     * @notice Updates the capped oracle snapshot.\n     * @dev Cache the asset price and return if already cached\n     * @param asset asset address\n     */\n    function _updateAssetPrice(address asset) internal {\n        if (Transient.readCachedPrice(CACHE_SLOT, asset) != 0) {\n            return;\n        }\n\n        (address mainOracle, bool mainOracleEnabled) = getOracle(asset, OracleRole.MAIN);\n        if (mainOracle != address(0) && mainOracleEnabled) {\n            // if main oracle is not CorrelatedTokenOracle it will revert so we need to catch the revert\n            try ICappedOracle(mainOracle).updateSnapshot() {} catch {}\n        }\n\n        if (_isCacheEnabled(asset)) {\n            uint256 price = _getPrice(asset);\n            Transient.cachePrice(CACHE_SLOT, asset, price);\n        }\n    }\n\n    /**\n     * @notice Gets price for the provided asset\n     * @param asset asset address\n     * @return price USD price in scaled decimal places.\n     * @custom:error Invalid resilient oracle price error is thrown if fetched prices from oracle is invalid\n     */\n    function _getPrice(address asset) internal view returns (uint256) {\n        uint256 pivotPrice = INVALID_PRICE;\n        uint256 price;\n\n        price = Transient.readCachedPrice(CACHE_SLOT, asset);\n        if (price != 0) {\n            return price;\n        }\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 successfully\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    /**\n     * @dev This function checks if the asset price should be cached\n     * @param asset asset address\n     * @return bool true if caching is enabled, false otherwise\n     */\n    function _isCacheEnabled(address asset) private view returns (bool) {\n        return tokenConfigs[asset].cachingEnabled;\n    }\n}\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/MockAsBNB.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 { IAsBNB } from \"../interfaces/IAsBNB.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract MockAsBNB is ERC20, Ownable, IAsBNB {\n    uint8 private immutable _decimals;\n    address public minter;\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        uint8 decimals_,\n        address minter_\n    ) ERC20(name_, symbol_) Ownable() {\n        _decimals = decimals_;\n        minter = minter_;\n    }\n\n    function faucet(uint256 amount) external {\n        _mint(msg.sender, amount);\n    }\n\n    function setMinter(address minter_) external onlyOwner {\n        minter = minter_;\n    }\n\n    function decimals() public view virtual override(ERC20, IAsBNB) returns (uint8) {\n        return _decimals;\n    }\n}\n"
    },
    "contracts/test/MockAsBNBMinter.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 { IAsBNBMinter } from \"../interfaces/IAsBNBMinter.sol\";\n\ncontract MockAsBNBMinter is IAsBNBMinter {\n    function convertToTokens(uint256 _amount) external pure override returns (uint256) {\n        return _amount;\n    }\n}\n"
    },
    "contracts/test/MockCallPrice.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 { OracleInterface, ResilientOracleInterface } from \"../interfaces/OracleInterface.sol\";\n\ninterface CorrelatedTokenOracleInterface {\n    function updateSnapshot() external;\n    function getPrice(address asset) external view returns (uint256);\n}\n\ncontract MockCallPrice {\n    function getMultiPrice(CorrelatedTokenOracleInterface oracle, address asset) public returns (uint256, uint256) {\n        oracle.updateSnapshot();\n        return (oracle.getPrice(asset), oracle.getPrice(asset));\n    }\n\n    function getUnderlyingPriceResilientOracle(\n        ResilientOracleInterface oracle,\n        address vToken\n    ) public returns (uint256, uint256) {\n        oracle.updatePrice(vToken);\n        oracle.updatePrice(vToken);\n        return (oracle.getUnderlyingPrice(vToken), oracle.getUnderlyingPrice(vToken));\n    }\n\n    function getAssetPriceResilientOracle(\n        ResilientOracleInterface oracle,\n        address asset\n    ) public returns (uint256, uint256) {\n        oracle.updateAssetPrice(asset);\n        oracle.updateAssetPrice(asset);\n        return (oracle.getPrice(asset), oracle.getPrice(asset));\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/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/oracles/MockCorrelatedTokenOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { CorrelatedTokenOracle } from \"../../oracles/common/CorrelatedTokenOracle.sol\";\n\ncontract MockCorrelatedTokenOracle is CorrelatedTokenOracle {\n    uint256 public mockUnderlyingAmount;\n\n    constructor(\n        address correlatedToken,\n        address underlyingToken,\n        address resilientOracle,\n        uint256 annualGrowthRate,\n        uint256 snapshotInterval,\n        uint256 initialSnapshotMaxExchangeRate,\n        uint256 initialSnapshotTimestamp,\n        address accessControlManager,\n        uint256 snapshotGap\n    )\n        CorrelatedTokenOracle(\n            correlatedToken,\n            underlyingToken,\n            resilientOracle,\n            annualGrowthRate,\n            snapshotInterval,\n            initialSnapshotMaxExchangeRate,\n            initialSnapshotTimestamp,\n            accessControlManager,\n            snapshotGap\n        )\n    {}\n\n    function setMockUnderlyingAmount(uint256 amount) external {\n        mockUnderlyingAmount = amount;\n    }\n\n    function getUnderlyingAmount() public view override returns (uint256) {\n        return mockUnderlyingAmount;\n    }\n}\n"
    },
    "contracts/test/oracles/MockERC20.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract MockERC20 is ERC20 {\n    constructor(string memory name, string memory symbol, uint8 decimals) ERC20(name, symbol) {\n        _mint(msg.sender, 100000 * 10 ** uint256(decimals));\n    }\n}\n"
    },
    "contracts/test/oracles/MockResilientOracle.sol": {
      "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"../../interfaces/OracleInterface.sol\";\n\ncontract MockOracle is OracleInterface {\n    mapping(address => uint256) public prices;\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"
    },
    "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,
      "runs": 200,
      "details": {
        "yul": true
      }
    },
    "evmVersion": "cancun",
    "outputSelection": {
      "*": {
        "*": [
          "storageLayout",
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "evm.methodIdentifiers",
          "metadata",
          "devdoc",
          "userdoc",
          "evm.gasEstimates"
        ],
        "": ["ast"]
      }
    },
    "metadata": {
      "useLiteralContent": true
    }
  }
}
