mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
refactor: further refactored the cache helper functions
This commit is contained in:
parent
c794a697a7
commit
86686ef3be
|
@ -26,7 +26,6 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
|
||||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||||
import {CachingHelper} from '../libraries/helpers/CachingHelper.sol';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title LendingPool contract
|
* @title LendingPool contract
|
||||||
|
@ -270,7 +269,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
**/
|
**/
|
||||||
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
|
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
|
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
|
||||||
|
|
||||||
|
@ -278,53 +277,54 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
|
|
||||||
ValidationLogic.validateSwapRateMode(
|
ValidationLogic.validateSwapRateMode(
|
||||||
reserve,
|
reserve,
|
||||||
|
reserveCache,
|
||||||
_usersConfig[msg.sender],
|
_usersConfig[msg.sender],
|
||||||
stableDebt,
|
stableDebt,
|
||||||
variableDebt,
|
variableDebt,
|
||||||
interestRateMode
|
interestRateMode
|
||||||
);
|
);
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||||
IStableDebtToken(cachedData.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
IStableDebtToken(reserveCache.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
||||||
|
|
||||||
cachedData.newPrincipalStableDebt = cachedData.newTotalStableDebt = cachedData
|
reserveCache.newPrincipalStableDebt = reserveCache.newTotalStableDebt = reserveCache
|
||||||
.oldTotalStableDebt
|
.oldTotalStableDebt
|
||||||
.sub(stableDebt);
|
.sub(stableDebt);
|
||||||
|
|
||||||
IVariableDebtToken(cachedData.variableDebtTokenAddress).mint(
|
IVariableDebtToken(reserveCache.variableDebtTokenAddress).mint(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
stableDebt,
|
stableDebt,
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
cachedData.newScaledVariableDebt = cachedData.oldScaledVariableDebt.add(
|
reserveCache.newScaledVariableDebt = reserveCache.oldScaledVariableDebt.add(
|
||||||
stableDebt.rayDiv(cachedData.newVariableBorrowIndex)
|
stableDebt.rayDiv(reserveCache.newVariableBorrowIndex)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
IVariableDebtToken(cachedData.variableDebtTokenAddress).burn(
|
IVariableDebtToken(reserveCache.variableDebtTokenAddress).burn(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
variableDebt,
|
variableDebt,
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
cachedData.newScaledVariableDebt = cachedData.oldScaledVariableDebt.sub(
|
reserveCache.newScaledVariableDebt = reserveCache.oldScaledVariableDebt.sub(
|
||||||
variableDebt.rayDiv(cachedData.newVariableBorrowIndex)
|
variableDebt.rayDiv(reserveCache.newVariableBorrowIndex)
|
||||||
);
|
);
|
||||||
|
|
||||||
IStableDebtToken(cachedData.stableDebtTokenAddress).mint(
|
IStableDebtToken(reserveCache.stableDebtTokenAddress).mint(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
msg.sender,
|
msg.sender,
|
||||||
variableDebt,
|
variableDebt,
|
||||||
reserve.currentStableBorrowRate
|
reserve.currentStableBorrowRate
|
||||||
);
|
);
|
||||||
|
|
||||||
cachedData.newPrincipalStableDebt = cachedData.newTotalStableDebt = cachedData
|
reserveCache.newPrincipalStableDebt = reserveCache.newTotalStableDebt = reserveCache
|
||||||
.oldTotalStableDebt
|
.oldTotalStableDebt
|
||||||
.add(stableDebt);
|
.add(stableDebt);
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateInterestRates(cachedData, asset, 0, 0);
|
reserve.updateInterestRates(reserveCache, asset, 0, 0);
|
||||||
|
|
||||||
emit Swap(asset, msg.sender, rateMode);
|
emit Swap(asset, msg.sender, rateMode);
|
||||||
}
|
}
|
||||||
|
@ -340,21 +340,22 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
**/
|
**/
|
||||||
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
|
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
IERC20 stableDebtToken = IERC20(cachedData.stableDebtTokenAddress);
|
IERC20 stableDebtToken = IERC20(reserveCache.stableDebtTokenAddress);
|
||||||
IERC20 variableDebtToken = IERC20(cachedData.variableDebtTokenAddress);
|
IERC20 variableDebtToken = IERC20(reserveCache.variableDebtTokenAddress);
|
||||||
uint256 stableDebt = IERC20(stableDebtToken).balanceOf(user);
|
uint256 stableDebt = IERC20(stableDebtToken).balanceOf(user);
|
||||||
|
|
||||||
ValidationLogic.validateRebalanceStableBorrowRate(
|
ValidationLogic.validateRebalanceStableBorrowRate(
|
||||||
reserve,
|
reserve,
|
||||||
|
reserveCache,
|
||||||
asset,
|
asset,
|
||||||
stableDebtToken,
|
stableDebtToken,
|
||||||
variableDebtToken,
|
variableDebtToken,
|
||||||
cachedData.aTokenAddress
|
reserveCache.aTokenAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
IStableDebtToken(address(stableDebtToken)).burn(user, stableDebt);
|
IStableDebtToken(address(stableDebtToken)).burn(user, stableDebt);
|
||||||
IStableDebtToken(address(stableDebtToken)).mint(
|
IStableDebtToken(address(stableDebtToken)).mint(
|
||||||
|
@ -364,7 +365,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
reserve.currentStableBorrowRate
|
reserve.currentStableBorrowRate
|
||||||
);
|
);
|
||||||
|
|
||||||
reserve.updateInterestRates(cachedData, asset, 0, 0);
|
reserve.updateInterestRates(reserveCache, asset, 0, 0);
|
||||||
|
|
||||||
emit RebalanceStableBorrowRate(asset, user);
|
emit RebalanceStableBorrowRate(asset, user);
|
||||||
}
|
}
|
||||||
|
@ -380,8 +381,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
whenNotPaused
|
whenNotPaused
|
||||||
{
|
{
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
ValidationLogic.validateSetUseReserveAsCollateral(reserve);
|
ValidationLogic.validateSetUseReserveAsCollateral(reserve, reserveCache);
|
||||||
|
|
||||||
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
|
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
|
||||||
|
|
||||||
|
@ -512,15 +514,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
|
|
||||||
if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
|
if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[vars.currentAsset];
|
DataTypes.ReserveData storage reserve = _reserves[vars.currentAsset];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
reserve.cumulateToLiquidityIndex(
|
reserve.cumulateToLiquidityIndex(
|
||||||
IERC20(vars.currentATokenAddress).totalSupply(),
|
IERC20(vars.currentATokenAddress).totalSupply(),
|
||||||
vars.currentPremium
|
vars.currentPremium
|
||||||
);
|
);
|
||||||
reserve.updateInterestRates(
|
reserve.updateInterestRates(
|
||||||
cachedData,
|
reserveCache,
|
||||||
vars.currentAsset,
|
vars.currentAsset,
|
||||||
vars.currentAmountPlusPremium,
|
vars.currentAmountPlusPremium,
|
||||||
0
|
0
|
||||||
|
@ -894,12 +896,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
function _executeBorrow(ExecuteBorrowParams memory vars) internal {
|
function _executeBorrow(ExecuteBorrowParams memory vars) internal {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[vars.asset];
|
DataTypes.ReserveData storage reserve = _reserves[vars.asset];
|
||||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf];
|
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
ValidationLogic.validateBorrow(
|
ValidationLogic.validateBorrow(
|
||||||
cachedData,
|
reserveCache,
|
||||||
vars.asset,
|
vars.asset,
|
||||||
vars.onBehalfOf,
|
vars.onBehalfOf,
|
||||||
vars.amount,
|
vars.amount,
|
||||||
|
@ -918,27 +920,27 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
if (DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE) {
|
if (DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE) {
|
||||||
currentStableRate = reserve.currentStableBorrowRate;
|
currentStableRate = reserve.currentStableBorrowRate;
|
||||||
|
|
||||||
isFirstBorrowing = IStableDebtToken(cachedData.stableDebtTokenAddress).mint(
|
isFirstBorrowing = IStableDebtToken(reserveCache.stableDebtTokenAddress).mint(
|
||||||
vars.user,
|
vars.user,
|
||||||
vars.onBehalfOf,
|
vars.onBehalfOf,
|
||||||
vars.amount,
|
vars.amount,
|
||||||
currentStableRate
|
currentStableRate
|
||||||
);
|
);
|
||||||
|
|
||||||
cachedData.newPrincipalStableDebt = cachedData.newTotalStableDebt = cachedData
|
reserveCache.newPrincipalStableDebt = reserveCache.newTotalStableDebt = reserveCache
|
||||||
.oldTotalStableDebt
|
.oldTotalStableDebt
|
||||||
.add(vars.amount);
|
.add(vars.amount);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
isFirstBorrowing = IVariableDebtToken(cachedData.variableDebtTokenAddress).mint(
|
isFirstBorrowing = IVariableDebtToken(reserveCache.variableDebtTokenAddress).mint(
|
||||||
vars.user,
|
vars.user,
|
||||||
vars.onBehalfOf,
|
vars.onBehalfOf,
|
||||||
vars.amount,
|
vars.amount,
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
cachedData.newScaledVariableDebt = cachedData.newScaledVariableDebt.add(
|
reserveCache.newScaledVariableDebt = reserveCache.newScaledVariableDebt.add(
|
||||||
vars.amount.rayDiv(cachedData.newVariableBorrowIndex)
|
vars.amount.rayDiv(reserveCache.newVariableBorrowIndex)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,14 +949,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateInterestRates(
|
reserve.updateInterestRates(
|
||||||
cachedData,
|
reserveCache,
|
||||||
vars.asset,
|
vars.asset,
|
||||||
0,
|
0,
|
||||||
vars.releaseUnderlying ? vars.amount : 0
|
vars.releaseUnderlying ? vars.amount : 0
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vars.releaseUnderlying) {
|
if (vars.releaseUnderlying) {
|
||||||
IAToken(cachedData.aTokenAddress).transferUnderlyingTo(vars.user, vars.amount);
|
IAToken(reserveCache.aTokenAddress).transferUnderlyingTo(vars.user, vars.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit Borrow(
|
emit Borrow(
|
||||||
|
@ -977,18 +979,18 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
uint16 referralCode
|
uint16 referralCode
|
||||||
) internal {
|
) internal {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
ValidationLogic.validateDeposit(reserve, cachedData, amount);
|
ValidationLogic.validateDeposit(reserve, reserveCache, amount);
|
||||||
|
|
||||||
reserve.updateInterestRates(cachedData, asset, amount, 0);
|
reserve.updateInterestRates(reserveCache, asset, amount, 0);
|
||||||
|
|
||||||
IERC20(asset).safeTransferFrom(msg.sender, cachedData.aTokenAddress, amount);
|
IERC20(asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, amount);
|
||||||
|
|
||||||
bool isFirstDeposit =
|
bool isFirstDeposit =
|
||||||
IAToken(cachedData.aTokenAddress).mint(onBehalfOf, amount, cachedData.newLiquidityIndex);
|
IAToken(reserveCache.aTokenAddress).mint(onBehalfOf, amount, reserveCache.newLiquidityIndex);
|
||||||
|
|
||||||
if (isFirstDeposit) {
|
if (isFirstDeposit) {
|
||||||
_usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true);
|
_usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true);
|
||||||
|
@ -1005,13 +1007,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
) internal returns (uint256) {
|
) internal returns (uint256) {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[msg.sender];
|
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[msg.sender];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
uint256 userBalance =
|
uint256 userBalance =
|
||||||
IAToken(cachedData.aTokenAddress).scaledBalanceOf(msg.sender).rayMul(
|
IAToken(reserveCache.aTokenAddress).scaledBalanceOf(msg.sender).rayMul(
|
||||||
cachedData.newLiquidityIndex
|
reserveCache.newLiquidityIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
uint256 amountToWithdraw = amount;
|
uint256 amountToWithdraw = amount;
|
||||||
|
@ -1020,15 +1022,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
amountToWithdraw = userBalance;
|
amountToWithdraw = userBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidationLogic.validateWithdraw(reserve, amountToWithdraw, userBalance);
|
ValidationLogic.validateWithdraw(reserve, reserveCache, amountToWithdraw, userBalance);
|
||||||
|
|
||||||
reserve.updateInterestRates(cachedData, asset, 0, amountToWithdraw);
|
reserve.updateInterestRates(reserveCache, asset, 0, amountToWithdraw);
|
||||||
|
|
||||||
IAToken(cachedData.aTokenAddress).burn(
|
IAToken(reserveCache.aTokenAddress).burn(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
to,
|
to,
|
||||||
amountToWithdraw,
|
amountToWithdraw,
|
||||||
cachedData.newLiquidityIndex
|
reserveCache.newLiquidityIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
if (userConfig.isUsingAsCollateral(reserve.id)) {
|
if (userConfig.isUsingAsCollateral(reserve.id)) {
|
||||||
|
@ -1061,7 +1063,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
address onBehalfOf
|
address onBehalfOf
|
||||||
) internal returns (uint256) {
|
) internal returns (uint256) {
|
||||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||||
CachingHelper.CachedData memory cachedData = CachingHelper.fetchData(reserve);
|
DataTypes.ReserveCache memory reserveCache = reserve.cache();
|
||||||
|
|
||||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
|
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
|
||||||
|
|
||||||
|
@ -1069,6 +1071,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
|
|
||||||
ValidationLogic.validateRepay(
|
ValidationLogic.validateRepay(
|
||||||
reserve,
|
reserve,
|
||||||
|
reserveCache,
|
||||||
amount,
|
amount,
|
||||||
interestRateMode,
|
interestRateMode,
|
||||||
onBehalfOf,
|
onBehalfOf,
|
||||||
|
@ -1083,33 +1086,33 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
paybackAmount = amount;
|
paybackAmount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateState(cachedData);
|
reserve.updateState(reserveCache);
|
||||||
|
|
||||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||||
IStableDebtToken(cachedData.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
IStableDebtToken(reserveCache.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
||||||
cachedData.newPrincipalStableDebt = cachedData.newTotalStableDebt = cachedData
|
reserveCache.newPrincipalStableDebt = reserveCache.newTotalStableDebt = reserveCache
|
||||||
.oldTotalStableDebt
|
.oldTotalStableDebt
|
||||||
.sub(paybackAmount);
|
.sub(paybackAmount);
|
||||||
} else {
|
} else {
|
||||||
IVariableDebtToken(cachedData.variableDebtTokenAddress).burn(
|
IVariableDebtToken(reserveCache.variableDebtTokenAddress).burn(
|
||||||
onBehalfOf,
|
onBehalfOf,
|
||||||
paybackAmount,
|
paybackAmount,
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
cachedData.newScaledVariableDebt = cachedData.oldScaledVariableDebt.sub(
|
reserveCache.newScaledVariableDebt = reserveCache.oldScaledVariableDebt.sub(
|
||||||
paybackAmount.rayDiv(cachedData.newVariableBorrowIndex)
|
paybackAmount.rayDiv(reserveCache.newVariableBorrowIndex)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
reserve.updateInterestRates(cachedData, asset, paybackAmount, 0);
|
reserve.updateInterestRates(reserveCache, asset, paybackAmount, 0);
|
||||||
|
|
||||||
if (stableDebt.add(variableDebt).sub(paybackAmount) == 0) {
|
if (stableDebt.add(variableDebt).sub(paybackAmount) == 0) {
|
||||||
_usersConfig[onBehalfOf].setBorrowing(reserve.id, false);
|
_usersConfig[onBehalfOf].setBorrowing(reserve.id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
IERC20(asset).safeTransferFrom(msg.sender, cachedData.aTokenAddress, paybackAmount);
|
IERC20(asset).safeTransferFrom(msg.sender, reserveCache.aTokenAddress, paybackAmount);
|
||||||
|
|
||||||
IAToken(cachedData.aTokenAddress).handleRepayment(msg.sender, paybackAmount);
|
IAToken(reserveCache.aTokenAddress).handleRepayment(msg.sender, paybackAmount);
|
||||||
|
|
||||||
emit Repay(asset, onBehalfOf, msg.sender, paybackAmount);
|
emit Repay(asset, onBehalfOf, msg.sender, paybackAmount);
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ import {Errors} from '../libraries/helpers/Errors.sol';
|
||||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
||||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||||
import {CachingHelper} from '../libraries/helpers/CachingHelper.sol';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title LendingPoolCollateralManager contract
|
* @title LendingPoolCollateralManager contract
|
||||||
|
@ -101,11 +100,16 @@ contract LendingPoolCollateralManager is
|
||||||
_addressesProvider.getPriceOracle()
|
_addressesProvider.getPriceOracle()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DataTypes.ReserveCache memory debtReserveCache = debtReserve.cache();
|
||||||
|
DataTypes.ReserveCache memory collateralReserveCache = collateralReserve.cache();
|
||||||
|
|
||||||
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
|
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
|
||||||
|
|
||||||
(vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
|
(vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
|
||||||
collateralReserve,
|
collateralReserve,
|
||||||
debtReserve,
|
debtReserve,
|
||||||
|
debtReserveCache,
|
||||||
|
collateralReserveCache,
|
||||||
userConfig,
|
userConfig,
|
||||||
vars.healthFactor,
|
vars.healthFactor,
|
||||||
vars.userStableDebt,
|
vars.userStableDebt,
|
||||||
|
@ -161,44 +165,42 @@ contract LendingPoolCollateralManager is
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CachingHelper.CachedData memory debtReserveCachedData = CachingHelper.fetchData(debtReserve);
|
debtReserve.updateState(debtReserveCache);
|
||||||
|
|
||||||
debtReserve.updateState(debtReserveCachedData);
|
|
||||||
|
|
||||||
if (vars.userVariableDebt >= vars.actualDebtToLiquidate) {
|
if (vars.userVariableDebt >= vars.actualDebtToLiquidate) {
|
||||||
IVariableDebtToken(debtReserveCachedData.variableDebtTokenAddress).burn(
|
IVariableDebtToken(debtReserveCache.variableDebtTokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.actualDebtToLiquidate,
|
vars.actualDebtToLiquidate,
|
||||||
debtReserveCachedData.newVariableBorrowIndex
|
debtReserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
debtReserveCachedData.newScaledVariableDebt = debtReserveCachedData.oldScaledVariableDebt.sub(
|
debtReserveCache.newScaledVariableDebt = debtReserveCache.oldScaledVariableDebt.sub(
|
||||||
vars.actualDebtToLiquidate.rayDiv(debtReserveCachedData.newVariableBorrowIndex)
|
vars.actualDebtToLiquidate.rayDiv(debtReserveCache.newVariableBorrowIndex)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// If the user doesn't have variable debt, no need to try to burn variable debt tokens
|
// If the user doesn't have variable debt, no need to try to burn variable debt tokens
|
||||||
if (vars.userVariableDebt > 0) {
|
if (vars.userVariableDebt > 0) {
|
||||||
IVariableDebtToken(debtReserveCachedData.variableDebtTokenAddress).burn(
|
IVariableDebtToken(debtReserveCache.variableDebtTokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.userVariableDebt,
|
vars.userVariableDebt,
|
||||||
debtReserveCachedData.newVariableBorrowIndex
|
debtReserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
debtReserveCachedData.newScaledVariableDebt = debtReserveCachedData
|
debtReserveCache.newScaledVariableDebt = debtReserveCache
|
||||||
.oldScaledVariableDebt
|
.oldScaledVariableDebt
|
||||||
.sub(vars.userVariableDebt.rayDiv(debtReserveCachedData.newVariableBorrowIndex));
|
.sub(vars.userVariableDebt.rayDiv(debtReserveCache.newVariableBorrowIndex));
|
||||||
}
|
}
|
||||||
IStableDebtToken(debtReserveCachedData.stableDebtTokenAddress).burn(
|
IStableDebtToken(debtReserveCache.stableDebtTokenAddress).burn(
|
||||||
user,
|
user,
|
||||||
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
||||||
);
|
);
|
||||||
|
|
||||||
debtReserveCachedData.newPrincipalStableDebt = debtReserveCachedData
|
debtReserveCache.newPrincipalStableDebt = debtReserveCache
|
||||||
.newTotalStableDebt = debtReserveCachedData.oldTotalStableDebt.sub(
|
.newTotalStableDebt = debtReserveCache.oldTotalStableDebt.sub(
|
||||||
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
debtReserve.updateInterestRates(
|
debtReserve.updateInterestRates(
|
||||||
debtReserveCachedData,
|
debtReserveCache,
|
||||||
debtAsset,
|
debtAsset,
|
||||||
vars.actualDebtToLiquidate,
|
vars.actualDebtToLiquidate,
|
||||||
0
|
0
|
||||||
|
@ -214,12 +216,9 @@ contract LendingPoolCollateralManager is
|
||||||
emit ReserveUsedAsCollateralEnabled(collateralAsset, msg.sender);
|
emit ReserveUsedAsCollateralEnabled(collateralAsset, msg.sender);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CachingHelper.CachedData memory collateralReserveCachedData =
|
collateralReserve.updateState(collateralReserveCache);
|
||||||
CachingHelper.fetchData(collateralReserve);
|
|
||||||
|
|
||||||
collateralReserve.updateState(collateralReserveCachedData);
|
|
||||||
collateralReserve.updateInterestRates(
|
collateralReserve.updateInterestRates(
|
||||||
collateralReserveCachedData,
|
collateralReserveCache,
|
||||||
collateralAsset,
|
collateralAsset,
|
||||||
0,
|
0,
|
||||||
vars.maxCollateralToLiquidate
|
vars.maxCollateralToLiquidate
|
||||||
|
|
|
@ -104,6 +104,18 @@ library ReserveConfiguration {
|
||||||
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
|
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Gets the liquidation threshold of the reserve
|
||||||
|
* @param self The reserve configuration
|
||||||
|
* @return The liquidation threshold
|
||||||
|
**/
|
||||||
|
function getLiquidationThresholdMemory(DataTypes.ReserveConfigurationMap memory self)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @dev Sets the liquidation bonus of the reserve
|
* @dev Sets the liquidation bonus of the reserve
|
||||||
* @param self The reserve configuration
|
* @param self The reserve configuration
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
pragma solidity 0.6.12;
|
|
||||||
|
|
||||||
pragma experimental ABIEncoderV2;
|
|
||||||
|
|
||||||
import {DataTypes} from '../types/DataTypes.sol';
|
|
||||||
import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol';
|
|
||||||
import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol';
|
|
||||||
|
|
||||||
library CachingHelper {
|
|
||||||
struct CachedData {
|
|
||||||
uint256 oldScaledVariableDebt;
|
|
||||||
uint256 oldTotalVariableDebt;
|
|
||||||
uint256 newScaledVariableDebt;
|
|
||||||
uint256 newTotalVariableDebt;
|
|
||||||
uint256 oldPrincipalStableDebt;
|
|
||||||
uint256 oldAvgStableBorrowRate;
|
|
||||||
uint256 oldTotalStableDebt;
|
|
||||||
uint256 newPrincipalStableDebt;
|
|
||||||
uint256 newAvgStableBorrowRate;
|
|
||||||
uint256 newTotalStableDebt;
|
|
||||||
uint256 oldLiquidityIndex;
|
|
||||||
uint256 newLiquidityIndex;
|
|
||||||
uint256 oldVariableBorrowIndex;
|
|
||||||
uint256 newVariableBorrowIndex;
|
|
||||||
uint256 oldLiquidityRate;
|
|
||||||
uint256 oldVariableBorrowRate;
|
|
||||||
DataTypes.ReserveConfigurationMap reserveConfiguration;
|
|
||||||
address aTokenAddress;
|
|
||||||
address stableDebtTokenAddress;
|
|
||||||
address variableDebtTokenAddress;
|
|
||||||
uint40 reserveLastUpdateTimestamp;
|
|
||||||
uint40 stableDebtLastUpdateTimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchData(DataTypes.ReserveData storage reserveData)
|
|
||||||
internal
|
|
||||||
view
|
|
||||||
returns (CachingHelper.CachedData memory)
|
|
||||||
{
|
|
||||||
CachedData memory cachedData;
|
|
||||||
|
|
||||||
cachedData.reserveConfiguration = reserveData.configuration;
|
|
||||||
cachedData.oldLiquidityIndex = reserveData.liquidityIndex;
|
|
||||||
cachedData.oldVariableBorrowIndex = reserveData.variableBorrowIndex;
|
|
||||||
cachedData.oldLiquidityRate = reserveData.currentLiquidityRate;
|
|
||||||
cachedData.oldVariableBorrowRate = reserveData.currentVariableBorrowRate;
|
|
||||||
|
|
||||||
cachedData.aTokenAddress = reserveData.aTokenAddress;
|
|
||||||
cachedData.stableDebtTokenAddress = reserveData.stableDebtTokenAddress;
|
|
||||||
cachedData.variableDebtTokenAddress = reserveData.variableDebtTokenAddress;
|
|
||||||
|
|
||||||
cachedData.reserveLastUpdateTimestamp = reserveData.lastUpdateTimestamp;
|
|
||||||
|
|
||||||
cachedData.oldScaledVariableDebt = cachedData.newScaledVariableDebt = IVariableDebtToken(
|
|
||||||
cachedData
|
|
||||||
.variableDebtTokenAddress
|
|
||||||
)
|
|
||||||
.scaledTotalSupply();
|
|
||||||
|
|
||||||
(
|
|
||||||
cachedData.oldPrincipalStableDebt,
|
|
||||||
cachedData.oldTotalStableDebt,
|
|
||||||
cachedData.oldAvgStableBorrowRate,
|
|
||||||
cachedData.stableDebtLastUpdateTimestamp
|
|
||||||
) = IStableDebtToken(cachedData.stableDebtTokenAddress).getSupplyData();
|
|
||||||
|
|
||||||
cachedData.newPrincipalStableDebt = cachedData.oldPrincipalStableDebt;
|
|
||||||
cachedData.newTotalStableDebt = cachedData.oldTotalStableDebt;
|
|
||||||
cachedData.newAvgStableBorrowRate = cachedData.oldAvgStableBorrowRate;
|
|
||||||
|
|
||||||
return cachedData;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,6 @@ import {WadRayMath} from '../math/WadRayMath.sol';
|
||||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||||
import {Errors} from '../helpers/Errors.sol';
|
import {Errors} from '../helpers/Errors.sol';
|
||||||
import {DataTypes} from '../types/DataTypes.sol';
|
import {DataTypes} from '../types/DataTypes.sol';
|
||||||
import {CachingHelper} from '../helpers/CachingHelper.sol';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title ReserveLogic library
|
* @title ReserveLogic library
|
||||||
|
@ -110,11 +109,10 @@ library ReserveLogic {
|
||||||
**/
|
**/
|
||||||
function updateState(
|
function updateState(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
CachingHelper.CachedData memory cachedData
|
DataTypes.ReserveCache memory reserveCache
|
||||||
) internal {
|
) internal {
|
||||||
_updateIndexes(reserve, cachedData);
|
_updateIndexes(reserve, reserveCache);
|
||||||
|
_accrueToTreasury(reserve, reserveCache);
|
||||||
_accrueToTreasury(reserve, cachedData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -181,20 +179,20 @@ library ReserveLogic {
|
||||||
**/
|
**/
|
||||||
function updateInterestRates(
|
function updateInterestRates(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
CachingHelper.CachedData memory cachedData,
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
address reserveAddress,
|
address reserveAddress,
|
||||||
uint256 liquidityAdded,
|
uint256 liquidityAdded,
|
||||||
uint256 liquidityTaken
|
uint256 liquidityTaken
|
||||||
) internal {
|
) internal {
|
||||||
UpdateInterestRatesLocalVars memory vars;
|
UpdateInterestRatesLocalVars memory vars;
|
||||||
|
|
||||||
if (cachedData.oldTotalStableDebt != cachedData.newTotalStableDebt) {
|
if (reserveCache.oldTotalStableDebt != reserveCache.newTotalStableDebt) {
|
||||||
cachedData.newAvgStableBorrowRate = IStableDebtToken(cachedData.stableDebtTokenAddress)
|
reserveCache.newAvgStableBorrowRate = IStableDebtToken(reserveCache.stableDebtTokenAddress)
|
||||||
.getAverageStableRate();
|
.getAverageStableRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedData.newTotalVariableDebt = cachedData.newScaledVariableDebt.rayMul(
|
reserveCache.newTotalVariableDebt = reserveCache.newScaledVariableDebt.rayMul(
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -203,13 +201,13 @@ library ReserveLogic {
|
||||||
vars.newVariableRate
|
vars.newVariableRate
|
||||||
) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
|
) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
|
||||||
reserveAddress,
|
reserveAddress,
|
||||||
cachedData.aTokenAddress,
|
reserveCache.aTokenAddress,
|
||||||
liquidityAdded,
|
liquidityAdded,
|
||||||
liquidityTaken,
|
liquidityTaken,
|
||||||
cachedData.newTotalStableDebt,
|
reserveCache.newTotalStableDebt,
|
||||||
cachedData.newTotalVariableDebt,
|
reserveCache.newTotalVariableDebt,
|
||||||
cachedData.newAvgStableBorrowRate,
|
reserveCache.newAvgStableBorrowRate,
|
||||||
cachedData.reserveConfiguration.getReserveFactorMemory()
|
reserveCache.reserveConfiguration.getReserveFactorMemory()
|
||||||
);
|
);
|
||||||
require(vars.newLiquidityRate <= type(uint128).max, Errors.RL_LIQUIDITY_RATE_OVERFLOW);
|
require(vars.newLiquidityRate <= type(uint128).max, Errors.RL_LIQUIDITY_RATE_OVERFLOW);
|
||||||
require(vars.newStableRate <= type(uint128).max, Errors.RL_STABLE_BORROW_RATE_OVERFLOW);
|
require(vars.newStableRate <= type(uint128).max, Errors.RL_STABLE_BORROW_RATE_OVERFLOW);
|
||||||
|
@ -224,8 +222,8 @@ library ReserveLogic {
|
||||||
vars.newLiquidityRate,
|
vars.newLiquidityRate,
|
||||||
vars.newStableRate,
|
vars.newStableRate,
|
||||||
vars.newVariableRate,
|
vars.newVariableRate,
|
||||||
cachedData.newLiquidityIndex,
|
reserveCache.newLiquidityIndex,
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,43 +245,45 @@ library ReserveLogic {
|
||||||
* @dev Mints part of the repaid interest to the reserve treasury as a function of the reserveFactor for the
|
* @dev Mints part of the repaid interest to the reserve treasury as a function of the reserveFactor for the
|
||||||
* specific asset.
|
* specific asset.
|
||||||
* @param reserve The reserve reserve to be updated
|
* @param reserve The reserve reserve to be updated
|
||||||
* @param cachedData The caching layer for the reserve data
|
* @param reserveCache The caching layer for the reserve data
|
||||||
**/
|
**/
|
||||||
function _accrueToTreasury(
|
function _accrueToTreasury(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
CachingHelper.CachedData memory cachedData
|
DataTypes.ReserveCache memory reserveCache
|
||||||
) internal {
|
) internal {
|
||||||
MintToTreasuryLocalVars memory vars;
|
MintToTreasuryLocalVars memory vars;
|
||||||
|
|
||||||
vars.reserveFactor = cachedData.reserveConfiguration.getReserveFactorMemory();
|
vars.reserveFactor = reserveCache.reserveConfiguration.getReserveFactorMemory();
|
||||||
|
|
||||||
if (vars.reserveFactor == 0) {
|
if (vars.reserveFactor == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//calculate the last principal variable debt
|
//calculate the last principal variable debt
|
||||||
vars.previousVariableDebt = cachedData.oldScaledVariableDebt.rayMul(
|
vars.previousVariableDebt = reserveCache.oldScaledVariableDebt.rayMul(
|
||||||
cachedData.oldVariableBorrowIndex
|
reserveCache.oldVariableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
//calculate the new total supply after accumulation of the index
|
//calculate the new total supply after accumulation of the index
|
||||||
vars.currentVariableDebt = cachedData.oldScaledVariableDebt.rayMul(
|
vars.currentVariableDebt = reserveCache.oldScaledVariableDebt.rayMul(
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
//calculate the stable debt until the last timestamp update
|
//calculate the stable debt until the last timestamp update
|
||||||
vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(
|
vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(
|
||||||
cachedData.oldAvgStableBorrowRate,
|
reserveCache.oldAvgStableBorrowRate,
|
||||||
cachedData.stableDebtLastUpdateTimestamp,
|
reserveCache.stableDebtLastUpdateTimestamp,
|
||||||
cachedData.reserveLastUpdateTimestamp
|
reserveCache.reserveLastUpdateTimestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
vars.previousStableDebt = cachedData.oldPrincipalStableDebt.rayMul(vars.cumulatedStableInterest);
|
vars.previousStableDebt = reserveCache.oldPrincipalStableDebt.rayMul(
|
||||||
|
vars.cumulatedStableInterest
|
||||||
|
);
|
||||||
|
|
||||||
//debt accrued is the sum of the current debt minus the sum of the debt at the last update
|
//debt accrued is the sum of the current debt minus the sum of the debt at the last update
|
||||||
vars.totalDebtAccrued = vars
|
vars.totalDebtAccrued = vars
|
||||||
.currentVariableDebt
|
.currentVariableDebt
|
||||||
.add(cachedData.oldTotalStableDebt)
|
.add(reserveCache.oldTotalStableDebt)
|
||||||
.sub(vars.previousVariableDebt)
|
.sub(vars.previousVariableDebt)
|
||||||
.sub(vars.previousStableDebt);
|
.sub(vars.previousStableDebt);
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ library ReserveLogic {
|
||||||
|
|
||||||
if (vars.amountToMint != 0) {
|
if (vars.amountToMint != 0) {
|
||||||
reserve.accruedToTreasury = reserve.accruedToTreasury.add(
|
reserve.accruedToTreasury = reserve.accruedToTreasury.add(
|
||||||
vars.amountToMint.rayDiv(cachedData.newLiquidityIndex)
|
vars.amountToMint.rayDiv(reserveCache.newLiquidityIndex)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,52 +299,90 @@ library ReserveLogic {
|
||||||
/**
|
/**
|
||||||
* @dev Updates the reserve indexes and the timestamp of the update
|
* @dev Updates the reserve indexes and the timestamp of the update
|
||||||
* @param reserve The reserve reserve to be updated
|
* @param reserve The reserve reserve to be updated
|
||||||
* @param cachedData The cache layer holding the cached protocol data
|
* @param reserveCache The cache layer holding the cached protocol data
|
||||||
**/
|
**/
|
||||||
function _updateIndexes(
|
function _updateIndexes(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
CachingHelper.CachedData memory cachedData
|
DataTypes.ReserveCache memory reserveCache
|
||||||
) internal {
|
) internal {
|
||||||
cachedData.newLiquidityIndex = cachedData.oldLiquidityIndex;
|
reserveCache.newLiquidityIndex = reserveCache.oldLiquidityIndex;
|
||||||
cachedData.newVariableBorrowIndex = cachedData.oldVariableBorrowIndex;
|
reserveCache.newVariableBorrowIndex = reserveCache.oldVariableBorrowIndex;
|
||||||
|
|
||||||
//only cumulating if there is any income being produced
|
//only cumulating if there is any income being produced
|
||||||
if (cachedData.oldLiquidityRate > 0) {
|
if (reserveCache.oldLiquidityRate > 0) {
|
||||||
uint256 cumulatedLiquidityInterest =
|
uint256 cumulatedLiquidityInterest =
|
||||||
MathUtils.calculateLinearInterest(
|
MathUtils.calculateLinearInterest(
|
||||||
cachedData.oldLiquidityRate,
|
reserveCache.oldLiquidityRate,
|
||||||
cachedData.reserveLastUpdateTimestamp
|
reserveCache.reserveLastUpdateTimestamp
|
||||||
);
|
);
|
||||||
cachedData.newLiquidityIndex = cumulatedLiquidityInterest.rayMul(
|
reserveCache.newLiquidityIndex = cumulatedLiquidityInterest.rayMul(
|
||||||
cachedData.oldLiquidityIndex
|
reserveCache.oldLiquidityIndex
|
||||||
);
|
);
|
||||||
require(
|
require(
|
||||||
cachedData.newLiquidityIndex <= type(uint128).max,
|
reserveCache.newLiquidityIndex <= type(uint128).max,
|
||||||
Errors.RL_LIQUIDITY_INDEX_OVERFLOW
|
Errors.RL_LIQUIDITY_INDEX_OVERFLOW
|
||||||
);
|
);
|
||||||
|
reserve.liquidityIndex = uint128(reserveCache.newLiquidityIndex);
|
||||||
reserve.liquidityIndex = uint128(cachedData.newLiquidityIndex);
|
|
||||||
|
|
||||||
//as the liquidity rate might come only from stable rate loans, we need to ensure
|
//as the liquidity rate might come only from stable rate loans, we need to ensure
|
||||||
//that there is actual variable debt before accumulating
|
//that there is actual variable debt before accumulating
|
||||||
if (cachedData.oldScaledVariableDebt != 0) {
|
if (reserveCache.oldScaledVariableDebt != 0) {
|
||||||
uint256 cumulatedVariableBorrowInterest =
|
uint256 cumulatedVariableBorrowInterest =
|
||||||
MathUtils.calculateCompoundedInterest(
|
MathUtils.calculateCompoundedInterest(
|
||||||
cachedData.oldVariableBorrowRate,
|
reserveCache.oldVariableBorrowRate,
|
||||||
cachedData.reserveLastUpdateTimestamp
|
reserveCache.reserveLastUpdateTimestamp
|
||||||
);
|
);
|
||||||
cachedData.newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
|
reserveCache.newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
|
||||||
cachedData.oldVariableBorrowIndex
|
reserveCache.oldVariableBorrowIndex
|
||||||
);
|
);
|
||||||
require(
|
require(
|
||||||
cachedData.newVariableBorrowIndex <= type(uint128).max,
|
reserveCache.newVariableBorrowIndex <= type(uint128).max,
|
||||||
Errors.RL_VARIABLE_BORROW_INDEX_OVERFLOW
|
Errors.RL_VARIABLE_BORROW_INDEX_OVERFLOW
|
||||||
);
|
);
|
||||||
reserve.variableBorrowIndex = uint128(cachedData.newVariableBorrowIndex);
|
reserve.variableBorrowIndex = uint128(reserveCache.newVariableBorrowIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//solium-disable-next-line
|
//solium-disable-next-line
|
||||||
reserve.lastUpdateTimestamp = uint40(block.timestamp);
|
reserve.lastUpdateTimestamp = uint40(block.timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cache(DataTypes.ReserveData storage reserve)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (DataTypes.ReserveCache memory)
|
||||||
|
{
|
||||||
|
DataTypes.ReserveCache memory reserveCache;
|
||||||
|
|
||||||
|
reserveCache.reserveConfiguration = reserve.configuration;
|
||||||
|
reserveCache.oldLiquidityIndex = reserve.liquidityIndex;
|
||||||
|
reserveCache.oldVariableBorrowIndex = reserve.variableBorrowIndex;
|
||||||
|
reserveCache.oldLiquidityRate = reserve.currentLiquidityRate;
|
||||||
|
reserveCache.oldVariableBorrowRate = reserve.currentVariableBorrowRate;
|
||||||
|
|
||||||
|
reserveCache.aTokenAddress = reserve.aTokenAddress;
|
||||||
|
reserveCache.stableDebtTokenAddress = reserve.stableDebtTokenAddress;
|
||||||
|
reserveCache.variableDebtTokenAddress = reserve.variableDebtTokenAddress;
|
||||||
|
|
||||||
|
reserveCache.reserveLastUpdateTimestamp = reserve.lastUpdateTimestamp;
|
||||||
|
|
||||||
|
reserveCache.oldScaledVariableDebt = reserveCache.newScaledVariableDebt = IVariableDebtToken(
|
||||||
|
reserveCache
|
||||||
|
.variableDebtTokenAddress
|
||||||
|
)
|
||||||
|
.scaledTotalSupply();
|
||||||
|
|
||||||
|
(
|
||||||
|
reserveCache.oldPrincipalStableDebt,
|
||||||
|
reserveCache.oldTotalStableDebt,
|
||||||
|
reserveCache.oldAvgStableBorrowRate,
|
||||||
|
reserveCache.stableDebtLastUpdateTimestamp
|
||||||
|
) = IStableDebtToken(reserveCache.stableDebtTokenAddress).getSupplyData();
|
||||||
|
|
||||||
|
reserveCache.newPrincipalStableDebt = reserveCache.oldPrincipalStableDebt;
|
||||||
|
reserveCache.newTotalStableDebt = reserveCache.oldTotalStableDebt;
|
||||||
|
reserveCache.newAvgStableBorrowRate = reserveCache.oldAvgStableBorrowRate;
|
||||||
|
|
||||||
|
return reserveCache;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.
|
||||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||||
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
||||||
import {Errors} from '../helpers/Errors.sol';
|
import {Errors} from '../helpers/Errors.sol';
|
||||||
import {CachingHelper} from '../helpers/CachingHelper.sol';
|
|
||||||
import {Helpers} from '../helpers/Helpers.sol';
|
import {Helpers} from '../helpers/Helpers.sol';
|
||||||
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
|
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
|
||||||
import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol';
|
import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol';
|
||||||
|
@ -45,13 +44,13 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
function validateDeposit(
|
function validateDeposit(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
CachingHelper.CachedData memory cachedData,
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
uint256 amount
|
uint256 amount
|
||||||
) internal view {
|
) internal view {
|
||||||
(bool isActive, bool isFrozen, , , bool isPaused) =
|
(bool isActive, bool isFrozen, , , bool isPaused) =
|
||||||
cachedData.reserveConfiguration.getFlagsMemory();
|
reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
(, , , uint256 reserveDecimals, ) = cachedData.reserveConfiguration.getParamsMemory();
|
(, , , uint256 reserveDecimals, ) = reserveCache.reserveConfiguration.getParamsMemory();
|
||||||
uint256 supplyCap = cachedData.reserveConfiguration.getSupplyCapMemory();
|
uint256 supplyCap = reserveCache.reserveConfiguration.getSupplyCapMemory();
|
||||||
|
|
||||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
|
@ -59,9 +58,9 @@ library ValidationLogic {
|
||||||
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
||||||
require(
|
require(
|
||||||
supplyCap == 0 ||
|
supplyCap == 0 ||
|
||||||
IAToken(cachedData.aTokenAddress)
|
IAToken(reserveCache.aTokenAddress)
|
||||||
.scaledTotalSupply()
|
.scaledTotalSupply()
|
||||||
.rayMul(cachedData.newLiquidityIndex)
|
.rayMul(reserveCache.newLiquidityIndex)
|
||||||
.add(amount)
|
.add(amount)
|
||||||
.div(10**reserveDecimals) <
|
.div(10**reserveDecimals) <
|
||||||
supplyCap,
|
supplyCap,
|
||||||
|
@ -77,13 +76,14 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
function validateWithdraw(
|
function validateWithdraw(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint256 userBalance
|
uint256 userBalance
|
||||||
) external view {
|
) external view {
|
||||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||||
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
|
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
|
||||||
|
|
||||||
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
|
(bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function validateBorrow(
|
function validateBorrow(
|
||||||
CachingHelper.CachedData memory cachedData,
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
address asset,
|
address asset,
|
||||||
address userAddress,
|
address userAddress,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
|
@ -136,7 +136,7 @@ library ValidationLogic {
|
||||||
) external view {
|
) external view {
|
||||||
ValidateBorrowLocalVars memory vars;
|
ValidateBorrowLocalVars memory vars;
|
||||||
|
|
||||||
(, , , vars.reserveDecimals, ) = cachedData.reserveConfiguration.getParamsMemory();
|
(, , , vars.reserveDecimals, ) = reserveCache.reserveConfiguration.getParamsMemory();
|
||||||
|
|
||||||
(
|
(
|
||||||
vars.isActive,
|
vars.isActive,
|
||||||
|
@ -144,7 +144,7 @@ library ValidationLogic {
|
||||||
vars.borrowingEnabled,
|
vars.borrowingEnabled,
|
||||||
vars.stableRateBorrowingEnabled,
|
vars.stableRateBorrowingEnabled,
|
||||||
vars.isPaused
|
vars.isPaused
|
||||||
) = cachedData.reserveConfiguration.getFlagsMemory();
|
) = reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
|
|
||||||
require(vars.isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(vars.isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!vars.isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!vars.isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
|
@ -160,15 +160,15 @@ library ValidationLogic {
|
||||||
Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
|
Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
|
||||||
);
|
);
|
||||||
|
|
||||||
vars.borrowCap = cachedData.reserveConfiguration.getBorrowCapMemory();
|
vars.borrowCap = reserveCache.reserveConfiguration.getBorrowCapMemory();
|
||||||
|
|
||||||
if (vars.borrowCap > 0) {
|
if (vars.borrowCap > 0) {
|
||||||
{
|
{
|
||||||
vars.totalSupplyVariableDebt = cachedData.oldScaledVariableDebt.rayMul(
|
vars.totalSupplyVariableDebt = reserveCache.oldScaledVariableDebt.rayMul(
|
||||||
cachedData.newVariableBorrowIndex
|
reserveCache.newVariableBorrowIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
vars.totalDebt = cachedData.oldTotalStableDebt.add(vars.totalSupplyVariableDebt).add(
|
vars.totalDebt = reserveCache.oldTotalStableDebt.add(vars.totalSupplyVariableDebt).add(
|
||||||
amount
|
amount
|
||||||
);
|
);
|
||||||
require(
|
require(
|
||||||
|
@ -228,12 +228,12 @@ library ValidationLogic {
|
||||||
|
|
||||||
require(
|
require(
|
||||||
!userConfig.isUsingAsCollateral(reservesData[asset].id) ||
|
!userConfig.isUsingAsCollateral(reservesData[asset].id) ||
|
||||||
cachedData.reserveConfiguration.getLtvMemory() == 0 ||
|
reserveCache.reserveConfiguration.getLtvMemory() == 0 ||
|
||||||
amount > IERC20(cachedData.aTokenAddress).balanceOf(userAddress),
|
amount > IERC20(reserveCache.aTokenAddress).balanceOf(userAddress),
|
||||||
Errors.VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY
|
Errors.VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY
|
||||||
);
|
);
|
||||||
|
|
||||||
vars.availableLiquidity = IERC20(asset).balanceOf(cachedData.aTokenAddress);
|
vars.availableLiquidity = IERC20(asset).balanceOf(reserveCache.aTokenAddress);
|
||||||
|
|
||||||
//calculate the max available loan size in stable rate mode as a percentage of the
|
//calculate the max available loan size in stable rate mode as a percentage of the
|
||||||
//available liquidity
|
//available liquidity
|
||||||
|
@ -253,13 +253,14 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
function validateRepay(
|
function validateRepay(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
uint256 amountSent,
|
uint256 amountSent,
|
||||||
DataTypes.InterestRateMode rateMode,
|
DataTypes.InterestRateMode rateMode,
|
||||||
address onBehalfOf,
|
address onBehalfOf,
|
||||||
uint256 stableDebt,
|
uint256 stableDebt,
|
||||||
uint256 variableDebt
|
uint256 variableDebt
|
||||||
) external view {
|
) external view {
|
||||||
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
|
(bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
|
|
||||||
|
@ -289,13 +290,14 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
function validateSwapRateMode(
|
function validateSwapRateMode(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
DataTypes.UserConfigurationMap storage userConfig,
|
DataTypes.UserConfigurationMap storage userConfig,
|
||||||
uint256 stableDebt,
|
uint256 stableDebt,
|
||||||
uint256 variableDebt,
|
uint256 variableDebt,
|
||||||
DataTypes.InterestRateMode currentRateMode
|
DataTypes.InterestRateMode currentRateMode
|
||||||
) external view {
|
) external view {
|
||||||
(bool isActive, bool isFrozen, , bool stableRateEnabled, bool isPaused) =
|
(bool isActive, bool isFrozen, , bool stableRateEnabled, bool isPaused) =
|
||||||
reserve.configuration.getFlags();
|
reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
|
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
|
@ -316,8 +318,8 @@ library ValidationLogic {
|
||||||
|
|
||||||
require(
|
require(
|
||||||
!userConfig.isUsingAsCollateral(reserve.id) ||
|
!userConfig.isUsingAsCollateral(reserve.id) ||
|
||||||
reserve.configuration.getLtv() == 0 ||
|
reserveCache.reserveConfiguration.getLtvMemory() == 0 ||
|
||||||
stableDebt.add(variableDebt) > IERC20(reserve.aTokenAddress).balanceOf(msg.sender),
|
stableDebt.add(variableDebt) > IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender),
|
||||||
Errors.VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY
|
Errors.VL_COLLATERAL_SAME_AS_BORROWING_CURRENCY
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -335,12 +337,13 @@ library ValidationLogic {
|
||||||
*/
|
*/
|
||||||
function validateRebalanceStableBorrowRate(
|
function validateRebalanceStableBorrowRate(
|
||||||
DataTypes.ReserveData storage reserve,
|
DataTypes.ReserveData storage reserve,
|
||||||
|
DataTypes.ReserveCache memory reserveCache,
|
||||||
address reserveAddress,
|
address reserveAddress,
|
||||||
IERC20 stableDebtToken,
|
IERC20 stableDebtToken,
|
||||||
IERC20 variableDebtToken,
|
IERC20 variableDebtToken,
|
||||||
address aTokenAddress
|
address aTokenAddress
|
||||||
) external view {
|
) external view {
|
||||||
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
|
(bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
|
|
||||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
|
@ -354,7 +357,7 @@ library ValidationLogic {
|
||||||
//if the liquidity rate is below REBALANCE_UP_THRESHOLD of the max variable APR at 95% usage,
|
//if the liquidity rate is below REBALANCE_UP_THRESHOLD of the max variable APR at 95% usage,
|
||||||
//then we allow rebalancing of the stable rate positions.
|
//then we allow rebalancing of the stable rate positions.
|
||||||
|
|
||||||
uint256 currentLiquidityRate = reserve.currentLiquidityRate;
|
uint256 currentLiquidityRate = reserveCache.oldLiquidityRate;
|
||||||
uint256 maxVariableBorrowRate =
|
uint256 maxVariableBorrowRate =
|
||||||
IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).getMaxVariableBorrowRate();
|
IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).getMaxVariableBorrowRate();
|
||||||
|
|
||||||
|
@ -370,10 +373,14 @@ library ValidationLogic {
|
||||||
* @dev Validates the action of setting an asset as collateral
|
* @dev Validates the action of setting an asset as collateral
|
||||||
* @param reserve The state of the reserve that the user is enabling or disabling as collateral
|
* @param reserve The state of the reserve that the user is enabling or disabling as collateral
|
||||||
*/
|
*/
|
||||||
function validateSetUseReserveAsCollateral(DataTypes.ReserveData storage reserve) external view {
|
function validateSetUseReserveAsCollateral(
|
||||||
uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
|
DataTypes.ReserveData storage reserve,
|
||||||
bool isPaused = reserve.configuration.getPaused();
|
DataTypes.ReserveCache memory reserveCache
|
||||||
|
) external view {
|
||||||
|
uint256 underlyingBalance = IERC20(reserveCache.aTokenAddress).balanceOf(msg.sender);
|
||||||
|
(bool isActive, , , , bool isPaused) = reserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
|
|
||||||
|
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||||
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
require(!isPaused, Errors.VL_RESERVE_PAUSED);
|
||||||
|
|
||||||
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
|
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
|
||||||
|
@ -407,20 +414,26 @@ library ValidationLogic {
|
||||||
function validateLiquidationCall(
|
function validateLiquidationCall(
|
||||||
DataTypes.ReserveData storage collateralReserve,
|
DataTypes.ReserveData storage collateralReserve,
|
||||||
DataTypes.ReserveData storage principalReserve,
|
DataTypes.ReserveData storage principalReserve,
|
||||||
|
DataTypes.ReserveCache memory collateralReserveCache,
|
||||||
|
DataTypes.ReserveCache memory principalReserveCache,
|
||||||
DataTypes.UserConfigurationMap storage userConfig,
|
DataTypes.UserConfigurationMap storage userConfig,
|
||||||
uint256 userHealthFactor,
|
uint256 userHealthFactor,
|
||||||
uint256 userStableDebt,
|
uint256 userStableDebt,
|
||||||
uint256 userVariableDebt
|
uint256 userVariableDebt
|
||||||
) internal view returns (uint256, string memory) {
|
) internal view returns (uint256, string memory) {
|
||||||
if (
|
(bool collateralReserveActive, , , , bool collateralReservePaused) =
|
||||||
!collateralReserve.configuration.getActive() || !principalReserve.configuration.getActive()
|
collateralReserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
) {
|
|
||||||
|
(bool principalReserveActive, , , , bool principalReservePaused) =
|
||||||
|
collateralReserveCache.reserveConfiguration.getFlagsMemory();
|
||||||
|
|
||||||
|
if (!collateralReserveActive || !principalReserveActive) {
|
||||||
return (
|
return (
|
||||||
uint256(Errors.CollateralManagerErrors.NO_ACTIVE_RESERVE),
|
uint256(Errors.CollateralManagerErrors.NO_ACTIVE_RESERVE),
|
||||||
Errors.VL_NO_ACTIVE_RESERVE
|
Errors.VL_NO_ACTIVE_RESERVE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (collateralReserve.configuration.getPaused() || principalReserve.configuration.getPaused()) {
|
if (collateralReservePaused || principalReservePaused) {
|
||||||
return (uint256(Errors.CollateralManagerErrors.PAUSED_RESERVE), Errors.VL_RESERVE_PAUSED);
|
return (uint256(Errors.CollateralManagerErrors.PAUSED_RESERVE), Errors.VL_RESERVE_PAUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +445,7 @@ library ValidationLogic {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isCollateralEnabled =
|
bool isCollateralEnabled =
|
||||||
collateralReserve.configuration.getLiquidationThreshold() > 0 &&
|
collateralReserveCache.reserveConfiguration.getLiquidationThresholdMemory() > 0 &&
|
||||||
userConfig.isUsingAsCollateral(collateralReserve.id);
|
userConfig.isUsingAsCollateral(collateralReserve.id);
|
||||||
|
|
||||||
//if collateral isn't enabled as collateral by user, it cannot be liquidated
|
//if collateral isn't enabled as collateral by user, it cannot be liquidated
|
||||||
|
|
|
@ -51,4 +51,29 @@ library DataTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||||
|
|
||||||
|
struct ReserveCache {
|
||||||
|
uint256 oldScaledVariableDebt;
|
||||||
|
uint256 oldTotalVariableDebt;
|
||||||
|
uint256 newScaledVariableDebt;
|
||||||
|
uint256 newTotalVariableDebt;
|
||||||
|
uint256 oldPrincipalStableDebt;
|
||||||
|
uint256 oldAvgStableBorrowRate;
|
||||||
|
uint256 oldTotalStableDebt;
|
||||||
|
uint256 newPrincipalStableDebt;
|
||||||
|
uint256 newAvgStableBorrowRate;
|
||||||
|
uint256 newTotalStableDebt;
|
||||||
|
uint256 oldLiquidityIndex;
|
||||||
|
uint256 newLiquidityIndex;
|
||||||
|
uint256 oldVariableBorrowIndex;
|
||||||
|
uint256 newVariableBorrowIndex;
|
||||||
|
uint256 oldLiquidityRate;
|
||||||
|
uint256 oldVariableBorrowRate;
|
||||||
|
DataTypes.ReserveConfigurationMap reserveConfiguration;
|
||||||
|
address aTokenAddress;
|
||||||
|
address stableDebtTokenAddress;
|
||||||
|
address variableDebtTokenAddress;
|
||||||
|
uint40 reserveLastUpdateTimestamp;
|
||||||
|
uint40 stableDebtLastUpdateTimestamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -11142,14 +11142,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"min-document": "^2.19.0",
|
"min-document": "^2.19.0",
|
||||||
"process": "^0.11.10"
|
"process": "^0.11.10"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"process": {
|
|
||||||
"version": "0.5.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
|
|
||||||
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"got": {
|
"got": {
|
||||||
|
@ -12794,6 +12786,12 @@
|
||||||
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
|
"integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"process": {
|
||||||
|
"version": "0.11.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
"integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"process-nextick-args": {
|
"process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user