diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index b5753258..82bc7389 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -366,9 +366,9 @@ interface ILendingPool { /** * @dev Returns the user account data across all the reserves * @param user The address of the user - * @return totalCollateralETH the total collateral in ETH of the user - * @return totalDebtETH the total debt in ETH of the user - * @return availableBorrowsETH the borrowing power left of the user + * @return totalCollateralBase the total collateral of the user in the base currency used by the price feed + * @return totalDebtBase the total debt of the user in the base currency used by the price feed + * @return availableBorrowsBase the borrowing power left of the user in the base currency used by the price feed * @return currentLiquidationThreshold the liquidation threshold of the user * @return ltv the loan to value of the user * @return healthFactor the current health factor of the user @@ -377,9 +377,9 @@ interface ILendingPool { external view returns ( - uint256 totalCollateralETH, - uint256 totalDebtETH, - uint256 availableBorrowsETH, + uint256 totalCollateralBase, + uint256 totalDebtBase, + uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 4bfe23f9..a36dd278 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -474,17 +474,17 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage view override returns ( - uint256 totalCollateralETH, - uint256 totalDebtETH, - uint256 availableBorrowsETH, + uint256 totalCollateralBase, + uint256 totalDebtBase, + uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ) { ( - totalCollateralETH, - totalDebtETH, + totalCollateralBase, + totalDebtBase, ltv, currentLiquidationThreshold, healthFactor, @@ -498,9 +498,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _addressesProvider.getPriceOracle() ); - availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH( - totalCollateralETH, - totalDebtETH, + availableBorrowsBase = GenericLogic.calculateAvailableBorrows( + totalCollateralBase, + totalDebtBase, ltv ); } diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol index 66053b6e..1309731a 100644 --- a/contracts/protocol/libraries/logic/GenericLogic.sol +++ b/contracts/protocol/libraries/logic/GenericLogic.sol @@ -32,17 +32,17 @@ library GenericLogic { uint256 assetPrice; uint256 assetUnit; uint256 userBalance; - uint256 userBalanceETH; + uint256 userBalanceInBaseCurrency; uint256 userDebt; uint256 userStableDebt; - uint256 userDebtETH; + uint256 userDebtInBaseCurrency; uint256 decimals; uint256 ltv; uint256 liquidationThreshold; uint256 i; uint256 healthFactor; - uint256 totalCollateralInETH; - uint256 totalDebtInETH; + uint256 totalCollateralInBaseCurrency; + uint256 totalDebtInBaseCurrency; uint256 avgLtv; uint256 avgUncappedLtv; uint256 avgLiquidationThreshold; @@ -60,14 +60,15 @@ library GenericLogic { /** * @dev Calculates the user data across the reserves. - * this includes the total liquidity/collateral/borrow balances in ETH, + * this includes the total liquidity/collateral/borrow balances in the base currency used by the price feed, * the average Loan To Value, the average Liquidation Ratio, and the Health factor. * @param user The address of the user * @param reservesData Data of all the reserves * @param userConfig The configuration of the user * @param reserves The list of the available reserves * @param oracle The price oracle address - * @return The total collateral and total debt of the user in ETH, the avg ltv, liquidation threshold, the HF and the uncapped avg ltv (without exposure ceiling) + * @return The total collateral and total debt of the user in the base currency used by the price feed, + * the avg ltv, liquidation threshold, the HF and the uncapped avg ltv (without exposure ceiling) **/ function calculateUserAccountData( address user, @@ -129,18 +130,20 @@ library GenericLogic { vars.aTokenSupply = 0; } - vars.userBalanceETH = vars.assetPrice.mul(vars.userBalance).div(vars.assetUnit); - vars.totalCollateralInETH = vars.totalCollateralInETH.add(vars.userBalanceETH); + vars.userBalanceInBaseCurrency = vars.assetPrice.mul(vars.userBalance).div(vars.assetUnit); + vars.totalCollateralInBaseCurrency = vars.totalCollateralInBaseCurrency.add( + vars.userBalanceInBaseCurrency + ); vars.exposureCapCrossed = vars.exposureCap != 0 && vars.aTokenSupply.div(10**vars.decimals) > vars.exposureCap; vars.avgLtv = vars.avgLtv.add( - vars.exposureCapCrossed ? 0 : vars.userBalanceETH.mul(vars.ltv) + vars.exposureCapCrossed ? 0 : vars.userBalanceInBaseCurrency.mul(vars.ltv) ); - vars.avgUncappedLtv = vars.avgUncappedLtv.add(vars.userBalanceETH.mul(vars.ltv)); + vars.avgUncappedLtv = vars.avgUncappedLtv.add(vars.userBalanceInBaseCurrency.mul(vars.ltv)); vars.avgLiquidationThreshold = vars.avgLiquidationThreshold.add( - vars.userBalanceETH.mul(vars.liquidationThreshold) + vars.userBalanceInBaseCurrency.mul(vars.liquidationThreshold) ); } @@ -154,27 +157,29 @@ library GenericLogic { vars.userDebt = vars.userDebt.rayMul(vars.normalizedDebt); } vars.userDebt = vars.userDebt.add(vars.userStableDebt); - vars.userDebtETH = vars.assetPrice.mul(vars.userDebt).div(vars.assetUnit); - vars.totalDebtInETH = vars.totalDebtInETH.add(vars.userDebtETH); + vars.userDebtInBaseCurrency = vars.assetPrice.mul(vars.userDebt).div(vars.assetUnit); + vars.totalDebtInBaseCurrency = vars.totalDebtInBaseCurrency.add(vars.userDebtInBaseCurrency); } } - vars.avgLtv = vars.totalCollateralInETH > 0 ? vars.avgLtv.div(vars.totalCollateralInETH) : 0; - vars.avgUncappedLtv = vars.totalCollateralInETH > 0 - ? vars.avgUncappedLtv.div(vars.totalCollateralInETH) + vars.avgLtv = vars.totalCollateralInBaseCurrency > 0 + ? vars.avgLtv.div(vars.totalCollateralInBaseCurrency) : 0; - vars.avgLiquidationThreshold = vars.totalCollateralInETH > 0 - ? vars.avgLiquidationThreshold.div(vars.totalCollateralInETH) + vars.avgUncappedLtv = vars.totalCollateralInBaseCurrency > 0 + ? vars.avgUncappedLtv.div(vars.totalCollateralInBaseCurrency) + : 0; + vars.avgLiquidationThreshold = vars.totalCollateralInBaseCurrency > 0 + ? vars.avgLiquidationThreshold.div(vars.totalCollateralInBaseCurrency) : 0; vars.healthFactor = calculateHealthFactorFromBalances( - vars.totalCollateralInETH, - vars.totalDebtInETH, + vars.totalCollateralInBaseCurrency, + vars.totalDebtInBaseCurrency, vars.avgLiquidationThreshold ); return ( - vars.totalCollateralInETH, - vars.totalDebtInETH, + vars.totalCollateralInBaseCurrency, + vars.totalDebtInBaseCurrency, vars.avgLtv, vars.avgLiquidationThreshold, vars.healthFactor, @@ -184,43 +189,46 @@ library GenericLogic { /** * @dev Calculates the health factor from the corresponding balances - * @param totalCollateralInETH The total collateral in ETH - * @param totalDebtInETH The total debt in ETH + * @param totalCollateralInBaseCurrency The total collateral in the base currency used by the price feed + * @param totalDebtInBaseCurrency The total debt in the base currency used by the price feed * @param liquidationThreshold The avg liquidation threshold * @return The health factor calculated from the balances provided **/ function calculateHealthFactorFromBalances( - uint256 totalCollateralInETH, - uint256 totalDebtInETH, + uint256 totalCollateralInBaseCurrency, + uint256 totalDebtInBaseCurrency, uint256 liquidationThreshold ) internal pure returns (uint256) { - if (totalDebtInETH == 0) return uint256(-1); + if (totalDebtInBaseCurrency == 0) return uint256(-1); - return (totalCollateralInETH.percentMul(liquidationThreshold)).wadDiv(totalDebtInETH); + return + (totalCollateralInBaseCurrency.percentMul(liquidationThreshold)).wadDiv( + totalDebtInBaseCurrency + ); } /** - * @dev Calculates the equivalent amount in ETH that an user can borrow, depending on the available collateral and the + * @dev Calculates the maximum amount that can be borrowed depending on the available collateral, the total debt and the * average Loan To Value - * @param totalCollateralInETH The total collateral in ETH - * @param totalDebtInETH The total borrow balance + * @param totalCollateralInBaseCurrency The total collateral in the base currency used by the price feed + * @param totalDebtInBaseCurrency The total borrow balance in the base currency used by the price feed * @param ltv The average loan to value - * @return the amount available to borrow in ETH for the user + * @return the amount available to borrow in the base currency of the used by the price feed **/ - function calculateAvailableBorrowsETH( - uint256 totalCollateralInETH, - uint256 totalDebtInETH, + function calculateAvailableBorrows( + uint256 totalCollateralInBaseCurrency, + uint256 totalDebtInBaseCurrency, uint256 ltv ) internal pure returns (uint256) { - uint256 availableBorrowsETH = totalCollateralInETH.percentMul(ltv); + uint256 availableBorrowsInBaseCurrency = totalCollateralInBaseCurrency.percentMul(ltv); - if (availableBorrowsETH < totalDebtInETH) { + if (availableBorrowsInBaseCurrency < totalDebtInBaseCurrency) { return 0; } - availableBorrowsETH = availableBorrowsETH.sub(totalDebtInETH); - return availableBorrowsETH; + availableBorrowsInBaseCurrency = availableBorrowsInBaseCurrency.sub(totalDebtInBaseCurrency); + return availableBorrowsInBaseCurrency; } /** diff --git a/contracts/protocol/libraries/logic/ValidationLogic.sol b/contracts/protocol/libraries/logic/ValidationLogic.sol index 10b7a4f5..89e92db7 100644 --- a/contracts/protocol/libraries/logic/ValidationLogic.sol +++ b/contracts/protocol/libraries/logic/ValidationLogic.sol @@ -92,16 +92,16 @@ library ValidationLogic { struct ValidateBorrowLocalVars { uint256 currentLtv; uint256 currentLiquidationThreshold; - uint256 amountOfCollateralNeededETH; - uint256 userCollateralBalanceETH; - uint256 userBorrowBalanceETH; + uint256 collateralNeededInBaseCurrency; + uint256 userCollateralInBaseCurrency; + uint256 userDebtInBaseCurrency; uint256 availableLiquidity; uint256 healthFactor; uint256 totalDebt; uint256 totalSupplyVariableDebt; uint256 reserveDecimals; uint256 borrowCap; - uint256 amountInETH; + uint256 amountInBaseCurrency; bool isActive; bool isFrozen; bool isPaused; @@ -181,8 +181,8 @@ library ValidationLogic { } ( - vars.userCollateralBalanceETH, - vars.userBorrowBalanceETH, + vars.userCollateralInBaseCurrency, + vars.userDebtInBaseCurrency, vars.currentLtv, vars.currentLiquidationThreshold, vars.healthFactor, @@ -196,23 +196,23 @@ library ValidationLogic { oracle ); - require(vars.userCollateralBalanceETH > 0, Errors.VL_COLLATERAL_BALANCE_IS_0); + require(vars.userCollateralInBaseCurrency > 0, Errors.VL_COLLATERAL_BALANCE_IS_0); require( vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD ); - vars.amountInETH = IPriceOracleGetter(oracle).getAssetPrice(asset); - vars.amountInETH = vars.amountInETH.mul(amount).div(10**vars.reserveDecimals); + vars.amountInBaseCurrency = IPriceOracleGetter(oracle).getAssetPrice(asset); + vars.amountInBaseCurrency = vars.amountInBaseCurrency.mul(amount).div(10**vars.reserveDecimals); //add the current already borrowed amount to the amount requested to calculate the total collateral needed. - vars.amountOfCollateralNeededETH = vars.userBorrowBalanceETH.add(vars.amountInETH).percentDiv( + vars.collateralNeededInBaseCurrency = vars.userDebtInBaseCurrency.add(vars.amountInBaseCurrency).percentDiv( vars.currentLtv ); //LTV is calculated in percentage require( - vars.amountOfCollateralNeededETH <= vars.userCollateralBalanceETH, + vars.collateralNeededInBaseCurrency <= vars.userCollateralInBaseCurrency, Errors.VL_COLLATERAL_CANNOT_COVER_NEW_BORROW ); diff --git a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol index e013885c..6ad68411 100644 --- a/specs/harness/LendingPoolHarnessForVariableDebtToken.sol +++ b/specs/harness/LendingPoolHarnessForVariableDebtToken.sol @@ -100,9 +100,9 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool { view override returns ( - uint256 totalCollateralETH, - uint256 totalDebtETH, - uint256 availableBorrowsETH, + uint256 totalCollateralBase, + uint256 totalDebtBase, + uint256 availableBorrowsBase, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor diff --git a/test-suites/test-aave/liquidation-atoken.spec.ts b/test-suites/test-aave/liquidation-atoken.spec.ts index 00ad07be..e5ca0e3b 100644 --- a/test-suites/test-aave/liquidation-atoken.spec.ts +++ b/test-suites/test-aave/liquidation-atoken.spec.ts @@ -55,7 +55,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.95) .toFixed(0) @@ -269,7 +269,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-aave/liquidation-underlying.spec.ts b/test-suites/test-aave/liquidation-underlying.spec.ts index b0951ce3..72143ba2 100644 --- a/test-suites/test-aave/liquidation-underlying.spec.ts +++ b/test-suites/test-aave/liquidation-underlying.spec.ts @@ -83,7 +83,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.95) .toFixed(0) @@ -267,7 +267,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-aave/pausable-functions.spec.ts b/test-suites/test-aave/pausable-functions.spec.ts index 54b318e7..ae555736 100644 --- a/test-suites/test-aave/pausable-functions.spec.ts +++ b/test-suites/test-aave/pausable-functions.spec.ts @@ -224,7 +224,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-aave/reserve-pause.spec.ts b/test-suites/test-aave/reserve-pause.spec.ts index 771fd0fd..f489a621 100644 --- a/test-suites/test-aave/reserve-pause.spec.ts +++ b/test-suites/test-aave/reserve-pause.spec.ts @@ -224,7 +224,7 @@ makeSuite('Pause One Reserve', (testEnv: TestEnv) => { const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts b/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts index cc161b4b..6437605e 100644 --- a/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts +++ b/test-suites/test-aave/uniswapAdapters.flashLiquidation.spec.ts @@ -61,7 +61,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalDataBefore.availableBorrowsETH.toString()) + new BigNumber(userGlobalDataBefore.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.95) .toFixed(0) @@ -128,7 +128,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalDataBefore.availableBorrowsETH.toString()) + new BigNumber(userGlobalDataBefore.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.8) .toFixed(0) @@ -141,7 +141,7 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => { const userGlobalDataBefore2 = await pool.getUserAccountData(borrower.address); - const amountWETHToBorrow = new BigNumber(userGlobalDataBefore2.availableBorrowsETH.toString()) + const amountWETHToBorrow = new BigNumber(userGlobalDataBefore2.availableBorrowsBase.toString()) .multipliedBy(0.8) .toFixed(0); diff --git a/test-suites/test-amm/liquidation-atoken.spec.ts b/test-suites/test-amm/liquidation-atoken.spec.ts index 775fe769..d229bf29 100644 --- a/test-suites/test-amm/liquidation-atoken.spec.ts +++ b/test-suites/test-amm/liquidation-atoken.spec.ts @@ -55,7 +55,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.95) .toFixed(0) @@ -269,7 +269,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-amm/liquidation-underlying.spec.ts b/test-suites/test-amm/liquidation-underlying.spec.ts index e44a2d80..64014ee0 100644 --- a/test-suites/test-amm/liquidation-underlying.spec.ts +++ b/test-suites/test-amm/liquidation-underlying.spec.ts @@ -83,7 +83,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', const amountDAIToBorrow = await convertToCurrencyDecimals( dai.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(daiPrice.toString()) .multipliedBy(0.95) .toFixed(0) @@ -267,7 +267,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0) diff --git a/test-suites/test-amm/pausable-functions.spec.ts b/test-suites/test-amm/pausable-functions.spec.ts index e5bd4637..1d6d21dd 100644 --- a/test-suites/test-amm/pausable-functions.spec.ts +++ b/test-suites/test-amm/pausable-functions.spec.ts @@ -224,7 +224,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => { const amountUSDCToBorrow = await convertToCurrencyDecimals( usdc.address, - new BigNumber(userGlobalData.availableBorrowsETH.toString()) + new BigNumber(userGlobalData.availableBorrowsBase.toString()) .div(usdcPrice.toString()) .multipliedBy(0.9502) .toFixed(0)