creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/protocol/InterestRate.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\nimport {IInterestRate} from \"../interfaces/IInterestRate.sol\";\nimport {ILendPoolAddressesProvider} from \"../interfaces/ILendPoolAddressesProvider.sol\";\nimport {WadRayMath} from \"../libraries/math/WadRayMath.sol\";\nimport {PercentageMath} from \"../libraries/math/PercentageMath.sol\";\n\nimport {IERC20Upgradeable} from \"@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol\";\n\n/**\n * @title InterestRate contract\n * @notice Implements the calculation of the interest rates depending on the reserve state\n * @dev The model of interest rate is based on 2 slopes, one before the `OPTIMAL_UTILIZATION_RATE`\n * point of utilization and another from that one to 100%\n * @author Bend\n **/\ncontract InterestRate is IInterestRate {\n  using WadRayMath for uint256;\n  using PercentageMath for uint256;\n\n  ILendPoolAddressesProvider public immutable addressesProvider;\n\n  /**\n   * @dev this constant represents the utilization rate at which the pool aims to obtain most competitive borrow rates.\n   * Expressed in ray\n   **/\n  uint256 public immutable OPTIMAL_UTILIZATION_RATE;\n\n  /**\n   * @dev This constant represents the excess utilization rate above the optimal. It's always equal to\n   * 1-optimal utilization rate. Added as a constant here for gas optimizations.\n   * Expressed in ray\n   **/\n\n  uint256 public immutable EXCESS_UTILIZATION_RATE;\n\n  // Base variable borrow rate when Utilization rate = 0. Expressed in ray\n  uint256 internal immutable _baseVariableBorrowRate;\n\n  // Slope of the variable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray\n  uint256 internal immutable _variableRateSlope1;\n\n  // Slope of the variable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray\n  uint256 internal immutable _variableRateSlope2;\n\n  constructor(\n    ILendPoolAddressesProvider provider,\n    uint256 optimalUtilizationRate_,\n    uint256 baseVariableBorrowRate_,\n    uint256 variableRateSlope1_,\n    uint256 variableRateSlope2_\n  ) {\n    addressesProvider = provider;\n    OPTIMAL_UTILIZATION_RATE = optimalUtilizationRate_;\n    EXCESS_UTILIZATION_RATE = WadRayMath.ray() - (optimalUtilizationRate_);\n    _baseVariableBorrowRate = baseVariableBorrowRate_;\n    _variableRateSlope1 = variableRateSlope1_;\n    _variableRateSlope2 = variableRateSlope2_;\n  }\n\n  function variableRateSlope1() external view returns (uint256) {\n    return _variableRateSlope1;\n  }\n\n  function variableRateSlope2() external view returns (uint256) {\n    return _variableRateSlope2;\n  }\n\n  function baseVariableBorrowRate() external view override returns (uint256) {\n    return _baseVariableBorrowRate;\n  }\n\n  function getMaxVariableBorrowRate() external view override returns (uint256) {\n    return _baseVariableBorrowRate + (_variableRateSlope1) + (_variableRateSlope2);\n  }\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations\n   * @param reserve The address of the reserve\n   * @param liquidityAdded The liquidity added during the operation\n   * @param liquidityTaken The liquidity taken during the operation\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param reserveFactor The reserve portion of the interest that goes to the treasury of the market\n   * @return The liquidity rate, the stable borrow rate and the variable borrow rate\n   **/\n  function calculateInterestRates(\n    address reserve,\n    address bToken,\n    uint256 liquidityAdded,\n    uint256 liquidityTaken,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) external view override returns (uint256, uint256) {\n    uint256 availableLiquidity = IERC20Upgradeable(reserve).balanceOf(bToken);\n    //avoid stack too deep\n    availableLiquidity = availableLiquidity + (liquidityAdded) - (liquidityTaken);\n\n    return calculateInterestRates(reserve, availableLiquidity, totalVariableDebt, reserveFactor);\n  }\n\n  struct CalcInterestRatesLocalVars {\n    uint256 totalDebt;\n    uint256 currentVariableBorrowRate;\n    uint256 currentLiquidityRate;\n    uint256 utilizationRate;\n  }\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations.\n   * NOTE This function is kept for compatibility with the previous DefaultInterestRateStrategy interface.\n   * New protocol implementation uses the new calculateInterestRates() interface\n   * @param reserve The address of the reserve\n   * @param availableLiquidity The liquidity available in the corresponding bToken\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param reserveFactor The reserve portion of the interest that goes to the treasury of the market\n   * @return The liquidity rate and the variable borrow rate\n   **/\n  function calculateInterestRates(\n    address reserve,\n    uint256 availableLiquidity,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) public view override returns (uint256, uint256) {\n    reserve;\n\n    CalcInterestRatesLocalVars memory vars;\n\n    vars.totalDebt = totalVariableDebt;\n    vars.currentVariableBorrowRate = 0;\n    vars.currentLiquidityRate = 0;\n\n    vars.utilizationRate = vars.totalDebt == 0 ? 0 : vars.totalDebt.rayDiv(availableLiquidity + (vars.totalDebt));\n\n    if (vars.utilizationRate > OPTIMAL_UTILIZATION_RATE) {\n      uint256 excessUtilizationRateRatio = (vars.utilizationRate - (OPTIMAL_UTILIZATION_RATE)).rayDiv(\n        EXCESS_UTILIZATION_RATE\n      );\n\n      vars.currentVariableBorrowRate =\n        _baseVariableBorrowRate +\n        (_variableRateSlope1) +\n        (_variableRateSlope2.rayMul(excessUtilizationRateRatio));\n    } else {\n      vars.currentVariableBorrowRate =\n        _baseVariableBorrowRate +\n        (vars.utilizationRate.rayMul(_variableRateSlope1).rayDiv(OPTIMAL_UTILIZATION_RATE));\n    }\n\n    vars.currentLiquidityRate = _getOverallBorrowRate(totalVariableDebt, vars.currentVariableBorrowRate)\n      .rayMul(vars.utilizationRate)\n      .percentMul(PercentageMath.PERCENTAGE_FACTOR - (reserveFactor));\n\n    return (vars.currentLiquidityRate, vars.currentVariableBorrowRate);\n  }\n\n  /**\n   * @dev Calculates the overall borrow rate as the weighted average between the total variable debt and total stable debt\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param currentVariableBorrowRate The current variable borrow rate of the reserve\n   * @return The weighted averaged borrow rate\n   **/\n  function _getOverallBorrowRate(uint256 totalVariableDebt, uint256 currentVariableBorrowRate)\n    internal\n    pure\n    returns (uint256)\n  {\n    uint256 totalDebt = totalVariableDebt;\n\n    if (totalDebt == 0) return 0;\n\n    uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);\n\n    uint256 overallBorrowRate = weightedVariableRate.rayDiv(totalDebt.wadToRay());\n\n    return overallBorrowRate;\n  }\n}\n"
      },
      "contracts/interfaces/IInterestRate.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\n/**\n * @title IInterestRate interface\n * @dev Interface for the calculation of the interest rates\n * @author Bend\n */\ninterface IInterestRate {\n  function baseVariableBorrowRate() external view returns (uint256);\n\n  function getMaxVariableBorrowRate() external view returns (uint256);\n\n  function calculateInterestRates(\n    address reserve,\n    uint256 availableLiquidity,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) external view returns (uint256, uint256);\n\n  function calculateInterestRates(\n    address reserve,\n    address bToken,\n    uint256 liquidityAdded,\n    uint256 liquidityTaken,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) external view returns (uint256 liquidityRate, uint256 variableBorrowRate);\n}\n"
      },
      "contracts/interfaces/ILendPoolAddressesProvider.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\n/**\n * @title LendPoolAddressesProvider contract\n * @dev Main registry of addresses part of or connected to the protocol, including permissioned roles\n * - Acting also as factory of proxies and admin of those, so with right to change its implementations\n * - Owned by the Bend Governance\n * @author Bend\n **/\ninterface ILendPoolAddressesProvider {\n  event MarketIdSet(string newMarketId);\n  event LendPoolUpdated(address indexed newAddress, bytes encodedCallData);\n  event ConfigurationAdminUpdated(address indexed newAddress);\n  event EmergencyAdminUpdated(address indexed newAddress);\n  event LendPoolConfiguratorUpdated(address indexed newAddress, bytes encodedCallData);\n  event ReserveOracleUpdated(address indexed newAddress);\n  event NftOracleUpdated(address indexed newAddress);\n  event LendPoolLoanUpdated(address indexed newAddress, bytes encodedCallData);\n  event ProxyCreated(bytes32 id, address indexed newAddress);\n  event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy, bytes encodedCallData);\n  event BNFTRegistryUpdated(address indexed newAddress);\n  event IncentivesControllerUpdated(address indexed newAddress);\n  event UIDataProviderUpdated(address indexed newAddress);\n  event BendDataProviderUpdated(address indexed newAddress);\n  event WalletBalanceProviderUpdated(address indexed newAddress);\n\n  function getMarketId() external view returns (string memory);\n\n  function setMarketId(string calldata marketId) external;\n\n  function setAddress(bytes32 id, address newAddress) external;\n\n  function setAddressAsProxy(\n    bytes32 id,\n    address impl,\n    bytes memory encodedCallData\n  ) external;\n\n  function getAddress(bytes32 id) external view returns (address);\n\n  function getLendPool() external view returns (address);\n\n  function setLendPoolImpl(address pool, bytes memory encodedCallData) external;\n\n  function getLendPoolConfigurator() external view returns (address);\n\n  function setLendPoolConfiguratorImpl(address configurator, bytes memory encodedCallData) external;\n\n  function getPoolAdmin() external view returns (address);\n\n  function setPoolAdmin(address admin) external;\n\n  function getEmergencyAdmin() external view returns (address);\n\n  function setEmergencyAdmin(address admin) external;\n\n  function getReserveOracle() external view returns (address);\n\n  function setReserveOracle(address reserveOracle) external;\n\n  function getNFTOracle() external view returns (address);\n\n  function setNFTOracle(address nftOracle) external;\n\n  function getLendPoolLoan() external view returns (address);\n\n  function setLendPoolLoanImpl(address loan, bytes memory encodedCallData) external;\n\n  function getBNFTRegistry() external view returns (address);\n\n  function setBNFTRegistry(address factory) external;\n\n  function getIncentivesController() external view returns (address);\n\n  function setIncentivesController(address controller) external;\n\n  function getUIDataProvider() external view returns (address);\n\n  function setUIDataProvider(address provider) external;\n\n  function getBendDataProvider() external view returns (address);\n\n  function setBendDataProvider(address provider) external;\n\n  function getWalletBalanceProvider() external view returns (address);\n\n  function setWalletBalanceProvider(address provider) external;\n}\n"
      },
      "contracts/libraries/math/WadRayMath.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\nimport {Errors} from \"../helpers/Errors.sol\";\n\n/**\n * @title WadRayMath library\n * @author Bend\n * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)\n **/\n\nlibrary WadRayMath {\n  uint256 internal constant WAD = 1e18;\n  uint256 internal constant HALF_WAD = WAD / 2;\n\n  uint256 internal constant RAY = 1e27;\n  uint256 internal constant HALF_RAY = RAY / 2;\n\n  uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n  /**\n   * @return One ray, 1e27\n   **/\n  function ray() internal pure returns (uint256) {\n    return RAY;\n  }\n\n  /**\n   * @return One wad, 1e18\n   **/\n\n  function wad() internal pure returns (uint256) {\n    return WAD;\n  }\n\n  /**\n   * @return Half ray, 1e27/2\n   **/\n  function halfRay() internal pure returns (uint256) {\n    return HALF_RAY;\n  }\n\n  /**\n   * @return Half ray, 1e18/2\n   **/\n  function halfWad() internal pure returns (uint256) {\n    return HALF_WAD;\n  }\n\n  /**\n   * @dev Multiplies two wad, rounding half up to the nearest wad\n   * @param a Wad\n   * @param b Wad\n   * @return The result of a*b, in wad\n   **/\n  function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n\n    require(a <= (type(uint256).max - HALF_WAD) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * b + HALF_WAD) / WAD;\n  }\n\n  /**\n   * @dev Divides two wad, rounding half up to the nearest wad\n   * @param a Wad\n   * @param b Wad\n   * @return The result of a/b, in wad\n   **/\n  function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b != 0, Errors.MATH_DIVISION_BY_ZERO);\n    uint256 halfB = b / 2;\n\n    require(a <= (type(uint256).max - halfB) / WAD, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * WAD + halfB) / b;\n  }\n\n  /**\n   * @dev Multiplies two ray, rounding half up to the nearest ray\n   * @param a Ray\n   * @param b Ray\n   * @return The result of a*b, in ray\n   **/\n  function rayMul(uint256 a, uint256 b) internal pure returns (uint256) {\n    if (a == 0 || b == 0) {\n      return 0;\n    }\n\n    require(a <= (type(uint256).max - HALF_RAY) / b, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * b + HALF_RAY) / RAY;\n  }\n\n  /**\n   * @dev Divides two ray, rounding half up to the nearest ray\n   * @param a Ray\n   * @param b Ray\n   * @return The result of a/b, in ray\n   **/\n  function rayDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n    require(b != 0, Errors.MATH_DIVISION_BY_ZERO);\n    uint256 halfB = b / 2;\n\n    require(a <= (type(uint256).max - halfB) / RAY, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (a * RAY + halfB) / b;\n  }\n\n  /**\n   * @dev Casts ray down to wad\n   * @param a Ray\n   * @return a casted to wad, rounded half up to the nearest wad\n   **/\n  function rayToWad(uint256 a) internal pure returns (uint256) {\n    uint256 halfRatio = WAD_RAY_RATIO / 2;\n    uint256 result = halfRatio + a;\n    require(result >= halfRatio, Errors.MATH_ADDITION_OVERFLOW);\n\n    return result / WAD_RAY_RATIO;\n  }\n\n  /**\n   * @dev Converts wad up to ray\n   * @param a Wad\n   * @return a converted in ray\n   **/\n  function wadToRay(uint256 a) internal pure returns (uint256) {\n    uint256 result = a * WAD_RAY_RATIO;\n    require(result / WAD_RAY_RATIO == a, Errors.MATH_MULTIPLICATION_OVERFLOW);\n    return result;\n  }\n}\n"
      },
      "contracts/libraries/math/PercentageMath.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\nimport {Errors} from \"../helpers/Errors.sol\";\n\n/**\n * @title PercentageMath library\n * @author Bend\n * @notice Provides functions to perform percentage calculations\n * @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR\n * @dev Operations are rounded half up\n **/\n\nlibrary PercentageMath {\n  uint256 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals\n  uint256 constant HALF_PERCENT = PERCENTAGE_FACTOR / 2;\n  uint256 constant ONE_PERCENT = 1e2; //100, 1%\n  uint256 constant TEN_PERCENT = 1e3; //1000, 10%\n  uint256 constant ONE_THOUSANDTH_PERCENT = 1e1; //10, 0.1%\n  uint256 constant ONE_TEN_THOUSANDTH_PERCENT = 1; //1, 0.01%\n\n  /**\n   * @dev Executes a percentage multiplication\n   * @param value The value of which the percentage needs to be calculated\n   * @param percentage The percentage of the value to be calculated\n   * @return The percentage of value\n   **/\n  function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256) {\n    if (value == 0 || percentage == 0) {\n      return 0;\n    }\n\n    require(value <= (type(uint256).max - HALF_PERCENT) / percentage, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (value * percentage + HALF_PERCENT) / PERCENTAGE_FACTOR;\n  }\n\n  /**\n   * @dev Executes a percentage division\n   * @param value The value of which the percentage needs to be calculated\n   * @param percentage The percentage of the value to be calculated\n   * @return The value divided the percentage\n   **/\n  function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256) {\n    require(percentage != 0, Errors.MATH_DIVISION_BY_ZERO);\n    uint256 halfPercentage = percentage / 2;\n\n    require(value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR, Errors.MATH_MULTIPLICATION_OVERFLOW);\n\n    return (value * PERCENTAGE_FACTOR + halfPercentage) / percentage;\n  }\n}\n"
      },
      "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (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 IERC20Upgradeable {\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 `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, 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 `sender` to `recipient` 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(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\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"
      },
      "contracts/libraries/helpers/Errors.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.4;\n\n/**\n * @title Errors library\n * @author Bend\n * @notice Defines the error messages emitted by the different contracts of the Bend protocol\n */\nlibrary Errors {\n  enum ReturnCode {\n    SUCCESS,\n    FAILED\n  }\n\n  string public constant SUCCESS = \"0\";\n\n  //common errors\n  string public constant CALLER_NOT_POOL_ADMIN = \"100\"; // 'The caller must be the pool admin'\n  string public constant CALLER_NOT_ADDRESS_PROVIDER = \"101\";\n  string public constant INVALID_FROM_BALANCE_AFTER_TRANSFER = \"102\";\n  string public constant INVALID_TO_BALANCE_AFTER_TRANSFER = \"103\";\n  string public constant CALLER_NOT_ONBEHALFOF_OR_IN_WHITELIST = \"104\";\n\n  //math library erros\n  string public constant MATH_MULTIPLICATION_OVERFLOW = \"200\";\n  string public constant MATH_ADDITION_OVERFLOW = \"201\";\n  string public constant MATH_DIVISION_BY_ZERO = \"202\";\n  string public constant MATH_NUMBER_OVERFLOW = \"203\";\n\n  //validation & check errors\n  string public constant VL_INVALID_AMOUNT = \"301\"; // 'Amount must be greater than 0'\n  string public constant VL_NO_ACTIVE_RESERVE = \"302\"; // 'Action requires an active reserve'\n  string public constant VL_RESERVE_FROZEN = \"303\"; // 'Action cannot be performed because the reserve is frozen'\n  string public constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = \"304\"; // 'User cannot withdraw more than the available balance'\n  string public constant VL_BORROWING_NOT_ENABLED = \"305\"; // 'Borrowing is not enabled'\n  string public constant VL_COLLATERAL_BALANCE_IS_0 = \"306\"; // 'The collateral balance is 0'\n  string public constant VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD = \"307\"; // 'Health factor is lesser than the liquidation threshold'\n  string public constant VL_COLLATERAL_CANNOT_COVER_NEW_BORROW = \"308\"; // 'There is not enough collateral to cover a new borrow'\n  string public constant VL_NO_DEBT_OF_SELECTED_TYPE = \"309\"; // 'There's no debt need to repay'\n  string public constant VL_NO_ACTIVE_NFT = \"310\";\n  string public constant VL_NFT_FROZEN = \"311\";\n  string public constant VL_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER = \"312\"; // 'User did not borrow the specified currency'\n  string public constant VL_INVALID_HEALTH_FACTOR = \"313\";\n  string public constant VL_INVALID_ONBEHALFOF_ADDRESS = \"314\";\n  string public constant VL_INVALID_TARGET_ADDRESS = \"315\";\n  string public constant VL_INVALID_RESERVE_ADDRESS = \"316\";\n  string public constant VL_SPECIFIED_LOAN_NOT_BORROWED_BY_USER = \"317\";\n  string public constant VL_SPECIFIED_RESERVE_NOT_BORROWED_BY_USER = \"318\";\n  string public constant VL_HEALTH_FACTOR_HIGHER_THAN_LIQUIDATION_THRESHOLD = \"319\";\n\n  //lend pool errors\n  string public constant LP_CALLER_NOT_LEND_POOL_CONFIGURATOR = \"400\"; // 'The caller of the function is not the lending pool configurator'\n  string public constant LP_IS_PAUSED = \"401\"; // 'Pool is paused'\n  string public constant LP_NO_MORE_RESERVES_ALLOWED = \"402\";\n  string public constant LP_NOT_CONTRACT = \"403\";\n  string public constant LP_BORROW_NOT_EXCEED_LIQUIDATION_THRESHOLD = \"404\";\n  string public constant LP_BORROW_IS_EXCEED_LIQUIDATION_PRICE = \"405\";\n  string public constant LP_NO_MORE_NFTS_ALLOWED = \"406\";\n  string public constant LP_INVALIED_USER_NFT_AMOUNT = \"407\";\n  string public constant LP_INCONSISTENT_PARAMS = \"408\";\n  string public constant LP_NFT_IS_NOT_USED_AS_COLLATERAL = \"409\";\n  string public constant LP_CALLER_MUST_BE_AN_BTOKEN = \"410\";\n  string public constant LP_INVALIED_NFT_AMOUNT = \"411\";\n  string public constant LP_NFT_HAS_USED_AS_COLLATERAL = \"412\";\n  string public constant LP_DELEGATE_CALL_FAILED = \"413\";\n  string public constant LP_AMOUNT_LESS_THAN_EXTRA_DEBT = \"414\";\n  string public constant LP_AMOUNT_LESS_THAN_REDEEM_THRESHOLD = \"415\";\n  string public constant LP_AMOUNT_GREATER_THAN_MAX_REPAY = \"416\";\n  string public constant LP_NFT_TOKEN_ID_EXCEED_MAX_LIMIT = \"417\";\n  string public constant LP_NFT_SUPPLY_NUM_EXCEED_MAX_LIMIT = \"418\";\n  string public constant LP_CALLER_NOT_VALID_INTERCEPTOR = \"419\";\n  string public constant LP_CALLER_NOT_VALID_LOCKER = \"420\";\n\n  //lend pool loan errors\n  string public constant LPL_INVALID_LOAN_STATE = \"480\";\n  string public constant LPL_INVALID_LOAN_AMOUNT = \"481\";\n  string public constant LPL_INVALID_TAKEN_AMOUNT = \"482\";\n  string public constant LPL_AMOUNT_OVERFLOW = \"483\";\n  string public constant LPL_BID_PRICE_LESS_THAN_LIQUIDATION_PRICE = \"484\";\n  string public constant LPL_BID_PRICE_LESS_THAN_HIGHEST_PRICE = \"485\";\n  string public constant LPL_BID_REDEEM_DURATION_HAS_END = \"486\";\n  string public constant LPL_BID_USER_NOT_SAME = \"487\";\n  string public constant LPL_BID_REPAY_AMOUNT_NOT_ENOUGH = \"488\";\n  string public constant LPL_BID_AUCTION_DURATION_HAS_END = \"489\";\n  string public constant LPL_BID_AUCTION_DURATION_NOT_END = \"490\";\n  string public constant LPL_BID_PRICE_LESS_THAN_BORROW = \"491\";\n  string public constant LPL_INVALID_BIDDER_ADDRESS = \"492\";\n  string public constant LPL_AMOUNT_LESS_THAN_BID_FINE = \"493\";\n  string public constant LPL_INVALID_BID_FINE = \"494\";\n\n  //common token errors\n  string public constant CT_CALLER_MUST_BE_LEND_POOL = \"500\"; // 'The caller of this function must be a lending pool'\n  string public constant CT_INVALID_MINT_AMOUNT = \"501\"; //invalid amount to mint\n  string public constant CT_INVALID_BURN_AMOUNT = \"502\"; //invalid amount to burn\n  string public constant CT_BORROW_ALLOWANCE_NOT_ENOUGH = \"503\";\n\n  //reserve logic errors\n  string public constant RL_RESERVE_ALREADY_INITIALIZED = \"601\"; // 'Reserve has already been initialized'\n  string public constant RL_LIQUIDITY_INDEX_OVERFLOW = \"602\"; //  Liquidity index overflows uint128\n  string public constant RL_VARIABLE_BORROW_INDEX_OVERFLOW = \"603\"; //  Variable borrow index overflows uint128\n  string public constant RL_LIQUIDITY_RATE_OVERFLOW = \"604\"; //  Liquidity rate overflows uint128\n  string public constant RL_VARIABLE_BORROW_RATE_OVERFLOW = \"605\"; //  Variable borrow rate overflows uint128\n\n  //configure errors\n  string public constant LPC_RESERVE_LIQUIDITY_NOT_0 = \"700\"; // 'The liquidity of the reserve needs to be 0'\n  string public constant LPC_INVALID_CONFIGURATION = \"701\"; // 'Invalid risk parameters for the reserve'\n  string public constant LPC_CALLER_NOT_EMERGENCY_ADMIN = \"702\"; // 'The caller must be the emergency admin'\n  string public constant LPC_INVALIED_BNFT_ADDRESS = \"703\";\n  string public constant LPC_INVALIED_LOAN_ADDRESS = \"704\";\n  string public constant LPC_NFT_LIQUIDITY_NOT_0 = \"705\";\n\n  //reserve config errors\n  string public constant RC_INVALID_LTV = \"730\";\n  string public constant RC_INVALID_LIQ_THRESHOLD = \"731\";\n  string public constant RC_INVALID_LIQ_BONUS = \"732\";\n  string public constant RC_INVALID_DECIMALS = \"733\";\n  string public constant RC_INVALID_RESERVE_FACTOR = \"734\";\n  string public constant RC_INVALID_REDEEM_DURATION = \"735\";\n  string public constant RC_INVALID_AUCTION_DURATION = \"736\";\n  string public constant RC_INVALID_REDEEM_FINE = \"737\";\n  string public constant RC_INVALID_REDEEM_THRESHOLD = \"738\";\n  string public constant RC_INVALID_MIN_BID_FINE = \"739\";\n  string public constant RC_INVALID_MAX_BID_FINE = \"740\";\n\n  //address provider erros\n  string public constant LPAPR_PROVIDER_NOT_REGISTERED = \"760\"; // 'Provider is not registered'\n  string public constant LPAPR_INVALID_ADDRESSES_PROVIDER_ID = \"761\";\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "evmVersion": "istanbul",
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}