Fixed errors

This commit is contained in:
The3D 2020-09-14 15:09:16 +02:00
parent 6e92575ac2
commit bb4e1b5c4b
16 changed files with 189 additions and 164 deletions

View File

@ -326,7 +326,6 @@ interface ILendingPool {
uint256 currentStableDebt,
uint256 currentVariableDebt,
uint256 principalStableDebt,
uint256 principalVariableDebt,
uint256 scaledVariableDebt,
uint256 stableBorrowRate,
uint256 liquidityRate,

View File

@ -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()

View File

@ -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);
}
}
}

View File

@ -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)
);
}
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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()),

View File

@ -6,7 +6,6 @@ export interface UserReserveData {
currentStableDebt: BigNumber;
currentVariableDebt: BigNumber;
principalStableDebt: BigNumber;
principalVariableDebt: BigNumber;
scaledVariableDebt: BigNumber;
liquidityRate: BigNumber;
stableBorrowRate: BigNumber;

View File

@ -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;

View File

@ -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
);
});