mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge local branch
This commit is contained in:
parent
3df87a8e5d
commit
4a1e1156f4
|
@ -305,7 +305,6 @@ interface ILendingPool {
|
||||||
uint256 principalVariableDebt,
|
uint256 principalVariableDebt,
|
||||||
uint256 stableBorrowRate,
|
uint256 stableBorrowRate,
|
||||||
uint256 liquidityRate,
|
uint256 liquidityRate,
|
||||||
uint256 variableBorrowIndex,
|
|
||||||
uint40 stableRateLastUpdated,
|
uint40 stableRateLastUpdated,
|
||||||
bool usageAsCollateralEnabled
|
bool usageAsCollateralEnabled
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,7 +23,8 @@ interface IReserveInterestRateStrategy {
|
||||||
uint256 utilizationRate,
|
uint256 utilizationRate,
|
||||||
uint256 totalBorrowsStable,
|
uint256 totalBorrowsStable,
|
||||||
uint256 totalBorrowsVariable,
|
uint256 totalBorrowsVariable,
|
||||||
uint256 averageStableBorrowRate
|
uint256 averageStableBorrowRate,
|
||||||
|
uint256 reserveFactor
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
|
|
|
@ -49,6 +49,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
//slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
//slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||||
uint256 internal immutable _stableRateSlope2;
|
uint256 internal immutable _stableRateSlope2;
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
LendingPoolAddressesProvider provider,
|
LendingPoolAddressesProvider provider,
|
||||||
uint256 baseVariableBorrowRate,
|
uint256 baseVariableBorrowRate,
|
||||||
|
@ -89,6 +90,15 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
return _baseVariableBorrowRate;
|
return _baseVariableBorrowRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CalcInterestRatesLocalVars {
|
||||||
|
|
||||||
|
uint256 totalBorrows;
|
||||||
|
uint256 currentVariableBorrowRate;
|
||||||
|
uint256 currentStableBorrowRate;
|
||||||
|
uint256 currentLiquidityRate;
|
||||||
|
uint256 utilizationRate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev calculates the interest rates depending on the available liquidity and the total borrowed.
|
* @dev calculates the interest rates depending on the available liquidity and the total borrowed.
|
||||||
* @param reserve the address of the reserve
|
* @param reserve the address of the reserve
|
||||||
|
@ -96,6 +106,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
* @param totalBorrowsStable the total borrowed from the reserve a stable rate
|
* @param totalBorrowsStable the total borrowed from the reserve a stable rate
|
||||||
* @param totalBorrowsVariable the total borrowed from the reserve at a variable rate
|
* @param totalBorrowsVariable the total borrowed from the reserve at a variable rate
|
||||||
* @param averageStableBorrowRate the weighted average of all the stable rate borrows
|
* @param averageStableBorrowRate the weighted average of all the stable rate borrows
|
||||||
|
* @param reserveFactor the reserve portion of the interest to redirect to the reserve treasury
|
||||||
* @return currentLiquidityRate the liquidity rate
|
* @return currentLiquidityRate the liquidity rate
|
||||||
* @return currentStableBorrowRate stable borrow rate
|
* @return currentStableBorrowRate stable borrow rate
|
||||||
* @return currentVariableBorrowRate variable borrow rate
|
* @return currentVariableBorrowRate variable borrow rate
|
||||||
|
@ -105,7 +116,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
uint256 availableLiquidity,
|
uint256 availableLiquidity,
|
||||||
uint256 totalBorrowsStable,
|
uint256 totalBorrowsStable,
|
||||||
uint256 totalBorrowsVariable,
|
uint256 totalBorrowsVariable,
|
||||||
uint256 averageStableBorrowRate
|
uint256 averageStableBorrowRate,
|
||||||
|
uint256 reserveFactor
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
override
|
override
|
||||||
|
@ -116,16 +128,19 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
uint256
|
uint256
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint256 totalBorrows = totalBorrowsStable.add(totalBorrowsVariable);
|
|
||||||
uint256 currentVariableBorrowRate = 0;
|
|
||||||
uint256 currentStableBorrowRate = 0;
|
|
||||||
uint256 currentLiquidityRate = 0;
|
|
||||||
|
|
||||||
uint256 utilizationRate = totalBorrows == 0
|
CalcInterestRatesLocalVars memory vars;
|
||||||
|
|
||||||
|
vars.totalBorrows = totalBorrowsStable.add(totalBorrowsVariable);
|
||||||
|
vars.currentVariableBorrowRate = 0;
|
||||||
|
vars.currentStableBorrowRate = 0;
|
||||||
|
vars.currentLiquidityRate = 0;
|
||||||
|
|
||||||
|
uint256 utilizationRate = vars.totalBorrows == 0
|
||||||
? 0
|
? 0
|
||||||
: totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
|
: vars.totalBorrows.rayDiv(availableLiquidity.add(vars.totalBorrows));
|
||||||
|
|
||||||
currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle())
|
vars.currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle())
|
||||||
.getMarketBorrowRate(reserve);
|
.getMarketBorrowRate(reserve);
|
||||||
|
|
||||||
if (utilizationRate > OPTIMAL_UTILIZATION_RATE) {
|
if (utilizationRate > OPTIMAL_UTILIZATION_RATE) {
|
||||||
|
@ -133,31 +148,32 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||||
EXCESS_UTILIZATION_RATE
|
EXCESS_UTILIZATION_RATE
|
||||||
);
|
);
|
||||||
|
|
||||||
currentStableBorrowRate = currentStableBorrowRate.add(_stableRateSlope1).add(
|
vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(_stableRateSlope1).add(
|
||||||
_stableRateSlope2.rayMul(excessUtilizationRateRatio)
|
_stableRateSlope2.rayMul(excessUtilizationRateRatio)
|
||||||
);
|
);
|
||||||
|
|
||||||
currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add(
|
vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add(
|
||||||
_variableRateSlope2.rayMul(excessUtilizationRateRatio)
|
_variableRateSlope2.rayMul(excessUtilizationRateRatio)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
currentStableBorrowRate = currentStableBorrowRate.add(
|
vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(
|
||||||
_stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE))
|
_stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE))
|
||||||
);
|
);
|
||||||
currentVariableBorrowRate = _baseVariableBorrowRate.add(
|
vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(
|
||||||
utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE).rayMul(_variableRateSlope1)
|
utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE).rayMul(_variableRateSlope1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentLiquidityRate = _getOverallBorrowRate(
|
vars.currentLiquidityRate = _getOverallBorrowRate(
|
||||||
totalBorrowsStable,
|
totalBorrowsStable,
|
||||||
totalBorrowsVariable,
|
totalBorrowsVariable,
|
||||||
currentVariableBorrowRate,
|
vars.currentVariableBorrowRate,
|
||||||
averageStableBorrowRate
|
averageStableBorrowRate
|
||||||
)
|
)
|
||||||
.rayMul(utilizationRate);
|
.rayMul(utilizationRate)
|
||||||
|
.rayMul(WadRayMath.ray().sub(reserveFactor));
|
||||||
|
|
||||||
return (currentLiquidityRate, currentStableBorrowRate, currentVariableBorrowRate);
|
return (vars.currentLiquidityRate, vars.currentStableBorrowRate, vars.currentVariableBorrowRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||||
|
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
||||||
|
@ -19,12 +20,12 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
|
||||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||||
|
import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol';
|
||||||
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||||
import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol';
|
import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol';
|
||||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title LendingPool contract
|
* @title LendingPool contract
|
||||||
* @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data
|
* @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data
|
||||||
|
@ -34,6 +35,7 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||||
contract LendingPool is VersionedInitializable, ILendingPool {
|
contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
|
using PercentageMath for uint256;
|
||||||
using ReserveLogic for ReserveLogic.ReserveData;
|
using ReserveLogic for ReserveLogic.ReserveData;
|
||||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||||
using UserConfiguration for UserConfiguration.Map;
|
using UserConfiguration for UserConfiguration.Map;
|
||||||
|
@ -224,6 +226,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress;
|
||||||
|
_mintToReserveTreasury(reserve, onBehalfOf, debtTokenAddress);
|
||||||
|
|
||||||
//burns an equivalent amount of debt tokens
|
//burns an equivalent amount of debt tokens
|
||||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
||||||
|
@ -265,6 +270,10 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress;
|
||||||
|
_mintToReserveTreasury(reserve, msg.sender, debtTokenAddress);
|
||||||
|
|
||||||
|
|
||||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||||
//burn stable rate tokens, mint variable rate tokens
|
//burn stable rate tokens, mint variable rate tokens
|
||||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
||||||
|
@ -321,6 +330,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
_mintToReserveTreasury(reserve, user, address(stableDebtToken));
|
||||||
|
|
||||||
|
|
||||||
stableDebtToken.burn(user, stableBorrowBalance);
|
stableDebtToken.burn(user, stableBorrowBalance);
|
||||||
stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
|
stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate);
|
||||||
|
|
||||||
|
@ -609,7 +621,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
uint256 principalVariableDebt,
|
uint256 principalVariableDebt,
|
||||||
uint256 stableBorrowRate,
|
uint256 stableBorrowRate,
|
||||||
uint256 liquidityRate,
|
uint256 liquidityRate,
|
||||||
uint256 variableBorrowIndex,
|
|
||||||
uint40 stableRateLastUpdated,
|
uint40 stableRateLastUpdated,
|
||||||
bool usageAsCollateralEnabled
|
bool usageAsCollateralEnabled
|
||||||
)
|
)
|
||||||
|
@ -625,7 +636,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
user
|
user
|
||||||
);
|
);
|
||||||
usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.index);
|
usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.index);
|
||||||
variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReserves() external override view returns (address[] memory) {
|
function getReserves() external override view returns (address[] memory) {
|
||||||
|
@ -706,6 +716,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
* @param vars Input struct for the borrowing action, in order to avoid STD errors
|
* @param vars Input struct for the borrowing action, in order to avoid STD errors
|
||||||
**/
|
**/
|
||||||
function _executeBorrow(ExecuteBorrowParams memory vars) internal {
|
function _executeBorrow(ExecuteBorrowParams memory vars) internal {
|
||||||
|
|
||||||
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
|
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
|
||||||
UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
|
UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
|
||||||
|
|
||||||
|
@ -730,13 +741,21 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
|
|
||||||
|
|
||||||
uint256 reserveIndex = reserve.index;
|
uint256 reserveIndex = reserve.index;
|
||||||
|
|
||||||
if (!userConfig.isBorrowing(reserveIndex)) {
|
if (!userConfig.isBorrowing(reserveIndex)) {
|
||||||
userConfig.setBorrowing(reserveIndex, true);
|
userConfig.setBorrowing(reserveIndex, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE ?
|
||||||
|
reserve.stableDebtTokenAddress
|
||||||
|
:
|
||||||
|
reserve.variableDebtTokenAddress;
|
||||||
|
|
||||||
|
|
||||||
reserve.updateCumulativeIndexesAndTimestamp();
|
reserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
_mintToReserveTreasury(reserve, vars.user, debtTokenAddress);
|
||||||
|
|
||||||
//caching the current stable borrow rate
|
//caching the current stable borrow rate
|
||||||
uint256 currentStableRate = 0;
|
uint256 currentStableRate = 0;
|
||||||
|
|
||||||
|
@ -745,13 +764,13 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
) {
|
) {
|
||||||
currentStableRate = reserve.currentStableBorrowRate;
|
currentStableRate = reserve.currentStableBorrowRate;
|
||||||
|
|
||||||
IStableDebtToken(reserve.stableDebtTokenAddress).mint(
|
IStableDebtToken(debtTokenAddress).mint(
|
||||||
vars.user,
|
vars.user,
|
||||||
vars.amount,
|
vars.amount,
|
||||||
currentStableRate
|
currentStableRate
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount);
|
IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ? vars.amount : 0);
|
reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ? vars.amount : 0);
|
||||||
|
@ -848,4 +867,19 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
||||||
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) {
|
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) {
|
||||||
return _addressesProvider;
|
return _addressesProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal {
|
||||||
|
|
||||||
|
uint256 currentPrincipalBalance = DebtTokenBase(debtTokenAddress).principalBalanceOf(user);
|
||||||
|
//calculating the interest accrued since the last borrow and minting the equivalent amount to the reserve factor
|
||||||
|
if(currentPrincipalBalance > 0){
|
||||||
|
|
||||||
|
uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub(currentPrincipalBalance);
|
||||||
|
|
||||||
|
uint256 amountForReserveFactor = balanceIncrease.percentMul(reserve.configuration.getReserveFactor());
|
||||||
|
|
||||||
|
IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddresse
|
||||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||||
|
import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol';
|
||||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||||
|
@ -208,6 +209,9 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
||||||
|
|
||||||
//update the principal reserve
|
//update the principal reserve
|
||||||
principalReserve.updateCumulativeIndexesAndTimestamp();
|
principalReserve.updateCumulativeIndexesAndTimestamp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
principalReserve.updateInterestRates(
|
principalReserve.updateInterestRates(
|
||||||
principal,
|
principal,
|
||||||
principalReserve.aTokenAddress,
|
principalReserve.aTokenAddress,
|
||||||
|
@ -216,16 +220,29 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
|
||||||
|
address tokenAddress = principalReserve.variableDebtTokenAddress;
|
||||||
|
|
||||||
|
_mintToReserveTreasury(principalReserve, user, tokenAddress);
|
||||||
|
|
||||||
|
IVariableDebtToken(tokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.actualAmountToLiquidate
|
vars.actualAmountToLiquidate
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
|
||||||
|
address tokenAddress = principalReserve.variableDebtTokenAddress;
|
||||||
|
|
||||||
|
_mintToReserveTreasury(principalReserve, user, tokenAddress);
|
||||||
|
|
||||||
|
IVariableDebtToken(tokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.userVariableDebt
|
vars.userVariableDebt
|
||||||
);
|
);
|
||||||
IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(
|
|
||||||
|
tokenAddress = principalReserve.stableDebtTokenAddress;
|
||||||
|
|
||||||
|
IStableDebtToken(tokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
||||||
);
|
);
|
||||||
|
@ -337,4 +354,19 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
||||||
}
|
}
|
||||||
return (collateralAmount, principalAmountNeeded);
|
return (collateralAmount, principalAmountNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal {
|
||||||
|
|
||||||
|
uint256 currentPrincipalBalance = DebtTokenBase(debtTokenAddress).principalBalanceOf(user);
|
||||||
|
//calculating the interest accrued since the last borrow and minting the equivalent amount to the reserve factor
|
||||||
|
if(currentPrincipalBalance > 0){
|
||||||
|
|
||||||
|
uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub(currentPrincipalBalance);
|
||||||
|
|
||||||
|
uint256 amountForReserveFactor = balanceIncrease.percentMul(reserve.configuration.getReserveFactor());
|
||||||
|
|
||||||
|
IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ library ReserveConfiguration {
|
||||||
uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF;
|
uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF;
|
||||||
uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF;
|
uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF;
|
||||||
uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF;
|
uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF;
|
||||||
|
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
|
||||||
struct Map {
|
struct Map {
|
||||||
//bit 0-15: LTV
|
//bit 0-15: LTV
|
||||||
|
@ -31,9 +32,27 @@ library ReserveConfiguration {
|
||||||
//bit 57: reserve is freezed
|
//bit 57: reserve is freezed
|
||||||
//bit 58: borrowing is enabled
|
//bit 58: borrowing is enabled
|
||||||
//bit 59: stable rate borrowing enabled
|
//bit 59: stable rate borrowing enabled
|
||||||
|
//bit 64-79: reserve factor
|
||||||
uint256 data;
|
uint256 data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev sets the reserve factor of the reserve
|
||||||
|
* @param self the reserve configuration
|
||||||
|
* @param ltv the new ltv
|
||||||
|
**/
|
||||||
|
function setReserveFactor(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
|
||||||
|
self.data = (self.data & RESERVE_FACTOR_MASK) | ltv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev gets the reserve factor of the reserve
|
||||||
|
* @param self the reserve configuration
|
||||||
|
* @return the reserve factor
|
||||||
|
**/
|
||||||
|
function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||||
|
return self.data & ~RESERVE_FACTOR_MASK;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @dev sets the Loan to Value of the reserve
|
* @dev sets the Loan to Value of the reserve
|
||||||
* @param self the reserve configuration
|
* @param self the reserve configuration
|
||||||
|
|
|
@ -246,7 +246,8 @@ library ReserveLogic {
|
||||||
vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken),
|
vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken),
|
||||||
IERC20(vars.stableDebtTokenAddress).totalSupply(),
|
IERC20(vars.stableDebtTokenAddress).totalSupply(),
|
||||||
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
||||||
vars.currentAvgStableRate
|
vars.currentAvgStableRate,
|
||||||
|
reserve.configuration.getReserveFactor()
|
||||||
);
|
);
|
||||||
require(vars.newLiquidityRate < (1 << 128), "ReserveLogic: Liquidity rate overflow");
|
require(vars.newLiquidityRate < (1 << 128), "ReserveLogic: Liquidity rate overflow");
|
||||||
require(vars.newStableRate < (1 << 128), "ReserveLogic: Stable borrow rate overflow");
|
require(vars.newStableRate < (1 << 128), "ReserveLogic: Stable borrow rate overflow");
|
||||||
|
|
|
@ -10,7 +10,7 @@ contract MockAToken is AToken {
|
||||||
address _underlyingAssetAddress,
|
address _underlyingAssetAddress,
|
||||||
string memory _tokenName,
|
string memory _tokenName,
|
||||||
string memory _tokenSymbol
|
string memory _tokenSymbol
|
||||||
) public AToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {}
|
) public AToken(_pool, _underlyingAssetAddress,address(0), _tokenName, _tokenSymbol) {}
|
||||||
|
|
||||||
function getRevision() internal override pure returns (uint256) {
|
function getRevision() internal override pure returns (uint256) {
|
||||||
return 0x2;
|
return 0x2;
|
||||||
|
|
|
@ -25,6 +25,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
||||||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||||
|
|
||||||
address public immutable UNDERLYING_ASSET_ADDRESS;
|
address public immutable UNDERLYING_ASSET_ADDRESS;
|
||||||
|
address public immutable RESERVE_TREASURY_ADDRESS;
|
||||||
|
|
||||||
mapping(address => uint256) private _userIndexes;
|
mapping(address => uint256) private _userIndexes;
|
||||||
mapping(address => address) private _interestRedirectionAddresses;
|
mapping(address => address) private _interestRedirectionAddresses;
|
||||||
|
@ -48,11 +49,13 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
||||||
constructor(
|
constructor(
|
||||||
LendingPool pool,
|
LendingPool pool,
|
||||||
address underlyingAssetAddress,
|
address underlyingAssetAddress,
|
||||||
|
address reserveTreasuryAddress,
|
||||||
string memory tokenName,
|
string memory tokenName,
|
||||||
string memory tokenSymbol
|
string memory tokenSymbol
|
||||||
) public ERC20(tokenName, tokenSymbol, 18) {
|
) public ERC20(tokenName, tokenSymbol, 18) {
|
||||||
_pool = pool;
|
_pool = pool;
|
||||||
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
|
UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress;
|
||||||
|
RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRevision() internal virtual override pure returns (uint256) {
|
function getRevision() internal virtual override pure returns (uint256) {
|
||||||
|
@ -183,6 +186,11 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
||||||
emit Mint(user, amount, balanceIncrease, index);
|
emit Mint(user, amount, balanceIncrease, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mintToReserve(uint256 amount) external override onlyLendingPool {
|
||||||
|
uint256 index = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
|
||||||
|
_mint(RESERVE_TREASURY_ADDRESS, amount.div(index));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
|
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
|
||||||
* only lending pools can call this function
|
* only lending pools can call this function
|
||||||
|
|
|
@ -17,6 +17,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
|
|
||||||
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
|
uint256 public constant DEBT_TOKEN_REVISION = 0x1;
|
||||||
|
mapping(address => uint256) _userIndexes;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
address pool,
|
address pool,
|
||||||
|
@ -59,6 +60,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||||
uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
||||||
|
|
||||||
_mint(user, amount.rayDiv(index));
|
_mint(user, amount.rayDiv(index));
|
||||||
|
_userIndexes[user] = index;
|
||||||
emit MintDebt(user, amount, index);
|
emit MintDebt(user, amount, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +73,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||||
|
|
||||||
uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET);
|
||||||
_burn(user, amount.rayDiv(index));
|
_burn(user, amount.rayDiv(index));
|
||||||
|
_userIndexes[user] = index;
|
||||||
emit BurnDebt(user, amount, index);
|
emit BurnDebt(user, amount, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the principal debt balance of the user from
|
||||||
|
* @return The debt balance of the user since the last burn/mint action
|
||||||
|
**/
|
||||||
|
function principalBalanceOf(address user) public virtual override view returns (uint256) {
|
||||||
|
return super.balanceOf(user).rayMul(_userIndexes[user]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable {
|
||||||
* @dev Returns the principal debt balance of the user from
|
* @dev Returns the principal debt balance of the user from
|
||||||
* @return The debt balance of the user since the last burn/mint action
|
* @return The debt balance of the user since the last burn/mint action
|
||||||
**/
|
**/
|
||||||
function principalBalanceOf(address user) public view returns (uint256) {
|
function principalBalanceOf(address user) public virtual view returns (uint256) {
|
||||||
return super.balanceOf(user);
|
return super.balanceOf(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,14 @@ interface IAToken is IERC20 {
|
||||||
*/
|
*/
|
||||||
function mint(address user, uint256 amount) external;
|
function mint(address user, uint256 amount) external;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev mints aTokens to reserve, based on the reserveFactor value
|
||||||
|
* only lending pools can call this function
|
||||||
|
* @param amount the amount of tokens to mint
|
||||||
|
*/
|
||||||
|
function mintToReserve(uint256 amount) external;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
|
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
|
||||||
* only lending pools can call this function
|
* only lending pools can call this function
|
||||||
|
|
|
@ -46,9 +46,4 @@ interface IVariableDebtToken {
|
||||||
**/
|
**/
|
||||||
function burn(address user, uint256 amount) external;
|
function burn(address user, uint256 amount) external;
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev returns the last index of the user
|
|
||||||
* @return the index of the user
|
|
||||||
**/
|
|
||||||
function getUserIndex(address user) external view returns (uint256);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user