mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Fixed errors
This commit is contained in:
parent
6e92575ac2
commit
bb4e1b5c4b
|
@ -326,7 +326,6 @@ interface ILendingPool {
|
|||
uint256 currentStableDebt,
|
||||
uint256 currentVariableDebt,
|
||||
uint256 principalStableDebt,
|
||||
uint256 principalVariableDebt,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 liquidityRate,
|
||||
|
|
|
@ -49,10 +49,9 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||
uint256 public constant LENDINGPOOL_REVISION = 0x2;
|
||||
|
||||
ILendingPoolAddressesProvider public immutable ADDRESSES_PROVIDER;
|
||||
|
||||
mapping(address => ReserveLogic.ReserveData) internal _reserves;
|
||||
mapping(address => UserConfiguration.Map) internal _usersConfig;
|
||||
ILendingPoolAddressesProvider internal _addressesProvider;
|
||||
|
||||
address[] internal _reservesList;
|
||||
|
||||
|
@ -63,7 +62,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
**/
|
||||
modifier onlyLendingPoolConfigurator {
|
||||
require(
|
||||
ADDRESSES_PROVIDER.getLendingPoolConfigurator() == msg.sender,
|
||||
_addressesProvider.getLendingPoolConfigurator() == msg.sender,
|
||||
Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR
|
||||
);
|
||||
_;
|
||||
|
@ -79,7 +78,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
* @param provider the address of the LendingPoolAddressesProvider registry
|
||||
**/
|
||||
function initialize(ILendingPoolAddressesProvider provider) public initializer {
|
||||
ADDRESSES_PROVIDER = provider;
|
||||
_addressesProvider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,7 +143,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
_reserves,
|
||||
_usersConfig[msg.sender],
|
||||
_reservesList,
|
||||
ADDRESSES_PROVIDER.getPriceOracle()
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
reserve.updateState();
|
||||
|
@ -271,10 +270,10 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
//burn stable rate tokens, mint variable rate tokens
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, stableDebt);
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(msg.sender, stableDebt, reserve.variableBorrowIndex);
|
||||
} else {
|
||||
//do the opposite
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(msg.sender, variableDebt);
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(msg.sender, variableDebt, reserve.variableBorrowIndex);
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).mint(
|
||||
msg.sender,
|
||||
variableDebt,
|
||||
|
@ -348,7 +347,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
_reserves,
|
||||
_usersConfig[msg.sender],
|
||||
_reservesList,
|
||||
ADDRESSES_PROVIDER.getPriceOracle()
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
_usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral);
|
||||
|
@ -376,7 +375,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
uint256 purchaseAmount,
|
||||
bool receiveAToken
|
||||
) external override {
|
||||
address liquidationManager = ADDRESSES_PROVIDER.getLendingPoolLiquidationManager();
|
||||
address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
|
||||
|
||||
//solium-disable-next-line
|
||||
(bool success, bytes memory result) = liquidationManager.delegatecall(
|
||||
|
@ -435,7 +434,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED);
|
||||
_flashLiquidationLocked = true;
|
||||
|
||||
address liquidationManager = ADDRESSES_PROVIDER.getLendingPoolLiquidationManager();
|
||||
address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager();
|
||||
|
||||
//solium-disable-next-line
|
||||
(bool success, bytes memory result) = liquidationManager.delegatecall(
|
||||
|
@ -638,7 +637,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
_reserves,
|
||||
_usersConfig[user],
|
||||
_reservesList,
|
||||
ADDRESSES_PROVIDER.getPriceOracle()
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
|
||||
|
@ -657,7 +656,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
uint256 currentStableDebt,
|
||||
uint256 currentVariableDebt,
|
||||
uint256 principalStableDebt,
|
||||
uint256 variableBorrowIndex,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 liquidityRate,
|
||||
|
@ -669,7 +667,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
|
||||
currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user);
|
||||
(currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve);
|
||||
(principalStableDebt, principalVariableDebt) = Helpers.getUserPrincipalDebt(user, reserve);
|
||||
principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user);
|
||||
scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user);
|
||||
liquidityRate = reserve.currentLiquidityRate;
|
||||
stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user);
|
||||
|
@ -677,7 +675,6 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
user
|
||||
);
|
||||
usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id);
|
||||
variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(user);
|
||||
}
|
||||
|
||||
function getReserves() external override view returns (address[] memory) {
|
||||
|
@ -784,7 +781,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
_reserves,
|
||||
_usersConfig[user],
|
||||
_reservesList,
|
||||
ADDRESSES_PROVIDER.getPriceOracle()
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -799,7 +796,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
* @dev returns the addresses provider
|
||||
**/
|
||||
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) {
|
||||
return ADDRESSES_PROVIDER;
|
||||
return _addressesProvider;
|
||||
}
|
||||
|
||||
// internal functions
|
||||
|
@ -822,7 +819,7 @@ contract LendingPool is VersionedInitializable, ILendingPool {
|
|||
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
|
||||
UserConfiguration.Map storage userConfig = _usersConfig[msg.sender];
|
||||
|
||||
address oracle = ADDRESSES_PROVIDER.getPriceOracle();
|
||||
address oracle = _addressesProvider.getPriceOracle();
|
||||
|
||||
uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
|
||||
10**reserve.configuration.getDecimals()
|
||||
|
|
|
@ -234,8 +234,6 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
//update the principal reserve
|
||||
principalReserve.updateState();
|
||||
|
||||
|
||||
|
||||
principalReserve.updateInterestRates(
|
||||
principal,
|
||||
principalReserve.aTokenAddress,
|
||||
|
@ -244,29 +242,19 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
);
|
||||
|
||||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||
|
||||
address tokenAddress = principalReserve.variableDebtTokenAddress;
|
||||
|
||||
_mintToReserveTreasury(principalReserve, user, tokenAddress);
|
||||
|
||||
IVariableDebtToken(tokenAddress).burn(
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate
|
||||
vars.actualAmountToLiquidate,
|
||||
principalReserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
|
||||
address tokenAddress = principalReserve.variableDebtTokenAddress;
|
||||
|
||||
_mintToReserveTreasury(principalReserve, user, tokenAddress);
|
||||
|
||||
IVariableDebtToken(tokenAddress).burn(
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.userVariableDebt
|
||||
vars.userVariableDebt,
|
||||
principalReserve.variableBorrowIndex
|
||||
);
|
||||
|
||||
tokenAddress = principalReserve.stableDebtTokenAddress;
|
||||
|
||||
IStableDebtToken(tokenAddress).burn(
|
||||
IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
||||
);
|
||||
|
@ -288,7 +276,12 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
);
|
||||
|
||||
//burn the equivalent amount of atoken
|
||||
vars.collateralAtoken.burn(user, msg.sender, vars.maxCollateralToLiquidate, collateralReserve.liquidityIndex);
|
||||
vars.collateralAtoken.burn(
|
||||
user,
|
||||
msg.sender,
|
||||
vars.maxCollateralToLiquidate,
|
||||
collateralReserve.liquidityIndex
|
||||
);
|
||||
}
|
||||
|
||||
//transfers the principal currency to the aToken
|
||||
|
@ -408,7 +401,12 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
//updating collateral reserve indexes
|
||||
collateralReserve.updateState();
|
||||
|
||||
vars.collateralAtoken.burn(user, receiver, vars.maxCollateralToLiquidate, collateralReserve.liquidityIndex);
|
||||
vars.collateralAtoken.burn(
|
||||
user,
|
||||
receiver,
|
||||
vars.maxCollateralToLiquidate,
|
||||
collateralReserve.liquidityIndex
|
||||
);
|
||||
|
||||
if (vars.userCollateralBalance == vars.maxCollateralToLiquidate) {
|
||||
usersConfig[user].setUsingAsCollateral(collateralReserve.id, false);
|
||||
|
@ -433,10 +431,15 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate
|
||||
vars.actualAmountToLiquidate,
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(user, vars.userVariableDebt);
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.userVariableDebt,
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
IStableDebtToken(debtReserve.stableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
||||
|
@ -530,19 +533,4 @@ contract LendingPoolLiquidationManager is VersionedInitializable {
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,21 +26,4 @@ library Helpers {
|
|||
DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev fetches the user principal stable and variable debt balances
|
||||
* @param user the user
|
||||
* @param reserve the reserve object
|
||||
* @return the stable and variable debt balance
|
||||
**/
|
||||
function getUserPrincipalDebt(address user, ReserveLogic.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(reserve.stableDebtTokenAddress).principalBalanceOf(user),
|
||||
DebtTokenBase(reserve.variableDebtTokenAddress).principalBalanceOf(user)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,13 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
|||
import {MathUtils} from '../math/MathUtils.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {IAToken} from '../../tokenization/interfaces/IAToken.sol';
|
||||
import {IStableDebtToken} from '../../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
|
||||
/**
|
||||
|
@ -21,6 +23,7 @@ import {Errors} from '../helpers/Errors.sol';
|
|||
library ReserveLogic {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/**
|
||||
|
@ -63,14 +66,12 @@ library ReserveLogic {
|
|||
//the current stable borrow rate. Expressed in ray
|
||||
uint128 currentStableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
|
||||
//tokens addresses
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
//address of the interest rate strategy
|
||||
address interestRateStrategyAddress;
|
||||
|
||||
//the id of the reserve. Represents the position in the list of the active reserves
|
||||
uint8 id;
|
||||
}
|
||||
|
@ -127,8 +128,14 @@ library ReserveLogic {
|
|||
* @param reserve the reserve object
|
||||
**/
|
||||
function updateState(ReserveData storage reserve) internal {
|
||||
_mintToTreasury(reserve);
|
||||
_updateIndexes(reserve);
|
||||
address stableDebtToken = reserve.stableDebtTokenAddress;
|
||||
address variableDebtToken = reserve.variableDebtTokenAddress;
|
||||
uint256 variableBorrowIndex = reserve.variableBorrowIndex;
|
||||
uint256 liquidityIndex = reserve.liquidityIndex;
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
_mintToTreasury(reserve, stableDebtToken, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp);
|
||||
_updateIndexes(reserve, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,28 +250,70 @@ library ReserveLogic {
|
|||
);
|
||||
}
|
||||
|
||||
function _mintToTreasury(ReserveData storage reserve) internal {
|
||||
|
||||
address stableDebtToken = reserve.stableDebtTokenAddress;
|
||||
address variableDebtToken = reserve.variableDebtTokenAddress;
|
||||
struct MintToTreasuryLocalVars {
|
||||
uint256 currentTotalDebt;
|
||||
uint256 principalStableDebt;
|
||||
uint256 avgStableRate;
|
||||
uint256 scaledVariableDebt;
|
||||
uint256 cumulatedStableInterest;
|
||||
uint256 variableDebtOnLastUpdate;
|
||||
uint256 stableDebtOnLastUpdate;
|
||||
uint256 totalInterestAccrued;
|
||||
uint256 amountToMint;
|
||||
uint256 reserveFactor;
|
||||
}
|
||||
|
||||
uint256 currentVariableDebt = IERC20(variableDebtToken).totalSupply();
|
||||
uint256 currentStableDebt = IERC20(stableDebtToken).totalSupply();
|
||||
function _mintToTreasury(
|
||||
ReserveData storage reserve,
|
||||
address stableDebtToken,
|
||||
address variableDebtToken,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex,
|
||||
uint40 lastUpdateTimestamp
|
||||
) internal {
|
||||
|
||||
MintToTreasuryLocalVars memory vars;
|
||||
|
||||
uint256 principalStableDebt = IStableDebtToken(stableDebtToken).principalTotalSupply();
|
||||
uint256 scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply();
|
||||
|
||||
|
||||
|
||||
vars.reserveFactor = reserve.configuration.getReserveFactor();
|
||||
|
||||
if(vars.reserveFactor == 0){
|
||||
return;
|
||||
}
|
||||
|
||||
vars.currentTotalDebt = IERC20(variableDebtToken).totalSupply().add(IERC20(stableDebtToken).totalSupply());
|
||||
|
||||
(vars.principalStableDebt, vars.avgStableRate) = IStableDebtToken(stableDebtToken)
|
||||
.getPrincipalSupplyAndAvgRate();
|
||||
|
||||
vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply();
|
||||
|
||||
vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest(
|
||||
vars.avgStableRate,
|
||||
lastUpdateTimestamp
|
||||
);
|
||||
|
||||
vars.variableDebtOnLastUpdate = vars.scaledVariableDebt.rayMul(variableBorrowIndex);
|
||||
vars.stableDebtOnLastUpdate = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest);
|
||||
|
||||
vars.totalInterestAccrued =vars.currentTotalDebt.sub(vars.variableDebtOnLastUpdate.add(vars.stableDebtOnLastUpdate));
|
||||
|
||||
vars.amountToMint = vars.totalInterestAccrued.percentMul(vars.reserveFactor);
|
||||
|
||||
IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, liquidityIndex);
|
||||
|
||||
}
|
||||
|
||||
function _updateIndexes(ReserveData storage reserve) internal {
|
||||
function _updateIndexes(
|
||||
ReserveData storage reserve,
|
||||
address variableDebtToken,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex,
|
||||
uint40 lastUpdateTimestamp
|
||||
) internal {
|
||||
uint256 currentLiquidityRate = reserve.currentLiquidityRate;
|
||||
|
||||
//only cumulating if there is any income being produced
|
||||
if (currentLiquidityRate > 0) {
|
||||
uint40 lastUpdateTimestamp = reserve.lastUpdateTimestamp;
|
||||
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
|
||||
currentLiquidityRate,
|
||||
lastUpdateTimestamp
|
||||
|
@ -276,12 +325,12 @@ library ReserveLogic {
|
|||
|
||||
//as the liquidity rate might come only from stable rate loans, we need to ensure
|
||||
//that there is actual variable debt before accumulating
|
||||
if (IERC20(reserve.variableDebtTokenAddress).totalSupply() > 0) {
|
||||
if (IERC20(variableDebtToken).totalSupply() > 0) {
|
||||
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
|
||||
reserve.currentVariableBorrowRate,
|
||||
lastUpdateTimestamp
|
||||
);
|
||||
index = cumulatedVariableBorrowInterest.rayMul(reserve.variableBorrowIndex);
|
||||
index = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex);
|
||||
require(index < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW);
|
||||
reserve.variableBorrowIndex = uint128(index);
|
||||
}
|
||||
|
|
|
@ -105,8 +105,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
|
|||
emit Mint(user, amount, index);
|
||||
}
|
||||
|
||||
function mintToReserve(uint256 amount) external override onlyLendingPool {
|
||||
uint256 index = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
|
||||
function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool {
|
||||
_mint(RESERVE_TREASURY_ADDRESS, amount.div(index));
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @return the accumulated debt of the user
|
||||
**/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
uint256 accountBalance = principalBalanceOf(account);
|
||||
uint256 accountBalance = super.balanceOf(account);
|
||||
uint256 stableRate = _usersData[account];
|
||||
if (accountBalance == 0) {
|
||||
return 0;
|
||||
|
@ -125,7 +125,6 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
//solium-disable-next-line
|
||||
_totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp);
|
||||
|
||||
|
||||
//calculates the updated average stable rate
|
||||
_avgStableRate = _avgStableRate
|
||||
.rayMul(vars.supplyBeforeMint.wadToRay())
|
||||
|
@ -185,15 +184,22 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
emit BurnDebt(user, amount, previousBalance, currentBalance, balanceIncrease);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Calculates the increase in balance since the last user interaction
|
||||
* @param user The address of the user for which the interest is being accumulated
|
||||
* @return The previous principal balance, the new principal balance, the balance increase
|
||||
* and the new user index
|
||||
**/
|
||||
function _calculateBalanceIncrease(address user) internal view returns (uint256, uint256, uint256) {
|
||||
uint256 previousPrincipalBalance = principalBalanceOf(user);
|
||||
function _calculateBalanceIncrease(address user)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
uint256
|
||||
)
|
||||
{
|
||||
uint256 previousPrincipalBalance = super.balanceOf(user);
|
||||
|
||||
if (previousPrincipalBalance == 0) {
|
||||
return (0, 0, 0);
|
||||
|
@ -209,11 +215,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
);
|
||||
}
|
||||
|
||||
function principalTotalSupply() public override view returns(uint256) {
|
||||
return super.totalSupply();
|
||||
function getPrincipalSupplyAndAvgRate() public override view returns (uint256, uint256) {
|
||||
return (super.totalSupply(), _avgStableRate);
|
||||
}
|
||||
|
||||
function totalSupply() public override view returns(uint256) {
|
||||
|
||||
function totalSupply() public override view returns (uint256) {
|
||||
uint256 principalSupply = super.totalSupply();
|
||||
if (principalSupply == 0) {
|
||||
return 0;
|
||||
|
@ -225,4 +231,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
return principalSupply.rayMul(cumulatedInterest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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) external virtual override view returns (uint256) {
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @return the debt balance of the user
|
||||
**/
|
||||
function balanceOf(address user) public virtual override view returns (uint256) {
|
||||
uint256 scaledBalance = super.principalBalanceOf(user);
|
||||
uint256 scaledBalance = super.balanceOf(user);
|
||||
|
||||
if (scaledBalance == 0) {
|
||||
return 0;
|
||||
|
|
|
@ -64,14 +64,6 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable {
|
|||
return UNDERLYING_ASSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 view returns (uint256) {
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Being non transferrable, the debt token does not implement any of the
|
||||
* standard ERC20 functions for transfer and allowance.
|
||||
|
|
|
@ -62,12 +62,11 @@ interface IAToken is IERC20 {
|
|||
function mint(address user, uint256 amount, uint256 index) 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 mints aTokens to the reserve treasury
|
||||
* @param amount the amount to mint
|
||||
* @param index the liquidity index of the reserve
|
||||
**/
|
||||
function mintToTreasury(uint256 amount, uint256 index) external;
|
||||
|
||||
/**
|
||||
* @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken
|
||||
|
@ -104,6 +103,7 @@ interface IAToken is IERC20 {
|
|||
* @param amount the amount to transfer
|
||||
* @return the amount transferred
|
||||
**/
|
||||
|
||||
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -86,7 +86,14 @@ interface IStableDebtToken {
|
|||
function getUserLastUpdated(address user) external view returns (uint40);
|
||||
|
||||
/**
|
||||
* @dev returns the principal total supply
|
||||
* @dev returns the principal total supply and the average stable rate
|
||||
**/
|
||||
function principalTotalSupply() external view returns (uint40);
|
||||
function getPrincipalSupplyAndAvgRate() external view returns (uint256, uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the principal debt balance of the user
|
||||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function principalBalanceOf(address user) external view returns (uint256);
|
||||
|
||||
}
|
||||
|
|
|
@ -273,19 +273,16 @@ export const calcExpectedReserveDataAfterBorrow = (
|
|||
|
||||
const amountBorrowedBN = new BigNumber(amountBorrowed);
|
||||
|
||||
const userStableBorrowBalance = calcExpectedStableDebtTokenBalance(
|
||||
userDataBeforeAction,
|
||||
txTimestamp
|
||||
);
|
||||
const userStableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp);
|
||||
|
||||
const userVariableBorrowBalance = calcExpectedVariableDebtTokenBalance(
|
||||
const userVariableDebt = calcExpectedVariableDebtTokenBalance(
|
||||
reserveDataBeforeAction,
|
||||
userDataBeforeAction,
|
||||
txTimestamp
|
||||
);
|
||||
|
||||
if (borrowRateMode == RateMode.Stable) {
|
||||
const debtAccrued = userStableBorrowBalance.minus(userDataBeforeAction.principalStableDebt);
|
||||
const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt);
|
||||
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
|
||||
|
@ -301,7 +298,11 @@ export const calcExpectedReserveDataAfterBorrow = (
|
|||
);
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable;
|
||||
} else {
|
||||
const debtAccrued = userVariableBorrowBalance.minus(userDataBeforeAction.principalVariableDebt);
|
||||
const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul(
|
||||
reserveDataBeforeAction.variableBorrowIndex
|
||||
);
|
||||
|
||||
const debtAccrued = userVariableDebt.minus(variableDebtBefore);
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable
|
||||
.plus(amountBorrowedBN)
|
||||
|
@ -362,12 +363,9 @@ export const calcExpectedReserveDataAfterRepay = (
|
|||
|
||||
let amountRepaidBN = new BigNumber(amountRepaid);
|
||||
|
||||
const userStableBorrowBalance = calcExpectedStableDebtTokenBalance(
|
||||
userDataBeforeAction,
|
||||
txTimestamp
|
||||
);
|
||||
const userStableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp);
|
||||
|
||||
const userVariableBorrowBalance = calcExpectedVariableDebtTokenBalance(
|
||||
const userVariableDebt = calcExpectedVariableDebtTokenBalance(
|
||||
reserveDataBeforeAction,
|
||||
userDataBeforeAction,
|
||||
txTimestamp
|
||||
|
@ -376,14 +374,14 @@ export const calcExpectedReserveDataAfterRepay = (
|
|||
//if amount repaid = MAX_UINT_AMOUNT, user is repaying everything
|
||||
if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) {
|
||||
if (borrowRateMode == RateMode.Stable) {
|
||||
amountRepaidBN = userStableBorrowBalance;
|
||||
amountRepaidBN = userStableDebt;
|
||||
} else {
|
||||
amountRepaidBN = userVariableBorrowBalance;
|
||||
amountRepaidBN = userVariableDebt;
|
||||
}
|
||||
}
|
||||
|
||||
if (borrowRateMode == RateMode.Stable) {
|
||||
const debtAccrued = userStableBorrowBalance.minus(userDataBeforeAction.principalStableDebt);
|
||||
const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt);
|
||||
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
|
||||
|
@ -399,7 +397,11 @@ export const calcExpectedReserveDataAfterRepay = (
|
|||
);
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable;
|
||||
} else {
|
||||
const debtAccrued = userVariableBorrowBalance.minus(userDataBeforeAction.principalVariableDebt);
|
||||
const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul(
|
||||
reserveDataBeforeAction.variableBorrowIndex
|
||||
);
|
||||
|
||||
const debtAccrued = userVariableDebt.minus(variableDebtBefore);
|
||||
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
|
||||
|
@ -477,7 +479,7 @@ export const calcExpectedUserDataAfterBorrow = (
|
|||
const debtAccrued = currentStableDebt.minus(userDataBeforeAction.principalStableDebt);
|
||||
|
||||
expectedUserData.principalStableDebt = currentStableDebt.plus(amountBorrowed);
|
||||
expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt;
|
||||
expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
|
||||
|
||||
expectedUserData.stableBorrowRate = calcExpectedUserStableRate(
|
||||
userDataBeforeAction.principalStableDebt.plus(debtAccrued),
|
||||
|
@ -510,8 +512,8 @@ export const calcExpectedUserDataAfterBorrow = (
|
|||
expectedDataAfterAction,
|
||||
{
|
||||
...userDataBeforeAction,
|
||||
currentVariableDebt: expectedUserData.principalVariableDebt,
|
||||
principalVariableDebt: expectedUserData.principalVariableDebt,
|
||||
currentVariableDebt: expectedUserData.scaledVariableDebt.rayMul(reserveDataBeforeAction.variableBorrowIndex),
|
||||
scaledVariableDebt: expectedUserData.scaledVariableDebt,
|
||||
variableBorrowIndex:
|
||||
interestRateMode == RateMode.Variable
|
||||
? expectedDataAfterAction.variableBorrowIndex
|
||||
|
@ -520,7 +522,7 @@ export const calcExpectedUserDataAfterBorrow = (
|
|||
currentTimestamp
|
||||
);
|
||||
|
||||
if (expectedUserData.principalVariableDebt.eq(0)) {
|
||||
if (expectedUserData.scaledVariableDebt.eq(0)) {
|
||||
expectedUserData.variableBorrowIndex = new BigNumber(0);
|
||||
} else {
|
||||
expectedUserData.variableBorrowIndex =
|
||||
|
@ -539,7 +541,7 @@ export const calcExpectedUserDataAfterBorrow = (
|
|||
currentTimestamp
|
||||
);
|
||||
expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
|
||||
|
||||
|
||||
expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed);
|
||||
|
||||
return expectedUserData;
|
||||
|
@ -623,7 +625,7 @@ export const calcExpectedUserDataAfterRepay = (
|
|||
txTimestamp
|
||||
);
|
||||
expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance;
|
||||
|
||||
|
||||
if (user === onBehalfOf) {
|
||||
expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaid);
|
||||
} else {
|
||||
|
@ -657,51 +659,52 @@ export const calcExpectedReserveDataAfterSwapRateMode = (
|
|||
|
||||
expectedReserveData.address = reserveDataBeforeAction.address;
|
||||
|
||||
const variableBorrowBalance = calcExpectedVariableDebtTokenBalance(
|
||||
const variableDebt = calcExpectedVariableDebtTokenBalance(
|
||||
reserveDataBeforeAction,
|
||||
userDataBeforeAction,
|
||||
txTimestamp
|
||||
);
|
||||
|
||||
const stableBorrowBalance = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp);
|
||||
const stableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp);
|
||||
|
||||
expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity;
|
||||
|
||||
if (rateMode === RateMode.Stable) {
|
||||
//swap user stable debt to variable
|
||||
const debtAccrued = stableBorrowBalance.minus(userDataBeforeAction.principalStableDebt);
|
||||
const debtAccrued = stableDebt.minus(userDataBeforeAction.principalStableDebt);
|
||||
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
|
||||
expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
|
||||
reserveDataBeforeAction.averageStableBorrowRate,
|
||||
reserveDataBeforeAction.totalBorrowsStable.plus(debtAccrued),
|
||||
stableBorrowBalance.negated(),
|
||||
stableDebt.negated(),
|
||||
userDataBeforeAction.stableBorrowRate
|
||||
);
|
||||
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable.plus(
|
||||
stableBorrowBalance
|
||||
stableDebt
|
||||
);
|
||||
|
||||
expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable.minus(
|
||||
userDataBeforeAction.principalStableDebt
|
||||
);
|
||||
} else {
|
||||
const debtAccrued = variableBorrowBalance.minus(userDataBeforeAction.principalVariableDebt);
|
||||
const totalDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul(reserveDataBeforeAction.variableBorrowIndex);
|
||||
const debtAccrued = variableDebt.minus(totalDebtBefore);
|
||||
|
||||
expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued);
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable.minus(
|
||||
userDataBeforeAction.principalVariableDebt
|
||||
);
|
||||
|
||||
expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable;
|
||||
|
||||
|
||||
expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable.plus(
|
||||
variableBorrowBalance
|
||||
variableDebt
|
||||
);
|
||||
expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
|
||||
reserveDataBeforeAction.averageStableBorrowRate,
|
||||
reserveDataBeforeAction.totalBorrowsStable,
|
||||
variableBorrowBalance,
|
||||
variableDebt,
|
||||
reserveDataBeforeAction.stableBorrowRate
|
||||
);
|
||||
}
|
||||
|
@ -926,9 +929,7 @@ const calcExpectedATokenBalance = (
|
|||
) => {
|
||||
const index = calcExpectedReserveNormalizedIncome(reserveDataBeforeAction, currentTimestamp);
|
||||
|
||||
const {
|
||||
scaledATokenBalance: scaledBalanceBeforeAction,
|
||||
} = userDataBeforeAction;
|
||||
const {scaledATokenBalance: scaledBalanceBeforeAction} = userDataBeforeAction;
|
||||
|
||||
return scaledBalanceBeforeAction.rayMul(index);
|
||||
};
|
||||
|
@ -969,8 +970,7 @@ export const calcExpectedVariableDebtTokenBalance = (
|
|||
) => {
|
||||
const debt = calcExpectedReserveNormalizedDebt(reserveDataBeforeAction, currentTimestamp);
|
||||
|
||||
const { scaledVariableDebt } = userDataBeforeAction;
|
||||
|
||||
const {scaledVariableDebt} = userDataBeforeAction;
|
||||
|
||||
return scaledVariableDebt.rayMul(debt);
|
||||
};
|
||||
|
|
|
@ -79,7 +79,6 @@ export const getUserData = async (
|
|||
currentStableDebt: new BigNumber(userData.currentStableDebt.toString()),
|
||||
currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()),
|
||||
principalStableDebt: new BigNumber(userData.principalStableDebt.toString()),
|
||||
principalVariableDebt: new BigNumber(userData.principalVariableDebt.toString()),
|
||||
scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()),
|
||||
stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()),
|
||||
liquidityRate: new BigNumber(userData.liquidityRate.toString()),
|
||||
|
|
|
@ -6,7 +6,6 @@ export interface UserReserveData {
|
|||
currentStableDebt: BigNumber;
|
||||
currentVariableDebt: BigNumber;
|
||||
principalStableDebt: BigNumber;
|
||||
principalVariableDebt: BigNumber;
|
||||
scaledVariableDebt: BigNumber;
|
||||
liquidityRate: BigNumber;
|
||||
stableBorrowRate: BigNumber;
|
||||
|
|
|
@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine';
|
|||
|
||||
const scenarioFolder = './test/helpers/scenarios/';
|
||||
|
||||
const selectedScenarios: string[] = [''];
|
||||
const selectedScenarios: string[] = ['deposit.json'];
|
||||
|
||||
fs.readdirSync(scenarioFolder).forEach((file) => {
|
||||
if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return;
|
||||
|
|
|
@ -18,7 +18,7 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
|
|||
daiVariableDebtTokenAddress
|
||||
);
|
||||
|
||||
await expect(variableDebtContract.mint(deployer.address, '1')).to.be.revertedWith(
|
||||
await expect(variableDebtContract.mint(deployer.address, '1', '1')).to.be.revertedWith(
|
||||
CALLER_MUST_BE_LENDING_POOL
|
||||
);
|
||||
});
|
||||
|
@ -34,7 +34,7 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
|
|||
daiVariableDebtTokenAddress
|
||||
);
|
||||
|
||||
await expect(variableDebtContract.burn(deployer.address, '1')).to.be.revertedWith(
|
||||
await expect(variableDebtContract.burn(deployer.address, '1', '1')).to.be.revertedWith(
|
||||
CALLER_MUST_BE_LENDING_POOL
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user