Readded calculateAvailableBorrowsETH

This commit is contained in:
The3D 2020-09-21 22:08:44 +02:00
parent 2e30bb8b85
commit 12f1dbd0dc
8 changed files with 104 additions and 21 deletions

View File

@ -367,6 +367,7 @@ interface ILendingPool {
returns (
uint256 totalCollateralETH,
uint256 totalBorrowsETH,
uint256 availableBorrowsETH,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor

View File

@ -29,7 +29,6 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol';
import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol';
/**
* @title LendingPool contract
* @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data
@ -161,6 +160,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
emit Withdraw(asset, msg.sender, amount);
}
/**
* @dev returns the borrow allowance of the user
* @param asset The underlying asset of the debt token
* @param fromUser The user to giving allowance
* @param toUser The user to give allowance to
* @param interestRateMode Type of debt: 1 for stable, 2 for variable
* @return the current allowance of toUser
**/
function getBorrowAllowance(
address fromUser,
address toUser,
@ -363,15 +370,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress);
IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress);
address aTokenAddress = reserve.aTokenAddress;
uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user);
// user must be borrowing on asset at a stable rate
require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE);
//if the utilization rate is below 95%, no rebalances are needed
uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay();
uint256 availableLiquidity = IERC20(asset).balanceOf(reserve.aTokenAddress).wadToRay();
uint256 availableLiquidity = IERC20(asset).balanceOf(aTokenAddress).wadToRay();
uint256 usageRatio = totalBorrows == 0
? 0
: totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
@ -398,11 +403,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
IStableDebtToken(address(stableDebtToken)).burn(user, stableBorrowBalance);
IStableDebtToken(address(stableDebtToken)).mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0);
reserve.updateInterestRates(asset, aTokenAddress, 0, 0);
emit RebalanceStableBorrowRate(asset, user);
return;
}
/**
@ -731,6 +735,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
returns (
uint256 totalCollateralETH,
uint256 totalBorrowsETH,
uint256 availableBorrowsETH,
uint256 currentLiquidationThreshold,
uint256 ltv,
uint256 healthFactor
@ -749,6 +754,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
_reservesList,
_addressesProvider.getPriceOracle()
);
availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
totalCollateralETH,
totalBorrowsETH,
ltv
);
}
function getUserReserveData(address asset, address user)

View File

@ -6,7 +6,6 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {ReserveLogic} from '../logic/ReserveLogic.sol';
import {WadRayMath} from '../math/WadRayMath.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import "@nomiclabs/buidler/console.sol";
/**
* @title ReserveConfiguration library

View File

@ -253,4 +253,28 @@ library GenericLogic {
return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH);
}
/**
* @dev calculates the equivalent amount in ETH that an user can borrow, depending on the available collateral and the
* average Loan To Value.
* @param collateralBalanceETH the total collateral balance
* @param borrowBalanceETH the total borrow balance
* @param ltv the average loan to value
* @return the amount available to borrow in ETH for the user
**/
function calculateAvailableBorrowsETH(
uint256 collateralBalanceETH,
uint256 borrowBalanceETH,
uint256 ltv
) internal pure returns (uint256) {
uint256 availableBorrowsETH = collateralBalanceETH.percentMul(ltv); //ltv is in percentage
if (availableBorrowsETH < borrowBalanceETH) {
return 0;
}
availableBorrowsETH = availableBorrowsETH.sub(borrowBalanceETH);
return availableBorrowsETH;
}
}

View File

@ -8,7 +8,6 @@ import {DebtTokenBase} from './base/DebtTokenBase.sol';
import {MathUtils} from '../libraries/math/MathUtils.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
import "@nomiclabs/buidler/console.sol";
/**
* @title contract StableDebtToken

View File

@ -636,11 +636,6 @@ export const rebalanceStableBorrowRate = async (
testEnv
);
console.log("avl liquidity ", reserveDataBefore.availableLiquidity.toFixed());
console.log("Total borrows stable ", reserveDataBefore.totalStableDebt.toFixed());
console.log("Total borrows variable ", reserveDataBefore.totalVariableDebt.toFixed());
console.log("Usage ratio ", reserveDataBefore.utilizationRate.toFixed());
if (expectedResult === 'success') {
const txResult = await waitForTx(
await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address)

View File

@ -78,8 +78,8 @@
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "600",
"borrowRateMode": "variable",
"amount": "250",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
@ -98,14 +98,68 @@
]
},
{
"description": "User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
"description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
"actions": [
{
"name": "swapBorrowRateMode",
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "200",
"borrowRateMode": "stable",
"user": "1",
"borrowRateMode": "variable"
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "Interest rate rebalance conditions were not met"
}
]
},
{
"description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "200",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
{
"name": "rebalanceStableBorrowRate",
"args": {
"reserve": "DAI",
"user": "0",
"target": "1"
},
"expected": "revert",
"revertMessage": "Interest rate rebalance conditions were not met"
}
]
},
{
"description": "User 1 borrows another 100 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)",
"actions": [
{
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "100",
"borrowRateMode": "stable",
"user": "1",
"timeTravel": "365"
},
"expected": "success"
},
@ -155,7 +209,7 @@
"name": "borrow",
"args": {
"reserve": "DAI",
"amount": "340",
"amount": "190",
"borrowRateMode": "variable",
"user": "2"
},

View File

@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine';
const scenarioFolder = './test/helpers/scenarios/';
const selectedScenarios: string[] = ['rebalance-stable-rate.json'];
const selectedScenarios: string[] = [];
fs.readdirSync(scenarioFolder).forEach((file) => {
if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return;