From 3df87a8e5d8f289c80612cbe756f66900c2874e9 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 11:25:45 +0200 Subject: [PATCH 01/79] Initial commit --- contracts/tokenization/StableDebtToken.sol | 25 ++++++++ contracts/tokenization/VariableDebtToken.sol | 62 ++++--------------- contracts/tokenization/base/DebtTokenBase.sol | 23 ------- .../interfaces/IVariableDebtToken.sol | 12 ---- 4 files changed, 38 insertions(+), 84 deletions(-) diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 4fdcad09..a30219e3 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -182,4 +182,29 @@ 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); + + if (previousPrincipalBalance == 0) { + return (0, 0, 0); + } + + // Calculation of the accrued interest since the last accumulation + uint256 balanceIncrease = balanceOf(user).sub(previousPrincipalBalance); + + return ( + previousPrincipalBalance, + previousPrincipalBalance.add(balanceIncrease), + balanceIncrease + ); + } + } diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 580151eb..1fcda07a 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -38,27 +38,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @return the debt balance of the user **/ function balanceOf(address user) public virtual override view returns (uint256) { - uint256 userBalance = principalBalanceOf(user); - uint256 index = _usersData[user]; - if (userBalance == 0) { + uint256 scaledBalance = principalBalanceOf(user); + + if (scaledBalance == 0) { return 0; } return - userBalance - .wadToRay() - .rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)) - .rayDiv(index) - .rayToWad(); - } - - /** - * @dev returns the index of the last user action - * @return the user index - **/ - - function getUserIndex(address user) external virtual override view returns (uint256) { - return _usersData[user]; + scaledBalance + .rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); } /** @@ -66,20 +54,12 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @param user the user receiving the debt * @param amount the amount of debt being minted **/ - function mint(address user, uint256 amount) external override onlyLendingPool { - ( - uint256 previousBalance, - uint256 currentBalance, - uint256 balanceIncrease - ) = _calculateBalanceIncrease(user); + function mint(address user, uint256 amount) external override onlyLendingPool { + + uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); - _mint(user, amount.add(balanceIncrease)); - - uint256 newUserIndex = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); - require(newUserIndex < (1 << 128), "Debt token: Index overflow"); - _usersData[user] = newUserIndex; - - emit MintDebt(user, amount, previousBalance, currentBalance, balanceIncrease, newUserIndex); + _mint(user, amount.rayDiv(index)); + emit MintDebt(user, amount, index); } /** @@ -88,26 +68,10 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @param amount the amount of debt being burned **/ function burn(address user, uint256 amount) external override onlyLendingPool { - ( - uint256 previousBalance, - uint256 currentBalance, - uint256 balanceIncrease - ) = _calculateBalanceIncrease(user); - if (balanceIncrease > amount) { - _mint(user, balanceIncrease.sub(amount)); - } else { - _burn(user, amount.sub(balanceIncrease)); - } + uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); + _burn(user, amount.rayDiv(index)); - uint256 newUserIndex = 0; - //if user not repaid everything - if (currentBalance != amount) { - newUserIndex = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); - require(newUserIndex < (1 << 128), "Debt token: Index overflow"); - } - _usersData[user] = newUserIndex; - - emit BurnDebt(user, amount, previousBalance, currentBalance, balanceIncrease, newUserIndex); + emit BurnDebt(user, amount, index); } } diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index 04009023..ec021951 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -104,27 +104,4 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable { spender; subtractedValue; revert('ALLOWANCE_NOT_SUPPORTED'); } - - /** - * @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); - - if (previousPrincipalBalance == 0) { - return (0, 0, 0); - } - - // Calculation of the accrued interest since the last accumulation - uint256 balanceIncrease = balanceOf(user).sub(previousPrincipalBalance); - - return ( - previousPrincipalBalance, - previousPrincipalBalance.add(balanceIncrease), - balanceIncrease - ); - } } diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index fdd86a0d..e979b4a5 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -12,17 +12,11 @@ interface IVariableDebtToken { * @dev emitted when new variable debt is minted * @param user the user receiving the debt * @param amount the amount of debt being minted - * @param previousBalance the previous balance of the user - * @param currentBalance the current balance of the user - * @param balanceIncrease the debt accumulated since the last action * @param index the index of the user **/ event MintDebt( address user, uint256 amount, - uint256 previousBalance, - uint256 currentBalance, - uint256 balanceIncrease, uint256 index ); @@ -30,17 +24,11 @@ interface IVariableDebtToken { * @dev emitted when variable debt is burnt * @param user the user which debt has been burned * @param amount the amount of debt being burned - * @param previousBalance the previous balance of the user - * @param currentBalance the current balance of the user - * @param balanceIncrease the debt accumulated since the last action * @param index the index of the user **/ event BurnDebt( address user, uint256 amount, - uint256 previousBalance, - uint256 currentBalance, - uint256 balanceIncrease, uint256 index ); From 4a1e1156f48447526e38d194d8a217a8cdb626ca Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 12:51:52 +0200 Subject: [PATCH 02/79] Merge local branch --- contracts/interfaces/ILendingPool.sol | 1 - .../IReserveInterestRateStrategy.sol | 3 +- .../DefaultReserveInterestRateStrategy.sol | 48 ++++++++++++------- contracts/lendingpool/LendingPool.sol | 44 +++++++++++++++-- .../LendingPoolLiquidationManager.sol | 38 +++++++++++++-- .../configuration/ReserveConfiguration.sol | 19 ++++++++ contracts/libraries/logic/ReserveLogic.sol | 3 +- contracts/mocks/upgradeability/MockAToken.sol | 2 +- contracts/tokenization/AToken.sol | 8 ++++ contracts/tokenization/VariableDebtToken.sol | 12 ++++- contracts/tokenization/base/DebtTokenBase.sol | 2 +- contracts/tokenization/interfaces/IAToken.sol | 8 ++++ .../interfaces/IVariableDebtToken.sol | 5 -- 13 files changed, 158 insertions(+), 35 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index a7a5e1ca..12119a3a 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -305,7 +305,6 @@ interface ILendingPool { uint256 principalVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, - uint256 variableBorrowIndex, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ); diff --git a/contracts/interfaces/IReserveInterestRateStrategy.sol b/contracts/interfaces/IReserveInterestRateStrategy.sol index 48311e70..acc097bf 100644 --- a/contracts/interfaces/IReserveInterestRateStrategy.sol +++ b/contracts/interfaces/IReserveInterestRateStrategy.sol @@ -23,7 +23,8 @@ interface IReserveInterestRateStrategy { uint256 utilizationRate, uint256 totalBorrowsStable, uint256 totalBorrowsVariable, - uint256 averageStableBorrowRate + uint256 averageStableBorrowRate, + uint256 reserveFactor ) external view diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol index c2303254..c93e6c38 100644 --- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol @@ -49,6 +49,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { //slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray uint256 internal immutable _stableRateSlope2; + constructor( LendingPoolAddressesProvider provider, uint256 baseVariableBorrowRate, @@ -89,6 +90,15 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { return _baseVariableBorrowRate; } + struct CalcInterestRatesLocalVars { + + uint256 totalBorrows; + uint256 currentVariableBorrowRate; + uint256 currentStableBorrowRate; + uint256 currentLiquidityRate; + uint256 utilizationRate; + } + /** * @dev calculates the interest rates depending on the available liquidity and the total borrowed. * @param reserve the address of the reserve @@ -96,6 +106,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { * @param totalBorrowsStable the total borrowed from the reserve a stable rate * @param totalBorrowsVariable the total borrowed from the reserve at a variable rate * @param averageStableBorrowRate the weighted average of all the stable rate borrows + * @param reserveFactor the reserve portion of the interest to redirect to the reserve treasury * @return currentLiquidityRate the liquidity rate * @return currentStableBorrowRate stable borrow rate * @return currentVariableBorrowRate variable borrow rate @@ -105,7 +116,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { uint256 availableLiquidity, uint256 totalBorrowsStable, uint256 totalBorrowsVariable, - uint256 averageStableBorrowRate + uint256 averageStableBorrowRate, + uint256 reserveFactor ) external override @@ -116,16 +128,19 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { uint256 ) { - uint256 totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); - uint256 currentVariableBorrowRate = 0; - uint256 currentStableBorrowRate = 0; - uint256 currentLiquidityRate = 0; - uint256 utilizationRate = totalBorrows == 0 + CalcInterestRatesLocalVars memory vars; + + vars.totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); + vars.currentVariableBorrowRate = 0; + vars.currentStableBorrowRate = 0; + vars.currentLiquidityRate = 0; + + uint256 utilizationRate = vars.totalBorrows == 0 ? 0 - : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows)); + : vars.totalBorrows.rayDiv(availableLiquidity.add(vars.totalBorrows)); - currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle()) + vars.currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle()) .getMarketBorrowRate(reserve); if (utilizationRate > OPTIMAL_UTILIZATION_RATE) { @@ -133,31 +148,32 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { EXCESS_UTILIZATION_RATE ); - currentStableBorrowRate = currentStableBorrowRate.add(_stableRateSlope1).add( + vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(_stableRateSlope1).add( _stableRateSlope2.rayMul(excessUtilizationRateRatio) ); - currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add( + vars.currentVariableBorrowRate = _baseVariableBorrowRate.add(_variableRateSlope1).add( _variableRateSlope2.rayMul(excessUtilizationRateRatio) ); } else { - currentStableBorrowRate = currentStableBorrowRate.add( + vars.currentStableBorrowRate = vars.currentStableBorrowRate.add( _stableRateSlope1.rayMul(utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE)) ); - currentVariableBorrowRate = _baseVariableBorrowRate.add( + vars.currentVariableBorrowRate = _baseVariableBorrowRate.add( utilizationRate.rayDiv(OPTIMAL_UTILIZATION_RATE).rayMul(_variableRateSlope1) ); } - currentLiquidityRate = _getOverallBorrowRate( + vars.currentLiquidityRate = _getOverallBorrowRate( totalBorrowsStable, totalBorrowsVariable, - currentVariableBorrowRate, + vars.currentVariableBorrowRate, averageStableBorrowRate ) - .rayMul(utilizationRate); + .rayMul(utilizationRate) + .rayMul(WadRayMath.ray().sub(reserveFactor)); - return (currentLiquidityRate, currentStableBorrowRate, currentVariableBorrowRate); + return (vars.currentLiquidityRate, vars.currentStableBorrowRate, vars.currentVariableBorrowRate); } /** diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 9e4e6707..50944f9f 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -12,6 +12,7 @@ import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; +import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; @@ -19,12 +20,12 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; +import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol'; import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol'; import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; - /** * @title LendingPool contract * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data @@ -34,6 +35,7 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol'; contract LendingPool is VersionedInitializable, ILendingPool { using SafeMath for uint256; using WadRayMath for uint256; + using PercentageMath for uint256; using ReserveLogic for ReserveLogic.ReserveData; using ReserveConfiguration for ReserveConfiguration.Map; using UserConfiguration for UserConfiguration.Map; @@ -224,6 +226,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, onBehalfOf, debtTokenAddress); + //burns an equivalent amount of debt tokens if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); @@ -265,6 +270,10 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, msg.sender, debtTokenAddress); + + if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { //burn stable rate tokens, mint variable rate tokens IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); @@ -321,6 +330,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); + _mintToReserveTreasury(reserve, user, address(stableDebtToken)); + + stableDebtToken.burn(user, stableBorrowBalance); stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); @@ -609,7 +621,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 principalVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, - uint256 variableBorrowIndex, uint40 stableRateLastUpdated, bool usageAsCollateralEnabled ) @@ -625,7 +636,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { user ); usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.index); - variableBorrowIndex = IVariableDebtToken(reserve.variableDebtTokenAddress).getUserIndex(user); } function getReserves() external override view returns (address[] memory) { @@ -706,6 +716,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { * @param vars Input struct for the borrowing action, in order to avoid STD errors **/ function _executeBorrow(ExecuteBorrowParams memory vars) internal { + ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; UserConfiguration.Map storage userConfig = _usersConfig[msg.sender]; @@ -730,13 +741,21 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 reserveIndex = reserve.index; + if (!userConfig.isBorrowing(reserveIndex)) { userConfig.setBorrowing(reserveIndex, true); } + address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE ? + reserve.stableDebtTokenAddress + : + reserve.variableDebtTokenAddress; + reserve.updateCumulativeIndexesAndTimestamp(); + _mintToReserveTreasury(reserve, vars.user, debtTokenAddress); + //caching the current stable borrow rate uint256 currentStableRate = 0; @@ -745,13 +764,13 @@ contract LendingPool is VersionedInitializable, ILendingPool { ) { currentStableRate = reserve.currentStableBorrowRate; - IStableDebtToken(reserve.stableDebtTokenAddress).mint( + IStableDebtToken(debtTokenAddress).mint( vars.user, vars.amount, currentStableRate ); } else { - IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount); + IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount); } reserve.updateInterestRates(vars.asset, vars.aTokenAddress, 0, vars.releaseUnderlying ? vars.amount : 0); @@ -848,4 +867,19 @@ contract LendingPool is VersionedInitializable, ILendingPool { function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { return _addressesProvider; } + + function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal { + + uint256 currentPrincipalBalance = DebtTokenBase(debtTokenAddress).principalBalanceOf(user); + //calculating the interest accrued since the last borrow and minting the equivalent amount to the reserve factor + if(currentPrincipalBalance > 0){ + + uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub(currentPrincipalBalance); + + uint256 amountForReserveFactor = balanceIncrease.percentMul(reserve.configuration.getReserveFactor()); + + IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); + } + + } } diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol index 12ecf777..dee6d90c 100644 --- a/contracts/lendingpool/LendingPoolLiquidationManager.sol +++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol @@ -10,6 +10,7 @@ import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddresse import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; +import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; @@ -208,6 +209,9 @@ contract LendingPoolLiquidationManager is VersionedInitializable { //update the principal reserve principalReserve.updateCumulativeIndexesAndTimestamp(); + + + principalReserve.updateInterestRates( principal, principalReserve.aTokenAddress, @@ -216,16 +220,29 @@ contract LendingPoolLiquidationManager is VersionedInitializable { ); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + + address tokenAddress = principalReserve.variableDebtTokenAddress; + + _mintToReserveTreasury(principalReserve, user, tokenAddress); + + IVariableDebtToken(tokenAddress).burn( user, vars.actualAmountToLiquidate ); } else { - IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn( + + address tokenAddress = principalReserve.variableDebtTokenAddress; + + _mintToReserveTreasury(principalReserve, user, tokenAddress); + + IVariableDebtToken(tokenAddress).burn( user, vars.userVariableDebt ); - IStableDebtToken(principalReserve.stableDebtTokenAddress).burn( + + tokenAddress = principalReserve.stableDebtTokenAddress; + + IStableDebtToken(tokenAddress).burn( user, vars.actualAmountToLiquidate.sub(vars.userVariableDebt) ); @@ -337,4 +354,19 @@ 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); + } + + } } diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 46ad9ba9..96c0024c 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -21,6 +21,7 @@ library ReserveConfiguration { uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF; uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF; uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF; + uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF; struct Map { //bit 0-15: LTV @@ -31,9 +32,27 @@ library ReserveConfiguration { //bit 57: reserve is freezed //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled + //bit 64-79: reserve factor uint256 data; } + /** + * @dev sets the reserve factor of the reserve + * @param self the reserve configuration + * @param ltv the new ltv + **/ + function setReserveFactor(ReserveConfiguration.Map memory self, uint256 ltv) internal pure { + self.data = (self.data & RESERVE_FACTOR_MASK) | ltv; + } + + /** + * @dev gets the reserve factor of the reserve + * @param self the reserve configuration + * @return the reserve factor + **/ + function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { + return self.data & ~RESERVE_FACTOR_MASK; + } /** * @dev sets the Loan to Value of the reserve * @param self the reserve configuration diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 607c8c63..90ed10cf 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -246,7 +246,8 @@ library ReserveLogic { vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken), IERC20(vars.stableDebtTokenAddress).totalSupply(), IERC20(reserve.variableDebtTokenAddress).totalSupply(), - vars.currentAvgStableRate + vars.currentAvgStableRate, + reserve.configuration.getReserveFactor() ); require(vars.newLiquidityRate < (1 << 128), "ReserveLogic: Liquidity rate overflow"); require(vars.newStableRate < (1 << 128), "ReserveLogic: Stable borrow rate overflow"); diff --git a/contracts/mocks/upgradeability/MockAToken.sol b/contracts/mocks/upgradeability/MockAToken.sol index 05f0db4e..a0368535 100644 --- a/contracts/mocks/upgradeability/MockAToken.sol +++ b/contracts/mocks/upgradeability/MockAToken.sol @@ -10,7 +10,7 @@ contract MockAToken is AToken { address _underlyingAssetAddress, string memory _tokenName, string memory _tokenSymbol - ) public AToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol) {} + ) public AToken(_pool, _underlyingAssetAddress,address(0), _tokenName, _tokenSymbol) {} function getRevision() internal override pure returns (uint256) { return 0x2; diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index de178819..36ca5ecb 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -25,6 +25,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken { uint256 public constant UINT_MAX_VALUE = uint256(-1); address public immutable UNDERLYING_ASSET_ADDRESS; + address public immutable RESERVE_TREASURY_ADDRESS; mapping(address => uint256) private _userIndexes; mapping(address => address) private _interestRedirectionAddresses; @@ -48,11 +49,13 @@ contract AToken is VersionedInitializable, ERC20, IAToken { constructor( LendingPool pool, address underlyingAssetAddress, + address reserveTreasuryAddress, string memory tokenName, string memory tokenSymbol ) public ERC20(tokenName, tokenSymbol, 18) { _pool = pool; UNDERLYING_ASSET_ADDRESS = underlyingAssetAddress; + RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress; } function getRevision() internal virtual override pure returns (uint256) { @@ -183,6 +186,11 @@ contract AToken is VersionedInitializable, ERC20, IAToken { emit Mint(user, amount, balanceIncrease, index); } + function mintToReserve(uint256 amount) external override onlyLendingPool { + uint256 index = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS); + _mint(RESERVE_TREASURY_ADDRESS, amount.div(index)); + } + /** * @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * only lending pools can call this function diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 1fcda07a..80f626f9 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -17,6 +17,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { using WadRayMath for uint256; uint256 public constant DEBT_TOKEN_REVISION = 0x1; + mapping(address => uint256) _userIndexes; constructor( address pool, @@ -59,6 +60,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); _mint(user, amount.rayDiv(index)); + _userIndexes[user] = index; emit MintDebt(user, amount, index); } @@ -71,7 +73,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); _burn(user, amount.rayDiv(index)); - + _userIndexes[user] = index; emit BurnDebt(user, amount, index); } + + /** + * @dev Returns the principal debt balance of the user from + * @return The debt balance of the user since the last burn/mint action + **/ + function principalBalanceOf(address user) public virtual override view returns (uint256) { + return super.balanceOf(user).rayMul(_userIndexes[user]); + } } diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index ec021951..21d4dcf6 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -67,7 +67,7 @@ abstract contract DebtTokenBase is ERC20, VersionedInitializable { * @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 view returns (uint256) { + function principalBalanceOf(address user) public virtual view returns (uint256) { return super.balanceOf(user); } diff --git a/contracts/tokenization/interfaces/IAToken.sol b/contracts/tokenization/interfaces/IAToken.sol index 65ad0cfa..ec6898fe 100644 --- a/contracts/tokenization/interfaces/IAToken.sol +++ b/contracts/tokenization/interfaces/IAToken.sol @@ -127,6 +127,14 @@ interface IAToken is IERC20 { */ function mint(address user, uint256 amount) external; + /** + * @dev mints aTokens to reserve, based on the reserveFactor value + * only lending pools can call this function + * @param amount the amount of tokens to mint + */ + function mintToReserve(uint256 amount) external; + + /** * @dev transfers tokens in the event of a borrow being liquidated, in case the liquidators reclaims the aToken * only lending pools can call this function diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index e979b4a5..6f58e2d2 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -46,9 +46,4 @@ interface IVariableDebtToken { **/ function burn(address user, uint256 amount) external; - /** - * @dev returns the last index of the user - * @return the index of the user - **/ - function getUserIndex(address user) external view returns (uint256); } From de8ae523c8b0373df7a408003ae9241508d57d85 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 13:05:02 +0200 Subject: [PATCH 03/79] Fixed total supply, tests --- contracts/interfaces/ILendingPool.sol | 1 + contracts/lendingpool/LendingPool.sol | 2 ++ contracts/tokenization/VariableDebtToken.sol | 14 +++++++++++++- .../tokenization/interfaces/IVariableDebtToken.sol | 6 ++++++ helpers/contracts-helpers.ts | 5 ++++- test/__setup.spec.ts | 1 + test/helpers/utils/calculations.ts | 7 ++----- test/helpers/utils/helpers.ts | 2 +- test/helpers/utils/interfaces/index.ts | 2 +- 9 files changed, 31 insertions(+), 9 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 12119a3a..177f04d8 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -303,6 +303,7 @@ interface ILendingPool { uint256 currentVariableDebt, uint256 principalStableDebt, uint256 principalVariableDebt, + uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 50944f9f..902388f0 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -619,6 +619,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 currentVariableDebt, uint256 principalStableDebt, uint256 principalVariableDebt, + uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, uint40 stableRateLastUpdated, @@ -630,6 +631,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user); (currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve); (principalStableDebt, principalVariableDebt) = Helpers.getUserPrincipalDebt(user, reserve); + scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user); liquidityRate = reserve.currentLiquidityRate; stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user); stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated( diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 80f626f9..0fb4c0bd 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -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 = principalBalanceOf(user); + uint256 scaledBalance = super.principalBalanceOf(user); if (scaledBalance == 0) { return 0; @@ -84,4 +84,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { function principalBalanceOf(address user) public virtual override view returns (uint256) { return super.balanceOf(user).rayMul(_userIndexes[user]); } + + /** + * @dev Returns the principal debt balance of the user from + * @return The debt balance of the user since the last burn/mint action + **/ + function scaledBalanceOf(address user) public virtual override view returns (uint256) { + return super.balanceOf(user); + } + + function totalSupply() public virtual override view returns(uint256) { + return super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); + } } diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 6f58e2d2..01b2aaca 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -46,4 +46,10 @@ interface IVariableDebtToken { **/ function burn(address user, uint256 amount) external; + /** + * @dev returns the scaled balance of the variable debt token + * @param user the user + **/ + function scaledBalanceOf(address user) external view returns(uint256); + } diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index b5b483d3..1743b416 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -31,6 +31,7 @@ import BigNumber from 'bignumber.js'; import {Ierc20Detailed} from '../types/Ierc20Detailed'; import {StableDebtToken} from '../types/StableDebtToken'; import {VariableDebtToken} from '../types/VariableDebtToken'; +import { ZERO_ADDRESS } from './constants'; export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => { const currentNetwork = BRE.network.name; @@ -277,7 +278,8 @@ export const deployVariableDebtToken = async ([name, symbol, underlyingAsset, po return token; }; -export const deployGenericAToken = async ([poolAddress, underlyingAssetAddress, name, symbol]: [ +export const deployGenericAToken = async ([poolAddress, underlyingAssetAddress, reserveTreasuryAddress, name, symbol]: [ + tEthereumAddress, tEthereumAddress, tEthereumAddress, string, @@ -286,6 +288,7 @@ export const deployGenericAToken = async ([poolAddress, underlyingAssetAddress, const token = await deployContract(eContractid.AToken, [ poolAddress, underlyingAssetAddress, + ZERO_ADDRESS, name, symbol, ]); diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts index 342b7b64..fa4d557f 100644 --- a/test/__setup.spec.ts +++ b/test/__setup.spec.ts @@ -241,6 +241,7 @@ const initReserves = async ( const aToken = await deployGenericAToken([ lendingPool.address, tokenAddress, + ZERO_ADDRESS, `Aave interest bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`, `a${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`, ]); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 4ff03b19..c50703d9 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -1164,13 +1164,10 @@ export const calcExpectedVariableDebtTokenBalance = ( ) => { const debt = calcExpectedReserveNormalizedDebt(reserveDataBeforeAction, currentTimestamp); - const { principalVariableDebt, variableBorrowIndex } = userDataBeforeAction; + const { scaledVariableDebt } = userDataBeforeAction; - if (variableBorrowIndex.eq(0)) { - return principalVariableDebt; - } - return principalVariableDebt.wadToRay().rayMul(debt).rayDiv(variableBorrowIndex).rayToWad(); + return scaledVariableDebt.rayMul(debt); }; export const calcExpectedStableDebtTokenBalance = ( diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index c20c67ac..1e0218b1 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -90,7 +90,7 @@ export const getUserData = async ( currentVariableDebt: new BigNumber(userData.currentVariableDebt.toString()), principalStableDebt: new BigNumber(userData.principalStableDebt.toString()), principalVariableDebt: new BigNumber(userData.principalVariableDebt.toString()), - variableBorrowIndex: new BigNumber(userData.variableBorrowIndex.toString()), + scaledVariableDebt: new BigNumber(userData.scaledVariableDebt.toString()), stableBorrowRate: new BigNumber(userData.stableBorrowRate.toString()), liquidityRate: new BigNumber(userData.liquidityRate.toString()), usageAsCollateralEnabled: userData.usageAsCollateralEnabled, diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts index aa84ad3d..952bbf25 100644 --- a/test/helpers/utils/interfaces/index.ts +++ b/test/helpers/utils/interfaces/index.ts @@ -11,7 +11,7 @@ export interface UserReserveData { currentVariableDebt: BigNumber; principalStableDebt: BigNumber; principalVariableDebt: BigNumber; - variableBorrowIndex: BigNumber; + scaledVariableDebt: BigNumber; liquidityRate: BigNumber; stableBorrowRate: BigNumber; stableRateLastUpdated: BigNumber; From af362141fd9d18dc053dc198a5891a68818ac065 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 13:16:32 +0200 Subject: [PATCH 04/79] Added reserveFactor to getReserveConfigurationData --- contracts/interfaces/ILendingPool.sol | 1 + contracts/lendingpool/LendingPool.sol | 9 ++++++++- contracts/lendingpool/LendingPoolConfigurator.sol | 2 +- contracts/misc/WalletBalanceProvider.sol | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 177f04d8..587e151b 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -249,6 +249,7 @@ interface ILendingPool { uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, + uint256 reserveFactor, address interestRateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 902388f0..2cd1a962 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -500,6 +500,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 ltv, uint256 liquidationThreshold, uint256 liquidationBonus, + uint256 reserveFactor, address interestRateStrategyAddress, bool usageAsCollateralEnabled, bool borrowingEnabled, @@ -515,6 +516,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.configuration.getLtv(), reserve.configuration.getLiquidationThreshold(), reserve.configuration.getLiquidationBonus(), + reserve.configuration.getReserveFactor(), reserve.interestRateStrategyAddress, reserve.configuration.getLtv() != 0, reserve.configuration.getBorrowingEnabled(), @@ -872,13 +874,18 @@ contract LendingPool is VersionedInitializable, ILendingPool { function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal { + uint256 reserveFactor = reserve.configuration.getReserveFactor(); + if(reserveFactor == 0) { + return; + } + 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()); + uint256 amountForReserveFactor = balanceIncrease.percentMul(reserveFactor); IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); } diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index e9c0a292..97998556 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -571,7 +571,7 @@ contract LendingPoolConfigurator is VersionedInitializable { payable(proxyAddress) ); - (uint256 decimals, , , , , , , , , ) = pool.getReserveConfigurationData(asset); + (uint256 decimals, , , , , , , , , , ) = pool.getReserveConfigurationData(asset); bytes memory params = abi.encodeWithSignature( 'initialize(uint8,string,string)', diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index d4497178..c52b5f21 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -91,7 +91,7 @@ contract WalletBalanceProvider { uint256[] memory balances = new uint256[](reserves.length); for (uint256 j = 0; j < reserves.length; j++) { - (, , , , , , , , bool isActive, ) = pool.getReserveConfigurationData(reserves[j]); + (, , , , , , , , , bool isActive, ) = pool.getReserveConfigurationData(reserves[j]); if (!isActive) { balances[j] = 0; From c3b1ab0585772efa4c88402b877fab650841e9c9 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 13:21:50 +0200 Subject: [PATCH 05/79] Refactored interestRateStrategy --- contracts/lendingpool/DefaultReserveInterestRateStrategy.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol index c93e6c38..f03b3c94 100644 --- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol @@ -4,6 +4,7 @@ pragma solidity ^0.6.8; import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol'; import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; +import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {ILendingRateOracle} from '../interfaces/ILendingRateOracle.sol'; @@ -17,7 +18,7 @@ import {ILendingRateOracle} from '../interfaces/ILendingRateOracle.sol'; contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { using WadRayMath for uint256; using SafeMath for uint256; - + using PercentageMath for uint256; /** * @dev this constant represents the utilization rate at which the pool aims to obtain most competitive borrow rates * expressed in ray @@ -171,7 +172,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { averageStableBorrowRate ) .rayMul(utilizationRate) - .rayMul(WadRayMath.ray().sub(reserveFactor)); + .percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(reserveFactor)); return (vars.currentLiquidityRate, vars.currentStableBorrowRate, vars.currentVariableBorrowRate); } From 3563f1379d852721d212ddbccd8f3165850351e0 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 13:26:02 +0200 Subject: [PATCH 06/79] Updated configurator for the reserve factor --- .../lendingpool/LendingPoolConfigurator.sol | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index 97998556..42cbffb3 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -118,6 +118,13 @@ contract LendingPoolConfigurator is VersionedInitializable { **/ event ReserveBaseLtvChanged(address asset, uint256 ltv); + /** + * @dev emitted when a reserve factor is updated + * @param asset the address of the reserve + * @param factor the new reserve factor + **/ + event ReserveFactorChanged(address asset, uint256 factor); + /** * @dev emitted when a reserve liquidation threshold is updated * @param asset the address of the reserve @@ -467,7 +474,7 @@ contract LendingPoolConfigurator is VersionedInitializable { } /** - * @dev emitted when a reserve loan to value is updated + * @dev updates the ltv of a reserve * @param asset the address of the reserve * @param ltv the new value for the loan to value **/ @@ -481,6 +488,22 @@ contract LendingPoolConfigurator is VersionedInitializable { emit ReserveBaseLtvChanged(asset, ltv); } + /** + * @dev updates the reserve factor of a reserve + * @param asset the address of the reserve + * @param reserveFactor the new reserve factor of the reserve + **/ + function setReserveFactor(address asset, uint256 reserveFactor) external onlyLendingPoolManager { + ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); + + currentConfig.setReserveFactor(reserveFactor); + + pool.setConfiguration(asset, currentConfig.data); + + emit ReserveFactorChanged(asset, reserveFactor); + } + + /** * @dev updates the liquidation threshold of a reserve. * @param asset the address of the reserve From 73d7ca001c3e637e9c2a2c5de70e1e99388b86dd Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 10 Sep 2020 13:52:07 +0200 Subject: [PATCH 07/79] added configurator tests --- .../configuration/ReserveConfiguration.sol | 27 ++++++++++--------- test/configurator.spec.ts | 17 ++++++++++++ test/scenario.spec.ts | 2 +- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 96c0024c..10471f6e 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -6,6 +6,7 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {ReserveLogic} from '../logic/ReserveLogic.sol'; import {WadRayMath} from '../math/WadRayMath.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; +import "@nomiclabs/buidler/console.sol"; /** * @title ReserveConfiguration library @@ -13,14 +14,14 @@ import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; * @notice Implements the bitmap logic to handle the reserve configuration */ library ReserveConfiguration { - uint256 constant LTV_MASK = 0xFFFFFFFFFFF0000; - uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFF0000FFFF; - uint256 constant LIQUIDATION_BONUS_MASK = 0xFFF0000FFFFFFFF; - uint256 constant DECIMALS_MASK = 0xF00FFFFFFFFFFFF; - uint256 constant ACTIVE_MASK = 0xEFFFFFFFFFFFFFF; - uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF; - uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF; - uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF; + uint256 constant LTV_MASK = 0xFFFFFFFFFFFFFFFF0000; + uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFF0000FFFF; + uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFF0000FFFFFFFF; + uint256 constant DECIMALS_MASK = 0xFFFFFF00FFFFFFFFFFFF; + uint256 constant ACTIVE_MASK = 0xFFFFFEFFFFFFFFFFFFFF; + uint256 constant FROZEN_MASK = 0xFFFFFDFFFFFFFFFFFFFF; + uint256 constant BORROWING_MASK = 0xFFFFFBFFFFFFFFFFFFFF; + uint256 constant STABLE_BORROWING_MASK = 0xFFFF07FFFFFFFFFFFFFF; uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF; struct Map { @@ -39,10 +40,12 @@ library ReserveConfiguration { /** * @dev sets the reserve factor of the reserve * @param self the reserve configuration - * @param ltv the new ltv + * @param reserveFactor the reserve factor **/ - function setReserveFactor(ReserveConfiguration.Map memory self, uint256 ltv) internal pure { - self.data = (self.data & RESERVE_FACTOR_MASK) | ltv; + function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) internal view { + console.log("Setting reserve factor to %s", reserveFactor); + + self.data = (self.data & RESERVE_FACTOR_MASK) | reserveFactor << 64; } /** @@ -51,7 +54,7 @@ library ReserveConfiguration { * @return the reserve factor **/ function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { - return self.data & ~RESERVE_FACTOR_MASK; + return (self.data & ~RESERVE_FACTOR_MASK) >> 64; } /** * @dev sets the Loan to Value of the reserve diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index a6513e54..8b694afb 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -180,6 +180,23 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER); }); + + it('Changes the reserve factor of the reserve', async () => { + const {configurator, pool, weth} = testEnv; + await configurator.setReserveFactor(weth.address, '1000'); + const {reserveFactor} = await pool.getReserveConfigurationData(weth.address); + expect(reserveFactor.toString()).to.be.bignumber.equal('1000', 'Invalid reserve factor'); + }); + + it('Check the onlyLendingPoolManager on setReserveFactor', async () => { + const {configurator, users, weth} = testEnv; + await expect( + configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'), + CALLER_NOT_LENDING_POOL_MANAGER + ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER); + }); + + it('Changes liquidation threshold of the reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.setLiquidationThreshold(weth.address, '75'); diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 5d449d76..025bc720 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -12,7 +12,7 @@ BigNumber.config({DECIMAL_PLACES: 0, ROUNDING_MODE: BigNumber.ROUND_DOWN}); const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = []; +const selectedScenarios: string[] = ['']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From b5efaa740f6457896aff791c81399c255f6d0e62 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 11 Sep 2020 15:22:54 +0200 Subject: [PATCH 08/79] Added total supply timestamp on the stable debt token --- contracts/tokenization/StableDebtToken.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index a30219e3..1ae900de 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -21,6 +21,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 private _avgStableRate; mapping(address => uint40) _timestamps; + uint40 _totalSupplyTimestamp; constructor( address pool, @@ -122,7 +123,8 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _usersData[user] = vars.newStableRate; //solium-disable-next-line - _timestamps[user] = uint40(block.timestamp); + _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); + //calculates the updated average stable rate _avgStableRate = _avgStableRate @@ -171,7 +173,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _timestamps[user] = 0; } else { //solium-disable-next-line - _timestamps[user] = uint40(block.timestamp); + _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); } if (balanceIncrease > amount) { From edfcdd6db4ce4d18f120ace94d554f0c714fb866 Mon Sep 17 00:00:00 2001 From: The3D Date: Sun, 13 Sep 2020 10:58:36 +0200 Subject: [PATCH 09/79] Removed timestamp from stableDebtToken --- contracts/tokenization/StableDebtToken.sol | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 1ae900de..ba2c9d66 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -21,7 +21,6 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 private _avgStableRate; mapping(address => uint40) _timestamps; - uint40 _totalSupplyTimestamp; constructor( address pool, @@ -123,7 +122,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _usersData[user] = vars.newStableRate; //solium-disable-next-line - _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); + _timestamps[user] = uint40(block.timestamp); //calculates the updated average stable rate @@ -173,7 +172,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _timestamps[user] = 0; } else { //solium-disable-next-line - _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); + _timestamps[user] = uint40(block.timestamp); } if (balanceIncrease > amount) { From 162c7924a9da6f53643eb3917aa62957bfd3a83d Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 09:33:53 +0200 Subject: [PATCH 10/79] Added index to mint and burn of variableDebtToken --- contracts/lendingpool/LendingPool.sol | 58 ++++++++++--------- contracts/tokenization/VariableDebtToken.sol | 12 ++-- .../interfaces/IVariableDebtToken.sol | 6 +- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 453b9ac2..34d8e1aa 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -26,6 +26,7 @@ import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; + /** * @title LendingPool contract * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data @@ -238,14 +239,17 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); - address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE + ? reserve.stableDebtTokenAddress + : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, onBehalfOf, debtTokenAddress); //burns an equivalent amount of debt tokens if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); } else { - IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount); + IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount, reserve.variableBorrowIndex); } address aToken = reserve.aTokenAddress; @@ -282,10 +286,12 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateCumulativeIndexesAndTimestamp(); - address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress : reserve.variableDebtTokenAddress; + address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE + ? reserve.stableDebtTokenAddress + : reserve.variableDebtTokenAddress; + _mintToReserveTreasury(reserve, msg.sender, debtTokenAddress); - if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { //burn stable rate tokens, mint variable rate tokens IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); @@ -344,7 +350,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { _mintToReserveTreasury(reserve, user, address(stableDebtToken)); - stableDebtToken.burn(user, stableBorrowBalance); stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); @@ -779,7 +784,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { * @param vars Input struct for the borrowing action, in order to avoid STD errors **/ function _executeBorrow(ExecuteBorrowParams memory vars) internal { - ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; UserConfiguration.Map storage userConfig = _usersConfig[msg.sender]; @@ -807,16 +811,15 @@ contract LendingPool is VersionedInitializable, ILendingPool { userConfig.setBorrowing(reserveId, true); } - address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE ? - reserve.stableDebtTokenAddress - : - reserve.variableDebtTokenAddress; - - - reserve.updateCumulativeIndexesAndTimestamp(); + address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == + ReserveLogic.InterestRateMode.STABLE + ? reserve.stableDebtTokenAddress + : reserve.variableDebtTokenAddress; _mintToReserveTreasury(reserve, vars.user, debtTokenAddress); + reserve.updateCumulativeIndexesAndTimestamp(); + //caching the current stable borrow rate uint256 currentStableRate = 0; @@ -825,13 +828,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { ) { currentStableRate = reserve.currentStableBorrowRate; - IStableDebtToken(debtTokenAddress).mint( - vars.user, - vars.amount, - currentStableRate - ); + IStableDebtToken(debtTokenAddress).mint(vars.user, vars.amount, currentStableRate); } else { - IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount); + IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount, reserve.variableBorrowIndex); } reserve.updateInterestRates( @@ -933,23 +932,26 @@ contract LendingPool is VersionedInitializable, ILendingPool { return _addressesProvider; } - function _mintToReserveTreasury(ReserveLogic.ReserveData storage reserve, address user, address debtTokenAddress) internal { - + function _mintToReserveTreasury( + ReserveLogic.ReserveData storage reserve, + address user, + address debtTokenAddress + ) internal { uint256 reserveFactor = reserve.configuration.getReserveFactor(); - if(reserveFactor == 0) { + if (reserveFactor == 0) { return; } 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); + if (currentPrincipalBalance > 0) { + uint256 balanceIncrease = IERC20(debtTokenAddress).balanceOf(user).sub( + currentPrincipalBalance + ); uint256 amountForReserveFactor = balanceIncrease.percentMul(reserveFactor); - IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); - } - + IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); + } } } diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 9bdff0e7..b43cbec4 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -54,23 +54,21 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @dev mints new variable debt * @param user the user receiving the debt * @param amount the amount of debt being minted + * @param index the variable debt index of the reserve **/ - function mint(address user, uint256 amount) external override onlyLendingPool { - - uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); + function mint(address user, uint256 amount, uint256 index) external override onlyLendingPool { _mint(user, amount.rayDiv(index)); + emit MintDebt(user, amount, index); } /** * @dev burns user variable debt * @param user the user which debt is burnt - * @param amount the amount of debt being burned + * @param index the variable debt index of the reserve **/ - function burn(address user, uint256 amount) external override onlyLendingPool { - - uint256 index = POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET); + function burn(address user, uint256 amount, uint256 index) external override onlyLendingPool { _burn(user, amount.rayDiv(index)); _userIndexes[user] = index; emit BurnDebt(user, amount, index); diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 01b2aaca..3d26ed6e 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -36,15 +36,17 @@ interface IVariableDebtToken { * @dev mints new variable debt * @param user the user receiving the debt * @param amount the amount of debt being minted + * @param index the variable debt index of the reserve **/ - function mint(address user, uint256 amount) external; + function mint(address user, uint256 amount, uint256 index) external; /** * @dev burns user variable debt * @param user the user which debt is burnt * @param amount the amount of debt being burned + * @param index the variable debt index of the reserve **/ - function burn(address user, uint256 amount) external; + function burn(address user, uint256 amount, uint256 index) external; /** * @dev returns the scaled balance of the variable debt token From fc2852e94e1d1aae18e25852fe366f5725670dd9 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 09:53:21 +0200 Subject: [PATCH 11/79] Rename updateIndexesAndTimestamp to updateState --- contracts/lendingpool/LendingPool.sol | 37 ++++--------------- .../LendingPoolLiquidationManager.sol | 8 ++-- contracts/libraries/logic/ReserveLogic.sol | 4 +- 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 34d8e1aa..88df63af 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -103,7 +103,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { address aToken = reserve.aTokenAddress; - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); reserve.updateInterestRates(asset, aToken, amount, 0); bool isFirstDeposit = IAToken(aToken).balanceOf(onBehalfOf) == 0; @@ -149,7 +149,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _addressesProvider.getPriceOracle() ); - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); reserve.updateInterestRates(asset, aToken, 0, amountToWithdraw); @@ -237,7 +237,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { variableDebt ); - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress @@ -284,7 +284,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { interestRateMode ); - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE ? reserve.stableDebtTokenAddress @@ -346,7 +346,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { //burn old debt tokens, mint new ones - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); _mintToReserveTreasury(reserve, user, address(stableDebtToken)); @@ -529,7 +529,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { if (debtMode == ReserveLogic.InterestRateMode.NONE) { IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium); - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium); reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0); @@ -818,7 +818,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _mintToReserveTreasury(reserve, vars.user, debtTokenAddress); - reserve.updateCumulativeIndexesAndTimestamp(); + reserve.updateState(); //caching the current stable borrow rate uint256 currentStableRate = 0; @@ -931,27 +931,4 @@ contract LendingPool is VersionedInitializable, ILendingPool { function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { return _addressesProvider; } - - function _mintToReserveTreasury( - ReserveLogic.ReserveData storage reserve, - address user, - address debtTokenAddress - ) internal { - uint256 reserveFactor = reserve.configuration.getReserveFactor(); - if (reserveFactor == 0) { - return; - } - - 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(reserveFactor); - - IAToken(reserve.aTokenAddress).mintToReserve(amountForReserveFactor); - } - } } diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol index 83f37172..848aaffb 100644 --- a/contracts/lendingpool/LendingPoolLiquidationManager.sol +++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol @@ -232,7 +232,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { } //update the principal reserve - principalReserve.updateCumulativeIndexesAndTimestamp(); + principalReserve.updateState(); @@ -279,7 +279,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { //otherwise receives the underlying asset //updating collateral reserve - collateralReserve.updateCumulativeIndexesAndTimestamp(); + collateralReserve.updateState(); collateralReserve.updateInterestRates( collateral, address(vars.collateralAtoken), @@ -406,7 +406,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { vars.actualAmountToLiquidate = vars.principalAmountNeeded; } //updating collateral reserve indexes - collateralReserve.updateCumulativeIndexesAndTimestamp(); + collateralReserve.updateState(); vars.collateralAtoken.burn(user, receiver, vars.maxCollateralToLiquidate, collateralReserve.liquidityIndex); @@ -426,7 +426,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { ); //updating debt reserve - debtReserve.updateCumulativeIndexesAndTimestamp(); + debtReserve.updateState(); debtReserve.updateInterestRates(principal, principalAToken, vars.actualAmountToLiquidate, 0); IERC20(principal).transferFrom(receiver, principalAToken, vars.actualAmountToLiquidate); diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 3d688b75..e2f3df70 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -125,7 +125,9 @@ library ReserveLogic { * a formal specification. * @param reserve the reserve object **/ - function updateCumulativeIndexesAndTimestamp(ReserveData storage reserve) internal { + function updateState(ReserveData storage reserve) internal { + + uint256 currentLiquidityRate = reserve.currentLiquidityRate; //only cumulating if there is any income being produced From 3c8018fab9d9c8bda7f2b717b7268c69120aef3d Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 10:43:30 +0200 Subject: [PATCH 12/79] Cleaned up code, converted addressesProvider to immutable in LendingPool --- contracts/lendingpool/LendingPool.sol | 247 ++++++++---------- contracts/libraries/logic/ReserveLogic.sol | 71 ++--- contracts/tokenization/VariableDebtToken.sol | 12 + .../interfaces/IVariableDebtToken.sol | 6 + 4 files changed, 163 insertions(+), 173 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 88df63af..1d969b1d 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -47,7 +47,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; - ILendingPoolAddressesProvider internal _addressesProvider; + ILendingPoolAddressesProvider public immutable ADDRESSES_PROVIDER; mapping(address => ReserveLogic.ReserveData) internal _reserves; mapping(address => UserConfiguration.Map) internal _usersConfig; @@ -61,7 +61,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { **/ modifier onlyLendingPoolConfigurator { require( - _addressesProvider.getLendingPoolConfigurator() == msg.sender, + ADDRESSES_PROVIDER.getLendingPoolConfigurator() == msg.sender, Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR ); _; @@ -81,7 +81,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { * @param provider the address of the LendingPoolAddressesProvider registry **/ function initialize(ILendingPoolAddressesProvider provider) public initializer { - _addressesProvider = provider; + ADDRESSES_PROVIDER = provider; } /** @@ -146,7 +146,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _reserves, _usersConfig[msg.sender], _reservesList, - _addressesProvider.getPriceOracle() + ADDRESSES_PROVIDER.getPriceOracle() ); reserve.updateState(); @@ -203,16 +203,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 rateMode, address onBehalfOf ) external override { - _executeRepay(asset, msg.sender, amount, rateMode, onBehalfOf); - } - - function _executeRepay( - address asset, - address user, - uint256 amount, - uint256 rateMode, - address onBehalfOf - ) internal { ReserveLogic.ReserveData storage reserve = _reserves[asset]; (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve); @@ -239,12 +229,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateState(); - address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE - ? reserve.stableDebtTokenAddress - : reserve.variableDebtTokenAddress; - - _mintToReserveTreasury(reserve, onBehalfOf, debtTokenAddress); - //burns an equivalent amount of debt tokens if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); @@ -286,12 +270,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { reserve.updateState(); - address debtTokenAddress = interestRateMode == ReserveLogic.InterestRateMode.STABLE - ? reserve.stableDebtTokenAddress - : reserve.variableDebtTokenAddress; - - _mintToReserveTreasury(reserve, msg.sender, debtTokenAddress); - if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { //burn stable rate tokens, mint variable rate tokens IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); @@ -344,12 +322,10 @@ contract LendingPool is VersionedInitializable, ILendingPool { Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET ); - //burn old debt tokens, mint new ones reserve.updateState(); - _mintToReserveTreasury(reserve, user, address(stableDebtToken)); - + //burn old debt tokens, mint new ones stableDebtToken.burn(user, stableBorrowBalance); stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); @@ -374,7 +350,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _reserves, _usersConfig[msg.sender], _reservesList, - _addressesProvider.getPriceOracle() + ADDRESSES_PROVIDER.getPriceOracle() ); _usersConfig[msg.sender].setUsingAsCollateral(reserve.id, useAsCollateral); @@ -402,7 +378,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 purchaseAmount, bool receiveAToken ) external override { - address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager(); + address liquidationManager = ADDRESSES_PROVIDER.getLendingPoolLiquidationManager(); //solium-disable-next-line (bool success, bytes memory result) = liquidationManager.delegatecall( @@ -461,7 +437,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED); _flashLiquidationLocked = true; - address liquidationManager = _addressesProvider.getLendingPoolLiquidationManager(); + address liquidationManager = ADDRESSES_PROVIDER.getLendingPoolLiquidationManager(); //solium-disable-next-line (bool success, bytes memory result) = liquidationManager.delegatecall( @@ -664,7 +640,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _reserves, _usersConfig[user], _reservesList, - _addressesProvider.getPriceOracle() + ADDRESSES_PROVIDER.getPriceOracle() ); availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH( @@ -767,110 +743,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { return _reserves[asset].configuration; } - // internal functions - - struct ExecuteBorrowParams { - address asset; - address user; - uint256 amount; - uint256 interestRateMode; - address aTokenAddress; - uint16 referralCode; - bool releaseUnderlying; - } - - /** - * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying - * @param vars Input struct for the borrowing action, in order to avoid STD errors - **/ - function _executeBorrow(ExecuteBorrowParams memory vars) internal { - ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; - UserConfiguration.Map storage userConfig = _usersConfig[msg.sender]; - - address oracle = _addressesProvider.getPriceOracle(); - - uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div( - 10**reserve.configuration.getDecimals() - ); - - ValidationLogic.validateBorrow( - reserve, - vars.asset, - vars.amount, - amountInETH, - vars.interestRateMode, - MAX_STABLE_RATE_BORROW_SIZE_PERCENT, - _reserves, - userConfig, - _reservesList, - oracle - ); - - uint256 reserveId = reserve.id; - if (!userConfig.isBorrowing(reserveId)) { - userConfig.setBorrowing(reserveId, true); - } - - address debtTokenAddress = ReserveLogic.InterestRateMode(vars.interestRateMode) == - ReserveLogic.InterestRateMode.STABLE - ? reserve.stableDebtTokenAddress - : reserve.variableDebtTokenAddress; - - _mintToReserveTreasury(reserve, vars.user, debtTokenAddress); - - reserve.updateState(); - - //caching the current stable borrow rate - uint256 currentStableRate = 0; - - if ( - ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE - ) { - currentStableRate = reserve.currentStableBorrowRate; - - IStableDebtToken(debtTokenAddress).mint(vars.user, vars.amount, currentStableRate); - } else { - IVariableDebtToken(debtTokenAddress).mint(vars.user, vars.amount, reserve.variableBorrowIndex); - } - - reserve.updateInterestRates( - vars.asset, - vars.aTokenAddress, - 0, - vars.releaseUnderlying ? vars.amount : 0 - ); - - if (vars.releaseUnderlying) { - IAToken(vars.aTokenAddress).transferUnderlyingTo(msg.sender, vars.amount); - } - - emit Borrow( - vars.asset, - msg.sender, - vars.amount, - vars.interestRateMode, - ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE - ? currentStableRate - : reserve.currentVariableBorrowRate, - vars.referralCode - ); - } - - /** - * @dev adds a reserve to the array of the _reserves address - **/ - function _addReserveToList(address asset) internal { - bool reserveAlreadyAdded = false; - for (uint256 i = 0; i < _reservesList.length; i++) - if (_reservesList[i] == asset) { - reserveAlreadyAdded = true; - } - if (!reserveAlreadyAdded) { - _reserves[asset].id = uint8(_reservesList.length); - _reservesList.push(asset); - } - } - /** * @dev returns the normalized income per unit of asset * @param asset the address of the reserve @@ -914,7 +786,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { _reserves, _usersConfig[user], _reservesList, - _addressesProvider.getPriceOracle() + ADDRESSES_PROVIDER.getPriceOracle() ); } @@ -929,6 +801,103 @@ contract LendingPool is VersionedInitializable, ILendingPool { * @dev returns the addresses provider **/ function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { - return _addressesProvider; + return ADDRESSES_PROVIDER; + } + + // internal functions + + struct ExecuteBorrowParams { + address asset; + address user; + uint256 amount; + uint256 interestRateMode; + address aTokenAddress; + uint16 referralCode; + bool releaseUnderlying; + } + + /** + * @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying + * @param vars Input struct for the borrowing action, in order to avoid STD errors + **/ + function _executeBorrow(ExecuteBorrowParams memory vars) internal { + ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; + UserConfiguration.Map storage userConfig = _usersConfig[msg.sender]; + + address oracle = ADDRESSES_PROVIDER.getPriceOracle(); + + uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div( + 10**reserve.configuration.getDecimals() + ); + + ValidationLogic.validateBorrow( + reserve, + vars.asset, + vars.amount, + amountInETH, + vars.interestRateMode, + MAX_STABLE_RATE_BORROW_SIZE_PERCENT, + _reserves, + userConfig, + _reservesList, + oracle + ); + + uint256 reserveId = reserve.id; + if (!userConfig.isBorrowing(reserveId)) { + userConfig.setBorrowing(reserveId, true); + } + + reserve.updateState(); + + //caching the current stable borrow rate + uint256 currentStableRate = 0; + + if ( + ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE + ) { + currentStableRate = reserve.currentStableBorrowRate; + + IStableDebtToken(reserve.stableDebtTokenAddress).mint(vars.user, vars.amount, currentStableRate); + } else { + IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount, reserve.variableBorrowIndex); + } + + reserve.updateInterestRates( + vars.asset, + vars.aTokenAddress, + 0, + vars.releaseUnderlying ? vars.amount : 0 + ); + + if (vars.releaseUnderlying) { + IAToken(vars.aTokenAddress).transferUnderlyingTo(msg.sender, vars.amount); + } + + emit Borrow( + vars.asset, + msg.sender, + vars.amount, + vars.interestRateMode, + ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE + ? currentStableRate + : reserve.currentVariableBorrowRate, + vars.referralCode + ); + } + + /** + * @dev adds a reserve to the array of the _reserves address + **/ + function _addReserveToList(address asset) internal { + bool reserveAlreadyAdded = false; + for (uint256 i = 0; i < _reservesList.length; i++) + if (_reservesList[i] == asset) { + reserveAlreadyAdded = true; + } + if (!reserveAlreadyAdded) { + _reserves[asset].id = uint8(_reservesList.length); + _reservesList.push(asset); + } } } diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index e2f3df70..acb1e501 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -67,7 +67,7 @@ library ReserveLogic { 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 @@ -121,42 +121,13 @@ library ReserveLogic { } /** - * @dev Updates the liquidity cumulative index Ci and variable borrow cumulative index Bvc. Refer to the whitepaper for - * a formal specification. + * @dev Updates the state of the reserve by minting to the reserve treasury and calculate the new + * reserve indexes * @param reserve the reserve object **/ function updateState(ReserveData storage reserve) 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 - ); - uint256 index = cumulatedLiquidityInterest.rayMul(reserve.liquidityIndex); - require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); - - reserve.liquidityIndex = uint128(index); - - //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) { - uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( - reserve.currentVariableBorrowRate, - lastUpdateTimestamp - ); - index = cumulatedVariableBorrowInterest.rayMul(reserve.variableBorrowIndex); - require(index < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); - reserve.variableBorrowIndex = uint128(index); - } - } - - //solium-disable-next-line - reserve.lastUpdateTimestamp = uint40(block.timestamp); + _mintToTreasury(reserve); + _updateIndexes(reserve); } /** @@ -270,4 +241,36 @@ library ReserveLogic { reserve.variableBorrowIndex ); } + + function _updateIndexes(ReserveData storage reserve) 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 + ); + uint256 index = cumulatedLiquidityInterest.rayMul(reserve.liquidityIndex); + require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); + + reserve.liquidityIndex = uint128(index); + + //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) { + uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( + reserve.currentVariableBorrowRate, + lastUpdateTimestamp + ); + index = cumulatedVariableBorrowInterest.rayMul(reserve.variableBorrowIndex); + require(index < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); + reserve.variableBorrowIndex = uint128(index); + } + } + + //solium-disable-next-line + reserve.lastUpdateTimestamp = uint40(block.timestamp); + } } diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index b43cbec4..d9a423eb 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -82,7 +82,19 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { return super.balanceOf(user); } + /** + * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users + * @return the total supply + **/ function totalSupply() public virtual override view returns(uint256) { return super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); } + + /** + * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) + * @return the scaled total supply + **/ + function scaledTotalSupply() public virtual override view returns(uint256) { + return super.totalSupply(); + } } diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 3d26ed6e..320d0f5a 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -53,5 +53,11 @@ interface IVariableDebtToken { * @param user the user **/ function scaledBalanceOf(address user) external view returns(uint256); + + /** + * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) + * @return the scaled total supply + **/ + function scaledTotalSupply() external view returns(uint256); } From 5061aab9cc29c32c006b472a772557002c13b3c1 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 11:09:47 +0200 Subject: [PATCH 13/79] Added the total supply on stable debt token --- contracts/libraries/logic/ReserveLogic.sol | 6 +++++ contracts/tokenization/StableDebtToken.sol | 23 ++++++++++++++++--- .../interfaces/IStableDebtToken.sol | 7 ++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index acb1e501..58bf29bd 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -240,6 +240,12 @@ library ReserveLogic { reserve.liquidityIndex, reserve.variableBorrowIndex ); + } + + function _mintToTreasury(ReserveData storage reserve) internal { + + + } function _updateIndexes(ReserveData storage reserve) internal { diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 8d5a18e1..cf50fb18 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -21,6 +21,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 private _avgStableRate; mapping(address => uint40) _timestamps; + uint40 _totalSupplyTimestamp; constructor( address pool, @@ -76,7 +77,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { stableRate, _timestamps[account] ); - return accountBalance.wadToRay().rayMul(cumulatedInterest).rayToWad(); + return accountBalance.rayMul(cumulatedInterest); } struct MintLocalVars { @@ -122,7 +123,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _usersData[user] = vars.newStableRate; //solium-disable-next-line - _timestamps[user] = uint40(block.timestamp); + _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); //calculates the updated average stable rate @@ -172,7 +173,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _timestamps[user] = 0; } else { //solium-disable-next-line - _timestamps[user] = uint40(block.timestamp); + _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); } if (balanceIncrease > amount) { @@ -208,4 +209,20 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ); } + function principalTotalSupply() public override view returns(uint256) { + return super.totalSupply(); + } + + function totalSupply() public override view returns(uint256) { + uint256 principalSupply = super.totalSupply(); + if (principalSupply == 0) { + return 0; + } + uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( + _avgStableRate, + _totalSupplyTimestamp + ); + return principalSupply.rayMul(cumulatedInterest); + } + } diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index 0aaccd26..fc15e00f 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -84,4 +84,11 @@ interface IStableDebtToken { * @return the timestamp **/ function getUserLastUpdated(address user) external view returns (uint40); + + /** + * @dev returns the principal total supply + **/ + function principalTotalSupply() external view returns (uint40); + + } From 13f77ec0d200b9eb97916d55b0709825979f0e6b Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 11:34:40 +0200 Subject: [PATCH 14/79] Fixed repay --- contracts/lendingpool/LendingPool.sol | 4 ++-- contracts/libraries/logic/ReserveLogic.sol | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index eeeb0d9a..79940ef2 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -241,9 +241,9 @@ contract LendingPool is VersionedInitializable, ILendingPool { _usersConfig[onBehalfOf].setBorrowing(reserve.id, false); } - IERC20(asset).safeTransferFrom(user, aToken, paybackAmount); + IERC20(asset).safeTransferFrom(msg.sender, aToken, paybackAmount); - emit Repay(asset, onBehalfOf, user, paybackAmount); + emit Repay(asset, onBehalfOf, msg.sender, paybackAmount); } /** diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 58bf29bd..0cb07416 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -243,7 +243,7 @@ library ReserveLogic { } function _mintToTreasury(ReserveData storage reserve) internal { - + } From 6e92575ac2fff0284b6d70c60981c5659757e254 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 11:41:14 +0200 Subject: [PATCH 15/79] add code to _mintToTreasury --- contracts/libraries/logic/ReserveLogic.sol | 13 ++++++++++++- .../tokenization/interfaces/IStableDebtToken.sol | 2 -- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 0cb07416..0530e650 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -7,6 +7,7 @@ import {MathUtils} from '../math/MathUtils.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.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'; @@ -244,7 +245,17 @@ library ReserveLogic { function _mintToTreasury(ReserveData storage reserve) internal { - + address stableDebtToken = reserve.stableDebtTokenAddress; + address variableDebtToken = reserve.variableDebtTokenAddress; + + uint256 currentVariableDebt = IERC20(variableDebtToken).totalSupply(); + uint256 currentStableDebt = IERC20(stableDebtToken).totalSupply(); + + uint256 principalStableDebt = IStableDebtToken(stableDebtToken).principalTotalSupply(); + uint256 scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply(); + + + } diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index fc15e00f..4c3800e0 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -89,6 +89,4 @@ interface IStableDebtToken { * @dev returns the principal total supply **/ function principalTotalSupply() external view returns (uint40); - - } From bb4e1b5c4b3da4528408c29b6d9feb19e9c43d11 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 15:09:16 +0200 Subject: [PATCH 16/79] Fixed errors --- contracts/interfaces/ILendingPool.sol | 1 - contracts/lendingpool/LendingPool.sol | 31 +++---- .../LendingPoolLiquidationManager.sol | 64 ++++++-------- contracts/libraries/helpers/Helpers.sol | 17 ---- contracts/libraries/logic/ReserveLogic.sol | 87 +++++++++++++++---- contracts/tokenization/AToken.sol | 3 +- contracts/tokenization/StableDebtToken.sol | 31 +++++-- contracts/tokenization/VariableDebtToken.sol | 2 +- contracts/tokenization/base/DebtTokenBase.sol | 8 -- contracts/tokenization/interfaces/IAToken.sol | 14 +-- .../interfaces/IStableDebtToken.sol | 11 ++- test/helpers/utils/calculations.ts | 76 ++++++++-------- test/helpers/utils/helpers.ts | 1 - test/helpers/utils/interfaces/index.ts | 1 - test/scenario.spec.ts | 2 +- test/variable-debt-token.spec.ts | 4 +- 16 files changed, 189 insertions(+), 164 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index c13fe2e5..4b3c8385 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -326,7 +326,6 @@ interface ILendingPool { uint256 currentStableDebt, uint256 currentVariableDebt, uint256 principalStableDebt, - uint256 principalVariableDebt, uint256 scaledVariableDebt, uint256 stableBorrowRate, uint256 liquidityRate, diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 79940ef2..93716948 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -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() diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol index 848aaffb..8a018489 100644 --- a/contracts/lendingpool/LendingPoolLiquidationManager.sol +++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol @@ -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); - } - - } } diff --git a/contracts/libraries/helpers/Helpers.sol b/contracts/libraries/helpers/Helpers.sol index dda22eb4..e1d65502 100644 --- a/contracts/libraries/helpers/Helpers.sol +++ b/contracts/libraries/helpers/Helpers.sol @@ -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) - ); - } } diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index 0530e650..b287094a 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -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); } diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index 9df145ba..cd270ccb 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -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)); } diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index cf50fb18..1d166c8f 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -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); + } } diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index d9a423eb..8a70f31c 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -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; diff --git a/contracts/tokenization/base/DebtTokenBase.sol b/contracts/tokenization/base/DebtTokenBase.sol index d8798906..ff0070b8 100644 --- a/contracts/tokenization/base/DebtTokenBase.sol +++ b/contracts/tokenization/base/DebtTokenBase.sol @@ -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. diff --git a/contracts/tokenization/interfaces/IAToken.sol b/contracts/tokenization/interfaces/IAToken.sol index c188162e..de8b0d3c 100644 --- a/contracts/tokenization/interfaces/IAToken.sol +++ b/contracts/tokenization/interfaces/IAToken.sol @@ -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); + + } diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index 4c3800e0..c1e97388 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -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); + } diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 861f5a94..b9f9ebe2 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -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); }; diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index 59eb600a..1d2516ad 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -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()), diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts index 646e6b10..2acbfa31 100644 --- a/test/helpers/utils/interfaces/index.ts +++ b/test/helpers/utils/interfaces/index.ts @@ -6,7 +6,6 @@ export interface UserReserveData { currentStableDebt: BigNumber; currentVariableDebt: BigNumber; principalStableDebt: BigNumber; - principalVariableDebt: BigNumber; scaledVariableDebt: BigNumber; liquidityRate: BigNumber; stableBorrowRate: BigNumber; diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 1d8da5e9..17830d1c 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -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; diff --git a/test/variable-debt-token.spec.ts b/test/variable-debt-token.spec.ts index 89bb1acc..a79bdde2 100644 --- a/test/variable-debt-token.spec.ts +++ b/test/variable-debt-token.spec.ts @@ -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 ); }); From b2ec4dd2fabad7b577a289432b0032ee53c9b03c Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 15:13:30 +0200 Subject: [PATCH 17/79] Renamed totalBorrowsStable, totalBorrowsVariable --- contracts/interfaces/ILendingPool.sol | 4 +- .../IReserveInterestRateStrategy.sol | 4 +- .../DefaultReserveInterestRateStrategy.sol | 28 ++-- contracts/lendingpool/LendingPool.sol | 4 +- .../lendingpool/LendingPoolConfigurator.sol | 6 +- .../flash-liquidation-with-collateral.spec.ts | 12 +- test/flashloan.spec.ts | 12 +- test/helpers/utils/calculations.ts | 132 +++++++++--------- test/helpers/utils/helpers.ts | 12 +- test/helpers/utils/interfaces/index.ts | 4 +- 10 files changed, 109 insertions(+), 109 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 4b3c8385..4daf85e0 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -295,8 +295,8 @@ interface ILendingPool { view returns ( uint256 availableLiquidity, - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, diff --git a/contracts/interfaces/IReserveInterestRateStrategy.sol b/contracts/interfaces/IReserveInterestRateStrategy.sol index acc097bf..99f30b78 100644 --- a/contracts/interfaces/IReserveInterestRateStrategy.sol +++ b/contracts/interfaces/IReserveInterestRateStrategy.sol @@ -21,8 +21,8 @@ interface IReserveInterestRateStrategy { function calculateInterestRates( address reserve, uint256 utilizationRate, - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, uint256 averageStableBorrowRate, uint256 reserveFactor ) diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol index f03b3c94..045e9358 100644 --- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol @@ -104,8 +104,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { * @dev calculates the interest rates depending on the available liquidity and the total borrowed. * @param reserve the address of the reserve * @param availableLiquidity the liquidity available in the reserve - * @param totalBorrowsStable the total borrowed from the reserve a stable rate - * @param totalBorrowsVariable the total borrowed from the reserve at a variable rate + * @param totalStableDebt the total borrowed from the reserve a stable rate + * @param totalVariableDebt the total borrowed from the reserve at a variable rate * @param averageStableBorrowRate the weighted average of all the stable rate borrows * @param reserveFactor the reserve portion of the interest to redirect to the reserve treasury * @return currentLiquidityRate the liquidity rate @@ -115,8 +115,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { function calculateInterestRates( address reserve, uint256 availableLiquidity, - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, uint256 averageStableBorrowRate, uint256 reserveFactor ) @@ -132,7 +132,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { CalcInterestRatesLocalVars memory vars; - vars.totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); + vars.totalBorrows = totalStableDebt.add(totalVariableDebt); vars.currentVariableBorrowRate = 0; vars.currentStableBorrowRate = 0; vars.currentLiquidityRate = 0; @@ -166,8 +166,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { } vars.currentLiquidityRate = _getOverallBorrowRate( - totalBorrowsStable, - totalBorrowsVariable, + totalStableDebt, + totalVariableDebt, vars.currentVariableBorrowRate, averageStableBorrowRate ) @@ -179,27 +179,27 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { /** * @dev calculates the overall borrow rate as the weighted average between the total variable borrows and total stable borrows. - * @param totalBorrowsStable the total borrowed from the reserve a stable rate - * @param totalBorrowsVariable the total borrowed from the reserve at a variable rate + * @param totalStableDebt the total borrowed from the reserve a stable rate + * @param totalVariableDebt the total borrowed from the reserve at a variable rate * @param currentVariableBorrowRate the current variable borrow rate * @param currentAverageStableBorrowRate the weighted average of all the stable rate borrows * @return the weighted averaged borrow rate **/ function _getOverallBorrowRate( - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, uint256 currentVariableBorrowRate, uint256 currentAverageStableBorrowRate ) internal pure returns (uint256) { - uint256 totalBorrows = totalBorrowsStable.add(totalBorrowsVariable); + uint256 totalBorrows = totalStableDebt.add(totalVariableDebt); if (totalBorrows == 0) return 0; - uint256 weightedVariableRate = totalBorrowsVariable.wadToRay().rayMul( + uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul( currentVariableBorrowRate ); - uint256 weightedStableRate = totalBorrowsStable.wadToRay().rayMul( + uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul( currentAverageStableBorrowRate ); diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 93716948..1ccfc467 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -587,8 +587,8 @@ contract LendingPool is VersionedInitializable, ILendingPool { view returns ( uint256 availableLiquidity, - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, uint256 liquidityRate, uint256 variableBorrowRate, uint256 stableBorrowRate, diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index 42cbffb3..c41d14ba 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -421,8 +421,8 @@ contract LendingPoolConfigurator is VersionedInitializable { function deactivateReserve(address asset) external onlyLendingPoolManager { ( uint256 availableLiquidity, - uint256 totalBorrowsStable, - uint256 totalBorrowsVariable, + uint256 totalStableDebt, + uint256 totalVariableDebt, , , , @@ -432,7 +432,7 @@ contract LendingPoolConfigurator is VersionedInitializable { ) = pool.getReserveData(asset); require( - availableLiquidity == 0 && totalBorrowsStable == 0 && totalBorrowsVariable == 0, + availableLiquidity == 0 && totalStableDebt == 0 && totalVariableDebt == 0, Errors.RESERVE_LIQUIDITY_NOT_0 ); diff --git a/test/flash-liquidation-with-collateral.spec.ts b/test/flash-liquidation-with-collateral.spec.ts index c48b5e99..be1db606 100644 --- a/test/flash-liquidation-with-collateral.spec.ts +++ b/test/flash-liquidation-with-collateral.spec.ts @@ -233,7 +233,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn userData: usdcUserDataBefore, } = await getContractsData(usdc.address, user.address, testEnv); - const amountToRepay = usdcReserveDataBefore.totalBorrowsVariable.dividedBy(2).toFixed(0); + const amountToRepay = usdcReserveDataBefore.totalVariableDebt.dividedBy(2).toFixed(0); await mockSwapAdapter.setAmountToReturn(amountToRepay); await waitForTx( @@ -368,7 +368,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn userData: usdcUserDataBefore, } = await getContractsData(usdc.address, user.address, testEnv); - const amountToRepay = usdcReserveDataBefore.totalBorrowsVariable.toFixed(0); + const amountToRepay = usdcReserveDataBefore.totalVariableDebt.toFixed(0); await mockSwapAdapter.setAmountToReturn(amountToRepay); await waitForTx( @@ -486,7 +486,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn testEnv ); - const amountToRepay = daiReserveDataBefore.totalBorrowsVariable.toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt.toString(); await waitForTx(await mockSwapAdapter.setTryReentrancy(true)); @@ -522,7 +522,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ); // First half - const amountToRepay = daiReserveDataBefore.totalBorrowsVariable.dividedBy(2).toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt.dividedBy(2).toString(); await mockSwapAdapter.setAmountToReturn(amountToRepay); await expect( @@ -568,7 +568,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ); // First half - const amountToRepay = daiReserveDataBefore.totalBorrowsVariable.multipliedBy(0.6).toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt.multipliedBy(0.6).toString(); await mockSwapAdapter.setAmountToReturn(amountToRepay); await waitForTx( @@ -654,7 +654,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn await increaseTime(1000); // Repay the remaining DAI - const amountToRepay = daiReserveDataBefore.totalBorrowsVariable.toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt.toString(); await mockSwapAdapter.setAmountToReturn(amountToRepay); const receipt = await waitForTx( diff --git a/test/flashloan.spec.ts b/test/flashloan.spec.ts index 952bdab4..ad8e7e08 100644 --- a/test/flashloan.spec.ts +++ b/test/flashloan.spec.ts @@ -60,8 +60,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { const currentLiquidityIndex = reserveData.liquidityIndex; const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString()) - .plus(reserveData.totalBorrowsStable.toString()) - .plus(reserveData.totalBorrowsVariable.toString()); + .plus(reserveData.totalStableDebt.toString()) + .plus(reserveData.totalVariableDebt.toString()); expect(totalLiquidity.toString()).to.be.equal('1000720000000000000'); expect(currentLiquidityRate.toString()).to.be.equal('0'); @@ -87,8 +87,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { const currentLiquidityIndex = reserveData.liquidityIndex; const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString()) - .plus(reserveData.totalBorrowsStable.toString()) - .plus(reserveData.totalBorrowsVariable.toString()); + .plus(reserveData.totalStableDebt.toString()) + .plus(reserveData.totalVariableDebt.toString()); expect(totalLiquidity.toString()).to.be.equal('1001620648000000000'); expect(currentLiqudityRate.toString()).to.be.equal('0'); @@ -242,8 +242,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => { const userData = await pool.getUserReserveData(usdc.address, depositor.address); const totalLiquidity = reserveData.availableLiquidity - .add(reserveData.totalBorrowsStable) - .add(reserveData.totalBorrowsVariable) + .add(reserveData.totalStableDebt) + .add(reserveData.totalVariableDebt) .toString(); const currentLiqudityRate = reserveData.liquidityRate.toString(); const currentLiquidityIndex = reserveData.liquidityIndex.toString(); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index b9f9ebe2..9c84d851 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -166,21 +166,21 @@ export const calcExpectedReserveDataAfterDeposit = ( reserveDataBeforeAction.availableLiquidity ).plus(amountDeposited); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable; - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); const rates = calcExpectedInterestRates( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); expectedReserveData.liquidityRate = rates[0]; @@ -225,21 +225,21 @@ export const calcExpectedReserveDataAfterWithdraw = ( reserveDataBeforeAction.availableLiquidity ).minus(amountWithdrawn); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable; - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); const rates = calcExpectedInterestRates( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); expectedReserveData.liquidityRate = rates[0]; @@ -286,17 +286,17 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt .plus(amountBorrowedBN) .plus(debtAccrued); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalBorrowsStable.plus(debtAccrued), + reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), amountBorrowedBN, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; } else { const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( reserveDataBeforeAction.variableBorrowIndex @@ -304,10 +304,10 @@ export const calcExpectedReserveDataAfterBorrow = ( const debtAccrued = userVariableDebt.minus(variableDebtBefore); expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt .plus(amountBorrowedBN) .plus(debtAccrued); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable; + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; } @@ -316,8 +316,8 @@ export const calcExpectedReserveDataAfterBorrow = ( ); expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); @@ -325,8 +325,8 @@ export const calcExpectedReserveDataAfterBorrow = ( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); expectedReserveData.liquidityRate = rates[0]; @@ -385,17 +385,17 @@ export const calcExpectedReserveDataAfterRepay = ( expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt .minus(amountRepaidBN) .plus(debtAccrued); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalBorrowsStable.plus(debtAccrued), + reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), amountRepaidBN.negated(), userDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; } else { const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( reserveDataBeforeAction.variableBorrowIndex @@ -405,11 +405,11 @@ export const calcExpectedReserveDataAfterRepay = ( expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt .plus(debtAccrued) .minus(amountRepaidBN); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable; + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; } @@ -422,8 +422,8 @@ export const calcExpectedReserveDataAfterRepay = ( ); expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); @@ -431,8 +431,8 @@ export const calcExpectedReserveDataAfterRepay = ( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); expectedReserveData.liquidityRate = rates[0]; @@ -677,16 +677,16 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalBorrowsStable.plus(debtAccrued), + reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), stableDebt.negated(), userDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable.plus( + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt.plus( stableDebt ); - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable.minus( + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.minus( userDataBeforeAction.principalStableDebt ); } else { @@ -695,23 +695,23 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable.plus( + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( variableDebt ); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalBorrowsStable, + reserveDataBeforeAction.totalStableDebt, variableDebt, reserveDataBeforeAction.stableBorrowRate ); } expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); @@ -719,8 +719,8 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); expectedReserveData.liquidityRate = rates[0]; @@ -824,7 +824,7 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( const avgRateBefore = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalBorrowsStable.plus(debtAccrued), + reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), stableBorrowBalance.negated(), userDataBeforeAction.stableBorrowRate ); @@ -832,19 +832,19 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( avgRateBefore, - reserveDataBeforeAction.totalBorrowsStable.minus(userDataBeforeAction.principalStableDebt), + reserveDataBeforeAction.totalStableDebt.minus(userDataBeforeAction.principalStableDebt), stableBorrowBalance, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalBorrowsVariable = reserveDataBeforeAction.totalBorrowsVariable; - expectedReserveData.totalBorrowsStable = reserveDataBeforeAction.totalBorrowsStable.plus( + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( debtAccrued ); expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); @@ -852,8 +852,8 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, expectedReserveData.utilizationRate, - expectedReserveData.totalBorrowsStable, - expectedReserveData.totalBorrowsVariable, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, expectedReserveData.averageStableBorrowRate ); @@ -936,13 +936,13 @@ const calcExpectedATokenBalance = ( const calcExpectedAverageStableBorrowRate = ( avgStableRateBefore: BigNumber, - totalBorrowsStableBefore: BigNumber, + totalStableDebtBefore: BigNumber, amountChanged: string | BigNumber, rate: BigNumber ) => { - const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalBorrowsStableBefore); + const weightedTotalBorrows = avgStableRateBefore.multipliedBy(totalStableDebtBefore); const weightedAmountBorrowed = rate.multipliedBy(amountChanged); - const totalBorrowedStable = totalBorrowsStableBefore.plus(new BigNumber(amountChanged)); + const totalBorrowedStable = totalStableDebtBefore.plus(new BigNumber(amountChanged)); if (totalBorrowedStable.eq(0)) return new BigNumber('0'); @@ -1048,8 +1048,8 @@ const calcExpectedInterestRates = ( reserveSymbol: string, marketStableRate: BigNumber, utilizationRate: BigNumber, - totalBorrowsStable: BigNumber, - totalBorrowsVariable: BigNumber, + totalStableDebt: BigNumber, + totalVariableDebt: BigNumber, averageStableBorrowRate: BigNumber ): BigNumber[] => { const {reservesParams} = configuration; @@ -1093,8 +1093,8 @@ const calcExpectedInterestRates = ( } const expectedOverallRate = calcExpectedOverallBorrowRate( - totalBorrowsStable, - totalBorrowsVariable, + totalStableDebt, + totalVariableDebt, variableBorrowRate, averageStableBorrowRate ); @@ -1104,18 +1104,18 @@ const calcExpectedInterestRates = ( }; const calcExpectedOverallBorrowRate = ( - totalBorrowsStable: BigNumber, - totalBorrowsVariable: BigNumber, + totalStableDebt: BigNumber, + totalVariableDebt: BigNumber, currentVariableBorrowRate: BigNumber, currentAverageStableBorrowRate: BigNumber ): BigNumber => { - const totalBorrows = totalBorrowsStable.plus(totalBorrowsVariable); + const totalBorrows = totalStableDebt.plus(totalVariableDebt); if (totalBorrows.eq(0)) return strToBN('0'); - const weightedVariableRate = totalBorrowsVariable.wadToRay().rayMul(currentVariableBorrowRate); + const weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate); - const weightedStableRate = totalBorrowsStable.wadToRay().rayMul(currentAverageStableBorrowRate); + const weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate); const overallBorrowRate = weightedVariableRate .plus(weightedStableRate) @@ -1125,15 +1125,15 @@ const calcExpectedOverallBorrowRate = ( }; const calcExpectedUtilizationRate = ( - totalBorrowsStable: BigNumber, - totalBorrowsVariable: BigNumber, + totalStableDebt: BigNumber, + totalVariableDebt: BigNumber, totalLiquidity: BigNumber ): BigNumber => { - if (totalBorrowsStable.eq('0') && totalBorrowsVariable.eq('0')) { + if (totalStableDebt.eq('0') && totalVariableDebt.eq('0')) { return strToBN('0'); } - const utilization = totalBorrowsStable.plus(totalBorrowsVariable).rayDiv(totalLiquidity); + const utilization = totalStableDebt.plus(totalVariableDebt).rayDiv(totalLiquidity); return utilization; }; @@ -1210,8 +1210,8 @@ const calcExpectedLiquidityIndex = (reserveData: ReserveData, timestamp: BigNumb }; const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: BigNumber) => { - //if totalBorrowsVariable is 0, nothing to compound - if (reserveData.totalBorrowsVariable.eq('0')) { + //if totalVariableDebt is 0, nothing to compound + if (reserveData.totalVariableDebt.eq('0')) { return reserveData.variableBorrowIndex; } diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index 1d2516ad..2289c7ad 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -26,14 +26,14 @@ export const getReserveData = async ( const decimals = new BigNumber(await token.decimals()); const totalLiquidity = new BigNumber(data.availableLiquidity.toString()) - .plus(data.totalBorrowsStable.toString()) - .plus(data.totalBorrowsVariable.toString()); + .plus(data.totalStableDebt.toString()) + .plus(data.totalVariableDebt.toString()); const utilizationRate = new BigNumber( totalLiquidity.eq(0) ? 0 - : new BigNumber(data.totalBorrowsStable.toString()) - .plus(data.totalBorrowsVariable.toString()) + : new BigNumber(data.totalStableDebt.toString()) + .plus(data.totalVariableDebt.toString()) .rayDiv(totalLiquidity) ); @@ -41,8 +41,8 @@ export const getReserveData = async ( totalLiquidity, utilizationRate, availableLiquidity: new BigNumber(data.availableLiquidity.toString()), - totalBorrowsStable: new BigNumber(data.totalBorrowsStable.toString()), - totalBorrowsVariable: new BigNumber(data.totalBorrowsVariable.toString()), + totalStableDebt: new BigNumber(data.totalStableDebt.toString()), + totalVariableDebt: new BigNumber(data.totalVariableDebt.toString()), liquidityRate: new BigNumber(data.liquidityRate.toString()), variableBorrowRate: new BigNumber(data.variableBorrowRate.toString()), stableBorrowRate: new BigNumber(data.stableBorrowRate.toString()), diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts index 2acbfa31..b0497592 100644 --- a/test/helpers/utils/interfaces/index.ts +++ b/test/helpers/utils/interfaces/index.ts @@ -21,8 +21,8 @@ export interface ReserveData { decimals: BigNumber; totalLiquidity: BigNumber; availableLiquidity: BigNumber; - totalBorrowsStable: BigNumber; - totalBorrowsVariable: BigNumber; + totalStableDebt: BigNumber; + totalVariableDebt: BigNumber; averageStableBorrowRate: BigNumber; variableBorrowRate: BigNumber; stableBorrowRate: BigNumber; From d542f098c14ca31f60286eb75c158c7b4b656872 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 19:25:45 +0200 Subject: [PATCH 18/79] fixed deposit, withdraw tests --- contracts/libraries/logic/ReserveLogic.sol | 20 ++-- contracts/tokenization/StableDebtToken.sol | 32 ++++-- .../interfaces/IStableDebtToken.sol | 16 ++- helpers/contracts-helpers.ts | 15 +++ test/helpers/utils/calculations.ts | 97 ++++++++++++------- test/helpers/utils/helpers.ts | 55 ++++++----- test/helpers/utils/interfaces/index.ts | 2 + test/scenario.spec.ts | 2 +- 8 files changed, 157 insertions(+), 82 deletions(-) diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index b287094a..73b68f17 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -31,7 +31,6 @@ library ReserveLogic { * @param reserve the address of the reserve * @param liquidityRate the new liquidity rate * @param stableBorrowRate the new stable borrow rate - * @param averageStableBorrowRate the new average stable borrow rate * @param variableBorrowRate the new variable borrow rate * @param liquidityIndex the new liquidity index * @param variableBorrowIndex the new variable borrow index @@ -40,7 +39,6 @@ library ReserveLogic { address indexed reserve, uint256 liquidityRate, uint256 stableBorrowRate, - uint256 averageStableBorrowRate, uint256 variableBorrowRate, uint256 liquidityIndex, uint256 variableBorrowIndex @@ -190,12 +188,13 @@ library ReserveLogic { } struct UpdateInterestRatesLocalVars { - uint256 currentAvgStableRate; - uint256 availableLiquidity; address stableDebtTokenAddress; + uint256 availableLiquidity; + uint256 totalStableDebt; uint256 newLiquidityRate; uint256 newStableRate; uint256 newVariableRate; + uint256 avgStableRate; } /** @@ -215,8 +214,10 @@ library ReserveLogic { UpdateInterestRatesLocalVars memory vars; vars.stableDebtTokenAddress = reserve.stableDebtTokenAddress; - vars.currentAvgStableRate = IStableDebtToken(vars.stableDebtTokenAddress) - .getAverageStableRate(); + + (vars.totalStableDebt, vars.avgStableRate) = IStableDebtToken(vars.stableDebtTokenAddress) + .getTotalSupplyAndAvgRate(); + vars.availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress); ( @@ -226,9 +227,9 @@ library ReserveLogic { ) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates( reserveAddress, vars.availableLiquidity.add(liquidityAdded).sub(liquidityTaken), - IERC20(vars.stableDebtTokenAddress).totalSupply(), + vars.totalStableDebt, IERC20(reserve.variableDebtTokenAddress).totalSupply(), - vars.currentAvgStableRate, + vars.avgStableRate, reserve.configuration.getReserveFactor() ); require(vars.newLiquidityRate < (1 << 128), 'ReserveLogic: Liquidity rate overflow'); @@ -243,7 +244,6 @@ library ReserveLogic { reserveAddress, vars.newLiquidityRate, vars.newStableRate, - vars.currentAvgStableRate, vars.newVariableRate, reserve.liquidityIndex, reserve.variableBorrowIndex @@ -318,7 +318,7 @@ library ReserveLogic { currentLiquidityRate, lastUpdateTimestamp ); - uint256 index = cumulatedLiquidityInterest.rayMul(reserve.liquidityIndex); + uint256 index = cumulatedLiquidityInterest.rayMul(liquidityIndex); require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); reserve.liquidityIndex = uint128(index); diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 1d166c8f..0434906f 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -219,18 +219,18 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { return (super.totalSupply(), _avgStableRate); } - function totalSupply() public override view returns (uint256) { - uint256 principalSupply = super.totalSupply(); - if (principalSupply == 0) { - return 0; - } - uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( - _avgStableRate, - _totalSupplyTimestamp - ); - return principalSupply.rayMul(cumulatedInterest); + function getTotalSupplyAndAvgRate() public override view returns (uint256, uint256) { + uint256 avgRate = _avgStableRate; + return (_calcTotalSupply(avgRate), avgRate); } + function totalSupply() public override view returns (uint256) { + _calcTotalSupply(_avgStableRate); + } + + function getTotalSupplyLastUpdated() public override view returns(uint40) { + return _totalSupplyTimestamp; + } /** * @dev Returns the principal debt balance of the user from * @return The debt balance of the user since the last burn/mint action @@ -238,4 +238,16 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { function principalBalanceOf(address user) external virtual override view returns (uint256) { return super.balanceOf(user); } + + function _calcTotalSupply(uint256 avgRate) internal view returns(uint256) { + uint256 principalSupply = super.totalSupply(); + if (principalSupply == 0) { + return 0; + } + uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( + avgRate, + _totalSupplyTimestamp + ); + return principalSupply.rayMul(cumulatedInterest); + } } diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index c1e97388..46324e88 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -90,10 +90,20 @@ interface IStableDebtToken { **/ function getPrincipalSupplyAndAvgRate() external view returns (uint256, uint256); - /** - * @dev Returns the principal debt balance of the user + /** + * @dev returns the timestamp of the last update of the total supply + * @return the timestamp + **/ + function getTotalSupplyLastUpdated() external view returns (uint40); + + /** + * @dev returns the total supply and the average stable rate + **/ + function getTotalSupplyAndAvgRate() 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); - } diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index 11780c11..c5edc9da 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -348,6 +348,21 @@ export const getAToken = async (address?: tEthereumAddress) => { ); }; +export const getStableDebtToken = async (address?: tEthereumAddress) => { + return await getContract( + eContractid.StableDebtToken, + address || (await getDb().get(`${eContractid.StableDebtToken}.${BRE.network.name}`).value()).address + ); +}; + +export const getVariableDebtToken = async (address?: tEthereumAddress) => { + return await getContract( + eContractid.VariableDebtToken, + address || (await getDb().get(`${eContractid.VariableDebtToken}.${BRE.network.name}`).value()).address + ); +}; + + export const getMintableErc20 = async (address: tEthereumAddress) => { return await getContract( eContractid.MintableERC20, diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 9c84d851..98d52cf2 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -42,7 +42,7 @@ export const calcExpectedUserDataAfterDeposit = ( ); expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt; + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex; expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; @@ -115,7 +115,7 @@ export const calcExpectedUserDataAfterWithdraw = ( expectedUserData.currentATokenBalance = aTokenBalance.minus(amountWithdrawn); expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; - expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt; + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( userDataBeforeAction, @@ -166,9 +166,28 @@ export const calcExpectedReserveDataAfterDeposit = ( reserveDataBeforeAction.availableLiquidity ).plus(amountDeposited); - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( + reserveDataBeforeAction, + txTimestamp + ); + + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( + reserveDataBeforeAction, + expectedReserveData.variableBorrowIndex + ); + + + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, @@ -186,17 +205,7 @@ export const calcExpectedReserveDataAfterDeposit = ( expectedReserveData.liquidityRate = rates[0]; expectedReserveData.stableBorrowRate = rates[1]; expectedReserveData.variableBorrowRate = rates[2]; - - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - + return expectedReserveData; }; @@ -225,8 +234,21 @@ export const calcExpectedReserveDataAfterWithdraw = ( reserveDataBeforeAction.availableLiquidity ).minus(amountWithdrawn); - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; + + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( + reserveDataBeforeAction, + txTimestamp + ); + + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(reserveDataBeforeAction, txTimestamp); + expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(reserveDataBeforeAction, expectedReserveData.variableBorrowIndex); + expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; expectedReserveData.utilizationRate = calcExpectedUtilizationRate( @@ -246,16 +268,6 @@ export const calcExpectedReserveDataAfterWithdraw = ( expectedReserveData.stableBorrowRate = rates[1]; expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - return expectedReserveData; }; @@ -512,7 +524,9 @@ export const calcExpectedUserDataAfterBorrow = ( expectedDataAfterAction, { ...userDataBeforeAction, - currentVariableDebt: expectedUserData.scaledVariableDebt.rayMul(reserveDataBeforeAction.variableBorrowIndex), + currentVariableDebt: expectedUserData.scaledVariableDebt.rayMul( + reserveDataBeforeAction.variableBorrowIndex + ), scaledVariableDebt: expectedUserData.scaledVariableDebt, variableBorrowIndex: interestRateMode == RateMode.Variable @@ -690,13 +704,14 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( userDataBeforeAction.principalStableDebt ); } else { - const totalDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul(reserveDataBeforeAction.variableBorrowIndex); + const totalDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( + reserveDataBeforeAction.variableBorrowIndex + ); const debtAccrued = variableDebt.minus(totalDebtBefore); expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( variableDebt @@ -838,9 +853,7 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( ); expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( - debtAccrued - ); + expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus(debtAccrued); expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, @@ -1223,3 +1236,19 @@ const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: Bi return cumulatedInterest.rayMul(reserveData.variableBorrowIndex); }; + +const calcExpectedTotalStableDebt = (reserveData: ReserveData, timestamp: BigNumber) => { + + const cumulatedInterest = calcCompoundedInterest( + reserveData.averageStableBorrowRate, + timestamp, + reserveData.lastUpdateTimestamp + ); + + return cumulatedInterest.rayMul(reserveData.principalStableDebt); +} + +const calcExpectedTotalVariableDebt = (reserveData: ReserveData, expectedVariableDebtIndex: BigNumber) => { + + return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex); +} diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index 2289c7ad..3f3a2ec8 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -4,9 +4,8 @@ import { getLendingRateOracle, getIErc20Detailed, getMintableErc20, - getAToken, + getAToken, getStableDebtToken, getVariableDebtToken } from '../../../helpers/contracts-helpers'; -import {ZERO_ADDRESS} from '../../../helpers/constants'; import {tEthereumAddress} from '../../../helpers/types'; import BigNumber from 'bignumber.js'; import {getDb, BRE} from '../../../helpers/misc-utils'; @@ -15,41 +14,51 @@ export const getReserveData = async ( pool: LendingPool, reserve: tEthereumAddress ): Promise => { - const data = await pool.getReserveData(reserve); - const tokenAddresses = await pool.getReserveTokensAddresses(reserve); - const rateOracle = await getLendingRateOracle(); + const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([ + pool.getReserveData(reserve), + pool.getReserveTokensAddresses(reserve), + getLendingRateOracle(), + getIErc20Detailed(reserve), + ]); + + const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress); + const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); + + const [principalStableDebt] = await stableDebtToken.getPrincipalSupplyAndAvgRate(); + + const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString(); - - const token = await getIErc20Detailed(reserve); const symbol = await token.symbol(); const decimals = new BigNumber(await token.decimals()); - const totalLiquidity = new BigNumber(data.availableLiquidity.toString()) - .plus(data.totalStableDebt.toString()) - .plus(data.totalVariableDebt.toString()); + const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString()) + .plus(reserveData.totalStableDebt.toString()) + .plus(reserveData.totalVariableDebt.toString()); const utilizationRate = new BigNumber( totalLiquidity.eq(0) ? 0 - : new BigNumber(data.totalStableDebt.toString()) - .plus(data.totalVariableDebt.toString()) + : new BigNumber(reserveData.totalStableDebt.toString()) + .plus(reserveData.totalVariableDebt.toString()) .rayDiv(totalLiquidity) ); return { totalLiquidity, utilizationRate, - availableLiquidity: new BigNumber(data.availableLiquidity.toString()), - totalStableDebt: new BigNumber(data.totalStableDebt.toString()), - totalVariableDebt: new BigNumber(data.totalVariableDebt.toString()), - liquidityRate: new BigNumber(data.liquidityRate.toString()), - variableBorrowRate: new BigNumber(data.variableBorrowRate.toString()), - stableBorrowRate: new BigNumber(data.stableBorrowRate.toString()), - averageStableBorrowRate: new BigNumber(data.averageStableBorrowRate.toString()), - liquidityIndex: new BigNumber(data.liquidityIndex.toString()), - variableBorrowIndex: new BigNumber(data.variableBorrowIndex.toString()), - lastUpdateTimestamp: new BigNumber(data.lastUpdateTimestamp), + availableLiquidity: new BigNumber(reserveData.availableLiquidity.toString()), + totalStableDebt: new BigNumber(reserveData.totalStableDebt.toString()), + totalVariableDebt: new BigNumber(reserveData.totalVariableDebt.toString()), + liquidityRate: new BigNumber(reserveData.liquidityRate.toString()), + variableBorrowRate: new BigNumber(reserveData.variableBorrowRate.toString()), + stableBorrowRate: new BigNumber(reserveData.stableBorrowRate.toString()), + averageStableBorrowRate: new BigNumber(reserveData.averageStableBorrowRate.toString()), + liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()), + variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()), + lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp), + principalStableDebt: new BigNumber(principalStableDebt.toString()), + scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()), address: reserve, aTokenAddress: tokenAddresses.aTokenAddress, symbol, @@ -69,7 +78,6 @@ export const getUserData = async ( getATokenUserData(reserve, user, pool), ]); - const token = await getMintableErc20(reserve); const walletBalance = new BigNumber((await token.balanceOf(sender || user)).toString()); @@ -106,5 +114,4 @@ const getATokenUserData = async (reserve: string, user: string, pool: LendingPoo const scaledBalance = await aToken.scaledBalanceOf(user); return scaledBalance.toString(); - }; diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts index b0497592..3162e398 100644 --- a/test/helpers/utils/interfaces/index.ts +++ b/test/helpers/utils/interfaces/index.ts @@ -23,6 +23,8 @@ export interface ReserveData { availableLiquidity: BigNumber; totalStableDebt: BigNumber; totalVariableDebt: BigNumber; + principalStableDebt: BigNumber, + scaledVariableDebt: BigNumber, averageStableBorrowRate: BigNumber; variableBorrowRate: BigNumber; stableBorrowRate: BigNumber; diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 17830d1c..ee45a08f 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['deposit.json']; +const selectedScenarios: string[] = ['withdraw.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From d0d1db5e4d7e686ad44993310526282a158bc239 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 14 Sep 2020 20:04:49 +0200 Subject: [PATCH 19/79] Initial fix of the borrow tests --- test/helpers/utils/calculations.ts | 28 ++++++++++------------------ test/scenario.spec.ts | 2 +- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 98d52cf2..4c6d951e 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -30,12 +30,12 @@ export const calcExpectedUserDataAfterDeposit = ( ): UserReserveData => { const expectedUserData = {}; - expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance( + expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( userDataBeforeAction, txTimestamp ); - expectedUserData.currentVariableDebt = expectedUserData.principalStableDebt = calcExpectedVariableDebtTokenBalance( + expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( reserveDataBeforeAction, userDataBeforeAction, txTimestamp @@ -285,22 +285,23 @@ export const calcExpectedReserveDataAfterBorrow = ( const amountBorrowedBN = new BigNumber(amountBorrowed); - const userStableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); - - const userVariableDebt = calcExpectedVariableDebtTokenBalance( + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( reserveDataBeforeAction, - userDataBeforeAction, txTimestamp ); if (borrowRateMode == RateMode.Stable) { + + expectedReserveData. const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt); expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt - .plus(amountBorrowedBN) - .plus(debtAccrued); + expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, @@ -347,15 +348,6 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.lastUpdateTimestamp = txTimestamp; return expectedReserveData; diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index ee45a08f..98e0c164 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['withdraw.json']; +const selectedScenarios: string[] = ['borrow-repay-variable.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 04a67d3df0bbc95c24e882255fff2c5c93c5ec54 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 15 Sep 2020 18:49:53 +0200 Subject: [PATCH 20/79] updated stabledebttoken --- contracts/tokenization/StableDebtToken.sol | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 85277ddc..7ba4ad31 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -81,10 +81,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } struct MintLocalVars { - uint256 supplyAfterMint; - uint256 supplyBeforeMint; + uint256 currentPrincipalSupply; + uint256 nextSupply; uint256 amountInRay; uint256 newStableRate; + uint256 currentAvgStableRate; } /** @@ -108,8 +109,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 balanceIncrease ) = _calculateBalanceIncrease(user); - vars.supplyBeforeMint = totalSupply().add(balanceIncrease); - vars.supplyAfterMint = vars.supplyBeforeMint.add(amount); + vars.currentPrincipalSupply = totalSupply(); + vars.currentAvgStableRate = _avgStableRate; + vars.nextSupply = _totalSupply = _calcTotalSupply(vars.currentAvgStableRate).add(amount); vars.amountInRay = amount.wadToRay(); @@ -126,10 +128,10 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); //calculates the updated average stable rate - _avgStableRate = _avgStableRate - .rayMul(vars.supplyBeforeMint.wadToRay()) + _avgStableRate = vars.currentAvgStableRate + .rayMul(vars.currentPrincipalSupply.wadToRay()) .add(rate.rayMul(vars.amountInRay)) - .rayDiv(vars.supplyAfterMint.wadToRay()); + .rayDiv(vars.nextSupply.wadToRay()); _mint(user, amount.add(balanceIncrease)); @@ -237,6 +239,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { function getTotalSupplyLastUpdated() public override view returns(uint40) { return _totalSupplyTimestamp; } + /** * @dev Returns the principal debt balance of the user from * @return The debt balance of the user since the last burn/mint action From d873b630829e97ba63b0afc18fb0d0e157197477 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 15 Sep 2020 18:54:59 +0200 Subject: [PATCH 21/79] Removed unused flashloan vars --- contracts/lendingpool/LendingPool.sol | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 2c9ad98a..36335e94 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -453,19 +453,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { } } - struct FlashLoanLocalVars { - uint256 premium; - uint256 amountPlusPremium; - uint256 amountPlusPremiumInETH; - uint256 receiverBalance; - uint256 receiverAllowance; - uint256 availableBalance; - uint256 assetPrice; - IFlashLoanReceiver receiver; - address aTokenAddress; - address oracle; - } - /** * @dev flashes the underlying collateral on an user to swap for the owed asset and repay * - Both the owner of the position and other liquidators can execute it @@ -514,6 +501,14 @@ contract LendingPool is VersionedInitializable, ILendingPool { _flashLiquidationLocked = false; } + struct FlashLoanLocalVars { + uint256 premium; + uint256 amountPlusPremium; + IFlashLoanReceiver receiver; + address aTokenAddress; + address oracle; + } + /** * @dev allows smartcontracts to access the liquidity of the pool within one transaction, * as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts @@ -569,7 +564,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { asset, msg.sender, msg.sender, - vars.amountPlusPremium.sub(vars.availableBalance), + vars.amountPlusPremium, mode, vars.aTokenAddress, referralCode, From 77c812b975c1278a29d9350a3c027951b8001567 Mon Sep 17 00:00:00 2001 From: andyk Date: Wed, 16 Sep 2020 13:16:51 +0300 Subject: [PATCH 22/79] Refactor the storage of lendingpool to LendingPoolStorage parent contract --- contracts/lendingpool/LendingPool.sol | 40 +--- .../LendingPoolLiquidationManager.sol | 65 +++---- contracts/lendingpool/LendingPoolStorage.sol | 39 ++++ deployed-contracts.json | 173 +++++++++++++++++- 4 files changed, 241 insertions(+), 76 deletions(-) create mode 100644 contracts/lendingpool/LendingPoolStorage.sol diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 69a92b6f..aa3a758b 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -25,6 +25,7 @@ import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; +import {LendingPoolStorage} from './LendingPoolStorage.sol'; /** * @title LendingPool contract @@ -32,12 +33,9 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol'; * @author Aave **/ -contract LendingPool is VersionedInitializable, ILendingPool { +contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage { using SafeMath for uint256; using WadRayMath for uint256; - using ReserveLogic for ReserveLogic.ReserveData; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; using SafeERC20 for IERC20; //main configuration parameters @@ -45,18 +43,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; - ILendingPoolAddressesProvider internal _addressesProvider; - - mapping(address => ReserveLogic.ReserveData) internal _reserves; - mapping(address => UserConfiguration.Map) internal _usersConfig; - // debt token address => user who gives allowance => user who receives allowance => amount - mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; - - address[] internal _reservesList; - - bool internal _flashLiquidationLocked; - bool internal _paused; - /** * @dev only lending pools configurator can use functions affected by this modifier **/ @@ -78,8 +64,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { require(!_paused, Errors.IS_PAUSED); } - uint256 public constant UINT_MAX_VALUE = uint256(-1); - uint256 public constant LENDINGPOOL_REVISION = 0x2; function getRevision() internal override pure returns (uint256) { @@ -147,7 +131,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 amountToWithdraw = amount; //if amount is equal to uint(-1), the user wants to redeem everything - if (amount == UINT_MAX_VALUE) { + if (amount == type(uint256).max) { amountToWithdraw = userBalance; } @@ -283,7 +267,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { ? stableDebt : variableDebt; - if (amount != UINT_MAX_VALUE && amount < paybackAmount) { + if (amount != type(uint256).max && amount < paybackAmount) { paybackAmount = amount; } @@ -1003,20 +987,6 @@ contract LendingPool is VersionedInitializable, ILendingPool { ); } - /** - * @dev returns the list of the initialized reserves - **/ - function getReservesList() external view returns (address[] memory) { - return _reservesList; - } - - /** - * @dev returns the addresses provider - **/ - function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { - return _addressesProvider; - } - /** * @dev Set the _pause state * @param val the boolean value to set the current pause state of LendingPool @@ -1035,7 +1005,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { /** * @dev Returns if the LendingPool is paused */ - function paused() external view override returns(bool) { + function paused() external override view returns (bool) { return _paused; } } diff --git a/contracts/lendingpool/LendingPoolLiquidationManager.sol b/contracts/lendingpool/LendingPoolLiquidationManager.sol index 6adc18d9..6e488428 100644 --- a/contracts/lendingpool/LendingPoolLiquidationManager.sol +++ b/contracts/lendingpool/LendingPoolLiquidationManager.sol @@ -6,14 +6,12 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { VersionedInitializable } from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol'; -import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol'; import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; -import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; @@ -22,6 +20,7 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ISwapAdapter} from '../interfaces/ISwapAdapter.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; +import {LendingPoolStorage} from './LendingPoolStorage.sol'; /** * @title LendingPoolLiquidationManager contract @@ -29,29 +28,15 @@ import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; * @notice Implements the liquidation function. * @dev LendingPoolLiquidationManager inherits Pausable from OpenZeppelin to have the same storage layout as LendingPool **/ -contract LendingPoolLiquidationManager is VersionedInitializable { +contract LendingPoolLiquidationManager is VersionedInitializable, LendingPoolStorage { using SafeERC20 for IERC20; using SafeMath for uint256; using WadRayMath for uint256; using PercentageMath for uint256; - using ReserveLogic for ReserveLogic.ReserveData; - using ReserveConfiguration for ReserveConfiguration.Map; - using UserConfiguration for UserConfiguration.Map; // IMPORTANT The storage layout of the LendingPool is reproduced here because this contract // is gonna be used through DELEGATECALL - LendingPoolAddressesProvider internal addressesProvider; - - mapping(address => ReserveLogic.ReserveData) internal reserves; - mapping(address => UserConfiguration.Map) internal usersConfig; - mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; - - address[] internal reservesList; - - bool internal _flashLiquidationLocked; - bool public _paused; - uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000; /** @@ -156,18 +141,18 @@ contract LendingPoolLiquidationManager is VersionedInitializable { uint256 purchaseAmount, bool receiveAToken ) external returns (uint256, string memory) { - ReserveLogic.ReserveData storage collateralReserve = reserves[collateral]; - ReserveLogic.ReserveData storage principalReserve = reserves[principal]; - UserConfiguration.Map storage userConfig = usersConfig[user]; + ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral]; + ReserveLogic.ReserveData storage principalReserve = _reserves[principal]; + UserConfiguration.Map storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; (, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData( user, - reserves, - usersConfig[user], - reservesList, - addressesProvider.getPriceOracle() + _reserves, + _usersConfig[user], + _reservesList, + _addressesProvider.getPriceOracle() ); //if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated @@ -323,18 +308,18 @@ contract LendingPoolLiquidationManager is VersionedInitializable { address receiver, bytes calldata params ) external returns (uint256, string memory) { - ReserveLogic.ReserveData storage collateralReserve = reserves[collateral]; - ReserveLogic.ReserveData storage debtReserve = reserves[principal]; - UserConfiguration.Map storage userConfig = usersConfig[user]; + ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral]; + ReserveLogic.ReserveData storage debtReserve = _reserves[principal]; + UserConfiguration.Map storage userConfig = _usersConfig[user]; LiquidationCallLocalVars memory vars; (, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData( user, - reserves, - usersConfig[user], - reservesList, - addressesProvider.getPriceOracle() + _reserves, + _usersConfig[user], + _reservesList, + _addressesProvider.getPriceOracle() ); (vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve); @@ -391,7 +376,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { ); if (vars.userCollateralBalance == vars.maxCollateralToLiquidate) { - usersConfig[user].setUsingAsCollateral(collateralReserve.id, false); + _usersConfig[user].setUsingAsCollateral(collateralReserve.id, false); } vars.principalAToken = debtReserve.aTokenAddress; @@ -463,8 +448,8 @@ contract LendingPoolLiquidationManager is VersionedInitializable { uint256 amountToSwap, bytes calldata params ) external returns (uint256, string memory) { - ReserveLogic.ReserveData storage fromReserve = reserves[fromAsset]; - ReserveLogic.ReserveData storage toReserve = reserves[toAsset]; + ReserveLogic.ReserveData storage fromReserve = _reserves[fromAsset]; + ReserveLogic.ReserveData storage toReserve = _reserves[toAsset]; // Usage of a memory struct of vars to avoid "Stack too deep" errors due to local variables SwapLiquidityLocalVars memory vars; @@ -487,7 +472,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { toReserve.updateCumulativeIndexesAndTimestamp(); if (vars.fromReserveAToken.balanceOf(msg.sender) == amountToSwap) { - usersConfig[msg.sender].setUsingAsCollateral(fromReserve.id, false); + _usersConfig[msg.sender].setUsingAsCollateral(fromReserve.id, false); } fromReserve.updateInterestRates(fromAsset, address(vars.fromReserveAToken), 0, amountToSwap); @@ -525,10 +510,10 @@ contract LendingPoolLiquidationManager is VersionedInitializable { (, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData( msg.sender, - reserves, - usersConfig[msg.sender], - reservesList, - addressesProvider.getPriceOracle() + _reserves, + _usersConfig[msg.sender], + _reservesList, + _addressesProvider.getPriceOracle() ); if (vars.healthFactor < GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) { @@ -562,7 +547,7 @@ contract LendingPoolLiquidationManager is VersionedInitializable { ) internal view returns (uint256, uint256) { uint256 collateralAmount = 0; uint256 principalAmountNeeded = 0; - IPriceOracleGetter oracle = IPriceOracleGetter(addressesProvider.getPriceOracle()); + IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle()); // Usage of a memory struct of vars to avoid "Stack too deep" errors due to local variables AvailableCollateralToLiquidateLocalVars memory vars; diff --git a/contracts/lendingpool/LendingPoolStorage.sol b/contracts/lendingpool/LendingPoolStorage.sol new file mode 100644 index 00000000..1f1e6d2e --- /dev/null +++ b/contracts/lendingpool/LendingPoolStorage.sol @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.6.8; + +import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; +import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; +import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; +import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; + +contract LendingPoolStorage { + using ReserveLogic for ReserveLogic.ReserveData; + using ReserveConfiguration for ReserveConfiguration.Map; + using UserConfiguration for UserConfiguration.Map; + + ILendingPoolAddressesProvider internal _addressesProvider; + + mapping(address => ReserveLogic.ReserveData) internal _reserves; + mapping(address => UserConfiguration.Map) internal _usersConfig; + // debt token address => user who gives allowance => user who receives allowance => amount + mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; + + address[] internal _reservesList; + + bool internal _flashLiquidationLocked; + bool internal _paused; + + /** + * @dev returns the list of the initialized reserves + **/ + function getReservesList() external view returns (address[] memory) { + return _reservesList; + } + + /** + * @dev returns the addresses provider + **/ + function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { + return _addressesProvider; + } +} diff --git a/deployed-contracts.json b/deployed-contracts.json index 9981b17c..60c63dd8 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -7,6 +7,10 @@ "localhost": { "address": "0x9Dc554694756dC303a087e04bA6918C333Bc26a7", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LendingPoolAddressesProvider": { @@ -17,6 +21,10 @@ "localhost": { "address": "0xAfC307938C1c0035942c141c31524504c89Aaa8B", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LendingPoolAddressesProviderRegistry": { @@ -27,6 +35,10 @@ "localhost": { "address": "0x73DE1e0ab6A5C221258703bc546E0CAAcCc6EC87", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "FeeProvider": { @@ -54,6 +66,9 @@ }, "localhost": { "address": "0x65e0Cd5B8904A02f2e00BC6f58bf881998D54BDe" + }, + "coverage": { + "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" } }, "LendingPoolDataProvider": { @@ -67,6 +82,9 @@ }, "localhost": { "address": "0x5d12dDe3286D94E0d85F9D3B01B7099cfA0aBCf1" + }, + "coverage": { + "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" } }, "PriceOracle": { @@ -77,6 +95,10 @@ "localhost": { "address": "0xbeA90474c2F3C7c43bC7c36CaAf5272c927Af5a1", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x1750499D05Ed1674d822430FB960d5F6731fDf64", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MockAggregator": { @@ -87,6 +109,10 @@ "localhost": { "address": "0x19E42cA990cF697D3dda0e59131215C43bB6989F", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "ChainlinkProxyPriceProvider": { @@ -97,6 +123,10 @@ "localhost": { "address": "0xE30c3983E51bC9d6baE3E9437710a1459e21e81F", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x7B6C3e5486D9e6959441ab554A889099eed76290", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LendingRateOracle": { @@ -107,6 +137,10 @@ "localhost": { "address": "0xDf69898e844197a24C658CcF9fD53dF15948dc8b", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "DefaultReserveInterestRateStrategy": { @@ -117,6 +151,10 @@ "localhost": { "address": "0xBe6d8642382C241c9B4B50c89574DbF3f4181E7D", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x626FdE749F9d499d3777320CAf29484B624ab84a", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LendingPoolLiquidationManager": { @@ -170,6 +208,9 @@ }, "localhost": { "address": "0xAd49512dFBaD6fc13D67d3935283c0606812E962" + }, + "coverage": { + "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" } }, "WalletBalanceProvider": { @@ -180,6 +221,10 @@ "localhost": { "address": "0xA29C2A7e59aa49C71aF084695337E3AA5e820758", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "DAI": { @@ -190,6 +235,10 @@ "localhost": { "address": "0xbe66dC9DFEe580ED968403e35dF7b5159f873df8", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LEND": { @@ -200,6 +249,10 @@ "localhost": { "address": "0x93AfC6Df4bB8F62F2493B19e577f8382c0BA9EBC", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "TUSD": { @@ -210,6 +263,10 @@ "localhost": { "address": "0x75Ded61646B5945BdDd0CD9a9Db7c8288DA6F810", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "BAT": { @@ -220,6 +277,10 @@ "localhost": { "address": "0xdE7c40e675bF1aA45c18cCbaEb9662B16b0Ddf7E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "USDC": { @@ -230,6 +291,10 @@ "localhost": { "address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "USDT": { @@ -240,6 +305,10 @@ "localhost": { "address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "SUSD": { @@ -250,6 +319,10 @@ "localhost": { "address": "0x8F9422aa37215c8b3D1Ea1674138107F84D68F26", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "ZRX": { @@ -260,6 +333,10 @@ "localhost": { "address": "0xa89E20284Bd638F31b0011D0fC754Fc9d2fa73e3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MKR": { @@ -270,6 +347,10 @@ "localhost": { "address": "0xaA935993065F2dDB1d13623B1941C7AEE3A60F23", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xc4905364b78a742ccce7B890A89514061E47068D", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "WBTC": { @@ -280,6 +361,10 @@ "localhost": { "address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "LINK": { @@ -290,6 +375,10 @@ "localhost": { "address": "0x1f569c307949a908A4b8Ff7453a88Ca0b8D8df13", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "KNC": { @@ -300,6 +389,10 @@ "localhost": { "address": "0x4301cb254CCc126B9eb9cbBE030C6FDA2FA16D4a", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MANA": { @@ -310,6 +403,10 @@ "localhost": { "address": "0x0766c9592a8686CAB0081b4f35449462c6e82F11", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "REP": { @@ -320,6 +417,10 @@ "localhost": { "address": "0xaF6D34adD35E1A565be4539E4d1069c48A49C953", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "SNX": { @@ -330,6 +431,10 @@ "localhost": { "address": "0x48bb3E35D2D6994374db457a6Bf61de2d9cC8E49", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "BUSD": { @@ -340,6 +445,10 @@ "localhost": { "address": "0x1E59BA56B1F61c3Ee946D8c7e2994B4A9b0cA45C", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "USD": { @@ -350,6 +459,10 @@ "localhost": { "address": "0x53813198c75959DDB604462831d8989C29152164", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_DAI_ETH": { @@ -360,6 +473,10 @@ "localhost": { "address": "0x0eD6115873ce6B807a03FE0df1f940387779b729", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_USDC_ETH": { @@ -370,6 +487,10 @@ "localhost": { "address": "0xFFfDa24e7E3d5F89a24278f53d6f0F81B3bE0d6B", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_SETH_ETH": { @@ -380,6 +501,10 @@ "localhost": { "address": "0x5889354f21A1C8D8D2f82669d778f6Dab778B519", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_LINK_ETH": { @@ -390,6 +515,10 @@ "localhost": { "address": "0x09F7bF33B3F8922268B34103af3a8AF83148C9B1", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_MKR_ETH": { @@ -400,6 +529,10 @@ "localhost": { "address": "0x8f3966F7d53Fd5f12b701C8835e1e32541613869", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "UNI_LEND_ETH": { @@ -410,6 +543,10 @@ "localhost": { "address": "0x9Dc554694756dC303a087e04bA6918C333Bc26a7", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "AaveProtocolTestHelpers": { @@ -418,6 +555,9 @@ }, "localhost": { "address": "0x9305d862ee95a899b83906Cd9CB666aC269E5f66" + }, + "coverage": { + "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" } }, "StableDebtToken": { @@ -428,6 +568,10 @@ "localhost": { "address": "0x02BB514187B830d6A2111197cd7D8cb60650B970", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "VariableDebtToken": { @@ -438,6 +582,10 @@ "localhost": { "address": "0x6774Ce86Abf5EBB22E9F45b5f55daCbB4170aD7f", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "AToken": { @@ -448,6 +596,10 @@ "buidlerevm": { "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MockAToken": { @@ -458,6 +610,10 @@ "localhost": { "address": "0xFBdF1E93D0D88145e3CcA63bf8d513F83FB0903b", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x392E5355a0e88Bd394F717227c752670fb3a8020", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "WETH": { @@ -468,6 +624,10 @@ "localhost": { "address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MockStableDebtToken": { @@ -478,6 +638,10 @@ "localhost": { "address": "0xE45fF4A0A8D0E9734C73874c034E03594E15ba28", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MockVariableDebtToken": { @@ -488,11 +652,18 @@ "localhost": { "address": "0x5cCC6Abc4c9F7262B9485797a848Ec6CC28A11dF", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" + }, + "coverage": { + "address": "0xEBAB67ee3ef604D5c250A53b4b8fcbBC6ec3007C", + "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "MockSwapAdapter": { "buidlerevm": { "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" + }, + "coverage": { + "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" } } -} +} \ No newline at end of file From 570a81a1b24e4c183ba5ec3336622456aa353a44 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 16 Sep 2020 16:44:27 +0200 Subject: [PATCH 23/79] Fixed aToken deployment function --- contracts/lendingpool/LendingPool.sol | 1 - contracts/tokenization/StableDebtToken.sol | 6 +++--- helpers/contracts-helpers.ts | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 7ea95be3..288de674 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -33,7 +33,6 @@ import {ILendingPool} from '../interfaces/ILendingPool.sol'; * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data * @author Aave **/ - contract LendingPool is VersionedInitializable, ILendingPool { using SafeMath for uint256; using WadRayMath for uint256; diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 75771d18..5b286e93 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -82,7 +82,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } struct MintLocalVars { - uint256 currentPrincipalSupply; + uint256 currentSupply; uint256 nextSupply; uint256 amountInRay; uint256 newStableRate; @@ -110,9 +110,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 balanceIncrease ) = _calculateBalanceIncrease(user); - vars.currentPrincipalSupply = totalSupply(); + vars.currentSupply = totalSupply(); vars.currentAvgStableRate = _avgStableRate; - vars.nextSupply = _totalSupply = _calcTotalSupply(vars.currentAvgStableRate).add(amount); + vars.nextSupply = vars.currentSupply.add(amount); vars.amountInRay = amount.wadToRay(); diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index 3c3a66bb..e871f469 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -299,7 +299,7 @@ export const deployGenericAToken = async ([ const token = await deployContract(eContractid.AToken, [ poolAddress, underlyingAssetAddress, - ZERO_ADDRESS, + reserveTreasuryAddress, name, symbol, incentivesController, From 5c2ec07b709d7dae63998d6a9f58277d4a67e266 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 16 Sep 2020 17:12:07 +0200 Subject: [PATCH 24/79] Fixes #42 --- contracts/lendingpool/LendingPool.sol | 2 ++ contracts/libraries/helpers/Errors.sol | 1 + 2 files changed, 3 insertions(+) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index e6a3c059..c9919495 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -44,6 +44,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5; uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; + uint256 public constant MAX_NUMBER_RESERVES = 128; ILendingPoolAddressesProvider internal _addressesProvider; @@ -945,6 +946,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { **/ function _addReserveToList(address asset) internal { bool reserveAlreadyAdded = false; + require(_reservesList.length < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); for (uint256 i = 0; i < _reservesList.length; i++) if (_reservesList[i] == asset) { reserveAlreadyAdded = true; diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol index d25b041b..23431b03 100644 --- a/contracts/libraries/helpers/Errors.sol +++ b/contracts/libraries/helpers/Errors.sol @@ -43,6 +43,7 @@ library Errors { string public constant FAILED_REPAY_WITH_COLLATERAL = '53'; string public constant FAILED_COLLATERAL_SWAP = '55'; string public constant INVALID_EQUAL_ASSETS_TO_SWAP = '56'; + string public constant NO_MORE_RESERVES_ALLOWED = '59'; // require error messages - aToken string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool' From bcdef6fa7e39e7dd6fa2111dbf8ba89c00faca6d Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 16 Sep 2020 20:00:13 +0200 Subject: [PATCH 25/79] Added change to the stabledebttoken --- contracts/tokenization/StableDebtToken.sol | 11 +++++++---- .../tokenization/interfaces/IStableDebtToken.sol | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 5b286e93..610b2ae8 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -110,7 +110,8 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 balanceIncrease ) = _calculateBalanceIncrease(user); - vars.currentSupply = totalSupply(); + //accrueing the interest accumulation to the stored total supply and caching it + vars.currentSupply = _totalSupply = totalSupply(); vars.currentAvgStableRate = _avgStableRate; vars.nextSupply = vars.currentSupply.add(amount); @@ -125,12 +126,13 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { require(vars.newStableRate < (1 << 128), 'Debt token: stable rate overflow'); _usersData[user] = vars.newStableRate; + //updating the user and supply timestamp //solium-disable-next-line _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); //calculates the updated average stable rate _avgStableRate = vars.currentAvgStableRate - .rayMul(vars.currentPrincipalSupply.wadToRay()) + .rayMul(vars.currentSupply.wadToRay()) .add(rate.rayMul(vars.amountInRay)) .rayDiv(vars.nextSupply.wadToRay()); @@ -224,8 +226,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ); } - function getPrincipalSupplyAndAvgRate() public override view returns (uint256, uint256) { - return (super.totalSupply(), _avgStableRate); + function getSupplyData() public override view returns (uint256, uint256, uint256) { + uint256 avgRate = _avgStableRate; + return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate); } function getTotalSupplyAndAvgRate() public override view returns (uint256, uint256) { diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index 46324e88..0e75bae4 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -86,9 +86,9 @@ interface IStableDebtToken { function getUserLastUpdated(address user) external view returns (uint40); /** - * @dev returns the principal total supply and the average stable rate + * @dev returns the principal, the total supply and the average stable rate **/ - function getPrincipalSupplyAndAvgRate() external view returns (uint256, uint256); + function getSupplyData() external view returns (uint256, uint256, uint256); /** * @dev returns the timestamp of the last update of the total supply From 7986a4704b98b3fa0f63fefc8f2fce01feb48426 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 10:53:55 +0200 Subject: [PATCH 26/79] Fixed mintToTreasury function --- contracts/libraries/logic/ReserveLogic.sol | 102 ++++++++++++------ contracts/tokenization/StableDebtToken.sol | 23 ++-- .../interfaces/IVariableDebtToken.sol | 2 +- test/helpers/utils/calculations.ts | 3 +- 4 files changed, 85 insertions(+), 45 deletions(-) diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index aed82e45..ecd96954 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -150,12 +150,28 @@ library ReserveLogic { function updateState(ReserveData storage reserve) internal { address stableDebtToken = reserve.stableDebtTokenAddress; address variableDebtToken = reserve.variableDebtTokenAddress; - uint256 variableBorrowIndex = reserve.variableBorrowIndex; - uint256 liquidityIndex = reserve.liquidityIndex; + uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex; + uint256 previousLiquidityIndex = reserve.liquidityIndex; uint40 timestamp = reserve.lastUpdateTimestamp; - _mintToTreasury(reserve, stableDebtToken, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp); - _updateIndexes(reserve, variableDebtToken, liquidityIndex, variableBorrowIndex, timestamp); + (uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes( + reserve, + variableDebtToken, + previousLiquidityIndex, + previousVariableBorrowIndex, + timestamp + ); + + _mintToTreasury( + reserve, + stableDebtToken, + variableDebtToken, + previousLiquidityIndex, + previousVariableBorrowIndex, + newLiquidityIndex, + newVariableBorrowIndex, + timestamp + ); } /** @@ -212,7 +228,7 @@ library ReserveLogic { struct UpdateInterestRatesLocalVars { address stableDebtTokenAddress; uint256 availableLiquidity; - uint256 totalStableDebt; + uint256 totalStableDebt; uint256 newLiquidityRate; uint256 newStableRate; uint256 newVariableRate; @@ -273,14 +289,15 @@ library ReserveLogic { } struct MintToTreasuryLocalVars { - uint256 currentTotalDebt; + uint256 currentStableDebt; uint256 principalStableDebt; - uint256 avgStableRate; + uint256 previousStableDebt; + uint256 currentVariableDebt; uint256 scaledVariableDebt; + uint256 previousVariableDebt; + uint256 avgStableRate; uint256 cumulatedStableInterest; - uint256 variableDebtOnLastUpdate; - uint256 stableDebtOnLastUpdate; - uint256 totalInterestAccrued; + uint256 totalDebtAccrued; uint256 amountToMint; uint256 reserveFactor; } @@ -289,40 +306,53 @@ library ReserveLogic { ReserveData storage reserve, address stableDebtToken, address variableDebtToken, - uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp + uint256 previousLiquidityIndex, + uint256 previousVariableBorrowIndex, + uint256 newLiquidityIndex, + uint256 newVariableBorrowIndex, + uint40 previousTimestamp ) internal { - MintToTreasuryLocalVars memory vars; vars.reserveFactor = reserve.configuration.getReserveFactor(); - if(vars.reserveFactor == 0){ + if (vars.reserveFactor == 0) { return; } - vars.currentTotalDebt = IERC20(variableDebtToken).totalSupply().add(IERC20(stableDebtToken).totalSupply()); - - (vars.principalStableDebt, vars.avgStableRate) = IStableDebtToken(stableDebtToken) - .getPrincipalSupplyAndAvgRate(); - + //fetching the last scaled total variable debt vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply(); + //fetching the principal, total stable debt and the avg stable rate + (vars.principalStableDebt, vars.currentStableDebt, vars.avgStableRate) = IStableDebtToken( + stableDebtToken + ) + .getSupplyData(); + + //calculate the last principal variable debt + vars.previousVariableDebt = vars.scaledVariableDebt.rayMul(previousVariableBorrowIndex); + + //calculate the new total supply after accumulation of the index + vars.currentVariableDebt = vars.scaledVariableDebt.rayMul(newVariableBorrowIndex); + + //calculate the stable debt until the last timestamp update vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( vars.avgStableRate, - lastUpdateTimestamp + previousTimestamp ); - vars.variableDebtOnLastUpdate = vars.scaledVariableDebt.rayMul(variableBorrowIndex); - vars.stableDebtOnLastUpdate = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest); + vars.previousStableDebt = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest); - vars.totalInterestAccrued =vars.currentTotalDebt.sub(vars.variableDebtOnLastUpdate.add(vars.stableDebtOnLastUpdate)); + //debt accrued is the sum of the current debt minus the sum of the debt at the last update + vars.totalDebtAccrued = vars + .currentVariableDebt + .add(vars.currentStableDebt) + .sub(vars.previousVariableDebt) + .sub(vars.previousStableDebt); - vars.amountToMint = vars.totalInterestAccrued.percentMul(vars.reserveFactor); - - IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, liquidityIndex); + vars.amountToMint = vars.totalDebtAccrued.percentMul(vars.reserveFactor); + IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex); } function _updateIndexes( @@ -331,19 +361,22 @@ library ReserveLogic { uint256 liquidityIndex, uint256 variableBorrowIndex, uint40 lastUpdateTimestamp - ) internal { + ) internal returns (uint256, uint256) { uint256 currentLiquidityRate = reserve.currentLiquidityRate; + uint256 newLiquidityIndex = liquidityIndex; + uint256 newVariableBorrowIndex = variableBorrowIndex; + //only cumulating if there is any income being produced if (currentLiquidityRate > 0) { uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest( currentLiquidityRate, lastUpdateTimestamp ); - uint256 index = cumulatedLiquidityInterest.rayMul(liquidityIndex); - require(index < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); + newLiquidityIndex = cumulatedLiquidityInterest.rayMul(liquidityIndex); + require(newLiquidityIndex < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); - reserve.liquidityIndex = uint128(index); + reserve.liquidityIndex = uint128(newLiquidityIndex); //as the liquidity rate might come only from stable rate loans, we need to ensure //that there is actual variable debt before accumulating @@ -352,13 +385,14 @@ library ReserveLogic { reserve.currentVariableBorrowRate, lastUpdateTimestamp ); - index = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex); - require(index < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); - reserve.variableBorrowIndex = uint128(index); + newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex); + require(newVariableBorrowIndex < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); + reserve.variableBorrowIndex = uint128(newVariableBorrowIndex); } } //solium-disable-next-line reserve.lastUpdateTimestamp = uint40(block.timestamp); + return (newLiquidityIndex, newVariableBorrowIndex); } } diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 610b2ae8..5c31e0cf 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -111,9 +111,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ) = _calculateBalanceIncrease(user); //accrueing the interest accumulation to the stored total supply and caching it - vars.currentSupply = _totalSupply = totalSupply(); + vars.currentSupply = totalSupply(); vars.currentAvgStableRate = _avgStableRate; - vars.nextSupply = vars.currentSupply.add(amount); + vars.nextSupply = _totalSupply = vars.currentSupply.add(amount); vars.amountInRay = amount.wadToRay(); @@ -163,25 +163,32 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 balanceIncrease ) = _calculateBalanceIncrease(user); - uint256 supplyBeforeBurn = totalSupply().add(balanceIncrease); - uint256 supplyAfterBurn = supplyBeforeBurn.sub(amount); + + uint256 currentSupply = totalSupply(); + uint256 currentAvgStableRate = _avgStableRate; + - if (supplyAfterBurn == 0) { + if (currentSupply <= amount) { _avgStableRate = 0; + _totalSupply = 0; } else { + uint256 nextSupply = _totalSupply = currentSupply.sub(amount); _avgStableRate = _avgStableRate - .rayMul(supplyBeforeBurn.wadToRay()) + .rayMul(currentSupply.wadToRay()) .sub(_usersData[user].rayMul(amount.wadToRay())) - .rayDiv(supplyAfterBurn.wadToRay()); + .rayDiv(nextSupply.wadToRay()); } if (amount == currentBalance) { _usersData[user] = 0; _timestamps[user] = 0; + } else { //solium-disable-next-line - _totalSupplyTimestamp = _timestamps[user] = uint40(block.timestamp); + _timestamps[user] = uint40(block.timestamp); } + //solium-disable-next-line + _totalSupplyTimestamp = uint40(block.timestamp); if (balanceIncrease > amount) { _mint(user, balanceIncrease.sub(amount)); diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 320d0f5a..0b680f51 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -58,6 +58,6 @@ interface IVariableDebtToken { * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) * @return the scaled total supply **/ - function scaledTotalSupply() external view returns(uint256); + function scaledTotalSupply() external view returns(uint256); } diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 1d0fa82b..fc98ccd4 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -296,8 +296,7 @@ export const calcExpectedReserveDataAfterBorrow = ( if (borrowRateMode == RateMode.Stable) { - expectedReserveData. - const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt); + //if the borrow rate mode expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); From 5b38bb144b3025fe6fcc9f25fe23e00e5390db87 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 11:52:10 +0200 Subject: [PATCH 27/79] Updated borrow calculations on scenarios --- test/helpers/utils/calculations.ts | 115 ++++++++++++++++++----------- test/scenario.spec.ts | 2 +- 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index fc98ccd4..f8ccc4ce 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -185,7 +185,6 @@ export const calcExpectedReserveDataAfterDeposit = ( expectedReserveData.variableBorrowIndex ); - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; @@ -205,7 +204,7 @@ export const calcExpectedReserveDataAfterDeposit = ( expectedReserveData.liquidityRate = rates[0]; expectedReserveData.stableBorrowRate = rates[1]; expectedReserveData.variableBorrowRate = rates[2]; - + return expectedReserveData; }; @@ -246,8 +245,14 @@ export const calcExpectedReserveDataAfterWithdraw = ( txTimestamp ); - expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt(reserveDataBeforeAction, txTimestamp); - expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt(reserveDataBeforeAction, expectedReserveData.variableBorrowIndex); + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( + reserveDataBeforeAction, + expectedReserveData.variableBorrowIndex + ); expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; @@ -295,60 +300,85 @@ export const calcExpectedReserveDataAfterBorrow = ( ); if (borrowRateMode == RateMode.Stable) { + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); - //if the borrow rate mode - - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - - + const totalStableDebtUntilTx = calcExpectedTotalStableDebt( + reserveDataBeforeAction, + txTimestamp + ); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), + totalStableDebtUntilTx, amountBorrowedBN, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - } else { - const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( - reserveDataBeforeAction.variableBorrowIndex + + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( + { + ...reserveDataBeforeAction, + principalStableDebt: totalStableDebtUntilTx.plus(amountBorrowedBN), + averageStableBorrowRate: expectedReserveData.averageStableBorrowRate, + }, + currentTimestamp ); - const debtAccrued = userVariableDebt.minus(variableDebtBefore); - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt - .plus(amountBorrowedBN) - .plus(debtAccrued); - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; - expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; + expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity + .minus(amountBorrowedBN) + .plus(expectedReserveData.totalVariableDebt) + .plus(expectedReserveData.totalStableDebt); + } else { + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; + expectedReserveData.totalStableDebt = calcExpectedStableDebtTokenBalance( + userDataBeforeAction, + currentTimestamp + ); + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( + amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex) + ); + const totalVariableDebtAfterTx = reserveDataBeforeAction.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); + + const rates = calcExpectedInterestRates( + reserveDataBeforeAction.symbol, + reserveDataBeforeAction.marketStableRate, + expectedReserveData.utilizationRate, + expectedReserveData.totalStableDebt, + totalVariableDebtAfterTx, + expectedReserveData.averageStableBorrowRate + ); + + expectedReserveData.liquidityRate = rates[0]; + + expectedReserveData.stableBorrowRate = rates[1]; + + expectedReserveData.variableBorrowRate = rates[2]; + + expectedReserveData.lastUpdateTimestamp = txTimestamp; + + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + calcExpectedReserveNormalizedDebt(expectedReserveData, currentTimestamp) + ); } expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus( amountBorrowedBN ); + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(expectedReserveData.totalVariableDebt); + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.utilizationRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate - ); - expectedReserveData.liquidityRate = rates[0]; - - expectedReserveData.stableBorrowRate = rates[1]; - - expectedReserveData.variableBorrowRate = rates[2]; - - expectedReserveData.lastUpdateTimestamp = txTimestamp; - return expectedReserveData; }; @@ -1229,7 +1259,6 @@ const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: Bi }; const calcExpectedTotalStableDebt = (reserveData: ReserveData, timestamp: BigNumber) => { - const cumulatedInterest = calcCompoundedInterest( reserveData.averageStableBorrowRate, timestamp, @@ -1237,9 +1266,11 @@ const calcExpectedTotalStableDebt = (reserveData: ReserveData, timestamp: BigNum ); return cumulatedInterest.rayMul(reserveData.principalStableDebt); -} - -const calcExpectedTotalVariableDebt = (reserveData: ReserveData, expectedVariableDebtIndex: BigNumber) => { +}; +const calcExpectedTotalVariableDebt = ( + reserveData: ReserveData, + expectedVariableDebtIndex: BigNumber +) => { return reserveData.scaledVariableDebt.rayMul(expectedVariableDebtIndex); -} +}; diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 98e0c164..17830d1c 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['borrow-repay-variable.json']; +const selectedScenarios: string[] = ['deposit.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From bfe0657b1aa05d6a250d2c65cca794c2e827297e Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 16:37:51 +0200 Subject: [PATCH 28/79] Updated code to fix deposit and withdraw tests --- contracts/lendingpool/LendingPool.sol | 2 + .../lendingpool/LendingPoolConfigurator.sol | 2 +- .../configuration/ReserveConfiguration.sol | 3 +- contracts/libraries/logic/ReserveLogic.sol | 4 +- contracts/tokenization/StableDebtToken.sol | 51 ++-- test/configurator.spec.ts | 4 +- test/helpers/actions.ts | 13 + test/helpers/utils/calculations.ts | 226 +++++++++++------- test/helpers/utils/helpers.ts | 2 +- test/scenario.spec.ts | 2 +- 10 files changed, 196 insertions(+), 113 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 275843a7..9fd5ce71 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -27,6 +27,7 @@ import {LendingPoolCollateralManager} from './LendingPoolCollateralManager.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; +import "@nomiclabs/buidler/console.sol"; /** * @title LendingPool contract @@ -702,6 +703,7 @@ contract LendingPool is VersionedInitializable, ILendingPool { ) { ReserveLogic.ReserveData memory reserve = _reserves[asset]; + return ( IERC20(asset).balanceOf(reserve.aTokenAddress), IERC20(reserve.stableDebtTokenAddress).totalSupply(), diff --git a/contracts/lendingpool/LendingPoolConfigurator.sol b/contracts/lendingpool/LendingPoolConfigurator.sol index 0b5b472f..6bedff76 100644 --- a/contracts/lendingpool/LendingPoolConfigurator.sol +++ b/contracts/lendingpool/LendingPoolConfigurator.sol @@ -484,7 +484,7 @@ contract LendingPoolConfigurator is VersionedInitializable { * @param asset the address of the reserve * @param reserveFactor the new reserve factor of the reserve **/ - function setReserveFactor(address asset, uint256 reserveFactor) external onlyLendingPoolManager { + function setReserveFactor(address asset, uint256 reserveFactor) external onlyAaveAdmin { ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset); currentConfig.setReserveFactor(reserveFactor); diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 10471f6e..ed4df31e 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -42,8 +42,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param reserveFactor the reserve factor **/ - function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) internal view { - console.log("Setting reserve factor to %s", reserveFactor); + function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) internal pure { self.data = (self.data & RESERVE_FACTOR_MASK) | reserveFactor << 64; } diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index ecd96954..e5eac57a 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -147,7 +147,7 @@ library ReserveLogic { * a formal specification. * @param reserve the reserve object **/ - function updateState(ReserveData storage reserve) internal { + function updateState(ReserveData storage reserve) external { address stableDebtToken = reserve.stableDebtTokenAddress; address variableDebtToken = reserve.variableDebtTokenAddress; uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex; @@ -166,7 +166,6 @@ library ReserveLogic { reserve, stableDebtToken, variableDebtToken, - previousLiquidityIndex, previousVariableBorrowIndex, newLiquidityIndex, newVariableBorrowIndex, @@ -306,7 +305,6 @@ library ReserveLogic { ReserveData storage reserve, address stableDebtToken, address variableDebtToken, - uint256 previousLiquidityIndex, uint256 previousVariableBorrowIndex, uint256 newLiquidityIndex, uint256 newVariableBorrowIndex, diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 5c31e0cf..6401bfc9 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -8,6 +8,7 @@ import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {MathUtils} from '../libraries/math/MathUtils.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {IStableDebtToken} from './interfaces/IStableDebtToken.sol'; +import "@nomiclabs/buidler/console.sol"; /** * @title contract StableDebtToken @@ -82,7 +83,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } struct MintLocalVars { - uint256 currentSupply; + uint256 previousSupply; uint256 nextSupply; uint256 amountInRay; uint256 newStableRate; @@ -111,9 +112,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ) = _calculateBalanceIncrease(user); //accrueing the interest accumulation to the stored total supply and caching it - vars.currentSupply = totalSupply(); + vars.previousSupply = totalSupply(); vars.currentAvgStableRate = _avgStableRate; - vars.nextSupply = _totalSupply = vars.currentSupply.add(amount); + vars.nextSupply = _totalSupply = vars.previousSupply.add(amount); vars.amountInRay = amount.wadToRay(); @@ -132,11 +133,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { //calculates the updated average stable rate _avgStableRate = vars.currentAvgStableRate - .rayMul(vars.currentSupply.wadToRay()) + .rayMul(vars.previousSupply.wadToRay()) .add(rate.rayMul(vars.amountInRay)) .rayDiv(vars.nextSupply.wadToRay()); - _mint(user, amount.add(balanceIncrease)); + _mint(user, amount.add(balanceIncrease), vars.previousSupply); // transfer event to track balances emit Transfer(address(0), user, amount); @@ -164,17 +165,15 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ) = _calculateBalanceIncrease(user); - uint256 currentSupply = totalSupply(); - uint256 currentAvgStableRate = _avgStableRate; - + uint256 previousSupply = totalSupply(); - if (currentSupply <= amount) { + if (previousSupply <= amount) { _avgStableRate = 0; _totalSupply = 0; } else { - uint256 nextSupply = _totalSupply = currentSupply.sub(amount); + uint256 nextSupply = _totalSupply = previousSupply.sub(amount); _avgStableRate = _avgStableRate - .rayMul(currentSupply.wadToRay()) + .rayMul(previousSupply.wadToRay()) .sub(_usersData[user].rayMul(amount.wadToRay())) .rayDiv(nextSupply.wadToRay()); } @@ -191,9 +190,9 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { _totalSupplyTimestamp = uint40(block.timestamp); if (balanceIncrease > amount) { - _mint(user, balanceIncrease.sub(amount)); + _mint(user, balanceIncrease.sub(amount), previousSupply); } else { - _burn(user, amount.sub(balanceIncrease)); + _burn(user, amount.sub(balanceIncrease), previousSupply); } // transfer event to track balances @@ -244,7 +243,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } function totalSupply() public override view returns (uint256) { - _calcTotalSupply(_avgStableRate); + return _calcTotalSupply(_avgStableRate); } function getTotalSupplyLastUpdated() public override view returns(uint40) { @@ -261,13 +260,37 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { function _calcTotalSupply(uint256 avgRate) internal view returns(uint256) { uint256 principalSupply = super.totalSupply(); + if (principalSupply == 0) { return 0; } + uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest( avgRate, _totalSupplyTimestamp ); + return principalSupply.rayMul(cumulatedInterest); } + + function _mint(address account, uint256 amount, uint256 oldTotalSupply) internal { + + uint256 oldAccountBalance = _balances[account]; + _balances[account] = oldAccountBalance.add(amount); + + if (address(_incentivesController) != address(0)) { + _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); + } + } + + function _burn(address account, uint256 amount, uint256 oldTotalSupply) internal { + + + uint256 oldAccountBalance = _balances[account]; + _balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance'); + + if (address(_incentivesController) != address(0)) { + _incentivesController.handleAction(account, oldTotalSupply, oldAccountBalance); + } + } } diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 66f7ef82..0fa3289c 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -192,8 +192,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { const {configurator, users, weth} = testEnv; await expect( configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'), - CALLER_NOT_LENDING_POOL_MANAGER - ).to.be.revertedWith(CALLER_NOT_LENDING_POOL_MANAGER); + CALLER_NOT_AAVE_ADMIN + ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN); }); diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 3e60955d..0d1d2775 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -375,6 +375,19 @@ export const borrow = async ( txCost ); + console.log("Expected available liquidity: ", expectedReserveData.availableLiquidity.toFixed()); + console.log("Expected total liquidity: ", expectedReserveData.totalLiquidity.toFixed()); + console.log("Expected total debt stable: ", expectedReserveData.totalStableDebt.toFixed()); + console.log("Expected total debt variable: ", expectedReserveData.totalVariableDebt.toFixed()); + console.log("Expected utilization rate: ", expectedReserveData.utilizationRate.toFixed()); + + console.log("actual available liquidity: ", reserveDataAfter.availableLiquidity.toFixed()); + console.log("actual total liquidity: ", reserveDataAfter.totalLiquidity.toFixed()); + console.log("actual total debt stable: ", reserveDataAfter.totalStableDebt.toFixed()); + console.log("actual total debt variable: ", reserveDataAfter.totalVariableDebt.toFixed()); + console.log("actual utilization rate: ", reserveDataAfter.utilizationRate.toFixed()); + console.log("User debt: ", userDataAfter.currentStableDebt.toFixed(0)); + expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index f8ccc4ce..d394a8ff 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -31,7 +31,9 @@ export const calcExpectedUserDataAfterDeposit = ( const expectedUserData = {}; expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, txTimestamp ); @@ -71,7 +73,9 @@ export const calcExpectedUserDataAfterDeposit = ( expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(amountDeposited); expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, txTimestamp ); @@ -118,7 +122,9 @@ export const calcExpectedUserDataAfterWithdraw = ( expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, txTimestamp ); @@ -294,13 +300,21 @@ export const calcExpectedReserveDataAfterBorrow = ( reserveDataBeforeAction, txTimestamp ); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( reserveDataBeforeAction, txTimestamp ); + expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus( + amountBorrowedBN + ); + + expectedReserveData.lastUpdateTimestamp = txTimestamp; + if (borrowRateMode == RateMode.Stable) { expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul( expectedReserveData.variableBorrowIndex ); @@ -317,32 +331,68 @@ export const calcExpectedReserveDataAfterBorrow = ( reserveDataBeforeAction.stableBorrowRate ); + expectedReserveData.principalStableDebt = totalStableDebtUntilTx.plus(amountBorrowedBN); + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( { ...reserveDataBeforeAction, - principalStableDebt: totalStableDebtUntilTx.plus(amountBorrowedBN), + principalStableDebt: expectedReserveData.principalStableDebt, averageStableBorrowRate: expectedReserveData.averageStableBorrowRate, + lastUpdateTimestamp: txTimestamp, }, currentTimestamp ); - expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity - .minus(amountBorrowedBN) + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity .plus(expectedReserveData.totalVariableDebt) .plus(expectedReserveData.totalStableDebt); + + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, + expectedReserveData.totalLiquidity + ); + + const rates = calcExpectedInterestRates( + reserveDataBeforeAction.symbol, + reserveDataBeforeAction.marketStableRate, + expectedReserveData.utilizationRate, + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, + expectedReserveData.averageStableBorrowRate + ); + + expectedReserveData.liquidityRate = rates[0]; + + expectedReserveData.stableBorrowRate = rates[1]; + + expectedReserveData.variableBorrowRate = rates[2]; } else { expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; + expectedReserveData.totalStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, currentTimestamp ); + expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex) ); - const totalVariableDebtAfterTx = reserveDataBeforeAction.scaledVariableDebt.rayMul( + const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul( expectedReserveData.variableBorrowIndex ); + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( + expectedReserveData.totalStableDebt, + totalVariableDebtAfterTx, + expectedReserveData.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(totalVariableDebtAfterTx) + ); + const rates = calcExpectedInterestRates( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, @@ -358,27 +408,15 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.lastUpdateTimestamp = txTimestamp; - expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( calcExpectedReserveNormalizedDebt(expectedReserveData, currentTimestamp) ); } - expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.minus( - amountBorrowedBN - ); - expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity .plus(expectedReserveData.totalStableDebt) .plus(expectedReserveData.totalVariableDebt); - expectedReserveData.utilizationRate = calcExpectedUtilizationRate( - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.totalLiquidity - ); - return expectedReserveData; }; @@ -396,7 +434,12 @@ export const calcExpectedReserveDataAfterRepay = ( let amountRepaidBN = new BigNumber(amountRepaid); - const userStableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); + const userStableDebt = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + txTimestamp + ); const userVariableDebt = calcExpectedVariableDebtTokenBalance( reserveDataBeforeAction, @@ -500,29 +543,50 @@ export const calcExpectedUserDataAfterBorrow = ( ): UserReserveData => { const expectedUserData = {}; - const currentStableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); - - const currentVariableDebt = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); + const amountBorrowedBN = new BigNumber(amountBorrowed); if (interestRateMode == RateMode.Stable) { - const debtAccrued = currentStableDebt.minus(userDataBeforeAction.principalStableDebt); + const stableDebtUntilTx = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + txTimestamp + ); - expectedUserData.principalStableDebt = currentStableDebt.plus(amountBorrowed); - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; + expectedUserData.principalStableDebt = stableDebtUntilTx.plus(amountBorrowed); + expectedUserData.stableRateLastUpdated = txTimestamp; expectedUserData.stableBorrowRate = calcExpectedUserStableRate( - userDataBeforeAction.principalStableDebt.plus(debtAccrued), + stableDebtUntilTx, userDataBeforeAction.stableBorrowRate, - new BigNumber(amountBorrowed), + amountBorrowedBN, reserveDataBeforeAction.stableBorrowRate ); - expectedUserData.stableRateLastUpdated = txTimestamp; + + console.log("Principal stable debt: ",expectedUserData.principalStableDebt.toFixed() ); + console.log("stable borrow rate: ",expectedUserData.stableBorrowRate.toFixed() ); + + expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( + expectedUserData.principalStableDebt, + expectedUserData.stableBorrowRate, + txTimestamp, + currentTimestamp + ); + + console.log("expected stable debt: ", expectedUserData.currentStableDebt); + + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; + + expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( + expectedDataAfterAction, + expectedUserData, + currentTimestamp + ); } else { - expectedUserData.principalVariableDebt = currentVariableDebt.plus(amountBorrowed); + expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( + amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) + ); + expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; @@ -530,42 +594,6 @@ export const calcExpectedUserDataAfterBorrow = ( expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; } - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( - { - ...userDataBeforeAction, - currentStableDebt: expectedUserData.principalStableDebt, - principalStableDebt: expectedUserData.principalStableDebt, - stableBorrowRate: expectedUserData.stableBorrowRate, - stableRateLastUpdated: expectedUserData.stableRateLastUpdated, - }, - currentTimestamp - ); - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - expectedDataAfterAction, - { - ...userDataBeforeAction, - currentVariableDebt: expectedUserData.scaledVariableDebt.rayMul( - reserveDataBeforeAction.variableBorrowIndex - ), - scaledVariableDebt: expectedUserData.scaledVariableDebt, - variableBorrowIndex: - interestRateMode == RateMode.Variable - ? expectedDataAfterAction.variableBorrowIndex - : userDataBeforeAction.variableBorrowIndex, - }, - currentTimestamp - ); - - if (expectedUserData.scaledVariableDebt.eq(0)) { - expectedUserData.variableBorrowIndex = new BigNumber(0); - } else { - expectedUserData.variableBorrowIndex = - interestRateMode == RateMode.Variable - ? expectedDataAfterAction.variableBorrowIndex - : userDataBeforeAction.variableBorrowIndex; - } - expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; @@ -575,6 +603,7 @@ export const calcExpectedUserDataAfterBorrow = ( userDataBeforeAction, currentTimestamp ); + expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance; expectedUserData.walletBalance = userDataBeforeAction.walletBalance.plus(amountBorrowed); @@ -603,7 +632,9 @@ export const calcExpectedUserDataAfterRepay = ( ); const stableBorrowBalance = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, currentTimestamp ); @@ -700,7 +731,12 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( txTimestamp ); - const stableDebt = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); + const stableDebt = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + txTimestamp + ); expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity; @@ -793,7 +829,12 @@ export const calcExpectedUserDataAfterSwapRateMode = ( txTimestamp ); - const stableBorrowBalance = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); + const stableBorrowBalance = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + txTimestamp + ); expectedUserData.currentATokenBalance = calcExpectedATokenBalance( reserveDataBeforeAction, @@ -848,7 +889,12 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( expectedReserveData.address = reserveDataBeforeAction.address; - const stableBorrowBalance = calcExpectedStableDebtTokenBalance(userDataBeforeAction, txTimestamp); + const stableBorrowBalance = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + txTimestamp + ); const debtAccrued = stableBorrowBalance.minus(userDataBeforeAction.principalStableDebt); @@ -924,7 +970,9 @@ export const calcExpectedUserDataAfterStableRateRebalance = ( txTimestamp ); expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction, + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, txTimestamp ); @@ -957,13 +1005,13 @@ const calcExpectedScaledATokenBalance = ( }; export const calcExpectedATokenBalance = ( - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, + reserveData: ReserveData, + userData: UserReserveData, currentTimestamp: BigNumber ) => { - const index = calcExpectedReserveNormalizedIncome(reserveDataBeforeAction, currentTimestamp); + const index = calcExpectedReserveNormalizedIncome(reserveData, currentTimestamp); - const {scaledATokenBalance: scaledBalanceBeforeAction} = userDataBeforeAction; + const {scaledATokenBalance: scaledBalanceBeforeAction} = userData; return scaledBalanceBeforeAction.rayMul(index); }; @@ -998,23 +1046,23 @@ const calcExpectedVariableDebtUserIndex = ( }; export const calcExpectedVariableDebtTokenBalance = ( - reserveDataBeforeAction: ReserveData, - userDataBeforeAction: UserReserveData, + reserveData: ReserveData, + userData: UserReserveData, currentTimestamp: BigNumber ) => { - const debt = calcExpectedReserveNormalizedDebt(reserveDataBeforeAction, currentTimestamp); + const normalizedDebt = calcExpectedReserveNormalizedDebt(reserveData, currentTimestamp); - const {scaledVariableDebt} = userDataBeforeAction; + const {scaledVariableDebt} = userData; - return scaledVariableDebt.rayMul(debt); + return scaledVariableDebt.rayMul(normalizedDebt); }; export const calcExpectedStableDebtTokenBalance = ( - userDataBeforeAction: UserReserveData, + principalStableDebt: BigNumber, + stableBorrowRate: BigNumber, + stableRateLastUpdated: BigNumber, currentTimestamp: BigNumber ) => { - const {principalStableDebt, stableBorrowRate, stableRateLastUpdated} = userDataBeforeAction; - if ( stableBorrowRate.eq(0) || currentTimestamp.eq(stableRateLastUpdated) || @@ -1029,7 +1077,7 @@ export const calcExpectedStableDebtTokenBalance = ( stableRateLastUpdated ); - return principalStableDebt.wadToRay().rayMul(cumulatedInterest).rayToWad(); + return principalStableDebt.rayMul(cumulatedInterest); }; const calcLinearInterest = ( diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index 3f3a2ec8..b98ba688 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -24,7 +24,7 @@ export const getReserveData = async ( const stableDebtToken = await getStableDebtToken(tokenAddresses.stableDebtTokenAddress); const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); - const [principalStableDebt] = await stableDebtToken.getPrincipalSupplyAndAvgRate(); + const [principalStableDebt] = await stableDebtToken.getSupplyData(); const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 17830d1c..ee45a08f 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['deposit.json']; +const selectedScenarios: string[] = ['withdraw.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 6df8a7a6e0050de79aa4ca299cf196ced5f86ce4 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 16:38:15 +0200 Subject: [PATCH 29/79] Removed console.log --- test/helpers/utils/calculations.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index d394a8ff..7343e593 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -563,9 +563,6 @@ export const calcExpectedUserDataAfterBorrow = ( reserveDataBeforeAction.stableBorrowRate ); - console.log("Principal stable debt: ",expectedUserData.principalStableDebt.toFixed() ); - console.log("stable borrow rate: ",expectedUserData.stableBorrowRate.toFixed() ); - expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( expectedUserData.principalStableDebt, expectedUserData.stableBorrowRate, @@ -573,8 +570,6 @@ export const calcExpectedUserDataAfterBorrow = ( currentTimestamp ); - console.log("expected stable debt: ", expectedUserData.currentStableDebt); - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( From 72e2102529b9c9659f36fc11221e1d769f824c83 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 16:40:23 +0200 Subject: [PATCH 30/79] removed other console.log --- test/helpers/actions.ts | 13 ------------- test/scenario.spec.ts | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 0d1d2775..3e60955d 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -375,19 +375,6 @@ export const borrow = async ( txCost ); - console.log("Expected available liquidity: ", expectedReserveData.availableLiquidity.toFixed()); - console.log("Expected total liquidity: ", expectedReserveData.totalLiquidity.toFixed()); - console.log("Expected total debt stable: ", expectedReserveData.totalStableDebt.toFixed()); - console.log("Expected total debt variable: ", expectedReserveData.totalVariableDebt.toFixed()); - console.log("Expected utilization rate: ", expectedReserveData.utilizationRate.toFixed()); - - console.log("actual available liquidity: ", reserveDataAfter.availableLiquidity.toFixed()); - console.log("actual total liquidity: ", reserveDataAfter.totalLiquidity.toFixed()); - console.log("actual total debt stable: ", reserveDataAfter.totalStableDebt.toFixed()); - console.log("actual total debt variable: ", reserveDataAfter.totalVariableDebt.toFixed()); - console.log("actual utilization rate: ", reserveDataAfter.utilizationRate.toFixed()); - console.log("User debt: ", userDataAfter.currentStableDebt.toFixed(0)); - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index ee45a08f..98e0c164 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['withdraw.json']; +const selectedScenarios: string[] = ['borrow-repay-variable.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 13f6c264b3b65f3e514c98b18343e24787447a0d Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 17 Sep 2020 19:05:22 +0200 Subject: [PATCH 31/79] Partially fixed repay tests --- buidler.config.ts | 2 +- deployed-contracts.json | 83 +++++----- .../flash-liquidation-with-collateral.spec.ts | 4 +- test/helpers/utils/calculations.ts | 145 +++++++++--------- test/liquidation-underlying.spec.ts | 4 +- test/repay-with-collateral.spec.ts | 4 +- test/scenario.spec.ts | 2 +- 7 files changed, 126 insertions(+), 118 deletions(-) diff --git a/buidler.config.ts b/buidler.config.ts index 47eba1e2..9db632a2 100644 --- a/buidler.config.ts +++ b/buidler.config.ts @@ -9,7 +9,7 @@ usePlugin('buidler-typechain'); usePlugin('solidity-coverage'); usePlugin('@nomiclabs/buidler-waffle'); usePlugin('@nomiclabs/buidler-etherscan'); -//usePlugin('buidler-gas-reporter'); +usePlugin('buidler-gas-reporter'); const DEFAULT_BLOCK_GAS_LIMIT = 10000000; const DEFAULT_GAS_PRICE = 10; const HARDFORK = 'istanbul'; diff --git a/deployed-contracts.json b/deployed-contracts.json index 00c4ef4f..b0a60439 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -5,7 +5,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x9Dc554694756dC303a087e04bA6918C333Bc26a7", + "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -15,7 +15,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xAfC307938C1c0035942c141c31524504c89Aaa8B", + "address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -25,7 +25,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x73DE1e0ab6A5C221258703bc546E0CAAcCc6EC87", + "address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -53,7 +53,7 @@ "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" }, "localhost": { - "address": "0x65e0Cd5B8904A02f2e00BC6f58bf881998D54BDe" + "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" } }, "LendingPoolDataProvider": { @@ -66,7 +66,7 @@ "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" }, "localhost": { - "address": "0x5d12dDe3286D94E0d85F9D3B01B7099cfA0aBCf1" + "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" } }, "PriceOracle": { @@ -75,7 +75,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xbeA90474c2F3C7c43bC7c36CaAf5272c927Af5a1", + "address": "0x1750499D05Ed1674d822430FB960d5F6731fDf64", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -85,7 +85,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x19E42cA990cF697D3dda0e59131215C43bB6989F", + "address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -95,7 +95,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xE30c3983E51bC9d6baE3E9437710a1459e21e81F", + "address": "0x7B6C3e5486D9e6959441ab554A889099eed76290", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -105,7 +105,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xDf69898e844197a24C658CcF9fD53dF15948dc8b", + "address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -115,7 +115,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xBe6d8642382C241c9B4B50c89574DbF3f4181E7D", + "address": "0x626FdE749F9d499d3777320CAf29484B624ab84a", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -169,7 +169,7 @@ "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" }, "localhost": { - "address": "0xAd49512dFBaD6fc13D67d3935283c0606812E962" + "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" } }, "WalletBalanceProvider": { @@ -178,7 +178,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xA29C2A7e59aa49C71aF084695337E3AA5e820758", + "address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -188,7 +188,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xbe66dC9DFEe580ED968403e35dF7b5159f873df8", + "address": "0x7c2C195CD6D34B8F845992d380aADB2730bB9C6F", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -198,7 +198,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x93AfC6Df4bB8F62F2493B19e577f8382c0BA9EBC", + "address": "0x8858eeB3DfffA017D4BCE9801D340D36Cf895CCf", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -208,7 +208,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x75Ded61646B5945BdDd0CD9a9Db7c8288DA6F810", + "address": "0x0078371BDeDE8aAc7DeBfFf451B74c5EDB385Af7", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -218,7 +218,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xdE7c40e675bF1aA45c18cCbaEb9662B16b0Ddf7E", + "address": "0xf4e77E5Da47AC3125140c470c71cBca77B5c638c", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -228,7 +228,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544", + "address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -238,7 +238,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040", + "address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -248,7 +248,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x8F9422aa37215c8b3D1Ea1674138107F84D68F26", + "address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -258,7 +258,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xa89E20284Bd638F31b0011D0fC754Fc9d2fa73e3", + "address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -268,7 +268,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xaA935993065F2dDB1d13623B1941C7AEE3A60F23", + "address": "0xc4905364b78a742ccce7B890A89514061E47068D", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -278,7 +278,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3", + "address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -288,7 +288,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x1f569c307949a908A4b8Ff7453a88Ca0b8D8df13", + "address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -298,7 +298,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x4301cb254CCc126B9eb9cbBE030C6FDA2FA16D4a", + "address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -308,7 +308,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x0766c9592a8686CAB0081b4f35449462c6e82F11", + "address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -318,7 +318,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xaF6D34adD35E1A565be4539E4d1069c48A49C953", + "address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -328,7 +328,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x48bb3E35D2D6994374db457a6Bf61de2d9cC8E49", + "address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -338,7 +338,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x1E59BA56B1F61c3Ee946D8c7e2994B4A9b0cA45C", + "address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -348,7 +348,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x53813198c75959DDB604462831d8989C29152164", + "address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -358,7 +358,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x0eD6115873ce6B807a03FE0df1f940387779b729", + "address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -368,7 +368,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xFFfDa24e7E3d5F89a24278f53d6f0F81B3bE0d6B", + "address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -378,7 +378,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x5889354f21A1C8D8D2f82669d778f6Dab778B519", + "address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -388,7 +388,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x09F7bF33B3F8922268B34103af3a8AF83148C9B1", + "address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -398,7 +398,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x8f3966F7d53Fd5f12b701C8835e1e32541613869", + "address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -408,7 +408,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x9Dc554694756dC303a087e04bA6918C333Bc26a7", + "address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -417,7 +417,7 @@ "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" }, "localhost": { - "address": "0x9305d862ee95a899b83906Cd9CB666aC269E5f66" + "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" } }, "StableDebtToken": { @@ -426,7 +426,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x02BB514187B830d6A2111197cd7D8cb60650B970", + "address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -436,13 +436,13 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x6774Ce86Abf5EBB22E9F45b5f55daCbB4170aD7f", + "address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, "AToken": { "localhost": { - "address": "0x007C1a44e85bDa8F562F916685A9DC8BdC6542bF", + "address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "buidlerevm": { @@ -466,7 +466,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd", + "address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" } }, @@ -493,6 +493,9 @@ "MockSwapAdapter": { "buidlerevm": { "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" + }, + "localhost": { + "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" } } } \ No newline at end of file diff --git a/test/flash-liquidation-with-collateral.spec.ts b/test/flash-liquidation-with-collateral.spec.ts index 01a8fec0..7298cb9b 100644 --- a/test/flash-liquidation-with-collateral.spec.ts +++ b/test/flash-liquidation-with-collateral.spec.ts @@ -125,7 +125,9 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ).minus(usdcUserDataBefore.currentVariableDebt); const expectedStableDebtIncrease = calcExpectedStableDebtTokenBalance( - usdcUserDataBefore, + usdcUserDataBefore.principalStableDebt, + usdcUserDataBefore.stableBorrowRate, + usdcUserDataBefore.stableRateLastUpdated, new BigNumber(repayWithCollateralTimestamp) ).minus(usdcUserDataBefore.currentStableDebt); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 7343e593..795dbaa3 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -319,19 +319,16 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.variableBorrowIndex ); - const totalStableDebtUntilTx = calcExpectedTotalStableDebt( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - totalStableDebtUntilTx, + reserveDataBeforeAction.totalStableDebt, amountBorrowedBN, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.principalStableDebt = totalStableDebtUntilTx.plus(amountBorrowedBN); + expectedReserveData.principalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( + amountBorrowedBN + ); expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( { @@ -385,7 +382,7 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.variableBorrowIndex ); - expectedReserveData.utilizationRate = calcExpectedUtilizationRate( + const utilizationRateAfterTx = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, totalVariableDebtAfterTx, expectedReserveData.availableLiquidity @@ -396,7 +393,7 @@ export const calcExpectedReserveDataAfterBorrow = ( const rates = calcExpectedInterestRates( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, - expectedReserveData.utilizationRate, + utilizationRateAfterTx, expectedReserveData.totalStableDebt, totalVariableDebtAfterTx, expectedReserveData.averageStableBorrowRate @@ -411,11 +408,17 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( calcExpectedReserveNormalizedDebt(expectedReserveData, currentTimestamp) ); - } - expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity - .plus(expectedReserveData.totalStableDebt) - .plus(expectedReserveData.totalVariableDebt); + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(expectedReserveData.totalVariableDebt); + + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( + expectedReserveData.totalStableDebt, + expectedReserveData.totalVariableDebt, + expectedReserveData.totalLiquidity + ); + } return expectedReserveData; }; @@ -447,7 +450,7 @@ export const calcExpectedReserveDataAfterRepay = ( txTimestamp ); - //if amount repaid = MAX_UINT_AMOUNT, user is repaying everything + //if amount repaid == MAX_UINT_AMOUNT, user is repaying everything if (amountRepaidBN.abs().eq(MAX_UINT_AMOUNT)) { if (borrowRateMode == RateMode.Stable) { amountRepaidBN = userStableDebt; @@ -456,36 +459,40 @@ export const calcExpectedReserveDataAfterRepay = ( } } + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( + reserveDataBeforeAction, + txTimestamp + ); + if (borrowRateMode == RateMode.Stable) { - const debtAccrued = userStableDebt.minus(userDataBeforeAction.principalStableDebt); - - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt - .minus(amountRepaidBN) - .plus(debtAccrued); + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.minus( + amountRepaidBN + ); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), + reserveDataBeforeAction.totalStableDebt, amountRepaidBN.negated(), userDataBeforeAction.stableBorrowRate ); + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; } else { - const variableDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( - reserveDataBeforeAction.variableBorrowIndex + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus( + amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex) ); - const debtAccrued = userVariableDebt.minus(variableDebtBefore); - - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); - - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt - .plus(debtAccrued) - .minus(amountRepaidBN); + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt; + expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; } @@ -493,9 +500,9 @@ export const calcExpectedReserveDataAfterRepay = ( amountRepaidBN ); - expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity.plus( - amountRepaidBN - ); + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(expectedReserveData.totalVariableDebt); expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, @@ -517,15 +524,6 @@ export const calcExpectedReserveDataAfterRepay = ( expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.lastUpdateTimestamp = txTimestamp; return expectedReserveData; @@ -571,12 +569,6 @@ export const calcExpectedUserDataAfterBorrow = ( ); expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - - expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( - expectedDataAfterAction, - expectedUserData, - currentTimestamp - ); } else { expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) @@ -587,8 +579,20 @@ export const calcExpectedUserDataAfterBorrow = ( expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; + + expectedUserData.currentStableDebt = calcExpectedStableDebtTokenBalance( + userDataBeforeAction.principalStableDebt, + userDataBeforeAction.stableBorrowRate, + userDataBeforeAction.stableRateLastUpdated, + currentTimestamp + ); } + expectedUserData.currentVariableDebt = calcExpectedVariableDebtTokenBalance( + expectedDataAfterAction, + expectedUserData, + currentTimestamp + ); expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; @@ -620,32 +624,33 @@ export const calcExpectedUserDataAfterRepay = ( ): UserReserveData => { const expectedUserData = {}; - const variableBorrowBalance = calcExpectedVariableDebtTokenBalance( + const variableDebt = calcExpectedVariableDebtTokenBalance( reserveDataBeforeAction, userDataBeforeAction, currentTimestamp ); - const stableBorrowBalance = calcExpectedStableDebtTokenBalance( + const stableDebt = calcExpectedStableDebtTokenBalance( userDataBeforeAction.principalStableDebt, userDataBeforeAction.stableBorrowRate, userDataBeforeAction.stableRateLastUpdated, currentTimestamp ); - - if (new BigNumber(totalRepaid).abs().eq(MAX_UINT_AMOUNT)) { - totalRepaid = + + let totalRepaidBN = new BigNumber(totalRepaid); + if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) { + totalRepaidBN = rateMode == RateMode.Stable - ? stableBorrowBalance.toFixed(0) - : variableBorrowBalance.toFixed(); + ? stableDebt + : variableDebt; } if (rateMode == RateMode.Stable) { - expectedUserData.principalVariableDebt = userDataBeforeAction.principalVariableDebt; - expectedUserData.currentVariableDebt = variableBorrowBalance; - expectedUserData.variableBorrowIndex = userDataBeforeAction.variableBorrowIndex; - expectedUserData.currentStableDebt = expectedUserData.principalStableDebt = stableBorrowBalance.minus( + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; + expectedUserData.currentVariableDebt = userDataBeforeAction.currentVariableDebt; + + expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus( totalRepaid ); @@ -659,21 +664,15 @@ export const calcExpectedUserDataAfterRepay = ( expectedUserData.stableRateLastUpdated = txTimestamp; } } else { - expectedUserData.currentStableDebt = stableBorrowBalance; - expectedUserData.principalStableDebt = userDataBeforeAction.principalStableDebt; + + expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt; + expectedUserData.principalStableDebt = stableDebt; expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; + + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)); + expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(expectedDataAfterAction.variableBorrowIndex); - expectedUserData.currentVariableDebt = expectedUserData.principalVariableDebt = variableBorrowBalance.minus( - totalRepaid - ); - - if (expectedUserData.currentVariableDebt.eq('0')) { - //user repaid everything - expectedUserData.variableBorrowIndex = new BigNumber('0'); - } else { - expectedUserData.variableBorrowIndex = expectedDataAfterAction.variableBorrowIndex; - } } expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; @@ -688,7 +687,7 @@ export const calcExpectedUserDataAfterRepay = ( expectedUserData.scaledATokenBalance = userDataBeforeAction.scaledATokenBalance; if (user === onBehalfOf) { - expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaid); + expectedUserData.walletBalance = userDataBeforeAction.walletBalance.minus(totalRepaidBN); } else { //wallet balance didn't change expectedUserData.walletBalance = userDataBeforeAction.walletBalance; diff --git a/test/liquidation-underlying.spec.ts b/test/liquidation-underlying.spec.ts index 26f10ced..df1e9404 100644 --- a/test/liquidation-underlying.spec.ts +++ b/test/liquidation-underlying.spec.ts @@ -175,7 +175,9 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset', ); const stableDebtBeforeTx = calcExpectedStableDebtTokenBalance( - userReserveDataBefore, + userReserveDataBefore.principalStableDebt, + userReserveDataBefore.stableBorrowRate, + userReserveDataBefore.stableRateLastUpdated, txTimestamp ); diff --git a/test/repay-with-collateral.spec.ts b/test/repay-with-collateral.spec.ts index 41e9060f..455520f5 100644 --- a/test/repay-with-collateral.spec.ts +++ b/test/repay-with-collateral.spec.ts @@ -420,7 +420,9 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { ).minus(usdcUserDataBefore.currentVariableDebt); const expectedStableDebtIncrease = calcExpectedStableDebtTokenBalance( - usdcUserDataBefore, + usdcUserDataBefore.principalStableDebt, + usdcUserDataBefore.stableBorrowRate, + usdcUserDataBefore.stableRateLastUpdated, new BigNumber(repayWithCollateralTimestamp) ).minus(usdcUserDataBefore.currentStableDebt); diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 98e0c164..54fe7433 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['borrow-repay-variable.json']; +const selectedScenarios: string[] = []; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 5868a4844fd4bae919ace682cb5a1a40c16f36e3 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 18 Sep 2020 17:56:33 +0200 Subject: [PATCH 32/79] Updated testsW --- buidler.config.ts | 3 +- contracts/tokenization/StableDebtToken.sol | 38 ++++- test/helpers/actions.ts | 23 ++- test/helpers/utils/calculations.ts | 181 +++++++++++++-------- test/scenario.spec.ts | 2 +- 5 files changed, 173 insertions(+), 74 deletions(-) diff --git a/buidler.config.ts b/buidler.config.ts index 9db632a2..03f42645 100644 --- a/buidler.config.ts +++ b/buidler.config.ts @@ -9,7 +9,8 @@ usePlugin('buidler-typechain'); usePlugin('solidity-coverage'); usePlugin('@nomiclabs/buidler-waffle'); usePlugin('@nomiclabs/buidler-etherscan'); -usePlugin('buidler-gas-reporter'); +//usePlugin('buidler-gas-reporter'); + const DEFAULT_BLOCK_GAS_LIMIT = 10000000; const DEFAULT_GAS_PRICE = 10; const HARDFORK = 'istanbul'; diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 6401bfc9..fe352b32 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -167,6 +167,10 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { uint256 previousSupply = totalSupply(); + //since the total supply and each single user debt accrue separately, + //there might be accumulation errors so that the last borrower repaying + //might actually try to repay more than the available debt supply. + //in this case we simply set the total supply and the avg stable rate to 0 if (previousSupply <= amount) { _avgStableRate = 0; _totalSupply = 0; @@ -232,32 +236,51 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { ); } + /** + * @dev returns the principal, total supply and the average borrow rate + **/ function getSupplyData() public override view returns (uint256, uint256, uint256) { uint256 avgRate = _avgStableRate; return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate); } + /** + * @dev returns the the total supply and the average stable rate + **/ function getTotalSupplyAndAvgRate() public override view returns (uint256, uint256) { uint256 avgRate = _avgStableRate; return (_calcTotalSupply(avgRate), avgRate); } + /** + * @dev returns the total supply + **/ function totalSupply() public override view returns (uint256) { return _calcTotalSupply(_avgStableRate); } - + + /** + * @dev returns the timestamp at which the total supply was updated + **/ function getTotalSupplyLastUpdated() public override view returns(uint40) { return _totalSupplyTimestamp; } /** * @dev Returns the principal debt balance of the user from + * @param user the user * @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); } + + /** + * @dev calculates the total supply + * @param avgRate the average rate at which calculate the total supply + * @return The debt balance of the user since the last burn/mint action + **/ function _calcTotalSupply(uint256 avgRate) internal view returns(uint256) { uint256 principalSupply = super.totalSupply(); @@ -273,6 +296,12 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { return principalSupply.rayMul(cumulatedInterest); } + /** + * @dev mints stable debt tokens to an user + * @param account the account receiving the debt tokens + * @param amount the amount being minted + * @param oldTotalSupply the total supply before the minting event + **/ function _mint(address account, uint256 amount, uint256 oldTotalSupply) internal { uint256 oldAccountBalance = _balances[account]; @@ -283,9 +312,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } } + /** + * @dev burns stable debt tokens of an user + * @param account the user getting his debt burned + * @param amount the amount being burned + * @param oldTotalSupply the total supply before the burning event + **/ function _burn(address account, uint256 amount, uint256 oldTotalSupply) internal { - uint256 oldAccountBalance = _balances[account]; _balances[account] = oldAccountBalance.sub(amount, 'ERC20: burn amount exceeds balance'); diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 3e60955d..ba874e6e 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -375,6 +375,12 @@ export const borrow = async ( txCost ); + console.log("total stable debt actual: ", reserveDataAfter.totalStableDebt.toFixed()); + console.log("total stable debt expected: ", expectedReserveData.totalStableDebt.toFixed()); + + console.log("total variable debt actual: ", reserveDataAfter.totalVariableDebt.toFixed()); + console.log("total variable debt expected: ", expectedReserveData.totalVariableDebt.toFixed()); + expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); @@ -479,6 +485,14 @@ export const repay = async ( txCost ); + + console.log("total stable debt actual: ", reserveDataAfter.totalStableDebt.toFixed()); + console.log("total stable debt expected: ", expectedReserveData.totalStableDebt.toFixed()); + + console.log("total variable debt actual: ", reserveDataAfter.totalVariableDebt.toFixed()); + console.log("total variable debt expected: ", expectedReserveData.totalVariableDebt.toFixed()); + + expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); @@ -741,9 +755,12 @@ export const getContractsData = async ( sender?: string ) => { const {pool} = testEnv; - const reserveData = await getReserveData(pool, reserve); - const userData = await getUserData(pool, reserve, user, sender || user); - const timestamp = await timeLatest(); + + const [userData, reserveData, timestamp] = await Promise.all([ + getUserData(pool, reserve, user, sender || user), + getReserveData(pool, reserve), + timeLatest(), + ]); return { reserveData, diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 795dbaa3..3cd05b69 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -97,6 +97,8 @@ export const calcExpectedUserDataAfterWithdraw = ( currentTimestamp: BigNumber, txCost: BigNumber ): UserReserveData => { + console.log('Checking withdraw'); + const expectedUserData = {}; const aTokenBalance = calcExpectedATokenBalance( @@ -183,7 +185,9 @@ export const calcExpectedReserveDataAfterDeposit = ( ); expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - reserveDataBeforeAction, + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, txTimestamp ); expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( @@ -252,7 +256,9 @@ export const calcExpectedReserveDataAfterWithdraw = ( ); expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - reserveDataBeforeAction, + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, txTimestamp ); expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( @@ -313,33 +319,71 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.lastUpdateTimestamp = txTimestamp; if (borrowRateMode == RateMode.Stable) { + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul( - expectedReserveData.variableBorrowIndex + const expectedVariableDebtAfterTx = calcExpectedTotalVariableDebt( + reserveDataBeforeAction, + txTimestamp ); + const expectedStableDebtUntilTx = calcExpectedTotalStableDebt( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, + txTimestamp + ); + + expectedReserveData.principalStableDebt = expectedStableDebtUntilTx.plus(amountBorrowedBN); + expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt, + expectedStableDebtUntilTx, amountBorrowedBN, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.principalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( - amountBorrowedBN + const totalLiquidityAfterTx = expectedReserveData.availableLiquidity + .plus(expectedReserveData.principalStableDebt) + .plus(expectedVariableDebtAfterTx); + + const utilizationRateAfterTx = calcExpectedUtilizationRate( + expectedReserveData.principalStableDebt, //the expected principal debt is the total debt immediately after the tx + expectedVariableDebtAfterTx, + totalLiquidityAfterTx ); + const ratesAfterTx = calcExpectedInterestRates( + reserveDataBeforeAction.symbol, + reserveDataBeforeAction.marketStableRate, + utilizationRateAfterTx, + expectedReserveData.principalStableDebt, + expectedVariableDebtAfterTx, + expectedReserveData.averageStableBorrowRate + ); + + expectedReserveData.liquidityRate = ratesAfterTx[0]; + + expectedReserveData.stableBorrowRate = ratesAfterTx[1]; + + expectedReserveData.variableBorrowRate = ratesAfterTx[2]; + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( - { - ...reserveDataBeforeAction, - principalStableDebt: expectedReserveData.principalStableDebt, - averageStableBorrowRate: expectedReserveData.averageStableBorrowRate, - lastUpdateTimestamp: txTimestamp, - }, + expectedReserveData.principalStableDebt, + expectedReserveData.averageStableBorrowRate, + txTimestamp, currentTimestamp ); + expectedReserveData.totalVariableDebt = reserveDataBeforeAction.scaledVariableDebt.rayMul( + calcExpectedReserveNormalizedDebt( + expectedReserveData.variableBorrowRate, + expectedReserveData.variableBorrowIndex, + txTimestamp, + currentTimestamp + ) + ); + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity .plus(expectedReserveData.totalVariableDebt) .plus(expectedReserveData.totalStableDebt); @@ -349,21 +393,6 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalVariableDebt, expectedReserveData.totalLiquidity ); - - const rates = calcExpectedInterestRates( - reserveDataBeforeAction.symbol, - reserveDataBeforeAction.marketStableRate, - expectedReserveData.utilizationRate, - expectedReserveData.totalStableDebt, - expectedReserveData.totalVariableDebt, - expectedReserveData.averageStableBorrowRate - ); - - expectedReserveData.liquidityRate = rates[0]; - - expectedReserveData.stableBorrowRate = rates[1]; - - expectedReserveData.variableBorrowRate = rates[2]; } else { expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; @@ -406,7 +435,12 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.variableBorrowRate = rates[2]; expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( - calcExpectedReserveNormalizedDebt(expectedReserveData, currentTimestamp) + calcExpectedReserveNormalizedDebt( + expectedReserveData.variableBorrowRate, + expectedReserveData.variableBorrowIndex, + txTimestamp, + currentTimestamp + ) ); expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity @@ -469,16 +503,32 @@ export const calcExpectedReserveDataAfterRepay = ( ); if (borrowRateMode == RateMode.Stable) { - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.minus( - amountRepaidBN + const expectedDebt = calcExpectedTotalStableDebt( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, + txTimestamp ); - expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( - reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt, - amountRepaidBN.negated(), - userDataBeforeAction.stableBorrowRate + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus( + amountRepaidBN ); + //due to accumulation errors, the total stable debt might be smaller than the last user debt. + //in this case we simply set the total supply and avg stable rate to 0. + if (expectedReserveData.principalStableDebt.lt(0)) { + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = new BigNumber( + 0 + ); + expectedReserveData.averageStableBorrowRate = new BigNumber(0); + } else { + expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( + reserveDataBeforeAction.averageStableBorrowRate, + expectedDebt, + amountRepaidBN.negated(), + userDataBeforeAction.stableBorrowRate + ); + } + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; } else { @@ -636,22 +686,18 @@ export const calcExpectedUserDataAfterRepay = ( userDataBeforeAction.stableRateLastUpdated, currentTimestamp ); - + let totalRepaidBN = new BigNumber(totalRepaid); if (totalRepaidBN.abs().eq(MAX_UINT_AMOUNT)) { - totalRepaidBN = - rateMode == RateMode.Stable - ? stableDebt - : variableDebt; + totalRepaidBN = rateMode == RateMode.Stable ? stableDebt : variableDebt; } if (rateMode == RateMode.Stable) { - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; expectedUserData.currentVariableDebt = userDataBeforeAction.currentVariableDebt; expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus( - totalRepaid + totalRepaidBN ); if (expectedUserData.currentStableDebt.eq('0')) { @@ -664,15 +710,17 @@ export const calcExpectedUserDataAfterRepay = ( expectedUserData.stableRateLastUpdated = txTimestamp; } } else { - expectedUserData.currentStableDebt = userDataBeforeAction.principalStableDebt; expectedUserData.principalStableDebt = stableDebt; expectedUserData.stableBorrowRate = userDataBeforeAction.stableBorrowRate; expectedUserData.stableRateLastUpdated = userDataBeforeAction.stableRateLastUpdated; - - expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus(totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)); - expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul(expectedDataAfterAction.variableBorrowIndex); + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.minus( + totalRepaidBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) + ); + expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul( + expectedDataAfterAction.variableBorrowIndex + ); } expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; @@ -1028,23 +1076,17 @@ const calcExpectedAverageStableBorrowRate = ( .decimalPlaces(0, BigNumber.ROUND_DOWN); }; -const calcExpectedVariableDebtUserIndex = ( - reserveDataBeforeAction: ReserveData, - expectedUserBalanceAfterAction: BigNumber, - currentTimestamp: BigNumber -) => { - if (expectedUserBalanceAfterAction.eq(0)) { - return new BigNumber(0); - } - return calcExpectedReserveNormalizedDebt(reserveDataBeforeAction, currentTimestamp); -}; - export const calcExpectedVariableDebtTokenBalance = ( reserveData: ReserveData, userData: UserReserveData, currentTimestamp: BigNumber ) => { - const normalizedDebt = calcExpectedReserveNormalizedDebt(reserveData, currentTimestamp); + const normalizedDebt = calcExpectedReserveNormalizedDebt( + reserveData.variableBorrowRate, + reserveData.variableBorrowIndex, + reserveData.lastUpdateTimestamp, + currentTimestamp + ); const {scaledVariableDebt} = userData; @@ -1237,11 +1279,11 @@ const calcExpectedReserveNormalizedIncome = ( }; const calcExpectedReserveNormalizedDebt = ( - reserveData: ReserveData, + variableBorrowRate: BigNumber, + variableBorrowIndex: BigNumber, + lastUpdateTimestamp: BigNumber, currentTimestamp: BigNumber ) => { - const {variableBorrowRate, variableBorrowIndex, lastUpdateTimestamp} = reserveData; - //if utilization rate is 0, nothing to compound if (variableBorrowRate.eq('0')) { return variableBorrowIndex; @@ -1300,14 +1342,19 @@ const calcExpectedVariableBorrowIndex = (reserveData: ReserveData, timestamp: Bi return cumulatedInterest.rayMul(reserveData.variableBorrowIndex); }; -const calcExpectedTotalStableDebt = (reserveData: ReserveData, timestamp: BigNumber) => { +const calcExpectedTotalStableDebt = ( + principalStableDebt: BigNumber, + averageStableBorrowRate: BigNumber, + lastUpdateTimestamp: BigNumber, + currentTimestamp: BigNumber +) => { const cumulatedInterest = calcCompoundedInterest( - reserveData.averageStableBorrowRate, - timestamp, - reserveData.lastUpdateTimestamp + averageStableBorrowRate, + currentTimestamp, + lastUpdateTimestamp ); - return cumulatedInterest.rayMul(reserveData.principalStableDebt); + return cumulatedInterest.rayMul(principalStableDebt); }; const calcExpectedTotalVariableDebt = ( diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 54fe7433..98e0c164 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = []; +const selectedScenarios: string[] = ['borrow-repay-variable.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 52033bae21518bbed67ef54a9142cd3d4c3655b0 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 18 Sep 2020 18:03:38 +0200 Subject: [PATCH 33/79] Added console logs --- test/helpers/actions.ts | 4 ++++ test/scenario.spec.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index ba874e6e..4921e66c 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -377,9 +377,13 @@ export const borrow = async ( console.log("total stable debt actual: ", reserveDataAfter.totalStableDebt.toFixed()); console.log("total stable debt expected: ", expectedReserveData.totalStableDebt.toFixed()); + console.log("total avg stable rate actual: ", reserveDataAfter.averageStableBorrowRate.toFixed()); + console.log("total avg stable rate expected: ", expectedReserveData.averageStableBorrowRate.toFixed()); console.log("total variable debt actual: ", reserveDataAfter.totalVariableDebt.toFixed()); console.log("total variable debt expected: ", expectedReserveData.totalVariableDebt.toFixed()); + console.log("variable borrow rate actual: ", reserveDataAfter.variableBorrowRate.toFixed()); + console.log("variable borrow rate expected: ", expectedReserveData.variableBorrowRate.toFixed()); expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 98e0c164..d9edd4ac 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['borrow-repay-variable.json']; +const selectedScenarios: string[] = ['borrow-repay-stable.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From f188a212215e9c1ea9a71a93cec33d1e1ac70c9b Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 10:12:04 +0200 Subject: [PATCH 34/79] Fixed deployed-contracts --- deployed-contracts.json | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/deployed-contracts.json b/deployed-contracts.json index e37c68bd..daecd72c 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -65,12 +65,9 @@ "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" }, "localhost": { -<<<<<<< HEAD -======= "address": "0x65e0Cd5B8904A02f2e00BC6f58bf881998D54BDe" }, "coverage": { ->>>>>>> master "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" } }, @@ -84,12 +81,9 @@ "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" }, "localhost": { -<<<<<<< HEAD -======= "address": "0x5d12dDe3286D94E0d85F9D3B01B7099cfA0aBCf1" }, "coverage": { ->>>>>>> master "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" } }, @@ -213,12 +207,9 @@ "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" }, "localhost": { -<<<<<<< HEAD -======= "address": "0xAd49512dFBaD6fc13D67d3935283c0606812E962" }, "coverage": { ->>>>>>> master "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" } }, @@ -563,12 +554,9 @@ "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" }, "localhost": { -<<<<<<< HEAD -======= "address": "0x9305d862ee95a899b83906Cd9CB666aC269E5f66" }, "coverage": { ->>>>>>> master "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" } }, @@ -674,11 +662,7 @@ "buidlerevm": { "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" }, -<<<<<<< HEAD - "localhost": { -======= "coverage": { ->>>>>>> master "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" } } From c8b044aecfdd5a2f208840b1d887d12c92f480ba Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 12:29:33 +0200 Subject: [PATCH 35/79] Fixed borrow tests --- test/helpers/actions.ts | 23 +-------- .../scenarios/borrow-repay-stable.json | 11 ++++ test/helpers/utils/calculations.ts | 51 +++++++++++-------- test/scenario.spec.ts | 2 +- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 4921e66c..c9bf4bcf 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -32,6 +32,7 @@ import {waitForTx} from '../__setup.spec'; import {ContractReceipt} from 'ethers'; import {AToken} from '../../types/AToken'; import {RateMode, tEthereumAddress} from '../../helpers/types'; +import { time } from 'console'; const {expect} = chai; @@ -262,10 +263,6 @@ export const withdraw = async ( txCost ); - const actualAmountWithdrawn = userDataBefore.currentATokenBalance.minus( - expectedUserData.currentATokenBalance - ); - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); @@ -375,16 +372,6 @@ export const borrow = async ( txCost ); - console.log("total stable debt actual: ", reserveDataAfter.totalStableDebt.toFixed()); - console.log("total stable debt expected: ", expectedReserveData.totalStableDebt.toFixed()); - console.log("total avg stable rate actual: ", reserveDataAfter.averageStableBorrowRate.toFixed()); - console.log("total avg stable rate expected: ", expectedReserveData.averageStableBorrowRate.toFixed()); - - console.log("total variable debt actual: ", reserveDataAfter.totalVariableDebt.toFixed()); - console.log("total variable debt expected: ", expectedReserveData.totalVariableDebt.toFixed()); - console.log("variable borrow rate actual: ", reserveDataAfter.variableBorrowRate.toFixed()); - console.log("variable borrow rate expected: ", expectedReserveData.variableBorrowRate.toFixed()); - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); @@ -489,14 +476,6 @@ export const repay = async ( txCost ); - - console.log("total stable debt actual: ", reserveDataAfter.totalStableDebt.toFixed()); - console.log("total stable debt expected: ", expectedReserveData.totalStableDebt.toFixed()); - - console.log("total variable debt actual: ", reserveDataAfter.totalVariableDebt.toFixed()); - console.log("total variable debt expected: ", expectedReserveData.totalVariableDebt.toFixed()); - - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/helpers/scenarios/borrow-repay-stable.json b/test/helpers/scenarios/borrow-repay-stable.json index 9d2348e9..87e7de0b 100644 --- a/test/helpers/scenarios/borrow-repay-stable.json +++ b/test/helpers/scenarios/borrow-repay-stable.json @@ -626,6 +626,17 @@ }, "expected": "success" }, + { + "name": "repay", + "args": { + "reserve": "DAI", + "amount": "-1", + "user": "1", + "onBehalfOf": "1", + "borrowRateMode": "variable" + }, + "expected": "success" + }, { "name": "withdraw", "args": { diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 3cd05b69..671e6205 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -97,8 +97,6 @@ export const calcExpectedUserDataAfterWithdraw = ( currentTimestamp: BigNumber, txCost: BigNumber ): UserReserveData => { - console.log('Checking withdraw'); - const expectedUserData = {}; const aTokenBalance = calcExpectedATokenBalance( @@ -236,9 +234,6 @@ export const calcExpectedReserveDataAfterWithdraw = ( ).toFixed(); } - expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.totalLiquidity).minus( - amountWithdrawn - ); expectedReserveData.availableLiquidity = new BigNumber( reserveDataBeforeAction.availableLiquidity ).minus(amountWithdrawn); @@ -261,13 +256,17 @@ export const calcExpectedReserveDataAfterWithdraw = ( reserveDataBeforeAction.lastUpdateTimestamp, txTimestamp ); - expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( - reserveDataBeforeAction, + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( expectedReserveData.variableBorrowIndex ); expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; + expectedReserveData.totalLiquidity = new BigNumber(reserveDataBeforeAction.availableLiquidity) + .minus(amountWithdrawn) + .plus(expectedReserveData.totalVariableDebt) + .plus(expectedReserveData.totalStableDebt); + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, expectedReserveData.totalVariableDebt, @@ -319,12 +318,10 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.lastUpdateTimestamp = txTimestamp; if (borrowRateMode == RateMode.Stable) { - expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; - const expectedVariableDebtAfterTx = calcExpectedTotalVariableDebt( - reserveDataBeforeAction, - txTimestamp + const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex ); const expectedStableDebtUntilTx = calcExpectedTotalStableDebt( @@ -394,28 +391,38 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalLiquidity ); } else { + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; - expectedReserveData.totalStableDebt = calcExpectedStableDebtTokenBalance( - userDataBeforeAction.principalStableDebt, - userDataBeforeAction.stableBorrowRate, - userDataBeforeAction.stableRateLastUpdated, + const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, + txTimestamp + ); + + expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, currentTimestamp ); + expectedReserveData.averageStableBorrowRate = reserveDataBeforeAction.averageStableBorrowRate; expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( amountBorrowedBN.rayDiv(expectedReserveData.variableBorrowIndex) ); + const totalVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul( expectedReserveData.variableBorrowIndex ); const utilizationRateAfterTx = calcExpectedUtilizationRate( - expectedReserveData.totalStableDebt, + totalStableDebtAfterTx, totalVariableDebtAfterTx, expectedReserveData.availableLiquidity - .plus(expectedReserveData.totalStableDebt) + .plus(totalStableDebtAfterTx) .plus(totalVariableDebtAfterTx) ); @@ -423,7 +430,7 @@ export const calcExpectedReserveDataAfterBorrow = ( reserveDataBeforeAction.symbol, reserveDataBeforeAction.marketStableRate, utilizationRateAfterTx, - expectedReserveData.totalStableDebt, + totalStableDebtAfterTx, totalVariableDebtAfterTx, expectedReserveData.averageStableBorrowRate ); @@ -513,6 +520,7 @@ export const calcExpectedReserveDataAfterRepay = ( expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedDebt.minus( amountRepaidBN ); + //due to accumulation errors, the total stable debt might be smaller than the last user debt. //in this case we simply set the total supply and avg stable rate to 0. if (expectedReserveData.principalStableDebt.lt(0)) { @@ -530,7 +538,10 @@ export const calcExpectedReserveDataAfterRepay = ( } expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; + + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); } else { expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus( amountRepaidBN.rayDiv(expectedReserveData.variableBorrowIndex) @@ -694,7 +705,7 @@ export const calcExpectedUserDataAfterRepay = ( if (rateMode == RateMode.Stable) { expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; - expectedUserData.currentVariableDebt = userDataBeforeAction.currentVariableDebt; + expectedUserData.currentVariableDebt = variableDebt; expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = stableDebt.minus( totalRepaidBN diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index d9edd4ac..be3f2977 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['borrow-repay-stable.json']; +const selectedScenarios: string[] = ['borrow-repay-stable.json','borrow-repay-variable.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 8792515f5b45907323b304e63b1b80fe20d05e25 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 14:29:59 +0200 Subject: [PATCH 36/79] fixed swap rate mode tests --- test/helpers/utils/calculations.ts | 105 ++++++++++++++++------------- test/scenario.spec.ts | 2 +- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 671e6205..8f029d9a 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -391,7 +391,6 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalLiquidity ); } else { - expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance( @@ -791,41 +790,59 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( txTimestamp ); + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); + + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( + reserveDataBeforeAction, + txTimestamp + ); + expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity; + const totalStableDebtUntilTx = calcExpectedTotalStableDebt( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.lastUpdateTimestamp, + txTimestamp + ); + if (rateMode === RateMode.Stable) { //swap user stable debt to variable - const debtAccrued = stableDebt.minus(userDataBeforeAction.principalStableDebt); + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( + stableDebt.rayDiv(expectedReserveData.variableBorrowIndex) + ); - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); + + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(stableDebt); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), + expectedReserveData.principalStableDebt.plus(stableDebt), stableDebt.negated(), userDataBeforeAction.stableBorrowRate ); - - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt.plus( - stableDebt - ); - - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.minus( - userDataBeforeAction.principalStableDebt - ); } else { - const totalDebtBefore = userDataBeforeAction.scaledVariableDebt.rayMul( - reserveDataBeforeAction.variableBorrowIndex - ); - const debtAccrued = variableDebt.minus(totalDebtBefore); - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); + //swap variable to stable - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus( + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus( variableDebt ); + + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.minus( + variableDebt.rayDiv(expectedReserveData.variableBorrowIndex) + ); + + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); + expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, reserveDataBeforeAction.totalStableDebt, @@ -834,6 +851,10 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( ); } + expectedReserveData.totalLiquidity = reserveDataBeforeAction.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(expectedReserveData.totalVariableDebt); + expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, expectedReserveData.totalVariableDebt, @@ -854,15 +875,6 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - return expectedReserveData; }; @@ -876,19 +888,19 @@ export const calcExpectedUserDataAfterSwapRateMode = ( ): UserReserveData => { const expectedUserData = {...userDataBeforeAction}; - const variableBorrowBalance = calcExpectedVariableDebtTokenBalance( - reserveDataBeforeAction, - userDataBeforeAction, - txTimestamp - ); - - const stableBorrowBalance = calcExpectedStableDebtTokenBalance( + const stableDebtBalance = calcExpectedStableDebtTokenBalance( userDataBeforeAction.principalStableDebt, userDataBeforeAction.stableBorrowRate, userDataBeforeAction.stableRateLastUpdated, txTimestamp ); + const variableDebtBalance = calcExpectedVariableDebtTokenBalance( + reserveDataBeforeAction, + userDataBeforeAction, + txTimestamp + ); + expectedUserData.currentATokenBalance = calcExpectedATokenBalance( reserveDataBeforeAction, userDataBeforeAction, @@ -901,31 +913,30 @@ export const calcExpectedUserDataAfterSwapRateMode = ( expectedUserData.stableBorrowRate = new BigNumber(0); - expectedUserData.principalVariableDebt = expectedUserData.currentVariableDebt = userDataBeforeAction.currentVariableDebt.plus( - stableBorrowBalance + expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt.plus( + stableDebtBalance.rayDiv(expectedDataAfterAction.variableBorrowIndex) ); - expectedUserData.variableBorrowIndex = expectedDataAfterAction.variableBorrowIndex; + expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt.rayMul( + expectedDataAfterAction.variableBorrowIndex + ); + expectedUserData.stableRateLastUpdated = new BigNumber(0); } else { expectedUserData.principalStableDebt = expectedUserData.currentStableDebt = userDataBeforeAction.currentStableDebt.plus( - variableBorrowBalance + variableDebtBalance ); //weighted average of the previous and the current expectedUserData.stableBorrowRate = calcExpectedUserStableRate( - userDataBeforeAction.principalStableDebt, + stableDebtBalance, userDataBeforeAction.stableBorrowRate, - variableBorrowBalance, + variableDebtBalance, reserveDataBeforeAction.stableBorrowRate ); expectedUserData.stableRateLastUpdated = txTimestamp; - expectedUserData.currentVariableDebt = expectedUserData.principalVariableDebt = new BigNumber( - 0 - ); - - expectedUserData.variableBorrowIndex = new BigNumber(0); + expectedUserData.currentVariableDebt = expectedUserData.scaledVariableDebt = new BigNumber(0); } expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index be3f2977..8a14d4e2 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['borrow-repay-stable.json','borrow-repay-variable.json']; +const selectedScenarios: string[] = ['swap-rate-mode.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From a1a45d392a7bb1b0e7b1d0781825b4600c536f1e Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 15:27:53 +0200 Subject: [PATCH 37/79] Updating rebalance rate tests --- test/helpers/actions.ts | 28 +++++++++- test/helpers/utils/calculations.ts | 72 +++++++++++++++----------- test/helpers/utils/helpers.ts | 3 ++ test/helpers/utils/interfaces/index.ts | 1 + test/scenario.spec.ts | 2 +- 5 files changed, 74 insertions(+), 32 deletions(-) diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index c9bf4bcf..44c134eb 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -49,7 +49,8 @@ const almostEqualOrEqual = function ( key === 'marketStableRate' || key === 'symbol' || key === 'aTokenAddress' || - key === 'decimals' + key === 'decimals' || + key === 'totalStableDebtLastUpdated' ) { // skipping consistency check on accessory data return; @@ -369,9 +370,23 @@ export const borrow = async ( userDataBefore, txTimestamp, timestamp, - txCost + onBehalfOf, + user.address ); + console.log("total debt stable exp ", expectedReserveData.totalStableDebt.toFixed()); + console.log("total debt stable act ", reserveDataAfter.totalStableDebt.toFixed()); + + console.log("total debt variable exp ", expectedReserveData.totalVariableDebt.toFixed()); + console.log("total debt variable act ", reserveDataAfter.totalVariableDebt.toFixed()); + + console.log("avl liquidity exp ", expectedReserveData.availableLiquidity.toFixed()); + console.log("avl liquidity exp ", reserveDataAfter.availableLiquidity.toFixed()); + + console.log("avg borrow rate exp ", expectedReserveData.averageStableBorrowRate.toFixed()); + console.log("avl borrow rate exp ", reserveDataAfter.averageStableBorrowRate.toFixed()); + + expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); @@ -664,6 +679,15 @@ export const rebalanceStableBorrowRate = async ( txTimestamp ); + console.log("total debt stable exp ", expectedReserveData.totalStableDebt.toFixed()); + console.log("total debt stable act ", reserveDataAfter.totalStableDebt.toFixed()); + + console.log("total debt variable exp ", expectedReserveData.totalVariableDebt.toFixed()); + console.log("total debt variable act ", reserveDataAfter.totalVariableDebt.toFixed()); + + console.log("avl liquidity exp ", expectedReserveData.availableLiquidity.toFixed()); + console.log("avl liquidity exp ", reserveDataAfter.availableLiquidity.toFixed()); + expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 8f029d9a..6d76db67 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -7,7 +7,7 @@ import { EXCESS_UTILIZATION_RATE, ZERO_ADDRESS, } from '../../../helpers/constants'; -import {IReserveParams, iAavePoolAssets, RateMode} from '../../../helpers/types'; +import {IReserveParams, iAavePoolAssets, RateMode, tEthereumAddress} from '../../../helpers/types'; import './math'; import {ReserveData, UserReserveData} from './interfaces'; @@ -185,7 +185,7 @@ export const calcExpectedReserveDataAfterDeposit = ( expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); expectedReserveData.totalVariableDebt = calcExpectedTotalVariableDebt( @@ -253,7 +253,7 @@ export const calcExpectedReserveDataAfterWithdraw = ( expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( @@ -318,6 +318,7 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.lastUpdateTimestamp = txTimestamp; if (borrowRateMode == RateMode.Stable) { + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul( @@ -327,7 +328,7 @@ export const calcExpectedReserveDataAfterBorrow = ( const expectedStableDebtUntilTx = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); @@ -403,7 +404,7 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, currentTimestamp ); @@ -512,7 +513,7 @@ export const calcExpectedReserveDataAfterRepay = ( const expectedDebt = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); @@ -597,13 +598,15 @@ export const calcExpectedUserDataAfterBorrow = ( userDataBeforeAction: UserReserveData, txTimestamp: BigNumber, currentTimestamp: BigNumber, - txCost: BigNumber + user: tEthereumAddress, + onBehalfOf: tEthereumAddress ): UserReserveData => { const expectedUserData = {}; const amountBorrowedBN = new BigNumber(amountBorrowed); if (interestRateMode == RateMode.Stable) { + const stableDebtUntilTx = calcExpectedStableDebtTokenBalance( userDataBeforeAction.principalStableDebt, userDataBeforeAction.stableBorrowRate, @@ -805,7 +808,7 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( const totalStableDebtUntilTx = calcExpectedTotalStableDebt( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); @@ -819,7 +822,9 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( expectedReserveData.variableBorrowIndex ); - expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus(stableDebt); + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.minus( + stableDebt + ); expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, @@ -828,7 +833,6 @@ export const calcExpectedReserveDataAfterSwapRateMode = ( userDataBeforeAction.stableBorrowRate ); } else { - //swap variable to stable expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = totalStableDebtUntilTx.plus( @@ -953,39 +957,58 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( expectedReserveData.address = reserveDataBeforeAction.address; - const stableBorrowBalance = calcExpectedStableDebtTokenBalance( + const userStableDebt = calcExpectedStableDebtTokenBalance( userDataBeforeAction.principalStableDebt, userDataBeforeAction.stableBorrowRate, userDataBeforeAction.stableRateLastUpdated, txTimestamp ); - const debtAccrued = stableBorrowBalance.minus(userDataBeforeAction.principalStableDebt); + expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( + reserveDataBeforeAction, + txTimestamp + ); - expectedReserveData.totalLiquidity = reserveDataBeforeAction.totalLiquidity.plus(debtAccrued); + expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( + reserveDataBeforeAction, + txTimestamp + ); + + expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; + expectedReserveData.totalVariableDebt = expectedReserveData.scaledVariableDebt.rayMul( + expectedReserveData.variableBorrowIndex + ); + + expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = calcExpectedTotalStableDebt( + reserveDataBeforeAction.principalStableDebt, + reserveDataBeforeAction.averageStableBorrowRate, + reserveDataBeforeAction.totalStableDebtLastUpdated, + txTimestamp + ); expectedReserveData.availableLiquidity = reserveDataBeforeAction.availableLiquidity; + expectedReserveData.totalLiquidity = expectedReserveData.availableLiquidity + .plus(expectedReserveData.totalStableDebt) + .plus(expectedReserveData.totalVariableDebt); + //removing the stable liquidity at the old rate const avgRateBefore = calcExpectedAverageStableBorrowRate( reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.totalStableDebt.plus(debtAccrued), - stableBorrowBalance.negated(), + expectedReserveData.totalStableDebt, + userStableDebt.negated(), userDataBeforeAction.stableBorrowRate ); // adding it again at the new rate expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( avgRateBefore, - reserveDataBeforeAction.totalStableDebt.minus(userDataBeforeAction.principalStableDebt), - stableBorrowBalance, + expectedReserveData.totalStableDebt.minus(userStableDebt), + userStableDebt, reserveDataBeforeAction.stableBorrowRate ); - expectedReserveData.totalVariableDebt = reserveDataBeforeAction.totalVariableDebt; - expectedReserveData.totalStableDebt = reserveDataBeforeAction.totalStableDebt.plus(debtAccrued); - expectedReserveData.utilizationRate = calcExpectedUtilizationRate( expectedReserveData.totalStableDebt, expectedReserveData.totalVariableDebt, @@ -1007,15 +1030,6 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( expectedReserveData.variableBorrowRate = rates[2]; - expectedReserveData.liquidityIndex = calcExpectedLiquidityIndex( - reserveDataBeforeAction, - txTimestamp - ); - expectedReserveData.variableBorrowIndex = calcExpectedVariableBorrowIndex( - reserveDataBeforeAction, - txTimestamp - ); - return expectedReserveData; }; diff --git a/test/helpers/utils/helpers.ts b/test/helpers/utils/helpers.ts index b98ba688..7c3dbd2a 100644 --- a/test/helpers/utils/helpers.ts +++ b/test/helpers/utils/helpers.ts @@ -25,6 +25,8 @@ export const getReserveData = async ( const variableDebtToken = await getVariableDebtToken(tokenAddresses.variableDebtTokenAddress); const [principalStableDebt] = await stableDebtToken.getSupplyData(); + const totalStableDebtLastUpdated = await stableDebtToken.getTotalSupplyLastUpdated(); + const scaledVariableDebt = await variableDebtToken.scaledTotalSupply(); @@ -57,6 +59,7 @@ export const getReserveData = async ( liquidityIndex: new BigNumber(reserveData.liquidityIndex.toString()), variableBorrowIndex: new BigNumber(reserveData.variableBorrowIndex.toString()), lastUpdateTimestamp: new BigNumber(reserveData.lastUpdateTimestamp), + totalStableDebtLastUpdated: new BigNumber(totalStableDebtLastUpdated), principalStableDebt: new BigNumber(principalStableDebt.toString()), scaledVariableDebt: new BigNumber(scaledVariableDebt.toString()), address: reserve, diff --git a/test/helpers/utils/interfaces/index.ts b/test/helpers/utils/interfaces/index.ts index 3162e398..72b30708 100644 --- a/test/helpers/utils/interfaces/index.ts +++ b/test/helpers/utils/interfaces/index.ts @@ -34,6 +34,7 @@ export interface ReserveData { aTokenAddress: string; marketStableRate: BigNumber; lastUpdateTimestamp: BigNumber; + totalStableDebtLastUpdated: BigNumber; liquidityRate: BigNumber; [key: string]: BigNumber | string; } diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 8a14d4e2..54fe7433 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['swap-rate-mode.json']; +const selectedScenarios: string[] = []; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 6f9ff11e497dc5688b67a1cb8d205d439e0dbefe Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 15:35:22 +0200 Subject: [PATCH 38/79] Fixed credit delegation tests --- contracts/lendingpool/LendingPool.sol | 39 +++++++++++++++++++-------- test/helpers/actions.ts | 14 +++++----- test/helpers/utils/calculations.ts | 7 ++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index a63f11df..53721f53 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -47,7 +47,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 public constant UINT_MAX_VALUE = uint256(-1); uint256 public constant LENDINGPOOL_REVISION = 0x2; - /** * @dev only lending pools configurator can use functions affected by this modifier **/ @@ -68,7 +67,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage function whenNotPaused() internal view { require(!_paused, Errors.IS_PAUSED); } - + function getRevision() internal override pure returns (uint256) { return LENDINGPOOL_REVISION; } @@ -248,9 +247,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 rateMode, address onBehalfOf ) external override { - whenNotPaused(); - + ReserveLogic.ReserveData storage reserve = _reserves[asset]; (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve); @@ -281,7 +279,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); } else { - IVariableDebtToken(reserve.variableDebtTokenAddress).burn(onBehalfOf, paybackAmount, reserve.variableBorrowIndex); + IVariableDebtToken(reserve.variableDebtTokenAddress).burn( + onBehalfOf, + paybackAmount, + reserve.variableBorrowIndex + ); } address aToken = reserve.aTokenAddress; @@ -322,10 +324,18 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage 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, reserve.variableBorrowIndex); + IVariableDebtToken(reserve.variableDebtTokenAddress).mint( + msg.sender, + stableDebt, + reserve.variableBorrowIndex + ); } else { //do the opposite - IVariableDebtToken(reserve.variableDebtTokenAddress).burn(msg.sender, variableDebt, reserve.variableBorrowIndex); + IVariableDebtToken(reserve.variableDebtTokenAddress).burn( + msg.sender, + variableDebt, + reserve.variableBorrowIndex + ); IStableDebtToken(reserve.stableDebtTokenAddress).mint( msg.sender, variableDebt, @@ -372,7 +382,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET ); - reserve.updateState(); //burn old debt tokens, mint new ones @@ -502,7 +511,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _flashLiquidationLocked = false; } - struct FlashLoanLocalVars { + struct FlashLoanLocalVars { uint256 premium; uint256 amountPlusPremium; IFlashLoanReceiver receiver; @@ -883,9 +892,17 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ) { currentStableRate = reserve.currentStableBorrowRate; - IStableDebtToken(reserve.stableDebtTokenAddress).mint(vars.user, vars.amount, currentStableRate); + IStableDebtToken(reserve.stableDebtTokenAddress).mint( + vars.onBehalfOf, + vars.amount, + currentStableRate + ); } else { - IVariableDebtToken(reserve.variableDebtTokenAddress).mint(vars.user, vars.amount, reserve.variableBorrowIndex); + IVariableDebtToken(reserve.variableDebtTokenAddress).mint( + vars.onBehalfOf, + vars.amount, + reserve.variableBorrowIndex + ); } reserve.updateInterestRates( diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 44c134eb..b1e60e0d 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -369,9 +369,7 @@ export const borrow = async ( expectedReserveData, userDataBefore, txTimestamp, - timestamp, - onBehalfOf, - user.address + timestamp ); console.log("total debt stable exp ", expectedReserveData.totalStableDebt.toFixed()); @@ -381,10 +379,13 @@ export const borrow = async ( console.log("total debt variable act ", reserveDataAfter.totalVariableDebt.toFixed()); console.log("avl liquidity exp ", expectedReserveData.availableLiquidity.toFixed()); - console.log("avl liquidity exp ", reserveDataAfter.availableLiquidity.toFixed()); + console.log("avl liquidity act ", reserveDataAfter.availableLiquidity.toFixed()); console.log("avg borrow rate exp ", expectedReserveData.averageStableBorrowRate.toFixed()); - console.log("avl borrow rate exp ", reserveDataAfter.averageStableBorrowRate.toFixed()); + console.log("avl borrow rate act ", reserveDataAfter.averageStableBorrowRate.toFixed()); + + console.log("liquidity rate exp ", expectedReserveData.averageStableBorrowRate.toFixed()); + console.log("avl borrow rate act ", reserveDataAfter.averageStableBorrowRate.toFixed()); expectEqual(reserveDataAfter, expectedReserveData); @@ -487,8 +488,7 @@ export const repay = async ( user.address, onBehalfOf.address, txTimestamp, - timestamp, - txCost + timestamp ); expectEqual(reserveDataAfter, expectedReserveData); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 6d76db67..10f1127a 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -597,9 +597,7 @@ export const calcExpectedUserDataAfterBorrow = ( expectedDataAfterAction: ReserveData, userDataBeforeAction: UserReserveData, txTimestamp: BigNumber, - currentTimestamp: BigNumber, - user: tEthereumAddress, - onBehalfOf: tEthereumAddress + currentTimestamp: BigNumber ): UserReserveData => { const expectedUserData = {}; @@ -682,8 +680,7 @@ export const calcExpectedUserDataAfterRepay = ( user: string, onBehalfOf: string, txTimestamp: BigNumber, - currentTimestamp: BigNumber, - txCost: BigNumber + currentTimestamp: BigNumber ): UserReserveData => { const expectedUserData = {}; From 56be9304c24ff0f1f4246248ac45147a176bb3fd Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 15:52:53 +0200 Subject: [PATCH 39/79] Fixed rebalance rate tests --- test/helpers/actions.ts | 16 ---------------- test/helpers/utils/calculations.ts | 8 +++++++- test/upgradeability.spec.ts | 3 ++- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index b1e60e0d..e1b55fc9 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -372,22 +372,6 @@ export const borrow = async ( timestamp ); - console.log("total debt stable exp ", expectedReserveData.totalStableDebt.toFixed()); - console.log("total debt stable act ", reserveDataAfter.totalStableDebt.toFixed()); - - console.log("total debt variable exp ", expectedReserveData.totalVariableDebt.toFixed()); - console.log("total debt variable act ", reserveDataAfter.totalVariableDebt.toFixed()); - - console.log("avl liquidity exp ", expectedReserveData.availableLiquidity.toFixed()); - console.log("avl liquidity act ", reserveDataAfter.availableLiquidity.toFixed()); - - console.log("avg borrow rate exp ", expectedReserveData.averageStableBorrowRate.toFixed()); - console.log("avl borrow rate act ", reserveDataAfter.averageStableBorrowRate.toFixed()); - - console.log("liquidity rate exp ", expectedReserveData.averageStableBorrowRate.toFixed()); - console.log("avl borrow rate act ", reserveDataAfter.averageStableBorrowRate.toFixed()); - - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index 10f1127a..be0a8c3f 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -392,12 +392,13 @@ export const calcExpectedReserveDataAfterBorrow = ( expectedReserveData.totalLiquidity ); } else { + expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt; const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance( reserveDataBeforeAction.principalStableDebt, reserveDataBeforeAction.averageStableBorrowRate, - reserveDataBeforeAction.lastUpdateTimestamp, + reserveDataBeforeAction.totalStableDebtLastUpdated, txTimestamp ); @@ -630,7 +631,9 @@ export const calcExpectedUserDataAfterBorrow = ( ); expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt; + } else { + expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus( amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex) ); @@ -654,6 +657,7 @@ export const calcExpectedUserDataAfterBorrow = ( expectedUserData, currentTimestamp ); + expectedUserData.liquidityRate = expectedDataAfterAction.liquidityRate; expectedUserData.usageAsCollateralEnabled = userDataBeforeAction.usageAsCollateralEnabled; @@ -952,6 +956,8 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( ): ReserveData => { const expectedReserveData: ReserveData = {}; + console.log("Rebalancing"); + expectedReserveData.address = reserveDataBeforeAction.address; const userStableDebt = calcExpectedStableDebtTokenBalance( diff --git a/test/upgradeability.spec.ts b/test/upgradeability.spec.ts index 47c452bf..29f2da40 100644 --- a/test/upgradeability.spec.ts +++ b/test/upgradeability.spec.ts @@ -23,9 +23,10 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => { const aTokenInstance = await deployContract(eContractid.MockAToken, [ pool.address, dai.address, + ZERO_ADDRESS, 'Aave Interest bearing DAI updated', 'aDAI', - ZERO_ADDRESS, + ZERO_ADDRESS ]); const stableDebtTokenInstance = await deployContract( From b7c4a255a96815f65287e24f7e482b0ff04b522c Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 15:58:19 +0200 Subject: [PATCH 40/79] Refactored aToken --- contracts/tokenization/AToken.sol | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index eef9ffa4..00025c05 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -20,19 +20,9 @@ import {SafeERC20} from '../misc/SafeERC20.sol'; */ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { using WadRayMath for uint256; - using SafeERC20 for IncentivizedERC20; + using SafeERC20 for IERC20; - uint256 public constant UINT_MAX_VALUE = uint256(-1); - address public immutable UNDERLYING_ASSET_ADDRESS; - address public immutable RESERVE_TREASURY_ADDRESS; - LendingPool public immutable POOL; - /// @dev owner => next valid nonce to submit with permit() - mapping(address => uint256) public _nonces; - - uint256 public constant ATOKEN_REVISION = 0x1; - - bytes32 public DOMAIN_SEPARATOR; bytes public constant EIP712_REVISION = bytes('1'); bytes32 internal constant EIP712_DOMAIN = keccak256( 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' @@ -41,6 +31,17 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { 'Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)' ); + uint256 public constant UINT_MAX_VALUE = uint256(-1); + uint256 public constant ATOKEN_REVISION = 0x1; + address public immutable UNDERLYING_ASSET_ADDRESS; + address public immutable RESERVE_TREASURY_ADDRESS; + LendingPool public immutable POOL; + + /// @dev owner => next valid nonce to submit with permit() + mapping(address => uint256) public _nonces; + + bytes32 public DOMAIN_SEPARATOR; + modifier onlyLendingPool { require(msg.sender == address(POOL), Errors.CALLER_MUST_BE_LENDING_POOL); _; @@ -110,7 +111,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { _burn(user, scaledAmount); //transfers the underlying to the target - IncentivizedERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount); + IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount); //transfer event to track balances emit Transfer(user, address(0), amount); @@ -239,7 +240,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { onlyLendingPool returns (uint256) { - IncentivizedERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(target, amount); + IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(target, amount); return amount; } From 8ed9b88163e51e115e9cf94b9bca98035ca0b0a4 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 16:07:26 +0200 Subject: [PATCH 41/79] fixed last tests on repayWithCollateral --- test/flash-liquidation-with-collateral.spec.ts | 6 +++--- test/helpers/actions.ts | 9 --------- test/helpers/utils/calculations.ts | 2 -- test/repay-with-collateral.spec.ts | 4 ++-- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/test/flash-liquidation-with-collateral.spec.ts b/test/flash-liquidation-with-collateral.spec.ts index 7298cb9b..3b20f79c 100644 --- a/test/flash-liquidation-with-collateral.spec.ts +++ b/test/flash-liquidation-with-collateral.spec.ts @@ -297,7 +297,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn 'INVALID_DEBT_POSITION' ); - expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.equal( + expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.almostEqual( new BigNumber(wethUserDataBefore.currentATokenBalance).minus( expectedCollateralLiquidated.toString() ), @@ -570,7 +570,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn ); // First half - const amountToRepay = daiReserveDataBefore.totalVariableDebt.multipliedBy(0.6).toString(); + const amountToRepay = daiReserveDataBefore.totalVariableDebt.multipliedBy(0.6).toFixed(0).toString(); await mockSwapAdapter.setAmountToReturn(amountToRepay); await waitForTx( @@ -818,7 +818,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn new BigNumber(repayWithCollateralTimestamp) ).minus(usdcUserDataBefore.currentVariableDebt); - expect(usdcUserDataAfter.currentVariableDebt).to.be.bignumber.equal( + expect(usdcUserDataAfter.currentVariableDebt).to.be.bignumber.almostEqual( new BigNumber(usdcUserDataBefore.currentVariableDebt) .minus(expectedDebtCovered.toString()) .plus(expectedVariableDebtIncrease), diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index e1b55fc9..69c9c6ce 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -663,15 +663,6 @@ export const rebalanceStableBorrowRate = async ( txTimestamp ); - console.log("total debt stable exp ", expectedReserveData.totalStableDebt.toFixed()); - console.log("total debt stable act ", reserveDataAfter.totalStableDebt.toFixed()); - - console.log("total debt variable exp ", expectedReserveData.totalVariableDebt.toFixed()); - console.log("total debt variable act ", reserveDataAfter.totalVariableDebt.toFixed()); - - console.log("avl liquidity exp ", expectedReserveData.availableLiquidity.toFixed()); - console.log("avl liquidity exp ", reserveDataAfter.availableLiquidity.toFixed()); - expectEqual(reserveDataAfter, expectedReserveData); expectEqual(userDataAfter, expectedUserData); diff --git a/test/helpers/utils/calculations.ts b/test/helpers/utils/calculations.ts index be0a8c3f..7ef73c48 100644 --- a/test/helpers/utils/calculations.ts +++ b/test/helpers/utils/calculations.ts @@ -956,8 +956,6 @@ export const calcExpectedReserveDataAfterStableRateRebalance = ( ): ReserveData => { const expectedReserveData: ReserveData = {}; - console.log("Rebalancing"); - expectedReserveData.address = reserveDataBeforeAction.address; const userStableDebt = calcExpectedStableDebtTokenBalance( diff --git a/test/repay-with-collateral.spec.ts b/test/repay-with-collateral.spec.ts index 455520f5..7fe7d714 100644 --- a/test/repay-with-collateral.spec.ts +++ b/test/repay-with-collateral.spec.ts @@ -558,14 +558,14 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => { new BigNumber(repayWithCollateralTimestamp) ).minus(daiUserDataBefore.currentVariableDebt); - expect(daiUserDataAfter.currentVariableDebt).to.be.bignumber.equal( + expect(daiUserDataAfter.currentVariableDebt).to.be.bignumber.almostEqual( new BigNumber(daiUserDataBefore.currentVariableDebt) .minus(expectedDebtCovered.toString()) .plus(expectedVariableDebtIncrease), 'INVALID_VARIABLE_DEBT_POSITION' ); - expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.equal(0); + expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.almostEqual(0); expect(wethUserDataAfter.usageAsCollateralEnabled).to.be.false; }); From 2ebe34a051331ca0abc8d99f90e5b8d1b27c8745 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 16:11:14 +0200 Subject: [PATCH 42/79] removed userIndex from variabledebttoken --- contracts/tokenization/AToken.sol | 1 - contracts/tokenization/VariableDebtToken.sol | 49 +++++++++++--------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index 00025c05..45f623a3 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -115,7 +115,6 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { //transfer event to track balances emit Transfer(user, address(0), amount); - emit Burn(msg.sender, receiverOfUnderlying, amount, index); } diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index feae82e0..a94f16aa 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -17,7 +17,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { using WadRayMath for uint256; uint256 public constant DEBT_TOKEN_REVISION = 0x1; - mapping(address => uint256) _userIndexes; constructor( address pool, @@ -41,14 +40,12 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { **/ function balanceOf(address user) public virtual override view returns (uint256) { uint256 scaledBalance = super.balanceOf(user); - + if (scaledBalance == 0) { return 0; } - return - scaledBalance - .rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); + return scaledBalance.rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); } /** @@ -57,10 +54,13 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @param amount the amount of debt being minted * @param index the variable debt index of the reserve **/ - function mint(address user, uint256 amount, uint256 index) external override onlyLendingPool { - + function mint( + address user, + uint256 amount, + uint256 index + ) external override onlyLendingPool { _mint(user, amount.rayDiv(index)); - + emit Transfer(address(0), user, amount); emit MintDebt(user, amount, index); } @@ -70,35 +70,38 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { * @param user the user which debt is burnt * @param index the variable debt index of the reserve **/ - function burn(address user, uint256 amount, uint256 index) external override onlyLendingPool { - _burn(user, amount.rayDiv(index)); - _userIndexes[user] = index; - + function burn( + address user, + uint256 amount, + uint256 index + ) external override onlyLendingPool { + _burn(user, amount.rayDiv(index)); + emit Transfer(user, address(0), amount); emit BurnDebt(user, amount, index); } /** - * @dev Returns the principal debt balance of the user from - * @return The debt balance of the user since the last burn/mint action - **/ + * @dev Returns the principal debt balance of the user from + * @return The debt balance of the user since the last burn/mint action + **/ function scaledBalanceOf(address user) public virtual override view returns (uint256) { return super.balanceOf(user); } /** - * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users - * @return the total supply - **/ - function totalSupply() public virtual override view returns(uint256) { + * @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users + * @return the total supply + **/ + function totalSupply() public virtual override view returns (uint256) { return super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET)); } /** - * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) - * @return the scaled total supply - **/ - function scaledTotalSupply() public virtual override view returns(uint256) { + * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) + * @return the scaled total supply + **/ + function scaledTotalSupply() public virtual override view returns (uint256) { return super.totalSupply(); } } From 9d1c13cf960f48af7dfce0a5b61fcafddda4db42 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 17:41:38 +0200 Subject: [PATCH 43/79] added events to mintToTreasury() --- contracts/tokenization/AToken.sol | 19 +++++-- contracts/tokenization/VariableDebtToken.sol | 15 +++++- contracts/tokenization/interfaces/IAToken.sol | 45 ++-------------- .../interfaces/IScaledBalanceToken.sol | 49 +++++++++++++++++ .../interfaces/IVariableDebtToken.sol | 53 +++++-------------- 5 files changed, 93 insertions(+), 88 deletions(-) create mode 100644 contracts/tokenization/interfaces/IScaledBalanceToken.sol diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index 45f623a3..fe270785 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -22,7 +22,6 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { using WadRayMath for uint256; using SafeERC20 for IERC20; - bytes public constant EIP712_REVISION = bytes('1'); bytes32 internal constant EIP712_DOMAIN = keccak256( 'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)' @@ -39,9 +38,9 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { /// @dev owner => next valid nonce to submit with permit() mapping(address => uint256) public _nonces; - + bytes32 public DOMAIN_SEPARATOR; - + modifier onlyLendingPool { require(msg.sender == address(POOL), Errors.CALLER_MUST_BE_LENDING_POOL); _; @@ -140,7 +139,11 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { } function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool { - _mint(RESERVE_TREASURY_ADDRESS, amount.div(index)); + _mint(RESERVE_TREASURY_ADDRESS, amount.div(index)); + + //transfer event to track balances + emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount); + emit Mint(RESERVE_TREASURY_ADDRESS, amount, index); } /** @@ -216,6 +219,14 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { return currentSupplyScaled.rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS)); } + /** + * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) + * @return the scaled total supply + **/ + function scaledTotalSupply() public virtual override view returns (uint256) { + return super.totalSupply(); + } + /** * @dev Used to validate transfers before actually executing them. * @param user address of the user to check diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index a94f16aa..600ef08d 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -62,7 +62,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { _mint(user, amount.rayDiv(index)); emit Transfer(address(0), user, amount); - emit MintDebt(user, amount, index); + emit Mint(user, amount, index); } /** @@ -78,7 +78,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { _burn(user, amount.rayDiv(index)); emit Transfer(user, address(0), amount); - emit BurnDebt(user, amount, index); + emit Burn(user, amount, index); } /** @@ -104,4 +104,15 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { function scaledTotalSupply() public virtual override view returns (uint256) { return super.totalSupply(); } + + /** + * @dev returns the principal balance of the user and principal total supply. + * @param user the address of the user + * @return the principal balance of the user + * @return the principal total supply + **/ + function getScaledUserBalanceAndSupply(address user) external override view returns (uint256, uint256){ + return (super.balanceOf(user), super.totalSupply()); + } + } diff --git a/contracts/tokenization/interfaces/IAToken.sol b/contracts/tokenization/interfaces/IAToken.sol index a9fbc49b..b5e182bc 100644 --- a/contracts/tokenization/interfaces/IAToken.sol +++ b/contracts/tokenization/interfaces/IAToken.sol @@ -2,8 +2,9 @@ pragma solidity ^0.6.8; import {IERC20} from '../../interfaces/IERC20.sol'; +import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; -interface IAToken is IERC20 { +interface IAToken is IERC20, IScaledBalanceToken { /** * @dev emitted after aTokens are burned * @param from the address performing the redeem @@ -16,15 +17,6 @@ interface IAToken is IERC20 { uint256 value, uint256 index ); - - /** - * @dev emitted after the mint action - * @param from the address performing the mint - * @param value the amount to be minted - * @param index the last index of the reserve - **/ - event Mint(address indexed from, uint256 value, uint256 index); - /** * @dev emitted during the transfer action * @param from the address from which the tokens are being transferred @@ -38,7 +30,6 @@ interface IAToken is IERC20 { uint256 value, uint256 index ); - /** * @dev burns the aTokens and sends the equivalent amount of underlying to the target. * only lending pools can call this function @@ -52,15 +43,6 @@ interface IAToken is IERC20 { uint256 index ) external; - /** - * @dev mints aTokens to user - * only lending pools can call this function - * @param user the address receiving the minted tokens - * @param amount the amount of tokens to mint - * @param index the liquidity index - */ - function mint(address user, uint256 amount, uint256 index) external; - /** * @dev mints aTokens to the reserve treasury * @param amount the amount to mint @@ -81,28 +63,7 @@ interface IAToken is IERC20 { uint256 value ) external; - /** - * @dev returns the principal balance of the user. The principal balance is the last - * updated stored balance, which does not consider the perpetually accruing interest. - * @param user the address of the user - * @return the principal balance of the user - **/ - function scaledBalanceOf(address user) external view returns (uint256); - - /** - * @dev returns the principal balance of the user and principal total supply. - * @param user the address of the user - * @return the principal balance of the user - * @return the principal total supply - **/ - function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); - - /** - * @dev Used to validate transfers before actually executing them. - * @param user address of the user to check - * @param amount the amount to check - * @return true if the user can transfer amount, false otherwise - **/ + function isTransferAllowed(address user, uint256 amount) external view returns (bool); /** diff --git a/contracts/tokenization/interfaces/IScaledBalanceToken.sol b/contracts/tokenization/interfaces/IScaledBalanceToken.sol new file mode 100644 index 00000000..9bcd2427 --- /dev/null +++ b/contracts/tokenization/interfaces/IScaledBalanceToken.sol @@ -0,0 +1,49 @@ + +// SPDX-License-Identifier: agpl-3.0 +pragma solidity ^0.6.8; + +interface IScaledBalanceToken { + + /** + * @dev emitted after the mint action + * @param from the address performing the mint + * @param value the amount to be minted + * @param index the last index of the reserve + **/ + event Mint(address indexed from, uint256 value, uint256 index); + + /** + * @dev mints aTokens to user + * only lending pools can call this function + * @param user the address receiving the minted tokens + * @param amount the amount of tokens to mint + * @param index the liquidity index + */ + function mint( + address user, + uint256 amount, + uint256 index + ) external; + + /** + * @dev returns the principal balance of the user. The principal balance is the last + * updated stored balance, which does not consider the perpetually accruing interest. + * @param user the address of the user + * @return the principal balance of the user + **/ + function scaledBalanceOf(address user) external view returns (uint256); + + /** + * @dev returns the principal balance of the user and principal total supply. + * @param user the address of the user + * @return the principal balance of the user + * @return the principal total supply + **/ + function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256); + + /** + * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) + * @return the scaled total supply + **/ + function scaledTotalSupply() external view returns (uint256); +} diff --git a/contracts/tokenization/interfaces/IVariableDebtToken.sol b/contracts/tokenization/interfaces/IVariableDebtToken.sol index 0b680f51..2e6bae93 100644 --- a/contracts/tokenization/interfaces/IVariableDebtToken.sol +++ b/contracts/tokenization/interfaces/IVariableDebtToken.sol @@ -1,63 +1,36 @@ // SPDX-License-Identifier: agpl-3.0 pragma solidity ^0.6.8; +import {IScaledBalanceToken} from './IScaledBalanceToken.sol'; + /** * @title interface IVariableDebtToken * @author Aave * @notice defines the basic interface for a variable debt token. - * @dev does not inherit from IERC20 to save in contract size **/ -interface IVariableDebtToken { - /** - * @dev emitted when new variable debt is minted - * @param user the user receiving the debt - * @param amount the amount of debt being minted - * @param index the index of the user - **/ - event MintDebt( - address user, - uint256 amount, - uint256 index - ); - +interface IVariableDebtToken is IScaledBalanceToken { + /** * @dev emitted when variable debt is burnt * @param user the user which debt has been burned * @param amount the amount of debt being burned * @param index the index of the user **/ - event BurnDebt( - address user, + event Burn( + address indexed user, uint256 amount, uint256 index ); - /** - * @dev mints new variable debt - * @param user the user receiving the debt - * @param amount the amount of debt being minted - * @param index the variable debt index of the reserve - **/ - function mint(address user, uint256 amount, uint256 index) external; - - /** + /** * @dev burns user variable debt * @param user the user which debt is burnt - * @param amount the amount of debt being burned * @param index the variable debt index of the reserve **/ - function burn(address user, uint256 amount, uint256 index) external; - - /** - * @dev returns the scaled balance of the variable debt token - * @param user the user - **/ - function scaledBalanceOf(address user) external view returns(uint256); - - /** - * @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index) - * @return the scaled total supply - **/ - function scaledTotalSupply() external view returns(uint256); - + function burn( + address user, + uint256 amount, + uint256 index + ) external; + } From e348c334e3d05cc3cd1e614f1f3903a88f3bc8d2 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 17:58:02 +0200 Subject: [PATCH 44/79] Cleaned up aToken, debt tokens code --- contracts/tokenization/AToken.sol | 32 +++++++++++--------- contracts/tokenization/VariableDebtToken.sol | 1 + deployed-contracts.json | 17 ++++++----- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/contracts/tokenization/AToken.sol b/contracts/tokenization/AToken.sol index fe270785..98c54bcd 100644 --- a/contracts/tokenization/AToken.sol +++ b/contracts/tokenization/AToken.sol @@ -101,13 +101,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { uint256 amount, uint256 index ) external override onlyLendingPool { - uint256 currentBalance = balanceOf(user); - - require(amount <= currentBalance, Errors.INVALID_ATOKEN_BALANCE); - - uint256 scaledAmount = amount.rayDiv(index); - - _burn(user, scaledAmount); + _burn(user, amount.rayDiv(index)); //transfers the underlying to the target IERC20(UNDERLYING_ASSET_ADDRESS).safeTransfer(receiverOfUnderlying, amount); @@ -128,10 +122,8 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { uint256 amount, uint256 index ) external override onlyLendingPool { - uint256 scaledAmount = amount.rayDiv(index); - //mint an equivalent amount of tokens to cover the new deposit - _mint(user, scaledAmount); + _mint(user, amount.rayDiv(index)); //transfer event to track balances emit Transfer(address(0), user, amount); @@ -140,7 +132,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool { _mint(RESERVE_TREASURY_ADDRESS, amount.div(index)); - + //transfer event to track balances emit Transfer(address(0), RESERVE_TREASURY_ADDRESS, amount); emit Mint(RESERVE_TREASURY_ADDRESS, amount, index); @@ -289,6 +281,14 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { _approve(owner, spender, value); } + /** + * @dev transfers the aTokens between two users. Validates the transfer + * (ie checks for valid HF after the transfer) if required + * @param from the source address + * @param to the destination address + * @param amount the amount to transfer + * @param validate true if the transfer needs to be validated + **/ function _transfer( address from, address to, @@ -301,13 +301,17 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken { uint256 index = POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS); - uint256 scaledAmount = amount.rayDiv(index); - - super._transfer(from, to, scaledAmount); + super._transfer(from, to, amount.rayDiv(index)); emit BalanceTransfer(from, to, amount, index); } + /** + * @dev overrides the parent _transfer to force validated transfer() and transferFrom() + * @param from the source address + * @param to the destination address + * @param amount the amount to transfer + **/ function _transfer( address from, address to, diff --git a/contracts/tokenization/VariableDebtToken.sol b/contracts/tokenization/VariableDebtToken.sol index 600ef08d..5e0f2dff 100644 --- a/contracts/tokenization/VariableDebtToken.sol +++ b/contracts/tokenization/VariableDebtToken.sol @@ -59,6 +59,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken { uint256 amount, uint256 index ) external override onlyLendingPool { + _mint(user, amount.rayDiv(index)); emit Transfer(address(0), user, amount); diff --git a/deployed-contracts.json b/deployed-contracts.json index daecd72c..dd305039 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -65,7 +65,7 @@ "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" }, "localhost": { - "address": "0x65e0Cd5B8904A02f2e00BC6f58bf881998D54BDe" + "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" }, "coverage": { "address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8" @@ -81,7 +81,7 @@ "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" }, "localhost": { - "address": "0x5d12dDe3286D94E0d85F9D3B01B7099cfA0aBCf1" + "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" }, "coverage": { "address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e" @@ -207,7 +207,7 @@ "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" }, "localhost": { - "address": "0xAd49512dFBaD6fc13D67d3935283c0606812E962" + "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" }, "coverage": { "address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA" @@ -554,7 +554,7 @@ "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" }, "localhost": { - "address": "0x9305d862ee95a899b83906Cd9CB666aC269E5f66" + "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" }, "coverage": { "address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4" @@ -608,7 +608,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xFBdF1E93D0D88145e3CcA63bf8d513F83FB0903b", + "address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -636,7 +636,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xE45fF4A0A8D0E9734C73874c034E03594E15ba28", + "address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -650,7 +650,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x5cCC6Abc4c9F7262B9485797a848Ec6CC28A11dF", + "address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -664,6 +664,9 @@ }, "coverage": { "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" + }, + "localhost": { + "address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2" } } } \ No newline at end of file From c278832e5a32dd0208464fe1680ee1ba659215fd Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 17:59:44 +0200 Subject: [PATCH 45/79] Removed unused error code --- contracts/libraries/helpers/Errors.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/libraries/helpers/Errors.sol b/contracts/libraries/helpers/Errors.sol index d25b041b..4f3f6daa 100644 --- a/contracts/libraries/helpers/Errors.sol +++ b/contracts/libraries/helpers/Errors.sol @@ -48,7 +48,6 @@ library Errors { string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool' string public constant CANNOT_GIVE_ALLOWANCE_TO_HIMSELF = '30'; // 'User cannot give allowance to himself' string public constant TRANSFER_AMOUNT_NOT_GT_0 = '31'; // 'Transferred amount needs to be greater than zero' - string public constant INVALID_ATOKEN_BALANCE = '52'; // balance on burning is invalid // require error messages - ReserveLogic string public constant RESERVE_ALREADY_INITIALIZED = '34'; // 'Reserve has already been initialized' From c346251df03b192897215c6185870e0aa982a134 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 18:51:51 +0200 Subject: [PATCH 46/79] Added comments --- contracts/libraries/logic/ReserveLogic.sol | 52 ++++++++++++------- contracts/tokenization/StableDebtToken.sol | 6 +-- .../interfaces/IStableDebtToken.sol | 2 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/contracts/libraries/logic/ReserveLogic.sol b/contracts/libraries/logic/ReserveLogic.sol index e5eac57a..8f6069ab 100644 --- a/contracts/libraries/logic/ReserveLogic.sol +++ b/contracts/libraries/logic/ReserveLogic.sol @@ -148,28 +148,23 @@ library ReserveLogic { * @param reserve the reserve object **/ function updateState(ReserveData storage reserve) external { - address stableDebtToken = reserve.stableDebtTokenAddress; address variableDebtToken = reserve.variableDebtTokenAddress; uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex; uint256 previousLiquidityIndex = reserve.liquidityIndex; - uint40 timestamp = reserve.lastUpdateTimestamp; (uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes( reserve, variableDebtToken, previousLiquidityIndex, - previousVariableBorrowIndex, - timestamp + previousVariableBorrowIndex ); _mintToTreasury( reserve, - stableDebtToken, variableDebtToken, previousVariableBorrowIndex, newLiquidityIndex, - newVariableBorrowIndex, - timestamp + newVariableBorrowIndex ); } @@ -299,16 +294,24 @@ library ReserveLogic { uint256 totalDebtAccrued; uint256 amountToMint; uint256 reserveFactor; + uint40 stableSupplyUpdatedTimestamp; } + /** + * @dev mints part of the repaid interest to the reserve treasury, depending on the reserveFactor for the + * specific asset. + * @param reserve the reserve reserve to be updated + * @param variableDebtToken the debt token address + * @param previousVariableBorrowIndex the variable borrow index before the last accumulation of the interest + * @param newLiquidityIndex the new liquidity index + * @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest + **/ function _mintToTreasury( ReserveData storage reserve, - address stableDebtToken, address variableDebtToken, uint256 previousVariableBorrowIndex, uint256 newLiquidityIndex, - uint256 newVariableBorrowIndex, - uint40 previousTimestamp + uint256 newVariableBorrowIndex ) internal { MintToTreasuryLocalVars memory vars; @@ -322,10 +325,12 @@ library ReserveLogic { vars.scaledVariableDebt = IVariableDebtToken(variableDebtToken).scaledTotalSupply(); //fetching the principal, total stable debt and the avg stable rate - (vars.principalStableDebt, vars.currentStableDebt, vars.avgStableRate) = IStableDebtToken( - stableDebtToken - ) - .getSupplyData(); + ( + vars.principalStableDebt, + vars.currentStableDebt, + vars.avgStableRate, + vars.stableSupplyUpdatedTimestamp + ) = IStableDebtToken(reserve.stableDebtTokenAddress).getSupplyData(); //calculate the last principal variable debt vars.previousVariableDebt = vars.scaledVariableDebt.rayMul(previousVariableBorrowIndex); @@ -336,7 +341,7 @@ library ReserveLogic { //calculate the stable debt until the last timestamp update vars.cumulatedStableInterest = MathUtils.calculateCompoundedInterest( vars.avgStableRate, - previousTimestamp + vars.stableSupplyUpdatedTimestamp ); vars.previousStableDebt = vars.principalStableDebt.rayMul(vars.cumulatedStableInterest); @@ -353,13 +358,22 @@ library ReserveLogic { IAToken(reserve.aTokenAddress).mintToTreasury(vars.amountToMint, newLiquidityIndex); } + /** + * @dev updates the reserve indexes and the timestamp of the update + * @param reserve the reserve reserve to be updated + * @param variableDebtToken the debt token address + * @param liquidityIndex the last stored liquidity index + * @param variableBorrowIndex the last stored variable borrow index + **/ function _updateIndexes( ReserveData storage reserve, address variableDebtToken, uint256 liquidityIndex, - uint256 variableBorrowIndex, - uint40 lastUpdateTimestamp + uint256 variableBorrowIndex ) internal returns (uint256, uint256) { + + uint40 timestamp = reserve.lastUpdateTimestamp; + uint256 currentLiquidityRate = reserve.currentLiquidityRate; uint256 newLiquidityIndex = liquidityIndex; @@ -369,7 +383,7 @@ library ReserveLogic { if (currentLiquidityRate > 0) { uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest( currentLiquidityRate, - lastUpdateTimestamp + timestamp ); newLiquidityIndex = cumulatedLiquidityInterest.rayMul(liquidityIndex); require(newLiquidityIndex < (1 << 128), Errors.LIQUIDITY_INDEX_OVERFLOW); @@ -381,7 +395,7 @@ library ReserveLogic { if (IERC20(variableDebtToken).totalSupply() > 0) { uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( reserve.currentVariableBorrowRate, - lastUpdateTimestamp + timestamp ); newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex); require(newVariableBorrowIndex < (1 << 128), Errors.VARIABLE_BORROW_INDEX_OVERFLOW); diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index fe352b32..1974d51e 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -237,11 +237,11 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase { } /** - * @dev returns the principal, total supply and the average borrow rate + * @dev returns the principal and total supply, the average borrow rate and the last supply update timestamp **/ - function getSupplyData() public override view returns (uint256, uint256, uint256) { + function getSupplyData() public override view returns (uint256, uint256, uint256,uint40) { uint256 avgRate = _avgStableRate; - return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate); + return (super.totalSupply(), _calcTotalSupply(avgRate), avgRate, _totalSupplyTimestamp); } /** diff --git a/contracts/tokenization/interfaces/IStableDebtToken.sol b/contracts/tokenization/interfaces/IStableDebtToken.sol index 0e75bae4..901a1178 100644 --- a/contracts/tokenization/interfaces/IStableDebtToken.sol +++ b/contracts/tokenization/interfaces/IStableDebtToken.sol @@ -88,7 +88,7 @@ interface IStableDebtToken { /** * @dev returns the principal, the total supply and the average stable rate **/ - function getSupplyData() external view returns (uint256, uint256, uint256); + function getSupplyData() external view returns (uint256, uint256, uint256, uint40); /** * @dev returns the timestamp of the last update of the total supply From 07db321b4dc7abedc3150f71acbe32db8e306a84 Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 19:52:22 +0200 Subject: [PATCH 47/79] updated rebalance conditions,tests --- .../IReserveInterestRateStrategy.sol | 6 ++- .../DefaultReserveInterestRateStrategy.sol | 4 ++ contracts/lendingpool/LendingPool.sol | 51 ++++++++++++------- .../scenarios/rebalance-stable-rate.json | 43 +++------------- 4 files changed, 51 insertions(+), 53 deletions(-) diff --git a/contracts/interfaces/IReserveInterestRateStrategy.sol b/contracts/interfaces/IReserveInterestRateStrategy.sol index 48311e70..a69160b3 100644 --- a/contracts/interfaces/IReserveInterestRateStrategy.sol +++ b/contracts/interfaces/IReserveInterestRateStrategy.sol @@ -10,9 +10,13 @@ interface IReserveInterestRateStrategy { /** * @dev returns the base variable borrow rate, in rays */ - function baseVariableBorrowRate() external view returns (uint256); + /** + * @dev returns the maximum variable borrow rate + */ + function getMaxVariableBorrowRate() external view returns (uint256); + /** * @dev calculates the liquidity, stable, and variable rates depending on the current utilization rate * and the base parameters diff --git a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol index c2303254..64b90a44 100644 --- a/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol +++ b/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol @@ -89,6 +89,10 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy { return _baseVariableBorrowRate; } + function getMaxVariableBorrowRate() external override view returns (uint256) { + return _baseVariableBorrowRate.add(_variableRateSlope1).add(_variableRateSlope2); + } + /** * @dev calculates the interest rates depending on the available liquidity and the total borrowed. * @param reserve the address of the reserve diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 86c47374..bd651647 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -12,6 +12,7 @@ import {IAToken} from '../tokenization/interfaces/IAToken.sol'; import {Helpers} from '../libraries/helpers/Helpers.sol'; import {Errors} from '../libraries/helpers/Errors.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; +import {PercentageMath} from '../libraries/math/PercentageMath.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {GenericLogic} from '../libraries/logic/GenericLogic.sol'; import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol'; @@ -26,6 +27,7 @@ import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol'; +import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; /** * @title LendingPool contract @@ -36,10 +38,12 @@ import {LendingPoolStorage} from './LendingPoolStorage.sol'; contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage { using SafeMath for uint256; using WadRayMath for uint256; + using PercentageMath for uint256; using SafeERC20 for IERC20; //main configuration parameters - uint256 public constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5; + uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000; + uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95% uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; @@ -354,26 +358,39 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; - IStableDebtToken stableDebtToken = IStableDebtToken(reserve.stableDebtTokenAddress); + IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress); + IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress); - uint256 stableBorrowBalance = IERC20(address(stableDebtToken)).balanceOf(user); + uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user); // user must be borrowing on asset at a stable rate require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE); - uint256 rebalanceDownRateThreshold = WadRayMath.ray().add(REBALANCE_DOWN_RATE_DELTA).rayMul( - reserve.currentStableBorrowRate - ); - - //1. user stable borrow rate is below the current liquidity rate. The loan needs to be rebalanced, - //as this situation can be abused (user putting back the borrowed liquidity in the same reserve to earn on it) - //2. user stable rate is above the market avg borrow rate of a certain delta, and utilization rate is low. - //In this case, the user is paying an interest that is too high, and needs to be rescaled down. - - uint256 userStableRate = stableDebtToken.getUserStableRate(user); + //if the utilization rate is below 95%, no rebalances are needed + uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()); + uint256 availableLiquidity = IERC20(reserve.aTokenAddress).totalSupply(); + uint256 utilizationRate = totalBorrows == 0 + ? 0 + : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows)); require( - userStableRate < reserve.currentLiquidityRate || userStableRate > rebalanceDownRateThreshold, + utilizationRate >= REBALANCE_UP_USAGE_RATIO_THRESHOLD, + Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET + ); + + //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. + + uint256 currentLiquidityRate = reserve.currentLiquidityRate; + uint256 maxVariableBorrowRate = IReserveInterestRateStrategy( + reserve + .interestRateStrategyAddress + ) + .getMaxVariableBorrowRate(); + + require( + currentLiquidityRate <= + maxVariableBorrowRate.percentMul(REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD), Errors.INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET ); @@ -381,8 +398,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage reserve.updateCumulativeIndexesAndTimestamp(); - stableDebtToken.burn(user, stableBorrowBalance); - stableDebtToken.mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); + IStableDebtToken(address(stableDebtToken)).burn(user, stableBorrowBalance); + IStableDebtToken(address(stableDebtToken)).mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0); @@ -507,7 +524,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _flashLiquidationLocked = false; } - struct FlashLoanLocalVars { + struct FlashLoanLocalVars { uint256 premium; uint256 amountPlusPremium; IFlashLoanReceiver receiver; diff --git a/test/helpers/scenarios/rebalance-stable-rate.json b/test/helpers/scenarios/rebalance-stable-rate.json index 1200ff3e..891de2b7 100644 --- a/test/helpers/scenarios/rebalance-stable-rate.json +++ b/test/helpers/scenarios/rebalance-stable-rate.json @@ -19,7 +19,7 @@ ] }, { - "description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH, borrows 100 DAI at a variable rate, user 0 rebalances user 1 (revert expected)", + "description": "User 0 deposits 1000 DAI, user 1 deposits 5 ETH, borrows 600 DAI at a variable rate, user 0 rebalances user 1 (revert expected)", "actions": [ { "name": "mint", @@ -51,7 +51,7 @@ "name": "mint", "args": { "reserve": "WETH", - "amount": "1", + "amount": "5", "user": "1" }, "expected": "success" @@ -69,7 +69,7 @@ "args": { "reserve": "WETH", - "amount": "1", + "amount": "5", "user": "1" }, "expected": "success" @@ -78,7 +78,7 @@ "name": "borrow", "args": { "reserve": "DAI", - "amount": "100", + "amount": "600", "borrowRateMode": "variable", "user": "1", "timeTravel": "365" @@ -122,7 +122,7 @@ ] }, { - "description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)", + "description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (usage ratio = 94%). User 0 tries to rebalance user 1 (revert expected)", "actions": [ { "name": "mint", @@ -155,7 +155,7 @@ "name": "borrow", "args": { "reserve": "DAI", - "amount": "100", + "amount": "340", "borrowRateMode": "variable", "user": "2" }, @@ -174,40 +174,13 @@ ] }, { - "description": "User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1", + "description": "User 2 borrows the remaining DAI (usage ratio = 100%). User 0 rebalances user 1", "actions": [ - { - "name": "mint", - "args": { - "reserve": "WETH", - "amount": "3", - "user": "2" - }, - "expected": "success" - }, - { - "name": "approve", - "args": { - "reserve": "WETH", - "user": "2" - }, - "expected": "success" - }, - { - "name": "deposit", - "args": { - "reserve": "WETH", - - "amount": "3", - "user": "2" - }, - "expected": "success" - }, { "name": "borrow", "args": { "reserve": "DAI", - "amount": "700", + "amount": "60", "borrowRateMode": "variable", "user": "2" }, From 2e30bb8b858bd33c00df00b74ca797947747cccb Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 21:15:12 +0200 Subject: [PATCH 48/79] Fixed error on rebalance conditions, changed style of internal functions --- contracts/lendingpool/LendingPool.sol | 47 +++++++++---------- .../configuration/ReserveConfiguration.sol | 2 +- contracts/libraries/logic/ValidationLogic.sol | 4 +- test/helpers/actions.ts | 5 ++ test/scenario.spec.ts | 2 +- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 68b6182d..4d5ef9e8 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -35,7 +35,6 @@ import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateSt * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data * @author Aave **/ - contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage { using SafeMath for uint256; using WadRayMath for uint256; @@ -45,7 +44,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage //main configuration parameters uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000; uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95% - uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25; + uint256 public constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 2500; uint256 public constant FLASHLOAN_PREMIUM_TOTAL = 9; uint256 public constant MAX_NUMBER_RESERVES = 128; uint256 public constant LENDINGPOOL_REVISION = 0x2; @@ -53,13 +52,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage /** * @dev only lending pools configurator can use functions affected by this modifier **/ - function onlyLendingPoolConfigurator() internal view { + function _onlyLendingPoolConfigurator() internal view { require( _addressesProvider.getLendingPoolConfigurator() == msg.sender, Errors.CALLER_NOT_LENDING_POOL_CONFIGURATOR ); } - /** * @dev Function to make a function callable only when the contract is not paused. * @@ -67,7 +65,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * * - The contract must not be paused. */ - function whenNotPaused() internal view { + function _whenNotPaused() internal view { require(!_paused, Errors.IS_PAUSED); } @@ -97,7 +95,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address onBehalfOf, uint16 referralCode ) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; ValidationLogic.validateDeposit(reserve, amount); @@ -126,7 +124,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param amount the underlying amount to be redeemed **/ function withdraw(address asset, uint256 amount) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; address aToken = reserve.aTokenAddress; @@ -142,7 +140,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ValidationLogic.validateWithdraw( asset, - aToken, amountToWithdraw, userBalance, _reserves, @@ -187,7 +184,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 interestRateMode, uint256 amount ) external override { - whenNotPaused(); + _whenNotPaused(); address debtToken = _reserves[asset].getDebtTokenAddress(interestRateMode); _borrowAllowance[debtToken][msg.sender][user] = amount; @@ -210,7 +207,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint16 referralCode, address onBehalfOf ) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; if (onBehalfOf != msg.sender) { @@ -250,7 +247,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 rateMode, address onBehalfOf ) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; @@ -307,7 +304,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param rateMode the rate mode that the user wants to swap **/ function swapBorrowRateMode(address asset, uint256 rateMode) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve); @@ -360,7 +357,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage **/ function rebalanceStableBorrowRate(address asset, address user) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; @@ -373,8 +370,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE); //if the utilization rate is below 95%, no rebalances are needed - uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()); - uint256 availableLiquidity = IERC20(reserve.aTokenAddress).totalSupply(); + uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay(); + uint256 availableLiquidity = IERC20(asset).balanceOf(reserve.aTokenAddress).wadToRay(); uint256 usageRatio = totalBorrows == 0 ? 0 : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows)); @@ -414,7 +411,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise. **/ function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; ValidationLogic.validateSetUseReserveAsCollateral( @@ -451,7 +448,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 purchaseAmount, bool receiveAToken ) external override { - whenNotPaused(); + _whenNotPaused(); address collateralManager = _addressesProvider.getLendingPoolCollateralManager(); //solium-disable-next-line @@ -495,7 +492,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address receiver, bytes calldata params ) external override { - whenNotPaused(); + _whenNotPaused(); require(!_flashLiquidationLocked, Errors.REENTRANCY_NOT_ALLOWED); _flashLiquidationLocked = true; @@ -551,7 +548,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage bytes calldata params, uint16 referralCode ) external override { - whenNotPaused(); + _whenNotPaused(); ReserveLogic.ReserveData storage reserve = _reserves[asset]; FlashLoanLocalVars memory vars; @@ -613,7 +610,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage uint256 amountToSwap, bytes calldata params ) external override { - whenNotPaused(); + _whenNotPaused(); address collateralManager = _addressesProvider.getLendingPoolCollateralManager(); //solium-disable-next-line @@ -805,7 +802,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address variableDebtAddress, address interestRateStrategyAddress ) external override { - onlyLendingPoolConfigurator(); + _onlyLendingPoolConfigurator(); _reserves[asset].init( aTokenAddress, stableDebtAddress, @@ -825,12 +822,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage external override { - onlyLendingPoolConfigurator(); + _onlyLendingPoolConfigurator(); _reserves[asset].interestRateStrategyAddress = rateStrategyAddress; } function setConfiguration(address asset, uint256 configuration) external override { - onlyLendingPoolConfigurator(); + _onlyLendingPoolConfigurator(); _reserves[asset].configuration.data = configuration; } @@ -986,7 +983,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address user, uint256 amount ) external override view returns (bool) { - whenNotPaused(); + _whenNotPaused(); return GenericLogic.balanceDecreaseAllowed( asset, @@ -1004,7 +1001,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param val the boolean value to set the current pause state of LendingPool */ function setPause(bool val) external override { - onlyLendingPoolConfigurator(); + _onlyLendingPoolConfigurator(); _paused = val; if (_paused) { diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index ed4df31e..fb3d7972 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -143,7 +143,7 @@ library ReserveConfiguration { * @param self the reserve configuration * @param active the active state **/ - function setActive(ReserveConfiguration.Map memory self, bool active) internal { + function setActive(ReserveConfiguration.Map memory self, bool active) internal pure { self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << 56); } diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol index 5d201efd..4ffa49f2 100644 --- a/contracts/libraries/logic/ValidationLogic.sol +++ b/contracts/libraries/logic/ValidationLogic.sol @@ -34,7 +34,7 @@ library ValidationLogic { * @param reserve the reserve state on which the user is depositing * @param amount the amount to be deposited */ - function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) internal view { + function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view { (bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags(); require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0); @@ -45,13 +45,11 @@ library ValidationLogic { /** * @dev validates a withdraw action. * @param reserveAddress the address of the reserve - * @param aTokenAddress the address of the aToken for the reserve * @param amount the amount to be withdrawn * @param userBalance the balance of the user */ function validateWithdraw( address reserveAddress, - address aTokenAddress, uint256 amount, uint256 userBalance, mapping(address => ReserveLogic.ReserveData) storage reservesData, diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index 69c9c6ce..d5bdfee8 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -636,6 +636,11 @@ export const rebalanceStableBorrowRate = async ( testEnv ); + console.log("avl liquidity ", reserveDataBefore.availableLiquidity.toFixed()); + console.log("Total borrows stable ", reserveDataBefore.totalStableDebt.toFixed()); + console.log("Total borrows variable ", reserveDataBefore.totalVariableDebt.toFixed()); + console.log("Usage ratio ", reserveDataBefore.utilizationRate.toFixed()); + if (expectedResult === 'success') { const txResult = await waitForTx( await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address) diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 54fe7433..0a77c9e8 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = []; +const selectedScenarios: string[] = ['rebalance-stable-rate.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 12f1dbd0dcebdaf9e6f9a140c4e1ec3fec7ccd8d Mon Sep 17 00:00:00 2001 From: The3D Date: Mon, 21 Sep 2020 22:08:44 +0200 Subject: [PATCH 49/79] Readded calculateAvailableBorrowsETH --- contracts/interfaces/ILendingPool.sol | 1 + contracts/lendingpool/LendingPool.sol | 25 +++++-- .../configuration/ReserveConfiguration.sol | 1 - contracts/libraries/logic/GenericLogic.sol | 24 +++++++ contracts/tokenization/StableDebtToken.sol | 1 - test/helpers/actions.ts | 5 -- .../scenarios/rebalance-stable-rate.json | 66 +++++++++++++++++-- test/scenario.spec.ts | 2 +- 8 files changed, 104 insertions(+), 21 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index c98291c5..66d4542a 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -367,6 +367,7 @@ interface ILendingPool { returns ( uint256 totalCollateralETH, uint256 totalBorrowsETH, + uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 4d5ef9e8..95af83b1 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -29,7 +29,6 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol'; import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol'; - /** * @title LendingPool contract * @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data @@ -161,6 +160,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage emit Withdraw(asset, msg.sender, amount); } + /** + * @dev returns the borrow allowance of the user + * @param asset The underlying asset of the debt token + * @param fromUser The user to giving allowance + * @param toUser The user to give allowance to + * @param interestRateMode Type of debt: 1 for stable, 2 for variable + * @return the current allowance of toUser + **/ function getBorrowAllowance( address fromUser, address toUser, @@ -363,15 +370,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress); IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress); + address aTokenAddress = reserve.aTokenAddress; uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user); - // user must be borrowing on asset at a stable rate - require(stableBorrowBalance > 0, Errors.NOT_ENOUGH_STABLE_BORROW_BALANCE); - //if the utilization rate is below 95%, no rebalances are needed uint256 totalBorrows = stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay(); - uint256 availableLiquidity = IERC20(asset).balanceOf(reserve.aTokenAddress).wadToRay(); + uint256 availableLiquidity = IERC20(asset).balanceOf(aTokenAddress).wadToRay(); uint256 usageRatio = totalBorrows == 0 ? 0 : totalBorrows.rayDiv(availableLiquidity.add(totalBorrows)); @@ -398,11 +403,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage IStableDebtToken(address(stableDebtToken)).burn(user, stableBorrowBalance); IStableDebtToken(address(stableDebtToken)).mint(user, stableBorrowBalance, reserve.currentStableBorrowRate); - reserve.updateInterestRates(asset, reserve.aTokenAddress, 0, 0); + reserve.updateInterestRates(asset, aTokenAddress, 0, 0); emit RebalanceStableBorrowRate(asset, user); - return; } /** @@ -731,6 +735,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage returns ( uint256 totalCollateralETH, uint256 totalBorrowsETH, + uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor @@ -749,6 +754,12 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reservesList, _addressesProvider.getPriceOracle() ); + + availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH( + totalCollateralETH, + totalBorrowsETH, + ltv + ); } function getUserReserveData(address asset, address user) diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index fb3d7972..66fa21f4 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -6,7 +6,6 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {ReserveLogic} from '../logic/ReserveLogic.sol'; import {WadRayMath} from '../math/WadRayMath.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; -import "@nomiclabs/buidler/console.sol"; /** * @title ReserveConfiguration library diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index 82993d28..4b64e85f 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -253,4 +253,28 @@ library GenericLogic { return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH); } + + /** + * @dev calculates the equivalent amount in ETH that an user can borrow, depending on the available collateral and the + * average Loan To Value. + * @param collateralBalanceETH the total collateral balance + * @param borrowBalanceETH the total borrow balance + * @param ltv the average loan to value + * @return the amount available to borrow in ETH for the user + **/ + + function calculateAvailableBorrowsETH( + uint256 collateralBalanceETH, + uint256 borrowBalanceETH, + uint256 ltv + ) internal pure returns (uint256) { + uint256 availableBorrowsETH = collateralBalanceETH.percentMul(ltv); //ltv is in percentage + + if (availableBorrowsETH < borrowBalanceETH) { + return 0; + } + + availableBorrowsETH = availableBorrowsETH.sub(borrowBalanceETH); + return availableBorrowsETH; + } } diff --git a/contracts/tokenization/StableDebtToken.sol b/contracts/tokenization/StableDebtToken.sol index 1974d51e..160d0f88 100644 --- a/contracts/tokenization/StableDebtToken.sol +++ b/contracts/tokenization/StableDebtToken.sol @@ -8,7 +8,6 @@ import {DebtTokenBase} from './base/DebtTokenBase.sol'; import {MathUtils} from '../libraries/math/MathUtils.sol'; import {WadRayMath} from '../libraries/math/WadRayMath.sol'; import {IStableDebtToken} from './interfaces/IStableDebtToken.sol'; -import "@nomiclabs/buidler/console.sol"; /** * @title contract StableDebtToken diff --git a/test/helpers/actions.ts b/test/helpers/actions.ts index d5bdfee8..69c9c6ce 100644 --- a/test/helpers/actions.ts +++ b/test/helpers/actions.ts @@ -636,11 +636,6 @@ export const rebalanceStableBorrowRate = async ( testEnv ); - console.log("avl liquidity ", reserveDataBefore.availableLiquidity.toFixed()); - console.log("Total borrows stable ", reserveDataBefore.totalStableDebt.toFixed()); - console.log("Total borrows variable ", reserveDataBefore.totalVariableDebt.toFixed()); - console.log("Usage ratio ", reserveDataBefore.utilizationRate.toFixed()); - if (expectedResult === 'success') { const txResult = await waitForTx( await pool.connect(user.signer).rebalanceStableBorrowRate(reserve, target.address) diff --git a/test/helpers/scenarios/rebalance-stable-rate.json b/test/helpers/scenarios/rebalance-stable-rate.json index 891de2b7..70ea820a 100644 --- a/test/helpers/scenarios/rebalance-stable-rate.json +++ b/test/helpers/scenarios/rebalance-stable-rate.json @@ -78,8 +78,8 @@ "name": "borrow", "args": { "reserve": "DAI", - "amount": "600", - "borrowRateMode": "variable", + "amount": "250", + "borrowRateMode": "stable", "user": "1", "timeTravel": "365" }, @@ -98,14 +98,68 @@ ] }, { - "description": "User 1 swaps to stable, user 0 tries to rebalance but the conditions are not met (revert expected)", + "description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)", "actions": [ { - "name": "swapBorrowRateMode", + "name": "borrow", "args": { "reserve": "DAI", + "amount": "200", + "borrowRateMode": "stable", "user": "1", - "borrowRateMode": "variable" + "timeTravel": "365" + }, + "expected": "success" + }, + { + "name": "rebalanceStableBorrowRate", + "args": { + "reserve": "DAI", + "user": "0", + "target": "1" + }, + "expected": "revert", + "revertMessage": "Interest rate rebalance conditions were not met" + } + ] + }, + { + "description": "User 1 borrows another 200 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)", + "actions": [ + { + "name": "borrow", + "args": { + "reserve": "DAI", + "amount": "200", + "borrowRateMode": "stable", + "user": "1", + "timeTravel": "365" + }, + "expected": "success" + }, + { + "name": "rebalanceStableBorrowRate", + "args": { + "reserve": "DAI", + "user": "0", + "target": "1" + }, + "expected": "revert", + "revertMessage": "Interest rate rebalance conditions were not met" + } + ] + }, + { + "description": "User 1 borrows another 100 at stable, user 0 tries to rebalance but the conditions are not met (revert expected)", + "actions": [ + { + "name": "borrow", + "args": { + "reserve": "DAI", + "amount": "100", + "borrowRateMode": "stable", + "user": "1", + "timeTravel": "365" }, "expected": "success" }, @@ -155,7 +209,7 @@ "name": "borrow", "args": { "reserve": "DAI", - "amount": "340", + "amount": "190", "borrowRateMode": "variable", "user": "2" }, diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 0a77c9e8..54fe7433 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['rebalance-stable-rate.json']; +const selectedScenarios: string[] = []; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 06d16c6abf7ff2cf57548ac3ab3095cfeaf52e6f Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 11:21:49 +0200 Subject: [PATCH 50/79] Added initial test for the registry --- coverage.json | 1 + helpers/contracts-helpers.ts | 9 +++++++++ test/addresses-provider-registry.spec.ts | 23 +++++++++++++++++++++++ test/helpers/make-suite.ts | 8 ++++++-- 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 coverage.json create mode 100644 test/addresses-provider-registry.spec.ts diff --git a/coverage.json b/coverage.json new file mode 100644 index 00000000..a6a2eaab --- /dev/null +++ b/coverage.json @@ -0,0 +1 @@ +{"contracts/configuration/LendingPoolAddressesProvider.sol":{"l":{"38":9,"46":1,"47":1,"55":119,"63":1,"64":1,"75":37,"83":1,"84":1,"93":124,"97":1,"98":1,"102":168,"106":1,"107":1,"111":234,"115":1,"116":1,"125":2,"127":2,"130":2,"132":2,"133":2,"134":2,"135":2,"136":2,"138":0},"path":"/src/contracts/configuration/LendingPoolAddressesProvider.sol","s":{"1":9,"2":1,"3":1,"4":119,"5":1,"6":1,"7":37,"8":1,"9":1,"10":124,"11":1,"12":1,"13":168,"14":1,"15":1,"16":234,"17":1,"18":1,"19":2,"20":2,"21":2,"22":2,"23":2,"24":2,"25":2,"26":2,"27":0},"b":{"1":[2,0]},"f":{"1":9,"2":1,"3":119,"4":1,"5":37,"6":1,"7":124,"8":1,"9":168,"10":1,"11":234,"12":1,"13":2},"fnMap":{"1":{"name":"getLendingPool","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setLendingPoolImpl","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":48,"column":2}}},"3":{"name":"getLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"setLendingPoolConfiguratorImpl","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"getLendingPoolCollateralManager","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"setLendingPoolCollateralManager","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":85,"column":2}}},"7":{"name":"getAaveAdmin","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"setAaveAdmin","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":99,"column":2}}},"9":{"name":"getPriceOracle","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"10":{"name":"setPriceOracle","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":108,"column":2}}},"11":{"name":"getLendingRateOracle","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":112,"column":2}}},"12":{"name":"setLendingRateOracle","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":117,"column":2}}},"13":{"name":"_updateImpl","line":124,"loc":{"start":{"line":124,"column":2},"end":{"line":140,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":35}},"2":{"start":{"line":46,"column":4},"end":{"line":46,"column":34}},"3":{"start":{"line":47,"column":4},"end":{"line":47,"column":33}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":48}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":55}},"6":{"start":{"line":64,"column":4},"end":{"line":64,"column":53}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":54}},"8":{"start":{"line":83,"column":4},"end":{"line":83,"column":56}},"9":{"start":{"line":84,"column":4},"end":{"line":84,"column":53}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":33}},"11":{"start":{"line":97,"column":4},"end":{"line":97,"column":37}},"12":{"start":{"line":98,"column":4},"end":{"line":98,"column":36}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":35}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":41}},"15":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"16":{"start":{"line":111,"column":4},"end":{"line":111,"column":42}},"17":{"start":{"line":115,"column":4},"end":{"line":115,"column":54}},"18":{"start":{"line":116,"column":4},"end":{"line":116,"column":52}},"19":{"start":{"line":125,"column":4},"end":{"line":125,"column":58}},"20":{"start":{"line":127,"column":4},"end":{"line":127,"column":4874}},"21":{"start":{"line":130,"column":4},"end":{"line":130,"column":87}},"22":{"start":{"line":132,"column":4},"end":{"line":132,"column":5078}},"23":{"start":{"line":133,"column":6},"end":{"line":133,"column":56}},"24":{"start":{"line":134,"column":6},"end":{"line":134,"column":56}},"25":{"start":{"line":135,"column":6},"end":{"line":135,"column":36}},"26":{"start":{"line":136,"column":6},"end":{"line":136,"column":43}},"27":{"start":{"line":138,"column":6},"end":{"line":138,"column":47}}},"branchMap":{"1":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":132,"column":4}},{"start":{"line":132,"column":4},"end":{"line":132,"column":4}}]}}},"contracts/configuration/LendingPoolAddressesProviderRegistry.sol":{"l":{"31":0,"39":0,"41":0,"43":0,"44":0,"45":0,"49":0,"57":1,"58":1,"59":1,"67":0,"68":0,"69":0,"77":1,"78":0,"79":0,"83":1},"path":"/src/contracts/configuration/LendingPoolAddressesProviderRegistry.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":1,"9":1,"10":1,"11":0,"12":0,"13":0,"14":1,"15":0,"16":0,"17":1},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0,"2":0,"3":1,"4":0,"5":1},"fnMap":{"1":{"name":"isAddressesProviderRegistered","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"getAddressesProvidersList","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"registerAddressesProvider","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":60,"column":2}}},"4":{"name":"unregisterAddressesProvider","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":2}}},"5":{"name":"_addToAddressesProvidersList","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":84,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":39}},"2":{"start":{"line":39,"column":4},"end":{"line":39,"column":53}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":63}},"4":{"start":{"line":43,"column":4},"end":{"line":43,"column":1323}},"5":{"start":{"line":44,"column":6},"end":{"line":44,"column":1393}},"6":{"start":{"line":45,"column":8},"end":{"line":45,"column":53}},"7":{"start":{"line":49,"column":4},"end":{"line":49,"column":26}},"8":{"start":{"line":57,"column":4},"end":{"line":57,"column":36}},"9":{"start":{"line":58,"column":4},"end":{"line":58,"column":41}},"10":{"start":{"line":59,"column":4},"end":{"line":59,"column":46}},"11":{"start":{"line":67,"column":4},"end":{"line":67,"column":76}},"12":{"start":{"line":68,"column":4},"end":{"line":68,"column":35}},"13":{"start":{"line":69,"column":4},"end":{"line":69,"column":48}},"14":{"start":{"line":77,"column":4},"end":{"line":77,"column":2552}},"15":{"start":{"line":78,"column":6},"end":{"line":78,"column":2622}},"16":{"start":{"line":79,"column":8},"end":{"line":79,"column":14}},"17":{"start":{"line":83,"column":4},"end":{"line":83,"column":40}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":6},"end":{"line":44,"column":6}},{"start":{"line":44,"column":6},"end":{"line":44,"column":6}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":6},"end":{"line":78,"column":6}},{"start":{"line":78,"column":6},"end":{"line":78,"column":6}}]}}},"contracts/flashloan/base/FlashLoanReceiverBase.sol":{"l":{"18":3},"path":"/src/contracts/flashloan/base/FlashLoanReceiverBase.sol","s":{"1":3},"b":{},"f":{"1":3},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":32}}},"branchMap":{}},"contracts/flashloan/interfaces/IFlashLoanReceiver.sol":{"l":{},"path":"/src/contracts/flashloan/interfaces/IFlashLoanReceiver.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/lendingpool/DefaultReserveInterestRateStrategy.sol":{"l":{"62":51,"63":51,"64":51,"65":51,"66":51,"67":51,"75":0,"79":0,"83":0,"87":0,"91":0,"95":7,"137":234,"139":234,"140":234,"141":234,"142":234,"144":234,"148":234,"151":234,"152":4,"156":4,"160":4,"164":230,"167":230,"172":234,"181":234,"198":234,"200":234,"202":86,"206":86,"210":86,"214":86},"path":"/src/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":0,"8":0,"9":0,"10":0,"11":0,"12":7,"13":234,"14":234,"15":234,"16":234,"17":234,"18":234,"19":234,"20":234,"21":4,"22":4,"23":4,"24":230,"25":230,"26":234,"27":234,"28":234,"29":234,"30":148,"31":86,"32":86,"33":86,"34":86},"b":{"1":[4,230],"2":[148,86]},"f":{"1":51,"2":0,"3":0,"4":0,"5":0,"6":0,"7":7,"8":234,"9":234},"fnMap":{"1":{"name":"constructor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":68,"column":2}}},"2":{"name":"variableRateSlope1","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"variableRateSlope2","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":80,"column":2}}},"4":{"name":"stableRateSlope1","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":84,"column":2}}},"5":{"name":"stableRateSlope2","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":88,"column":2}}},"6":{"name":"baseVariableBorrowRate","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"getMaxVariableBorrowRate","line":94,"loc":{"start":{"line":94,"column":2},"end":{"line":96,"column":2}}},"8":{"name":"calculateInterestRates","line":119,"loc":{"start":{"line":119,"column":2},"end":{"line":182,"column":2}}},"9":{"name":"_getOverallBorrowRate","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":215,"column":2}}}},"statementMap":{"1":{"start":{"line":62,"column":4},"end":{"line":62,"column":31}},"2":{"start":{"line":63,"column":4},"end":{"line":63,"column":51}},"3":{"start":{"line":64,"column":4},"end":{"line":64,"column":43}},"4":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"5":{"start":{"line":66,"column":4},"end":{"line":66,"column":39}},"6":{"start":{"line":67,"column":4},"end":{"line":67,"column":39}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":30}},"8":{"start":{"line":79,"column":4},"end":{"line":79,"column":30}},"9":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"10":{"start":{"line":87,"column":4},"end":{"line":87,"column":28}},"11":{"start":{"line":91,"column":4},"end":{"line":91,"column":34}},"12":{"start":{"line":95,"column":4},"end":{"line":95,"column":84}},"13":{"start":{"line":137,"column":4},"end":{"line":137,"column":42}},"14":{"start":{"line":139,"column":4},"end":{"line":139,"column":61}},"15":{"start":{"line":140,"column":4},"end":{"line":140,"column":37}},"16":{"start":{"line":141,"column":4},"end":{"line":141,"column":35}},"17":{"start":{"line":142,"column":4},"end":{"line":142,"column":32}},"18":{"start":{"line":144,"column":4},"end":{"line":144,"column":5183}},"19":{"start":{"line":148,"column":4},"end":{"line":148,"column":5283}},"20":{"start":{"line":151,"column":4},"end":{"line":151,"column":5387}},"21":{"start":{"line":152,"column":6},"end":{"line":152,"column":5446}},"22":{"start":{"line":156,"column":6},"end":{"line":156,"column":5584}},"23":{"start":{"line":160,"column":6},"end":{"line":160,"column":5749}},"24":{"start":{"line":164,"column":6},"end":{"line":164,"column":5927}},"25":{"start":{"line":167,"column":6},"end":{"line":167,"column":6090}},"26":{"start":{"line":172,"column":4},"end":{"line":172,"column":6320}},"27":{"start":{"line":181,"column":4},"end":{"line":181,"column":100}},"28":{"start":{"line":198,"column":4},"end":{"line":198,"column":65}},"29":{"start":{"line":200,"column":4},"end":{"line":200,"column":35}},"30":{"start":{"line":200,"column":27},"end":{"line":200,"column":35}},"31":{"start":{"line":202,"column":4},"end":{"line":202,"column":7483}},"32":{"start":{"line":206,"column":4},"end":{"line":206,"column":7595}},"33":{"start":{"line":210,"column":4},"end":{"line":210,"column":7708}},"34":{"start":{"line":214,"column":4},"end":{"line":214,"column":28}}},"branchMap":{"1":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":4},"end":{"line":151,"column":4}},{"start":{"line":151,"column":4},"end":{"line":151,"column":4}}]},"2":{"line":200,"type":"if","locations":[{"start":{"line":200,"column":4},"end":{"line":200,"column":4}},{"start":{"line":200,"column":4},"end":{"line":200,"column":4}}]}}},"contracts/lendingpool/LendingPool.sol":{"l":{"55":118,"68":300,"72":1,"81":1,"97":105,"98":104,"100":104,"102":102,"104":102,"105":102,"107":102,"108":102,"109":94,"112":102,"115":102,"117":102,"126":26,"127":25,"129":25,"131":25,"133":25,"136":25,"137":19,"140":25,"150":22,"152":22,"154":22,"155":19,"158":22,"160":22,"177":3,"194":5,"195":4,"197":3,"198":3,"217":62,"218":61,"220":61,"221":4,"223":4,"229":59,"257":21,"259":20,"261":20,"263":20,"266":20,"270":20,"271":5,"274":20,"283":17,"286":17,"287":9,"289":8,"296":17,"297":17,"299":17,"300":12,"303":17,"305":17,"314":5,"315":4,"317":4,"319":4,"321":4,"329":2,"331":2,"333":1,"334":1,"341":1,"346":1,"353":2,"355":2,"367":8,"369":7,"371":7,"372":7,"373":7,"375":7,"378":7,"379":7,"380":7,"387":7,"388":7,"394":7,"401":1,"403":1,"404":1,"406":1,"408":1,"418":8,"419":7,"421":7,"430":6,"432":6,"433":2,"435":4,"455":11,"456":10,"459":10,"469":10,"471":10,"473":10,"475":5,"499":21,"500":20,"501":18,"503":18,"506":18,"517":18,"519":16,"521":16,"522":5,"525":11,"555":14,"556":13,"557":13,"559":13,"561":13,"563":13,"565":11,"567":11,"570":11,"573":9,"575":9,"577":9,"578":5,"580":3,"581":3,"582":3,"584":3,"587":4,"617":10,"618":9,"621":9,"631":9,"633":7,"635":7,"636":5,"662":97,"664":97,"689":710,"691":710,"715":363,"717":363,"744":21,"758":21,"781":343,"783":343,"784":343,"785":343,"786":343,"787":343,"788":343,"789":343,"792":343,"796":3,"800":0,"816":17,"817":17,"823":17,"836":0,"837":0,"841":75,"842":75,"851":75,"872":63,"873":63,"875":63,"877":63,"881":63,"894":50,"895":50,"896":37,"899":50,"902":50,"904":50,"907":25,"909":25,"915":25,"922":50,"929":50,"930":47,"933":50,"950":17,"951":17,"952":17,"953":136,"954":0,"956":17,"957":17,"958":17,"968":648,"982":809,"997":4,"998":3,"1015":26,"1017":26,"1018":26,"1019":13,"1021":13,"1029":0},"path":"/src/contracts/lendingpool/LendingPool.sol","s":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":104,"7":104,"8":102,"9":102,"10":102,"11":102,"12":102,"13":94,"14":102,"15":102,"16":102,"17":26,"18":25,"19":25,"20":25,"21":25,"22":25,"23":19,"24":25,"25":22,"26":22,"27":22,"28":19,"29":22,"30":22,"31":3,"32":5,"33":4,"34":3,"35":3,"36":62,"37":61,"38":61,"39":4,"40":4,"41":59,"42":21,"43":20,"44":20,"45":20,"46":20,"47":20,"48":5,"49":20,"50":17,"51":17,"52":9,"53":8,"54":17,"55":17,"56":17,"57":12,"58":17,"59":17,"60":5,"61":4,"62":4,"63":4,"64":4,"65":2,"66":2,"67":1,"68":1,"69":1,"70":1,"71":2,"72":2,"73":8,"74":7,"75":7,"76":7,"77":7,"78":7,"79":7,"80":7,"81":7,"82":7,"83":7,"84":7,"85":1,"86":1,"87":1,"88":1,"89":1,"90":8,"91":7,"92":7,"93":6,"94":6,"95":2,"96":4,"97":11,"98":10,"99":10,"100":10,"101":10,"102":10,"103":5,"104":21,"105":20,"106":18,"107":18,"108":18,"109":18,"110":16,"111":16,"112":5,"113":11,"114":14,"115":13,"116":13,"117":13,"118":13,"119":13,"120":11,"121":11,"122":11,"123":9,"124":9,"125":9,"126":5,"127":3,"128":3,"129":3,"130":3,"131":4,"132":10,"133":9,"134":9,"135":9,"136":7,"137":7,"138":5,"139":97,"140":97,"141":710,"142":710,"143":363,"144":363,"145":21,"146":21,"147":343,"148":343,"149":343,"150":343,"151":343,"152":343,"153":343,"154":343,"155":343,"156":3,"157":17,"158":17,"159":17,"160":0,"161":0,"162":75,"163":75,"164":75,"165":63,"166":63,"167":63,"168":63,"169":63,"170":50,"171":50,"172":37,"173":50,"174":50,"175":50,"176":25,"177":25,"178":25,"179":50,"180":50,"181":47,"182":50,"183":17,"184":17,"185":17,"186":136,"187":0,"188":17,"189":17,"190":17,"191":648,"192":809,"193":4,"194":3,"195":26,"196":26,"197":26,"198":13,"199":13,"200":0},"b":{"1":[118,0],"2":[287,13],"3":[94,8],"4":[19,6],"5":[19,3],"6":[4,57],"7":[5,15],"8":[9,8],"9":[12,5],"10":[1,1],"11":[1,6],"12":[2,4],"13":[10,0],"14":[5,5],"15":[18,2],"16":[16,2],"17":[5,11],"18":[5,4],"19":[7,2],"20":[5,2],"21":[37,13],"22":[25,25],"23":[47,3],"24":[17,0],"25":[0,136],"26":[17,0],"27":[13,13]},"f":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":26,"7":3,"8":5,"9":62,"10":21,"11":5,"12":8,"13":8,"14":11,"15":21,"16":14,"17":10,"18":97,"19":710,"20":363,"21":21,"22":343,"23":3,"24":17,"25":0,"26":75,"27":75,"28":63,"29":17,"30":648,"31":809,"32":4,"33":26,"34":0},"fnMap":{"1":{"name":"_onlyLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":59,"column":2}}},"2":{"name":"_whenNotPaused","line":67,"loc":{"start":{"line":67,"column":2},"end":{"line":69,"column":2}}},"3":{"name":"getRevision","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"4":{"name":"initialize","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":82,"column":2}}},"5":{"name":"deposit","line":91,"loc":{"start":{"line":91,"column":2},"end":{"line":118,"column":2}}},"6":{"name":"withdraw","line":125,"loc":{"start":{"line":125,"column":2},"end":{"line":161,"column":2}}},"7":{"name":"getBorrowAllowance","line":171,"loc":{"start":{"line":171,"column":2},"end":{"line":179,"column":2}}},"8":{"name":"delegateBorrowAllowance","line":188,"loc":{"start":{"line":188,"column":2},"end":{"line":199,"column":2}}},"9":{"name":"borrow","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":241,"column":2}}},"10":{"name":"repay","line":251,"loc":{"start":{"line":251,"column":2},"end":{"line":306,"column":2}}},"11":{"name":"swapBorrowRateMode","line":313,"loc":{"start":{"line":313,"column":2},"end":{"line":356,"column":2}}},"12":{"name":"rebalanceStableBorrowRate","line":365,"loc":{"start":{"line":365,"column":2},"end":{"line":410,"column":2}}},"13":{"name":"setUserUseReserveAsCollateral","line":417,"loc":{"start":{"line":417,"column":2},"end":{"line":437,"column":2}}},"14":{"name":"liquidationCall","line":448,"loc":{"start":{"line":448,"column":2},"end":{"line":477,"column":2}}},"15":{"name":"repayWithCollateral","line":491,"loc":{"start":{"line":491,"column":2},"end":{"line":526,"column":2}}},"16":{"name":"flashLoan","line":547,"loc":{"start":{"line":547,"column":2},"end":{"line":600,"column":2}}},"17":{"name":"swapLiquidity","line":610,"loc":{"start":{"line":610,"column":2},"end":{"line":638,"column":2}}},"18":{"name":"getReserveConfigurationData","line":644,"loc":{"start":{"line":644,"column":2},"end":{"line":677,"column":2}}},"19":{"name":"getReserveTokensAddresses","line":679,"loc":{"start":{"line":679,"column":2},"end":{"line":696,"column":2}}},"20":{"name":"getReserveData","line":698,"loc":{"start":{"line":698,"column":2},"end":{"line":729,"column":2}}},"21":{"name":"getUserAccountData","line":731,"loc":{"start":{"line":731,"column":2},"end":{"line":763,"column":2}}},"22":{"name":"getUserReserveData","line":765,"loc":{"start":{"line":765,"column":2},"end":{"line":793,"column":2}}},"23":{"name":"getReserves","line":795,"loc":{"start":{"line":795,"column":2},"end":{"line":797,"column":2}}},"24":{"name":"initReserve","line":809,"loc":{"start":{"line":809,"column":2},"end":{"line":824,"column":2}}},"25":{"name":"setReserveInterestRateStrategyAddress","line":832,"loc":{"start":{"line":832,"column":2},"end":{"line":838,"column":2}}},"26":{"name":"setConfiguration","line":840,"loc":{"start":{"line":840,"column":2},"end":{"line":843,"column":2}}},"27":{"name":"getConfiguration","line":845,"loc":{"start":{"line":845,"column":2},"end":{"line":852,"column":2}}},"28":{"name":"_executeBorrow","line":871,"loc":{"start":{"line":871,"column":2},"end":{"line":944,"column":2}}},"29":{"name":"_addReserveToList","line":949,"loc":{"start":{"line":949,"column":2},"end":{"line":960,"column":2}}},"30":{"name":"getReserveNormalizedIncome","line":967,"loc":{"start":{"line":967,"column":2},"end":{"line":969,"column":2}}},"31":{"name":"getReserveNormalizedVariableDebt","line":976,"loc":{"start":{"line":976,"column":2},"end":{"line":983,"column":2}}},"32":{"name":"balanceDecreaseAllowed","line":992,"loc":{"start":{"line":992,"column":2},"end":{"line":1008,"column":2}}},"33":{"name":"setPause","line":1014,"loc":{"start":{"line":1014,"column":2},"end":{"line":1023,"column":2}}},"34":{"name":"paused","line":1028,"loc":{"start":{"line":1028,"column":2},"end":{"line":1030,"column":2}}}},"statementMap":{"1":{"start":{"line":55,"column":4},"end":{"line":55,"column":2946}},"2":{"start":{"line":68,"column":4},"end":{"line":68,"column":38}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":31}},"4":{"start":{"line":81,"column":4},"end":{"line":81,"column":32}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":19}},"6":{"start":{"line":98,"column":4},"end":{"line":98,"column":63}},"7":{"start":{"line":100,"column":4},"end":{"line":100,"column":51}},"8":{"start":{"line":102,"column":4},"end":{"line":102,"column":42}},"9":{"start":{"line":104,"column":4},"end":{"line":104,"column":24}},"10":{"start":{"line":105,"column":4},"end":{"line":105,"column":56}},"11":{"start":{"line":107,"column":4},"end":{"line":107,"column":68}},"12":{"start":{"line":108,"column":4},"end":{"line":108,"column":4605}},"13":{"start":{"line":109,"column":6},"end":{"line":109,"column":68}},"14":{"start":{"line":112,"column":4},"end":{"line":112,"column":67}},"15":{"start":{"line":115,"column":4},"end":{"line":115,"column":61}},"16":{"start":{"line":117,"column":4},"end":{"line":117,"column":69}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":19}},"18":{"start":{"line":127,"column":4},"end":{"line":127,"column":63}},"19":{"start":{"line":129,"column":4},"end":{"line":129,"column":42}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":63}},"21":{"start":{"line":133,"column":4},"end":{"line":133,"column":37}},"22":{"start":{"line":136,"column":4},"end":{"line":136,"column":5500}},"23":{"start":{"line":137,"column":6},"end":{"line":137,"column":35}},"24":{"start":{"line":140,"column":4},"end":{"line":140,"column":5584}},"25":{"start":{"line":150,"column":4},"end":{"line":150,"column":24}},"26":{"start":{"line":152,"column":4},"end":{"line":152,"column":66}},"27":{"start":{"line":154,"column":4},"end":{"line":154,"column":5896}},"28":{"start":{"line":155,"column":6},"end":{"line":155,"column":69}},"29":{"start":{"line":158,"column":4},"end":{"line":158,"column":89}},"30":{"start":{"line":160,"column":4},"end":{"line":160,"column":44}},"31":{"start":{"line":177,"column":4},"end":{"line":177,"column":6759}},"32":{"start":{"line":194,"column":4},"end":{"line":194,"column":19}},"33":{"start":{"line":195,"column":4},"end":{"line":195,"column":78}},"34":{"start":{"line":197,"column":4},"end":{"line":197,"column":57}},"35":{"start":{"line":198,"column":4},"end":{"line":198,"column":84}},"36":{"start":{"line":217,"column":4},"end":{"line":217,"column":19}},"37":{"start":{"line":218,"column":4},"end":{"line":218,"column":63}},"38":{"start":{"line":220,"column":4},"end":{"line":220,"column":8253}},"39":{"start":{"line":221,"column":6},"end":{"line":221,"column":71}},"40":{"start":{"line":223,"column":6},"end":{"line":223,"column":8367}},"41":{"start":{"line":229,"column":4},"end":{"line":229,"column":8567}},"42":{"start":{"line":257,"column":4},"end":{"line":257,"column":19}},"43":{"start":{"line":259,"column":4},"end":{"line":259,"column":63}},"44":{"start":{"line":261,"column":4},"end":{"line":261,"column":96}},"45":{"start":{"line":263,"column":4},"end":{"line":263,"column":92}},"46":{"start":{"line":266,"column":4},"end":{"line":266,"column":9784}},"47":{"start":{"line":270,"column":4},"end":{"line":270,"column":9895}},"48":{"start":{"line":271,"column":6},"end":{"line":271,"column":27}},"49":{"start":{"line":274,"column":4},"end":{"line":274,"column":9997}},"50":{"start":{"line":283,"column":4},"end":{"line":283,"column":24}},"51":{"start":{"line":286,"column":4},"end":{"line":286,"column":10224}},"52":{"start":{"line":287,"column":6},"end":{"line":287,"column":85}},"53":{"start":{"line":289,"column":6},"end":{"line":289,"column":10397}},"54":{"start":{"line":296,"column":4},"end":{"line":296,"column":42}},"55":{"start":{"line":297,"column":4},"end":{"line":297,"column":63}},"56":{"start":{"line":299,"column":4},"end":{"line":299,"column":10664}},"57":{"start":{"line":300,"column":6},"end":{"line":300,"column":61}},"58":{"start":{"line":303,"column":4},"end":{"line":303,"column":68}},"59":{"start":{"line":305,"column":4},"end":{"line":305,"column":60}},"60":{"start":{"line":314,"column":4},"end":{"line":314,"column":19}},"61":{"start":{"line":315,"column":4},"end":{"line":315,"column":63}},"62":{"start":{"line":317,"column":4},"end":{"line":317,"column":96}},"63":{"start":{"line":319,"column":4},"end":{"line":319,"column":92}},"64":{"start":{"line":321,"column":4},"end":{"line":321,"column":11549}},"65":{"start":{"line":329,"column":4},"end":{"line":329,"column":24}},"66":{"start":{"line":331,"column":4},"end":{"line":331,"column":11735}},"67":{"start":{"line":333,"column":6},"end":{"line":333,"column":82}},"68":{"start":{"line":334,"column":6},"end":{"line":334,"column":11951}},"69":{"start":{"line":341,"column":6},"end":{"line":341,"column":12138}},"70":{"start":{"line":346,"column":6},"end":{"line":346,"column":12290}},"71":{"start":{"line":353,"column":4},"end":{"line":353,"column":66}},"72":{"start":{"line":355,"column":4},"end":{"line":355,"column":32}},"73":{"start":{"line":367,"column":4},"end":{"line":367,"column":19}},"74":{"start":{"line":369,"column":4},"end":{"line":369,"column":63}},"75":{"start":{"line":371,"column":4},"end":{"line":371,"column":67}},"76":{"start":{"line":372,"column":4},"end":{"line":372,"column":71}},"77":{"start":{"line":373,"column":4},"end":{"line":373,"column":49}},"78":{"start":{"line":375,"column":4},"end":{"line":375,"column":73}},"79":{"start":{"line":378,"column":4},"end":{"line":378,"column":104}},"80":{"start":{"line":379,"column":4},"end":{"line":379,"column":82}},"81":{"start":{"line":380,"column":4},"end":{"line":380,"column":13692}},"82":{"start":{"line":387,"column":4},"end":{"line":387,"column":63}},"83":{"start":{"line":388,"column":4},"end":{"line":388,"column":14007}},"84":{"start":{"line":394,"column":4},"end":{"line":394,"column":14137}},"85":{"start":{"line":401,"column":4},"end":{"line":401,"column":24}},"86":{"start":{"line":403,"column":4},"end":{"line":403,"column":77}},"87":{"start":{"line":404,"column":4},"end":{"line":404,"column":110}},"88":{"start":{"line":406,"column":4},"end":{"line":406,"column":58}},"89":{"start":{"line":408,"column":4},"end":{"line":408,"column":47}},"90":{"start":{"line":418,"column":4},"end":{"line":418,"column":19}},"91":{"start":{"line":419,"column":4},"end":{"line":419,"column":63}},"92":{"start":{"line":421,"column":4},"end":{"line":421,"column":15152}},"93":{"start":{"line":430,"column":4},"end":{"line":430,"column":77}},"94":{"start":{"line":432,"column":4},"end":{"line":432,"column":15436}},"95":{"start":{"line":433,"column":6},"end":{"line":433,"column":60}},"96":{"start":{"line":435,"column":6},"end":{"line":435,"column":61}},"97":{"start":{"line":455,"column":4},"end":{"line":455,"column":19}},"98":{"start":{"line":456,"column":4},"end":{"line":456,"column":84}},"99":{"start":{"line":459,"column":4},"end":{"line":459,"column":16409}},"100":{"start":{"line":469,"column":4},"end":{"line":469,"column":51}},"101":{"start":{"line":471,"column":4},"end":{"line":471,"column":93}},"102":{"start":{"line":473,"column":4},"end":{"line":473,"column":16839}},"103":{"start":{"line":475,"column":6},"end":{"line":475,"column":52}},"104":{"start":{"line":499,"column":4},"end":{"line":499,"column":19}},"105":{"start":{"line":500,"column":4},"end":{"line":500,"column":67}},"106":{"start":{"line":501,"column":4},"end":{"line":501,"column":33}},"107":{"start":{"line":503,"column":4},"end":{"line":503,"column":84}},"108":{"start":{"line":506,"column":4},"end":{"line":506,"column":18211}},"109":{"start":{"line":517,"column":4},"end":{"line":517,"column":56}},"110":{"start":{"line":519,"column":4},"end":{"line":519,"column":93}},"111":{"start":{"line":521,"column":4},"end":{"line":521,"column":18675}},"112":{"start":{"line":522,"column":6},"end":{"line":522,"column":52}},"113":{"start":{"line":525,"column":4},"end":{"line":525,"column":34}},"114":{"start":{"line":555,"column":4},"end":{"line":555,"column":19}},"115":{"start":{"line":556,"column":4},"end":{"line":556,"column":63}},"116":{"start":{"line":557,"column":4},"end":{"line":557,"column":34}},"117":{"start":{"line":559,"column":4},"end":{"line":559,"column":45}},"118":{"start":{"line":561,"column":4},"end":{"line":561,"column":64}},"119":{"start":{"line":563,"column":4},"end":{"line":563,"column":56}},"120":{"start":{"line":565,"column":4},"end":{"line":565,"column":80}},"121":{"start":{"line":567,"column":4},"end":{"line":567,"column":54}},"122":{"start":{"line":570,"column":4},"end":{"line":570,"column":76}},"123":{"start":{"line":573,"column":4},"end":{"line":573,"column":70}},"124":{"start":{"line":575,"column":4},"end":{"line":575,"column":52}},"125":{"start":{"line":577,"column":4},"end":{"line":577,"column":20770}},"126":{"start":{"line":578,"column":6},"end":{"line":578,"column":92}},"127":{"start":{"line":580,"column":6},"end":{"line":580,"column":26}},"128":{"start":{"line":581,"column":6},"end":{"line":581,"column":93}},"129":{"start":{"line":582,"column":6},"end":{"line":582,"column":76}},"130":{"start":{"line":584,"column":6},"end":{"line":584,"column":80}},"131":{"start":{"line":587,"column":6},"end":{"line":587,"column":21346}},"132":{"start":{"line":617,"column":4},"end":{"line":617,"column":19}},"133":{"start":{"line":618,"column":4},"end":{"line":618,"column":84}},"134":{"start":{"line":621,"column":4},"end":{"line":621,"column":22445}},"135":{"start":{"line":631,"column":4},"end":{"line":631,"column":50}},"136":{"start":{"line":633,"column":4},"end":{"line":633,"column":93}},"137":{"start":{"line":635,"column":4},"end":{"line":635,"column":22876}},"138":{"start":{"line":636,"column":6},"end":{"line":636,"column":52}},"139":{"start":{"line":662,"column":4},"end":{"line":662,"column":63}},"140":{"start":{"line":664,"column":4},"end":{"line":664,"column":23557}},"141":{"start":{"line":689,"column":4},"end":{"line":689,"column":63}},"142":{"start":{"line":691,"column":4},"end":{"line":691,"column":24379}},"143":{"start":{"line":715,"column":4},"end":{"line":715,"column":62}},"144":{"start":{"line":717,"column":4},"end":{"line":717,"column":25005}},"145":{"start":{"line":744,"column":4},"end":{"line":744,"column":25791}},"146":{"start":{"line":758,"column":4},"end":{"line":758,"column":26088}},"147":{"start":{"line":781,"column":4},"end":{"line":781,"column":63}},"148":{"start":{"line":783,"column":4},"end":{"line":783,"column":71}},"149":{"start":{"line":784,"column":4},"end":{"line":784,"column":87}},"150":{"start":{"line":785,"column":4},"end":{"line":785,"column":98}},"151":{"start":{"line":786,"column":4},"end":{"line":786,"column":98}},"152":{"start":{"line":787,"column":4},"end":{"line":787,"column":47}},"153":{"start":{"line":788,"column":4},"end":{"line":788,"column":94}},"154":{"start":{"line":789,"column":4},"end":{"line":789,"column":27231}},"155":{"start":{"line":792,"column":4},"end":{"line":792,"column":80}},"156":{"start":{"line":796,"column":4},"end":{"line":796,"column":24}},"157":{"start":{"line":816,"column":4},"end":{"line":816,"column":33}},"158":{"start":{"line":817,"column":4},"end":{"line":817,"column":28078}},"159":{"start":{"line":823,"column":4},"end":{"line":823,"column":27}},"160":{"start":{"line":836,"column":4},"end":{"line":836,"column":33}},"161":{"start":{"line":837,"column":4},"end":{"line":837,"column":69}},"162":{"start":{"line":841,"column":4},"end":{"line":841,"column":33}},"163":{"start":{"line":842,"column":4},"end":{"line":842,"column":54}},"164":{"start":{"line":851,"column":4},"end":{"line":851,"column":41}},"165":{"start":{"line":872,"column":4},"end":{"line":872,"column":68}},"166":{"start":{"line":873,"column":4},"end":{"line":873,"column":76}},"167":{"start":{"line":875,"column":4},"end":{"line":875,"column":56}},"168":{"start":{"line":877,"column":4},"end":{"line":877,"column":29792}},"169":{"start":{"line":881,"column":4},"end":{"line":881,"column":29946}},"170":{"start":{"line":894,"column":4},"end":{"line":894,"column":34}},"171":{"start":{"line":895,"column":4},"end":{"line":895,"column":30243}},"172":{"start":{"line":896,"column":6},"end":{"line":896,"column":45}},"173":{"start":{"line":899,"column":4},"end":{"line":899,"column":24}},"174":{"start":{"line":902,"column":4},"end":{"line":902,"column":33}},"175":{"start":{"line":904,"column":4},"end":{"line":904,"column":30453}},"176":{"start":{"line":907,"column":6},"end":{"line":907,"column":56}},"177":{"start":{"line":909,"column":6},"end":{"line":909,"column":30633}},"178":{"start":{"line":915,"column":6},"end":{"line":915,"column":30788}},"179":{"start":{"line":922,"column":4},"end":{"line":922,"column":30947}},"180":{"start":{"line":929,"column":4},"end":{"line":929,"column":31088}},"181":{"start":{"line":930,"column":6},"end":{"line":930,"column":77}},"182":{"start":{"line":933,"column":4},"end":{"line":933,"column":31210}},"183":{"start":{"line":950,"column":4},"end":{"line":950,"column":36}},"184":{"start":{"line":951,"column":4},"end":{"line":951,"column":87}},"185":{"start":{"line":952,"column":4},"end":{"line":952,"column":31801}},"186":{"start":{"line":953,"column":6},"end":{"line":953,"column":31858}},"187":{"start":{"line":954,"column":8},"end":{"line":954,"column":33}},"188":{"start":{"line":956,"column":4},"end":{"line":956,"column":31937}},"189":{"start":{"line":957,"column":6},"end":{"line":957,"column":54}},"190":{"start":{"line":958,"column":6},"end":{"line":958,"column":30}},"191":{"start":{"line":968,"column":4},"end":{"line":968,"column":49}},"192":{"start":{"line":982,"column":4},"end":{"line":982,"column":47}},"193":{"start":{"line":997,"column":4},"end":{"line":997,"column":19}},"194":{"start":{"line":998,"column":4},"end":{"line":998,"column":33188}},"195":{"start":{"line":1015,"column":4},"end":{"line":1015,"column":33}},"196":{"start":{"line":1017,"column":4},"end":{"line":1017,"column":16}},"197":{"start":{"line":1018,"column":4},"end":{"line":1018,"column":33641}},"198":{"start":{"line":1019,"column":6},"end":{"line":1019,"column":19}},"199":{"start":{"line":1021,"column":6},"end":{"line":1021,"column":21}},"200":{"start":{"line":1029,"column":4},"end":{"line":1029,"column":18}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":4}},{"start":{"line":68,"column":4},"end":{"line":68,"column":4}}]},"3":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":4},"end":{"line":108,"column":4}},{"start":{"line":108,"column":4},"end":{"line":108,"column":4}}]},"4":{"line":136,"type":"if","locations":[{"start":{"line":136,"column":4},"end":{"line":136,"column":4}},{"start":{"line":136,"column":4},"end":{"line":136,"column":4}}]},"5":{"line":154,"type":"if","locations":[{"start":{"line":154,"column":4},"end":{"line":154,"column":4}},{"start":{"line":154,"column":4},"end":{"line":154,"column":4}}]},"6":{"line":220,"type":"if","locations":[{"start":{"line":220,"column":4},"end":{"line":220,"column":4}},{"start":{"line":220,"column":4},"end":{"line":220,"column":4}}]},"7":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"8":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"9":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":4},"end":{"line":299,"column":4}},{"start":{"line":299,"column":4},"end":{"line":299,"column":4}}]},"10":{"line":331,"type":"if","locations":[{"start":{"line":331,"column":4},"end":{"line":331,"column":4}},{"start":{"line":331,"column":4},"end":{"line":331,"column":4}}]},"11":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":4},"end":{"line":394,"column":4}},{"start":{"line":394,"column":4},"end":{"line":394,"column":4}}]},"12":{"line":432,"type":"if","locations":[{"start":{"line":432,"column":4},"end":{"line":432,"column":4}},{"start":{"line":432,"column":4},"end":{"line":432,"column":4}}]},"13":{"line":469,"type":"if","locations":[{"start":{"line":469,"column":4},"end":{"line":469,"column":4}},{"start":{"line":469,"column":4},"end":{"line":469,"column":4}}]},"14":{"line":473,"type":"if","locations":[{"start":{"line":473,"column":4},"end":{"line":473,"column":4}},{"start":{"line":473,"column":4},"end":{"line":473,"column":4}}]},"15":{"line":500,"type":"if","locations":[{"start":{"line":500,"column":4},"end":{"line":500,"column":4}},{"start":{"line":500,"column":4},"end":{"line":500,"column":4}}]},"16":{"line":517,"type":"if","locations":[{"start":{"line":517,"column":4},"end":{"line":517,"column":4}},{"start":{"line":517,"column":4},"end":{"line":517,"column":4}}]},"17":{"line":521,"type":"if","locations":[{"start":{"line":521,"column":4},"end":{"line":521,"column":4}},{"start":{"line":521,"column":4},"end":{"line":521,"column":4}}]},"18":{"line":577,"type":"if","locations":[{"start":{"line":577,"column":4},"end":{"line":577,"column":4}},{"start":{"line":577,"column":4},"end":{"line":577,"column":4}}]},"19":{"line":631,"type":"if","locations":[{"start":{"line":631,"column":4},"end":{"line":631,"column":4}},{"start":{"line":631,"column":4},"end":{"line":631,"column":4}}]},"20":{"line":635,"type":"if","locations":[{"start":{"line":635,"column":4},"end":{"line":635,"column":4}},{"start":{"line":635,"column":4},"end":{"line":635,"column":4}}]},"21":{"line":895,"type":"if","locations":[{"start":{"line":895,"column":4},"end":{"line":895,"column":4}},{"start":{"line":895,"column":4},"end":{"line":895,"column":4}}]},"22":{"line":904,"type":"if","locations":[{"start":{"line":904,"column":4},"end":{"line":904,"column":4}},{"start":{"line":904,"column":4},"end":{"line":904,"column":4}}]},"23":{"line":929,"type":"if","locations":[{"start":{"line":929,"column":4},"end":{"line":929,"column":4}},{"start":{"line":929,"column":4},"end":{"line":929,"column":4}}]},"24":{"line":951,"type":"if","locations":[{"start":{"line":951,"column":4},"end":{"line":951,"column":4}},{"start":{"line":951,"column":4},"end":{"line":951,"column":4}}]},"25":{"line":953,"type":"if","locations":[{"start":{"line":953,"column":6},"end":{"line":953,"column":6}},{"start":{"line":953,"column":6},"end":{"line":953,"column":6}}]},"26":{"line":956,"type":"if","locations":[{"start":{"line":956,"column":4},"end":{"line":956,"column":4}},{"start":{"line":956,"column":4},"end":{"line":956,"column":4}}]},"27":{"line":1018,"type":"if","locations":[{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}},{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}}]}}},"contracts/lendingpool/LendingPoolCollateralManager.sol":{"l":{"127":0,"146":10,"147":10,"148":10,"150":10,"152":10,"161":10,"166":10,"175":10,"176":5,"179":5,"181":5,"183":5,"187":5,"191":5,"207":5,"208":1,"212":5,"213":3,"216":3,"217":0,"225":5,"227":5,"234":5,"235":1,"241":4,"247":4,"254":5,"255":2,"260":3,"261":3,"269":3,"278":5,"284":5,"294":5,"317":18,"318":18,"319":18,"321":18,"323":18,"331":18,"333":18,"343":18,"344":5,"347":13,"349":13,"353":13,"354":13,"356":13,"371":13,"372":2,"375":13,"377":13,"384":13,"385":2,"388":13,"391":13,"400":11,"401":11,"407":11,"409":11,"410":9,"416":2,"421":2,"428":11,"435":11,"444":11,"462":9,"463":9,"465":9,"467":9,"474":9,"475":4,"478":5,"479":5,"481":5,"482":5,"484":5,"485":2,"488":5,"490":4,"497":3,"505":3,"506":3,"507":3,"513":3,"514":1,"517":3,"518":3,"526":3,"534":3,"535":1,"541":2,"563":18,"564":18,"565":18,"567":18,"569":18,"570":18,"572":18,"575":18,"579":18,"586":18,"587":3,"588":3,"595":15,"596":15,"598":18},"path":"/src/contracts/lendingpool/LendingPoolCollateralManager.sol","s":{"1":0,"2":10,"3":10,"4":10,"5":10,"6":10,"7":10,"8":10,"9":10,"10":5,"11":5,"12":5,"13":5,"14":5,"15":5,"16":5,"17":1,"18":5,"19":3,"20":3,"21":0,"22":5,"23":5,"24":5,"25":1,"26":4,"27":4,"28":5,"29":2,"30":3,"31":3,"32":3,"33":5,"34":5,"35":5,"36":18,"37":18,"38":18,"39":18,"40":18,"41":18,"42":18,"43":18,"44":5,"45":13,"46":13,"47":13,"48":13,"49":13,"50":13,"51":2,"52":13,"53":13,"54":13,"55":2,"56":13,"57":13,"58":11,"59":11,"60":11,"61":11,"62":9,"63":2,"64":2,"65":11,"66":11,"67":11,"68":9,"69":9,"70":9,"71":9,"72":9,"73":4,"74":5,"75":5,"76":5,"77":5,"78":5,"79":2,"80":5,"81":4,"82":3,"83":3,"84":3,"85":3,"86":3,"87":1,"88":3,"89":3,"90":3,"91":3,"92":1,"93":2,"94":18,"95":18,"96":18,"97":18,"98":18,"99":18,"100":18,"101":18,"102":18,"103":18,"104":3,"105":3,"106":15,"107":15,"108":18},"b":{"1":[5,5],"2":[1,4],"3":[3,2],"4":[0,3],"5":[1,4],"6":[2,3],"7":[5,13],"8":[2,11],"9":[2,11],"10":[9,2],"11":[4,5],"12":[2,3],"13":[3,0],"14":[1,2],"15":[1,2],"16":[3,15]},"f":{"1":0,"2":10,"3":18,"4":9,"5":18},"fnMap":{"1":{"name":"getRevision","line":126,"loc":{"start":{"line":126,"column":2},"end":{"line":128,"column":2}}},"2":{"name":"liquidationCall","line":139,"loc":{"start":{"line":139,"column":2},"end":{"line":295,"column":2}}},"3":{"name":"repayWithCollateral","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":445,"column":2}}},"4":{"name":"swapLiquidity","line":455,"loc":{"start":{"line":455,"column":2},"end":{"line":542,"column":2}}},"5":{"name":"calculateAvailableCollateralToLiquidate","line":555,"loc":{"start":{"line":555,"column":2},"end":{"line":599,"column":2}}}},"statementMap":{"1":{"start":{"line":127,"column":4},"end":{"line":127,"column":12}},"2":{"start":{"line":146,"column":4},"end":{"line":146,"column":78}},"3":{"start":{"line":147,"column":4},"end":{"line":147,"column":76}},"4":{"start":{"line":148,"column":4},"end":{"line":148,"column":65}},"5":{"start":{"line":150,"column":4},"end":{"line":150,"column":40}},"6":{"start":{"line":152,"column":4},"end":{"line":152,"column":6033}},"7":{"start":{"line":161,"column":4},"end":{"line":161,"column":6330}},"8":{"start":{"line":166,"column":4},"end":{"line":166,"column":6452}},"9":{"start":{"line":175,"column":4},"end":{"line":175,"column":6686}},"10":{"start":{"line":176,"column":6},"end":{"line":176,"column":44}},"11":{"start":{"line":179,"column":4},"end":{"line":179,"column":67}},"12":{"start":{"line":181,"column":4},"end":{"line":181,"column":69}},"13":{"start":{"line":183,"column":4},"end":{"line":183,"column":6984}},"14":{"start":{"line":187,"column":4},"end":{"line":187,"column":7148}},"15":{"start":{"line":191,"column":4},"end":{"line":191,"column":7286}},"16":{"start":{"line":207,"column":4},"end":{"line":207,"column":7770}},"17":{"start":{"line":208,"column":6},"end":{"line":208,"column":62}},"18":{"start":{"line":212,"column":4},"end":{"line":212,"column":8027}},"19":{"start":{"line":213,"column":6},"end":{"line":213,"column":8058}},"20":{"start":{"line":216,"column":6},"end":{"line":216,"column":8178}},"21":{"start":{"line":217,"column":8},"end":{"line":217,"column":8255}},"22":{"start":{"line":225,"column":4},"end":{"line":225,"column":33}},"23":{"start":{"line":227,"column":4},"end":{"line":227,"column":8484}},"24":{"start":{"line":234,"column":4},"end":{"line":234,"column":8633}},"25":{"start":{"line":235,"column":6},"end":{"line":235,"column":8702}},"26":{"start":{"line":241,"column":6},"end":{"line":241,"column":8895}},"27":{"start":{"line":247,"column":6},"end":{"line":247,"column":9069}},"28":{"start":{"line":254,"column":4},"end":{"line":254,"column":9311}},"29":{"start":{"line":255,"column":6},"end":{"line":255,"column":97}},"30":{"start":{"line":260,"column":6},"end":{"line":260,"column":36}},"31":{"start":{"line":261,"column":6},"end":{"line":261,"column":9577}},"32":{"start":{"line":269,"column":6},"end":{"line":269,"column":9786}},"33":{"start":{"line":278,"column":4},"end":{"line":278,"column":9999}},"34":{"start":{"line":284,"column":4},"end":{"line":284,"column":10139}},"35":{"start":{"line":294,"column":4},"end":{"line":294,"column":79}},"36":{"start":{"line":317,"column":4},"end":{"line":317,"column":78}},"37":{"start":{"line":318,"column":4},"end":{"line":318,"column":71}},"38":{"start":{"line":319,"column":4},"end":{"line":319,"column":65}},"39":{"start":{"line":321,"column":4},"end":{"line":321,"column":40}},"40":{"start":{"line":323,"column":4},"end":{"line":323,"column":11674}},"41":{"start":{"line":331,"column":4},"end":{"line":331,"column":95}},"42":{"start":{"line":333,"column":4},"end":{"line":333,"column":11972}},"43":{"start":{"line":343,"column":4},"end":{"line":343,"column":12217}},"44":{"start":{"line":344,"column":6},"end":{"line":344,"column":44}},"45":{"start":{"line":347,"column":4},"end":{"line":347,"column":86}},"46":{"start":{"line":349,"column":4},"end":{"line":349,"column":12479}},"47":{"start":{"line":353,"column":4},"end":{"line":353,"column":67}},"48":{"start":{"line":354,"column":4},"end":{"line":354,"column":69}},"49":{"start":{"line":356,"column":4},"end":{"line":356,"column":12761}},"50":{"start":{"line":371,"column":4},"end":{"line":371,"column":13239}},"51":{"start":{"line":372,"column":6},"end":{"line":372,"column":62}},"52":{"start":{"line":375,"column":4},"end":{"line":375,"column":34}},"53":{"start":{"line":377,"column":4},"end":{"line":377,"column":13459}},"54":{"start":{"line":384,"column":4},"end":{"line":384,"column":13603}},"55":{"start":{"line":385,"column":6},"end":{"line":385,"column":73}},"56":{"start":{"line":388,"column":4},"end":{"line":388,"column":51}},"57":{"start":{"line":391,"column":4},"end":{"line":391,"column":13905}},"58":{"start":{"line":400,"column":4},"end":{"line":400,"column":28}},"59":{"start":{"line":401,"column":4},"end":{"line":401,"column":14123}},"60":{"start":{"line":407,"column":4},"end":{"line":407,"column":95}},"61":{"start":{"line":409,"column":4},"end":{"line":409,"column":14355}},"62":{"start":{"line":410,"column":6},"end":{"line":410,"column":14424}},"63":{"start":{"line":416,"column":6},"end":{"line":416,"column":14607}},"64":{"start":{"line":421,"column":6},"end":{"line":421,"column":14770}},"65":{"start":{"line":428,"column":4},"end":{"line":428,"column":14959}},"66":{"start":{"line":435,"column":4},"end":{"line":435,"column":15112}},"67":{"start":{"line":444,"column":4},"end":{"line":444,"column":79}},"68":{"start":{"line":462,"column":4},"end":{"line":462,"column":71}},"69":{"start":{"line":463,"column":4},"end":{"line":463,"column":67}},"70":{"start":{"line":465,"column":4},"end":{"line":465,"column":38}},"71":{"start":{"line":467,"column":4},"end":{"line":467,"column":16281}},"72":{"start":{"line":474,"column":4},"end":{"line":474,"column":16433}},"73":{"start":{"line":475,"column":6},"end":{"line":475,"column":44}},"74":{"start":{"line":478,"column":4},"end":{"line":478,"column":62}},"75":{"start":{"line":479,"column":4},"end":{"line":479,"column":58}},"76":{"start":{"line":481,"column":4},"end":{"line":481,"column":28}},"77":{"start":{"line":482,"column":4},"end":{"line":482,"column":26}},"78":{"start":{"line":484,"column":4},"end":{"line":484,"column":16775}},"79":{"start":{"line":485,"column":6},"end":{"line":485,"column":73}},"80":{"start":{"line":488,"column":4},"end":{"line":488,"column":95}},"81":{"start":{"line":490,"column":4},"end":{"line":490,"column":17029}},"82":{"start":{"line":497,"column":4},"end":{"line":497,"column":17256}},"83":{"start":{"line":505,"column":4},"end":{"line":505,"column":68}},"84":{"start":{"line":506,"column":4},"end":{"line":506,"column":17473}},"85":{"start":{"line":507,"column":6},"end":{"line":507,"column":17514}},"86":{"start":{"line":513,"column":6},"end":{"line":513,"column":17653}},"87":{"start":{"line":514,"column":8},"end":{"line":514,"column":72}},"88":{"start":{"line":517,"column":6},"end":{"line":517,"column":90}},"89":{"start":{"line":518,"column":6},"end":{"line":518,"column":17891}},"90":{"start":{"line":526,"column":4},"end":{"line":526,"column":18036}},"91":{"start":{"line":534,"column":4},"end":{"line":534,"column":18247}},"92":{"start":{"line":535,"column":6},"end":{"line":535,"column":18332}},"93":{"start":{"line":541,"column":4},"end":{"line":541,"column":79}},"94":{"start":{"line":563,"column":4},"end":{"line":563,"column":32}},"95":{"start":{"line":564,"column":4},"end":{"line":564,"column":37}},"96":{"start":{"line":565,"column":4},"end":{"line":565,"column":87}},"97":{"start":{"line":567,"column":4},"end":{"line":567,"column":55}},"98":{"start":{"line":569,"column":4},"end":{"line":569,"column":65}},"99":{"start":{"line":570,"column":4},"end":{"line":570,"column":71}},"100":{"start":{"line":572,"column":4},"end":{"line":572,"column":20103}},"101":{"start":{"line":575,"column":4},"end":{"line":575,"column":72}},"102":{"start":{"line":579,"column":4},"end":{"line":579,"column":20496}},"103":{"start":{"line":586,"column":4},"end":{"line":586,"column":20713}},"104":{"start":{"line":587,"column":6},"end":{"line":587,"column":45}},"105":{"start":{"line":588,"column":6},"end":{"line":588,"column":20871}},"106":{"start":{"line":595,"column":6},"end":{"line":595,"column":59}},"107":{"start":{"line":596,"column":6},"end":{"line":596,"column":43}},"108":{"start":{"line":598,"column":4},"end":{"line":598,"column":52}}},"branchMap":{"1":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":175,"column":4}},{"start":{"line":175,"column":4},"end":{"line":175,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"4":{"line":216,"type":"if","locations":[{"start":{"line":216,"column":6},"end":{"line":216,"column":6}},{"start":{"line":216,"column":6},"end":{"line":216,"column":6}}]},"5":{"line":234,"type":"if","locations":[{"start":{"line":234,"column":4},"end":{"line":234,"column":4}},{"start":{"line":234,"column":4},"end":{"line":234,"column":4}}]},"6":{"line":254,"type":"if","locations":[{"start":{"line":254,"column":4},"end":{"line":254,"column":4}},{"start":{"line":254,"column":4},"end":{"line":254,"column":4}}]},"7":{"line":343,"type":"if","locations":[{"start":{"line":343,"column":4},"end":{"line":343,"column":4}},{"start":{"line":343,"column":4},"end":{"line":343,"column":4}}]},"8":{"line":371,"type":"if","locations":[{"start":{"line":371,"column":4},"end":{"line":371,"column":4}},{"start":{"line":371,"column":4},"end":{"line":371,"column":4}}]},"9":{"line":384,"type":"if","locations":[{"start":{"line":384,"column":4},"end":{"line":384,"column":4}},{"start":{"line":384,"column":4},"end":{"line":384,"column":4}}]},"10":{"line":409,"type":"if","locations":[{"start":{"line":409,"column":4},"end":{"line":409,"column":4}},{"start":{"line":409,"column":4},"end":{"line":409,"column":4}}]},"11":{"line":474,"type":"if","locations":[{"start":{"line":474,"column":4},"end":{"line":474,"column":4}},{"start":{"line":474,"column":4},"end":{"line":474,"column":4}}]},"12":{"line":484,"type":"if","locations":[{"start":{"line":484,"column":4},"end":{"line":484,"column":4}},{"start":{"line":484,"column":4},"end":{"line":484,"column":4}}]},"13":{"line":506,"type":"if","locations":[{"start":{"line":506,"column":4},"end":{"line":506,"column":4}},{"start":{"line":506,"column":4},"end":{"line":506,"column":4}}]},"14":{"line":513,"type":"if","locations":[{"start":{"line":513,"column":6},"end":{"line":513,"column":6}},{"start":{"line":513,"column":6},"end":{"line":513,"column":6}}]},"15":{"line":534,"type":"if","locations":[{"start":{"line":534,"column":4},"end":{"line":534,"column":4}},{"start":{"line":534,"column":4},"end":{"line":534,"column":4}}]},"16":{"line":586,"type":"if","locations":[{"start":{"line":586,"column":4},"end":{"line":586,"column":4}},{"start":{"line":586,"column":4},"end":{"line":586,"column":4}}]}}},"contracts/lendingpool/LendingPoolConfigurator.sol":{"l":{"187":124,"188":105,"194":1,"198":1,"199":1,"219":17,"221":17,"226":17,"231":17,"239":17,"241":17,"243":17,"244":17,"246":17,"248":17,"263":1,"265":1,"267":1,"276":1,"278":1,"280":1,"289":1,"291":1,"293":1,"305":18,"307":18,"308":18,"310":18,"312":18,"320":1,"322":1,"324":1,"325":1,"341":14,"343":14,"344":14,"345":14,"347":14,"349":14,"357":1,"359":1,"361":1,"363":1,"371":1,"373":1,"375":1,"377":1,"385":1,"387":1,"389":1,"391":1,"399":7,"401":7,"403":7,"405":7,"413":8,"425":8,"430":7,"432":7,"434":7,"436":7,"444":2,"446":2,"448":2,"450":2,"458":2,"460":2,"462":2,"464":2,"473":1,"475":1,"477":1,"479":1,"488":1,"490":1,"492":1,"494":1,"504":1,"506":1,"508":1,"510":1,"519":1,"521":1,"523":1,"525":1,"534":0,"536":0,"538":0,"540":0,"552":0,"553":0,"562":51,"564":51,"571":51,"573":51,"581":3,"585":3,"587":3,"594":3,"602":26},"path":"/src/contracts/lendingpool/LendingPoolConfigurator.sol","s":{"1":124,"2":1,"3":1,"4":1,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":17,"12":17,"13":17,"14":17,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":18,"25":18,"26":18,"27":18,"28":18,"29":1,"30":1,"31":1,"32":1,"33":14,"34":14,"35":14,"36":14,"37":14,"38":14,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":7,"52":7,"53":7,"54":7,"55":8,"56":8,"57":7,"58":7,"59":7,"60":7,"61":2,"62":2,"63":2,"64":2,"65":2,"66":2,"67":2,"68":2,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":51,"92":51,"93":51,"94":51,"95":3,"96":3,"97":3,"98":3,"99":26},"b":{"1":[105,19],"2":[7,1]},"f":{"1":124,"2":1,"3":1,"4":17,"5":1,"6":1,"7":1,"8":18,"9":1,"10":14,"11":1,"12":1,"13":1,"14":7,"15":8,"16":2,"17":2,"18":1,"19":1,"20":1,"21":1,"22":0,"23":0,"24":51,"25":3,"26":26},"fnMap":{"1":{"name":"onlyAaveAdmin","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":189,"column":2}}},"2":{"name":"getRevision","line":193,"loc":{"start":{"line":193,"column":2},"end":{"line":195,"column":2}}},"3":{"name":"initialize","line":197,"loc":{"start":{"line":197,"column":2},"end":{"line":200,"column":2}}},"4":{"name":"initReserve","line":218,"loc":{"start":{"line":211,"column":2},"end":{"line":255,"column":2}}},"5":{"name":"updateAToken","line":262,"loc":{"start":{"line":262,"column":2},"end":{"line":268,"column":2}}},"6":{"name":"updateStableDebtToken","line":275,"loc":{"start":{"line":275,"column":2},"end":{"line":281,"column":2}}},"7":{"name":"updateVariableDebtToken","line":288,"loc":{"start":{"line":288,"column":2},"end":{"line":294,"column":2}}},"8":{"name":"enableBorrowingOnReserve","line":303,"loc":{"start":{"line":301,"column":2},"end":{"line":313,"column":2}}},"9":{"name":"disableBorrowingOnReserve","line":319,"loc":{"start":{"line":319,"column":2},"end":{"line":326,"column":2}}},"10":{"name":"enableReserveAsCollateral","line":340,"loc":{"start":{"line":335,"column":2},"end":{"line":350,"column":2}}},"11":{"name":"disableReserveAsCollateral","line":356,"loc":{"start":{"line":356,"column":2},"end":{"line":364,"column":2}}},"12":{"name":"enableReserveStableRate","line":370,"loc":{"start":{"line":370,"column":2},"end":{"line":378,"column":2}}},"13":{"name":"disableReserveStableRate","line":384,"loc":{"start":{"line":384,"column":2},"end":{"line":392,"column":2}}},"14":{"name":"activateReserve","line":398,"loc":{"start":{"line":398,"column":2},"end":{"line":406,"column":2}}},"15":{"name":"deactivateReserve","line":412,"loc":{"start":{"line":412,"column":2},"end":{"line":437,"column":2}}},"16":{"name":"freezeReserve","line":443,"loc":{"start":{"line":443,"column":2},"end":{"line":451,"column":2}}},"17":{"name":"unfreezeReserve","line":457,"loc":{"start":{"line":457,"column":2},"end":{"line":465,"column":2}}},"18":{"name":"setLtv","line":472,"loc":{"start":{"line":472,"column":2},"end":{"line":480,"column":2}}},"19":{"name":"setReserveFactor","line":487,"loc":{"start":{"line":487,"column":2},"end":{"line":495,"column":2}}},"20":{"name":"setLiquidationThreshold","line":503,"loc":{"start":{"line":503,"column":2},"end":{"line":511,"column":2}}},"21":{"name":"setLiquidationBonus","line":518,"loc":{"start":{"line":518,"column":2},"end":{"line":526,"column":2}}},"22":{"name":"setReserveDecimals","line":533,"loc":{"start":{"line":533,"column":2},"end":{"line":541,"column":2}}},"23":{"name":"setReserveInterestRateStrategyAddress","line":550,"loc":{"start":{"line":548,"column":2},"end":{"line":554,"column":2}}},"24":{"name":"_initTokenWithProxy","line":561,"loc":{"start":{"line":561,"column":2},"end":{"line":574,"column":2}}},"25":{"name":"_upgradeTokenImplementation","line":576,"loc":{"start":{"line":576,"column":2},"end":{"line":595,"column":2}}},"26":{"name":"setPoolPause","line":601,"loc":{"start":{"line":601,"column":2},"end":{"line":603,"column":2}}}},"statementMap":{"1":{"start":{"line":187,"column":4},"end":{"line":187,"column":88}},"2":{"start":{"line":194,"column":4},"end":{"line":194,"column":32}},"3":{"start":{"line":198,"column":4},"end":{"line":198,"column":31}},"4":{"start":{"line":199,"column":4},"end":{"line":199,"column":58}},"5":{"start":{"line":219,"column":4},"end":{"line":219,"column":89}},"6":{"start":{"line":221,"column":4},"end":{"line":221,"column":7918}},"7":{"start":{"line":226,"column":4},"end":{"line":226,"column":8046}},"8":{"start":{"line":231,"column":4},"end":{"line":231,"column":8177}},"9":{"start":{"line":239,"column":4},"end":{"line":239,"column":80}},"10":{"start":{"line":241,"column":4},"end":{"line":241,"column":53}},"11":{"start":{"line":243,"column":4},"end":{"line":243,"column":32}},"12":{"start":{"line":244,"column":4},"end":{"line":244,"column":33}},"13":{"start":{"line":246,"column":4},"end":{"line":246,"column":51}},"14":{"start":{"line":248,"column":4},"end":{"line":248,"column":8620}},"15":{"start":{"line":263,"column":4},"end":{"line":263,"column":71}},"16":{"start":{"line":265,"column":4},"end":{"line":265,"column":68}},"17":{"start":{"line":267,"column":4},"end":{"line":267,"column":61}},"18":{"start":{"line":276,"column":4},"end":{"line":276,"column":73}},"19":{"start":{"line":278,"column":4},"end":{"line":278,"column":70}},"20":{"start":{"line":280,"column":4},"end":{"line":280,"column":72}},"21":{"start":{"line":289,"column":4},"end":{"line":289,"column":75}},"22":{"start":{"line":291,"column":4},"end":{"line":291,"column":72}},"23":{"start":{"line":293,"column":4},"end":{"line":293,"column":76}},"24":{"start":{"line":305,"column":4},"end":{"line":305,"column":80}},"25":{"start":{"line":307,"column":4},"end":{"line":307,"column":42}},"26":{"start":{"line":308,"column":4},"end":{"line":308,"column":71}},"27":{"start":{"line":310,"column":4},"end":{"line":310,"column":51}},"28":{"start":{"line":312,"column":4},"end":{"line":312,"column":66}},"29":{"start":{"line":320,"column":4},"end":{"line":320,"column":80}},"30":{"start":{"line":322,"column":4},"end":{"line":322,"column":43}},"31":{"start":{"line":324,"column":4},"end":{"line":324,"column":51}},"32":{"start":{"line":325,"column":4},"end":{"line":325,"column":42}},"33":{"start":{"line":341,"column":4},"end":{"line":341,"column":80}},"34":{"start":{"line":343,"column":4},"end":{"line":343,"column":28}},"35":{"start":{"line":344,"column":4},"end":{"line":344,"column":62}},"36":{"start":{"line":345,"column":4},"end":{"line":345,"column":54}},"37":{"start":{"line":347,"column":4},"end":{"line":347,"column":51}},"38":{"start":{"line":349,"column":4},"end":{"line":349,"column":87}},"39":{"start":{"line":357,"column":4},"end":{"line":357,"column":80}},"40":{"start":{"line":359,"column":4},"end":{"line":359,"column":26}},"41":{"start":{"line":361,"column":4},"end":{"line":361,"column":51}},"42":{"start":{"line":363,"column":4},"end":{"line":363,"column":43}},"43":{"start":{"line":371,"column":4},"end":{"line":371,"column":80}},"44":{"start":{"line":373,"column":4},"end":{"line":373,"column":52}},"45":{"start":{"line":375,"column":4},"end":{"line":375,"column":51}},"46":{"start":{"line":377,"column":4},"end":{"line":377,"column":42}},"47":{"start":{"line":385,"column":4},"end":{"line":385,"column":80}},"48":{"start":{"line":387,"column":4},"end":{"line":387,"column":53}},"49":{"start":{"line":389,"column":4},"end":{"line":389,"column":51}},"50":{"start":{"line":391,"column":4},"end":{"line":391,"column":43}},"51":{"start":{"line":399,"column":4},"end":{"line":399,"column":80}},"52":{"start":{"line":401,"column":4},"end":{"line":401,"column":32}},"53":{"start":{"line":403,"column":4},"end":{"line":403,"column":51}},"54":{"start":{"line":405,"column":4},"end":{"line":405,"column":32}},"55":{"start":{"line":413,"column":4},"end":{"line":413,"column":14228}},"56":{"start":{"line":425,"column":4},"end":{"line":425,"column":14387}},"57":{"start":{"line":430,"column":4},"end":{"line":430,"column":80}},"58":{"start":{"line":432,"column":4},"end":{"line":432,"column":33}},"59":{"start":{"line":434,"column":4},"end":{"line":434,"column":51}},"60":{"start":{"line":436,"column":4},"end":{"line":436,"column":34}},"61":{"start":{"line":444,"column":4},"end":{"line":444,"column":80}},"62":{"start":{"line":446,"column":4},"end":{"line":446,"column":32}},"63":{"start":{"line":448,"column":4},"end":{"line":448,"column":51}},"64":{"start":{"line":450,"column":4},"end":{"line":450,"column":30}},"65":{"start":{"line":458,"column":4},"end":{"line":458,"column":80}},"66":{"start":{"line":460,"column":4},"end":{"line":460,"column":33}},"67":{"start":{"line":462,"column":4},"end":{"line":462,"column":51}},"68":{"start":{"line":464,"column":4},"end":{"line":464,"column":32}},"69":{"start":{"line":473,"column":4},"end":{"line":473,"column":80}},"70":{"start":{"line":475,"column":4},"end":{"line":475,"column":28}},"71":{"start":{"line":477,"column":4},"end":{"line":477,"column":51}},"72":{"start":{"line":479,"column":4},"end":{"line":479,"column":42}},"73":{"start":{"line":488,"column":4},"end":{"line":488,"column":80}},"74":{"start":{"line":490,"column":4},"end":{"line":490,"column":48}},"75":{"start":{"line":492,"column":4},"end":{"line":492,"column":51}},"76":{"start":{"line":494,"column":4},"end":{"line":494,"column":51}},"77":{"start":{"line":504,"column":4},"end":{"line":504,"column":80}},"78":{"start":{"line":506,"column":4},"end":{"line":506,"column":51}},"79":{"start":{"line":508,"column":4},"end":{"line":508,"column":51}},"80":{"start":{"line":510,"column":4},"end":{"line":510,"column":61}},"81":{"start":{"line":519,"column":4},"end":{"line":519,"column":80}},"82":{"start":{"line":521,"column":4},"end":{"line":521,"column":43}},"83":{"start":{"line":523,"column":4},"end":{"line":523,"column":51}},"84":{"start":{"line":525,"column":4},"end":{"line":525,"column":53}},"85":{"start":{"line":534,"column":4},"end":{"line":534,"column":80}},"86":{"start":{"line":536,"column":4},"end":{"line":536,"column":38}},"87":{"start":{"line":538,"column":4},"end":{"line":538,"column":51}},"88":{"start":{"line":540,"column":4},"end":{"line":540,"column":48}},"89":{"start":{"line":552,"column":4},"end":{"line":552,"column":73}},"90":{"start":{"line":553,"column":4},"end":{"line":553,"column":71}},"91":{"start":{"line":562,"column":4},"end":{"line":562,"column":93}},"92":{"start":{"line":564,"column":4},"end":{"line":564,"column":18940}},"93":{"start":{"line":571,"column":4},"end":{"line":571,"column":58}},"94":{"start":{"line":573,"column":4},"end":{"line":573,"column":25}},"95":{"start":{"line":581,"column":4},"end":{"line":581,"column":19368}},"96":{"start":{"line":585,"column":4},"end":{"line":585,"column":84}},"97":{"start":{"line":587,"column":4},"end":{"line":587,"column":19580}},"98":{"start":{"line":594,"column":4},"end":{"line":594,"column":49}},"99":{"start":{"line":602,"column":4},"end":{"line":602,"column":21}}},"branchMap":{"1":{"line":187,"type":"if","locations":[{"start":{"line":187,"column":4},"end":{"line":187,"column":4}},{"start":{"line":187,"column":4},"end":{"line":187,"column":4}}]},"2":{"line":425,"type":"if","locations":[{"start":{"line":425,"column":4},"end":{"line":425,"column":4}},{"start":{"line":425,"column":4},"end":{"line":425,"column":4}}]}}},"contracts/lendingpool/LendingPoolStorage.sol":{"l":{"30":0,"37":0},"path":"/src/contracts/lendingpool/LendingPoolStorage.sol","s":{"1":0,"2":0},"b":{},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"getReservesList","line":29,"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"getAddressesProvider","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":38,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":24}},"2":{"start":{"line":37,"column":4},"end":{"line":37,"column":29}}},"branchMap":{}},"contracts/libraries/configuration/ReserveConfiguration.sol":{"l":{"46":1,"55":570,"63":16,"72":194,"84":15,"97":112,"106":15,"119":97,"128":17,"137":178,"146":31,"155":179,"164":21,"173":97,"182":19,"191":97,"202":20,"215":97,"233":179,"235":179,"258":209,"260":209},"path":"/src/contracts/libraries/configuration/ReserveConfiguration.sol","s":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":179,"21":209,"22":209},"b":{},"f":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":209},"fnMap":{"1":{"name":"setReserveFactor","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"getReserveFactor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"3":{"name":"setLtv","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"getLtv","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"5":{"name":"setLiquidationThreshold","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":85,"column":2}}},"6":{"name":"getLiquidationThreshold","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":98,"column":2}}},"7":{"name":"setLiquidationBonus","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"8":{"name":"getLiquidationBonus","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":120,"column":2}}},"9":{"name":"setDecimals","line":127,"loc":{"start":{"line":127,"column":2},"end":{"line":129,"column":2}}},"10":{"name":"getDecimals","line":136,"loc":{"start":{"line":136,"column":2},"end":{"line":138,"column":2}}},"11":{"name":"setActive","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":147,"column":2}}},"12":{"name":"getActive","line":154,"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":2}}},"13":{"name":"setFrozen","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":165,"column":2}}},"14":{"name":"getFrozen","line":172,"loc":{"start":{"line":172,"column":2},"end":{"line":174,"column":2}}},"15":{"name":"setBorrowingEnabled","line":181,"loc":{"start":{"line":181,"column":2},"end":{"line":183,"column":2}}},"16":{"name":"getBorrowingEnabled","line":190,"loc":{"start":{"line":190,"column":2},"end":{"line":192,"column":2}}},"17":{"name":"setStableRateBorrowingEnabled","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":203,"column":2}}},"18":{"name":"getStableRateBorrowingEnabled","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":216,"column":2}}},"19":{"name":"getFlags","line":223,"loc":{"start":{"line":223,"column":2},"end":{"line":241,"column":2}}},"20":{"name":"getParams","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":266,"column":2}}}},"statementMap":{"1":{"start":{"line":46,"column":4},"end":{"line":46,"column":70}},"2":{"start":{"line":55,"column":4},"end":{"line":55,"column":51}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":43}},"4":{"start":{"line":72,"column":4},"end":{"line":72,"column":32}},"5":{"start":{"line":84,"column":4},"end":{"line":84,"column":75}},"6":{"start":{"line":97,"column":4},"end":{"line":97,"column":58}},"7":{"start":{"line":106,"column":4},"end":{"line":106,"column":67}},"8":{"start":{"line":119,"column":4},"end":{"line":119,"column":54}},"9":{"start":{"line":128,"column":4},"end":{"line":128,"column":61}},"10":{"start":{"line":137,"column":4},"end":{"line":137,"column":45}},"11":{"start":{"line":146,"column":4},"end":{"line":146,"column":74}},"12":{"start":{"line":155,"column":4},"end":{"line":155,"column":50}},"13":{"start":{"line":164,"column":4},"end":{"line":164,"column":74}},"14":{"start":{"line":173,"column":4},"end":{"line":173,"column":50}},"15":{"start":{"line":182,"column":4},"end":{"line":182,"column":78}},"16":{"start":{"line":191,"column":4},"end":{"line":191,"column":53}},"17":{"start":{"line":202,"column":4},"end":{"line":202,"column":85}},"18":{"start":{"line":215,"column":4},"end":{"line":215,"column":60}},"19":{"start":{"line":233,"column":4},"end":{"line":233,"column":33}},"20":{"start":{"line":235,"column":4},"end":{"line":235,"column":7613}},"21":{"start":{"line":258,"column":4},"end":{"line":258,"column":33}},"22":{"start":{"line":260,"column":4},"end":{"line":260,"column":8256}}},"branchMap":{}},"contracts/libraries/configuration/UserConfiguration.sol":{"l":{"31":49,"47":124,"63":1853,"77":235,"91":550,"100":33,"109":119},"path":"/src/contracts/libraries/configuration/UserConfiguration.sol","s":{"1":49,"2":124,"3":1853,"4":235,"5":550,"6":33,"7":119},"b":{},"f":{"1":49,"2":124,"3":1853,"4":235,"5":550,"6":33,"7":119},"fnMap":{"1":{"name":"setBorrowing","line":26,"loc":{"start":{"line":26,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"setUsingAsCollateral","line":42,"loc":{"start":{"line":42,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"isUsingAsCollateralOrBorrowing","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"isBorrowing","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":78,"column":2}}},"5":{"name":"isUsingAsCollateral","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":92,"column":2}}},"6":{"name":"isBorrowingAny","line":99,"loc":{"start":{"line":99,"column":2},"end":{"line":101,"column":2}}},"7":{"name":"isEmpty","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":110,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1104}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":1694}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":53}},"4":{"start":{"line":77,"column":4},"end":{"line":77,"column":53}},"5":{"start":{"line":91,"column":4},"end":{"line":91,"column":57}},"6":{"start":{"line":100,"column":4},"end":{"line":100,"column":42}},"7":{"start":{"line":109,"column":4},"end":{"line":109,"column":25}}},"branchMap":{}},"contracts/libraries/helpers/Errors.sol":{"l":{},"path":"/src/contracts/libraries/helpers/Errors.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/libraries/helpers/Helpers.sol":{"l":{"24":395},"path":"/src/contracts/libraries/helpers/Helpers.sol","s":{"1":395},"b":{},"f":{"1":395},"fnMap":{"1":{"name":"getUserCurrentDebt","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":24,"column":4},"end":{"line":24,"column":653}}},"branchMap":{}},"contracts/libraries/logic/GenericLogic.sol":{"l":{"65":33,"69":27,"72":6,"74":6,"76":6,"77":0,"80":6,"88":6,"89":0,"92":6,"96":6,"99":6,"100":3,"103":3,"109":3,"115":3,"169":119,"171":119,"172":10,"174":109,"175":1853,"176":1668,"179":185,"180":185,"182":185,"186":185,"187":185,"189":185,"190":128,"192":128,"197":128,"199":128,"200":128,"205":185,"206":63,"209":63,"213":63,"219":109,"222":109,"226":109,"231":109,"252":112,"254":64,"271":21,"273":21,"274":11,"277":10,"278":10},"path":"/src/contracts/libraries/logic/GenericLogic.sol","s":{"1":33,"2":27,"3":6,"4":6,"5":6,"6":0,"7":6,"8":6,"9":0,"10":6,"11":6,"12":6,"13":3,"14":3,"15":3,"16":3,"17":119,"18":119,"19":10,"20":109,"21":1853,"22":185,"23":185,"24":185,"25":185,"26":185,"27":185,"28":128,"29":128,"30":128,"31":128,"32":128,"33":185,"34":63,"35":63,"36":63,"37":109,"38":109,"39":109,"40":109,"41":112,"42":48,"43":64,"44":21,"45":21,"46":11,"47":10,"48":10},"b":{"1":[27,6],"2":[0,6],"3":[0,6],"4":[3,3],"5":[10,109],"6":[1668,185],"7":[128,57],"8":[63,122],"9":[48,64],"10":[11,10]},"f":{"1":33,"2":119,"3":112,"4":21},"fnMap":{"1":{"name":"balanceDecreaseAllowed","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":116,"column":2}}},"2":{"name":"calculateUserAccountData","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":238,"column":2}}},"3":{"name":"calculateHealthFactorFromBalances","line":247,"loc":{"start":{"line":247,"column":2},"end":{"line":255,"column":2}}},"4":{"name":"calculateAvailableBorrowsETH","line":266,"loc":{"start":{"line":266,"column":2},"end":{"line":279,"column":2}}}},"statementMap":{"1":{"start":{"line":65,"column":4},"end":{"line":65,"column":2530}},"2":{"start":{"line":69,"column":6},"end":{"line":69,"column":17}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":47}},"4":{"start":{"line":74,"column":4},"end":{"line":74,"column":80}},"5":{"start":{"line":76,"column":4},"end":{"line":76,"column":2807}},"6":{"start":{"line":77,"column":6},"end":{"line":77,"column":17}},"7":{"start":{"line":80,"column":4},"end":{"line":80,"column":3008}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":3133}},"9":{"start":{"line":89,"column":6},"end":{"line":89,"column":17}},"10":{"start":{"line":92,"column":4},"end":{"line":92,"column":3245}},"11":{"start":{"line":96,"column":4},"end":{"line":96,"column":95}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":3528}},"13":{"start":{"line":100,"column":6},"end":{"line":100,"column":18}},"14":{"start":{"line":103,"column":4},"end":{"line":103,"column":3647}},"15":{"start":{"line":109,"column":4},"end":{"line":109,"column":3854}},"16":{"start":{"line":115,"column":4},"end":{"line":115,"column":87}},"17":{"start":{"line":169,"column":4},"end":{"line":169,"column":44}},"18":{"start":{"line":171,"column":4},"end":{"line":171,"column":5830}},"19":{"start":{"line":172,"column":6},"end":{"line":172,"column":38}},"20":{"start":{"line":174,"column":4},"end":{"line":174,"column":5908}},"21":{"start":{"line":175,"column":6},"end":{"line":175,"column":5971}},"22":{"start":{"line":179,"column":6},"end":{"line":179,"column":50}},"23":{"start":{"line":180,"column":6},"end":{"line":180,"column":96}},"24":{"start":{"line":182,"column":6},"end":{"line":182,"column":6227}},"25":{"start":{"line":186,"column":6},"end":{"line":186,"column":39}},"26":{"start":{"line":187,"column":6},"end":{"line":187,"column":97}},"27":{"start":{"line":189,"column":6},"end":{"line":189,"column":6481}},"28":{"start":{"line":190,"column":8},"end":{"line":190,"column":93}},"29":{"start":{"line":192,"column":8},"end":{"line":192,"column":6673}},"30":{"start":{"line":197,"column":8},"end":{"line":197,"column":95}},"31":{"start":{"line":199,"column":8},"end":{"line":199,"column":71}},"32":{"start":{"line":200,"column":8},"end":{"line":200,"column":6976}},"33":{"start":{"line":205,"column":6},"end":{"line":205,"column":7126}},"34":{"start":{"line":206,"column":8},"end":{"line":206,"column":7174}},"35":{"start":{"line":209,"column":8},"end":{"line":209,"column":7296}},"36":{"start":{"line":213,"column":8},"end":{"line":213,"column":7455}},"37":{"start":{"line":219,"column":4},"end":{"line":219,"column":7632}},"38":{"start":{"line":222,"column":4},"end":{"line":222,"column":7752}},"39":{"start":{"line":226,"column":4},"end":{"line":226,"column":7903}},"40":{"start":{"line":231,"column":4},"end":{"line":231,"column":8077}},"41":{"start":{"line":252,"column":4},"end":{"line":252,"column":49}},"42":{"start":{"line":252,"column":31},"end":{"line":252,"column":49}},"43":{"start":{"line":254,"column":4},"end":{"line":254,"column":91}},"44":{"start":{"line":271,"column":4},"end":{"line":271,"column":70}},"45":{"start":{"line":273,"column":4},"end":{"line":273,"column":9571}},"46":{"start":{"line":274,"column":6},"end":{"line":274,"column":14}},"47":{"start":{"line":277,"column":4},"end":{"line":277,"column":66}},"48":{"start":{"line":278,"column":4},"end":{"line":278,"column":30}}},"branchMap":{"1":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":4},"end":{"line":65,"column":4}},{"start":{"line":65,"column":4},"end":{"line":65,"column":4}}]},"2":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":4}},{"start":{"line":76,"column":4},"end":{"line":76,"column":4}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"4":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":4},"end":{"line":99,"column":4}},{"start":{"line":99,"column":4},"end":{"line":99,"column":4}}]},"5":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":4},"end":{"line":171,"column":4}},{"start":{"line":171,"column":4},"end":{"line":171,"column":4}}]},"6":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":6},"end":{"line":175,"column":6}},{"start":{"line":175,"column":6},"end":{"line":175,"column":6}}]},"7":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"8":{"line":205,"type":"if","locations":[{"start":{"line":205,"column":6},"end":{"line":205,"column":6}},{"start":{"line":205,"column":6},"end":{"line":205,"column":6}}]},"9":{"line":252,"type":"if","locations":[{"start":{"line":252,"column":4},"end":{"line":252,"column":4}},{"start":{"line":252,"column":4},"end":{"line":252,"column":4}}]},"10":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":4},"end":{"line":273,"column":4}},{"start":{"line":273,"column":4},"end":{"line":273,"column":4}}]}}},"contracts/libraries/logic/ReserveLogic.sol":{"l":{"85":648,"88":648,"90":382,"93":266,"97":266,"108":809,"111":809,"113":493,"116":316,"120":316,"134":11,"139":10,"151":239,"152":239,"153":239,"155":239,"162":239,"183":3,"185":3,"187":3,"188":3,"190":3,"206":17,"207":17,"209":17,"212":17,"213":17,"216":17,"217":17,"218":17,"219":17,"246":235,"248":235,"250":235,"253":235,"255":235,"267":234,"268":234,"269":234,"271":234,"272":234,"273":234,"275":234,"316":239,"318":239,"320":239,"321":239,"325":0,"328":0,"336":0,"339":0,"342":0,"347":0,"350":0,"356":0,"358":0,"374":239,"376":239,"378":239,"379":239,"382":239,"383":69,"387":69,"388":69,"390":69,"394":69,"395":38,"399":38,"400":38,"401":38,"406":239,"407":239},"path":"/src/contracts/libraries/logic/ReserveLogic.sol","s":{"1":648,"2":648,"3":382,"4":266,"5":266,"6":809,"7":809,"8":493,"9":316,"10":316,"11":11,"12":10,"13":239,"14":239,"15":239,"16":239,"17":239,"18":3,"19":3,"20":3,"21":3,"22":3,"23":17,"24":17,"25":17,"26":17,"27":17,"28":17,"29":17,"30":17,"31":17,"32":235,"33":235,"34":235,"35":235,"36":235,"37":234,"38":234,"39":234,"40":234,"41":234,"42":234,"43":234,"44":239,"45":239,"46":239,"47":239,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":239,"58":239,"59":239,"60":239,"61":239,"62":69,"63":69,"64":69,"65":69,"66":69,"67":38,"68":38,"69":38,"70":38,"71":239,"72":239},"b":{"1":[382,266],"2":[493,316],"3":[10,1],"4":[3,0],"5":[17,0],"6":[17,0],"7":[17,0],"8":[234,0],"9":[234,0],"10":[234,0],"11":[239,0],"12":[69,170],"13":[69,0],"14":[38,31],"15":[38,0]},"f":{"1":648,"2":809,"3":11,"4":239,"5":3,"6":17,"7":235,"8":239,"9":239},"fnMap":{"1":{"name":"getNormalizedIncome","line":84,"loc":{"start":{"line":84,"column":2},"end":{"line":98,"column":2}}},"2":{"name":"getNormalizedDebt","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":121,"column":2}}},"3":{"name":"getDebtTokenAddress","line":129,"loc":{"start":{"line":129,"column":2},"end":{"line":143,"column":2}}},"4":{"name":"updateState","line":150,"loc":{"start":{"line":150,"column":2},"end":{"line":169,"column":2}}},"5":{"name":"cumulateToLiquidityIndex","line":178,"loc":{"start":{"line":178,"column":2},"end":{"line":191,"column":2}}},"6":{"name":"init","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":220,"column":2}}},"7":{"name":"updateInterestRates","line":239,"loc":{"start":{"line":239,"column":2},"end":{"line":283,"column":2}}},"8":{"name":"_mintToTreasury","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":359,"column":2}}},"9":{"name":"_updateIndexes","line":368,"loc":{"start":{"line":368,"column":2},"end":{"line":408,"column":2}}}},"statementMap":{"1":{"start":{"line":85,"column":4},"end":{"line":85,"column":50}},"2":{"start":{"line":88,"column":4},"end":{"line":88,"column":3533}},"3":{"start":{"line":90,"column":6},"end":{"line":90,"column":35}},"4":{"start":{"line":93,"column":4},"end":{"line":93,"column":3745}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":20}},"6":{"start":{"line":108,"column":4},"end":{"line":108,"column":50}},"7":{"start":{"line":111,"column":4},"end":{"line":111,"column":4417}},"8":{"start":{"line":113,"column":6},"end":{"line":113,"column":40}},"9":{"start":{"line":116,"column":4},"end":{"line":116,"column":4639}},"10":{"start":{"line":120,"column":4},"end":{"line":120,"column":20}},"11":{"start":{"line":134,"column":4},"end":{"line":134,"column":5256}},"12":{"start":{"line":139,"column":4},"end":{"line":139,"column":5559}},"13":{"start":{"line":151,"column":4},"end":{"line":151,"column":64}},"14":{"start":{"line":152,"column":4},"end":{"line":152,"column":69}},"15":{"start":{"line":153,"column":4},"end":{"line":153,"column":59}},"16":{"start":{"line":155,"column":4},"end":{"line":155,"column":6182}},"17":{"start":{"line":162,"column":4},"end":{"line":162,"column":6375}},"18":{"start":{"line":183,"column":4},"end":{"line":183,"column":88}},"19":{"start":{"line":185,"column":4},"end":{"line":185,"column":65}},"20":{"start":{"line":187,"column":4},"end":{"line":187,"column":49}},"21":{"start":{"line":188,"column":4},"end":{"line":188,"column":64}},"22":{"start":{"line":190,"column":4},"end":{"line":190,"column":43}},"23":{"start":{"line":206,"column":4},"end":{"line":206,"column":83}},"24":{"start":{"line":207,"column":4},"end":{"line":207,"column":7908}},"25":{"start":{"line":209,"column":6},"end":{"line":209,"column":55}},"26":{"start":{"line":212,"column":4},"end":{"line":212,"column":8064}},"27":{"start":{"line":213,"column":6},"end":{"line":213,"column":60}},"28":{"start":{"line":216,"column":4},"end":{"line":216,"column":40}},"29":{"start":{"line":217,"column":4},"end":{"line":217,"column":58}},"30":{"start":{"line":218,"column":4},"end":{"line":218,"column":62}},"31":{"start":{"line":219,"column":4},"end":{"line":219,"column":68}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":44}},"33":{"start":{"line":248,"column":4},"end":{"line":248,"column":63}},"34":{"start":{"line":250,"column":4},"end":{"line":250,"column":9530}},"35":{"start":{"line":253,"column":4},"end":{"line":253,"column":76}},"36":{"start":{"line":255,"column":4},"end":{"line":255,"column":9713}},"37":{"start":{"line":267,"column":4},"end":{"line":267,"column":87}},"38":{"start":{"line":268,"column":4},"end":{"line":268,"column":88}},"39":{"start":{"line":269,"column":4},"end":{"line":269,"column":92}},"40":{"start":{"line":271,"column":4},"end":{"line":271,"column":64}},"41":{"start":{"line":272,"column":4},"end":{"line":272,"column":64}},"42":{"start":{"line":273,"column":4},"end":{"line":273,"column":68}},"43":{"start":{"line":275,"column":4},"end":{"line":275,"column":10646}},"44":{"start":{"line":316,"column":4},"end":{"line":316,"column":39}},"45":{"start":{"line":318,"column":4},"end":{"line":318,"column":64}},"46":{"start":{"line":320,"column":4},"end":{"line":320,"column":12121}},"47":{"start":{"line":321,"column":6},"end":{"line":321,"column":12}},"48":{"start":{"line":325,"column":4},"end":{"line":325,"column":86}},"49":{"start":{"line":328,"column":4},"end":{"line":328,"column":12457}},"50":{"start":{"line":336,"column":4},"end":{"line":336,"column":90}},"51":{"start":{"line":339,"column":4},"end":{"line":339,"column":84}},"52":{"start":{"line":342,"column":4},"end":{"line":342,"column":12963}},"53":{"start":{"line":347,"column":4},"end":{"line":347,"column":90}},"54":{"start":{"line":350,"column":4},"end":{"line":350,"column":13330}},"55":{"start":{"line":356,"column":4},"end":{"line":356,"column":75}},"56":{"start":{"line":358,"column":4},"end":{"line":358,"column":86}},"57":{"start":{"line":374,"column":4},"end":{"line":374,"column":50}},"58":{"start":{"line":376,"column":4},"end":{"line":376,"column":63}},"59":{"start":{"line":378,"column":4},"end":{"line":378,"column":46}},"60":{"start":{"line":379,"column":4},"end":{"line":379,"column":56}},"61":{"start":{"line":382,"column":4},"end":{"line":382,"column":14442}},"62":{"start":{"line":383,"column":6},"end":{"line":383,"column":14483}},"63":{"start":{"line":387,"column":6},"end":{"line":387,"column":74}},"64":{"start":{"line":388,"column":6},"end":{"line":388,"column":77}},"65":{"start":{"line":390,"column":6},"end":{"line":390,"column":56}},"66":{"start":{"line":394,"column":6},"end":{"line":394,"column":14986}},"67":{"start":{"line":395,"column":8},"end":{"line":395,"column":15048}},"68":{"start":{"line":399,"column":8},"end":{"line":399,"column":91}},"69":{"start":{"line":400,"column":8},"end":{"line":400,"column":90}},"70":{"start":{"line":401,"column":8},"end":{"line":401,"column":68}},"71":{"start":{"line":406,"column":4},"end":{"line":406,"column":56}},"72":{"start":{"line":407,"column":4},"end":{"line":407,"column":54}}},"branchMap":{"1":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"2":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"3":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"4":{"line":188,"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":188,"column":4}},{"start":{"line":188,"column":4},"end":{"line":188,"column":4}}]},"5":{"line":206,"type":"if","locations":[{"start":{"line":206,"column":4},"end":{"line":206,"column":4}},{"start":{"line":206,"column":4},"end":{"line":206,"column":4}}]},"6":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"7":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"8":{"line":267,"type":"if","locations":[{"start":{"line":267,"column":4},"end":{"line":267,"column":4}},{"start":{"line":267,"column":4},"end":{"line":267,"column":4}}]},"9":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"10":{"line":269,"type":"if","locations":[{"start":{"line":269,"column":4},"end":{"line":269,"column":4}},{"start":{"line":269,"column":4},"end":{"line":269,"column":4}}]},"11":{"line":320,"type":"if","locations":[{"start":{"line":320,"column":4},"end":{"line":320,"column":4}},{"start":{"line":320,"column":4},"end":{"line":320,"column":4}}]},"12":{"line":382,"type":"if","locations":[{"start":{"line":382,"column":4},"end":{"line":382,"column":4}},{"start":{"line":382,"column":4},"end":{"line":382,"column":4}}]},"13":{"line":388,"type":"if","locations":[{"start":{"line":388,"column":6},"end":{"line":388,"column":6}},{"start":{"line":388,"column":6},"end":{"line":388,"column":6}}]},"14":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":6},"end":{"line":394,"column":6}},{"start":{"line":394,"column":6},"end":{"line":394,"column":6}}]},"15":{"line":400,"type":"if","locations":[{"start":{"line":400,"column":8},"end":{"line":400,"column":8}},{"start":{"line":400,"column":8},"end":{"line":400,"column":8}}]}}},"contracts/libraries/logic/ValidationLogic.sol":{"l":{"38":104,"40":104,"41":102,"42":102,"60":25,"62":24,"64":23,"125":63,"127":63,"134":63,"135":63,"137":63,"140":63,"146":61,"160":61,"162":55,"168":55,"172":55,"186":50,"189":0,"191":0,"200":0,"202":0,"222":20,"224":20,"226":20,"228":18,"236":18,"257":4,"259":4,"260":4,"262":4,"263":2,"265":2,"273":1,"275":1,"283":0,"304":7,"306":7,"308":7,"328":13,"329":12,"349":10,"352":2,"355":8,"356":1,"362":7,"366":7,"367":1,"373":6,"374":1,"380":5,"402":18,"405":2,"408":16,"411":0,"417":16,"418":8,"422":8,"423":1,"430":15,"431":2,"437":13,"453":9,"454":1,"460":8,"461":8,"462":2,"464":6,"465":1,"471":5},"path":"/src/contracts/libraries/logic/ValidationLogic.sol","s":{"1":104,"2":104,"3":102,"4":102,"5":25,"6":24,"7":23,"8":63,"9":63,"10":63,"11":63,"12":63,"13":63,"14":61,"15":61,"16":55,"17":55,"18":55,"19":50,"20":0,"21":0,"22":0,"23":0,"24":20,"25":20,"26":20,"27":18,"28":18,"29":4,"30":4,"31":4,"32":4,"33":2,"34":2,"35":2,"36":1,"37":1,"38":0,"39":7,"40":7,"41":7,"42":13,"43":12,"44":10,"45":2,"46":8,"47":1,"48":7,"49":7,"50":1,"51":6,"52":1,"53":5,"54":18,"55":2,"56":16,"57":0,"58":16,"59":8,"60":8,"61":1,"62":15,"63":2,"64":13,"65":9,"66":1,"67":8,"68":8,"69":2,"70":6,"71":1,"72":5},"b":{"1":[102,2],"2":[102,0],"3":[102,0],"4":[24,1],"5":[23,1],"6":[22,1],"7":[63,0],"8":[63,0],"9":[63,0],"10":[61,2],"11":[55,6],"12":[55,0],"13":[50,5],"14":[0,50],"15":[0,0],"16":[0,0],"17":[0,0],"18":[20,0],"19":[18,2],"20":[18,0],"21":[17,1],"22":[4,0],"23":[4,0],"24":[2,2],"25":[1,1],"26":[2,0],"27":[1,1],"28":[1,0],"29":[1,0],"30":[7,0],"31":[6,1],"32":[12,1],"33":[11,1],"34":[2,8],"35":[1,7],"36":[1,6],"37":[1,5],"38":[2,16],"39":[0,16],"40":[8,8],"41":[1,7],"42":[2,13],"43":[1,8],"44":[2,6],"45":[1,5]},"f":{"1":104,"2":25,"3":63,"4":20,"5":4,"6":7,"7":13,"8":10,"9":18,"10":9},"fnMap":{"1":{"name":"validateDeposit","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":43,"column":2}}},"2":{"name":"validateWithdraw","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"validateBorrow","line":113,"loc":{"start":{"line":113,"column":2},"end":{"line":204,"column":2}}},"4":{"name":"validateRepay","line":214,"loc":{"start":{"line":214,"column":2},"end":{"line":240,"column":2}}},"5":{"name":"validateSwapRateMode","line":250,"loc":{"start":{"line":250,"column":2},"end":{"line":285,"column":2}}},"6":{"name":"validateSetUseReserveAsCollateral","line":296,"loc":{"start":{"line":296,"column":2},"end":{"line":320,"column":2}}},"7":{"name":"validateFlashloan","line":327,"loc":{"start":{"line":327,"column":2},"end":{"line":330,"column":2}}},"8":{"name":"validateLiquidationCall","line":341,"loc":{"start":{"line":341,"column":2},"end":{"line":381,"column":2}}},"9":{"name":"validateRepayWithCollateral","line":393,"loc":{"start":{"line":393,"column":2},"end":{"line":438,"column":2}}},"10":{"name":"validateSwapLiquidity","line":447,"loc":{"start":{"line":447,"column":2},"end":{"line":472,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":74}},"2":{"start":{"line":40,"column":4},"end":{"line":40,"column":56}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":46}},"4":{"start":{"line":42,"column":4},"end":{"line":42,"column":51}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":56}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":75}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":2437}},"8":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"9":{"start":{"line":127,"column":4},"end":{"line":127,"column":4488}},"10":{"start":{"line":134,"column":4},"end":{"line":134,"column":51}},"11":{"start":{"line":135,"column":4},"end":{"line":135,"column":56}},"12":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"13":{"start":{"line":140,"column":4},"end":{"line":140,"column":4827}},"14":{"start":{"line":146,"column":4},"end":{"line":146,"column":5049}},"15":{"start":{"line":160,"column":4},"end":{"line":160,"column":77}},"16":{"start":{"line":162,"column":4},"end":{"line":162,"column":5434}},"17":{"start":{"line":168,"column":4},"end":{"line":168,"column":5703}},"18":{"start":{"line":172,"column":4},"end":{"line":172,"column":5861}},"19":{"start":{"line":186,"column":4},"end":{"line":186,"column":6430}},"20":{"start":{"line":189,"column":6},"end":{"line":189,"column":82}},"21":{"start":{"line":191,"column":6},"end":{"line":191,"column":6685}},"22":{"start":{"line":200,"column":6},"end":{"line":200,"column":90}},"23":{"start":{"line":202,"column":6},"end":{"line":202,"column":89}},"24":{"start":{"line":222,"column":4},"end":{"line":222,"column":53}},"25":{"start":{"line":224,"column":4},"end":{"line":224,"column":46}},"26":{"start":{"line":226,"column":4},"end":{"line":226,"column":60}},"27":{"start":{"line":228,"column":4},"end":{"line":228,"column":8040}},"28":{"start":{"line":236,"column":4},"end":{"line":236,"column":8339}},"29":{"start":{"line":257,"column":4},"end":{"line":257,"column":96}},"30":{"start":{"line":259,"column":4},"end":{"line":259,"column":46}},"31":{"start":{"line":260,"column":4},"end":{"line":260,"column":51}},"32":{"start":{"line":262,"column":4},"end":{"line":262,"column":9332}},"33":{"start":{"line":263,"column":6},"end":{"line":263,"column":76}},"34":{"start":{"line":264,"column":11},"end":{"line":264,"column":9485}},"35":{"start":{"line":265,"column":6},"end":{"line":265,"column":80}},"36":{"start":{"line":273,"column":6},"end":{"line":273,"column":68}},"37":{"start":{"line":275,"column":6},"end":{"line":275,"column":10079}},"38":{"start":{"line":283,"column":6},"end":{"line":283,"column":55}},"39":{"start":{"line":304,"column":4},"end":{"line":304,"column":83}},"40":{"start":{"line":306,"column":4},"end":{"line":306,"column":79}},"41":{"start":{"line":308,"column":4},"end":{"line":308,"column":11408}},"42":{"start":{"line":328,"column":4},"end":{"line":328,"column":58}},"43":{"start":{"line":329,"column":4},"end":{"line":329,"column":98}},"44":{"start":{"line":349,"column":4},"end":{"line":349,"column":12893}},"45":{"start":{"line":352,"column":6},"end":{"line":352,"column":98}},"46":{"start":{"line":355,"column":4},"end":{"line":355,"column":13115}},"47":{"start":{"line":356,"column":6},"end":{"line":356,"column":13200}},"48":{"start":{"line":362,"column":4},"end":{"line":362,"column":13408}},"49":{"start":{"line":366,"column":4},"end":{"line":366,"column":13592}},"50":{"start":{"line":367,"column":6},"end":{"line":367,"column":13629}},"51":{"start":{"line":373,"column":4},"end":{"line":373,"column":13783}},"52":{"start":{"line":374,"column":6},"end":{"line":374,"column":13844}},"53":{"start":{"line":380,"column":4},"end":{"line":380,"column":79}},"54":{"start":{"line":402,"column":4},"end":{"line":402,"column":14907}},"55":{"start":{"line":405,"column":6},"end":{"line":405,"column":98}},"56":{"start":{"line":408,"column":4},"end":{"line":408,"column":15129}},"57":{"start":{"line":411,"column":6},"end":{"line":411,"column":15248}},"58":{"start":{"line":417,"column":4},"end":{"line":417,"column":15402}},"59":{"start":{"line":418,"column":6},"end":{"line":418,"column":15490}},"60":{"start":{"line":422,"column":6},"end":{"line":422,"column":15680}},"61":{"start":{"line":423,"column":8},"end":{"line":423,"column":15719}},"62":{"start":{"line":430,"column":4},"end":{"line":430,"column":15885}},"63":{"start":{"line":431,"column":6},"end":{"line":431,"column":15946}},"64":{"start":{"line":437,"column":4},"end":{"line":437,"column":79}},"65":{"start":{"line":453,"column":4},"end":{"line":453,"column":16711}},"66":{"start":{"line":454,"column":6},"end":{"line":454,"column":16748}},"67":{"start":{"line":460,"column":4},"end":{"line":460,"column":80}},"68":{"start":{"line":461,"column":4},"end":{"line":461,"column":16978}},"69":{"start":{"line":462,"column":6},"end":{"line":462,"column":98}},"70":{"start":{"line":464,"column":4},"end":{"line":464,"column":17149}},"71":{"start":{"line":465,"column":6},"end":{"line":465,"column":17177}},"72":{"start":{"line":471,"column":4},"end":{"line":471,"column":79}}},"branchMap":{"1":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":4},"end":{"line":41,"column":4}},{"start":{"line":41,"column":4},"end":{"line":41,"column":4}}]},"3":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":4}},{"start":{"line":42,"column":4},"end":{"line":42,"column":4}}]},"4":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":4},"end":{"line":60,"column":4}},{"start":{"line":60,"column":4},"end":{"line":60,"column":4}}]},"5":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"6":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":64,"column":4}},{"start":{"line":64,"column":4},"end":{"line":64,"column":4}}]},"7":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"8":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":4},"end":{"line":135,"column":4}},{"start":{"line":135,"column":4},"end":{"line":135,"column":4}}]},"9":{"line":137,"type":"if","locations":[{"start":{"line":137,"column":4},"end":{"line":137,"column":4}},{"start":{"line":137,"column":4},"end":{"line":137,"column":4}}]},"10":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":140,"column":4}},{"start":{"line":140,"column":4},"end":{"line":140,"column":4}}]},"11":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]},"12":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":162,"column":4}},{"start":{"line":162,"column":4},"end":{"line":162,"column":4}}]},"13":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":4},"end":{"line":172,"column":4}},{"start":{"line":172,"column":4},"end":{"line":172,"column":4}}]},"14":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":4},"end":{"line":186,"column":4}},{"start":{"line":186,"column":4},"end":{"line":186,"column":4}}]},"15":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"16":{"line":191,"type":"if","locations":[{"start":{"line":191,"column":6},"end":{"line":191,"column":6}},{"start":{"line":191,"column":6},"end":{"line":191,"column":6}}]},"17":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":6},"end":{"line":202,"column":6}},{"start":{"line":202,"column":6},"end":{"line":202,"column":6}}]},"18":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"19":{"line":226,"type":"if","locations":[{"start":{"line":226,"column":4},"end":{"line":226,"column":4}},{"start":{"line":226,"column":4},"end":{"line":226,"column":4}}]},"20":{"line":228,"type":"if","locations":[{"start":{"line":228,"column":4},"end":{"line":228,"column":4}},{"start":{"line":228,"column":4},"end":{"line":228,"column":4}}]},"21":{"line":236,"type":"if","locations":[{"start":{"line":236,"column":4},"end":{"line":236,"column":4}},{"start":{"line":236,"column":4},"end":{"line":236,"column":4}}]},"22":{"line":259,"type":"if","locations":[{"start":{"line":259,"column":4},"end":{"line":259,"column":4}},{"start":{"line":259,"column":4},"end":{"line":259,"column":4}}]},"23":{"line":260,"type":"if","locations":[{"start":{"line":260,"column":4},"end":{"line":260,"column":4}},{"start":{"line":260,"column":4},"end":{"line":260,"column":4}}]},"24":{"line":262,"type":"if","locations":[{"start":{"line":262,"column":4},"end":{"line":262,"column":4}},{"start":{"line":262,"column":4},"end":{"line":262,"column":4}}]},"25":{"line":263,"type":"if","locations":[{"start":{"line":263,"column":6},"end":{"line":263,"column":6}},{"start":{"line":263,"column":6},"end":{"line":263,"column":6}}]},"26":{"line":264,"type":"if","locations":[{"start":{"line":264,"column":11},"end":{"line":264,"column":11}},{"start":{"line":264,"column":11},"end":{"line":264,"column":11}}]},"27":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":6},"end":{"line":265,"column":6}},{"start":{"line":265,"column":6},"end":{"line":265,"column":6}}]},"28":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":6},"end":{"line":273,"column":6}},{"start":{"line":273,"column":6},"end":{"line":273,"column":6}}]},"29":{"line":275,"type":"if","locations":[{"start":{"line":275,"column":6},"end":{"line":275,"column":6}},{"start":{"line":275,"column":6},"end":{"line":275,"column":6}}]},"30":{"line":306,"type":"if","locations":[{"start":{"line":306,"column":4},"end":{"line":306,"column":4}},{"start":{"line":306,"column":4},"end":{"line":306,"column":4}}]},"31":{"line":308,"type":"if","locations":[{"start":{"line":308,"column":4},"end":{"line":308,"column":4}},{"start":{"line":308,"column":4},"end":{"line":308,"column":4}}]},"32":{"line":328,"type":"if","locations":[{"start":{"line":328,"column":4},"end":{"line":328,"column":4}},{"start":{"line":328,"column":4},"end":{"line":328,"column":4}}]},"33":{"line":329,"type":"if","locations":[{"start":{"line":329,"column":4},"end":{"line":329,"column":4}},{"start":{"line":329,"column":4},"end":{"line":329,"column":4}}]},"34":{"line":349,"type":"if","locations":[{"start":{"line":349,"column":4},"end":{"line":349,"column":4}},{"start":{"line":349,"column":4},"end":{"line":349,"column":4}}]},"35":{"line":355,"type":"if","locations":[{"start":{"line":355,"column":4},"end":{"line":355,"column":4}},{"start":{"line":355,"column":4},"end":{"line":355,"column":4}}]},"36":{"line":366,"type":"if","locations":[{"start":{"line":366,"column":4},"end":{"line":366,"column":4}},{"start":{"line":366,"column":4},"end":{"line":366,"column":4}}]},"37":{"line":373,"type":"if","locations":[{"start":{"line":373,"column":4},"end":{"line":373,"column":4}},{"start":{"line":373,"column":4},"end":{"line":373,"column":4}}]},"38":{"line":402,"type":"if","locations":[{"start":{"line":402,"column":4},"end":{"line":402,"column":4}},{"start":{"line":402,"column":4},"end":{"line":402,"column":4}}]},"39":{"line":408,"type":"if","locations":[{"start":{"line":408,"column":4},"end":{"line":408,"column":4}},{"start":{"line":408,"column":4},"end":{"line":408,"column":4}}]},"40":{"line":417,"type":"if","locations":[{"start":{"line":417,"column":4},"end":{"line":417,"column":4}},{"start":{"line":417,"column":4},"end":{"line":417,"column":4}}]},"41":{"line":422,"type":"if","locations":[{"start":{"line":422,"column":6},"end":{"line":422,"column":6}},{"start":{"line":422,"column":6},"end":{"line":422,"column":6}}]},"42":{"line":430,"type":"if","locations":[{"start":{"line":430,"column":4},"end":{"line":430,"column":4}},{"start":{"line":430,"column":4},"end":{"line":430,"column":4}}]},"43":{"line":453,"type":"if","locations":[{"start":{"line":453,"column":4},"end":{"line":453,"column":4}},{"start":{"line":453,"column":4},"end":{"line":453,"column":4}}]},"44":{"line":461,"type":"if","locations":[{"start":{"line":461,"column":4},"end":{"line":461,"column":4}},{"start":{"line":461,"column":4},"end":{"line":461,"column":4}}]},"45":{"line":464,"type":"if","locations":[{"start":{"line":464,"column":4},"end":{"line":464,"column":4}},{"start":{"line":464,"column":4},"end":{"line":464,"column":4}}]}}},"contracts/libraries/math/MathUtils.sol":{"l":{"26":335,"28":335,"30":335,"52":675,"54":675,"55":93,"58":582,"60":582,"62":582,"64":582,"65":582,"67":582,"68":582,"70":582},"path":"/src/contracts/libraries/math/MathUtils.sol","s":{"1":335,"2":335,"3":335,"4":675,"5":675,"6":93,"7":582,"8":582,"9":582,"10":582,"11":582,"12":582,"13":582,"14":582},"b":{"1":[93,582]},"f":{"1":335,"2":675},"fnMap":{"1":{"name":"calculateLinearInterest","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"calculateCompoundedInterest","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":78}},"2":{"start":{"line":28,"column":4},"end":{"line":28,"column":85}},"3":{"start":{"line":30,"column":4},"end":{"line":30,"column":55}},"4":{"start":{"line":52,"column":4},"end":{"line":52,"column":67}},"5":{"start":{"line":54,"column":4},"end":{"line":54,"column":1957}},"6":{"start":{"line":55,"column":6},"end":{"line":55,"column":29}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":33}},"8":{"start":{"line":60,"column":4},"end":{"line":60,"column":47}},"9":{"start":{"line":62,"column":4},"end":{"line":62,"column":51}},"10":{"start":{"line":64,"column":4},"end":{"line":64,"column":62}},"11":{"start":{"line":65,"column":4},"end":{"line":65,"column":63}},"12":{"start":{"line":67,"column":4},"end":{"line":67,"column":67}},"13":{"start":{"line":68,"column":4},"end":{"line":68,"column":85}},"14":{"start":{"line":70,"column":4},"end":{"line":70,"column":86}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":54,"column":4}},{"start":{"line":54,"column":4},"end":{"line":54,"column":4}}]}}},"contracts/libraries/math/PercentageMath.sol":{"l":{"25":343,"26":148,"29":195,"31":195,"33":195,"35":195,"37":195,"47":58,"48":58,"50":58,"52":58,"54":58,"56":58,"58":58},"path":"/src/contracts/libraries/math/PercentageMath.sol","s":{"1":343,"2":148,"3":195,"4":195,"5":195,"6":195,"7":195,"8":58,"9":58,"10":58,"11":58,"12":58,"13":58,"14":58},"b":{"1":[148,195],"2":[195,0],"3":[195,0],"4":[58,0],"5":[58,0],"6":[58,0]},"f":{"1":343,"2":58},"fnMap":{"1":{"name":"percentMul","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"percentDiv","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":59,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":891}},"2":{"start":{"line":26,"column":6},"end":{"line":26,"column":14}},"3":{"start":{"line":29,"column":4},"end":{"line":29,"column":39}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":72}},"5":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"6":{"start":{"line":35,"column":4},"end":{"line":35,"column":60}},"7":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"8":{"start":{"line":47,"column":4},"end":{"line":47,"column":52}},"9":{"start":{"line":48,"column":4},"end":{"line":48,"column":43}},"10":{"start":{"line":50,"column":4},"end":{"line":50,"column":46}},"11":{"start":{"line":52,"column":4},"end":{"line":52,"column":79}},"12":{"start":{"line":54,"column":4},"end":{"line":54,"column":27}},"13":{"start":{"line":56,"column":4},"end":{"line":56,"column":62}},"14":{"start":{"line":58,"column":4},"end":{"line":58,"column":30}}},"branchMap":{"1":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":25,"column":4}},{"start":{"line":25,"column":4},"end":{"line":25,"column":4}}]},"2":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"3":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"4":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]},"5":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"6":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]}}},"contracts/libraries/math/SafeMath.sol":{"l":{"28":450,"29":450,"31":450,"44":124,"61":212,"62":211,"64":211,"80":0,"81":0,"84":0,"85":0,"87":0,"102":0,"122":0,"123":0,"126":0,"141":0,"160":0,"161":0},"path":"/src/contracts/libraries/math/SafeMath.sol","s":{"1":450,"2":450,"3":450,"4":124,"5":212,"6":211,"7":211,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0},"b":{"1":[450,0],"2":[211,1],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0]},"f":{"1":450,"2":124,"3":212,"4":0,"5":0,"6":0,"7":0,"8":0},"fnMap":{"1":{"name":"add","line":27,"loc":{"start":{"line":27,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"sub","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"sub","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":65,"column":2}}},"4":{"name":"mul","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":88,"column":2}}},"5":{"name":"div","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"6":{"name":"div","line":116,"loc":{"start":{"line":116,"column":2},"end":{"line":127,"column":2}}},"7":{"name":"mod","line":140,"loc":{"start":{"line":140,"column":2},"end":{"line":142,"column":2}}},"8":{"name":"mod","line":155,"loc":{"start":{"line":155,"column":2},"end":{"line":162,"column":2}}}},"statementMap":{"1":{"start":{"line":28,"column":4},"end":{"line":28,"column":21}},"2":{"start":{"line":29,"column":4},"end":{"line":29,"column":49}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":12}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":54}},"5":{"start":{"line":61,"column":4},"end":{"line":61,"column":32}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":21}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":12}},"8":{"start":{"line":80,"column":4},"end":{"line":80,"column":2341}},"9":{"start":{"line":81,"column":6},"end":{"line":81,"column":14}},"10":{"start":{"line":84,"column":4},"end":{"line":84,"column":21}},"11":{"start":{"line":85,"column":4},"end":{"line":85,"column":59}},"12":{"start":{"line":87,"column":4},"end":{"line":87,"column":12}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":50}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":31}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":21}},"16":{"start":{"line":126,"column":4},"end":{"line":126,"column":12}},"17":{"start":{"line":141,"column":4},"end":{"line":141,"column":48}},"18":{"start":{"line":160,"column":4},"end":{"line":160,"column":32}},"19":{"start":{"line":161,"column":4},"end":{"line":161,"column":16}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]},"2":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":61,"column":4}},{"start":{"line":61,"column":4},"end":{"line":61,"column":4}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":4},"end":{"line":80,"column":4}},{"start":{"line":80,"column":4},"end":{"line":80,"column":4}}]},"4":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"5":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]},"6":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]}}},"contracts/libraries/math/WadRayMath.sol":{"l":{"25":1047,"33":0,"40":0,"47":0,"57":0,"58":0,"61":0,"63":0,"65":0,"67":0,"69":0,"79":64,"81":64,"83":64,"85":64,"87":64,"89":64,"91":64,"101":4965,"102":1571,"105":3394,"107":3394,"109":3394,"111":3394,"113":3394,"123":1245,"125":1245,"127":1245,"129":1245,"131":1245,"133":1245,"135":1245,"144":0,"145":0,"146":0,"148":0,"157":1110,"158":1110,"159":1110},"path":"/src/contracts/libraries/math/WadRayMath.sol","s":{"1":1047,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":64,"13":64,"14":64,"15":64,"16":64,"17":64,"18":64,"19":4965,"20":1571,"21":3394,"22":3394,"23":3394,"24":3394,"25":3394,"26":1245,"27":1245,"28":1245,"29":1245,"30":1245,"31":1245,"32":1245,"33":0,"34":0,"35":0,"36":0,"37":1110,"38":1110,"39":1110},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[64,0],"5":[64,0],"6":[64,0],"7":[1571,3394],"8":[3394,0],"9":[3394,0],"10":[1245,0],"11":[1245,0],"12":[1245,0],"13":[0,0],"14":[1110,0]},"f":{"1":1047,"2":0,"3":0,"4":0,"5":0,"6":64,"7":4965,"8":1245,"9":0,"10":1110},"fnMap":{"1":{"name":"ray","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":2}}},"2":{"name":"wad","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"halfRay","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}},"4":{"name":"halfWad","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"5":{"name":"wadMul","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":70,"column":2}}},"6":{"name":"wadDiv","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"rayMul","line":100,"loc":{"start":{"line":100,"column":2},"end":{"line":114,"column":2}}},"8":{"name":"rayDiv","line":122,"loc":{"start":{"line":122,"column":2},"end":{"line":136,"column":2}}},"9":{"name":"rayToWad","line":143,"loc":{"start":{"line":143,"column":2},"end":{"line":149,"column":2}}},"10":{"name":"wadToRay","line":156,"loc":{"start":{"line":156,"column":2},"end":{"line":160,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":14}},"2":{"start":{"line":33,"column":4},"end":{"line":33,"column":14}},"3":{"start":{"line":40,"column":4},"end":{"line":40,"column":18}},"4":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}},"5":{"start":{"line":57,"column":4},"end":{"line":57,"column":1244}},"6":{"start":{"line":58,"column":6},"end":{"line":58,"column":14}},"7":{"start":{"line":61,"column":4},"end":{"line":61,"column":26}},"8":{"start":{"line":63,"column":4},"end":{"line":63,"column":59}},"9":{"start":{"line":65,"column":4},"end":{"line":65,"column":20}},"10":{"start":{"line":67,"column":4},"end":{"line":67,"column":55}},"11":{"start":{"line":69,"column":4},"end":{"line":69,"column":23}},"12":{"start":{"line":79,"column":4},"end":{"line":79,"column":43}},"13":{"start":{"line":81,"column":4},"end":{"line":81,"column":25}},"14":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"15":{"start":{"line":85,"column":4},"end":{"line":85,"column":61}},"16":{"start":{"line":87,"column":4},"end":{"line":87,"column":18}},"17":{"start":{"line":89,"column":4},"end":{"line":89,"column":53}},"18":{"start":{"line":91,"column":4},"end":{"line":91,"column":21}},"19":{"start":{"line":101,"column":4},"end":{"line":101,"column":2221}},"20":{"start":{"line":102,"column":6},"end":{"line":102,"column":14}},"21":{"start":{"line":105,"column":4},"end":{"line":105,"column":26}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":59}},"23":{"start":{"line":109,"column":4},"end":{"line":109,"column":20}},"24":{"start":{"line":111,"column":4},"end":{"line":111,"column":55}},"25":{"start":{"line":113,"column":4},"end":{"line":113,"column":23}},"26":{"start":{"line":123,"column":4},"end":{"line":123,"column":43}},"27":{"start":{"line":125,"column":4},"end":{"line":125,"column":25}},"28":{"start":{"line":127,"column":4},"end":{"line":127,"column":28}},"29":{"start":{"line":129,"column":4},"end":{"line":129,"column":61}},"30":{"start":{"line":131,"column":4},"end":{"line":131,"column":18}},"31":{"start":{"line":133,"column":4},"end":{"line":133,"column":53}},"32":{"start":{"line":135,"column":4},"end":{"line":135,"column":21}},"33":{"start":{"line":144,"column":4},"end":{"line":144,"column":41}},"34":{"start":{"line":145,"column":4},"end":{"line":145,"column":34}},"35":{"start":{"line":146,"column":4},"end":{"line":146,"column":57}},"36":{"start":{"line":148,"column":4},"end":{"line":148,"column":33}},"37":{"start":{"line":157,"column":4},"end":{"line":157,"column":38}},"38":{"start":{"line":158,"column":4},"end":{"line":158,"column":71}},"39":{"start":{"line":159,"column":4},"end":{"line":159,"column":17}}},"branchMap":{"1":{"line":57,"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":57,"column":4}},{"start":{"line":57,"column":4},"end":{"line":57,"column":4}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":63,"column":4}},{"start":{"line":63,"column":4},"end":{"line":63,"column":4}}]},"3":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"4":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":4}},{"start":{"line":79,"column":4},"end":{"line":79,"column":4}}]},"5":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"6":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":4}},{"start":{"line":89,"column":4},"end":{"line":89,"column":4}}]},"7":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":4},"end":{"line":101,"column":4}},{"start":{"line":101,"column":4},"end":{"line":101,"column":4}}]},"8":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":4},"end":{"line":107,"column":4}},{"start":{"line":107,"column":4},"end":{"line":107,"column":4}}]},"9":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"10":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":4},"end":{"line":123,"column":4}},{"start":{"line":123,"column":4},"end":{"line":123,"column":4}}]},"11":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":4},"end":{"line":129,"column":4}},{"start":{"line":129,"column":4},"end":{"line":129,"column":4}}]},"12":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":4}},{"start":{"line":133,"column":4},"end":{"line":133,"column":4}}]},"13":{"line":146,"type":"if","locations":[{"start":{"line":146,"column":4},"end":{"line":146,"column":4}},{"start":{"line":146,"column":4},"end":{"line":146,"column":4}}]},"14":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":4},"end":{"line":158,"column":4}},{"start":{"line":158,"column":4},"end":{"line":158,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol":{"l":{"26":0,"27":0,"34":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0},"b":{"1":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":21,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"_willFallback","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":79}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":20}},"3":{"start":{"line":34,"column":4},"end":{"line":34,"column":47}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":4},"end":{"line":26,"column":4}},{"start":{"line":26,"column":4},"end":{"line":26,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol":{"l":{"35":3,"36":3,"38":0,"46":0,"53":0,"62":0,"63":0,"64":0,"73":0,"90":3,"91":3,"92":3,"99":9901,"101":9901,"111":53,"113":53,"122":9898,"123":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":3,"10":3,"11":3,"12":9901,"13":53,"14":9898,"15":9898},"b":{"1":[3,0],"2":[0,0],"3":[3,0],"4":[9898,0]},"f":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":3,"7":9901,"8":53,"9":9898},"fnMap":{"1":{"name":"ifAdmin","line":34,"loc":{"start":{"line":34,"column":2},"end":{"line":40,"column":2}}},"2":{"name":"admin","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":47,"column":2}}},"3":{"name":"implementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":54,"column":2}}},"4":{"name":"changeAdmin","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"upgradeTo","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"upgradeToAndCall","line":88,"loc":{"start":{"line":85,"column":2},"end":{"line":93,"column":2}}},"7":{"name":"_admin","line":98,"loc":{"start":{"line":98,"column":2},"end":{"line":104,"column":2}}},"8":{"name":"_setAdmin","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":116,"column":2}}},"9":{"name":"_willFallback","line":121,"loc":{"start":{"line":121,"column":2},"end":{"line":124,"column":2}}}},"statementMap":{"1":{"start":{"line":35,"column":4},"end":{"line":35,"column":1284}},"2":{"start":{"line":38,"column":6},"end":{"line":38,"column":16}},"3":{"start":{"line":46,"column":4},"end":{"line":46,"column":19}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":28}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":92}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":41}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":22}},"8":{"start":{"line":73,"column":4},"end":{"line":73,"column":32}},"9":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"10":{"start":{"line":91,"column":4},"end":{"line":91,"column":59}},"11":{"start":{"line":92,"column":4},"end":{"line":92,"column":19}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":29}},"13":{"start":{"line":111,"column":4},"end":{"line":111,"column":29}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":88}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":24}}},"branchMap":{"1":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"2":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"3":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":4}},{"start":{"line":92,"column":4},"end":{"line":92,"column":4}}]},"4":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol":{"l":{"32":10004,"34":10004,"44":3,"45":3,"53":56,"58":56,"61":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol","s":{"1":10004,"2":3,"3":3,"4":56,"5":56},"b":{"1":[56,0]},"f":{"1":10004,"2":3,"3":56},"fnMap":{"1":{"name":"_implementation","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":37,"column":2}}},"2":{"name":"_upgradeTo","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"_setImplementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":64,"column":2}}}},"statementMap":{"1":{"start":{"line":32,"column":4},"end":{"line":32,"column":38}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":40}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":36}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":1706}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":38}}},"branchMap":{"1":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":53,"column":4}},{"start":{"line":53,"column":4},"end":{"line":53,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/Initializable.sol":{"l":{"31":0,"36":0,"37":0,"38":0,"39":0,"42":0,"44":0,"45":0,"56":0,"58":0,"61":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Initializable.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"initializer","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"isConstructor","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":62,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1056}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":39}},"3":{"start":{"line":37,"column":4},"end":{"line":37,"column":1228}},"4":{"start":{"line":38,"column":6},"end":{"line":38,"column":24}},"5":{"start":{"line":39,"column":6},"end":{"line":39,"column":23}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":1322}},"7":{"start":{"line":45,"column":6},"end":{"line":45,"column":25}},"8":{"start":{"line":56,"column":4},"end":{"line":56,"column":14}},"9":{"start":{"line":61,"column":4},"end":{"line":61,"column":18}}},"branchMap":{"1":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":4}},{"start":{"line":37,"column":4},"end":{"line":37,"column":4}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol":{"l":{"30":53,"31":53,"32":53,"33":53,"40":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":9898},"b":{"1":[53,0],"2":[53,0]},"f":{"1":53,"2":9898},"fnMap":{"1":{"name":"initialize","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"_willFallback","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":43}},"2":{"start":{"line":31,"column":4},"end":{"line":31,"column":59}},"3":{"start":{"line":32,"column":4},"end":{"line":32,"column":79}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":19}},"5":{"start":{"line":40,"column":4},"end":{"line":40,"column":47}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":4},"end":{"line":30,"column":4}},{"start":{"line":30,"column":4},"end":{"line":30,"column":4}}]},"2":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":4}},{"start":{"line":32,"column":4},"end":{"line":32,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol":{"l":{"21":53,"22":53,"23":53,"24":53,"25":53,"26":53},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":53,"6":53},"b":{"1":[53,0],"2":[53,0],"3":[53,0],"4":[53,0]},"f":{"1":53},"fnMap":{"1":{"name":"initialize","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":43}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":97}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":29}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":1119}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":51}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":22,"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":22,"column":4}},{"start":{"line":22,"column":4},"end":{"line":22,"column":4}}]},"3":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":4},"end":{"line":24,"column":4}},{"start":{"line":24,"column":4},"end":{"line":24,"column":4}}]},"4":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":6},"end":{"line":26,"column":6}},{"start":{"line":26,"column":6},"end":{"line":26,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/Proxy.sol":{"l":{"17":9898,"33":9898,"69":9898,"70":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Proxy.sol","s":{"1":9898,"2":9898,"3":9898},"b":{},"f":{"1":9898,"2":9898,"3":9898,"4":9898},"fnMap":{"1":{"name":null,"line":16,"loc":{"start":{"line":16,"column":2},"end":{"line":18,"column":2}}},"2":{"name":"_delegate","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":55,"column":2}}},"3":{"name":"_willFallback","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":45}}},"4":{"name":"_fallback","line":68,"loc":{"start":{"line":68,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":17,"column":4},"end":{"line":17,"column":14}},"2":{"start":{"line":69,"column":4},"end":{"line":69,"column":18}},"3":{"start":{"line":70,"column":4},"end":{"line":70,"column":31}}},"branchMap":{}},"contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol":{"l":{"21":0,"22":0,"23":0,"24":0,"25":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":27,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":97}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":29}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":1038}},"4":{"start":{"line":24,"column":6},"end":{"line":24,"column":51}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":4}},{"start":{"line":23,"column":4},"end":{"line":23,"column":4}}]},"3":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":6},"end":{"line":25,"column":6}},{"start":{"line":25,"column":6},"end":{"line":25,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol":{"l":{"33":56,"34":56,"39":56,"40":56,"41":56,"42":56,"45":56,"47":56,"48":56,"63":56,"65":56,"68":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol","s":{"1":56,"2":56,"3":56,"4":56,"5":56,"6":56,"7":56,"8":56,"9":56,"10":56},"b":{"1":[56,0],"2":[56,0],"3":[56,0]},"f":{"1":56,"2":56},"fnMap":{"1":{"name":"initializer","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":50,"column":2}}},"2":{"name":"isConstructor","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":69,"column":2}}}},"statementMap":{"1":{"start":{"line":33,"column":4},"end":{"line":33,"column":36}},"2":{"start":{"line":34,"column":4},"end":{"line":34,"column":1202}},"3":{"start":{"line":39,"column":4},"end":{"line":39,"column":39}},"4":{"start":{"line":40,"column":4},"end":{"line":40,"column":1396}},"5":{"start":{"line":41,"column":6},"end":{"line":41,"column":24}},"6":{"start":{"line":42,"column":6},"end":{"line":42,"column":39}},"7":{"start":{"line":47,"column":4},"end":{"line":47,"column":1506}},"8":{"start":{"line":48,"column":6},"end":{"line":48,"column":25}},"9":{"start":{"line":63,"column":4},"end":{"line":63,"column":14}},"10":{"start":{"line":68,"column":4},"end":{"line":68,"column":18}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]}}},"contracts/misc/AaveProtocolTestHelpers.sol":{"l":{"18":3,"22":1,"23":1,"24":1,"25":1,"26":17,"33":1,"37":2,"38":2,"39":2,"40":2,"41":34,"42":34,"47":2},"path":"/src/contracts/misc/AaveProtocolTestHelpers.sol","s":{"1":3,"2":1,"3":1,"4":1,"5":1,"6":17,"7":1,"8":2,"9":2,"10":2,"11":2,"12":34,"13":34,"14":2},"b":{},"f":{"1":3,"2":1,"3":2},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}},"2":{"name":"getAllReservesTokens","line":21,"loc":{"start":{"line":21,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"getAllATokens","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":48,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":41}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":73}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":50}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":72}},"5":{"start":{"line":25,"column":4},"end":{"line":25,"column":904}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":961}},"7":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"8":{"start":{"line":37,"column":4},"end":{"line":37,"column":73}},"9":{"start":{"line":38,"column":4},"end":{"line":38,"column":50}},"10":{"start":{"line":39,"column":4},"end":{"line":39,"column":65}},"11":{"start":{"line":40,"column":4},"end":{"line":40,"column":1486}},"12":{"start":{"line":41,"column":6},"end":{"line":41,"column":79}},"13":{"start":{"line":42,"column":6},"end":{"line":42,"column":1624}},"14":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}}},"branchMap":{}},"contracts/misc/Address.sol":{"l":{"29":99,"30":99,"32":99,"35":99,"55":0,"58":0,"59":0},"path":"/src/contracts/misc/Address.sol","s":{"1":99,"2":99,"3":99,"4":0,"5":0,"6":0},"b":{"1":[0,0],"2":[0,0]},"f":{"1":99,"2":0},"fnMap":{"1":{"name":"isContract","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":36,"column":2}}},"2":{"name":"sendValue","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":60,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":20}},"2":{"start":{"line":30,"column":4},"end":{"line":30,"column":92}},"3":{"start":{"line":35,"column":4},"end":{"line":35,"column":55}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":76}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":56}},"6":{"start":{"line":59,"column":4},"end":{"line":59,"column":81}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":4},"end":{"line":59,"column":4}},{"start":{"line":59,"column":4},"end":{"line":59,"column":4}}]}}},"contracts/misc/ChainlinkProxyPriceProvider.sol":{"l":{"37":3,"38":3,"48":0,"55":0,"62":3,"63":3,"64":72,"65":72,"72":3,"73":3,"79":0,"81":0,"82":0,"84":0,"85":0,"86":0,"88":0,"96":0,"97":0,"98":0,"100":0,"107":0,"113":0},"path":"/src/contracts/misc/ChainlinkProxyPriceProvider.sol","s":{"1":3,"2":3,"3":0,"4":0,"5":3,"6":3,"7":72,"8":72,"9":3,"10":3,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0},"b":{"1":[3,0],"2":[0,0],"3":[0,0]},"f":{"1":3,"2":0,"3":0,"4":3,"5":3,"6":0,"7":0,"8":0,"9":0},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setAssetSources","line":46,"loc":{"start":{"line":44,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"setFallbackOracle","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"_setAssetsSources","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"_setFallbackOracle","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"getAssetPrice","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"getAssetsPrices","line":95,"loc":{"start":{"line":95,"column":2},"end":{"line":101,"column":2}}},"8":{"name":"getSourceOfAsset","line":106,"loc":{"start":{"line":106,"column":2},"end":{"line":108,"column":2}}},"9":{"name":"getFallbackOracle","line":112,"loc":{"start":{"line":112,"column":2},"end":{"line":114,"column":2}}}},"statementMap":{"1":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"2":{"start":{"line":38,"column":4},"end":{"line":38,"column":37}},"3":{"start":{"line":48,"column":4},"end":{"line":48,"column":37}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":37}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":73}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":2670}},"7":{"start":{"line":64,"column":6},"end":{"line":64,"column":64}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":52}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":55}},"10":{"start":{"line":73,"column":4},"end":{"line":73,"column":46}},"11":{"start":{"line":79,"column":4},"end":{"line":79,"column":54}},"12":{"start":{"line":81,"column":4},"end":{"line":81,"column":3446}},"13":{"start":{"line":82,"column":6},"end":{"line":82,"column":49}},"14":{"start":{"line":84,"column":6},"end":{"line":84,"column":64}},"15":{"start":{"line":85,"column":6},"end":{"line":85,"column":3621}},"16":{"start":{"line":86,"column":8},"end":{"line":86,"column":29}},"17":{"start":{"line":88,"column":8},"end":{"line":88,"column":51}},"18":{"start":{"line":96,"column":4},"end":{"line":96,"column":58}},"19":{"start":{"line":97,"column":4},"end":{"line":97,"column":4032}},"20":{"start":{"line":98,"column":6},"end":{"line":98,"column":41}},"21":{"start":{"line":100,"column":4},"end":{"line":100,"column":17}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"23":{"start":{"line":113,"column":4},"end":{"line":113,"column":35}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"2":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":81,"column":4}},{"start":{"line":81,"column":4},"end":{"line":81,"column":4}}]},"3":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":6},"end":{"line":85,"column":6}},{"start":{"line":85,"column":6},"end":{"line":85,"column":6}}]}}},"contracts/misc/Context.sol":{"l":{"16":4,"20":0,"21":0},"path":"/src/contracts/misc/Context.sol","s":{"1":4,"2":0},"b":{},"f":{"1":4,"2":0},"fnMap":{"1":{"name":"_msgSender","line":15,"loc":{"start":{"line":15,"column":2},"end":{"line":17,"column":2}}},"2":{"name":"_msgData","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":22,"column":2}}}},"statementMap":{"1":{"start":{"line":16,"column":4},"end":{"line":16,"column":21}},"2":{"start":{"line":21,"column":4},"end":{"line":21,"column":19}}},"branchMap":{}},"contracts/misc/IERC20DetailedBytes.sol":{"l":{},"path":"/src/contracts/misc/IERC20DetailedBytes.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/misc/SafeERC20.sol":{"l":{"27":99,"36":0,"44":0,"48":0,"52":99,"55":99,"56":99,"58":97,"61":97},"path":"/src/contracts/misc/SafeERC20.sol","s":{"1":99,"2":0,"3":0,"4":0,"5":99,"6":99,"7":99,"8":97,"9":97},"b":{"1":[0,0],"2":[99,0],"3":[97,2],"4":[97,0],"5":[97,0]},"f":{"1":99,"2":0,"3":0,"4":99},"fnMap":{"1":{"name":"safeTransfer","line":22,"loc":{"start":{"line":22,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"safeTransferFrom","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":37,"column":2}}},"3":{"name":"safeApprove","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"callOptionalReturn","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":63,"column":2}}}},"statementMap":{"1":{"start":{"line":27,"column":4},"end":{"line":27,"column":88}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":98}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1254}},"4":{"start":{"line":48,"column":4},"end":{"line":48,"column":92}},"5":{"start":{"line":52,"column":4},"end":{"line":52,"column":74}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":71}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":55}},"8":{"start":{"line":58,"column":4},"end":{"line":58,"column":1845}},"9":{"start":{"line":61,"column":6},"end":{"line":61,"column":90}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]},"4":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":4}},{"start":{"line":58,"column":4},"end":{"line":58,"column":4}}]},"5":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":6}},{"start":{"line":61,"column":6},"end":{"line":61,"column":6}}]}}},"contracts/misc/WalletBalanceProvider.sol":{"l":{"26":3,"34":0,"45":0,"46":0,"48":0,"63":0,"65":0,"66":0,"67":0,"68":0,"69":0,"71":0,"76":0,"87":0,"89":0,"91":0,"93":0,"94":0,"96":0,"97":0,"98":0,"100":0,"103":0},"path":"/src/contracts/misc/WalletBalanceProvider.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0]},"f":{"1":3,"2":0,"3":0,"4":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":27,"column":2}}},"2":{"name":"balanceOf","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"batchBalanceOf","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":77,"column":2}}},"4":{"name":"getUserWalletBalances","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":104,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":4},"end":{"line":45,"column":1672}},"3":{"start":{"line":46,"column":6},"end":{"line":46,"column":42}},"4":{"start":{"line":48,"column":6},"end":{"line":48,"column":14}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":75}},"6":{"start":{"line":65,"column":4},"end":{"line":65,"column":2271}},"7":{"start":{"line":66,"column":6},"end":{"line":66,"column":2324}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":43}},"9":{"start":{"line":68,"column":8},"end":{"line":68,"column":2425}},"10":{"start":{"line":69,"column":10},"end":{"line":69,"column":32}},"11":{"start":{"line":71,"column":10},"end":{"line":71,"column":63}},"12":{"start":{"line":76,"column":4},"end":{"line":76,"column":19}},"13":{"start":{"line":87,"column":4},"end":{"line":87,"column":64}},"14":{"start":{"line":89,"column":4},"end":{"line":89,"column":50}},"15":{"start":{"line":91,"column":4},"end":{"line":91,"column":62}},"16":{"start":{"line":93,"column":4},"end":{"line":93,"column":3026}},"17":{"start":{"line":94,"column":6},"end":{"line":94,"column":89}},"18":{"start":{"line":96,"column":6},"end":{"line":96,"column":3174}},"19":{"start":{"line":97,"column":8},"end":{"line":97,"column":22}},"20":{"start":{"line":100,"column":6},"end":{"line":100,"column":47}},"21":{"start":{"line":103,"column":4},"end":{"line":103,"column":31}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"3":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":68,"column":8}},{"start":{"line":68,"column":8},"end":{"line":68,"column":8}}]},"4":{"line":96,"type":"if","locations":[{"start":{"line":96,"column":6},"end":{"line":96,"column":6}},{"start":{"line":96,"column":6},"end":{"line":96,"column":6}}]}}},"contracts/tokenization/AToken.sol":{"l":{"45":211,"46":207,"57":54,"58":54,"59":54,"63":17,"71":17,"74":17,"78":17,"88":17,"89":17,"90":17,"104":42,"107":41,"110":41,"111":41,"126":105,"129":105,"130":105,"134":0,"137":0,"138":0,"155":2,"170":641,"180":333,"195":0,"205":3,"207":3,"208":0,"211":3,"219":0,"229":4,"245":58,"246":56,"268":6,"270":5,"271":3,"272":3,"279":3,"280":0,"281":0,"298":6,"299":4,"302":4,"304":4,"306":4,"320":4,"327":0},"path":"/src/contracts/tokenization/AToken.sol","s":{"1":211,"2":54,"3":54,"4":54,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":42,"12":41,"13":41,"14":41,"15":105,"16":105,"17":105,"18":0,"19":0,"20":0,"21":2,"22":641,"23":333,"24":0,"25":3,"26":3,"27":0,"28":3,"29":0,"30":4,"31":58,"32":56,"33":6,"34":5,"35":3,"36":3,"37":3,"38":0,"39":0,"40":6,"41":4,"42":4,"43":4,"44":4,"45":4},"b":{"1":[207,4],"2":[0,3],"3":[5,1],"4":[3,2],"5":[0,3],"6":[4,2],"7":[2,2]},"f":{"1":211,"2":54,"3":17,"4":17,"5":42,"6":105,"7":0,"8":2,"9":641,"10":333,"11":0,"12":3,"13":0,"14":4,"15":58,"16":6,"17":6,"18":4},"fnMap":{"1":{"name":"onlyLendingPool","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"constructor","line":56,"loc":{"start":{"line":49,"column":2},"end":{"line":60,"column":2}}},"3":{"name":"getRevision","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"initialize","line":70,"loc":{"start":{"line":66,"column":2},"end":{"line":91,"column":2}}},"5":{"name":"burn","line":103,"loc":{"start":{"line":98,"column":2},"end":{"line":112,"column":2}}},"6":{"name":"mint","line":124,"loc":{"start":{"line":120,"column":2},"end":{"line":131,"column":2}}},"7":{"name":"mintToTreasury","line":133,"loc":{"start":{"line":133,"column":2},"end":{"line":139,"column":2}}},"8":{"name":"transferOnLiquidation","line":152,"loc":{"start":{"line":148,"column":2},"end":{"line":156,"column":2}}},"9":{"name":"balanceOf","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":171,"column":2}}},"10":{"name":"scaledBalanceOf","line":179,"loc":{"start":{"line":179,"column":2},"end":{"line":181,"column":2}}},"11":{"name":"getScaledUserBalanceAndSupply","line":189,"loc":{"start":{"line":189,"column":2},"end":{"line":196,"column":2}}},"12":{"name":"totalSupply","line":204,"loc":{"start":{"line":204,"column":2},"end":{"line":212,"column":2}}},"13":{"name":"scaledTotalSupply","line":218,"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":2}}},"14":{"name":"isTransferAllowed","line":228,"loc":{"start":{"line":228,"column":2},"end":{"line":230,"column":2}}},"15":{"name":"transferUnderlyingTo","line":242,"loc":{"start":{"line":239,"column":2},"end":{"line":247,"column":2}}},"16":{"name":"permit","line":259,"loc":{"start":{"line":259,"column":2},"end":{"line":282,"column":2}}},"17":{"name":"_transfer","line":292,"loc":{"start":{"line":292,"column":2},"end":{"line":307,"column":2}}},"18":{"name":"_transfer","line":315,"loc":{"start":{"line":315,"column":2},"end":{"line":321,"column":2}}}},"statementMap":{"1":{"start":{"line":45,"column":4},"end":{"line":45,"column":75}},"2":{"start":{"line":57,"column":4},"end":{"line":57,"column":14}},"3":{"start":{"line":58,"column":4},"end":{"line":58,"column":52}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":52}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":26}},"6":{"start":{"line":71,"column":4},"end":{"line":71,"column":19}},"7":{"start":{"line":78,"column":4},"end":{"line":78,"column":2480}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":22}},"9":{"start":{"line":89,"column":4},"end":{"line":89,"column":26}},"10":{"start":{"line":90,"column":4},"end":{"line":90,"column":40}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":36}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":78}},"13":{"start":{"line":110,"column":4},"end":{"line":110,"column":43}},"14":{"start":{"line":111,"column":4},"end":{"line":111,"column":62}},"15":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}},"16":{"start":{"line":129,"column":4},"end":{"line":129,"column":43}},"17":{"start":{"line":130,"column":4},"end":{"line":130,"column":34}},"18":{"start":{"line":134,"column":4},"end":{"line":134,"column":53}},"19":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"20":{"start":{"line":138,"column":4},"end":{"line":138,"column":54}},"21":{"start":{"line":155,"column":4},"end":{"line":155,"column":36}},"22":{"start":{"line":170,"column":4},"end":{"line":170,"column":98}},"23":{"start":{"line":180,"column":4},"end":{"line":180,"column":32}},"24":{"start":{"line":195,"column":4},"end":{"line":195,"column":55}},"25":{"start":{"line":205,"column":4},"end":{"line":205,"column":53}},"26":{"start":{"line":207,"column":4},"end":{"line":207,"column":6560}},"27":{"start":{"line":208,"column":6},"end":{"line":208,"column":14}},"28":{"start":{"line":211,"column":4},"end":{"line":211,"column":96}},"29":{"start":{"line":219,"column":4},"end":{"line":219,"column":30}},"30":{"start":{"line":229,"column":4},"end":{"line":229,"column":78}},"31":{"start":{"line":245,"column":4},"end":{"line":245,"column":64}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":17}},"33":{"start":{"line":268,"column":4},"end":{"line":268,"column":48}},"34":{"start":{"line":270,"column":4},"end":{"line":270,"column":61}},"35":{"start":{"line":271,"column":4},"end":{"line":271,"column":46}},"36":{"start":{"line":272,"column":4},"end":{"line":272,"column":8691}},"37":{"start":{"line":279,"column":4},"end":{"line":279,"column":68}},"38":{"start":{"line":280,"column":4},"end":{"line":280,"column":44}},"39":{"start":{"line":281,"column":4},"end":{"line":281,"column":34}},"40":{"start":{"line":298,"column":4},"end":{"line":298,"column":9504}},"41":{"start":{"line":299,"column":6},"end":{"line":299,"column":74}},"42":{"start":{"line":302,"column":4},"end":{"line":302,"column":77}},"43":{"start":{"line":304,"column":4},"end":{"line":304,"column":50}},"44":{"start":{"line":306,"column":4},"end":{"line":306,"column":49}},"45":{"start":{"line":320,"column":4},"end":{"line":320,"column":36}}},"branchMap":{"1":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"4":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"5":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":4},"end":{"line":279,"column":4}},{"start":{"line":279,"column":4},"end":{"line":279,"column":4}}]},"6":{"line":298,"type":"if","locations":[{"start":{"line":298,"column":4},"end":{"line":298,"column":4}},{"start":{"line":298,"column":4},"end":{"line":298,"column":4}}]},"7":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":6},"end":{"line":299,"column":6}},{"start":{"line":299,"column":6},"end":{"line":299,"column":6}}]}}},"contracts/tokenization/base/DebtTokenBase.sol":{"l":{"29":99,"30":95,"44":108,"45":108,"59":36,"60":36,"61":36,"65":0,"73":0,"74":0,"75":0,"85":0,"86":0,"87":0,"91":0,"92":0,"93":0,"101":0,"102":0,"103":0,"104":0,"113":0,"114":0,"115":0,"124":0,"125":0,"126":0},"path":"/src/contracts/tokenization/base/DebtTokenBase.sol","s":{"1":99,"2":108,"3":108,"4":36,"5":36,"6":36,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0},"b":{"1":[95,4]},"f":{"1":99,"2":108,"3":36,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},"fnMap":{"1":{"name":"onlyLendingPool","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"constructor","line":43,"loc":{"start":{"line":37,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"initialize","line":58,"loc":{"start":{"line":54,"column":2},"end":{"line":62,"column":2}}},"4":{"name":"underlyingAssetAddress","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"5":{"name":"transfer","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"allowance","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":88,"column":2}}},"7":{"name":"approve","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"transferFrom","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":105,"column":2}}},"9":{"name":"increaseAllowance","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":116,"column":2}}},"10":{"name":"decreaseAllowance","line":118,"loc":{"start":{"line":118,"column":2},"end":{"line":127,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":75}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":28}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":44}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":17}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":21}},"6":{"start":{"line":61,"column":4},"end":{"line":61,"column":25}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":27}},"8":{"start":{"line":75,"column":4},"end":{"line":75,"column":35}},"9":{"start":{"line":87,"column":4},"end":{"line":87,"column":36}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":35}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":35}},"12":{"start":{"line":115,"column":4},"end":{"line":115,"column":36}},"13":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]}}},"contracts/tokenization/IncentivizedERC20.sol":{"l":{"34":162,"35":162,"36":162,"37":162,"44":67,"51":88,"58":0,"65":2318,"72":2652,"82":4,"83":2,"84":2,"100":4,"109":0,"110":0,"125":0,"126":0,"131":0,"132":0,"142":0,"143":0,"157":0,"165":0,"173":4,"174":4,"176":4,"178":4,"179":4,"180":4,"181":4,"183":4,"184":0,"185":0,"186":0,"187":0,"193":131,"195":131,"197":131,"198":131,"200":131,"201":131,"203":131,"204":0,"209":67,"211":67,"213":67,"214":67,"216":67,"217":67,"219":66,"220":0,"229":0,"230":0,"232":0,"233":0,"237":54,"241":54,"245":54},"path":"/src/contracts/tokenization/IncentivizedERC20.sol","s":{"1":162,"2":162,"3":162,"4":162,"5":67,"6":88,"7":0,"8":2318,"9":2652,"10":4,"11":2,"12":2,"13":4,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":4,"25":4,"26":4,"27":4,"28":4,"29":4,"30":4,"31":4,"32":0,"33":0,"34":0,"35":0,"36":131,"37":131,"38":131,"39":131,"40":131,"41":131,"42":131,"43":0,"44":67,"45":67,"46":67,"47":67,"48":67,"49":67,"50":66,"51":0,"52":0,"53":0,"54":0,"55":0,"56":54,"57":54,"58":54},"b":{"1":[4,0],"2":[4,0],"3":[0,4],"4":[0,0],"5":[131,0],"6":[0,131],"7":[67,0],"8":[0,66],"9":[0,0],"10":[0,0]},"f":{"1":162,"2":67,"3":88,"4":0,"5":2318,"6":2652,"7":4,"8":4,"9":0,"10":0,"11":0,"12":0,"13":4,"14":131,"15":67,"16":0,"17":54,"18":54,"19":54,"20":202},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"name","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"symbol","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":2}}},"4":{"name":"decimals","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":59,"column":2}}},"5":{"name":"totalSupply","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"7":{"name":"transfer","line":81,"loc":{"start":{"line":81,"column":2},"end":{"line":85,"column":2}}},"8":{"name":"allowance","line":93,"loc":{"start":{"line":93,"column":2},"end":{"line":101,"column":2}}},"9":{"name":"approve","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":111,"column":2}}},"10":{"name":"transferFrom","line":120,"loc":{"start":{"line":120,"column":2},"end":{"line":133,"column":2}}},"11":{"name":"increaseAllowance","line":141,"loc":{"start":{"line":141,"column":2},"end":{"line":144,"column":2}}},"12":{"name":"decreaseAllowance","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":166,"column":2}}},"13":{"name":"_transfer","line":168,"loc":{"start":{"line":168,"column":2},"end":{"line":190,"column":2}}},"14":{"name":"_mint","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":206,"column":2}}},"15":{"name":"_burn","line":208,"loc":{"start":{"line":208,"column":2},"end":{"line":222,"column":2}}},"16":{"name":"_approve","line":224,"loc":{"start":{"line":224,"column":2},"end":{"line":234,"column":2}}},"17":{"name":"_setName","line":236,"loc":{"start":{"line":236,"column":2},"end":{"line":238,"column":2}}},"18":{"name":"_setSymbol","line":240,"loc":{"start":{"line":240,"column":2},"end":{"line":242,"column":2}}},"19":{"name":"_setDecimals","line":244,"loc":{"start":{"line":244,"column":2},"end":{"line":246,"column":2}}},"20":{"name":"_beforeTokenTransfer","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":252,"column":22}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":15}},"2":{"start":{"line":35,"column":4},"end":{"line":35,"column":19}},"3":{"start":{"line":36,"column":4},"end":{"line":36,"column":23}},"4":{"start":{"line":37,"column":4},"end":{"line":37,"column":74}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":16}},"6":{"start":{"line":51,"column":4},"end":{"line":51,"column":18}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":20}},"8":{"start":{"line":65,"column":4},"end":{"line":65,"column":23}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":29}},"10":{"start":{"line":82,"column":4},"end":{"line":82,"column":45}},"11":{"start":{"line":83,"column":4},"end":{"line":83,"column":48}},"12":{"start":{"line":84,"column":4},"end":{"line":84,"column":15}},"13":{"start":{"line":100,"column":4},"end":{"line":100,"column":38}},"14":{"start":{"line":109,"column":4},"end":{"line":109,"column":42}},"15":{"start":{"line":110,"column":4},"end":{"line":110,"column":15}},"16":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":3648}},"18":{"start":{"line":131,"column":4},"end":{"line":131,"column":44}},"19":{"start":{"line":132,"column":4},"end":{"line":132,"column":15}},"20":{"start":{"line":142,"column":4},"end":{"line":142,"column":86}},"21":{"start":{"line":143,"column":4},"end":{"line":143,"column":15}},"22":{"start":{"line":157,"column":4},"end":{"line":157,"column":4675}},"23":{"start":{"line":165,"column":4},"end":{"line":165,"column":15}},"24":{"start":{"line":173,"column":4},"end":{"line":173,"column":73}},"25":{"start":{"line":174,"column":4},"end":{"line":174,"column":74}},"26":{"start":{"line":176,"column":4},"end":{"line":176,"column":50}},"27":{"start":{"line":178,"column":4},"end":{"line":178,"column":48}},"28":{"start":{"line":179,"column":4},"end":{"line":179,"column":93}},"29":{"start":{"line":180,"column":4},"end":{"line":180,"column":54}},"30":{"start":{"line":181,"column":4},"end":{"line":181,"column":58}},"31":{"start":{"line":183,"column":4},"end":{"line":183,"column":5459}},"32":{"start":{"line":184,"column":6},"end":{"line":184,"column":40}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":78}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":5642}},"35":{"start":{"line":187,"column":8},"end":{"line":187,"column":86}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":68}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":52}},"38":{"start":{"line":197,"column":4},"end":{"line":197,"column":41}},"39":{"start":{"line":198,"column":4},"end":{"line":198,"column":44}},"40":{"start":{"line":200,"column":4},"end":{"line":200,"column":50}},"41":{"start":{"line":201,"column":4},"end":{"line":201,"column":53}},"42":{"start":{"line":203,"column":4},"end":{"line":203,"column":6176}},"43":{"start":{"line":204,"column":6},"end":{"line":204,"column":83}},"44":{"start":{"line":209,"column":4},"end":{"line":209,"column":70}},"45":{"start":{"line":211,"column":4},"end":{"line":211,"column":52}},"46":{"start":{"line":213,"column":4},"end":{"line":213,"column":41}},"47":{"start":{"line":214,"column":4},"end":{"line":214,"column":44}},"48":{"start":{"line":216,"column":4},"end":{"line":216,"column":50}},"49":{"start":{"line":217,"column":4},"end":{"line":217,"column":91}},"50":{"start":{"line":219,"column":4},"end":{"line":219,"column":6766}},"51":{"start":{"line":220,"column":6},"end":{"line":220,"column":83}},"52":{"start":{"line":229,"column":4},"end":{"line":229,"column":71}},"53":{"start":{"line":230,"column":4},"end":{"line":230,"column":71}},"54":{"start":{"line":232,"column":4},"end":{"line":232,"column":39}},"55":{"start":{"line":233,"column":4},"end":{"line":233,"column":41}},"56":{"start":{"line":237,"column":4},"end":{"line":237,"column":18}},"57":{"start":{"line":241,"column":4},"end":{"line":241,"column":22}},"58":{"start":{"line":245,"column":4},"end":{"line":245,"column":26}}},"branchMap":{"1":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"2":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":4},"end":{"line":174,"column":4}},{"start":{"line":174,"column":4},"end":{"line":174,"column":4}}]},"3":{"line":183,"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":183,"column":4}},{"start":{"line":183,"column":4},"end":{"line":183,"column":4}}]},"4":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":6},"end":{"line":186,"column":6}},{"start":{"line":186,"column":6},"end":{"line":186,"column":6}}]},"5":{"line":193,"type":"if","locations":[{"start":{"line":193,"column":4},"end":{"line":193,"column":4}},{"start":{"line":193,"column":4},"end":{"line":193,"column":4}}]},"6":{"line":203,"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":203,"column":4}},{"start":{"line":203,"column":4},"end":{"line":203,"column":4}}]},"7":{"line":209,"type":"if","locations":[{"start":{"line":209,"column":4},"end":{"line":209,"column":4}},{"start":{"line":209,"column":4},"end":{"line":209,"column":4}}]},"8":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":4},"end":{"line":219,"column":4}},{"start":{"line":219,"column":4},"end":{"line":219,"column":4}}]},"9":{"line":229,"type":"if","locations":[{"start":{"line":229,"column":4},"end":{"line":229,"column":4}},{"start":{"line":229,"column":4},"end":{"line":229,"column":4}}]},"10":{"line":230,"type":"if","locations":[{"start":{"line":230,"column":4},"end":{"line":230,"column":4}},{"start":{"line":230,"column":4},"end":{"line":230,"column":4}}]}}},"contracts/tokenization/interfaces/IAToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IAToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IScaledBalanceToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IScaledBalanceToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IStableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IStableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IVariableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IVariableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/StableDebtToken.sol":{"l":{"39":17,"47":363,"55":343,"64":343,"72":488,"73":488,"74":488,"75":366,"77":122,"81":122,"104":27,"107":27,"114":27,"115":27,"116":27,"118":27,"121":27,"126":27,"127":27,"131":27,"134":27,"139":27,"142":27,"144":27,"160":17,"167":17,"173":17,"174":8,"175":8,"177":9,"178":9,"184":17,"185":11,"186":11,"190":6,"193":17,"195":17,"196":0,"198":17,"202":17,"204":17,"222":44,"224":44,"225":22,"229":22,"231":22,"242":331,"243":331,"250":235,"251":235,"258":414,"265":331,"274":343,"284":980,"286":980,"287":781,"290":199,"295":199,"306":27,"307":27,"309":27,"310":0,"322":17,"323":17,"325":17,"326":0},"path":"/src/contracts/tokenization/StableDebtToken.sol","s":{"1":17,"2":363,"3":343,"4":343,"5":488,"6":488,"7":488,"8":366,"9":122,"10":122,"11":27,"12":27,"13":27,"14":27,"15":27,"16":27,"17":27,"18":27,"19":27,"20":27,"21":27,"22":27,"23":27,"24":27,"25":17,"26":17,"27":17,"28":8,"29":8,"30":9,"31":9,"32":17,"33":11,"34":11,"35":6,"36":17,"37":17,"38":0,"39":17,"40":17,"41":17,"42":44,"43":44,"44":22,"45":22,"46":22,"47":331,"48":331,"49":235,"50":235,"51":414,"52":331,"53":343,"54":980,"55":980,"56":781,"57":199,"58":199,"59":27,"60":27,"61":27,"62":0,"63":17,"64":17,"65":17,"66":0},"b":{"1":[366,122],"2":[27,0],"3":[8,9],"4":[11,6],"5":[0,17],"6":[22,22],"7":[781,199],"8":[0,27],"9":[0,17]},"f":{"1":54,"2":17,"3":363,"4":343,"5":343,"6":488,"7":27,"8":17,"9":44,"10":331,"11":235,"12":414,"13":331,"14":343,"15":980,"16":27,"17":17},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":2},"end":{"line":32,"column":85}}},"2":{"name":"getRevision","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":2}}},"3":{"name":"getAverageStableRate","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"4":{"name":"getUserLastUpdated","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"5":{"name":"getUserStableRate","line":63,"loc":{"start":{"line":63,"column":2},"end":{"line":65,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":82,"column":2}}},"7":{"name":"mint","line":103,"loc":{"start":{"line":99,"column":2},"end":{"line":152,"column":2}}},"8":{"name":"burn","line":159,"loc":{"start":{"line":159,"column":2},"end":{"line":205,"column":2}}},"9":{"name":"_calculateBalanceIncrease","line":213,"loc":{"start":{"line":213,"column":2},"end":{"line":236,"column":2}}},"10":{"name":"getSupplyData","line":241,"loc":{"start":{"line":241,"column":2},"end":{"line":244,"column":2}}},"11":{"name":"getTotalSupplyAndAvgRate","line":249,"loc":{"start":{"line":249,"column":2},"end":{"line":252,"column":2}}},"12":{"name":"totalSupply","line":257,"loc":{"start":{"line":257,"column":2},"end":{"line":259,"column":2}}},"13":{"name":"getTotalSupplyLastUpdated","line":264,"loc":{"start":{"line":264,"column":2},"end":{"line":266,"column":2}}},"14":{"name":"principalBalanceOf","line":273,"loc":{"start":{"line":273,"column":2},"end":{"line":275,"column":2}}},"15":{"name":"_calcTotalSupply","line":283,"loc":{"start":{"line":283,"column":2},"end":{"line":296,"column":2}}},"16":{"name":"_mint","line":304,"loc":{"start":{"line":304,"column":3},"end":{"line":312,"column":2}}},"17":{"name":"_burn","line":320,"loc":{"start":{"line":320,"column":2},"end":{"line":328,"column":2}}}},"statementMap":{"1":{"start":{"line":39,"column":4},"end":{"line":39,"column":30}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":25}},"3":{"start":{"line":55,"column":4},"end":{"line":55,"column":28}},"4":{"start":{"line":64,"column":4},"end":{"line":64,"column":27}},"5":{"start":{"line":72,"column":4},"end":{"line":72,"column":53}},"6":{"start":{"line":73,"column":4},"end":{"line":73,"column":44}},"7":{"start":{"line":74,"column":4},"end":{"line":74,"column":2428}},"8":{"start":{"line":75,"column":6},"end":{"line":75,"column":14}},"9":{"start":{"line":77,"column":4},"end":{"line":77,"column":2482}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":51}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":29}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":3360}},"13":{"start":{"line":114,"column":4},"end":{"line":114,"column":38}},"14":{"start":{"line":115,"column":4},"end":{"line":115,"column":45}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":67}},"16":{"start":{"line":118,"column":4},"end":{"line":118,"column":39}},"17":{"start":{"line":121,"column":4},"end":{"line":121,"column":3848}},"18":{"start":{"line":126,"column":4},"end":{"line":126,"column":79}},"19":{"start":{"line":127,"column":4},"end":{"line":127,"column":40}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":70}},"21":{"start":{"line":134,"column":4},"end":{"line":134,"column":4342}},"22":{"start":{"line":139,"column":4},"end":{"line":139,"column":64}},"23":{"start":{"line":142,"column":4},"end":{"line":142,"column":43}},"24":{"start":{"line":144,"column":4},"end":{"line":144,"column":4640}},"25":{"start":{"line":160,"column":4},"end":{"line":160,"column":5054}},"26":{"start":{"line":167,"column":4},"end":{"line":167,"column":42}},"27":{"start":{"line":173,"column":4},"end":{"line":173,"column":5510}},"28":{"start":{"line":174,"column":6},"end":{"line":174,"column":23}},"29":{"start":{"line":175,"column":6},"end":{"line":175,"column":21}},"30":{"start":{"line":177,"column":7},"end":{"line":177,"column":69}},"31":{"start":{"line":178,"column":6},"end":{"line":178,"column":5715}},"32":{"start":{"line":184,"column":4},"end":{"line":184,"column":5865}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":25}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":26}},"35":{"start":{"line":190,"column":6},"end":{"line":190,"column":48}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":50}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":6147}},"38":{"start":{"line":196,"column":6},"end":{"line":196,"column":61}},"39":{"start":{"line":198,"column":6},"end":{"line":198,"column":61}},"40":{"start":{"line":202,"column":4},"end":{"line":202,"column":43}},"41":{"start":{"line":204,"column":4},"end":{"line":204,"column":81}},"42":{"start":{"line":222,"column":4},"end":{"line":222,"column":60}},"43":{"start":{"line":224,"column":4},"end":{"line":224,"column":7006}},"44":{"start":{"line":225,"column":6},"end":{"line":225,"column":22}},"45":{"start":{"line":229,"column":4},"end":{"line":229,"column":75}},"46":{"start":{"line":231,"column":4},"end":{"line":231,"column":7228}},"47":{"start":{"line":242,"column":4},"end":{"line":242,"column":36}},"48":{"start":{"line":243,"column":4},"end":{"line":243,"column":91}},"49":{"start":{"line":250,"column":4},"end":{"line":250,"column":36}},"50":{"start":{"line":251,"column":4},"end":{"line":251,"column":47}},"51":{"start":{"line":258,"column":4},"end":{"line":258,"column":43}},"52":{"start":{"line":265,"column":4},"end":{"line":265,"column":32}},"53":{"start":{"line":274,"column":4},"end":{"line":274,"column":32}},"54":{"start":{"line":284,"column":4},"end":{"line":284,"column":49}},"55":{"start":{"line":286,"column":4},"end":{"line":286,"column":8975}},"56":{"start":{"line":287,"column":6},"end":{"line":287,"column":14}},"57":{"start":{"line":290,"column":4},"end":{"line":290,"column":9031}},"58":{"start":{"line":295,"column":4},"end":{"line":295,"column":52}},"59":{"start":{"line":306,"column":4},"end":{"line":306,"column":50}},"60":{"start":{"line":307,"column":4},"end":{"line":307,"column":53}},"61":{"start":{"line":309,"column":4},"end":{"line":309,"column":9637}},"62":{"start":{"line":310,"column":6},"end":{"line":310,"column":83}},"63":{"start":{"line":322,"column":4},"end":{"line":322,"column":50}},"64":{"start":{"line":323,"column":4},"end":{"line":323,"column":91}},"65":{"start":{"line":325,"column":4},"end":{"line":325,"column":10249}},"66":{"start":{"line":326,"column":6},"end":{"line":326,"column":83}}},"branchMap":{"1":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":74,"column":4}},{"start":{"line":74,"column":4},"end":{"line":74,"column":4}}]},"2":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":126,"column":4}},{"start":{"line":126,"column":4},"end":{"line":126,"column":4}}]},"3":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"4":{"line":184,"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":184,"column":4}},{"start":{"line":184,"column":4},"end":{"line":184,"column":4}}]},"5":{"line":195,"type":"if","locations":[{"start":{"line":195,"column":4},"end":{"line":195,"column":4}},{"start":{"line":195,"column":4},"end":{"line":195,"column":4}}]},"6":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"7":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"8":{"line":309,"type":"if","locations":[{"start":{"line":309,"column":4},"end":{"line":309,"column":4}},{"start":{"line":309,"column":4},"end":{"line":309,"column":4}}]},"9":{"line":325,"type":"if","locations":[{"start":{"line":325,"column":4},"end":{"line":325,"column":4}},{"start":{"line":325,"column":4},"end":{"line":325,"column":4}}]}}},"contracts/tokenization/VariableDebtToken.sol":{"l":{"34":17,"42":460,"44":460,"45":324,"48":136,"63":26,"65":26,"66":26,"79":25,"81":25,"82":25,"90":343,"98":673,"106":331,"116":0},"path":"/src/contracts/tokenization/VariableDebtToken.sol","s":{"1":17,"2":460,"3":460,"4":324,"5":136,"6":26,"7":26,"8":26,"9":25,"10":25,"11":25,"12":343,"13":673,"14":331,"15":0},"b":{"1":[324,136]},"f":{"1":54,"2":17,"3":460,"4":26,"5":25,"6":343,"7":673,"8":331,"9":0},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":21,"column":2},"end":{"line":27,"column":85}}},"2":{"name":"getRevision","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}},"3":{"name":"balanceOf","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"mint","line":61,"loc":{"start":{"line":57,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"burn","line":78,"loc":{"start":{"line":74,"column":2},"end":{"line":83,"column":2}}},"6":{"name":"scaledBalanceOf","line":89,"loc":{"start":{"line":89,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"totalSupply","line":97,"loc":{"start":{"line":97,"column":2},"end":{"line":99,"column":2}}},"8":{"name":"scaledTotalSupply","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"9":{"name":"getScaledUserBalanceAndSupply","line":115,"loc":{"start":{"line":115,"column":2},"end":{"line":117,"column":2}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":30}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":49}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1484}},"4":{"start":{"line":45,"column":6},"end":{"line":45,"column":14}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":88}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":36}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"8":{"start":{"line":66,"column":4},"end":{"line":66,"column":34}},"9":{"start":{"line":79,"column":4},"end":{"line":79,"column":36}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":43}},"11":{"start":{"line":82,"column":4},"end":{"line":82,"column":34}},"12":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"13":{"start":{"line":98,"column":4},"end":{"line":98,"column":94}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":30}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":55}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}}} \ No newline at end of file diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index 147135a2..b86785bd 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -317,6 +317,15 @@ export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress ); }; +export const getLendingPoolAddressesProviderRegistry = async (address?: tEthereumAddress) => { + return await getContract( + eContractid.LendingPoolAddressesProviderRegistry, + address || + (await getDb().get(`${eContractid.LendingPoolAddressesProviderRegistry}.${BRE.network.name}`).value()) + .address + ); +}; + export const getLendingPoolConfiguratorProxy = async (address?: tEthereumAddress) => { return await getContract( eContractid.LendingPoolConfigurator, diff --git a/test/addresses-provider-registry.spec.ts b/test/addresses-provider-registry.spec.ts new file mode 100644 index 00000000..a3af01de --- /dev/null +++ b/test/addresses-provider-registry.spec.ts @@ -0,0 +1,23 @@ +import {TestEnv, makeSuite} from './helpers/make-suite'; +import {RAY, APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants'; +import {convertToCurrencyDecimals} from '../helpers/contracts-helpers'; +import {ProtocolErrors} from '../helpers/types'; + +const {expect} = require('chai'); + +makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { + + it('Checks the addresses provider is added to the registry', async () => { + + const {addressesProvider, registry} = testEnv; + + const providers = await registry.getAddressesProvidersList(); + + expect(providers.length).to.be.equal(1, "Invalid length of the addresses providers list"); + expect(providers[1].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); + + }); + + +}); + diff --git a/test/helpers/make-suite.ts b/test/helpers/make-suite.ts index a0787a17..2a5bf6f6 100644 --- a/test/helpers/make-suite.ts +++ b/test/helpers/make-suite.ts @@ -9,7 +9,7 @@ import { getMintableErc20, getLendingPoolConfiguratorProxy, getPriceOracle, - getMockSwapAdapter, + getMockSwapAdapter, getLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-helpers'; import {tEthereumAddress} from '../../helpers/types'; import {LendingPool} from '../../types/LendingPool'; @@ -25,6 +25,7 @@ import {almostEqual} from './almost-equal'; import {PriceOracle} from '../../types/PriceOracle'; import {LendingPoolAddressesProvider} from '../../types/LendingPoolAddressesProvider'; import { MockSwapAdapter } from '../../types/MockSwapAdapter'; +import { LendingPoolAddressesProviderRegistry } from '../../types/LendingPoolAddressesProviderRegistry'; chai.use(bignumberChai()); chai.use(almostEqual()); @@ -47,6 +48,7 @@ export interface TestEnv { lend: MintableErc20; addressesProvider: LendingPoolAddressesProvider; mockSwapAdapter: MockSwapAdapter; + registry: LendingPoolAddressesProviderRegistry; } let buidlerevmSnapshotId: string = '0x1'; @@ -70,7 +72,8 @@ const testEnv: TestEnv = { usdc: {} as MintableErc20, lend: {} as MintableErc20, addressesProvider: {} as LendingPoolAddressesProvider, - mockSwapAdapter: {} as MockSwapAdapter + mockSwapAdapter: {} as MockSwapAdapter, + registry: {} as LendingPoolAddressesProviderRegistry } as TestEnv; export async function initializeMakeSuite() { @@ -95,6 +98,7 @@ export async function initializeMakeSuite() { testEnv.oracle = await getPriceOracle(); testEnv.addressesProvider = await getLendingPoolAddressesProvider(); + testEnv.registry = await getLendingPoolAddressesProviderRegistry(); testEnv.helpersContract = await getAaveProtocolTestHelpers(); From 2a5547570c274990ea2aeb9cec86bf466f598572 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 11:25:35 +0200 Subject: [PATCH 51/79] Adds another addresses provider test --- test/addresses-provider-registry.spec.ts | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/addresses-provider-registry.spec.ts b/test/addresses-provider-registry.spec.ts index a3af01de..651789e5 100644 --- a/test/addresses-provider-registry.spec.ts +++ b/test/addresses-provider-registry.spec.ts @@ -18,6 +18,45 @@ makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { }); + it('Checks the addresses provider is added to the registry', async () => { + + const {addressesProvider, registry} = testEnv; + + const providers = await registry.getAddressesProvidersList(); + + expect(providers.length).to.be.equal(1, "Invalid length of the addresses providers list"); + expect(providers[1].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); + + }); + + it('Registers a new mock addresses provider', async () => { + + const {users, registry} = testEnv; + + //simulating an addresses provider using the users[1] wallet address + await registry.registerAddressesProvider(users[1].address, "2"); + + const providers = await registry.getAddressesProvidersList(); + + expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list"); + expect(providers[2].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list"); + + }); + + it('Registers a new mock addresses provider', async () => { + + const {users, registry} = testEnv; + + //simulating an addresses provider using the users[1] wallet address + await registry.registerAddressesProvider(users[1].address, "2"); + + const providers = await registry.getAddressesProvidersList(); + + expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list"); + expect(providers[2].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list"); + + }); + }); From 7c892ec4ba658fbb9a5389efc6147e97a65f3125 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 12:34:53 +0200 Subject: [PATCH 52/79] added test on removal of an addresses provider --- test/__setup.spec.ts | 2 +- test/addresses-provider-registry.spec.ts | 33 ++++++++++-------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/test/__setup.spec.ts b/test/__setup.spec.ts index d1613e22..42934f7c 100644 --- a/test/__setup.spec.ts +++ b/test/__setup.spec.ts @@ -363,7 +363,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => { const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry(); await waitForTx( - await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 0) + await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 1) ); const lendingPoolImpl = await deployLendingPool(); diff --git a/test/addresses-provider-registry.spec.ts b/test/addresses-provider-registry.spec.ts index 651789e5..37a0978e 100644 --- a/test/addresses-provider-registry.spec.ts +++ b/test/addresses-provider-registry.spec.ts @@ -1,5 +1,5 @@ import {TestEnv, makeSuite} from './helpers/make-suite'; -import {RAY, APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants'; +import {RAY, APPROVAL_AMOUNT_LENDING_POOL, ZERO_ADDRESS} from '../helpers/constants'; import {convertToCurrencyDecimals} from '../helpers/contracts-helpers'; import {ProtocolErrors} from '../helpers/types'; @@ -14,20 +14,10 @@ makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { const providers = await registry.getAddressesProvidersList(); expect(providers.length).to.be.equal(1, "Invalid length of the addresses providers list"); - expect(providers[1].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); + expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); }); - it('Checks the addresses provider is added to the registry', async () => { - - const {addressesProvider, registry} = testEnv; - - const providers = await registry.getAddressesProvidersList(); - - expect(providers.length).to.be.equal(1, "Invalid length of the addresses providers list"); - expect(providers[1].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); - - }); it('Registers a new mock addresses provider', async () => { @@ -39,24 +29,27 @@ makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { const providers = await registry.getAddressesProvidersList(); expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list"); - expect(providers[2].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list"); + expect(providers[1].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list"); }); - it('Registers a new mock addresses provider', async () => { + it('Removes the mock addresses provider', async () => { - const {users, registry} = testEnv; + const {users, registry, addressesProvider} = testEnv; - //simulating an addresses provider using the users[1] wallet address - await registry.registerAddressesProvider(users[1].address, "2"); + //checking the isAddressesProviderRegistered function + const id = await registry.isAddressesProviderRegistered(users[1].address); + + expect(id).to.be.equal("2", "Invalid isRegistered return value"); + + await registry.unregisterAddressesProvider(users[1].address); const providers = await registry.getAddressesProvidersList(); expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list"); - expect(providers[2].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list"); + expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); + expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, " Invalid addresses"); }); - - }); From 7c6034db674a75d27d58abfb30317ae2cbedf465 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 12:57:48 +0200 Subject: [PATCH 53/79] Fixes the flashloan transferFrom() --- contracts/lendingpool/LendingPool.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 95af83b1..d16d6ec3 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -575,7 +575,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage vars.amountPlusPremium = amount.add(vars.premium); if (debtMode == ReserveLogic.InterestRateMode.NONE) { - IERC20(asset).transferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium); + IERC20(asset).safeTransferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium); reserve.updateState(); reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium); From d724d1f58f88537d05c55d7661d80e87a6f87ffb Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 14:39:17 +0200 Subject: [PATCH 54/79] Fixed comment --- contracts/lendingpool/LendingPool.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index d16d6ec3..6afb3eed 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -583,7 +583,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode); } else { - // If the transfer didn't succeed, the receiver either didn't return the funds, or didn't approve the transfer. + //if the user didn't choose to return the funds, the system checks if there + //is enough collateral and eventually open a position _executeBorrow( ExecuteBorrowParams( asset, From 4e25657731da17bd854707a0ef0f52823add0b81 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 15:19:21 +0200 Subject: [PATCH 55/79] Updated transferFrom in repayWithCollateral() and swapLiquidity() --- contracts/lendingpool/LendingPoolCollateralManager.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/lendingpool/LendingPoolCollateralManager.sol b/contracts/lendingpool/LendingPoolCollateralManager.sol index fab8b71f..fad590be 100644 --- a/contracts/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/lendingpool/LendingPoolCollateralManager.sol @@ -404,7 +404,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor vars.actualAmountToLiquidate, 0 ); - IERC20(principal).transferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate); + IERC20(principal).safeTransferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( @@ -504,7 +504,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor vars.amountToReceive = IERC20(toAsset).balanceOf(receiverAddress); if (vars.amountToReceive != 0) { - IERC20(toAsset).transferFrom( + IERC20(toAsset).safeTransferFrom( receiverAddress, address(vars.toReserveAToken), vars.amountToReceive From 7be723c773a05ec31027d77a552ac03fc2676d84 Mon Sep 17 00:00:00 2001 From: The3D Date: Wed, 23 Sep 2020 17:59:43 +0200 Subject: [PATCH 56/79] Adds 100% test coverage to the addressesProviderRegistry --- coverage.json | 2 +- test/addresses-provider-registry.spec.ts | 38 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/coverage.json b/coverage.json index a6a2eaab..5c8fd1d4 100644 --- a/coverage.json +++ b/coverage.json @@ -1 +1 @@ -{"contracts/configuration/LendingPoolAddressesProvider.sol":{"l":{"38":9,"46":1,"47":1,"55":119,"63":1,"64":1,"75":37,"83":1,"84":1,"93":124,"97":1,"98":1,"102":168,"106":1,"107":1,"111":234,"115":1,"116":1,"125":2,"127":2,"130":2,"132":2,"133":2,"134":2,"135":2,"136":2,"138":0},"path":"/src/contracts/configuration/LendingPoolAddressesProvider.sol","s":{"1":9,"2":1,"3":1,"4":119,"5":1,"6":1,"7":37,"8":1,"9":1,"10":124,"11":1,"12":1,"13":168,"14":1,"15":1,"16":234,"17":1,"18":1,"19":2,"20":2,"21":2,"22":2,"23":2,"24":2,"25":2,"26":2,"27":0},"b":{"1":[2,0]},"f":{"1":9,"2":1,"3":119,"4":1,"5":37,"6":1,"7":124,"8":1,"9":168,"10":1,"11":234,"12":1,"13":2},"fnMap":{"1":{"name":"getLendingPool","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setLendingPoolImpl","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":48,"column":2}}},"3":{"name":"getLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"setLendingPoolConfiguratorImpl","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"getLendingPoolCollateralManager","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"setLendingPoolCollateralManager","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":85,"column":2}}},"7":{"name":"getAaveAdmin","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"setAaveAdmin","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":99,"column":2}}},"9":{"name":"getPriceOracle","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"10":{"name":"setPriceOracle","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":108,"column":2}}},"11":{"name":"getLendingRateOracle","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":112,"column":2}}},"12":{"name":"setLendingRateOracle","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":117,"column":2}}},"13":{"name":"_updateImpl","line":124,"loc":{"start":{"line":124,"column":2},"end":{"line":140,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":35}},"2":{"start":{"line":46,"column":4},"end":{"line":46,"column":34}},"3":{"start":{"line":47,"column":4},"end":{"line":47,"column":33}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":48}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":55}},"6":{"start":{"line":64,"column":4},"end":{"line":64,"column":53}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":54}},"8":{"start":{"line":83,"column":4},"end":{"line":83,"column":56}},"9":{"start":{"line":84,"column":4},"end":{"line":84,"column":53}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":33}},"11":{"start":{"line":97,"column":4},"end":{"line":97,"column":37}},"12":{"start":{"line":98,"column":4},"end":{"line":98,"column":36}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":35}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":41}},"15":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"16":{"start":{"line":111,"column":4},"end":{"line":111,"column":42}},"17":{"start":{"line":115,"column":4},"end":{"line":115,"column":54}},"18":{"start":{"line":116,"column":4},"end":{"line":116,"column":52}},"19":{"start":{"line":125,"column":4},"end":{"line":125,"column":58}},"20":{"start":{"line":127,"column":4},"end":{"line":127,"column":4874}},"21":{"start":{"line":130,"column":4},"end":{"line":130,"column":87}},"22":{"start":{"line":132,"column":4},"end":{"line":132,"column":5078}},"23":{"start":{"line":133,"column":6},"end":{"line":133,"column":56}},"24":{"start":{"line":134,"column":6},"end":{"line":134,"column":56}},"25":{"start":{"line":135,"column":6},"end":{"line":135,"column":36}},"26":{"start":{"line":136,"column":6},"end":{"line":136,"column":43}},"27":{"start":{"line":138,"column":6},"end":{"line":138,"column":47}}},"branchMap":{"1":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":132,"column":4}},{"start":{"line":132,"column":4},"end":{"line":132,"column":4}}]}}},"contracts/configuration/LendingPoolAddressesProviderRegistry.sol":{"l":{"31":0,"39":0,"41":0,"43":0,"44":0,"45":0,"49":0,"57":1,"58":1,"59":1,"67":0,"68":0,"69":0,"77":1,"78":0,"79":0,"83":1},"path":"/src/contracts/configuration/LendingPoolAddressesProviderRegistry.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":1,"9":1,"10":1,"11":0,"12":0,"13":0,"14":1,"15":0,"16":0,"17":1},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0,"2":0,"3":1,"4":0,"5":1},"fnMap":{"1":{"name":"isAddressesProviderRegistered","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"getAddressesProvidersList","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"registerAddressesProvider","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":60,"column":2}}},"4":{"name":"unregisterAddressesProvider","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":2}}},"5":{"name":"_addToAddressesProvidersList","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":84,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":39}},"2":{"start":{"line":39,"column":4},"end":{"line":39,"column":53}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":63}},"4":{"start":{"line":43,"column":4},"end":{"line":43,"column":1323}},"5":{"start":{"line":44,"column":6},"end":{"line":44,"column":1393}},"6":{"start":{"line":45,"column":8},"end":{"line":45,"column":53}},"7":{"start":{"line":49,"column":4},"end":{"line":49,"column":26}},"8":{"start":{"line":57,"column":4},"end":{"line":57,"column":36}},"9":{"start":{"line":58,"column":4},"end":{"line":58,"column":41}},"10":{"start":{"line":59,"column":4},"end":{"line":59,"column":46}},"11":{"start":{"line":67,"column":4},"end":{"line":67,"column":76}},"12":{"start":{"line":68,"column":4},"end":{"line":68,"column":35}},"13":{"start":{"line":69,"column":4},"end":{"line":69,"column":48}},"14":{"start":{"line":77,"column":4},"end":{"line":77,"column":2552}},"15":{"start":{"line":78,"column":6},"end":{"line":78,"column":2622}},"16":{"start":{"line":79,"column":8},"end":{"line":79,"column":14}},"17":{"start":{"line":83,"column":4},"end":{"line":83,"column":40}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":6},"end":{"line":44,"column":6}},{"start":{"line":44,"column":6},"end":{"line":44,"column":6}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":6},"end":{"line":78,"column":6}},{"start":{"line":78,"column":6},"end":{"line":78,"column":6}}]}}},"contracts/flashloan/base/FlashLoanReceiverBase.sol":{"l":{"18":3},"path":"/src/contracts/flashloan/base/FlashLoanReceiverBase.sol","s":{"1":3},"b":{},"f":{"1":3},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":32}}},"branchMap":{}},"contracts/flashloan/interfaces/IFlashLoanReceiver.sol":{"l":{},"path":"/src/contracts/flashloan/interfaces/IFlashLoanReceiver.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/lendingpool/DefaultReserveInterestRateStrategy.sol":{"l":{"62":51,"63":51,"64":51,"65":51,"66":51,"67":51,"75":0,"79":0,"83":0,"87":0,"91":0,"95":7,"137":234,"139":234,"140":234,"141":234,"142":234,"144":234,"148":234,"151":234,"152":4,"156":4,"160":4,"164":230,"167":230,"172":234,"181":234,"198":234,"200":234,"202":86,"206":86,"210":86,"214":86},"path":"/src/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":0,"8":0,"9":0,"10":0,"11":0,"12":7,"13":234,"14":234,"15":234,"16":234,"17":234,"18":234,"19":234,"20":234,"21":4,"22":4,"23":4,"24":230,"25":230,"26":234,"27":234,"28":234,"29":234,"30":148,"31":86,"32":86,"33":86,"34":86},"b":{"1":[4,230],"2":[148,86]},"f":{"1":51,"2":0,"3":0,"4":0,"5":0,"6":0,"7":7,"8":234,"9":234},"fnMap":{"1":{"name":"constructor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":68,"column":2}}},"2":{"name":"variableRateSlope1","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"variableRateSlope2","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":80,"column":2}}},"4":{"name":"stableRateSlope1","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":84,"column":2}}},"5":{"name":"stableRateSlope2","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":88,"column":2}}},"6":{"name":"baseVariableBorrowRate","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"getMaxVariableBorrowRate","line":94,"loc":{"start":{"line":94,"column":2},"end":{"line":96,"column":2}}},"8":{"name":"calculateInterestRates","line":119,"loc":{"start":{"line":119,"column":2},"end":{"line":182,"column":2}}},"9":{"name":"_getOverallBorrowRate","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":215,"column":2}}}},"statementMap":{"1":{"start":{"line":62,"column":4},"end":{"line":62,"column":31}},"2":{"start":{"line":63,"column":4},"end":{"line":63,"column":51}},"3":{"start":{"line":64,"column":4},"end":{"line":64,"column":43}},"4":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"5":{"start":{"line":66,"column":4},"end":{"line":66,"column":39}},"6":{"start":{"line":67,"column":4},"end":{"line":67,"column":39}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":30}},"8":{"start":{"line":79,"column":4},"end":{"line":79,"column":30}},"9":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"10":{"start":{"line":87,"column":4},"end":{"line":87,"column":28}},"11":{"start":{"line":91,"column":4},"end":{"line":91,"column":34}},"12":{"start":{"line":95,"column":4},"end":{"line":95,"column":84}},"13":{"start":{"line":137,"column":4},"end":{"line":137,"column":42}},"14":{"start":{"line":139,"column":4},"end":{"line":139,"column":61}},"15":{"start":{"line":140,"column":4},"end":{"line":140,"column":37}},"16":{"start":{"line":141,"column":4},"end":{"line":141,"column":35}},"17":{"start":{"line":142,"column":4},"end":{"line":142,"column":32}},"18":{"start":{"line":144,"column":4},"end":{"line":144,"column":5183}},"19":{"start":{"line":148,"column":4},"end":{"line":148,"column":5283}},"20":{"start":{"line":151,"column":4},"end":{"line":151,"column":5387}},"21":{"start":{"line":152,"column":6},"end":{"line":152,"column":5446}},"22":{"start":{"line":156,"column":6},"end":{"line":156,"column":5584}},"23":{"start":{"line":160,"column":6},"end":{"line":160,"column":5749}},"24":{"start":{"line":164,"column":6},"end":{"line":164,"column":5927}},"25":{"start":{"line":167,"column":6},"end":{"line":167,"column":6090}},"26":{"start":{"line":172,"column":4},"end":{"line":172,"column":6320}},"27":{"start":{"line":181,"column":4},"end":{"line":181,"column":100}},"28":{"start":{"line":198,"column":4},"end":{"line":198,"column":65}},"29":{"start":{"line":200,"column":4},"end":{"line":200,"column":35}},"30":{"start":{"line":200,"column":27},"end":{"line":200,"column":35}},"31":{"start":{"line":202,"column":4},"end":{"line":202,"column":7483}},"32":{"start":{"line":206,"column":4},"end":{"line":206,"column":7595}},"33":{"start":{"line":210,"column":4},"end":{"line":210,"column":7708}},"34":{"start":{"line":214,"column":4},"end":{"line":214,"column":28}}},"branchMap":{"1":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":4},"end":{"line":151,"column":4}},{"start":{"line":151,"column":4},"end":{"line":151,"column":4}}]},"2":{"line":200,"type":"if","locations":[{"start":{"line":200,"column":4},"end":{"line":200,"column":4}},{"start":{"line":200,"column":4},"end":{"line":200,"column":4}}]}}},"contracts/lendingpool/LendingPool.sol":{"l":{"55":118,"68":300,"72":1,"81":1,"97":105,"98":104,"100":104,"102":102,"104":102,"105":102,"107":102,"108":102,"109":94,"112":102,"115":102,"117":102,"126":26,"127":25,"129":25,"131":25,"133":25,"136":25,"137":19,"140":25,"150":22,"152":22,"154":22,"155":19,"158":22,"160":22,"177":3,"194":5,"195":4,"197":3,"198":3,"217":62,"218":61,"220":61,"221":4,"223":4,"229":59,"257":21,"259":20,"261":20,"263":20,"266":20,"270":20,"271":5,"274":20,"283":17,"286":17,"287":9,"289":8,"296":17,"297":17,"299":17,"300":12,"303":17,"305":17,"314":5,"315":4,"317":4,"319":4,"321":4,"329":2,"331":2,"333":1,"334":1,"341":1,"346":1,"353":2,"355":2,"367":8,"369":7,"371":7,"372":7,"373":7,"375":7,"378":7,"379":7,"380":7,"387":7,"388":7,"394":7,"401":1,"403":1,"404":1,"406":1,"408":1,"418":8,"419":7,"421":7,"430":6,"432":6,"433":2,"435":4,"455":11,"456":10,"459":10,"469":10,"471":10,"473":10,"475":5,"499":21,"500":20,"501":18,"503":18,"506":18,"517":18,"519":16,"521":16,"522":5,"525":11,"555":14,"556":13,"557":13,"559":13,"561":13,"563":13,"565":11,"567":11,"570":11,"573":9,"575":9,"577":9,"578":5,"580":3,"581":3,"582":3,"584":3,"587":4,"617":10,"618":9,"621":9,"631":9,"633":7,"635":7,"636":5,"662":97,"664":97,"689":710,"691":710,"715":363,"717":363,"744":21,"758":21,"781":343,"783":343,"784":343,"785":343,"786":343,"787":343,"788":343,"789":343,"792":343,"796":3,"800":0,"816":17,"817":17,"823":17,"836":0,"837":0,"841":75,"842":75,"851":75,"872":63,"873":63,"875":63,"877":63,"881":63,"894":50,"895":50,"896":37,"899":50,"902":50,"904":50,"907":25,"909":25,"915":25,"922":50,"929":50,"930":47,"933":50,"950":17,"951":17,"952":17,"953":136,"954":0,"956":17,"957":17,"958":17,"968":648,"982":809,"997":4,"998":3,"1015":26,"1017":26,"1018":26,"1019":13,"1021":13,"1029":0},"path":"/src/contracts/lendingpool/LendingPool.sol","s":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":104,"7":104,"8":102,"9":102,"10":102,"11":102,"12":102,"13":94,"14":102,"15":102,"16":102,"17":26,"18":25,"19":25,"20":25,"21":25,"22":25,"23":19,"24":25,"25":22,"26":22,"27":22,"28":19,"29":22,"30":22,"31":3,"32":5,"33":4,"34":3,"35":3,"36":62,"37":61,"38":61,"39":4,"40":4,"41":59,"42":21,"43":20,"44":20,"45":20,"46":20,"47":20,"48":5,"49":20,"50":17,"51":17,"52":9,"53":8,"54":17,"55":17,"56":17,"57":12,"58":17,"59":17,"60":5,"61":4,"62":4,"63":4,"64":4,"65":2,"66":2,"67":1,"68":1,"69":1,"70":1,"71":2,"72":2,"73":8,"74":7,"75":7,"76":7,"77":7,"78":7,"79":7,"80":7,"81":7,"82":7,"83":7,"84":7,"85":1,"86":1,"87":1,"88":1,"89":1,"90":8,"91":7,"92":7,"93":6,"94":6,"95":2,"96":4,"97":11,"98":10,"99":10,"100":10,"101":10,"102":10,"103":5,"104":21,"105":20,"106":18,"107":18,"108":18,"109":18,"110":16,"111":16,"112":5,"113":11,"114":14,"115":13,"116":13,"117":13,"118":13,"119":13,"120":11,"121":11,"122":11,"123":9,"124":9,"125":9,"126":5,"127":3,"128":3,"129":3,"130":3,"131":4,"132":10,"133":9,"134":9,"135":9,"136":7,"137":7,"138":5,"139":97,"140":97,"141":710,"142":710,"143":363,"144":363,"145":21,"146":21,"147":343,"148":343,"149":343,"150":343,"151":343,"152":343,"153":343,"154":343,"155":343,"156":3,"157":17,"158":17,"159":17,"160":0,"161":0,"162":75,"163":75,"164":75,"165":63,"166":63,"167":63,"168":63,"169":63,"170":50,"171":50,"172":37,"173":50,"174":50,"175":50,"176":25,"177":25,"178":25,"179":50,"180":50,"181":47,"182":50,"183":17,"184":17,"185":17,"186":136,"187":0,"188":17,"189":17,"190":17,"191":648,"192":809,"193":4,"194":3,"195":26,"196":26,"197":26,"198":13,"199":13,"200":0},"b":{"1":[118,0],"2":[287,13],"3":[94,8],"4":[19,6],"5":[19,3],"6":[4,57],"7":[5,15],"8":[9,8],"9":[12,5],"10":[1,1],"11":[1,6],"12":[2,4],"13":[10,0],"14":[5,5],"15":[18,2],"16":[16,2],"17":[5,11],"18":[5,4],"19":[7,2],"20":[5,2],"21":[37,13],"22":[25,25],"23":[47,3],"24":[17,0],"25":[0,136],"26":[17,0],"27":[13,13]},"f":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":26,"7":3,"8":5,"9":62,"10":21,"11":5,"12":8,"13":8,"14":11,"15":21,"16":14,"17":10,"18":97,"19":710,"20":363,"21":21,"22":343,"23":3,"24":17,"25":0,"26":75,"27":75,"28":63,"29":17,"30":648,"31":809,"32":4,"33":26,"34":0},"fnMap":{"1":{"name":"_onlyLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":59,"column":2}}},"2":{"name":"_whenNotPaused","line":67,"loc":{"start":{"line":67,"column":2},"end":{"line":69,"column":2}}},"3":{"name":"getRevision","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"4":{"name":"initialize","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":82,"column":2}}},"5":{"name":"deposit","line":91,"loc":{"start":{"line":91,"column":2},"end":{"line":118,"column":2}}},"6":{"name":"withdraw","line":125,"loc":{"start":{"line":125,"column":2},"end":{"line":161,"column":2}}},"7":{"name":"getBorrowAllowance","line":171,"loc":{"start":{"line":171,"column":2},"end":{"line":179,"column":2}}},"8":{"name":"delegateBorrowAllowance","line":188,"loc":{"start":{"line":188,"column":2},"end":{"line":199,"column":2}}},"9":{"name":"borrow","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":241,"column":2}}},"10":{"name":"repay","line":251,"loc":{"start":{"line":251,"column":2},"end":{"line":306,"column":2}}},"11":{"name":"swapBorrowRateMode","line":313,"loc":{"start":{"line":313,"column":2},"end":{"line":356,"column":2}}},"12":{"name":"rebalanceStableBorrowRate","line":365,"loc":{"start":{"line":365,"column":2},"end":{"line":410,"column":2}}},"13":{"name":"setUserUseReserveAsCollateral","line":417,"loc":{"start":{"line":417,"column":2},"end":{"line":437,"column":2}}},"14":{"name":"liquidationCall","line":448,"loc":{"start":{"line":448,"column":2},"end":{"line":477,"column":2}}},"15":{"name":"repayWithCollateral","line":491,"loc":{"start":{"line":491,"column":2},"end":{"line":526,"column":2}}},"16":{"name":"flashLoan","line":547,"loc":{"start":{"line":547,"column":2},"end":{"line":600,"column":2}}},"17":{"name":"swapLiquidity","line":610,"loc":{"start":{"line":610,"column":2},"end":{"line":638,"column":2}}},"18":{"name":"getReserveConfigurationData","line":644,"loc":{"start":{"line":644,"column":2},"end":{"line":677,"column":2}}},"19":{"name":"getReserveTokensAddresses","line":679,"loc":{"start":{"line":679,"column":2},"end":{"line":696,"column":2}}},"20":{"name":"getReserveData","line":698,"loc":{"start":{"line":698,"column":2},"end":{"line":729,"column":2}}},"21":{"name":"getUserAccountData","line":731,"loc":{"start":{"line":731,"column":2},"end":{"line":763,"column":2}}},"22":{"name":"getUserReserveData","line":765,"loc":{"start":{"line":765,"column":2},"end":{"line":793,"column":2}}},"23":{"name":"getReserves","line":795,"loc":{"start":{"line":795,"column":2},"end":{"line":797,"column":2}}},"24":{"name":"initReserve","line":809,"loc":{"start":{"line":809,"column":2},"end":{"line":824,"column":2}}},"25":{"name":"setReserveInterestRateStrategyAddress","line":832,"loc":{"start":{"line":832,"column":2},"end":{"line":838,"column":2}}},"26":{"name":"setConfiguration","line":840,"loc":{"start":{"line":840,"column":2},"end":{"line":843,"column":2}}},"27":{"name":"getConfiguration","line":845,"loc":{"start":{"line":845,"column":2},"end":{"line":852,"column":2}}},"28":{"name":"_executeBorrow","line":871,"loc":{"start":{"line":871,"column":2},"end":{"line":944,"column":2}}},"29":{"name":"_addReserveToList","line":949,"loc":{"start":{"line":949,"column":2},"end":{"line":960,"column":2}}},"30":{"name":"getReserveNormalizedIncome","line":967,"loc":{"start":{"line":967,"column":2},"end":{"line":969,"column":2}}},"31":{"name":"getReserveNormalizedVariableDebt","line":976,"loc":{"start":{"line":976,"column":2},"end":{"line":983,"column":2}}},"32":{"name":"balanceDecreaseAllowed","line":992,"loc":{"start":{"line":992,"column":2},"end":{"line":1008,"column":2}}},"33":{"name":"setPause","line":1014,"loc":{"start":{"line":1014,"column":2},"end":{"line":1023,"column":2}}},"34":{"name":"paused","line":1028,"loc":{"start":{"line":1028,"column":2},"end":{"line":1030,"column":2}}}},"statementMap":{"1":{"start":{"line":55,"column":4},"end":{"line":55,"column":2946}},"2":{"start":{"line":68,"column":4},"end":{"line":68,"column":38}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":31}},"4":{"start":{"line":81,"column":4},"end":{"line":81,"column":32}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":19}},"6":{"start":{"line":98,"column":4},"end":{"line":98,"column":63}},"7":{"start":{"line":100,"column":4},"end":{"line":100,"column":51}},"8":{"start":{"line":102,"column":4},"end":{"line":102,"column":42}},"9":{"start":{"line":104,"column":4},"end":{"line":104,"column":24}},"10":{"start":{"line":105,"column":4},"end":{"line":105,"column":56}},"11":{"start":{"line":107,"column":4},"end":{"line":107,"column":68}},"12":{"start":{"line":108,"column":4},"end":{"line":108,"column":4605}},"13":{"start":{"line":109,"column":6},"end":{"line":109,"column":68}},"14":{"start":{"line":112,"column":4},"end":{"line":112,"column":67}},"15":{"start":{"line":115,"column":4},"end":{"line":115,"column":61}},"16":{"start":{"line":117,"column":4},"end":{"line":117,"column":69}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":19}},"18":{"start":{"line":127,"column":4},"end":{"line":127,"column":63}},"19":{"start":{"line":129,"column":4},"end":{"line":129,"column":42}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":63}},"21":{"start":{"line":133,"column":4},"end":{"line":133,"column":37}},"22":{"start":{"line":136,"column":4},"end":{"line":136,"column":5500}},"23":{"start":{"line":137,"column":6},"end":{"line":137,"column":35}},"24":{"start":{"line":140,"column":4},"end":{"line":140,"column":5584}},"25":{"start":{"line":150,"column":4},"end":{"line":150,"column":24}},"26":{"start":{"line":152,"column":4},"end":{"line":152,"column":66}},"27":{"start":{"line":154,"column":4},"end":{"line":154,"column":5896}},"28":{"start":{"line":155,"column":6},"end":{"line":155,"column":69}},"29":{"start":{"line":158,"column":4},"end":{"line":158,"column":89}},"30":{"start":{"line":160,"column":4},"end":{"line":160,"column":44}},"31":{"start":{"line":177,"column":4},"end":{"line":177,"column":6759}},"32":{"start":{"line":194,"column":4},"end":{"line":194,"column":19}},"33":{"start":{"line":195,"column":4},"end":{"line":195,"column":78}},"34":{"start":{"line":197,"column":4},"end":{"line":197,"column":57}},"35":{"start":{"line":198,"column":4},"end":{"line":198,"column":84}},"36":{"start":{"line":217,"column":4},"end":{"line":217,"column":19}},"37":{"start":{"line":218,"column":4},"end":{"line":218,"column":63}},"38":{"start":{"line":220,"column":4},"end":{"line":220,"column":8253}},"39":{"start":{"line":221,"column":6},"end":{"line":221,"column":71}},"40":{"start":{"line":223,"column":6},"end":{"line":223,"column":8367}},"41":{"start":{"line":229,"column":4},"end":{"line":229,"column":8567}},"42":{"start":{"line":257,"column":4},"end":{"line":257,"column":19}},"43":{"start":{"line":259,"column":4},"end":{"line":259,"column":63}},"44":{"start":{"line":261,"column":4},"end":{"line":261,"column":96}},"45":{"start":{"line":263,"column":4},"end":{"line":263,"column":92}},"46":{"start":{"line":266,"column":4},"end":{"line":266,"column":9784}},"47":{"start":{"line":270,"column":4},"end":{"line":270,"column":9895}},"48":{"start":{"line":271,"column":6},"end":{"line":271,"column":27}},"49":{"start":{"line":274,"column":4},"end":{"line":274,"column":9997}},"50":{"start":{"line":283,"column":4},"end":{"line":283,"column":24}},"51":{"start":{"line":286,"column":4},"end":{"line":286,"column":10224}},"52":{"start":{"line":287,"column":6},"end":{"line":287,"column":85}},"53":{"start":{"line":289,"column":6},"end":{"line":289,"column":10397}},"54":{"start":{"line":296,"column":4},"end":{"line":296,"column":42}},"55":{"start":{"line":297,"column":4},"end":{"line":297,"column":63}},"56":{"start":{"line":299,"column":4},"end":{"line":299,"column":10664}},"57":{"start":{"line":300,"column":6},"end":{"line":300,"column":61}},"58":{"start":{"line":303,"column":4},"end":{"line":303,"column":68}},"59":{"start":{"line":305,"column":4},"end":{"line":305,"column":60}},"60":{"start":{"line":314,"column":4},"end":{"line":314,"column":19}},"61":{"start":{"line":315,"column":4},"end":{"line":315,"column":63}},"62":{"start":{"line":317,"column":4},"end":{"line":317,"column":96}},"63":{"start":{"line":319,"column":4},"end":{"line":319,"column":92}},"64":{"start":{"line":321,"column":4},"end":{"line":321,"column":11549}},"65":{"start":{"line":329,"column":4},"end":{"line":329,"column":24}},"66":{"start":{"line":331,"column":4},"end":{"line":331,"column":11735}},"67":{"start":{"line":333,"column":6},"end":{"line":333,"column":82}},"68":{"start":{"line":334,"column":6},"end":{"line":334,"column":11951}},"69":{"start":{"line":341,"column":6},"end":{"line":341,"column":12138}},"70":{"start":{"line":346,"column":6},"end":{"line":346,"column":12290}},"71":{"start":{"line":353,"column":4},"end":{"line":353,"column":66}},"72":{"start":{"line":355,"column":4},"end":{"line":355,"column":32}},"73":{"start":{"line":367,"column":4},"end":{"line":367,"column":19}},"74":{"start":{"line":369,"column":4},"end":{"line":369,"column":63}},"75":{"start":{"line":371,"column":4},"end":{"line":371,"column":67}},"76":{"start":{"line":372,"column":4},"end":{"line":372,"column":71}},"77":{"start":{"line":373,"column":4},"end":{"line":373,"column":49}},"78":{"start":{"line":375,"column":4},"end":{"line":375,"column":73}},"79":{"start":{"line":378,"column":4},"end":{"line":378,"column":104}},"80":{"start":{"line":379,"column":4},"end":{"line":379,"column":82}},"81":{"start":{"line":380,"column":4},"end":{"line":380,"column":13692}},"82":{"start":{"line":387,"column":4},"end":{"line":387,"column":63}},"83":{"start":{"line":388,"column":4},"end":{"line":388,"column":14007}},"84":{"start":{"line":394,"column":4},"end":{"line":394,"column":14137}},"85":{"start":{"line":401,"column":4},"end":{"line":401,"column":24}},"86":{"start":{"line":403,"column":4},"end":{"line":403,"column":77}},"87":{"start":{"line":404,"column":4},"end":{"line":404,"column":110}},"88":{"start":{"line":406,"column":4},"end":{"line":406,"column":58}},"89":{"start":{"line":408,"column":4},"end":{"line":408,"column":47}},"90":{"start":{"line":418,"column":4},"end":{"line":418,"column":19}},"91":{"start":{"line":419,"column":4},"end":{"line":419,"column":63}},"92":{"start":{"line":421,"column":4},"end":{"line":421,"column":15152}},"93":{"start":{"line":430,"column":4},"end":{"line":430,"column":77}},"94":{"start":{"line":432,"column":4},"end":{"line":432,"column":15436}},"95":{"start":{"line":433,"column":6},"end":{"line":433,"column":60}},"96":{"start":{"line":435,"column":6},"end":{"line":435,"column":61}},"97":{"start":{"line":455,"column":4},"end":{"line":455,"column":19}},"98":{"start":{"line":456,"column":4},"end":{"line":456,"column":84}},"99":{"start":{"line":459,"column":4},"end":{"line":459,"column":16409}},"100":{"start":{"line":469,"column":4},"end":{"line":469,"column":51}},"101":{"start":{"line":471,"column":4},"end":{"line":471,"column":93}},"102":{"start":{"line":473,"column":4},"end":{"line":473,"column":16839}},"103":{"start":{"line":475,"column":6},"end":{"line":475,"column":52}},"104":{"start":{"line":499,"column":4},"end":{"line":499,"column":19}},"105":{"start":{"line":500,"column":4},"end":{"line":500,"column":67}},"106":{"start":{"line":501,"column":4},"end":{"line":501,"column":33}},"107":{"start":{"line":503,"column":4},"end":{"line":503,"column":84}},"108":{"start":{"line":506,"column":4},"end":{"line":506,"column":18211}},"109":{"start":{"line":517,"column":4},"end":{"line":517,"column":56}},"110":{"start":{"line":519,"column":4},"end":{"line":519,"column":93}},"111":{"start":{"line":521,"column":4},"end":{"line":521,"column":18675}},"112":{"start":{"line":522,"column":6},"end":{"line":522,"column":52}},"113":{"start":{"line":525,"column":4},"end":{"line":525,"column":34}},"114":{"start":{"line":555,"column":4},"end":{"line":555,"column":19}},"115":{"start":{"line":556,"column":4},"end":{"line":556,"column":63}},"116":{"start":{"line":557,"column":4},"end":{"line":557,"column":34}},"117":{"start":{"line":559,"column":4},"end":{"line":559,"column":45}},"118":{"start":{"line":561,"column":4},"end":{"line":561,"column":64}},"119":{"start":{"line":563,"column":4},"end":{"line":563,"column":56}},"120":{"start":{"line":565,"column":4},"end":{"line":565,"column":80}},"121":{"start":{"line":567,"column":4},"end":{"line":567,"column":54}},"122":{"start":{"line":570,"column":4},"end":{"line":570,"column":76}},"123":{"start":{"line":573,"column":4},"end":{"line":573,"column":70}},"124":{"start":{"line":575,"column":4},"end":{"line":575,"column":52}},"125":{"start":{"line":577,"column":4},"end":{"line":577,"column":20770}},"126":{"start":{"line":578,"column":6},"end":{"line":578,"column":92}},"127":{"start":{"line":580,"column":6},"end":{"line":580,"column":26}},"128":{"start":{"line":581,"column":6},"end":{"line":581,"column":93}},"129":{"start":{"line":582,"column":6},"end":{"line":582,"column":76}},"130":{"start":{"line":584,"column":6},"end":{"line":584,"column":80}},"131":{"start":{"line":587,"column":6},"end":{"line":587,"column":21346}},"132":{"start":{"line":617,"column":4},"end":{"line":617,"column":19}},"133":{"start":{"line":618,"column":4},"end":{"line":618,"column":84}},"134":{"start":{"line":621,"column":4},"end":{"line":621,"column":22445}},"135":{"start":{"line":631,"column":4},"end":{"line":631,"column":50}},"136":{"start":{"line":633,"column":4},"end":{"line":633,"column":93}},"137":{"start":{"line":635,"column":4},"end":{"line":635,"column":22876}},"138":{"start":{"line":636,"column":6},"end":{"line":636,"column":52}},"139":{"start":{"line":662,"column":4},"end":{"line":662,"column":63}},"140":{"start":{"line":664,"column":4},"end":{"line":664,"column":23557}},"141":{"start":{"line":689,"column":4},"end":{"line":689,"column":63}},"142":{"start":{"line":691,"column":4},"end":{"line":691,"column":24379}},"143":{"start":{"line":715,"column":4},"end":{"line":715,"column":62}},"144":{"start":{"line":717,"column":4},"end":{"line":717,"column":25005}},"145":{"start":{"line":744,"column":4},"end":{"line":744,"column":25791}},"146":{"start":{"line":758,"column":4},"end":{"line":758,"column":26088}},"147":{"start":{"line":781,"column":4},"end":{"line":781,"column":63}},"148":{"start":{"line":783,"column":4},"end":{"line":783,"column":71}},"149":{"start":{"line":784,"column":4},"end":{"line":784,"column":87}},"150":{"start":{"line":785,"column":4},"end":{"line":785,"column":98}},"151":{"start":{"line":786,"column":4},"end":{"line":786,"column":98}},"152":{"start":{"line":787,"column":4},"end":{"line":787,"column":47}},"153":{"start":{"line":788,"column":4},"end":{"line":788,"column":94}},"154":{"start":{"line":789,"column":4},"end":{"line":789,"column":27231}},"155":{"start":{"line":792,"column":4},"end":{"line":792,"column":80}},"156":{"start":{"line":796,"column":4},"end":{"line":796,"column":24}},"157":{"start":{"line":816,"column":4},"end":{"line":816,"column":33}},"158":{"start":{"line":817,"column":4},"end":{"line":817,"column":28078}},"159":{"start":{"line":823,"column":4},"end":{"line":823,"column":27}},"160":{"start":{"line":836,"column":4},"end":{"line":836,"column":33}},"161":{"start":{"line":837,"column":4},"end":{"line":837,"column":69}},"162":{"start":{"line":841,"column":4},"end":{"line":841,"column":33}},"163":{"start":{"line":842,"column":4},"end":{"line":842,"column":54}},"164":{"start":{"line":851,"column":4},"end":{"line":851,"column":41}},"165":{"start":{"line":872,"column":4},"end":{"line":872,"column":68}},"166":{"start":{"line":873,"column":4},"end":{"line":873,"column":76}},"167":{"start":{"line":875,"column":4},"end":{"line":875,"column":56}},"168":{"start":{"line":877,"column":4},"end":{"line":877,"column":29792}},"169":{"start":{"line":881,"column":4},"end":{"line":881,"column":29946}},"170":{"start":{"line":894,"column":4},"end":{"line":894,"column":34}},"171":{"start":{"line":895,"column":4},"end":{"line":895,"column":30243}},"172":{"start":{"line":896,"column":6},"end":{"line":896,"column":45}},"173":{"start":{"line":899,"column":4},"end":{"line":899,"column":24}},"174":{"start":{"line":902,"column":4},"end":{"line":902,"column":33}},"175":{"start":{"line":904,"column":4},"end":{"line":904,"column":30453}},"176":{"start":{"line":907,"column":6},"end":{"line":907,"column":56}},"177":{"start":{"line":909,"column":6},"end":{"line":909,"column":30633}},"178":{"start":{"line":915,"column":6},"end":{"line":915,"column":30788}},"179":{"start":{"line":922,"column":4},"end":{"line":922,"column":30947}},"180":{"start":{"line":929,"column":4},"end":{"line":929,"column":31088}},"181":{"start":{"line":930,"column":6},"end":{"line":930,"column":77}},"182":{"start":{"line":933,"column":4},"end":{"line":933,"column":31210}},"183":{"start":{"line":950,"column":4},"end":{"line":950,"column":36}},"184":{"start":{"line":951,"column":4},"end":{"line":951,"column":87}},"185":{"start":{"line":952,"column":4},"end":{"line":952,"column":31801}},"186":{"start":{"line":953,"column":6},"end":{"line":953,"column":31858}},"187":{"start":{"line":954,"column":8},"end":{"line":954,"column":33}},"188":{"start":{"line":956,"column":4},"end":{"line":956,"column":31937}},"189":{"start":{"line":957,"column":6},"end":{"line":957,"column":54}},"190":{"start":{"line":958,"column":6},"end":{"line":958,"column":30}},"191":{"start":{"line":968,"column":4},"end":{"line":968,"column":49}},"192":{"start":{"line":982,"column":4},"end":{"line":982,"column":47}},"193":{"start":{"line":997,"column":4},"end":{"line":997,"column":19}},"194":{"start":{"line":998,"column":4},"end":{"line":998,"column":33188}},"195":{"start":{"line":1015,"column":4},"end":{"line":1015,"column":33}},"196":{"start":{"line":1017,"column":4},"end":{"line":1017,"column":16}},"197":{"start":{"line":1018,"column":4},"end":{"line":1018,"column":33641}},"198":{"start":{"line":1019,"column":6},"end":{"line":1019,"column":19}},"199":{"start":{"line":1021,"column":6},"end":{"line":1021,"column":21}},"200":{"start":{"line":1029,"column":4},"end":{"line":1029,"column":18}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":4}},{"start":{"line":68,"column":4},"end":{"line":68,"column":4}}]},"3":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":4},"end":{"line":108,"column":4}},{"start":{"line":108,"column":4},"end":{"line":108,"column":4}}]},"4":{"line":136,"type":"if","locations":[{"start":{"line":136,"column":4},"end":{"line":136,"column":4}},{"start":{"line":136,"column":4},"end":{"line":136,"column":4}}]},"5":{"line":154,"type":"if","locations":[{"start":{"line":154,"column":4},"end":{"line":154,"column":4}},{"start":{"line":154,"column":4},"end":{"line":154,"column":4}}]},"6":{"line":220,"type":"if","locations":[{"start":{"line":220,"column":4},"end":{"line":220,"column":4}},{"start":{"line":220,"column":4},"end":{"line":220,"column":4}}]},"7":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"8":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"9":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":4},"end":{"line":299,"column":4}},{"start":{"line":299,"column":4},"end":{"line":299,"column":4}}]},"10":{"line":331,"type":"if","locations":[{"start":{"line":331,"column":4},"end":{"line":331,"column":4}},{"start":{"line":331,"column":4},"end":{"line":331,"column":4}}]},"11":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":4},"end":{"line":394,"column":4}},{"start":{"line":394,"column":4},"end":{"line":394,"column":4}}]},"12":{"line":432,"type":"if","locations":[{"start":{"line":432,"column":4},"end":{"line":432,"column":4}},{"start":{"line":432,"column":4},"end":{"line":432,"column":4}}]},"13":{"line":469,"type":"if","locations":[{"start":{"line":469,"column":4},"end":{"line":469,"column":4}},{"start":{"line":469,"column":4},"end":{"line":469,"column":4}}]},"14":{"line":473,"type":"if","locations":[{"start":{"line":473,"column":4},"end":{"line":473,"column":4}},{"start":{"line":473,"column":4},"end":{"line":473,"column":4}}]},"15":{"line":500,"type":"if","locations":[{"start":{"line":500,"column":4},"end":{"line":500,"column":4}},{"start":{"line":500,"column":4},"end":{"line":500,"column":4}}]},"16":{"line":517,"type":"if","locations":[{"start":{"line":517,"column":4},"end":{"line":517,"column":4}},{"start":{"line":517,"column":4},"end":{"line":517,"column":4}}]},"17":{"line":521,"type":"if","locations":[{"start":{"line":521,"column":4},"end":{"line":521,"column":4}},{"start":{"line":521,"column":4},"end":{"line":521,"column":4}}]},"18":{"line":577,"type":"if","locations":[{"start":{"line":577,"column":4},"end":{"line":577,"column":4}},{"start":{"line":577,"column":4},"end":{"line":577,"column":4}}]},"19":{"line":631,"type":"if","locations":[{"start":{"line":631,"column":4},"end":{"line":631,"column":4}},{"start":{"line":631,"column":4},"end":{"line":631,"column":4}}]},"20":{"line":635,"type":"if","locations":[{"start":{"line":635,"column":4},"end":{"line":635,"column":4}},{"start":{"line":635,"column":4},"end":{"line":635,"column":4}}]},"21":{"line":895,"type":"if","locations":[{"start":{"line":895,"column":4},"end":{"line":895,"column":4}},{"start":{"line":895,"column":4},"end":{"line":895,"column":4}}]},"22":{"line":904,"type":"if","locations":[{"start":{"line":904,"column":4},"end":{"line":904,"column":4}},{"start":{"line":904,"column":4},"end":{"line":904,"column":4}}]},"23":{"line":929,"type":"if","locations":[{"start":{"line":929,"column":4},"end":{"line":929,"column":4}},{"start":{"line":929,"column":4},"end":{"line":929,"column":4}}]},"24":{"line":951,"type":"if","locations":[{"start":{"line":951,"column":4},"end":{"line":951,"column":4}},{"start":{"line":951,"column":4},"end":{"line":951,"column":4}}]},"25":{"line":953,"type":"if","locations":[{"start":{"line":953,"column":6},"end":{"line":953,"column":6}},{"start":{"line":953,"column":6},"end":{"line":953,"column":6}}]},"26":{"line":956,"type":"if","locations":[{"start":{"line":956,"column":4},"end":{"line":956,"column":4}},{"start":{"line":956,"column":4},"end":{"line":956,"column":4}}]},"27":{"line":1018,"type":"if","locations":[{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}},{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}}]}}},"contracts/lendingpool/LendingPoolCollateralManager.sol":{"l":{"127":0,"146":10,"147":10,"148":10,"150":10,"152":10,"161":10,"166":10,"175":10,"176":5,"179":5,"181":5,"183":5,"187":5,"191":5,"207":5,"208":1,"212":5,"213":3,"216":3,"217":0,"225":5,"227":5,"234":5,"235":1,"241":4,"247":4,"254":5,"255":2,"260":3,"261":3,"269":3,"278":5,"284":5,"294":5,"317":18,"318":18,"319":18,"321":18,"323":18,"331":18,"333":18,"343":18,"344":5,"347":13,"349":13,"353":13,"354":13,"356":13,"371":13,"372":2,"375":13,"377":13,"384":13,"385":2,"388":13,"391":13,"400":11,"401":11,"407":11,"409":11,"410":9,"416":2,"421":2,"428":11,"435":11,"444":11,"462":9,"463":9,"465":9,"467":9,"474":9,"475":4,"478":5,"479":5,"481":5,"482":5,"484":5,"485":2,"488":5,"490":4,"497":3,"505":3,"506":3,"507":3,"513":3,"514":1,"517":3,"518":3,"526":3,"534":3,"535":1,"541":2,"563":18,"564":18,"565":18,"567":18,"569":18,"570":18,"572":18,"575":18,"579":18,"586":18,"587":3,"588":3,"595":15,"596":15,"598":18},"path":"/src/contracts/lendingpool/LendingPoolCollateralManager.sol","s":{"1":0,"2":10,"3":10,"4":10,"5":10,"6":10,"7":10,"8":10,"9":10,"10":5,"11":5,"12":5,"13":5,"14":5,"15":5,"16":5,"17":1,"18":5,"19":3,"20":3,"21":0,"22":5,"23":5,"24":5,"25":1,"26":4,"27":4,"28":5,"29":2,"30":3,"31":3,"32":3,"33":5,"34":5,"35":5,"36":18,"37":18,"38":18,"39":18,"40":18,"41":18,"42":18,"43":18,"44":5,"45":13,"46":13,"47":13,"48":13,"49":13,"50":13,"51":2,"52":13,"53":13,"54":13,"55":2,"56":13,"57":13,"58":11,"59":11,"60":11,"61":11,"62":9,"63":2,"64":2,"65":11,"66":11,"67":11,"68":9,"69":9,"70":9,"71":9,"72":9,"73":4,"74":5,"75":5,"76":5,"77":5,"78":5,"79":2,"80":5,"81":4,"82":3,"83":3,"84":3,"85":3,"86":3,"87":1,"88":3,"89":3,"90":3,"91":3,"92":1,"93":2,"94":18,"95":18,"96":18,"97":18,"98":18,"99":18,"100":18,"101":18,"102":18,"103":18,"104":3,"105":3,"106":15,"107":15,"108":18},"b":{"1":[5,5],"2":[1,4],"3":[3,2],"4":[0,3],"5":[1,4],"6":[2,3],"7":[5,13],"8":[2,11],"9":[2,11],"10":[9,2],"11":[4,5],"12":[2,3],"13":[3,0],"14":[1,2],"15":[1,2],"16":[3,15]},"f":{"1":0,"2":10,"3":18,"4":9,"5":18},"fnMap":{"1":{"name":"getRevision","line":126,"loc":{"start":{"line":126,"column":2},"end":{"line":128,"column":2}}},"2":{"name":"liquidationCall","line":139,"loc":{"start":{"line":139,"column":2},"end":{"line":295,"column":2}}},"3":{"name":"repayWithCollateral","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":445,"column":2}}},"4":{"name":"swapLiquidity","line":455,"loc":{"start":{"line":455,"column":2},"end":{"line":542,"column":2}}},"5":{"name":"calculateAvailableCollateralToLiquidate","line":555,"loc":{"start":{"line":555,"column":2},"end":{"line":599,"column":2}}}},"statementMap":{"1":{"start":{"line":127,"column":4},"end":{"line":127,"column":12}},"2":{"start":{"line":146,"column":4},"end":{"line":146,"column":78}},"3":{"start":{"line":147,"column":4},"end":{"line":147,"column":76}},"4":{"start":{"line":148,"column":4},"end":{"line":148,"column":65}},"5":{"start":{"line":150,"column":4},"end":{"line":150,"column":40}},"6":{"start":{"line":152,"column":4},"end":{"line":152,"column":6033}},"7":{"start":{"line":161,"column":4},"end":{"line":161,"column":6330}},"8":{"start":{"line":166,"column":4},"end":{"line":166,"column":6452}},"9":{"start":{"line":175,"column":4},"end":{"line":175,"column":6686}},"10":{"start":{"line":176,"column":6},"end":{"line":176,"column":44}},"11":{"start":{"line":179,"column":4},"end":{"line":179,"column":67}},"12":{"start":{"line":181,"column":4},"end":{"line":181,"column":69}},"13":{"start":{"line":183,"column":4},"end":{"line":183,"column":6984}},"14":{"start":{"line":187,"column":4},"end":{"line":187,"column":7148}},"15":{"start":{"line":191,"column":4},"end":{"line":191,"column":7286}},"16":{"start":{"line":207,"column":4},"end":{"line":207,"column":7770}},"17":{"start":{"line":208,"column":6},"end":{"line":208,"column":62}},"18":{"start":{"line":212,"column":4},"end":{"line":212,"column":8027}},"19":{"start":{"line":213,"column":6},"end":{"line":213,"column":8058}},"20":{"start":{"line":216,"column":6},"end":{"line":216,"column":8178}},"21":{"start":{"line":217,"column":8},"end":{"line":217,"column":8255}},"22":{"start":{"line":225,"column":4},"end":{"line":225,"column":33}},"23":{"start":{"line":227,"column":4},"end":{"line":227,"column":8484}},"24":{"start":{"line":234,"column":4},"end":{"line":234,"column":8633}},"25":{"start":{"line":235,"column":6},"end":{"line":235,"column":8702}},"26":{"start":{"line":241,"column":6},"end":{"line":241,"column":8895}},"27":{"start":{"line":247,"column":6},"end":{"line":247,"column":9069}},"28":{"start":{"line":254,"column":4},"end":{"line":254,"column":9311}},"29":{"start":{"line":255,"column":6},"end":{"line":255,"column":97}},"30":{"start":{"line":260,"column":6},"end":{"line":260,"column":36}},"31":{"start":{"line":261,"column":6},"end":{"line":261,"column":9577}},"32":{"start":{"line":269,"column":6},"end":{"line":269,"column":9786}},"33":{"start":{"line":278,"column":4},"end":{"line":278,"column":9999}},"34":{"start":{"line":284,"column":4},"end":{"line":284,"column":10139}},"35":{"start":{"line":294,"column":4},"end":{"line":294,"column":79}},"36":{"start":{"line":317,"column":4},"end":{"line":317,"column":78}},"37":{"start":{"line":318,"column":4},"end":{"line":318,"column":71}},"38":{"start":{"line":319,"column":4},"end":{"line":319,"column":65}},"39":{"start":{"line":321,"column":4},"end":{"line":321,"column":40}},"40":{"start":{"line":323,"column":4},"end":{"line":323,"column":11674}},"41":{"start":{"line":331,"column":4},"end":{"line":331,"column":95}},"42":{"start":{"line":333,"column":4},"end":{"line":333,"column":11972}},"43":{"start":{"line":343,"column":4},"end":{"line":343,"column":12217}},"44":{"start":{"line":344,"column":6},"end":{"line":344,"column":44}},"45":{"start":{"line":347,"column":4},"end":{"line":347,"column":86}},"46":{"start":{"line":349,"column":4},"end":{"line":349,"column":12479}},"47":{"start":{"line":353,"column":4},"end":{"line":353,"column":67}},"48":{"start":{"line":354,"column":4},"end":{"line":354,"column":69}},"49":{"start":{"line":356,"column":4},"end":{"line":356,"column":12761}},"50":{"start":{"line":371,"column":4},"end":{"line":371,"column":13239}},"51":{"start":{"line":372,"column":6},"end":{"line":372,"column":62}},"52":{"start":{"line":375,"column":4},"end":{"line":375,"column":34}},"53":{"start":{"line":377,"column":4},"end":{"line":377,"column":13459}},"54":{"start":{"line":384,"column":4},"end":{"line":384,"column":13603}},"55":{"start":{"line":385,"column":6},"end":{"line":385,"column":73}},"56":{"start":{"line":388,"column":4},"end":{"line":388,"column":51}},"57":{"start":{"line":391,"column":4},"end":{"line":391,"column":13905}},"58":{"start":{"line":400,"column":4},"end":{"line":400,"column":28}},"59":{"start":{"line":401,"column":4},"end":{"line":401,"column":14123}},"60":{"start":{"line":407,"column":4},"end":{"line":407,"column":95}},"61":{"start":{"line":409,"column":4},"end":{"line":409,"column":14355}},"62":{"start":{"line":410,"column":6},"end":{"line":410,"column":14424}},"63":{"start":{"line":416,"column":6},"end":{"line":416,"column":14607}},"64":{"start":{"line":421,"column":6},"end":{"line":421,"column":14770}},"65":{"start":{"line":428,"column":4},"end":{"line":428,"column":14959}},"66":{"start":{"line":435,"column":4},"end":{"line":435,"column":15112}},"67":{"start":{"line":444,"column":4},"end":{"line":444,"column":79}},"68":{"start":{"line":462,"column":4},"end":{"line":462,"column":71}},"69":{"start":{"line":463,"column":4},"end":{"line":463,"column":67}},"70":{"start":{"line":465,"column":4},"end":{"line":465,"column":38}},"71":{"start":{"line":467,"column":4},"end":{"line":467,"column":16281}},"72":{"start":{"line":474,"column":4},"end":{"line":474,"column":16433}},"73":{"start":{"line":475,"column":6},"end":{"line":475,"column":44}},"74":{"start":{"line":478,"column":4},"end":{"line":478,"column":62}},"75":{"start":{"line":479,"column":4},"end":{"line":479,"column":58}},"76":{"start":{"line":481,"column":4},"end":{"line":481,"column":28}},"77":{"start":{"line":482,"column":4},"end":{"line":482,"column":26}},"78":{"start":{"line":484,"column":4},"end":{"line":484,"column":16775}},"79":{"start":{"line":485,"column":6},"end":{"line":485,"column":73}},"80":{"start":{"line":488,"column":4},"end":{"line":488,"column":95}},"81":{"start":{"line":490,"column":4},"end":{"line":490,"column":17029}},"82":{"start":{"line":497,"column":4},"end":{"line":497,"column":17256}},"83":{"start":{"line":505,"column":4},"end":{"line":505,"column":68}},"84":{"start":{"line":506,"column":4},"end":{"line":506,"column":17473}},"85":{"start":{"line":507,"column":6},"end":{"line":507,"column":17514}},"86":{"start":{"line":513,"column":6},"end":{"line":513,"column":17653}},"87":{"start":{"line":514,"column":8},"end":{"line":514,"column":72}},"88":{"start":{"line":517,"column":6},"end":{"line":517,"column":90}},"89":{"start":{"line":518,"column":6},"end":{"line":518,"column":17891}},"90":{"start":{"line":526,"column":4},"end":{"line":526,"column":18036}},"91":{"start":{"line":534,"column":4},"end":{"line":534,"column":18247}},"92":{"start":{"line":535,"column":6},"end":{"line":535,"column":18332}},"93":{"start":{"line":541,"column":4},"end":{"line":541,"column":79}},"94":{"start":{"line":563,"column":4},"end":{"line":563,"column":32}},"95":{"start":{"line":564,"column":4},"end":{"line":564,"column":37}},"96":{"start":{"line":565,"column":4},"end":{"line":565,"column":87}},"97":{"start":{"line":567,"column":4},"end":{"line":567,"column":55}},"98":{"start":{"line":569,"column":4},"end":{"line":569,"column":65}},"99":{"start":{"line":570,"column":4},"end":{"line":570,"column":71}},"100":{"start":{"line":572,"column":4},"end":{"line":572,"column":20103}},"101":{"start":{"line":575,"column":4},"end":{"line":575,"column":72}},"102":{"start":{"line":579,"column":4},"end":{"line":579,"column":20496}},"103":{"start":{"line":586,"column":4},"end":{"line":586,"column":20713}},"104":{"start":{"line":587,"column":6},"end":{"line":587,"column":45}},"105":{"start":{"line":588,"column":6},"end":{"line":588,"column":20871}},"106":{"start":{"line":595,"column":6},"end":{"line":595,"column":59}},"107":{"start":{"line":596,"column":6},"end":{"line":596,"column":43}},"108":{"start":{"line":598,"column":4},"end":{"line":598,"column":52}}},"branchMap":{"1":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":175,"column":4}},{"start":{"line":175,"column":4},"end":{"line":175,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"4":{"line":216,"type":"if","locations":[{"start":{"line":216,"column":6},"end":{"line":216,"column":6}},{"start":{"line":216,"column":6},"end":{"line":216,"column":6}}]},"5":{"line":234,"type":"if","locations":[{"start":{"line":234,"column":4},"end":{"line":234,"column":4}},{"start":{"line":234,"column":4},"end":{"line":234,"column":4}}]},"6":{"line":254,"type":"if","locations":[{"start":{"line":254,"column":4},"end":{"line":254,"column":4}},{"start":{"line":254,"column":4},"end":{"line":254,"column":4}}]},"7":{"line":343,"type":"if","locations":[{"start":{"line":343,"column":4},"end":{"line":343,"column":4}},{"start":{"line":343,"column":4},"end":{"line":343,"column":4}}]},"8":{"line":371,"type":"if","locations":[{"start":{"line":371,"column":4},"end":{"line":371,"column":4}},{"start":{"line":371,"column":4},"end":{"line":371,"column":4}}]},"9":{"line":384,"type":"if","locations":[{"start":{"line":384,"column":4},"end":{"line":384,"column":4}},{"start":{"line":384,"column":4},"end":{"line":384,"column":4}}]},"10":{"line":409,"type":"if","locations":[{"start":{"line":409,"column":4},"end":{"line":409,"column":4}},{"start":{"line":409,"column":4},"end":{"line":409,"column":4}}]},"11":{"line":474,"type":"if","locations":[{"start":{"line":474,"column":4},"end":{"line":474,"column":4}},{"start":{"line":474,"column":4},"end":{"line":474,"column":4}}]},"12":{"line":484,"type":"if","locations":[{"start":{"line":484,"column":4},"end":{"line":484,"column":4}},{"start":{"line":484,"column":4},"end":{"line":484,"column":4}}]},"13":{"line":506,"type":"if","locations":[{"start":{"line":506,"column":4},"end":{"line":506,"column":4}},{"start":{"line":506,"column":4},"end":{"line":506,"column":4}}]},"14":{"line":513,"type":"if","locations":[{"start":{"line":513,"column":6},"end":{"line":513,"column":6}},{"start":{"line":513,"column":6},"end":{"line":513,"column":6}}]},"15":{"line":534,"type":"if","locations":[{"start":{"line":534,"column":4},"end":{"line":534,"column":4}},{"start":{"line":534,"column":4},"end":{"line":534,"column":4}}]},"16":{"line":586,"type":"if","locations":[{"start":{"line":586,"column":4},"end":{"line":586,"column":4}},{"start":{"line":586,"column":4},"end":{"line":586,"column":4}}]}}},"contracts/lendingpool/LendingPoolConfigurator.sol":{"l":{"187":124,"188":105,"194":1,"198":1,"199":1,"219":17,"221":17,"226":17,"231":17,"239":17,"241":17,"243":17,"244":17,"246":17,"248":17,"263":1,"265":1,"267":1,"276":1,"278":1,"280":1,"289":1,"291":1,"293":1,"305":18,"307":18,"308":18,"310":18,"312":18,"320":1,"322":1,"324":1,"325":1,"341":14,"343":14,"344":14,"345":14,"347":14,"349":14,"357":1,"359":1,"361":1,"363":1,"371":1,"373":1,"375":1,"377":1,"385":1,"387":1,"389":1,"391":1,"399":7,"401":7,"403":7,"405":7,"413":8,"425":8,"430":7,"432":7,"434":7,"436":7,"444":2,"446":2,"448":2,"450":2,"458":2,"460":2,"462":2,"464":2,"473":1,"475":1,"477":1,"479":1,"488":1,"490":1,"492":1,"494":1,"504":1,"506":1,"508":1,"510":1,"519":1,"521":1,"523":1,"525":1,"534":0,"536":0,"538":0,"540":0,"552":0,"553":0,"562":51,"564":51,"571":51,"573":51,"581":3,"585":3,"587":3,"594":3,"602":26},"path":"/src/contracts/lendingpool/LendingPoolConfigurator.sol","s":{"1":124,"2":1,"3":1,"4":1,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":17,"12":17,"13":17,"14":17,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":18,"25":18,"26":18,"27":18,"28":18,"29":1,"30":1,"31":1,"32":1,"33":14,"34":14,"35":14,"36":14,"37":14,"38":14,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":7,"52":7,"53":7,"54":7,"55":8,"56":8,"57":7,"58":7,"59":7,"60":7,"61":2,"62":2,"63":2,"64":2,"65":2,"66":2,"67":2,"68":2,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":51,"92":51,"93":51,"94":51,"95":3,"96":3,"97":3,"98":3,"99":26},"b":{"1":[105,19],"2":[7,1]},"f":{"1":124,"2":1,"3":1,"4":17,"5":1,"6":1,"7":1,"8":18,"9":1,"10":14,"11":1,"12":1,"13":1,"14":7,"15":8,"16":2,"17":2,"18":1,"19":1,"20":1,"21":1,"22":0,"23":0,"24":51,"25":3,"26":26},"fnMap":{"1":{"name":"onlyAaveAdmin","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":189,"column":2}}},"2":{"name":"getRevision","line":193,"loc":{"start":{"line":193,"column":2},"end":{"line":195,"column":2}}},"3":{"name":"initialize","line":197,"loc":{"start":{"line":197,"column":2},"end":{"line":200,"column":2}}},"4":{"name":"initReserve","line":218,"loc":{"start":{"line":211,"column":2},"end":{"line":255,"column":2}}},"5":{"name":"updateAToken","line":262,"loc":{"start":{"line":262,"column":2},"end":{"line":268,"column":2}}},"6":{"name":"updateStableDebtToken","line":275,"loc":{"start":{"line":275,"column":2},"end":{"line":281,"column":2}}},"7":{"name":"updateVariableDebtToken","line":288,"loc":{"start":{"line":288,"column":2},"end":{"line":294,"column":2}}},"8":{"name":"enableBorrowingOnReserve","line":303,"loc":{"start":{"line":301,"column":2},"end":{"line":313,"column":2}}},"9":{"name":"disableBorrowingOnReserve","line":319,"loc":{"start":{"line":319,"column":2},"end":{"line":326,"column":2}}},"10":{"name":"enableReserveAsCollateral","line":340,"loc":{"start":{"line":335,"column":2},"end":{"line":350,"column":2}}},"11":{"name":"disableReserveAsCollateral","line":356,"loc":{"start":{"line":356,"column":2},"end":{"line":364,"column":2}}},"12":{"name":"enableReserveStableRate","line":370,"loc":{"start":{"line":370,"column":2},"end":{"line":378,"column":2}}},"13":{"name":"disableReserveStableRate","line":384,"loc":{"start":{"line":384,"column":2},"end":{"line":392,"column":2}}},"14":{"name":"activateReserve","line":398,"loc":{"start":{"line":398,"column":2},"end":{"line":406,"column":2}}},"15":{"name":"deactivateReserve","line":412,"loc":{"start":{"line":412,"column":2},"end":{"line":437,"column":2}}},"16":{"name":"freezeReserve","line":443,"loc":{"start":{"line":443,"column":2},"end":{"line":451,"column":2}}},"17":{"name":"unfreezeReserve","line":457,"loc":{"start":{"line":457,"column":2},"end":{"line":465,"column":2}}},"18":{"name":"setLtv","line":472,"loc":{"start":{"line":472,"column":2},"end":{"line":480,"column":2}}},"19":{"name":"setReserveFactor","line":487,"loc":{"start":{"line":487,"column":2},"end":{"line":495,"column":2}}},"20":{"name":"setLiquidationThreshold","line":503,"loc":{"start":{"line":503,"column":2},"end":{"line":511,"column":2}}},"21":{"name":"setLiquidationBonus","line":518,"loc":{"start":{"line":518,"column":2},"end":{"line":526,"column":2}}},"22":{"name":"setReserveDecimals","line":533,"loc":{"start":{"line":533,"column":2},"end":{"line":541,"column":2}}},"23":{"name":"setReserveInterestRateStrategyAddress","line":550,"loc":{"start":{"line":548,"column":2},"end":{"line":554,"column":2}}},"24":{"name":"_initTokenWithProxy","line":561,"loc":{"start":{"line":561,"column":2},"end":{"line":574,"column":2}}},"25":{"name":"_upgradeTokenImplementation","line":576,"loc":{"start":{"line":576,"column":2},"end":{"line":595,"column":2}}},"26":{"name":"setPoolPause","line":601,"loc":{"start":{"line":601,"column":2},"end":{"line":603,"column":2}}}},"statementMap":{"1":{"start":{"line":187,"column":4},"end":{"line":187,"column":88}},"2":{"start":{"line":194,"column":4},"end":{"line":194,"column":32}},"3":{"start":{"line":198,"column":4},"end":{"line":198,"column":31}},"4":{"start":{"line":199,"column":4},"end":{"line":199,"column":58}},"5":{"start":{"line":219,"column":4},"end":{"line":219,"column":89}},"6":{"start":{"line":221,"column":4},"end":{"line":221,"column":7918}},"7":{"start":{"line":226,"column":4},"end":{"line":226,"column":8046}},"8":{"start":{"line":231,"column":4},"end":{"line":231,"column":8177}},"9":{"start":{"line":239,"column":4},"end":{"line":239,"column":80}},"10":{"start":{"line":241,"column":4},"end":{"line":241,"column":53}},"11":{"start":{"line":243,"column":4},"end":{"line":243,"column":32}},"12":{"start":{"line":244,"column":4},"end":{"line":244,"column":33}},"13":{"start":{"line":246,"column":4},"end":{"line":246,"column":51}},"14":{"start":{"line":248,"column":4},"end":{"line":248,"column":8620}},"15":{"start":{"line":263,"column":4},"end":{"line":263,"column":71}},"16":{"start":{"line":265,"column":4},"end":{"line":265,"column":68}},"17":{"start":{"line":267,"column":4},"end":{"line":267,"column":61}},"18":{"start":{"line":276,"column":4},"end":{"line":276,"column":73}},"19":{"start":{"line":278,"column":4},"end":{"line":278,"column":70}},"20":{"start":{"line":280,"column":4},"end":{"line":280,"column":72}},"21":{"start":{"line":289,"column":4},"end":{"line":289,"column":75}},"22":{"start":{"line":291,"column":4},"end":{"line":291,"column":72}},"23":{"start":{"line":293,"column":4},"end":{"line":293,"column":76}},"24":{"start":{"line":305,"column":4},"end":{"line":305,"column":80}},"25":{"start":{"line":307,"column":4},"end":{"line":307,"column":42}},"26":{"start":{"line":308,"column":4},"end":{"line":308,"column":71}},"27":{"start":{"line":310,"column":4},"end":{"line":310,"column":51}},"28":{"start":{"line":312,"column":4},"end":{"line":312,"column":66}},"29":{"start":{"line":320,"column":4},"end":{"line":320,"column":80}},"30":{"start":{"line":322,"column":4},"end":{"line":322,"column":43}},"31":{"start":{"line":324,"column":4},"end":{"line":324,"column":51}},"32":{"start":{"line":325,"column":4},"end":{"line":325,"column":42}},"33":{"start":{"line":341,"column":4},"end":{"line":341,"column":80}},"34":{"start":{"line":343,"column":4},"end":{"line":343,"column":28}},"35":{"start":{"line":344,"column":4},"end":{"line":344,"column":62}},"36":{"start":{"line":345,"column":4},"end":{"line":345,"column":54}},"37":{"start":{"line":347,"column":4},"end":{"line":347,"column":51}},"38":{"start":{"line":349,"column":4},"end":{"line":349,"column":87}},"39":{"start":{"line":357,"column":4},"end":{"line":357,"column":80}},"40":{"start":{"line":359,"column":4},"end":{"line":359,"column":26}},"41":{"start":{"line":361,"column":4},"end":{"line":361,"column":51}},"42":{"start":{"line":363,"column":4},"end":{"line":363,"column":43}},"43":{"start":{"line":371,"column":4},"end":{"line":371,"column":80}},"44":{"start":{"line":373,"column":4},"end":{"line":373,"column":52}},"45":{"start":{"line":375,"column":4},"end":{"line":375,"column":51}},"46":{"start":{"line":377,"column":4},"end":{"line":377,"column":42}},"47":{"start":{"line":385,"column":4},"end":{"line":385,"column":80}},"48":{"start":{"line":387,"column":4},"end":{"line":387,"column":53}},"49":{"start":{"line":389,"column":4},"end":{"line":389,"column":51}},"50":{"start":{"line":391,"column":4},"end":{"line":391,"column":43}},"51":{"start":{"line":399,"column":4},"end":{"line":399,"column":80}},"52":{"start":{"line":401,"column":4},"end":{"line":401,"column":32}},"53":{"start":{"line":403,"column":4},"end":{"line":403,"column":51}},"54":{"start":{"line":405,"column":4},"end":{"line":405,"column":32}},"55":{"start":{"line":413,"column":4},"end":{"line":413,"column":14228}},"56":{"start":{"line":425,"column":4},"end":{"line":425,"column":14387}},"57":{"start":{"line":430,"column":4},"end":{"line":430,"column":80}},"58":{"start":{"line":432,"column":4},"end":{"line":432,"column":33}},"59":{"start":{"line":434,"column":4},"end":{"line":434,"column":51}},"60":{"start":{"line":436,"column":4},"end":{"line":436,"column":34}},"61":{"start":{"line":444,"column":4},"end":{"line":444,"column":80}},"62":{"start":{"line":446,"column":4},"end":{"line":446,"column":32}},"63":{"start":{"line":448,"column":4},"end":{"line":448,"column":51}},"64":{"start":{"line":450,"column":4},"end":{"line":450,"column":30}},"65":{"start":{"line":458,"column":4},"end":{"line":458,"column":80}},"66":{"start":{"line":460,"column":4},"end":{"line":460,"column":33}},"67":{"start":{"line":462,"column":4},"end":{"line":462,"column":51}},"68":{"start":{"line":464,"column":4},"end":{"line":464,"column":32}},"69":{"start":{"line":473,"column":4},"end":{"line":473,"column":80}},"70":{"start":{"line":475,"column":4},"end":{"line":475,"column":28}},"71":{"start":{"line":477,"column":4},"end":{"line":477,"column":51}},"72":{"start":{"line":479,"column":4},"end":{"line":479,"column":42}},"73":{"start":{"line":488,"column":4},"end":{"line":488,"column":80}},"74":{"start":{"line":490,"column":4},"end":{"line":490,"column":48}},"75":{"start":{"line":492,"column":4},"end":{"line":492,"column":51}},"76":{"start":{"line":494,"column":4},"end":{"line":494,"column":51}},"77":{"start":{"line":504,"column":4},"end":{"line":504,"column":80}},"78":{"start":{"line":506,"column":4},"end":{"line":506,"column":51}},"79":{"start":{"line":508,"column":4},"end":{"line":508,"column":51}},"80":{"start":{"line":510,"column":4},"end":{"line":510,"column":61}},"81":{"start":{"line":519,"column":4},"end":{"line":519,"column":80}},"82":{"start":{"line":521,"column":4},"end":{"line":521,"column":43}},"83":{"start":{"line":523,"column":4},"end":{"line":523,"column":51}},"84":{"start":{"line":525,"column":4},"end":{"line":525,"column":53}},"85":{"start":{"line":534,"column":4},"end":{"line":534,"column":80}},"86":{"start":{"line":536,"column":4},"end":{"line":536,"column":38}},"87":{"start":{"line":538,"column":4},"end":{"line":538,"column":51}},"88":{"start":{"line":540,"column":4},"end":{"line":540,"column":48}},"89":{"start":{"line":552,"column":4},"end":{"line":552,"column":73}},"90":{"start":{"line":553,"column":4},"end":{"line":553,"column":71}},"91":{"start":{"line":562,"column":4},"end":{"line":562,"column":93}},"92":{"start":{"line":564,"column":4},"end":{"line":564,"column":18940}},"93":{"start":{"line":571,"column":4},"end":{"line":571,"column":58}},"94":{"start":{"line":573,"column":4},"end":{"line":573,"column":25}},"95":{"start":{"line":581,"column":4},"end":{"line":581,"column":19368}},"96":{"start":{"line":585,"column":4},"end":{"line":585,"column":84}},"97":{"start":{"line":587,"column":4},"end":{"line":587,"column":19580}},"98":{"start":{"line":594,"column":4},"end":{"line":594,"column":49}},"99":{"start":{"line":602,"column":4},"end":{"line":602,"column":21}}},"branchMap":{"1":{"line":187,"type":"if","locations":[{"start":{"line":187,"column":4},"end":{"line":187,"column":4}},{"start":{"line":187,"column":4},"end":{"line":187,"column":4}}]},"2":{"line":425,"type":"if","locations":[{"start":{"line":425,"column":4},"end":{"line":425,"column":4}},{"start":{"line":425,"column":4},"end":{"line":425,"column":4}}]}}},"contracts/lendingpool/LendingPoolStorage.sol":{"l":{"30":0,"37":0},"path":"/src/contracts/lendingpool/LendingPoolStorage.sol","s":{"1":0,"2":0},"b":{},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"getReservesList","line":29,"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"getAddressesProvider","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":38,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":24}},"2":{"start":{"line":37,"column":4},"end":{"line":37,"column":29}}},"branchMap":{}},"contracts/libraries/configuration/ReserveConfiguration.sol":{"l":{"46":1,"55":570,"63":16,"72":194,"84":15,"97":112,"106":15,"119":97,"128":17,"137":178,"146":31,"155":179,"164":21,"173":97,"182":19,"191":97,"202":20,"215":97,"233":179,"235":179,"258":209,"260":209},"path":"/src/contracts/libraries/configuration/ReserveConfiguration.sol","s":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":179,"21":209,"22":209},"b":{},"f":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":209},"fnMap":{"1":{"name":"setReserveFactor","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"getReserveFactor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"3":{"name":"setLtv","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"getLtv","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"5":{"name":"setLiquidationThreshold","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":85,"column":2}}},"6":{"name":"getLiquidationThreshold","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":98,"column":2}}},"7":{"name":"setLiquidationBonus","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"8":{"name":"getLiquidationBonus","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":120,"column":2}}},"9":{"name":"setDecimals","line":127,"loc":{"start":{"line":127,"column":2},"end":{"line":129,"column":2}}},"10":{"name":"getDecimals","line":136,"loc":{"start":{"line":136,"column":2},"end":{"line":138,"column":2}}},"11":{"name":"setActive","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":147,"column":2}}},"12":{"name":"getActive","line":154,"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":2}}},"13":{"name":"setFrozen","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":165,"column":2}}},"14":{"name":"getFrozen","line":172,"loc":{"start":{"line":172,"column":2},"end":{"line":174,"column":2}}},"15":{"name":"setBorrowingEnabled","line":181,"loc":{"start":{"line":181,"column":2},"end":{"line":183,"column":2}}},"16":{"name":"getBorrowingEnabled","line":190,"loc":{"start":{"line":190,"column":2},"end":{"line":192,"column":2}}},"17":{"name":"setStableRateBorrowingEnabled","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":203,"column":2}}},"18":{"name":"getStableRateBorrowingEnabled","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":216,"column":2}}},"19":{"name":"getFlags","line":223,"loc":{"start":{"line":223,"column":2},"end":{"line":241,"column":2}}},"20":{"name":"getParams","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":266,"column":2}}}},"statementMap":{"1":{"start":{"line":46,"column":4},"end":{"line":46,"column":70}},"2":{"start":{"line":55,"column":4},"end":{"line":55,"column":51}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":43}},"4":{"start":{"line":72,"column":4},"end":{"line":72,"column":32}},"5":{"start":{"line":84,"column":4},"end":{"line":84,"column":75}},"6":{"start":{"line":97,"column":4},"end":{"line":97,"column":58}},"7":{"start":{"line":106,"column":4},"end":{"line":106,"column":67}},"8":{"start":{"line":119,"column":4},"end":{"line":119,"column":54}},"9":{"start":{"line":128,"column":4},"end":{"line":128,"column":61}},"10":{"start":{"line":137,"column":4},"end":{"line":137,"column":45}},"11":{"start":{"line":146,"column":4},"end":{"line":146,"column":74}},"12":{"start":{"line":155,"column":4},"end":{"line":155,"column":50}},"13":{"start":{"line":164,"column":4},"end":{"line":164,"column":74}},"14":{"start":{"line":173,"column":4},"end":{"line":173,"column":50}},"15":{"start":{"line":182,"column":4},"end":{"line":182,"column":78}},"16":{"start":{"line":191,"column":4},"end":{"line":191,"column":53}},"17":{"start":{"line":202,"column":4},"end":{"line":202,"column":85}},"18":{"start":{"line":215,"column":4},"end":{"line":215,"column":60}},"19":{"start":{"line":233,"column":4},"end":{"line":233,"column":33}},"20":{"start":{"line":235,"column":4},"end":{"line":235,"column":7613}},"21":{"start":{"line":258,"column":4},"end":{"line":258,"column":33}},"22":{"start":{"line":260,"column":4},"end":{"line":260,"column":8256}}},"branchMap":{}},"contracts/libraries/configuration/UserConfiguration.sol":{"l":{"31":49,"47":124,"63":1853,"77":235,"91":550,"100":33,"109":119},"path":"/src/contracts/libraries/configuration/UserConfiguration.sol","s":{"1":49,"2":124,"3":1853,"4":235,"5":550,"6":33,"7":119},"b":{},"f":{"1":49,"2":124,"3":1853,"4":235,"5":550,"6":33,"7":119},"fnMap":{"1":{"name":"setBorrowing","line":26,"loc":{"start":{"line":26,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"setUsingAsCollateral","line":42,"loc":{"start":{"line":42,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"isUsingAsCollateralOrBorrowing","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"isBorrowing","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":78,"column":2}}},"5":{"name":"isUsingAsCollateral","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":92,"column":2}}},"6":{"name":"isBorrowingAny","line":99,"loc":{"start":{"line":99,"column":2},"end":{"line":101,"column":2}}},"7":{"name":"isEmpty","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":110,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1104}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":1694}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":53}},"4":{"start":{"line":77,"column":4},"end":{"line":77,"column":53}},"5":{"start":{"line":91,"column":4},"end":{"line":91,"column":57}},"6":{"start":{"line":100,"column":4},"end":{"line":100,"column":42}},"7":{"start":{"line":109,"column":4},"end":{"line":109,"column":25}}},"branchMap":{}},"contracts/libraries/helpers/Errors.sol":{"l":{},"path":"/src/contracts/libraries/helpers/Errors.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/libraries/helpers/Helpers.sol":{"l":{"24":395},"path":"/src/contracts/libraries/helpers/Helpers.sol","s":{"1":395},"b":{},"f":{"1":395},"fnMap":{"1":{"name":"getUserCurrentDebt","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":24,"column":4},"end":{"line":24,"column":653}}},"branchMap":{}},"contracts/libraries/logic/GenericLogic.sol":{"l":{"65":33,"69":27,"72":6,"74":6,"76":6,"77":0,"80":6,"88":6,"89":0,"92":6,"96":6,"99":6,"100":3,"103":3,"109":3,"115":3,"169":119,"171":119,"172":10,"174":109,"175":1853,"176":1668,"179":185,"180":185,"182":185,"186":185,"187":185,"189":185,"190":128,"192":128,"197":128,"199":128,"200":128,"205":185,"206":63,"209":63,"213":63,"219":109,"222":109,"226":109,"231":109,"252":112,"254":64,"271":21,"273":21,"274":11,"277":10,"278":10},"path":"/src/contracts/libraries/logic/GenericLogic.sol","s":{"1":33,"2":27,"3":6,"4":6,"5":6,"6":0,"7":6,"8":6,"9":0,"10":6,"11":6,"12":6,"13":3,"14":3,"15":3,"16":3,"17":119,"18":119,"19":10,"20":109,"21":1853,"22":185,"23":185,"24":185,"25":185,"26":185,"27":185,"28":128,"29":128,"30":128,"31":128,"32":128,"33":185,"34":63,"35":63,"36":63,"37":109,"38":109,"39":109,"40":109,"41":112,"42":48,"43":64,"44":21,"45":21,"46":11,"47":10,"48":10},"b":{"1":[27,6],"2":[0,6],"3":[0,6],"4":[3,3],"5":[10,109],"6":[1668,185],"7":[128,57],"8":[63,122],"9":[48,64],"10":[11,10]},"f":{"1":33,"2":119,"3":112,"4":21},"fnMap":{"1":{"name":"balanceDecreaseAllowed","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":116,"column":2}}},"2":{"name":"calculateUserAccountData","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":238,"column":2}}},"3":{"name":"calculateHealthFactorFromBalances","line":247,"loc":{"start":{"line":247,"column":2},"end":{"line":255,"column":2}}},"4":{"name":"calculateAvailableBorrowsETH","line":266,"loc":{"start":{"line":266,"column":2},"end":{"line":279,"column":2}}}},"statementMap":{"1":{"start":{"line":65,"column":4},"end":{"line":65,"column":2530}},"2":{"start":{"line":69,"column":6},"end":{"line":69,"column":17}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":47}},"4":{"start":{"line":74,"column":4},"end":{"line":74,"column":80}},"5":{"start":{"line":76,"column":4},"end":{"line":76,"column":2807}},"6":{"start":{"line":77,"column":6},"end":{"line":77,"column":17}},"7":{"start":{"line":80,"column":4},"end":{"line":80,"column":3008}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":3133}},"9":{"start":{"line":89,"column":6},"end":{"line":89,"column":17}},"10":{"start":{"line":92,"column":4},"end":{"line":92,"column":3245}},"11":{"start":{"line":96,"column":4},"end":{"line":96,"column":95}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":3528}},"13":{"start":{"line":100,"column":6},"end":{"line":100,"column":18}},"14":{"start":{"line":103,"column":4},"end":{"line":103,"column":3647}},"15":{"start":{"line":109,"column":4},"end":{"line":109,"column":3854}},"16":{"start":{"line":115,"column":4},"end":{"line":115,"column":87}},"17":{"start":{"line":169,"column":4},"end":{"line":169,"column":44}},"18":{"start":{"line":171,"column":4},"end":{"line":171,"column":5830}},"19":{"start":{"line":172,"column":6},"end":{"line":172,"column":38}},"20":{"start":{"line":174,"column":4},"end":{"line":174,"column":5908}},"21":{"start":{"line":175,"column":6},"end":{"line":175,"column":5971}},"22":{"start":{"line":179,"column":6},"end":{"line":179,"column":50}},"23":{"start":{"line":180,"column":6},"end":{"line":180,"column":96}},"24":{"start":{"line":182,"column":6},"end":{"line":182,"column":6227}},"25":{"start":{"line":186,"column":6},"end":{"line":186,"column":39}},"26":{"start":{"line":187,"column":6},"end":{"line":187,"column":97}},"27":{"start":{"line":189,"column":6},"end":{"line":189,"column":6481}},"28":{"start":{"line":190,"column":8},"end":{"line":190,"column":93}},"29":{"start":{"line":192,"column":8},"end":{"line":192,"column":6673}},"30":{"start":{"line":197,"column":8},"end":{"line":197,"column":95}},"31":{"start":{"line":199,"column":8},"end":{"line":199,"column":71}},"32":{"start":{"line":200,"column":8},"end":{"line":200,"column":6976}},"33":{"start":{"line":205,"column":6},"end":{"line":205,"column":7126}},"34":{"start":{"line":206,"column":8},"end":{"line":206,"column":7174}},"35":{"start":{"line":209,"column":8},"end":{"line":209,"column":7296}},"36":{"start":{"line":213,"column":8},"end":{"line":213,"column":7455}},"37":{"start":{"line":219,"column":4},"end":{"line":219,"column":7632}},"38":{"start":{"line":222,"column":4},"end":{"line":222,"column":7752}},"39":{"start":{"line":226,"column":4},"end":{"line":226,"column":7903}},"40":{"start":{"line":231,"column":4},"end":{"line":231,"column":8077}},"41":{"start":{"line":252,"column":4},"end":{"line":252,"column":49}},"42":{"start":{"line":252,"column":31},"end":{"line":252,"column":49}},"43":{"start":{"line":254,"column":4},"end":{"line":254,"column":91}},"44":{"start":{"line":271,"column":4},"end":{"line":271,"column":70}},"45":{"start":{"line":273,"column":4},"end":{"line":273,"column":9571}},"46":{"start":{"line":274,"column":6},"end":{"line":274,"column":14}},"47":{"start":{"line":277,"column":4},"end":{"line":277,"column":66}},"48":{"start":{"line":278,"column":4},"end":{"line":278,"column":30}}},"branchMap":{"1":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":4},"end":{"line":65,"column":4}},{"start":{"line":65,"column":4},"end":{"line":65,"column":4}}]},"2":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":4}},{"start":{"line":76,"column":4},"end":{"line":76,"column":4}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"4":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":4},"end":{"line":99,"column":4}},{"start":{"line":99,"column":4},"end":{"line":99,"column":4}}]},"5":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":4},"end":{"line":171,"column":4}},{"start":{"line":171,"column":4},"end":{"line":171,"column":4}}]},"6":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":6},"end":{"line":175,"column":6}},{"start":{"line":175,"column":6},"end":{"line":175,"column":6}}]},"7":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"8":{"line":205,"type":"if","locations":[{"start":{"line":205,"column":6},"end":{"line":205,"column":6}},{"start":{"line":205,"column":6},"end":{"line":205,"column":6}}]},"9":{"line":252,"type":"if","locations":[{"start":{"line":252,"column":4},"end":{"line":252,"column":4}},{"start":{"line":252,"column":4},"end":{"line":252,"column":4}}]},"10":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":4},"end":{"line":273,"column":4}},{"start":{"line":273,"column":4},"end":{"line":273,"column":4}}]}}},"contracts/libraries/logic/ReserveLogic.sol":{"l":{"85":648,"88":648,"90":382,"93":266,"97":266,"108":809,"111":809,"113":493,"116":316,"120":316,"134":11,"139":10,"151":239,"152":239,"153":239,"155":239,"162":239,"183":3,"185":3,"187":3,"188":3,"190":3,"206":17,"207":17,"209":17,"212":17,"213":17,"216":17,"217":17,"218":17,"219":17,"246":235,"248":235,"250":235,"253":235,"255":235,"267":234,"268":234,"269":234,"271":234,"272":234,"273":234,"275":234,"316":239,"318":239,"320":239,"321":239,"325":0,"328":0,"336":0,"339":0,"342":0,"347":0,"350":0,"356":0,"358":0,"374":239,"376":239,"378":239,"379":239,"382":239,"383":69,"387":69,"388":69,"390":69,"394":69,"395":38,"399":38,"400":38,"401":38,"406":239,"407":239},"path":"/src/contracts/libraries/logic/ReserveLogic.sol","s":{"1":648,"2":648,"3":382,"4":266,"5":266,"6":809,"7":809,"8":493,"9":316,"10":316,"11":11,"12":10,"13":239,"14":239,"15":239,"16":239,"17":239,"18":3,"19":3,"20":3,"21":3,"22":3,"23":17,"24":17,"25":17,"26":17,"27":17,"28":17,"29":17,"30":17,"31":17,"32":235,"33":235,"34":235,"35":235,"36":235,"37":234,"38":234,"39":234,"40":234,"41":234,"42":234,"43":234,"44":239,"45":239,"46":239,"47":239,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":239,"58":239,"59":239,"60":239,"61":239,"62":69,"63":69,"64":69,"65":69,"66":69,"67":38,"68":38,"69":38,"70":38,"71":239,"72":239},"b":{"1":[382,266],"2":[493,316],"3":[10,1],"4":[3,0],"5":[17,0],"6":[17,0],"7":[17,0],"8":[234,0],"9":[234,0],"10":[234,0],"11":[239,0],"12":[69,170],"13":[69,0],"14":[38,31],"15":[38,0]},"f":{"1":648,"2":809,"3":11,"4":239,"5":3,"6":17,"7":235,"8":239,"9":239},"fnMap":{"1":{"name":"getNormalizedIncome","line":84,"loc":{"start":{"line":84,"column":2},"end":{"line":98,"column":2}}},"2":{"name":"getNormalizedDebt","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":121,"column":2}}},"3":{"name":"getDebtTokenAddress","line":129,"loc":{"start":{"line":129,"column":2},"end":{"line":143,"column":2}}},"4":{"name":"updateState","line":150,"loc":{"start":{"line":150,"column":2},"end":{"line":169,"column":2}}},"5":{"name":"cumulateToLiquidityIndex","line":178,"loc":{"start":{"line":178,"column":2},"end":{"line":191,"column":2}}},"6":{"name":"init","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":220,"column":2}}},"7":{"name":"updateInterestRates","line":239,"loc":{"start":{"line":239,"column":2},"end":{"line":283,"column":2}}},"8":{"name":"_mintToTreasury","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":359,"column":2}}},"9":{"name":"_updateIndexes","line":368,"loc":{"start":{"line":368,"column":2},"end":{"line":408,"column":2}}}},"statementMap":{"1":{"start":{"line":85,"column":4},"end":{"line":85,"column":50}},"2":{"start":{"line":88,"column":4},"end":{"line":88,"column":3533}},"3":{"start":{"line":90,"column":6},"end":{"line":90,"column":35}},"4":{"start":{"line":93,"column":4},"end":{"line":93,"column":3745}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":20}},"6":{"start":{"line":108,"column":4},"end":{"line":108,"column":50}},"7":{"start":{"line":111,"column":4},"end":{"line":111,"column":4417}},"8":{"start":{"line":113,"column":6},"end":{"line":113,"column":40}},"9":{"start":{"line":116,"column":4},"end":{"line":116,"column":4639}},"10":{"start":{"line":120,"column":4},"end":{"line":120,"column":20}},"11":{"start":{"line":134,"column":4},"end":{"line":134,"column":5256}},"12":{"start":{"line":139,"column":4},"end":{"line":139,"column":5559}},"13":{"start":{"line":151,"column":4},"end":{"line":151,"column":64}},"14":{"start":{"line":152,"column":4},"end":{"line":152,"column":69}},"15":{"start":{"line":153,"column":4},"end":{"line":153,"column":59}},"16":{"start":{"line":155,"column":4},"end":{"line":155,"column":6182}},"17":{"start":{"line":162,"column":4},"end":{"line":162,"column":6375}},"18":{"start":{"line":183,"column":4},"end":{"line":183,"column":88}},"19":{"start":{"line":185,"column":4},"end":{"line":185,"column":65}},"20":{"start":{"line":187,"column":4},"end":{"line":187,"column":49}},"21":{"start":{"line":188,"column":4},"end":{"line":188,"column":64}},"22":{"start":{"line":190,"column":4},"end":{"line":190,"column":43}},"23":{"start":{"line":206,"column":4},"end":{"line":206,"column":83}},"24":{"start":{"line":207,"column":4},"end":{"line":207,"column":7908}},"25":{"start":{"line":209,"column":6},"end":{"line":209,"column":55}},"26":{"start":{"line":212,"column":4},"end":{"line":212,"column":8064}},"27":{"start":{"line":213,"column":6},"end":{"line":213,"column":60}},"28":{"start":{"line":216,"column":4},"end":{"line":216,"column":40}},"29":{"start":{"line":217,"column":4},"end":{"line":217,"column":58}},"30":{"start":{"line":218,"column":4},"end":{"line":218,"column":62}},"31":{"start":{"line":219,"column":4},"end":{"line":219,"column":68}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":44}},"33":{"start":{"line":248,"column":4},"end":{"line":248,"column":63}},"34":{"start":{"line":250,"column":4},"end":{"line":250,"column":9530}},"35":{"start":{"line":253,"column":4},"end":{"line":253,"column":76}},"36":{"start":{"line":255,"column":4},"end":{"line":255,"column":9713}},"37":{"start":{"line":267,"column":4},"end":{"line":267,"column":87}},"38":{"start":{"line":268,"column":4},"end":{"line":268,"column":88}},"39":{"start":{"line":269,"column":4},"end":{"line":269,"column":92}},"40":{"start":{"line":271,"column":4},"end":{"line":271,"column":64}},"41":{"start":{"line":272,"column":4},"end":{"line":272,"column":64}},"42":{"start":{"line":273,"column":4},"end":{"line":273,"column":68}},"43":{"start":{"line":275,"column":4},"end":{"line":275,"column":10646}},"44":{"start":{"line":316,"column":4},"end":{"line":316,"column":39}},"45":{"start":{"line":318,"column":4},"end":{"line":318,"column":64}},"46":{"start":{"line":320,"column":4},"end":{"line":320,"column":12121}},"47":{"start":{"line":321,"column":6},"end":{"line":321,"column":12}},"48":{"start":{"line":325,"column":4},"end":{"line":325,"column":86}},"49":{"start":{"line":328,"column":4},"end":{"line":328,"column":12457}},"50":{"start":{"line":336,"column":4},"end":{"line":336,"column":90}},"51":{"start":{"line":339,"column":4},"end":{"line":339,"column":84}},"52":{"start":{"line":342,"column":4},"end":{"line":342,"column":12963}},"53":{"start":{"line":347,"column":4},"end":{"line":347,"column":90}},"54":{"start":{"line":350,"column":4},"end":{"line":350,"column":13330}},"55":{"start":{"line":356,"column":4},"end":{"line":356,"column":75}},"56":{"start":{"line":358,"column":4},"end":{"line":358,"column":86}},"57":{"start":{"line":374,"column":4},"end":{"line":374,"column":50}},"58":{"start":{"line":376,"column":4},"end":{"line":376,"column":63}},"59":{"start":{"line":378,"column":4},"end":{"line":378,"column":46}},"60":{"start":{"line":379,"column":4},"end":{"line":379,"column":56}},"61":{"start":{"line":382,"column":4},"end":{"line":382,"column":14442}},"62":{"start":{"line":383,"column":6},"end":{"line":383,"column":14483}},"63":{"start":{"line":387,"column":6},"end":{"line":387,"column":74}},"64":{"start":{"line":388,"column":6},"end":{"line":388,"column":77}},"65":{"start":{"line":390,"column":6},"end":{"line":390,"column":56}},"66":{"start":{"line":394,"column":6},"end":{"line":394,"column":14986}},"67":{"start":{"line":395,"column":8},"end":{"line":395,"column":15048}},"68":{"start":{"line":399,"column":8},"end":{"line":399,"column":91}},"69":{"start":{"line":400,"column":8},"end":{"line":400,"column":90}},"70":{"start":{"line":401,"column":8},"end":{"line":401,"column":68}},"71":{"start":{"line":406,"column":4},"end":{"line":406,"column":56}},"72":{"start":{"line":407,"column":4},"end":{"line":407,"column":54}}},"branchMap":{"1":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"2":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"3":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"4":{"line":188,"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":188,"column":4}},{"start":{"line":188,"column":4},"end":{"line":188,"column":4}}]},"5":{"line":206,"type":"if","locations":[{"start":{"line":206,"column":4},"end":{"line":206,"column":4}},{"start":{"line":206,"column":4},"end":{"line":206,"column":4}}]},"6":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"7":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"8":{"line":267,"type":"if","locations":[{"start":{"line":267,"column":4},"end":{"line":267,"column":4}},{"start":{"line":267,"column":4},"end":{"line":267,"column":4}}]},"9":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"10":{"line":269,"type":"if","locations":[{"start":{"line":269,"column":4},"end":{"line":269,"column":4}},{"start":{"line":269,"column":4},"end":{"line":269,"column":4}}]},"11":{"line":320,"type":"if","locations":[{"start":{"line":320,"column":4},"end":{"line":320,"column":4}},{"start":{"line":320,"column":4},"end":{"line":320,"column":4}}]},"12":{"line":382,"type":"if","locations":[{"start":{"line":382,"column":4},"end":{"line":382,"column":4}},{"start":{"line":382,"column":4},"end":{"line":382,"column":4}}]},"13":{"line":388,"type":"if","locations":[{"start":{"line":388,"column":6},"end":{"line":388,"column":6}},{"start":{"line":388,"column":6},"end":{"line":388,"column":6}}]},"14":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":6},"end":{"line":394,"column":6}},{"start":{"line":394,"column":6},"end":{"line":394,"column":6}}]},"15":{"line":400,"type":"if","locations":[{"start":{"line":400,"column":8},"end":{"line":400,"column":8}},{"start":{"line":400,"column":8},"end":{"line":400,"column":8}}]}}},"contracts/libraries/logic/ValidationLogic.sol":{"l":{"38":104,"40":104,"41":102,"42":102,"60":25,"62":24,"64":23,"125":63,"127":63,"134":63,"135":63,"137":63,"140":63,"146":61,"160":61,"162":55,"168":55,"172":55,"186":50,"189":0,"191":0,"200":0,"202":0,"222":20,"224":20,"226":20,"228":18,"236":18,"257":4,"259":4,"260":4,"262":4,"263":2,"265":2,"273":1,"275":1,"283":0,"304":7,"306":7,"308":7,"328":13,"329":12,"349":10,"352":2,"355":8,"356":1,"362":7,"366":7,"367":1,"373":6,"374":1,"380":5,"402":18,"405":2,"408":16,"411":0,"417":16,"418":8,"422":8,"423":1,"430":15,"431":2,"437":13,"453":9,"454":1,"460":8,"461":8,"462":2,"464":6,"465":1,"471":5},"path":"/src/contracts/libraries/logic/ValidationLogic.sol","s":{"1":104,"2":104,"3":102,"4":102,"5":25,"6":24,"7":23,"8":63,"9":63,"10":63,"11":63,"12":63,"13":63,"14":61,"15":61,"16":55,"17":55,"18":55,"19":50,"20":0,"21":0,"22":0,"23":0,"24":20,"25":20,"26":20,"27":18,"28":18,"29":4,"30":4,"31":4,"32":4,"33":2,"34":2,"35":2,"36":1,"37":1,"38":0,"39":7,"40":7,"41":7,"42":13,"43":12,"44":10,"45":2,"46":8,"47":1,"48":7,"49":7,"50":1,"51":6,"52":1,"53":5,"54":18,"55":2,"56":16,"57":0,"58":16,"59":8,"60":8,"61":1,"62":15,"63":2,"64":13,"65":9,"66":1,"67":8,"68":8,"69":2,"70":6,"71":1,"72":5},"b":{"1":[102,2],"2":[102,0],"3":[102,0],"4":[24,1],"5":[23,1],"6":[22,1],"7":[63,0],"8":[63,0],"9":[63,0],"10":[61,2],"11":[55,6],"12":[55,0],"13":[50,5],"14":[0,50],"15":[0,0],"16":[0,0],"17":[0,0],"18":[20,0],"19":[18,2],"20":[18,0],"21":[17,1],"22":[4,0],"23":[4,0],"24":[2,2],"25":[1,1],"26":[2,0],"27":[1,1],"28":[1,0],"29":[1,0],"30":[7,0],"31":[6,1],"32":[12,1],"33":[11,1],"34":[2,8],"35":[1,7],"36":[1,6],"37":[1,5],"38":[2,16],"39":[0,16],"40":[8,8],"41":[1,7],"42":[2,13],"43":[1,8],"44":[2,6],"45":[1,5]},"f":{"1":104,"2":25,"3":63,"4":20,"5":4,"6":7,"7":13,"8":10,"9":18,"10":9},"fnMap":{"1":{"name":"validateDeposit","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":43,"column":2}}},"2":{"name":"validateWithdraw","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"validateBorrow","line":113,"loc":{"start":{"line":113,"column":2},"end":{"line":204,"column":2}}},"4":{"name":"validateRepay","line":214,"loc":{"start":{"line":214,"column":2},"end":{"line":240,"column":2}}},"5":{"name":"validateSwapRateMode","line":250,"loc":{"start":{"line":250,"column":2},"end":{"line":285,"column":2}}},"6":{"name":"validateSetUseReserveAsCollateral","line":296,"loc":{"start":{"line":296,"column":2},"end":{"line":320,"column":2}}},"7":{"name":"validateFlashloan","line":327,"loc":{"start":{"line":327,"column":2},"end":{"line":330,"column":2}}},"8":{"name":"validateLiquidationCall","line":341,"loc":{"start":{"line":341,"column":2},"end":{"line":381,"column":2}}},"9":{"name":"validateRepayWithCollateral","line":393,"loc":{"start":{"line":393,"column":2},"end":{"line":438,"column":2}}},"10":{"name":"validateSwapLiquidity","line":447,"loc":{"start":{"line":447,"column":2},"end":{"line":472,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":74}},"2":{"start":{"line":40,"column":4},"end":{"line":40,"column":56}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":46}},"4":{"start":{"line":42,"column":4},"end":{"line":42,"column":51}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":56}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":75}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":2437}},"8":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"9":{"start":{"line":127,"column":4},"end":{"line":127,"column":4488}},"10":{"start":{"line":134,"column":4},"end":{"line":134,"column":51}},"11":{"start":{"line":135,"column":4},"end":{"line":135,"column":56}},"12":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"13":{"start":{"line":140,"column":4},"end":{"line":140,"column":4827}},"14":{"start":{"line":146,"column":4},"end":{"line":146,"column":5049}},"15":{"start":{"line":160,"column":4},"end":{"line":160,"column":77}},"16":{"start":{"line":162,"column":4},"end":{"line":162,"column":5434}},"17":{"start":{"line":168,"column":4},"end":{"line":168,"column":5703}},"18":{"start":{"line":172,"column":4},"end":{"line":172,"column":5861}},"19":{"start":{"line":186,"column":4},"end":{"line":186,"column":6430}},"20":{"start":{"line":189,"column":6},"end":{"line":189,"column":82}},"21":{"start":{"line":191,"column":6},"end":{"line":191,"column":6685}},"22":{"start":{"line":200,"column":6},"end":{"line":200,"column":90}},"23":{"start":{"line":202,"column":6},"end":{"line":202,"column":89}},"24":{"start":{"line":222,"column":4},"end":{"line":222,"column":53}},"25":{"start":{"line":224,"column":4},"end":{"line":224,"column":46}},"26":{"start":{"line":226,"column":4},"end":{"line":226,"column":60}},"27":{"start":{"line":228,"column":4},"end":{"line":228,"column":8040}},"28":{"start":{"line":236,"column":4},"end":{"line":236,"column":8339}},"29":{"start":{"line":257,"column":4},"end":{"line":257,"column":96}},"30":{"start":{"line":259,"column":4},"end":{"line":259,"column":46}},"31":{"start":{"line":260,"column":4},"end":{"line":260,"column":51}},"32":{"start":{"line":262,"column":4},"end":{"line":262,"column":9332}},"33":{"start":{"line":263,"column":6},"end":{"line":263,"column":76}},"34":{"start":{"line":264,"column":11},"end":{"line":264,"column":9485}},"35":{"start":{"line":265,"column":6},"end":{"line":265,"column":80}},"36":{"start":{"line":273,"column":6},"end":{"line":273,"column":68}},"37":{"start":{"line":275,"column":6},"end":{"line":275,"column":10079}},"38":{"start":{"line":283,"column":6},"end":{"line":283,"column":55}},"39":{"start":{"line":304,"column":4},"end":{"line":304,"column":83}},"40":{"start":{"line":306,"column":4},"end":{"line":306,"column":79}},"41":{"start":{"line":308,"column":4},"end":{"line":308,"column":11408}},"42":{"start":{"line":328,"column":4},"end":{"line":328,"column":58}},"43":{"start":{"line":329,"column":4},"end":{"line":329,"column":98}},"44":{"start":{"line":349,"column":4},"end":{"line":349,"column":12893}},"45":{"start":{"line":352,"column":6},"end":{"line":352,"column":98}},"46":{"start":{"line":355,"column":4},"end":{"line":355,"column":13115}},"47":{"start":{"line":356,"column":6},"end":{"line":356,"column":13200}},"48":{"start":{"line":362,"column":4},"end":{"line":362,"column":13408}},"49":{"start":{"line":366,"column":4},"end":{"line":366,"column":13592}},"50":{"start":{"line":367,"column":6},"end":{"line":367,"column":13629}},"51":{"start":{"line":373,"column":4},"end":{"line":373,"column":13783}},"52":{"start":{"line":374,"column":6},"end":{"line":374,"column":13844}},"53":{"start":{"line":380,"column":4},"end":{"line":380,"column":79}},"54":{"start":{"line":402,"column":4},"end":{"line":402,"column":14907}},"55":{"start":{"line":405,"column":6},"end":{"line":405,"column":98}},"56":{"start":{"line":408,"column":4},"end":{"line":408,"column":15129}},"57":{"start":{"line":411,"column":6},"end":{"line":411,"column":15248}},"58":{"start":{"line":417,"column":4},"end":{"line":417,"column":15402}},"59":{"start":{"line":418,"column":6},"end":{"line":418,"column":15490}},"60":{"start":{"line":422,"column":6},"end":{"line":422,"column":15680}},"61":{"start":{"line":423,"column":8},"end":{"line":423,"column":15719}},"62":{"start":{"line":430,"column":4},"end":{"line":430,"column":15885}},"63":{"start":{"line":431,"column":6},"end":{"line":431,"column":15946}},"64":{"start":{"line":437,"column":4},"end":{"line":437,"column":79}},"65":{"start":{"line":453,"column":4},"end":{"line":453,"column":16711}},"66":{"start":{"line":454,"column":6},"end":{"line":454,"column":16748}},"67":{"start":{"line":460,"column":4},"end":{"line":460,"column":80}},"68":{"start":{"line":461,"column":4},"end":{"line":461,"column":16978}},"69":{"start":{"line":462,"column":6},"end":{"line":462,"column":98}},"70":{"start":{"line":464,"column":4},"end":{"line":464,"column":17149}},"71":{"start":{"line":465,"column":6},"end":{"line":465,"column":17177}},"72":{"start":{"line":471,"column":4},"end":{"line":471,"column":79}}},"branchMap":{"1":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":4},"end":{"line":41,"column":4}},{"start":{"line":41,"column":4},"end":{"line":41,"column":4}}]},"3":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":4}},{"start":{"line":42,"column":4},"end":{"line":42,"column":4}}]},"4":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":4},"end":{"line":60,"column":4}},{"start":{"line":60,"column":4},"end":{"line":60,"column":4}}]},"5":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"6":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":64,"column":4}},{"start":{"line":64,"column":4},"end":{"line":64,"column":4}}]},"7":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"8":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":4},"end":{"line":135,"column":4}},{"start":{"line":135,"column":4},"end":{"line":135,"column":4}}]},"9":{"line":137,"type":"if","locations":[{"start":{"line":137,"column":4},"end":{"line":137,"column":4}},{"start":{"line":137,"column":4},"end":{"line":137,"column":4}}]},"10":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":140,"column":4}},{"start":{"line":140,"column":4},"end":{"line":140,"column":4}}]},"11":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]},"12":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":162,"column":4}},{"start":{"line":162,"column":4},"end":{"line":162,"column":4}}]},"13":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":4},"end":{"line":172,"column":4}},{"start":{"line":172,"column":4},"end":{"line":172,"column":4}}]},"14":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":4},"end":{"line":186,"column":4}},{"start":{"line":186,"column":4},"end":{"line":186,"column":4}}]},"15":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"16":{"line":191,"type":"if","locations":[{"start":{"line":191,"column":6},"end":{"line":191,"column":6}},{"start":{"line":191,"column":6},"end":{"line":191,"column":6}}]},"17":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":6},"end":{"line":202,"column":6}},{"start":{"line":202,"column":6},"end":{"line":202,"column":6}}]},"18":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"19":{"line":226,"type":"if","locations":[{"start":{"line":226,"column":4},"end":{"line":226,"column":4}},{"start":{"line":226,"column":4},"end":{"line":226,"column":4}}]},"20":{"line":228,"type":"if","locations":[{"start":{"line":228,"column":4},"end":{"line":228,"column":4}},{"start":{"line":228,"column":4},"end":{"line":228,"column":4}}]},"21":{"line":236,"type":"if","locations":[{"start":{"line":236,"column":4},"end":{"line":236,"column":4}},{"start":{"line":236,"column":4},"end":{"line":236,"column":4}}]},"22":{"line":259,"type":"if","locations":[{"start":{"line":259,"column":4},"end":{"line":259,"column":4}},{"start":{"line":259,"column":4},"end":{"line":259,"column":4}}]},"23":{"line":260,"type":"if","locations":[{"start":{"line":260,"column":4},"end":{"line":260,"column":4}},{"start":{"line":260,"column":4},"end":{"line":260,"column":4}}]},"24":{"line":262,"type":"if","locations":[{"start":{"line":262,"column":4},"end":{"line":262,"column":4}},{"start":{"line":262,"column":4},"end":{"line":262,"column":4}}]},"25":{"line":263,"type":"if","locations":[{"start":{"line":263,"column":6},"end":{"line":263,"column":6}},{"start":{"line":263,"column":6},"end":{"line":263,"column":6}}]},"26":{"line":264,"type":"if","locations":[{"start":{"line":264,"column":11},"end":{"line":264,"column":11}},{"start":{"line":264,"column":11},"end":{"line":264,"column":11}}]},"27":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":6},"end":{"line":265,"column":6}},{"start":{"line":265,"column":6},"end":{"line":265,"column":6}}]},"28":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":6},"end":{"line":273,"column":6}},{"start":{"line":273,"column":6},"end":{"line":273,"column":6}}]},"29":{"line":275,"type":"if","locations":[{"start":{"line":275,"column":6},"end":{"line":275,"column":6}},{"start":{"line":275,"column":6},"end":{"line":275,"column":6}}]},"30":{"line":306,"type":"if","locations":[{"start":{"line":306,"column":4},"end":{"line":306,"column":4}},{"start":{"line":306,"column":4},"end":{"line":306,"column":4}}]},"31":{"line":308,"type":"if","locations":[{"start":{"line":308,"column":4},"end":{"line":308,"column":4}},{"start":{"line":308,"column":4},"end":{"line":308,"column":4}}]},"32":{"line":328,"type":"if","locations":[{"start":{"line":328,"column":4},"end":{"line":328,"column":4}},{"start":{"line":328,"column":4},"end":{"line":328,"column":4}}]},"33":{"line":329,"type":"if","locations":[{"start":{"line":329,"column":4},"end":{"line":329,"column":4}},{"start":{"line":329,"column":4},"end":{"line":329,"column":4}}]},"34":{"line":349,"type":"if","locations":[{"start":{"line":349,"column":4},"end":{"line":349,"column":4}},{"start":{"line":349,"column":4},"end":{"line":349,"column":4}}]},"35":{"line":355,"type":"if","locations":[{"start":{"line":355,"column":4},"end":{"line":355,"column":4}},{"start":{"line":355,"column":4},"end":{"line":355,"column":4}}]},"36":{"line":366,"type":"if","locations":[{"start":{"line":366,"column":4},"end":{"line":366,"column":4}},{"start":{"line":366,"column":4},"end":{"line":366,"column":4}}]},"37":{"line":373,"type":"if","locations":[{"start":{"line":373,"column":4},"end":{"line":373,"column":4}},{"start":{"line":373,"column":4},"end":{"line":373,"column":4}}]},"38":{"line":402,"type":"if","locations":[{"start":{"line":402,"column":4},"end":{"line":402,"column":4}},{"start":{"line":402,"column":4},"end":{"line":402,"column":4}}]},"39":{"line":408,"type":"if","locations":[{"start":{"line":408,"column":4},"end":{"line":408,"column":4}},{"start":{"line":408,"column":4},"end":{"line":408,"column":4}}]},"40":{"line":417,"type":"if","locations":[{"start":{"line":417,"column":4},"end":{"line":417,"column":4}},{"start":{"line":417,"column":4},"end":{"line":417,"column":4}}]},"41":{"line":422,"type":"if","locations":[{"start":{"line":422,"column":6},"end":{"line":422,"column":6}},{"start":{"line":422,"column":6},"end":{"line":422,"column":6}}]},"42":{"line":430,"type":"if","locations":[{"start":{"line":430,"column":4},"end":{"line":430,"column":4}},{"start":{"line":430,"column":4},"end":{"line":430,"column":4}}]},"43":{"line":453,"type":"if","locations":[{"start":{"line":453,"column":4},"end":{"line":453,"column":4}},{"start":{"line":453,"column":4},"end":{"line":453,"column":4}}]},"44":{"line":461,"type":"if","locations":[{"start":{"line":461,"column":4},"end":{"line":461,"column":4}},{"start":{"line":461,"column":4},"end":{"line":461,"column":4}}]},"45":{"line":464,"type":"if","locations":[{"start":{"line":464,"column":4},"end":{"line":464,"column":4}},{"start":{"line":464,"column":4},"end":{"line":464,"column":4}}]}}},"contracts/libraries/math/MathUtils.sol":{"l":{"26":335,"28":335,"30":335,"52":675,"54":675,"55":93,"58":582,"60":582,"62":582,"64":582,"65":582,"67":582,"68":582,"70":582},"path":"/src/contracts/libraries/math/MathUtils.sol","s":{"1":335,"2":335,"3":335,"4":675,"5":675,"6":93,"7":582,"8":582,"9":582,"10":582,"11":582,"12":582,"13":582,"14":582},"b":{"1":[93,582]},"f":{"1":335,"2":675},"fnMap":{"1":{"name":"calculateLinearInterest","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"calculateCompoundedInterest","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":78}},"2":{"start":{"line":28,"column":4},"end":{"line":28,"column":85}},"3":{"start":{"line":30,"column":4},"end":{"line":30,"column":55}},"4":{"start":{"line":52,"column":4},"end":{"line":52,"column":67}},"5":{"start":{"line":54,"column":4},"end":{"line":54,"column":1957}},"6":{"start":{"line":55,"column":6},"end":{"line":55,"column":29}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":33}},"8":{"start":{"line":60,"column":4},"end":{"line":60,"column":47}},"9":{"start":{"line":62,"column":4},"end":{"line":62,"column":51}},"10":{"start":{"line":64,"column":4},"end":{"line":64,"column":62}},"11":{"start":{"line":65,"column":4},"end":{"line":65,"column":63}},"12":{"start":{"line":67,"column":4},"end":{"line":67,"column":67}},"13":{"start":{"line":68,"column":4},"end":{"line":68,"column":85}},"14":{"start":{"line":70,"column":4},"end":{"line":70,"column":86}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":54,"column":4}},{"start":{"line":54,"column":4},"end":{"line":54,"column":4}}]}}},"contracts/libraries/math/PercentageMath.sol":{"l":{"25":343,"26":148,"29":195,"31":195,"33":195,"35":195,"37":195,"47":58,"48":58,"50":58,"52":58,"54":58,"56":58,"58":58},"path":"/src/contracts/libraries/math/PercentageMath.sol","s":{"1":343,"2":148,"3":195,"4":195,"5":195,"6":195,"7":195,"8":58,"9":58,"10":58,"11":58,"12":58,"13":58,"14":58},"b":{"1":[148,195],"2":[195,0],"3":[195,0],"4":[58,0],"5":[58,0],"6":[58,0]},"f":{"1":343,"2":58},"fnMap":{"1":{"name":"percentMul","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"percentDiv","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":59,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":891}},"2":{"start":{"line":26,"column":6},"end":{"line":26,"column":14}},"3":{"start":{"line":29,"column":4},"end":{"line":29,"column":39}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":72}},"5":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"6":{"start":{"line":35,"column":4},"end":{"line":35,"column":60}},"7":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"8":{"start":{"line":47,"column":4},"end":{"line":47,"column":52}},"9":{"start":{"line":48,"column":4},"end":{"line":48,"column":43}},"10":{"start":{"line":50,"column":4},"end":{"line":50,"column":46}},"11":{"start":{"line":52,"column":4},"end":{"line":52,"column":79}},"12":{"start":{"line":54,"column":4},"end":{"line":54,"column":27}},"13":{"start":{"line":56,"column":4},"end":{"line":56,"column":62}},"14":{"start":{"line":58,"column":4},"end":{"line":58,"column":30}}},"branchMap":{"1":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":25,"column":4}},{"start":{"line":25,"column":4},"end":{"line":25,"column":4}}]},"2":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"3":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"4":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]},"5":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"6":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]}}},"contracts/libraries/math/SafeMath.sol":{"l":{"28":450,"29":450,"31":450,"44":124,"61":212,"62":211,"64":211,"80":0,"81":0,"84":0,"85":0,"87":0,"102":0,"122":0,"123":0,"126":0,"141":0,"160":0,"161":0},"path":"/src/contracts/libraries/math/SafeMath.sol","s":{"1":450,"2":450,"3":450,"4":124,"5":212,"6":211,"7":211,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0},"b":{"1":[450,0],"2":[211,1],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0]},"f":{"1":450,"2":124,"3":212,"4":0,"5":0,"6":0,"7":0,"8":0},"fnMap":{"1":{"name":"add","line":27,"loc":{"start":{"line":27,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"sub","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"sub","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":65,"column":2}}},"4":{"name":"mul","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":88,"column":2}}},"5":{"name":"div","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"6":{"name":"div","line":116,"loc":{"start":{"line":116,"column":2},"end":{"line":127,"column":2}}},"7":{"name":"mod","line":140,"loc":{"start":{"line":140,"column":2},"end":{"line":142,"column":2}}},"8":{"name":"mod","line":155,"loc":{"start":{"line":155,"column":2},"end":{"line":162,"column":2}}}},"statementMap":{"1":{"start":{"line":28,"column":4},"end":{"line":28,"column":21}},"2":{"start":{"line":29,"column":4},"end":{"line":29,"column":49}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":12}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":54}},"5":{"start":{"line":61,"column":4},"end":{"line":61,"column":32}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":21}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":12}},"8":{"start":{"line":80,"column":4},"end":{"line":80,"column":2341}},"9":{"start":{"line":81,"column":6},"end":{"line":81,"column":14}},"10":{"start":{"line":84,"column":4},"end":{"line":84,"column":21}},"11":{"start":{"line":85,"column":4},"end":{"line":85,"column":59}},"12":{"start":{"line":87,"column":4},"end":{"line":87,"column":12}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":50}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":31}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":21}},"16":{"start":{"line":126,"column":4},"end":{"line":126,"column":12}},"17":{"start":{"line":141,"column":4},"end":{"line":141,"column":48}},"18":{"start":{"line":160,"column":4},"end":{"line":160,"column":32}},"19":{"start":{"line":161,"column":4},"end":{"line":161,"column":16}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]},"2":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":61,"column":4}},{"start":{"line":61,"column":4},"end":{"line":61,"column":4}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":4},"end":{"line":80,"column":4}},{"start":{"line":80,"column":4},"end":{"line":80,"column":4}}]},"4":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"5":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]},"6":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]}}},"contracts/libraries/math/WadRayMath.sol":{"l":{"25":1047,"33":0,"40":0,"47":0,"57":0,"58":0,"61":0,"63":0,"65":0,"67":0,"69":0,"79":64,"81":64,"83":64,"85":64,"87":64,"89":64,"91":64,"101":4965,"102":1571,"105":3394,"107":3394,"109":3394,"111":3394,"113":3394,"123":1245,"125":1245,"127":1245,"129":1245,"131":1245,"133":1245,"135":1245,"144":0,"145":0,"146":0,"148":0,"157":1110,"158":1110,"159":1110},"path":"/src/contracts/libraries/math/WadRayMath.sol","s":{"1":1047,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":64,"13":64,"14":64,"15":64,"16":64,"17":64,"18":64,"19":4965,"20":1571,"21":3394,"22":3394,"23":3394,"24":3394,"25":3394,"26":1245,"27":1245,"28":1245,"29":1245,"30":1245,"31":1245,"32":1245,"33":0,"34":0,"35":0,"36":0,"37":1110,"38":1110,"39":1110},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[64,0],"5":[64,0],"6":[64,0],"7":[1571,3394],"8":[3394,0],"9":[3394,0],"10":[1245,0],"11":[1245,0],"12":[1245,0],"13":[0,0],"14":[1110,0]},"f":{"1":1047,"2":0,"3":0,"4":0,"5":0,"6":64,"7":4965,"8":1245,"9":0,"10":1110},"fnMap":{"1":{"name":"ray","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":2}}},"2":{"name":"wad","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"halfRay","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}},"4":{"name":"halfWad","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"5":{"name":"wadMul","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":70,"column":2}}},"6":{"name":"wadDiv","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"rayMul","line":100,"loc":{"start":{"line":100,"column":2},"end":{"line":114,"column":2}}},"8":{"name":"rayDiv","line":122,"loc":{"start":{"line":122,"column":2},"end":{"line":136,"column":2}}},"9":{"name":"rayToWad","line":143,"loc":{"start":{"line":143,"column":2},"end":{"line":149,"column":2}}},"10":{"name":"wadToRay","line":156,"loc":{"start":{"line":156,"column":2},"end":{"line":160,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":14}},"2":{"start":{"line":33,"column":4},"end":{"line":33,"column":14}},"3":{"start":{"line":40,"column":4},"end":{"line":40,"column":18}},"4":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}},"5":{"start":{"line":57,"column":4},"end":{"line":57,"column":1244}},"6":{"start":{"line":58,"column":6},"end":{"line":58,"column":14}},"7":{"start":{"line":61,"column":4},"end":{"line":61,"column":26}},"8":{"start":{"line":63,"column":4},"end":{"line":63,"column":59}},"9":{"start":{"line":65,"column":4},"end":{"line":65,"column":20}},"10":{"start":{"line":67,"column":4},"end":{"line":67,"column":55}},"11":{"start":{"line":69,"column":4},"end":{"line":69,"column":23}},"12":{"start":{"line":79,"column":4},"end":{"line":79,"column":43}},"13":{"start":{"line":81,"column":4},"end":{"line":81,"column":25}},"14":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"15":{"start":{"line":85,"column":4},"end":{"line":85,"column":61}},"16":{"start":{"line":87,"column":4},"end":{"line":87,"column":18}},"17":{"start":{"line":89,"column":4},"end":{"line":89,"column":53}},"18":{"start":{"line":91,"column":4},"end":{"line":91,"column":21}},"19":{"start":{"line":101,"column":4},"end":{"line":101,"column":2221}},"20":{"start":{"line":102,"column":6},"end":{"line":102,"column":14}},"21":{"start":{"line":105,"column":4},"end":{"line":105,"column":26}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":59}},"23":{"start":{"line":109,"column":4},"end":{"line":109,"column":20}},"24":{"start":{"line":111,"column":4},"end":{"line":111,"column":55}},"25":{"start":{"line":113,"column":4},"end":{"line":113,"column":23}},"26":{"start":{"line":123,"column":4},"end":{"line":123,"column":43}},"27":{"start":{"line":125,"column":4},"end":{"line":125,"column":25}},"28":{"start":{"line":127,"column":4},"end":{"line":127,"column":28}},"29":{"start":{"line":129,"column":4},"end":{"line":129,"column":61}},"30":{"start":{"line":131,"column":4},"end":{"line":131,"column":18}},"31":{"start":{"line":133,"column":4},"end":{"line":133,"column":53}},"32":{"start":{"line":135,"column":4},"end":{"line":135,"column":21}},"33":{"start":{"line":144,"column":4},"end":{"line":144,"column":41}},"34":{"start":{"line":145,"column":4},"end":{"line":145,"column":34}},"35":{"start":{"line":146,"column":4},"end":{"line":146,"column":57}},"36":{"start":{"line":148,"column":4},"end":{"line":148,"column":33}},"37":{"start":{"line":157,"column":4},"end":{"line":157,"column":38}},"38":{"start":{"line":158,"column":4},"end":{"line":158,"column":71}},"39":{"start":{"line":159,"column":4},"end":{"line":159,"column":17}}},"branchMap":{"1":{"line":57,"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":57,"column":4}},{"start":{"line":57,"column":4},"end":{"line":57,"column":4}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":63,"column":4}},{"start":{"line":63,"column":4},"end":{"line":63,"column":4}}]},"3":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"4":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":4}},{"start":{"line":79,"column":4},"end":{"line":79,"column":4}}]},"5":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"6":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":4}},{"start":{"line":89,"column":4},"end":{"line":89,"column":4}}]},"7":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":4},"end":{"line":101,"column":4}},{"start":{"line":101,"column":4},"end":{"line":101,"column":4}}]},"8":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":4},"end":{"line":107,"column":4}},{"start":{"line":107,"column":4},"end":{"line":107,"column":4}}]},"9":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"10":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":4},"end":{"line":123,"column":4}},{"start":{"line":123,"column":4},"end":{"line":123,"column":4}}]},"11":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":4},"end":{"line":129,"column":4}},{"start":{"line":129,"column":4},"end":{"line":129,"column":4}}]},"12":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":4}},{"start":{"line":133,"column":4},"end":{"line":133,"column":4}}]},"13":{"line":146,"type":"if","locations":[{"start":{"line":146,"column":4},"end":{"line":146,"column":4}},{"start":{"line":146,"column":4},"end":{"line":146,"column":4}}]},"14":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":4},"end":{"line":158,"column":4}},{"start":{"line":158,"column":4},"end":{"line":158,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol":{"l":{"26":0,"27":0,"34":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0},"b":{"1":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":21,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"_willFallback","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":79}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":20}},"3":{"start":{"line":34,"column":4},"end":{"line":34,"column":47}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":4},"end":{"line":26,"column":4}},{"start":{"line":26,"column":4},"end":{"line":26,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol":{"l":{"35":3,"36":3,"38":0,"46":0,"53":0,"62":0,"63":0,"64":0,"73":0,"90":3,"91":3,"92":3,"99":9901,"101":9901,"111":53,"113":53,"122":9898,"123":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":3,"10":3,"11":3,"12":9901,"13":53,"14":9898,"15":9898},"b":{"1":[3,0],"2":[0,0],"3":[3,0],"4":[9898,0]},"f":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":3,"7":9901,"8":53,"9":9898},"fnMap":{"1":{"name":"ifAdmin","line":34,"loc":{"start":{"line":34,"column":2},"end":{"line":40,"column":2}}},"2":{"name":"admin","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":47,"column":2}}},"3":{"name":"implementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":54,"column":2}}},"4":{"name":"changeAdmin","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"upgradeTo","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"upgradeToAndCall","line":88,"loc":{"start":{"line":85,"column":2},"end":{"line":93,"column":2}}},"7":{"name":"_admin","line":98,"loc":{"start":{"line":98,"column":2},"end":{"line":104,"column":2}}},"8":{"name":"_setAdmin","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":116,"column":2}}},"9":{"name":"_willFallback","line":121,"loc":{"start":{"line":121,"column":2},"end":{"line":124,"column":2}}}},"statementMap":{"1":{"start":{"line":35,"column":4},"end":{"line":35,"column":1284}},"2":{"start":{"line":38,"column":6},"end":{"line":38,"column":16}},"3":{"start":{"line":46,"column":4},"end":{"line":46,"column":19}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":28}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":92}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":41}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":22}},"8":{"start":{"line":73,"column":4},"end":{"line":73,"column":32}},"9":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"10":{"start":{"line":91,"column":4},"end":{"line":91,"column":59}},"11":{"start":{"line":92,"column":4},"end":{"line":92,"column":19}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":29}},"13":{"start":{"line":111,"column":4},"end":{"line":111,"column":29}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":88}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":24}}},"branchMap":{"1":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"2":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"3":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":4}},{"start":{"line":92,"column":4},"end":{"line":92,"column":4}}]},"4":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol":{"l":{"32":10004,"34":10004,"44":3,"45":3,"53":56,"58":56,"61":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol","s":{"1":10004,"2":3,"3":3,"4":56,"5":56},"b":{"1":[56,0]},"f":{"1":10004,"2":3,"3":56},"fnMap":{"1":{"name":"_implementation","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":37,"column":2}}},"2":{"name":"_upgradeTo","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"_setImplementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":64,"column":2}}}},"statementMap":{"1":{"start":{"line":32,"column":4},"end":{"line":32,"column":38}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":40}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":36}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":1706}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":38}}},"branchMap":{"1":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":53,"column":4}},{"start":{"line":53,"column":4},"end":{"line":53,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/Initializable.sol":{"l":{"31":0,"36":0,"37":0,"38":0,"39":0,"42":0,"44":0,"45":0,"56":0,"58":0,"61":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Initializable.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"initializer","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"isConstructor","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":62,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1056}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":39}},"3":{"start":{"line":37,"column":4},"end":{"line":37,"column":1228}},"4":{"start":{"line":38,"column":6},"end":{"line":38,"column":24}},"5":{"start":{"line":39,"column":6},"end":{"line":39,"column":23}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":1322}},"7":{"start":{"line":45,"column":6},"end":{"line":45,"column":25}},"8":{"start":{"line":56,"column":4},"end":{"line":56,"column":14}},"9":{"start":{"line":61,"column":4},"end":{"line":61,"column":18}}},"branchMap":{"1":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":4}},{"start":{"line":37,"column":4},"end":{"line":37,"column":4}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol":{"l":{"30":53,"31":53,"32":53,"33":53,"40":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":9898},"b":{"1":[53,0],"2":[53,0]},"f":{"1":53,"2":9898},"fnMap":{"1":{"name":"initialize","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"_willFallback","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":43}},"2":{"start":{"line":31,"column":4},"end":{"line":31,"column":59}},"3":{"start":{"line":32,"column":4},"end":{"line":32,"column":79}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":19}},"5":{"start":{"line":40,"column":4},"end":{"line":40,"column":47}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":4},"end":{"line":30,"column":4}},{"start":{"line":30,"column":4},"end":{"line":30,"column":4}}]},"2":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":4}},{"start":{"line":32,"column":4},"end":{"line":32,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol":{"l":{"21":53,"22":53,"23":53,"24":53,"25":53,"26":53},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":53,"6":53},"b":{"1":[53,0],"2":[53,0],"3":[53,0],"4":[53,0]},"f":{"1":53},"fnMap":{"1":{"name":"initialize","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":43}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":97}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":29}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":1119}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":51}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":22,"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":22,"column":4}},{"start":{"line":22,"column":4},"end":{"line":22,"column":4}}]},"3":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":4},"end":{"line":24,"column":4}},{"start":{"line":24,"column":4},"end":{"line":24,"column":4}}]},"4":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":6},"end":{"line":26,"column":6}},{"start":{"line":26,"column":6},"end":{"line":26,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/Proxy.sol":{"l":{"17":9898,"33":9898,"69":9898,"70":9898},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Proxy.sol","s":{"1":9898,"2":9898,"3":9898},"b":{},"f":{"1":9898,"2":9898,"3":9898,"4":9898},"fnMap":{"1":{"name":null,"line":16,"loc":{"start":{"line":16,"column":2},"end":{"line":18,"column":2}}},"2":{"name":"_delegate","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":55,"column":2}}},"3":{"name":"_willFallback","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":45}}},"4":{"name":"_fallback","line":68,"loc":{"start":{"line":68,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":17,"column":4},"end":{"line":17,"column":14}},"2":{"start":{"line":69,"column":4},"end":{"line":69,"column":18}},"3":{"start":{"line":70,"column":4},"end":{"line":70,"column":31}}},"branchMap":{}},"contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol":{"l":{"21":0,"22":0,"23":0,"24":0,"25":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":27,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":97}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":29}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":1038}},"4":{"start":{"line":24,"column":6},"end":{"line":24,"column":51}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":4}},{"start":{"line":23,"column":4},"end":{"line":23,"column":4}}]},"3":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":6},"end":{"line":25,"column":6}},{"start":{"line":25,"column":6},"end":{"line":25,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol":{"l":{"33":56,"34":56,"39":56,"40":56,"41":56,"42":56,"45":56,"47":56,"48":56,"63":56,"65":56,"68":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol","s":{"1":56,"2":56,"3":56,"4":56,"5":56,"6":56,"7":56,"8":56,"9":56,"10":56},"b":{"1":[56,0],"2":[56,0],"3":[56,0]},"f":{"1":56,"2":56},"fnMap":{"1":{"name":"initializer","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":50,"column":2}}},"2":{"name":"isConstructor","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":69,"column":2}}}},"statementMap":{"1":{"start":{"line":33,"column":4},"end":{"line":33,"column":36}},"2":{"start":{"line":34,"column":4},"end":{"line":34,"column":1202}},"3":{"start":{"line":39,"column":4},"end":{"line":39,"column":39}},"4":{"start":{"line":40,"column":4},"end":{"line":40,"column":1396}},"5":{"start":{"line":41,"column":6},"end":{"line":41,"column":24}},"6":{"start":{"line":42,"column":6},"end":{"line":42,"column":39}},"7":{"start":{"line":47,"column":4},"end":{"line":47,"column":1506}},"8":{"start":{"line":48,"column":6},"end":{"line":48,"column":25}},"9":{"start":{"line":63,"column":4},"end":{"line":63,"column":14}},"10":{"start":{"line":68,"column":4},"end":{"line":68,"column":18}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]}}},"contracts/misc/AaveProtocolTestHelpers.sol":{"l":{"18":3,"22":1,"23":1,"24":1,"25":1,"26":17,"33":1,"37":2,"38":2,"39":2,"40":2,"41":34,"42":34,"47":2},"path":"/src/contracts/misc/AaveProtocolTestHelpers.sol","s":{"1":3,"2":1,"3":1,"4":1,"5":1,"6":17,"7":1,"8":2,"9":2,"10":2,"11":2,"12":34,"13":34,"14":2},"b":{},"f":{"1":3,"2":1,"3":2},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}},"2":{"name":"getAllReservesTokens","line":21,"loc":{"start":{"line":21,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"getAllATokens","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":48,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":41}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":73}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":50}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":72}},"5":{"start":{"line":25,"column":4},"end":{"line":25,"column":904}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":961}},"7":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"8":{"start":{"line":37,"column":4},"end":{"line":37,"column":73}},"9":{"start":{"line":38,"column":4},"end":{"line":38,"column":50}},"10":{"start":{"line":39,"column":4},"end":{"line":39,"column":65}},"11":{"start":{"line":40,"column":4},"end":{"line":40,"column":1486}},"12":{"start":{"line":41,"column":6},"end":{"line":41,"column":79}},"13":{"start":{"line":42,"column":6},"end":{"line":42,"column":1624}},"14":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}}},"branchMap":{}},"contracts/misc/Address.sol":{"l":{"29":99,"30":99,"32":99,"35":99,"55":0,"58":0,"59":0},"path":"/src/contracts/misc/Address.sol","s":{"1":99,"2":99,"3":99,"4":0,"5":0,"6":0},"b":{"1":[0,0],"2":[0,0]},"f":{"1":99,"2":0},"fnMap":{"1":{"name":"isContract","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":36,"column":2}}},"2":{"name":"sendValue","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":60,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":20}},"2":{"start":{"line":30,"column":4},"end":{"line":30,"column":92}},"3":{"start":{"line":35,"column":4},"end":{"line":35,"column":55}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":76}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":56}},"6":{"start":{"line":59,"column":4},"end":{"line":59,"column":81}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":4},"end":{"line":59,"column":4}},{"start":{"line":59,"column":4},"end":{"line":59,"column":4}}]}}},"contracts/misc/ChainlinkProxyPriceProvider.sol":{"l":{"37":3,"38":3,"48":0,"55":0,"62":3,"63":3,"64":72,"65":72,"72":3,"73":3,"79":0,"81":0,"82":0,"84":0,"85":0,"86":0,"88":0,"96":0,"97":0,"98":0,"100":0,"107":0,"113":0},"path":"/src/contracts/misc/ChainlinkProxyPriceProvider.sol","s":{"1":3,"2":3,"3":0,"4":0,"5":3,"6":3,"7":72,"8":72,"9":3,"10":3,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0},"b":{"1":[3,0],"2":[0,0],"3":[0,0]},"f":{"1":3,"2":0,"3":0,"4":3,"5":3,"6":0,"7":0,"8":0,"9":0},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setAssetSources","line":46,"loc":{"start":{"line":44,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"setFallbackOracle","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"_setAssetsSources","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"_setFallbackOracle","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"getAssetPrice","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"getAssetsPrices","line":95,"loc":{"start":{"line":95,"column":2},"end":{"line":101,"column":2}}},"8":{"name":"getSourceOfAsset","line":106,"loc":{"start":{"line":106,"column":2},"end":{"line":108,"column":2}}},"9":{"name":"getFallbackOracle","line":112,"loc":{"start":{"line":112,"column":2},"end":{"line":114,"column":2}}}},"statementMap":{"1":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"2":{"start":{"line":38,"column":4},"end":{"line":38,"column":37}},"3":{"start":{"line":48,"column":4},"end":{"line":48,"column":37}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":37}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":73}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":2670}},"7":{"start":{"line":64,"column":6},"end":{"line":64,"column":64}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":52}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":55}},"10":{"start":{"line":73,"column":4},"end":{"line":73,"column":46}},"11":{"start":{"line":79,"column":4},"end":{"line":79,"column":54}},"12":{"start":{"line":81,"column":4},"end":{"line":81,"column":3446}},"13":{"start":{"line":82,"column":6},"end":{"line":82,"column":49}},"14":{"start":{"line":84,"column":6},"end":{"line":84,"column":64}},"15":{"start":{"line":85,"column":6},"end":{"line":85,"column":3621}},"16":{"start":{"line":86,"column":8},"end":{"line":86,"column":29}},"17":{"start":{"line":88,"column":8},"end":{"line":88,"column":51}},"18":{"start":{"line":96,"column":4},"end":{"line":96,"column":58}},"19":{"start":{"line":97,"column":4},"end":{"line":97,"column":4032}},"20":{"start":{"line":98,"column":6},"end":{"line":98,"column":41}},"21":{"start":{"line":100,"column":4},"end":{"line":100,"column":17}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"23":{"start":{"line":113,"column":4},"end":{"line":113,"column":35}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"2":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":81,"column":4}},{"start":{"line":81,"column":4},"end":{"line":81,"column":4}}]},"3":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":6},"end":{"line":85,"column":6}},{"start":{"line":85,"column":6},"end":{"line":85,"column":6}}]}}},"contracts/misc/Context.sol":{"l":{"16":4,"20":0,"21":0},"path":"/src/contracts/misc/Context.sol","s":{"1":4,"2":0},"b":{},"f":{"1":4,"2":0},"fnMap":{"1":{"name":"_msgSender","line":15,"loc":{"start":{"line":15,"column":2},"end":{"line":17,"column":2}}},"2":{"name":"_msgData","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":22,"column":2}}}},"statementMap":{"1":{"start":{"line":16,"column":4},"end":{"line":16,"column":21}},"2":{"start":{"line":21,"column":4},"end":{"line":21,"column":19}}},"branchMap":{}},"contracts/misc/IERC20DetailedBytes.sol":{"l":{},"path":"/src/contracts/misc/IERC20DetailedBytes.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/misc/SafeERC20.sol":{"l":{"27":99,"36":0,"44":0,"48":0,"52":99,"55":99,"56":99,"58":97,"61":97},"path":"/src/contracts/misc/SafeERC20.sol","s":{"1":99,"2":0,"3":0,"4":0,"5":99,"6":99,"7":99,"8":97,"9":97},"b":{"1":[0,0],"2":[99,0],"3":[97,2],"4":[97,0],"5":[97,0]},"f":{"1":99,"2":0,"3":0,"4":99},"fnMap":{"1":{"name":"safeTransfer","line":22,"loc":{"start":{"line":22,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"safeTransferFrom","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":37,"column":2}}},"3":{"name":"safeApprove","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"callOptionalReturn","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":63,"column":2}}}},"statementMap":{"1":{"start":{"line":27,"column":4},"end":{"line":27,"column":88}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":98}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1254}},"4":{"start":{"line":48,"column":4},"end":{"line":48,"column":92}},"5":{"start":{"line":52,"column":4},"end":{"line":52,"column":74}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":71}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":55}},"8":{"start":{"line":58,"column":4},"end":{"line":58,"column":1845}},"9":{"start":{"line":61,"column":6},"end":{"line":61,"column":90}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]},"4":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":4}},{"start":{"line":58,"column":4},"end":{"line":58,"column":4}}]},"5":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":6}},{"start":{"line":61,"column":6},"end":{"line":61,"column":6}}]}}},"contracts/misc/WalletBalanceProvider.sol":{"l":{"26":3,"34":0,"45":0,"46":0,"48":0,"63":0,"65":0,"66":0,"67":0,"68":0,"69":0,"71":0,"76":0,"87":0,"89":0,"91":0,"93":0,"94":0,"96":0,"97":0,"98":0,"100":0,"103":0},"path":"/src/contracts/misc/WalletBalanceProvider.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0]},"f":{"1":3,"2":0,"3":0,"4":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":27,"column":2}}},"2":{"name":"balanceOf","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"batchBalanceOf","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":77,"column":2}}},"4":{"name":"getUserWalletBalances","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":104,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":4},"end":{"line":45,"column":1672}},"3":{"start":{"line":46,"column":6},"end":{"line":46,"column":42}},"4":{"start":{"line":48,"column":6},"end":{"line":48,"column":14}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":75}},"6":{"start":{"line":65,"column":4},"end":{"line":65,"column":2271}},"7":{"start":{"line":66,"column":6},"end":{"line":66,"column":2324}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":43}},"9":{"start":{"line":68,"column":8},"end":{"line":68,"column":2425}},"10":{"start":{"line":69,"column":10},"end":{"line":69,"column":32}},"11":{"start":{"line":71,"column":10},"end":{"line":71,"column":63}},"12":{"start":{"line":76,"column":4},"end":{"line":76,"column":19}},"13":{"start":{"line":87,"column":4},"end":{"line":87,"column":64}},"14":{"start":{"line":89,"column":4},"end":{"line":89,"column":50}},"15":{"start":{"line":91,"column":4},"end":{"line":91,"column":62}},"16":{"start":{"line":93,"column":4},"end":{"line":93,"column":3026}},"17":{"start":{"line":94,"column":6},"end":{"line":94,"column":89}},"18":{"start":{"line":96,"column":6},"end":{"line":96,"column":3174}},"19":{"start":{"line":97,"column":8},"end":{"line":97,"column":22}},"20":{"start":{"line":100,"column":6},"end":{"line":100,"column":47}},"21":{"start":{"line":103,"column":4},"end":{"line":103,"column":31}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"3":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":68,"column":8}},{"start":{"line":68,"column":8},"end":{"line":68,"column":8}}]},"4":{"line":96,"type":"if","locations":[{"start":{"line":96,"column":6},"end":{"line":96,"column":6}},{"start":{"line":96,"column":6},"end":{"line":96,"column":6}}]}}},"contracts/tokenization/AToken.sol":{"l":{"45":211,"46":207,"57":54,"58":54,"59":54,"63":17,"71":17,"74":17,"78":17,"88":17,"89":17,"90":17,"104":42,"107":41,"110":41,"111":41,"126":105,"129":105,"130":105,"134":0,"137":0,"138":0,"155":2,"170":641,"180":333,"195":0,"205":3,"207":3,"208":0,"211":3,"219":0,"229":4,"245":58,"246":56,"268":6,"270":5,"271":3,"272":3,"279":3,"280":0,"281":0,"298":6,"299":4,"302":4,"304":4,"306":4,"320":4,"327":0},"path":"/src/contracts/tokenization/AToken.sol","s":{"1":211,"2":54,"3":54,"4":54,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":42,"12":41,"13":41,"14":41,"15":105,"16":105,"17":105,"18":0,"19":0,"20":0,"21":2,"22":641,"23":333,"24":0,"25":3,"26":3,"27":0,"28":3,"29":0,"30":4,"31":58,"32":56,"33":6,"34":5,"35":3,"36":3,"37":3,"38":0,"39":0,"40":6,"41":4,"42":4,"43":4,"44":4,"45":4},"b":{"1":[207,4],"2":[0,3],"3":[5,1],"4":[3,2],"5":[0,3],"6":[4,2],"7":[2,2]},"f":{"1":211,"2":54,"3":17,"4":17,"5":42,"6":105,"7":0,"8":2,"9":641,"10":333,"11":0,"12":3,"13":0,"14":4,"15":58,"16":6,"17":6,"18":4},"fnMap":{"1":{"name":"onlyLendingPool","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"constructor","line":56,"loc":{"start":{"line":49,"column":2},"end":{"line":60,"column":2}}},"3":{"name":"getRevision","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"initialize","line":70,"loc":{"start":{"line":66,"column":2},"end":{"line":91,"column":2}}},"5":{"name":"burn","line":103,"loc":{"start":{"line":98,"column":2},"end":{"line":112,"column":2}}},"6":{"name":"mint","line":124,"loc":{"start":{"line":120,"column":2},"end":{"line":131,"column":2}}},"7":{"name":"mintToTreasury","line":133,"loc":{"start":{"line":133,"column":2},"end":{"line":139,"column":2}}},"8":{"name":"transferOnLiquidation","line":152,"loc":{"start":{"line":148,"column":2},"end":{"line":156,"column":2}}},"9":{"name":"balanceOf","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":171,"column":2}}},"10":{"name":"scaledBalanceOf","line":179,"loc":{"start":{"line":179,"column":2},"end":{"line":181,"column":2}}},"11":{"name":"getScaledUserBalanceAndSupply","line":189,"loc":{"start":{"line":189,"column":2},"end":{"line":196,"column":2}}},"12":{"name":"totalSupply","line":204,"loc":{"start":{"line":204,"column":2},"end":{"line":212,"column":2}}},"13":{"name":"scaledTotalSupply","line":218,"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":2}}},"14":{"name":"isTransferAllowed","line":228,"loc":{"start":{"line":228,"column":2},"end":{"line":230,"column":2}}},"15":{"name":"transferUnderlyingTo","line":242,"loc":{"start":{"line":239,"column":2},"end":{"line":247,"column":2}}},"16":{"name":"permit","line":259,"loc":{"start":{"line":259,"column":2},"end":{"line":282,"column":2}}},"17":{"name":"_transfer","line":292,"loc":{"start":{"line":292,"column":2},"end":{"line":307,"column":2}}},"18":{"name":"_transfer","line":315,"loc":{"start":{"line":315,"column":2},"end":{"line":321,"column":2}}}},"statementMap":{"1":{"start":{"line":45,"column":4},"end":{"line":45,"column":75}},"2":{"start":{"line":57,"column":4},"end":{"line":57,"column":14}},"3":{"start":{"line":58,"column":4},"end":{"line":58,"column":52}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":52}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":26}},"6":{"start":{"line":71,"column":4},"end":{"line":71,"column":19}},"7":{"start":{"line":78,"column":4},"end":{"line":78,"column":2480}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":22}},"9":{"start":{"line":89,"column":4},"end":{"line":89,"column":26}},"10":{"start":{"line":90,"column":4},"end":{"line":90,"column":40}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":36}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":78}},"13":{"start":{"line":110,"column":4},"end":{"line":110,"column":43}},"14":{"start":{"line":111,"column":4},"end":{"line":111,"column":62}},"15":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}},"16":{"start":{"line":129,"column":4},"end":{"line":129,"column":43}},"17":{"start":{"line":130,"column":4},"end":{"line":130,"column":34}},"18":{"start":{"line":134,"column":4},"end":{"line":134,"column":53}},"19":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"20":{"start":{"line":138,"column":4},"end":{"line":138,"column":54}},"21":{"start":{"line":155,"column":4},"end":{"line":155,"column":36}},"22":{"start":{"line":170,"column":4},"end":{"line":170,"column":98}},"23":{"start":{"line":180,"column":4},"end":{"line":180,"column":32}},"24":{"start":{"line":195,"column":4},"end":{"line":195,"column":55}},"25":{"start":{"line":205,"column":4},"end":{"line":205,"column":53}},"26":{"start":{"line":207,"column":4},"end":{"line":207,"column":6560}},"27":{"start":{"line":208,"column":6},"end":{"line":208,"column":14}},"28":{"start":{"line":211,"column":4},"end":{"line":211,"column":96}},"29":{"start":{"line":219,"column":4},"end":{"line":219,"column":30}},"30":{"start":{"line":229,"column":4},"end":{"line":229,"column":78}},"31":{"start":{"line":245,"column":4},"end":{"line":245,"column":64}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":17}},"33":{"start":{"line":268,"column":4},"end":{"line":268,"column":48}},"34":{"start":{"line":270,"column":4},"end":{"line":270,"column":61}},"35":{"start":{"line":271,"column":4},"end":{"line":271,"column":46}},"36":{"start":{"line":272,"column":4},"end":{"line":272,"column":8691}},"37":{"start":{"line":279,"column":4},"end":{"line":279,"column":68}},"38":{"start":{"line":280,"column":4},"end":{"line":280,"column":44}},"39":{"start":{"line":281,"column":4},"end":{"line":281,"column":34}},"40":{"start":{"line":298,"column":4},"end":{"line":298,"column":9504}},"41":{"start":{"line":299,"column":6},"end":{"line":299,"column":74}},"42":{"start":{"line":302,"column":4},"end":{"line":302,"column":77}},"43":{"start":{"line":304,"column":4},"end":{"line":304,"column":50}},"44":{"start":{"line":306,"column":4},"end":{"line":306,"column":49}},"45":{"start":{"line":320,"column":4},"end":{"line":320,"column":36}}},"branchMap":{"1":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"4":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"5":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":4},"end":{"line":279,"column":4}},{"start":{"line":279,"column":4},"end":{"line":279,"column":4}}]},"6":{"line":298,"type":"if","locations":[{"start":{"line":298,"column":4},"end":{"line":298,"column":4}},{"start":{"line":298,"column":4},"end":{"line":298,"column":4}}]},"7":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":6},"end":{"line":299,"column":6}},{"start":{"line":299,"column":6},"end":{"line":299,"column":6}}]}}},"contracts/tokenization/base/DebtTokenBase.sol":{"l":{"29":99,"30":95,"44":108,"45":108,"59":36,"60":36,"61":36,"65":0,"73":0,"74":0,"75":0,"85":0,"86":0,"87":0,"91":0,"92":0,"93":0,"101":0,"102":0,"103":0,"104":0,"113":0,"114":0,"115":0,"124":0,"125":0,"126":0},"path":"/src/contracts/tokenization/base/DebtTokenBase.sol","s":{"1":99,"2":108,"3":108,"4":36,"5":36,"6":36,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0},"b":{"1":[95,4]},"f":{"1":99,"2":108,"3":36,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},"fnMap":{"1":{"name":"onlyLendingPool","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"constructor","line":43,"loc":{"start":{"line":37,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"initialize","line":58,"loc":{"start":{"line":54,"column":2},"end":{"line":62,"column":2}}},"4":{"name":"underlyingAssetAddress","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"5":{"name":"transfer","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"allowance","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":88,"column":2}}},"7":{"name":"approve","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"transferFrom","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":105,"column":2}}},"9":{"name":"increaseAllowance","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":116,"column":2}}},"10":{"name":"decreaseAllowance","line":118,"loc":{"start":{"line":118,"column":2},"end":{"line":127,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":75}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":28}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":44}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":17}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":21}},"6":{"start":{"line":61,"column":4},"end":{"line":61,"column":25}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":27}},"8":{"start":{"line":75,"column":4},"end":{"line":75,"column":35}},"9":{"start":{"line":87,"column":4},"end":{"line":87,"column":36}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":35}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":35}},"12":{"start":{"line":115,"column":4},"end":{"line":115,"column":36}},"13":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]}}},"contracts/tokenization/IncentivizedERC20.sol":{"l":{"34":162,"35":162,"36":162,"37":162,"44":67,"51":88,"58":0,"65":2318,"72":2652,"82":4,"83":2,"84":2,"100":4,"109":0,"110":0,"125":0,"126":0,"131":0,"132":0,"142":0,"143":0,"157":0,"165":0,"173":4,"174":4,"176":4,"178":4,"179":4,"180":4,"181":4,"183":4,"184":0,"185":0,"186":0,"187":0,"193":131,"195":131,"197":131,"198":131,"200":131,"201":131,"203":131,"204":0,"209":67,"211":67,"213":67,"214":67,"216":67,"217":67,"219":66,"220":0,"229":0,"230":0,"232":0,"233":0,"237":54,"241":54,"245":54},"path":"/src/contracts/tokenization/IncentivizedERC20.sol","s":{"1":162,"2":162,"3":162,"4":162,"5":67,"6":88,"7":0,"8":2318,"9":2652,"10":4,"11":2,"12":2,"13":4,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":4,"25":4,"26":4,"27":4,"28":4,"29":4,"30":4,"31":4,"32":0,"33":0,"34":0,"35":0,"36":131,"37":131,"38":131,"39":131,"40":131,"41":131,"42":131,"43":0,"44":67,"45":67,"46":67,"47":67,"48":67,"49":67,"50":66,"51":0,"52":0,"53":0,"54":0,"55":0,"56":54,"57":54,"58":54},"b":{"1":[4,0],"2":[4,0],"3":[0,4],"4":[0,0],"5":[131,0],"6":[0,131],"7":[67,0],"8":[0,66],"9":[0,0],"10":[0,0]},"f":{"1":162,"2":67,"3":88,"4":0,"5":2318,"6":2652,"7":4,"8":4,"9":0,"10":0,"11":0,"12":0,"13":4,"14":131,"15":67,"16":0,"17":54,"18":54,"19":54,"20":202},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"name","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"symbol","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":2}}},"4":{"name":"decimals","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":59,"column":2}}},"5":{"name":"totalSupply","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"7":{"name":"transfer","line":81,"loc":{"start":{"line":81,"column":2},"end":{"line":85,"column":2}}},"8":{"name":"allowance","line":93,"loc":{"start":{"line":93,"column":2},"end":{"line":101,"column":2}}},"9":{"name":"approve","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":111,"column":2}}},"10":{"name":"transferFrom","line":120,"loc":{"start":{"line":120,"column":2},"end":{"line":133,"column":2}}},"11":{"name":"increaseAllowance","line":141,"loc":{"start":{"line":141,"column":2},"end":{"line":144,"column":2}}},"12":{"name":"decreaseAllowance","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":166,"column":2}}},"13":{"name":"_transfer","line":168,"loc":{"start":{"line":168,"column":2},"end":{"line":190,"column":2}}},"14":{"name":"_mint","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":206,"column":2}}},"15":{"name":"_burn","line":208,"loc":{"start":{"line":208,"column":2},"end":{"line":222,"column":2}}},"16":{"name":"_approve","line":224,"loc":{"start":{"line":224,"column":2},"end":{"line":234,"column":2}}},"17":{"name":"_setName","line":236,"loc":{"start":{"line":236,"column":2},"end":{"line":238,"column":2}}},"18":{"name":"_setSymbol","line":240,"loc":{"start":{"line":240,"column":2},"end":{"line":242,"column":2}}},"19":{"name":"_setDecimals","line":244,"loc":{"start":{"line":244,"column":2},"end":{"line":246,"column":2}}},"20":{"name":"_beforeTokenTransfer","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":252,"column":22}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":15}},"2":{"start":{"line":35,"column":4},"end":{"line":35,"column":19}},"3":{"start":{"line":36,"column":4},"end":{"line":36,"column":23}},"4":{"start":{"line":37,"column":4},"end":{"line":37,"column":74}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":16}},"6":{"start":{"line":51,"column":4},"end":{"line":51,"column":18}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":20}},"8":{"start":{"line":65,"column":4},"end":{"line":65,"column":23}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":29}},"10":{"start":{"line":82,"column":4},"end":{"line":82,"column":45}},"11":{"start":{"line":83,"column":4},"end":{"line":83,"column":48}},"12":{"start":{"line":84,"column":4},"end":{"line":84,"column":15}},"13":{"start":{"line":100,"column":4},"end":{"line":100,"column":38}},"14":{"start":{"line":109,"column":4},"end":{"line":109,"column":42}},"15":{"start":{"line":110,"column":4},"end":{"line":110,"column":15}},"16":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":3648}},"18":{"start":{"line":131,"column":4},"end":{"line":131,"column":44}},"19":{"start":{"line":132,"column":4},"end":{"line":132,"column":15}},"20":{"start":{"line":142,"column":4},"end":{"line":142,"column":86}},"21":{"start":{"line":143,"column":4},"end":{"line":143,"column":15}},"22":{"start":{"line":157,"column":4},"end":{"line":157,"column":4675}},"23":{"start":{"line":165,"column":4},"end":{"line":165,"column":15}},"24":{"start":{"line":173,"column":4},"end":{"line":173,"column":73}},"25":{"start":{"line":174,"column":4},"end":{"line":174,"column":74}},"26":{"start":{"line":176,"column":4},"end":{"line":176,"column":50}},"27":{"start":{"line":178,"column":4},"end":{"line":178,"column":48}},"28":{"start":{"line":179,"column":4},"end":{"line":179,"column":93}},"29":{"start":{"line":180,"column":4},"end":{"line":180,"column":54}},"30":{"start":{"line":181,"column":4},"end":{"line":181,"column":58}},"31":{"start":{"line":183,"column":4},"end":{"line":183,"column":5459}},"32":{"start":{"line":184,"column":6},"end":{"line":184,"column":40}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":78}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":5642}},"35":{"start":{"line":187,"column":8},"end":{"line":187,"column":86}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":68}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":52}},"38":{"start":{"line":197,"column":4},"end":{"line":197,"column":41}},"39":{"start":{"line":198,"column":4},"end":{"line":198,"column":44}},"40":{"start":{"line":200,"column":4},"end":{"line":200,"column":50}},"41":{"start":{"line":201,"column":4},"end":{"line":201,"column":53}},"42":{"start":{"line":203,"column":4},"end":{"line":203,"column":6176}},"43":{"start":{"line":204,"column":6},"end":{"line":204,"column":83}},"44":{"start":{"line":209,"column":4},"end":{"line":209,"column":70}},"45":{"start":{"line":211,"column":4},"end":{"line":211,"column":52}},"46":{"start":{"line":213,"column":4},"end":{"line":213,"column":41}},"47":{"start":{"line":214,"column":4},"end":{"line":214,"column":44}},"48":{"start":{"line":216,"column":4},"end":{"line":216,"column":50}},"49":{"start":{"line":217,"column":4},"end":{"line":217,"column":91}},"50":{"start":{"line":219,"column":4},"end":{"line":219,"column":6766}},"51":{"start":{"line":220,"column":6},"end":{"line":220,"column":83}},"52":{"start":{"line":229,"column":4},"end":{"line":229,"column":71}},"53":{"start":{"line":230,"column":4},"end":{"line":230,"column":71}},"54":{"start":{"line":232,"column":4},"end":{"line":232,"column":39}},"55":{"start":{"line":233,"column":4},"end":{"line":233,"column":41}},"56":{"start":{"line":237,"column":4},"end":{"line":237,"column":18}},"57":{"start":{"line":241,"column":4},"end":{"line":241,"column":22}},"58":{"start":{"line":245,"column":4},"end":{"line":245,"column":26}}},"branchMap":{"1":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"2":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":4},"end":{"line":174,"column":4}},{"start":{"line":174,"column":4},"end":{"line":174,"column":4}}]},"3":{"line":183,"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":183,"column":4}},{"start":{"line":183,"column":4},"end":{"line":183,"column":4}}]},"4":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":6},"end":{"line":186,"column":6}},{"start":{"line":186,"column":6},"end":{"line":186,"column":6}}]},"5":{"line":193,"type":"if","locations":[{"start":{"line":193,"column":4},"end":{"line":193,"column":4}},{"start":{"line":193,"column":4},"end":{"line":193,"column":4}}]},"6":{"line":203,"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":203,"column":4}},{"start":{"line":203,"column":4},"end":{"line":203,"column":4}}]},"7":{"line":209,"type":"if","locations":[{"start":{"line":209,"column":4},"end":{"line":209,"column":4}},{"start":{"line":209,"column":4},"end":{"line":209,"column":4}}]},"8":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":4},"end":{"line":219,"column":4}},{"start":{"line":219,"column":4},"end":{"line":219,"column":4}}]},"9":{"line":229,"type":"if","locations":[{"start":{"line":229,"column":4},"end":{"line":229,"column":4}},{"start":{"line":229,"column":4},"end":{"line":229,"column":4}}]},"10":{"line":230,"type":"if","locations":[{"start":{"line":230,"column":4},"end":{"line":230,"column":4}},{"start":{"line":230,"column":4},"end":{"line":230,"column":4}}]}}},"contracts/tokenization/interfaces/IAToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IAToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IScaledBalanceToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IScaledBalanceToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IStableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IStableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IVariableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IVariableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/StableDebtToken.sol":{"l":{"39":17,"47":363,"55":343,"64":343,"72":488,"73":488,"74":488,"75":366,"77":122,"81":122,"104":27,"107":27,"114":27,"115":27,"116":27,"118":27,"121":27,"126":27,"127":27,"131":27,"134":27,"139":27,"142":27,"144":27,"160":17,"167":17,"173":17,"174":8,"175":8,"177":9,"178":9,"184":17,"185":11,"186":11,"190":6,"193":17,"195":17,"196":0,"198":17,"202":17,"204":17,"222":44,"224":44,"225":22,"229":22,"231":22,"242":331,"243":331,"250":235,"251":235,"258":414,"265":331,"274":343,"284":980,"286":980,"287":781,"290":199,"295":199,"306":27,"307":27,"309":27,"310":0,"322":17,"323":17,"325":17,"326":0},"path":"/src/contracts/tokenization/StableDebtToken.sol","s":{"1":17,"2":363,"3":343,"4":343,"5":488,"6":488,"7":488,"8":366,"9":122,"10":122,"11":27,"12":27,"13":27,"14":27,"15":27,"16":27,"17":27,"18":27,"19":27,"20":27,"21":27,"22":27,"23":27,"24":27,"25":17,"26":17,"27":17,"28":8,"29":8,"30":9,"31":9,"32":17,"33":11,"34":11,"35":6,"36":17,"37":17,"38":0,"39":17,"40":17,"41":17,"42":44,"43":44,"44":22,"45":22,"46":22,"47":331,"48":331,"49":235,"50":235,"51":414,"52":331,"53":343,"54":980,"55":980,"56":781,"57":199,"58":199,"59":27,"60":27,"61":27,"62":0,"63":17,"64":17,"65":17,"66":0},"b":{"1":[366,122],"2":[27,0],"3":[8,9],"4":[11,6],"5":[0,17],"6":[22,22],"7":[781,199],"8":[0,27],"9":[0,17]},"f":{"1":54,"2":17,"3":363,"4":343,"5":343,"6":488,"7":27,"8":17,"9":44,"10":331,"11":235,"12":414,"13":331,"14":343,"15":980,"16":27,"17":17},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":2},"end":{"line":32,"column":85}}},"2":{"name":"getRevision","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":2}}},"3":{"name":"getAverageStableRate","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"4":{"name":"getUserLastUpdated","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"5":{"name":"getUserStableRate","line":63,"loc":{"start":{"line":63,"column":2},"end":{"line":65,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":82,"column":2}}},"7":{"name":"mint","line":103,"loc":{"start":{"line":99,"column":2},"end":{"line":152,"column":2}}},"8":{"name":"burn","line":159,"loc":{"start":{"line":159,"column":2},"end":{"line":205,"column":2}}},"9":{"name":"_calculateBalanceIncrease","line":213,"loc":{"start":{"line":213,"column":2},"end":{"line":236,"column":2}}},"10":{"name":"getSupplyData","line":241,"loc":{"start":{"line":241,"column":2},"end":{"line":244,"column":2}}},"11":{"name":"getTotalSupplyAndAvgRate","line":249,"loc":{"start":{"line":249,"column":2},"end":{"line":252,"column":2}}},"12":{"name":"totalSupply","line":257,"loc":{"start":{"line":257,"column":2},"end":{"line":259,"column":2}}},"13":{"name":"getTotalSupplyLastUpdated","line":264,"loc":{"start":{"line":264,"column":2},"end":{"line":266,"column":2}}},"14":{"name":"principalBalanceOf","line":273,"loc":{"start":{"line":273,"column":2},"end":{"line":275,"column":2}}},"15":{"name":"_calcTotalSupply","line":283,"loc":{"start":{"line":283,"column":2},"end":{"line":296,"column":2}}},"16":{"name":"_mint","line":304,"loc":{"start":{"line":304,"column":3},"end":{"line":312,"column":2}}},"17":{"name":"_burn","line":320,"loc":{"start":{"line":320,"column":2},"end":{"line":328,"column":2}}}},"statementMap":{"1":{"start":{"line":39,"column":4},"end":{"line":39,"column":30}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":25}},"3":{"start":{"line":55,"column":4},"end":{"line":55,"column":28}},"4":{"start":{"line":64,"column":4},"end":{"line":64,"column":27}},"5":{"start":{"line":72,"column":4},"end":{"line":72,"column":53}},"6":{"start":{"line":73,"column":4},"end":{"line":73,"column":44}},"7":{"start":{"line":74,"column":4},"end":{"line":74,"column":2428}},"8":{"start":{"line":75,"column":6},"end":{"line":75,"column":14}},"9":{"start":{"line":77,"column":4},"end":{"line":77,"column":2482}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":51}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":29}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":3360}},"13":{"start":{"line":114,"column":4},"end":{"line":114,"column":38}},"14":{"start":{"line":115,"column":4},"end":{"line":115,"column":45}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":67}},"16":{"start":{"line":118,"column":4},"end":{"line":118,"column":39}},"17":{"start":{"line":121,"column":4},"end":{"line":121,"column":3848}},"18":{"start":{"line":126,"column":4},"end":{"line":126,"column":79}},"19":{"start":{"line":127,"column":4},"end":{"line":127,"column":40}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":70}},"21":{"start":{"line":134,"column":4},"end":{"line":134,"column":4342}},"22":{"start":{"line":139,"column":4},"end":{"line":139,"column":64}},"23":{"start":{"line":142,"column":4},"end":{"line":142,"column":43}},"24":{"start":{"line":144,"column":4},"end":{"line":144,"column":4640}},"25":{"start":{"line":160,"column":4},"end":{"line":160,"column":5054}},"26":{"start":{"line":167,"column":4},"end":{"line":167,"column":42}},"27":{"start":{"line":173,"column":4},"end":{"line":173,"column":5510}},"28":{"start":{"line":174,"column":6},"end":{"line":174,"column":23}},"29":{"start":{"line":175,"column":6},"end":{"line":175,"column":21}},"30":{"start":{"line":177,"column":7},"end":{"line":177,"column":69}},"31":{"start":{"line":178,"column":6},"end":{"line":178,"column":5715}},"32":{"start":{"line":184,"column":4},"end":{"line":184,"column":5865}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":25}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":26}},"35":{"start":{"line":190,"column":6},"end":{"line":190,"column":48}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":50}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":6147}},"38":{"start":{"line":196,"column":6},"end":{"line":196,"column":61}},"39":{"start":{"line":198,"column":6},"end":{"line":198,"column":61}},"40":{"start":{"line":202,"column":4},"end":{"line":202,"column":43}},"41":{"start":{"line":204,"column":4},"end":{"line":204,"column":81}},"42":{"start":{"line":222,"column":4},"end":{"line":222,"column":60}},"43":{"start":{"line":224,"column":4},"end":{"line":224,"column":7006}},"44":{"start":{"line":225,"column":6},"end":{"line":225,"column":22}},"45":{"start":{"line":229,"column":4},"end":{"line":229,"column":75}},"46":{"start":{"line":231,"column":4},"end":{"line":231,"column":7228}},"47":{"start":{"line":242,"column":4},"end":{"line":242,"column":36}},"48":{"start":{"line":243,"column":4},"end":{"line":243,"column":91}},"49":{"start":{"line":250,"column":4},"end":{"line":250,"column":36}},"50":{"start":{"line":251,"column":4},"end":{"line":251,"column":47}},"51":{"start":{"line":258,"column":4},"end":{"line":258,"column":43}},"52":{"start":{"line":265,"column":4},"end":{"line":265,"column":32}},"53":{"start":{"line":274,"column":4},"end":{"line":274,"column":32}},"54":{"start":{"line":284,"column":4},"end":{"line":284,"column":49}},"55":{"start":{"line":286,"column":4},"end":{"line":286,"column":8975}},"56":{"start":{"line":287,"column":6},"end":{"line":287,"column":14}},"57":{"start":{"line":290,"column":4},"end":{"line":290,"column":9031}},"58":{"start":{"line":295,"column":4},"end":{"line":295,"column":52}},"59":{"start":{"line":306,"column":4},"end":{"line":306,"column":50}},"60":{"start":{"line":307,"column":4},"end":{"line":307,"column":53}},"61":{"start":{"line":309,"column":4},"end":{"line":309,"column":9637}},"62":{"start":{"line":310,"column":6},"end":{"line":310,"column":83}},"63":{"start":{"line":322,"column":4},"end":{"line":322,"column":50}},"64":{"start":{"line":323,"column":4},"end":{"line":323,"column":91}},"65":{"start":{"line":325,"column":4},"end":{"line":325,"column":10249}},"66":{"start":{"line":326,"column":6},"end":{"line":326,"column":83}}},"branchMap":{"1":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":74,"column":4}},{"start":{"line":74,"column":4},"end":{"line":74,"column":4}}]},"2":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":126,"column":4}},{"start":{"line":126,"column":4},"end":{"line":126,"column":4}}]},"3":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"4":{"line":184,"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":184,"column":4}},{"start":{"line":184,"column":4},"end":{"line":184,"column":4}}]},"5":{"line":195,"type":"if","locations":[{"start":{"line":195,"column":4},"end":{"line":195,"column":4}},{"start":{"line":195,"column":4},"end":{"line":195,"column":4}}]},"6":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"7":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"8":{"line":309,"type":"if","locations":[{"start":{"line":309,"column":4},"end":{"line":309,"column":4}},{"start":{"line":309,"column":4},"end":{"line":309,"column":4}}]},"9":{"line":325,"type":"if","locations":[{"start":{"line":325,"column":4},"end":{"line":325,"column":4}},{"start":{"line":325,"column":4},"end":{"line":325,"column":4}}]}}},"contracts/tokenization/VariableDebtToken.sol":{"l":{"34":17,"42":460,"44":460,"45":324,"48":136,"63":26,"65":26,"66":26,"79":25,"81":25,"82":25,"90":343,"98":673,"106":331,"116":0},"path":"/src/contracts/tokenization/VariableDebtToken.sol","s":{"1":17,"2":460,"3":460,"4":324,"5":136,"6":26,"7":26,"8":26,"9":25,"10":25,"11":25,"12":343,"13":673,"14":331,"15":0},"b":{"1":[324,136]},"f":{"1":54,"2":17,"3":460,"4":26,"5":25,"6":343,"7":673,"8":331,"9":0},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":21,"column":2},"end":{"line":27,"column":85}}},"2":{"name":"getRevision","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}},"3":{"name":"balanceOf","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"mint","line":61,"loc":{"start":{"line":57,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"burn","line":78,"loc":{"start":{"line":74,"column":2},"end":{"line":83,"column":2}}},"6":{"name":"scaledBalanceOf","line":89,"loc":{"start":{"line":89,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"totalSupply","line":97,"loc":{"start":{"line":97,"column":2},"end":{"line":99,"column":2}}},"8":{"name":"scaledTotalSupply","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"9":{"name":"getScaledUserBalanceAndSupply","line":115,"loc":{"start":{"line":115,"column":2},"end":{"line":117,"column":2}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":30}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":49}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1484}},"4":{"start":{"line":45,"column":6},"end":{"line":45,"column":14}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":88}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":36}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"8":{"start":{"line":66,"column":4},"end":{"line":66,"column":34}},"9":{"start":{"line":79,"column":4},"end":{"line":79,"column":36}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":43}},"11":{"start":{"line":82,"column":4},"end":{"line":82,"column":34}},"12":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"13":{"start":{"line":98,"column":4},"end":{"line":98,"column":94}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":30}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":55}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}}} \ No newline at end of file +{"contracts/configuration/LendingPoolAddressesProvider.sol":{"l":{"38":9,"46":1,"47":1,"55":119,"63":1,"64":1,"75":37,"83":1,"84":1,"93":124,"97":1,"98":1,"102":168,"106":1,"107":1,"111":234,"115":1,"116":1,"125":2,"127":2,"130":2,"132":2,"133":2,"134":2,"135":2,"136":2,"138":0},"path":"/src/contracts/configuration/LendingPoolAddressesProvider.sol","s":{"1":9,"2":1,"3":1,"4":119,"5":1,"6":1,"7":37,"8":1,"9":1,"10":124,"11":1,"12":1,"13":168,"14":1,"15":1,"16":234,"17":1,"18":1,"19":2,"20":2,"21":2,"22":2,"23":2,"24":2,"25":2,"26":2,"27":0},"b":{"1":[2,0]},"f":{"1":9,"2":1,"3":119,"4":1,"5":37,"6":1,"7":124,"8":1,"9":168,"10":1,"11":234,"12":1,"13":2},"fnMap":{"1":{"name":"getLendingPool","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setLendingPoolImpl","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":48,"column":2}}},"3":{"name":"getLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"setLendingPoolConfiguratorImpl","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"getLendingPoolCollateralManager","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"setLendingPoolCollateralManager","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":85,"column":2}}},"7":{"name":"getAaveAdmin","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"setAaveAdmin","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":99,"column":2}}},"9":{"name":"getPriceOracle","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"10":{"name":"setPriceOracle","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":108,"column":2}}},"11":{"name":"getLendingRateOracle","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":112,"column":2}}},"12":{"name":"setLendingRateOracle","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":117,"column":2}}},"13":{"name":"_updateImpl","line":124,"loc":{"start":{"line":124,"column":2},"end":{"line":140,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":35}},"2":{"start":{"line":46,"column":4},"end":{"line":46,"column":34}},"3":{"start":{"line":47,"column":4},"end":{"line":47,"column":33}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":48}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":55}},"6":{"start":{"line":64,"column":4},"end":{"line":64,"column":53}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":54}},"8":{"start":{"line":83,"column":4},"end":{"line":83,"column":56}},"9":{"start":{"line":84,"column":4},"end":{"line":84,"column":53}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":33}},"11":{"start":{"line":97,"column":4},"end":{"line":97,"column":37}},"12":{"start":{"line":98,"column":4},"end":{"line":98,"column":36}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":35}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":41}},"15":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"16":{"start":{"line":111,"column":4},"end":{"line":111,"column":42}},"17":{"start":{"line":115,"column":4},"end":{"line":115,"column":54}},"18":{"start":{"line":116,"column":4},"end":{"line":116,"column":52}},"19":{"start":{"line":125,"column":4},"end":{"line":125,"column":58}},"20":{"start":{"line":127,"column":4},"end":{"line":127,"column":4874}},"21":{"start":{"line":130,"column":4},"end":{"line":130,"column":87}},"22":{"start":{"line":132,"column":4},"end":{"line":132,"column":5078}},"23":{"start":{"line":133,"column":6},"end":{"line":133,"column":56}},"24":{"start":{"line":134,"column":6},"end":{"line":134,"column":56}},"25":{"start":{"line":135,"column":6},"end":{"line":135,"column":36}},"26":{"start":{"line":136,"column":6},"end":{"line":136,"column":43}},"27":{"start":{"line":138,"column":6},"end":{"line":138,"column":47}}},"branchMap":{"1":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":4},"end":{"line":132,"column":4}},{"start":{"line":132,"column":4},"end":{"line":132,"column":4}}]}}},"contracts/configuration/LendingPoolAddressesProviderRegistry.sol":{"l":{"31":1,"39":3,"41":3,"43":3,"44":5,"45":4,"49":3,"57":2,"58":2,"59":2,"67":1,"68":1,"69":1,"77":2,"78":1,"79":0,"83":2},"path":"/src/contracts/configuration/LendingPoolAddressesProviderRegistry.sol","s":{"1":1,"2":3,"3":3,"4":3,"5":5,"6":4,"7":3,"8":2,"9":2,"10":2,"11":1,"12":1,"13":1,"14":2,"15":1,"16":0,"17":2},"b":{"1":[4,1],"2":[1,0],"3":[0,1]},"f":{"1":1,"2":3,"3":2,"4":1,"5":2},"fnMap":{"1":{"name":"isAddressesProviderRegistered","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"getAddressesProvidersList","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"registerAddressesProvider","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":60,"column":2}}},"4":{"name":"unregisterAddressesProvider","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":2}}},"5":{"name":"_addToAddressesProvidersList","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":84,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":39}},"2":{"start":{"line":39,"column":4},"end":{"line":39,"column":53}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":63}},"4":{"start":{"line":43,"column":4},"end":{"line":43,"column":1323}},"5":{"start":{"line":44,"column":6},"end":{"line":44,"column":1393}},"6":{"start":{"line":45,"column":8},"end":{"line":45,"column":53}},"7":{"start":{"line":49,"column":4},"end":{"line":49,"column":26}},"8":{"start":{"line":57,"column":4},"end":{"line":57,"column":36}},"9":{"start":{"line":58,"column":4},"end":{"line":58,"column":41}},"10":{"start":{"line":59,"column":4},"end":{"line":59,"column":46}},"11":{"start":{"line":67,"column":4},"end":{"line":67,"column":76}},"12":{"start":{"line":68,"column":4},"end":{"line":68,"column":35}},"13":{"start":{"line":69,"column":4},"end":{"line":69,"column":48}},"14":{"start":{"line":77,"column":4},"end":{"line":77,"column":2552}},"15":{"start":{"line":78,"column":6},"end":{"line":78,"column":2622}},"16":{"start":{"line":79,"column":8},"end":{"line":79,"column":14}},"17":{"start":{"line":83,"column":4},"end":{"line":83,"column":40}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":6},"end":{"line":44,"column":6}},{"start":{"line":44,"column":6},"end":{"line":44,"column":6}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":6},"end":{"line":78,"column":6}},{"start":{"line":78,"column":6},"end":{"line":78,"column":6}}]}}},"contracts/flashloan/base/FlashLoanReceiverBase.sol":{"l":{"18":3},"path":"/src/contracts/flashloan/base/FlashLoanReceiverBase.sol","s":{"1":3},"b":{},"f":{"1":3},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":32}}},"branchMap":{}},"contracts/flashloan/interfaces/IFlashLoanReceiver.sol":{"l":{},"path":"/src/contracts/flashloan/interfaces/IFlashLoanReceiver.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/lendingpool/DefaultReserveInterestRateStrategy.sol":{"l":{"62":51,"63":51,"64":51,"65":51,"66":51,"67":51,"75":0,"79":0,"83":0,"87":0,"91":0,"95":7,"137":234,"139":234,"140":234,"141":234,"142":234,"144":234,"148":234,"151":234,"152":4,"156":4,"160":4,"164":230,"167":230,"172":234,"181":234,"198":234,"200":234,"202":86,"206":86,"210":86,"214":86},"path":"/src/contracts/lendingpool/DefaultReserveInterestRateStrategy.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":0,"8":0,"9":0,"10":0,"11":0,"12":7,"13":234,"14":234,"15":234,"16":234,"17":234,"18":234,"19":234,"20":234,"21":4,"22":4,"23":4,"24":230,"25":230,"26":234,"27":234,"28":234,"29":234,"30":148,"31":86,"32":86,"33":86,"34":86},"b":{"1":[4,230],"2":[148,86]},"f":{"1":51,"2":0,"3":0,"4":0,"5":0,"6":0,"7":7,"8":234,"9":234},"fnMap":{"1":{"name":"constructor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":68,"column":2}}},"2":{"name":"variableRateSlope1","line":74,"loc":{"start":{"line":74,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"variableRateSlope2","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":80,"column":2}}},"4":{"name":"stableRateSlope1","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":84,"column":2}}},"5":{"name":"stableRateSlope2","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":88,"column":2}}},"6":{"name":"baseVariableBorrowRate","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"getMaxVariableBorrowRate","line":94,"loc":{"start":{"line":94,"column":2},"end":{"line":96,"column":2}}},"8":{"name":"calculateInterestRates","line":119,"loc":{"start":{"line":119,"column":2},"end":{"line":182,"column":2}}},"9":{"name":"_getOverallBorrowRate","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":215,"column":2}}}},"statementMap":{"1":{"start":{"line":62,"column":4},"end":{"line":62,"column":31}},"2":{"start":{"line":63,"column":4},"end":{"line":63,"column":51}},"3":{"start":{"line":64,"column":4},"end":{"line":64,"column":43}},"4":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"5":{"start":{"line":66,"column":4},"end":{"line":66,"column":39}},"6":{"start":{"line":67,"column":4},"end":{"line":67,"column":39}},"7":{"start":{"line":75,"column":4},"end":{"line":75,"column":30}},"8":{"start":{"line":79,"column":4},"end":{"line":79,"column":30}},"9":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"10":{"start":{"line":87,"column":4},"end":{"line":87,"column":28}},"11":{"start":{"line":91,"column":4},"end":{"line":91,"column":34}},"12":{"start":{"line":95,"column":4},"end":{"line":95,"column":84}},"13":{"start":{"line":137,"column":4},"end":{"line":137,"column":42}},"14":{"start":{"line":139,"column":4},"end":{"line":139,"column":61}},"15":{"start":{"line":140,"column":4},"end":{"line":140,"column":37}},"16":{"start":{"line":141,"column":4},"end":{"line":141,"column":35}},"17":{"start":{"line":142,"column":4},"end":{"line":142,"column":32}},"18":{"start":{"line":144,"column":4},"end":{"line":144,"column":5183}},"19":{"start":{"line":148,"column":4},"end":{"line":148,"column":5283}},"20":{"start":{"line":151,"column":4},"end":{"line":151,"column":5387}},"21":{"start":{"line":152,"column":6},"end":{"line":152,"column":5446}},"22":{"start":{"line":156,"column":6},"end":{"line":156,"column":5584}},"23":{"start":{"line":160,"column":6},"end":{"line":160,"column":5749}},"24":{"start":{"line":164,"column":6},"end":{"line":164,"column":5927}},"25":{"start":{"line":167,"column":6},"end":{"line":167,"column":6090}},"26":{"start":{"line":172,"column":4},"end":{"line":172,"column":6320}},"27":{"start":{"line":181,"column":4},"end":{"line":181,"column":100}},"28":{"start":{"line":198,"column":4},"end":{"line":198,"column":65}},"29":{"start":{"line":200,"column":4},"end":{"line":200,"column":35}},"30":{"start":{"line":200,"column":27},"end":{"line":200,"column":35}},"31":{"start":{"line":202,"column":4},"end":{"line":202,"column":7483}},"32":{"start":{"line":206,"column":4},"end":{"line":206,"column":7595}},"33":{"start":{"line":210,"column":4},"end":{"line":210,"column":7708}},"34":{"start":{"line":214,"column":4},"end":{"line":214,"column":28}}},"branchMap":{"1":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":4},"end":{"line":151,"column":4}},{"start":{"line":151,"column":4},"end":{"line":151,"column":4}}]},"2":{"line":200,"type":"if","locations":[{"start":{"line":200,"column":4},"end":{"line":200,"column":4}},{"start":{"line":200,"column":4},"end":{"line":200,"column":4}}]}}},"contracts/lendingpool/LendingPool.sol":{"l":{"55":118,"68":300,"72":1,"81":1,"97":105,"98":104,"100":104,"102":102,"104":102,"105":102,"107":102,"108":102,"109":93,"112":102,"115":102,"117":102,"126":26,"127":25,"129":25,"131":25,"133":25,"136":25,"137":19,"140":25,"150":22,"152":22,"154":22,"155":18,"158":22,"160":22,"177":3,"194":5,"195":4,"197":3,"198":3,"217":62,"218":61,"220":61,"221":4,"223":4,"229":59,"257":21,"259":20,"261":20,"263":20,"266":20,"270":20,"271":5,"274":20,"283":17,"286":17,"287":9,"289":8,"296":17,"297":17,"299":17,"300":12,"303":17,"305":17,"314":5,"315":4,"317":4,"319":4,"321":4,"329":2,"331":2,"333":1,"334":1,"341":1,"346":1,"353":2,"355":2,"367":8,"369":7,"371":7,"372":7,"373":7,"375":7,"378":7,"379":7,"380":7,"387":7,"388":7,"394":7,"401":1,"403":1,"404":1,"406":1,"408":1,"418":8,"419":7,"421":7,"430":6,"432":6,"433":2,"435":4,"455":11,"456":10,"459":10,"469":10,"471":10,"473":10,"475":5,"499":21,"500":20,"501":18,"503":18,"506":18,"517":18,"519":16,"521":16,"522":5,"525":11,"555":14,"556":13,"557":13,"559":13,"561":13,"563":13,"565":11,"567":11,"570":11,"573":9,"575":9,"577":9,"578":5,"580":3,"581":3,"582":3,"584":3,"587":4,"617":10,"618":9,"621":9,"631":9,"633":7,"635":7,"636":5,"662":97,"664":97,"689":710,"691":710,"715":363,"717":363,"744":21,"758":21,"781":343,"783":343,"784":343,"785":343,"786":343,"787":343,"788":343,"789":343,"792":343,"796":3,"800":0,"816":17,"817":17,"823":17,"836":0,"837":0,"841":75,"842":75,"851":75,"872":63,"873":63,"875":63,"877":63,"881":63,"894":50,"895":50,"896":37,"899":50,"902":50,"904":50,"907":25,"909":25,"915":25,"922":50,"929":50,"930":47,"933":50,"950":17,"951":17,"952":17,"953":136,"954":0,"956":17,"957":17,"958":17,"968":648,"982":810,"997":4,"998":3,"1015":26,"1017":26,"1018":26,"1019":13,"1021":13,"1029":0},"path":"/src/contracts/lendingpool/LendingPool.sol","s":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":104,"7":104,"8":102,"9":102,"10":102,"11":102,"12":102,"13":93,"14":102,"15":102,"16":102,"17":26,"18":25,"19":25,"20":25,"21":25,"22":25,"23":19,"24":25,"25":22,"26":22,"27":22,"28":18,"29":22,"30":22,"31":3,"32":5,"33":4,"34":3,"35":3,"36":62,"37":61,"38":61,"39":4,"40":4,"41":59,"42":21,"43":20,"44":20,"45":20,"46":20,"47":20,"48":5,"49":20,"50":17,"51":17,"52":9,"53":8,"54":17,"55":17,"56":17,"57":12,"58":17,"59":17,"60":5,"61":4,"62":4,"63":4,"64":4,"65":2,"66":2,"67":1,"68":1,"69":1,"70":1,"71":2,"72":2,"73":8,"74":7,"75":7,"76":7,"77":7,"78":7,"79":7,"80":7,"81":7,"82":7,"83":7,"84":7,"85":1,"86":1,"87":1,"88":1,"89":1,"90":8,"91":7,"92":7,"93":6,"94":6,"95":2,"96":4,"97":11,"98":10,"99":10,"100":10,"101":10,"102":10,"103":5,"104":21,"105":20,"106":18,"107":18,"108":18,"109":18,"110":16,"111":16,"112":5,"113":11,"114":14,"115":13,"116":13,"117":13,"118":13,"119":13,"120":11,"121":11,"122":11,"123":9,"124":9,"125":9,"126":5,"127":3,"128":3,"129":3,"130":3,"131":4,"132":10,"133":9,"134":9,"135":9,"136":7,"137":7,"138":5,"139":97,"140":97,"141":710,"142":710,"143":363,"144":363,"145":21,"146":21,"147":343,"148":343,"149":343,"150":343,"151":343,"152":343,"153":343,"154":343,"155":343,"156":3,"157":17,"158":17,"159":17,"160":0,"161":0,"162":75,"163":75,"164":75,"165":63,"166":63,"167":63,"168":63,"169":63,"170":50,"171":50,"172":37,"173":50,"174":50,"175":50,"176":25,"177":25,"178":25,"179":50,"180":50,"181":47,"182":50,"183":17,"184":17,"185":17,"186":136,"187":0,"188":17,"189":17,"190":17,"191":648,"192":810,"193":4,"194":3,"195":26,"196":26,"197":26,"198":13,"199":13,"200":0},"b":{"1":[118,0],"2":[287,13],"3":[93,9],"4":[19,6],"5":[18,4],"6":[4,57],"7":[5,15],"8":[9,8],"9":[12,5],"10":[1,1],"11":[1,6],"12":[2,4],"13":[10,0],"14":[5,5],"15":[18,2],"16":[16,2],"17":[5,11],"18":[5,4],"19":[7,2],"20":[5,2],"21":[37,13],"22":[25,25],"23":[47,3],"24":[17,0],"25":[0,136],"26":[17,0],"27":[13,13]},"f":{"1":118,"2":300,"3":1,"4":1,"5":105,"6":26,"7":3,"8":5,"9":62,"10":21,"11":5,"12":8,"13":8,"14":11,"15":21,"16":14,"17":10,"18":97,"19":710,"20":363,"21":21,"22":343,"23":3,"24":17,"25":0,"26":75,"27":75,"28":63,"29":17,"30":648,"31":810,"32":4,"33":26,"34":0},"fnMap":{"1":{"name":"_onlyLendingPoolConfigurator","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":59,"column":2}}},"2":{"name":"_whenNotPaused","line":67,"loc":{"start":{"line":67,"column":2},"end":{"line":69,"column":2}}},"3":{"name":"getRevision","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"4":{"name":"initialize","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":82,"column":2}}},"5":{"name":"deposit","line":91,"loc":{"start":{"line":91,"column":2},"end":{"line":118,"column":2}}},"6":{"name":"withdraw","line":125,"loc":{"start":{"line":125,"column":2},"end":{"line":161,"column":2}}},"7":{"name":"getBorrowAllowance","line":171,"loc":{"start":{"line":171,"column":2},"end":{"line":179,"column":2}}},"8":{"name":"delegateBorrowAllowance","line":188,"loc":{"start":{"line":188,"column":2},"end":{"line":199,"column":2}}},"9":{"name":"borrow","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":241,"column":2}}},"10":{"name":"repay","line":251,"loc":{"start":{"line":251,"column":2},"end":{"line":306,"column":2}}},"11":{"name":"swapBorrowRateMode","line":313,"loc":{"start":{"line":313,"column":2},"end":{"line":356,"column":2}}},"12":{"name":"rebalanceStableBorrowRate","line":365,"loc":{"start":{"line":365,"column":2},"end":{"line":410,"column":2}}},"13":{"name":"setUserUseReserveAsCollateral","line":417,"loc":{"start":{"line":417,"column":2},"end":{"line":437,"column":2}}},"14":{"name":"liquidationCall","line":448,"loc":{"start":{"line":448,"column":2},"end":{"line":477,"column":2}}},"15":{"name":"repayWithCollateral","line":491,"loc":{"start":{"line":491,"column":2},"end":{"line":526,"column":2}}},"16":{"name":"flashLoan","line":547,"loc":{"start":{"line":547,"column":2},"end":{"line":600,"column":2}}},"17":{"name":"swapLiquidity","line":610,"loc":{"start":{"line":610,"column":2},"end":{"line":638,"column":2}}},"18":{"name":"getReserveConfigurationData","line":644,"loc":{"start":{"line":644,"column":2},"end":{"line":677,"column":2}}},"19":{"name":"getReserveTokensAddresses","line":679,"loc":{"start":{"line":679,"column":2},"end":{"line":696,"column":2}}},"20":{"name":"getReserveData","line":698,"loc":{"start":{"line":698,"column":2},"end":{"line":729,"column":2}}},"21":{"name":"getUserAccountData","line":731,"loc":{"start":{"line":731,"column":2},"end":{"line":763,"column":2}}},"22":{"name":"getUserReserveData","line":765,"loc":{"start":{"line":765,"column":2},"end":{"line":793,"column":2}}},"23":{"name":"getReserves","line":795,"loc":{"start":{"line":795,"column":2},"end":{"line":797,"column":2}}},"24":{"name":"initReserve","line":809,"loc":{"start":{"line":809,"column":2},"end":{"line":824,"column":2}}},"25":{"name":"setReserveInterestRateStrategyAddress","line":832,"loc":{"start":{"line":832,"column":2},"end":{"line":838,"column":2}}},"26":{"name":"setConfiguration","line":840,"loc":{"start":{"line":840,"column":2},"end":{"line":843,"column":2}}},"27":{"name":"getConfiguration","line":845,"loc":{"start":{"line":845,"column":2},"end":{"line":852,"column":2}}},"28":{"name":"_executeBorrow","line":871,"loc":{"start":{"line":871,"column":2},"end":{"line":944,"column":2}}},"29":{"name":"_addReserveToList","line":949,"loc":{"start":{"line":949,"column":2},"end":{"line":960,"column":2}}},"30":{"name":"getReserveNormalizedIncome","line":967,"loc":{"start":{"line":967,"column":2},"end":{"line":969,"column":2}}},"31":{"name":"getReserveNormalizedVariableDebt","line":976,"loc":{"start":{"line":976,"column":2},"end":{"line":983,"column":2}}},"32":{"name":"balanceDecreaseAllowed","line":992,"loc":{"start":{"line":992,"column":2},"end":{"line":1008,"column":2}}},"33":{"name":"setPause","line":1014,"loc":{"start":{"line":1014,"column":2},"end":{"line":1023,"column":2}}},"34":{"name":"paused","line":1028,"loc":{"start":{"line":1028,"column":2},"end":{"line":1030,"column":2}}}},"statementMap":{"1":{"start":{"line":55,"column":4},"end":{"line":55,"column":2946}},"2":{"start":{"line":68,"column":4},"end":{"line":68,"column":38}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":31}},"4":{"start":{"line":81,"column":4},"end":{"line":81,"column":32}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":19}},"6":{"start":{"line":98,"column":4},"end":{"line":98,"column":63}},"7":{"start":{"line":100,"column":4},"end":{"line":100,"column":51}},"8":{"start":{"line":102,"column":4},"end":{"line":102,"column":42}},"9":{"start":{"line":104,"column":4},"end":{"line":104,"column":24}},"10":{"start":{"line":105,"column":4},"end":{"line":105,"column":56}},"11":{"start":{"line":107,"column":4},"end":{"line":107,"column":68}},"12":{"start":{"line":108,"column":4},"end":{"line":108,"column":4605}},"13":{"start":{"line":109,"column":6},"end":{"line":109,"column":68}},"14":{"start":{"line":112,"column":4},"end":{"line":112,"column":67}},"15":{"start":{"line":115,"column":4},"end":{"line":115,"column":61}},"16":{"start":{"line":117,"column":4},"end":{"line":117,"column":69}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":19}},"18":{"start":{"line":127,"column":4},"end":{"line":127,"column":63}},"19":{"start":{"line":129,"column":4},"end":{"line":129,"column":42}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":63}},"21":{"start":{"line":133,"column":4},"end":{"line":133,"column":37}},"22":{"start":{"line":136,"column":4},"end":{"line":136,"column":5500}},"23":{"start":{"line":137,"column":6},"end":{"line":137,"column":35}},"24":{"start":{"line":140,"column":4},"end":{"line":140,"column":5584}},"25":{"start":{"line":150,"column":4},"end":{"line":150,"column":24}},"26":{"start":{"line":152,"column":4},"end":{"line":152,"column":66}},"27":{"start":{"line":154,"column":4},"end":{"line":154,"column":5896}},"28":{"start":{"line":155,"column":6},"end":{"line":155,"column":69}},"29":{"start":{"line":158,"column":4},"end":{"line":158,"column":89}},"30":{"start":{"line":160,"column":4},"end":{"line":160,"column":44}},"31":{"start":{"line":177,"column":4},"end":{"line":177,"column":6759}},"32":{"start":{"line":194,"column":4},"end":{"line":194,"column":19}},"33":{"start":{"line":195,"column":4},"end":{"line":195,"column":78}},"34":{"start":{"line":197,"column":4},"end":{"line":197,"column":57}},"35":{"start":{"line":198,"column":4},"end":{"line":198,"column":84}},"36":{"start":{"line":217,"column":4},"end":{"line":217,"column":19}},"37":{"start":{"line":218,"column":4},"end":{"line":218,"column":63}},"38":{"start":{"line":220,"column":4},"end":{"line":220,"column":8253}},"39":{"start":{"line":221,"column":6},"end":{"line":221,"column":71}},"40":{"start":{"line":223,"column":6},"end":{"line":223,"column":8367}},"41":{"start":{"line":229,"column":4},"end":{"line":229,"column":8567}},"42":{"start":{"line":257,"column":4},"end":{"line":257,"column":19}},"43":{"start":{"line":259,"column":4},"end":{"line":259,"column":63}},"44":{"start":{"line":261,"column":4},"end":{"line":261,"column":96}},"45":{"start":{"line":263,"column":4},"end":{"line":263,"column":92}},"46":{"start":{"line":266,"column":4},"end":{"line":266,"column":9784}},"47":{"start":{"line":270,"column":4},"end":{"line":270,"column":9895}},"48":{"start":{"line":271,"column":6},"end":{"line":271,"column":27}},"49":{"start":{"line":274,"column":4},"end":{"line":274,"column":9997}},"50":{"start":{"line":283,"column":4},"end":{"line":283,"column":24}},"51":{"start":{"line":286,"column":4},"end":{"line":286,"column":10224}},"52":{"start":{"line":287,"column":6},"end":{"line":287,"column":85}},"53":{"start":{"line":289,"column":6},"end":{"line":289,"column":10397}},"54":{"start":{"line":296,"column":4},"end":{"line":296,"column":42}},"55":{"start":{"line":297,"column":4},"end":{"line":297,"column":63}},"56":{"start":{"line":299,"column":4},"end":{"line":299,"column":10664}},"57":{"start":{"line":300,"column":6},"end":{"line":300,"column":61}},"58":{"start":{"line":303,"column":4},"end":{"line":303,"column":68}},"59":{"start":{"line":305,"column":4},"end":{"line":305,"column":60}},"60":{"start":{"line":314,"column":4},"end":{"line":314,"column":19}},"61":{"start":{"line":315,"column":4},"end":{"line":315,"column":63}},"62":{"start":{"line":317,"column":4},"end":{"line":317,"column":96}},"63":{"start":{"line":319,"column":4},"end":{"line":319,"column":92}},"64":{"start":{"line":321,"column":4},"end":{"line":321,"column":11549}},"65":{"start":{"line":329,"column":4},"end":{"line":329,"column":24}},"66":{"start":{"line":331,"column":4},"end":{"line":331,"column":11735}},"67":{"start":{"line":333,"column":6},"end":{"line":333,"column":82}},"68":{"start":{"line":334,"column":6},"end":{"line":334,"column":11951}},"69":{"start":{"line":341,"column":6},"end":{"line":341,"column":12138}},"70":{"start":{"line":346,"column":6},"end":{"line":346,"column":12290}},"71":{"start":{"line":353,"column":4},"end":{"line":353,"column":66}},"72":{"start":{"line":355,"column":4},"end":{"line":355,"column":32}},"73":{"start":{"line":367,"column":4},"end":{"line":367,"column":19}},"74":{"start":{"line":369,"column":4},"end":{"line":369,"column":63}},"75":{"start":{"line":371,"column":4},"end":{"line":371,"column":67}},"76":{"start":{"line":372,"column":4},"end":{"line":372,"column":71}},"77":{"start":{"line":373,"column":4},"end":{"line":373,"column":49}},"78":{"start":{"line":375,"column":4},"end":{"line":375,"column":73}},"79":{"start":{"line":378,"column":4},"end":{"line":378,"column":104}},"80":{"start":{"line":379,"column":4},"end":{"line":379,"column":82}},"81":{"start":{"line":380,"column":4},"end":{"line":380,"column":13692}},"82":{"start":{"line":387,"column":4},"end":{"line":387,"column":63}},"83":{"start":{"line":388,"column":4},"end":{"line":388,"column":14007}},"84":{"start":{"line":394,"column":4},"end":{"line":394,"column":14137}},"85":{"start":{"line":401,"column":4},"end":{"line":401,"column":24}},"86":{"start":{"line":403,"column":4},"end":{"line":403,"column":77}},"87":{"start":{"line":404,"column":4},"end":{"line":404,"column":110}},"88":{"start":{"line":406,"column":4},"end":{"line":406,"column":58}},"89":{"start":{"line":408,"column":4},"end":{"line":408,"column":47}},"90":{"start":{"line":418,"column":4},"end":{"line":418,"column":19}},"91":{"start":{"line":419,"column":4},"end":{"line":419,"column":63}},"92":{"start":{"line":421,"column":4},"end":{"line":421,"column":15152}},"93":{"start":{"line":430,"column":4},"end":{"line":430,"column":77}},"94":{"start":{"line":432,"column":4},"end":{"line":432,"column":15436}},"95":{"start":{"line":433,"column":6},"end":{"line":433,"column":60}},"96":{"start":{"line":435,"column":6},"end":{"line":435,"column":61}},"97":{"start":{"line":455,"column":4},"end":{"line":455,"column":19}},"98":{"start":{"line":456,"column":4},"end":{"line":456,"column":84}},"99":{"start":{"line":459,"column":4},"end":{"line":459,"column":16409}},"100":{"start":{"line":469,"column":4},"end":{"line":469,"column":51}},"101":{"start":{"line":471,"column":4},"end":{"line":471,"column":93}},"102":{"start":{"line":473,"column":4},"end":{"line":473,"column":16839}},"103":{"start":{"line":475,"column":6},"end":{"line":475,"column":52}},"104":{"start":{"line":499,"column":4},"end":{"line":499,"column":19}},"105":{"start":{"line":500,"column":4},"end":{"line":500,"column":67}},"106":{"start":{"line":501,"column":4},"end":{"line":501,"column":33}},"107":{"start":{"line":503,"column":4},"end":{"line":503,"column":84}},"108":{"start":{"line":506,"column":4},"end":{"line":506,"column":18211}},"109":{"start":{"line":517,"column":4},"end":{"line":517,"column":56}},"110":{"start":{"line":519,"column":4},"end":{"line":519,"column":93}},"111":{"start":{"line":521,"column":4},"end":{"line":521,"column":18675}},"112":{"start":{"line":522,"column":6},"end":{"line":522,"column":52}},"113":{"start":{"line":525,"column":4},"end":{"line":525,"column":34}},"114":{"start":{"line":555,"column":4},"end":{"line":555,"column":19}},"115":{"start":{"line":556,"column":4},"end":{"line":556,"column":63}},"116":{"start":{"line":557,"column":4},"end":{"line":557,"column":34}},"117":{"start":{"line":559,"column":4},"end":{"line":559,"column":45}},"118":{"start":{"line":561,"column":4},"end":{"line":561,"column":64}},"119":{"start":{"line":563,"column":4},"end":{"line":563,"column":56}},"120":{"start":{"line":565,"column":4},"end":{"line":565,"column":80}},"121":{"start":{"line":567,"column":4},"end":{"line":567,"column":54}},"122":{"start":{"line":570,"column":4},"end":{"line":570,"column":76}},"123":{"start":{"line":573,"column":4},"end":{"line":573,"column":70}},"124":{"start":{"line":575,"column":4},"end":{"line":575,"column":52}},"125":{"start":{"line":577,"column":4},"end":{"line":577,"column":20770}},"126":{"start":{"line":578,"column":6},"end":{"line":578,"column":92}},"127":{"start":{"line":580,"column":6},"end":{"line":580,"column":26}},"128":{"start":{"line":581,"column":6},"end":{"line":581,"column":93}},"129":{"start":{"line":582,"column":6},"end":{"line":582,"column":76}},"130":{"start":{"line":584,"column":6},"end":{"line":584,"column":80}},"131":{"start":{"line":587,"column":6},"end":{"line":587,"column":21346}},"132":{"start":{"line":617,"column":4},"end":{"line":617,"column":19}},"133":{"start":{"line":618,"column":4},"end":{"line":618,"column":84}},"134":{"start":{"line":621,"column":4},"end":{"line":621,"column":22445}},"135":{"start":{"line":631,"column":4},"end":{"line":631,"column":50}},"136":{"start":{"line":633,"column":4},"end":{"line":633,"column":93}},"137":{"start":{"line":635,"column":4},"end":{"line":635,"column":22876}},"138":{"start":{"line":636,"column":6},"end":{"line":636,"column":52}},"139":{"start":{"line":662,"column":4},"end":{"line":662,"column":63}},"140":{"start":{"line":664,"column":4},"end":{"line":664,"column":23557}},"141":{"start":{"line":689,"column":4},"end":{"line":689,"column":63}},"142":{"start":{"line":691,"column":4},"end":{"line":691,"column":24379}},"143":{"start":{"line":715,"column":4},"end":{"line":715,"column":62}},"144":{"start":{"line":717,"column":4},"end":{"line":717,"column":25005}},"145":{"start":{"line":744,"column":4},"end":{"line":744,"column":25791}},"146":{"start":{"line":758,"column":4},"end":{"line":758,"column":26088}},"147":{"start":{"line":781,"column":4},"end":{"line":781,"column":63}},"148":{"start":{"line":783,"column":4},"end":{"line":783,"column":71}},"149":{"start":{"line":784,"column":4},"end":{"line":784,"column":87}},"150":{"start":{"line":785,"column":4},"end":{"line":785,"column":98}},"151":{"start":{"line":786,"column":4},"end":{"line":786,"column":98}},"152":{"start":{"line":787,"column":4},"end":{"line":787,"column":47}},"153":{"start":{"line":788,"column":4},"end":{"line":788,"column":94}},"154":{"start":{"line":789,"column":4},"end":{"line":789,"column":27231}},"155":{"start":{"line":792,"column":4},"end":{"line":792,"column":80}},"156":{"start":{"line":796,"column":4},"end":{"line":796,"column":24}},"157":{"start":{"line":816,"column":4},"end":{"line":816,"column":33}},"158":{"start":{"line":817,"column":4},"end":{"line":817,"column":28078}},"159":{"start":{"line":823,"column":4},"end":{"line":823,"column":27}},"160":{"start":{"line":836,"column":4},"end":{"line":836,"column":33}},"161":{"start":{"line":837,"column":4},"end":{"line":837,"column":69}},"162":{"start":{"line":841,"column":4},"end":{"line":841,"column":33}},"163":{"start":{"line":842,"column":4},"end":{"line":842,"column":54}},"164":{"start":{"line":851,"column":4},"end":{"line":851,"column":41}},"165":{"start":{"line":872,"column":4},"end":{"line":872,"column":68}},"166":{"start":{"line":873,"column":4},"end":{"line":873,"column":76}},"167":{"start":{"line":875,"column":4},"end":{"line":875,"column":56}},"168":{"start":{"line":877,"column":4},"end":{"line":877,"column":29792}},"169":{"start":{"line":881,"column":4},"end":{"line":881,"column":29946}},"170":{"start":{"line":894,"column":4},"end":{"line":894,"column":34}},"171":{"start":{"line":895,"column":4},"end":{"line":895,"column":30243}},"172":{"start":{"line":896,"column":6},"end":{"line":896,"column":45}},"173":{"start":{"line":899,"column":4},"end":{"line":899,"column":24}},"174":{"start":{"line":902,"column":4},"end":{"line":902,"column":33}},"175":{"start":{"line":904,"column":4},"end":{"line":904,"column":30453}},"176":{"start":{"line":907,"column":6},"end":{"line":907,"column":56}},"177":{"start":{"line":909,"column":6},"end":{"line":909,"column":30633}},"178":{"start":{"line":915,"column":6},"end":{"line":915,"column":30788}},"179":{"start":{"line":922,"column":4},"end":{"line":922,"column":30947}},"180":{"start":{"line":929,"column":4},"end":{"line":929,"column":31088}},"181":{"start":{"line":930,"column":6},"end":{"line":930,"column":77}},"182":{"start":{"line":933,"column":4},"end":{"line":933,"column":31210}},"183":{"start":{"line":950,"column":4},"end":{"line":950,"column":36}},"184":{"start":{"line":951,"column":4},"end":{"line":951,"column":87}},"185":{"start":{"line":952,"column":4},"end":{"line":952,"column":31801}},"186":{"start":{"line":953,"column":6},"end":{"line":953,"column":31858}},"187":{"start":{"line":954,"column":8},"end":{"line":954,"column":33}},"188":{"start":{"line":956,"column":4},"end":{"line":956,"column":31937}},"189":{"start":{"line":957,"column":6},"end":{"line":957,"column":54}},"190":{"start":{"line":958,"column":6},"end":{"line":958,"column":30}},"191":{"start":{"line":968,"column":4},"end":{"line":968,"column":49}},"192":{"start":{"line":982,"column":4},"end":{"line":982,"column":47}},"193":{"start":{"line":997,"column":4},"end":{"line":997,"column":19}},"194":{"start":{"line":998,"column":4},"end":{"line":998,"column":33188}},"195":{"start":{"line":1015,"column":4},"end":{"line":1015,"column":33}},"196":{"start":{"line":1017,"column":4},"end":{"line":1017,"column":16}},"197":{"start":{"line":1018,"column":4},"end":{"line":1018,"column":33641}},"198":{"start":{"line":1019,"column":6},"end":{"line":1019,"column":19}},"199":{"start":{"line":1021,"column":6},"end":{"line":1021,"column":21}},"200":{"start":{"line":1029,"column":4},"end":{"line":1029,"column":18}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":4},"end":{"line":68,"column":4}},{"start":{"line":68,"column":4},"end":{"line":68,"column":4}}]},"3":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":4},"end":{"line":108,"column":4}},{"start":{"line":108,"column":4},"end":{"line":108,"column":4}}]},"4":{"line":136,"type":"if","locations":[{"start":{"line":136,"column":4},"end":{"line":136,"column":4}},{"start":{"line":136,"column":4},"end":{"line":136,"column":4}}]},"5":{"line":154,"type":"if","locations":[{"start":{"line":154,"column":4},"end":{"line":154,"column":4}},{"start":{"line":154,"column":4},"end":{"line":154,"column":4}}]},"6":{"line":220,"type":"if","locations":[{"start":{"line":220,"column":4},"end":{"line":220,"column":4}},{"start":{"line":220,"column":4},"end":{"line":220,"column":4}}]},"7":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"8":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"9":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":4},"end":{"line":299,"column":4}},{"start":{"line":299,"column":4},"end":{"line":299,"column":4}}]},"10":{"line":331,"type":"if","locations":[{"start":{"line":331,"column":4},"end":{"line":331,"column":4}},{"start":{"line":331,"column":4},"end":{"line":331,"column":4}}]},"11":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":4},"end":{"line":394,"column":4}},{"start":{"line":394,"column":4},"end":{"line":394,"column":4}}]},"12":{"line":432,"type":"if","locations":[{"start":{"line":432,"column":4},"end":{"line":432,"column":4}},{"start":{"line":432,"column":4},"end":{"line":432,"column":4}}]},"13":{"line":469,"type":"if","locations":[{"start":{"line":469,"column":4},"end":{"line":469,"column":4}},{"start":{"line":469,"column":4},"end":{"line":469,"column":4}}]},"14":{"line":473,"type":"if","locations":[{"start":{"line":473,"column":4},"end":{"line":473,"column":4}},{"start":{"line":473,"column":4},"end":{"line":473,"column":4}}]},"15":{"line":500,"type":"if","locations":[{"start":{"line":500,"column":4},"end":{"line":500,"column":4}},{"start":{"line":500,"column":4},"end":{"line":500,"column":4}}]},"16":{"line":517,"type":"if","locations":[{"start":{"line":517,"column":4},"end":{"line":517,"column":4}},{"start":{"line":517,"column":4},"end":{"line":517,"column":4}}]},"17":{"line":521,"type":"if","locations":[{"start":{"line":521,"column":4},"end":{"line":521,"column":4}},{"start":{"line":521,"column":4},"end":{"line":521,"column":4}}]},"18":{"line":577,"type":"if","locations":[{"start":{"line":577,"column":4},"end":{"line":577,"column":4}},{"start":{"line":577,"column":4},"end":{"line":577,"column":4}}]},"19":{"line":631,"type":"if","locations":[{"start":{"line":631,"column":4},"end":{"line":631,"column":4}},{"start":{"line":631,"column":4},"end":{"line":631,"column":4}}]},"20":{"line":635,"type":"if","locations":[{"start":{"line":635,"column":4},"end":{"line":635,"column":4}},{"start":{"line":635,"column":4},"end":{"line":635,"column":4}}]},"21":{"line":895,"type":"if","locations":[{"start":{"line":895,"column":4},"end":{"line":895,"column":4}},{"start":{"line":895,"column":4},"end":{"line":895,"column":4}}]},"22":{"line":904,"type":"if","locations":[{"start":{"line":904,"column":4},"end":{"line":904,"column":4}},{"start":{"line":904,"column":4},"end":{"line":904,"column":4}}]},"23":{"line":929,"type":"if","locations":[{"start":{"line":929,"column":4},"end":{"line":929,"column":4}},{"start":{"line":929,"column":4},"end":{"line":929,"column":4}}]},"24":{"line":951,"type":"if","locations":[{"start":{"line":951,"column":4},"end":{"line":951,"column":4}},{"start":{"line":951,"column":4},"end":{"line":951,"column":4}}]},"25":{"line":953,"type":"if","locations":[{"start":{"line":953,"column":6},"end":{"line":953,"column":6}},{"start":{"line":953,"column":6},"end":{"line":953,"column":6}}]},"26":{"line":956,"type":"if","locations":[{"start":{"line":956,"column":4},"end":{"line":956,"column":4}},{"start":{"line":956,"column":4},"end":{"line":956,"column":4}}]},"27":{"line":1018,"type":"if","locations":[{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}},{"start":{"line":1018,"column":4},"end":{"line":1018,"column":4}}]}}},"contracts/lendingpool/LendingPoolCollateralManager.sol":{"l":{"127":0,"146":10,"147":10,"148":10,"150":10,"152":10,"161":10,"166":10,"175":10,"176":5,"179":5,"181":5,"183":5,"187":5,"191":5,"207":5,"208":1,"212":5,"213":3,"216":3,"217":0,"225":5,"227":5,"234":5,"235":1,"241":4,"247":4,"254":5,"255":2,"260":3,"261":3,"269":3,"278":5,"284":5,"294":5,"317":18,"318":18,"319":18,"321":18,"323":18,"331":18,"333":18,"343":18,"344":5,"347":13,"349":13,"353":13,"354":13,"356":13,"371":13,"372":2,"375":13,"377":13,"384":13,"385":2,"388":13,"391":13,"400":11,"401":11,"407":11,"409":11,"410":9,"416":2,"421":2,"428":11,"435":11,"444":11,"462":9,"463":9,"465":9,"467":9,"474":9,"475":4,"478":5,"479":5,"481":5,"482":5,"484":5,"485":1,"488":5,"490":4,"497":3,"505":3,"506":3,"507":3,"513":3,"514":1,"517":3,"518":3,"526":3,"534":3,"535":1,"541":2,"563":18,"564":18,"565":18,"567":18,"569":18,"570":18,"572":18,"575":18,"579":18,"586":18,"587":3,"588":3,"595":15,"596":15,"598":18},"path":"/src/contracts/lendingpool/LendingPoolCollateralManager.sol","s":{"1":0,"2":10,"3":10,"4":10,"5":10,"6":10,"7":10,"8":10,"9":10,"10":5,"11":5,"12":5,"13":5,"14":5,"15":5,"16":5,"17":1,"18":5,"19":3,"20":3,"21":0,"22":5,"23":5,"24":5,"25":1,"26":4,"27":4,"28":5,"29":2,"30":3,"31":3,"32":3,"33":5,"34":5,"35":5,"36":18,"37":18,"38":18,"39":18,"40":18,"41":18,"42":18,"43":18,"44":5,"45":13,"46":13,"47":13,"48":13,"49":13,"50":13,"51":2,"52":13,"53":13,"54":13,"55":2,"56":13,"57":13,"58":11,"59":11,"60":11,"61":11,"62":9,"63":2,"64":2,"65":11,"66":11,"67":11,"68":9,"69":9,"70":9,"71":9,"72":9,"73":4,"74":5,"75":5,"76":5,"77":5,"78":5,"79":1,"80":5,"81":4,"82":3,"83":3,"84":3,"85":3,"86":3,"87":1,"88":3,"89":3,"90":3,"91":3,"92":1,"93":2,"94":18,"95":18,"96":18,"97":18,"98":18,"99":18,"100":18,"101":18,"102":18,"103":18,"104":3,"105":3,"106":15,"107":15,"108":18},"b":{"1":[5,5],"2":[1,4],"3":[3,2],"4":[0,3],"5":[1,4],"6":[2,3],"7":[5,13],"8":[2,11],"9":[2,11],"10":[9,2],"11":[4,5],"12":[1,4],"13":[3,0],"14":[1,2],"15":[1,2],"16":[3,15]},"f":{"1":0,"2":10,"3":18,"4":9,"5":18},"fnMap":{"1":{"name":"getRevision","line":126,"loc":{"start":{"line":126,"column":2},"end":{"line":128,"column":2}}},"2":{"name":"liquidationCall","line":139,"loc":{"start":{"line":139,"column":2},"end":{"line":295,"column":2}}},"3":{"name":"repayWithCollateral","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":445,"column":2}}},"4":{"name":"swapLiquidity","line":455,"loc":{"start":{"line":455,"column":2},"end":{"line":542,"column":2}}},"5":{"name":"calculateAvailableCollateralToLiquidate","line":555,"loc":{"start":{"line":555,"column":2},"end":{"line":599,"column":2}}}},"statementMap":{"1":{"start":{"line":127,"column":4},"end":{"line":127,"column":12}},"2":{"start":{"line":146,"column":4},"end":{"line":146,"column":78}},"3":{"start":{"line":147,"column":4},"end":{"line":147,"column":76}},"4":{"start":{"line":148,"column":4},"end":{"line":148,"column":65}},"5":{"start":{"line":150,"column":4},"end":{"line":150,"column":40}},"6":{"start":{"line":152,"column":4},"end":{"line":152,"column":6033}},"7":{"start":{"line":161,"column":4},"end":{"line":161,"column":6330}},"8":{"start":{"line":166,"column":4},"end":{"line":166,"column":6452}},"9":{"start":{"line":175,"column":4},"end":{"line":175,"column":6686}},"10":{"start":{"line":176,"column":6},"end":{"line":176,"column":44}},"11":{"start":{"line":179,"column":4},"end":{"line":179,"column":67}},"12":{"start":{"line":181,"column":4},"end":{"line":181,"column":69}},"13":{"start":{"line":183,"column":4},"end":{"line":183,"column":6984}},"14":{"start":{"line":187,"column":4},"end":{"line":187,"column":7148}},"15":{"start":{"line":191,"column":4},"end":{"line":191,"column":7286}},"16":{"start":{"line":207,"column":4},"end":{"line":207,"column":7770}},"17":{"start":{"line":208,"column":6},"end":{"line":208,"column":62}},"18":{"start":{"line":212,"column":4},"end":{"line":212,"column":8027}},"19":{"start":{"line":213,"column":6},"end":{"line":213,"column":8058}},"20":{"start":{"line":216,"column":6},"end":{"line":216,"column":8178}},"21":{"start":{"line":217,"column":8},"end":{"line":217,"column":8255}},"22":{"start":{"line":225,"column":4},"end":{"line":225,"column":33}},"23":{"start":{"line":227,"column":4},"end":{"line":227,"column":8484}},"24":{"start":{"line":234,"column":4},"end":{"line":234,"column":8633}},"25":{"start":{"line":235,"column":6},"end":{"line":235,"column":8702}},"26":{"start":{"line":241,"column":6},"end":{"line":241,"column":8895}},"27":{"start":{"line":247,"column":6},"end":{"line":247,"column":9069}},"28":{"start":{"line":254,"column":4},"end":{"line":254,"column":9311}},"29":{"start":{"line":255,"column":6},"end":{"line":255,"column":97}},"30":{"start":{"line":260,"column":6},"end":{"line":260,"column":36}},"31":{"start":{"line":261,"column":6},"end":{"line":261,"column":9577}},"32":{"start":{"line":269,"column":6},"end":{"line":269,"column":9786}},"33":{"start":{"line":278,"column":4},"end":{"line":278,"column":9999}},"34":{"start":{"line":284,"column":4},"end":{"line":284,"column":10139}},"35":{"start":{"line":294,"column":4},"end":{"line":294,"column":79}},"36":{"start":{"line":317,"column":4},"end":{"line":317,"column":78}},"37":{"start":{"line":318,"column":4},"end":{"line":318,"column":71}},"38":{"start":{"line":319,"column":4},"end":{"line":319,"column":65}},"39":{"start":{"line":321,"column":4},"end":{"line":321,"column":40}},"40":{"start":{"line":323,"column":4},"end":{"line":323,"column":11674}},"41":{"start":{"line":331,"column":4},"end":{"line":331,"column":95}},"42":{"start":{"line":333,"column":4},"end":{"line":333,"column":11972}},"43":{"start":{"line":343,"column":4},"end":{"line":343,"column":12217}},"44":{"start":{"line":344,"column":6},"end":{"line":344,"column":44}},"45":{"start":{"line":347,"column":4},"end":{"line":347,"column":86}},"46":{"start":{"line":349,"column":4},"end":{"line":349,"column":12479}},"47":{"start":{"line":353,"column":4},"end":{"line":353,"column":67}},"48":{"start":{"line":354,"column":4},"end":{"line":354,"column":69}},"49":{"start":{"line":356,"column":4},"end":{"line":356,"column":12761}},"50":{"start":{"line":371,"column":4},"end":{"line":371,"column":13239}},"51":{"start":{"line":372,"column":6},"end":{"line":372,"column":62}},"52":{"start":{"line":375,"column":4},"end":{"line":375,"column":34}},"53":{"start":{"line":377,"column":4},"end":{"line":377,"column":13459}},"54":{"start":{"line":384,"column":4},"end":{"line":384,"column":13603}},"55":{"start":{"line":385,"column":6},"end":{"line":385,"column":73}},"56":{"start":{"line":388,"column":4},"end":{"line":388,"column":51}},"57":{"start":{"line":391,"column":4},"end":{"line":391,"column":13905}},"58":{"start":{"line":400,"column":4},"end":{"line":400,"column":28}},"59":{"start":{"line":401,"column":4},"end":{"line":401,"column":14123}},"60":{"start":{"line":407,"column":4},"end":{"line":407,"column":95}},"61":{"start":{"line":409,"column":4},"end":{"line":409,"column":14355}},"62":{"start":{"line":410,"column":6},"end":{"line":410,"column":14424}},"63":{"start":{"line":416,"column":6},"end":{"line":416,"column":14607}},"64":{"start":{"line":421,"column":6},"end":{"line":421,"column":14770}},"65":{"start":{"line":428,"column":4},"end":{"line":428,"column":14959}},"66":{"start":{"line":435,"column":4},"end":{"line":435,"column":15112}},"67":{"start":{"line":444,"column":4},"end":{"line":444,"column":79}},"68":{"start":{"line":462,"column":4},"end":{"line":462,"column":71}},"69":{"start":{"line":463,"column":4},"end":{"line":463,"column":67}},"70":{"start":{"line":465,"column":4},"end":{"line":465,"column":38}},"71":{"start":{"line":467,"column":4},"end":{"line":467,"column":16281}},"72":{"start":{"line":474,"column":4},"end":{"line":474,"column":16433}},"73":{"start":{"line":475,"column":6},"end":{"line":475,"column":44}},"74":{"start":{"line":478,"column":4},"end":{"line":478,"column":62}},"75":{"start":{"line":479,"column":4},"end":{"line":479,"column":58}},"76":{"start":{"line":481,"column":4},"end":{"line":481,"column":28}},"77":{"start":{"line":482,"column":4},"end":{"line":482,"column":26}},"78":{"start":{"line":484,"column":4},"end":{"line":484,"column":16775}},"79":{"start":{"line":485,"column":6},"end":{"line":485,"column":73}},"80":{"start":{"line":488,"column":4},"end":{"line":488,"column":95}},"81":{"start":{"line":490,"column":4},"end":{"line":490,"column":17029}},"82":{"start":{"line":497,"column":4},"end":{"line":497,"column":17256}},"83":{"start":{"line":505,"column":4},"end":{"line":505,"column":68}},"84":{"start":{"line":506,"column":4},"end":{"line":506,"column":17473}},"85":{"start":{"line":507,"column":6},"end":{"line":507,"column":17514}},"86":{"start":{"line":513,"column":6},"end":{"line":513,"column":17653}},"87":{"start":{"line":514,"column":8},"end":{"line":514,"column":72}},"88":{"start":{"line":517,"column":6},"end":{"line":517,"column":90}},"89":{"start":{"line":518,"column":6},"end":{"line":518,"column":17891}},"90":{"start":{"line":526,"column":4},"end":{"line":526,"column":18036}},"91":{"start":{"line":534,"column":4},"end":{"line":534,"column":18247}},"92":{"start":{"line":535,"column":6},"end":{"line":535,"column":18332}},"93":{"start":{"line":541,"column":4},"end":{"line":541,"column":79}},"94":{"start":{"line":563,"column":4},"end":{"line":563,"column":32}},"95":{"start":{"line":564,"column":4},"end":{"line":564,"column":37}},"96":{"start":{"line":565,"column":4},"end":{"line":565,"column":87}},"97":{"start":{"line":567,"column":4},"end":{"line":567,"column":55}},"98":{"start":{"line":569,"column":4},"end":{"line":569,"column":65}},"99":{"start":{"line":570,"column":4},"end":{"line":570,"column":71}},"100":{"start":{"line":572,"column":4},"end":{"line":572,"column":20103}},"101":{"start":{"line":575,"column":4},"end":{"line":575,"column":72}},"102":{"start":{"line":579,"column":4},"end":{"line":579,"column":20496}},"103":{"start":{"line":586,"column":4},"end":{"line":586,"column":20713}},"104":{"start":{"line":587,"column":6},"end":{"line":587,"column":45}},"105":{"start":{"line":588,"column":6},"end":{"line":588,"column":20871}},"106":{"start":{"line":595,"column":6},"end":{"line":595,"column":59}},"107":{"start":{"line":596,"column":6},"end":{"line":596,"column":43}},"108":{"start":{"line":598,"column":4},"end":{"line":598,"column":52}}},"branchMap":{"1":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":4},"end":{"line":175,"column":4}},{"start":{"line":175,"column":4},"end":{"line":175,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"4":{"line":216,"type":"if","locations":[{"start":{"line":216,"column":6},"end":{"line":216,"column":6}},{"start":{"line":216,"column":6},"end":{"line":216,"column":6}}]},"5":{"line":234,"type":"if","locations":[{"start":{"line":234,"column":4},"end":{"line":234,"column":4}},{"start":{"line":234,"column":4},"end":{"line":234,"column":4}}]},"6":{"line":254,"type":"if","locations":[{"start":{"line":254,"column":4},"end":{"line":254,"column":4}},{"start":{"line":254,"column":4},"end":{"line":254,"column":4}}]},"7":{"line":343,"type":"if","locations":[{"start":{"line":343,"column":4},"end":{"line":343,"column":4}},{"start":{"line":343,"column":4},"end":{"line":343,"column":4}}]},"8":{"line":371,"type":"if","locations":[{"start":{"line":371,"column":4},"end":{"line":371,"column":4}},{"start":{"line":371,"column":4},"end":{"line":371,"column":4}}]},"9":{"line":384,"type":"if","locations":[{"start":{"line":384,"column":4},"end":{"line":384,"column":4}},{"start":{"line":384,"column":4},"end":{"line":384,"column":4}}]},"10":{"line":409,"type":"if","locations":[{"start":{"line":409,"column":4},"end":{"line":409,"column":4}},{"start":{"line":409,"column":4},"end":{"line":409,"column":4}}]},"11":{"line":474,"type":"if","locations":[{"start":{"line":474,"column":4},"end":{"line":474,"column":4}},{"start":{"line":474,"column":4},"end":{"line":474,"column":4}}]},"12":{"line":484,"type":"if","locations":[{"start":{"line":484,"column":4},"end":{"line":484,"column":4}},{"start":{"line":484,"column":4},"end":{"line":484,"column":4}}]},"13":{"line":506,"type":"if","locations":[{"start":{"line":506,"column":4},"end":{"line":506,"column":4}},{"start":{"line":506,"column":4},"end":{"line":506,"column":4}}]},"14":{"line":513,"type":"if","locations":[{"start":{"line":513,"column":6},"end":{"line":513,"column":6}},{"start":{"line":513,"column":6},"end":{"line":513,"column":6}}]},"15":{"line":534,"type":"if","locations":[{"start":{"line":534,"column":4},"end":{"line":534,"column":4}},{"start":{"line":534,"column":4},"end":{"line":534,"column":4}}]},"16":{"line":586,"type":"if","locations":[{"start":{"line":586,"column":4},"end":{"line":586,"column":4}},{"start":{"line":586,"column":4},"end":{"line":586,"column":4}}]}}},"contracts/lendingpool/LendingPoolConfigurator.sol":{"l":{"187":124,"188":105,"194":1,"198":1,"199":1,"219":17,"221":17,"226":17,"231":17,"239":17,"241":17,"243":17,"244":17,"246":17,"248":17,"263":1,"265":1,"267":1,"276":1,"278":1,"280":1,"289":1,"291":1,"293":1,"305":18,"307":18,"308":18,"310":18,"312":18,"320":1,"322":1,"324":1,"325":1,"341":14,"343":14,"344":14,"345":14,"347":14,"349":14,"357":1,"359":1,"361":1,"363":1,"371":1,"373":1,"375":1,"377":1,"385":1,"387":1,"389":1,"391":1,"399":7,"401":7,"403":7,"405":7,"413":8,"425":8,"430":7,"432":7,"434":7,"436":7,"444":2,"446":2,"448":2,"450":2,"458":2,"460":2,"462":2,"464":2,"473":1,"475":1,"477":1,"479":1,"488":1,"490":1,"492":1,"494":1,"504":1,"506":1,"508":1,"510":1,"519":1,"521":1,"523":1,"525":1,"534":0,"536":0,"538":0,"540":0,"552":0,"553":0,"562":51,"564":51,"571":51,"573":51,"581":3,"585":3,"587":3,"594":3,"602":26},"path":"/src/contracts/lendingpool/LendingPoolConfigurator.sol","s":{"1":124,"2":1,"3":1,"4":1,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":17,"12":17,"13":17,"14":17,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":18,"25":18,"26":18,"27":18,"28":18,"29":1,"30":1,"31":1,"32":1,"33":14,"34":14,"35":14,"36":14,"37":14,"38":14,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":7,"52":7,"53":7,"54":7,"55":8,"56":8,"57":7,"58":7,"59":7,"60":7,"61":2,"62":2,"63":2,"64":2,"65":2,"66":2,"67":2,"68":2,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":1,"80":1,"81":1,"82":1,"83":1,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":51,"92":51,"93":51,"94":51,"95":3,"96":3,"97":3,"98":3,"99":26},"b":{"1":[105,19],"2":[7,1]},"f":{"1":124,"2":1,"3":1,"4":17,"5":1,"6":1,"7":1,"8":18,"9":1,"10":14,"11":1,"12":1,"13":1,"14":7,"15":8,"16":2,"17":2,"18":1,"19":1,"20":1,"21":1,"22":0,"23":0,"24":51,"25":3,"26":26},"fnMap":{"1":{"name":"onlyAaveAdmin","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":189,"column":2}}},"2":{"name":"getRevision","line":193,"loc":{"start":{"line":193,"column":2},"end":{"line":195,"column":2}}},"3":{"name":"initialize","line":197,"loc":{"start":{"line":197,"column":2},"end":{"line":200,"column":2}}},"4":{"name":"initReserve","line":218,"loc":{"start":{"line":211,"column":2},"end":{"line":255,"column":2}}},"5":{"name":"updateAToken","line":262,"loc":{"start":{"line":262,"column":2},"end":{"line":268,"column":2}}},"6":{"name":"updateStableDebtToken","line":275,"loc":{"start":{"line":275,"column":2},"end":{"line":281,"column":2}}},"7":{"name":"updateVariableDebtToken","line":288,"loc":{"start":{"line":288,"column":2},"end":{"line":294,"column":2}}},"8":{"name":"enableBorrowingOnReserve","line":303,"loc":{"start":{"line":301,"column":2},"end":{"line":313,"column":2}}},"9":{"name":"disableBorrowingOnReserve","line":319,"loc":{"start":{"line":319,"column":2},"end":{"line":326,"column":2}}},"10":{"name":"enableReserveAsCollateral","line":340,"loc":{"start":{"line":335,"column":2},"end":{"line":350,"column":2}}},"11":{"name":"disableReserveAsCollateral","line":356,"loc":{"start":{"line":356,"column":2},"end":{"line":364,"column":2}}},"12":{"name":"enableReserveStableRate","line":370,"loc":{"start":{"line":370,"column":2},"end":{"line":378,"column":2}}},"13":{"name":"disableReserveStableRate","line":384,"loc":{"start":{"line":384,"column":2},"end":{"line":392,"column":2}}},"14":{"name":"activateReserve","line":398,"loc":{"start":{"line":398,"column":2},"end":{"line":406,"column":2}}},"15":{"name":"deactivateReserve","line":412,"loc":{"start":{"line":412,"column":2},"end":{"line":437,"column":2}}},"16":{"name":"freezeReserve","line":443,"loc":{"start":{"line":443,"column":2},"end":{"line":451,"column":2}}},"17":{"name":"unfreezeReserve","line":457,"loc":{"start":{"line":457,"column":2},"end":{"line":465,"column":2}}},"18":{"name":"setLtv","line":472,"loc":{"start":{"line":472,"column":2},"end":{"line":480,"column":2}}},"19":{"name":"setReserveFactor","line":487,"loc":{"start":{"line":487,"column":2},"end":{"line":495,"column":2}}},"20":{"name":"setLiquidationThreshold","line":503,"loc":{"start":{"line":503,"column":2},"end":{"line":511,"column":2}}},"21":{"name":"setLiquidationBonus","line":518,"loc":{"start":{"line":518,"column":2},"end":{"line":526,"column":2}}},"22":{"name":"setReserveDecimals","line":533,"loc":{"start":{"line":533,"column":2},"end":{"line":541,"column":2}}},"23":{"name":"setReserveInterestRateStrategyAddress","line":550,"loc":{"start":{"line":548,"column":2},"end":{"line":554,"column":2}}},"24":{"name":"_initTokenWithProxy","line":561,"loc":{"start":{"line":561,"column":2},"end":{"line":574,"column":2}}},"25":{"name":"_upgradeTokenImplementation","line":576,"loc":{"start":{"line":576,"column":2},"end":{"line":595,"column":2}}},"26":{"name":"setPoolPause","line":601,"loc":{"start":{"line":601,"column":2},"end":{"line":603,"column":2}}}},"statementMap":{"1":{"start":{"line":187,"column":4},"end":{"line":187,"column":88}},"2":{"start":{"line":194,"column":4},"end":{"line":194,"column":32}},"3":{"start":{"line":198,"column":4},"end":{"line":198,"column":31}},"4":{"start":{"line":199,"column":4},"end":{"line":199,"column":58}},"5":{"start":{"line":219,"column":4},"end":{"line":219,"column":89}},"6":{"start":{"line":221,"column":4},"end":{"line":221,"column":7918}},"7":{"start":{"line":226,"column":4},"end":{"line":226,"column":8046}},"8":{"start":{"line":231,"column":4},"end":{"line":231,"column":8177}},"9":{"start":{"line":239,"column":4},"end":{"line":239,"column":80}},"10":{"start":{"line":241,"column":4},"end":{"line":241,"column":53}},"11":{"start":{"line":243,"column":4},"end":{"line":243,"column":32}},"12":{"start":{"line":244,"column":4},"end":{"line":244,"column":33}},"13":{"start":{"line":246,"column":4},"end":{"line":246,"column":51}},"14":{"start":{"line":248,"column":4},"end":{"line":248,"column":8620}},"15":{"start":{"line":263,"column":4},"end":{"line":263,"column":71}},"16":{"start":{"line":265,"column":4},"end":{"line":265,"column":68}},"17":{"start":{"line":267,"column":4},"end":{"line":267,"column":61}},"18":{"start":{"line":276,"column":4},"end":{"line":276,"column":73}},"19":{"start":{"line":278,"column":4},"end":{"line":278,"column":70}},"20":{"start":{"line":280,"column":4},"end":{"line":280,"column":72}},"21":{"start":{"line":289,"column":4},"end":{"line":289,"column":75}},"22":{"start":{"line":291,"column":4},"end":{"line":291,"column":72}},"23":{"start":{"line":293,"column":4},"end":{"line":293,"column":76}},"24":{"start":{"line":305,"column":4},"end":{"line":305,"column":80}},"25":{"start":{"line":307,"column":4},"end":{"line":307,"column":42}},"26":{"start":{"line":308,"column":4},"end":{"line":308,"column":71}},"27":{"start":{"line":310,"column":4},"end":{"line":310,"column":51}},"28":{"start":{"line":312,"column":4},"end":{"line":312,"column":66}},"29":{"start":{"line":320,"column":4},"end":{"line":320,"column":80}},"30":{"start":{"line":322,"column":4},"end":{"line":322,"column":43}},"31":{"start":{"line":324,"column":4},"end":{"line":324,"column":51}},"32":{"start":{"line":325,"column":4},"end":{"line":325,"column":42}},"33":{"start":{"line":341,"column":4},"end":{"line":341,"column":80}},"34":{"start":{"line":343,"column":4},"end":{"line":343,"column":28}},"35":{"start":{"line":344,"column":4},"end":{"line":344,"column":62}},"36":{"start":{"line":345,"column":4},"end":{"line":345,"column":54}},"37":{"start":{"line":347,"column":4},"end":{"line":347,"column":51}},"38":{"start":{"line":349,"column":4},"end":{"line":349,"column":87}},"39":{"start":{"line":357,"column":4},"end":{"line":357,"column":80}},"40":{"start":{"line":359,"column":4},"end":{"line":359,"column":26}},"41":{"start":{"line":361,"column":4},"end":{"line":361,"column":51}},"42":{"start":{"line":363,"column":4},"end":{"line":363,"column":43}},"43":{"start":{"line":371,"column":4},"end":{"line":371,"column":80}},"44":{"start":{"line":373,"column":4},"end":{"line":373,"column":52}},"45":{"start":{"line":375,"column":4},"end":{"line":375,"column":51}},"46":{"start":{"line":377,"column":4},"end":{"line":377,"column":42}},"47":{"start":{"line":385,"column":4},"end":{"line":385,"column":80}},"48":{"start":{"line":387,"column":4},"end":{"line":387,"column":53}},"49":{"start":{"line":389,"column":4},"end":{"line":389,"column":51}},"50":{"start":{"line":391,"column":4},"end":{"line":391,"column":43}},"51":{"start":{"line":399,"column":4},"end":{"line":399,"column":80}},"52":{"start":{"line":401,"column":4},"end":{"line":401,"column":32}},"53":{"start":{"line":403,"column":4},"end":{"line":403,"column":51}},"54":{"start":{"line":405,"column":4},"end":{"line":405,"column":32}},"55":{"start":{"line":413,"column":4},"end":{"line":413,"column":14228}},"56":{"start":{"line":425,"column":4},"end":{"line":425,"column":14387}},"57":{"start":{"line":430,"column":4},"end":{"line":430,"column":80}},"58":{"start":{"line":432,"column":4},"end":{"line":432,"column":33}},"59":{"start":{"line":434,"column":4},"end":{"line":434,"column":51}},"60":{"start":{"line":436,"column":4},"end":{"line":436,"column":34}},"61":{"start":{"line":444,"column":4},"end":{"line":444,"column":80}},"62":{"start":{"line":446,"column":4},"end":{"line":446,"column":32}},"63":{"start":{"line":448,"column":4},"end":{"line":448,"column":51}},"64":{"start":{"line":450,"column":4},"end":{"line":450,"column":30}},"65":{"start":{"line":458,"column":4},"end":{"line":458,"column":80}},"66":{"start":{"line":460,"column":4},"end":{"line":460,"column":33}},"67":{"start":{"line":462,"column":4},"end":{"line":462,"column":51}},"68":{"start":{"line":464,"column":4},"end":{"line":464,"column":32}},"69":{"start":{"line":473,"column":4},"end":{"line":473,"column":80}},"70":{"start":{"line":475,"column":4},"end":{"line":475,"column":28}},"71":{"start":{"line":477,"column":4},"end":{"line":477,"column":51}},"72":{"start":{"line":479,"column":4},"end":{"line":479,"column":42}},"73":{"start":{"line":488,"column":4},"end":{"line":488,"column":80}},"74":{"start":{"line":490,"column":4},"end":{"line":490,"column":48}},"75":{"start":{"line":492,"column":4},"end":{"line":492,"column":51}},"76":{"start":{"line":494,"column":4},"end":{"line":494,"column":51}},"77":{"start":{"line":504,"column":4},"end":{"line":504,"column":80}},"78":{"start":{"line":506,"column":4},"end":{"line":506,"column":51}},"79":{"start":{"line":508,"column":4},"end":{"line":508,"column":51}},"80":{"start":{"line":510,"column":4},"end":{"line":510,"column":61}},"81":{"start":{"line":519,"column":4},"end":{"line":519,"column":80}},"82":{"start":{"line":521,"column":4},"end":{"line":521,"column":43}},"83":{"start":{"line":523,"column":4},"end":{"line":523,"column":51}},"84":{"start":{"line":525,"column":4},"end":{"line":525,"column":53}},"85":{"start":{"line":534,"column":4},"end":{"line":534,"column":80}},"86":{"start":{"line":536,"column":4},"end":{"line":536,"column":38}},"87":{"start":{"line":538,"column":4},"end":{"line":538,"column":51}},"88":{"start":{"line":540,"column":4},"end":{"line":540,"column":48}},"89":{"start":{"line":552,"column":4},"end":{"line":552,"column":73}},"90":{"start":{"line":553,"column":4},"end":{"line":553,"column":71}},"91":{"start":{"line":562,"column":4},"end":{"line":562,"column":93}},"92":{"start":{"line":564,"column":4},"end":{"line":564,"column":18940}},"93":{"start":{"line":571,"column":4},"end":{"line":571,"column":58}},"94":{"start":{"line":573,"column":4},"end":{"line":573,"column":25}},"95":{"start":{"line":581,"column":4},"end":{"line":581,"column":19368}},"96":{"start":{"line":585,"column":4},"end":{"line":585,"column":84}},"97":{"start":{"line":587,"column":4},"end":{"line":587,"column":19580}},"98":{"start":{"line":594,"column":4},"end":{"line":594,"column":49}},"99":{"start":{"line":602,"column":4},"end":{"line":602,"column":21}}},"branchMap":{"1":{"line":187,"type":"if","locations":[{"start":{"line":187,"column":4},"end":{"line":187,"column":4}},{"start":{"line":187,"column":4},"end":{"line":187,"column":4}}]},"2":{"line":425,"type":"if","locations":[{"start":{"line":425,"column":4},"end":{"line":425,"column":4}},{"start":{"line":425,"column":4},"end":{"line":425,"column":4}}]}}},"contracts/lendingpool/LendingPoolStorage.sol":{"l":{"30":0,"37":0},"path":"/src/contracts/lendingpool/LendingPoolStorage.sol","s":{"1":0,"2":0},"b":{},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"getReservesList","line":29,"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"getAddressesProvider","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":38,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":24}},"2":{"start":{"line":37,"column":4},"end":{"line":37,"column":29}}},"branchMap":{}},"contracts/libraries/configuration/ReserveConfiguration.sol":{"l":{"46":1,"55":570,"63":16,"72":194,"84":15,"97":112,"106":15,"119":97,"128":17,"137":178,"146":31,"155":179,"164":21,"173":97,"182":19,"191":97,"202":20,"215":97,"233":179,"235":179,"258":209,"260":209},"path":"/src/contracts/libraries/configuration/ReserveConfiguration.sol","s":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":179,"21":209,"22":209},"b":{},"f":{"1":1,"2":570,"3":16,"4":194,"5":15,"6":112,"7":15,"8":97,"9":17,"10":178,"11":31,"12":179,"13":21,"14":97,"15":19,"16":97,"17":20,"18":97,"19":179,"20":209},"fnMap":{"1":{"name":"setReserveFactor","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"getReserveFactor","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"3":{"name":"setLtv","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"getLtv","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"5":{"name":"setLiquidationThreshold","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":85,"column":2}}},"6":{"name":"getLiquidationThreshold","line":92,"loc":{"start":{"line":92,"column":2},"end":{"line":98,"column":2}}},"7":{"name":"setLiquidationBonus","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"8":{"name":"getLiquidationBonus","line":114,"loc":{"start":{"line":114,"column":2},"end":{"line":120,"column":2}}},"9":{"name":"setDecimals","line":127,"loc":{"start":{"line":127,"column":2},"end":{"line":129,"column":2}}},"10":{"name":"getDecimals","line":136,"loc":{"start":{"line":136,"column":2},"end":{"line":138,"column":2}}},"11":{"name":"setActive","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":147,"column":2}}},"12":{"name":"getActive","line":154,"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":2}}},"13":{"name":"setFrozen","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":165,"column":2}}},"14":{"name":"getFrozen","line":172,"loc":{"start":{"line":172,"column":2},"end":{"line":174,"column":2}}},"15":{"name":"setBorrowingEnabled","line":181,"loc":{"start":{"line":181,"column":2},"end":{"line":183,"column":2}}},"16":{"name":"getBorrowingEnabled","line":190,"loc":{"start":{"line":190,"column":2},"end":{"line":192,"column":2}}},"17":{"name":"setStableRateBorrowingEnabled","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":203,"column":2}}},"18":{"name":"getStableRateBorrowingEnabled","line":210,"loc":{"start":{"line":210,"column":2},"end":{"line":216,"column":2}}},"19":{"name":"getFlags","line":223,"loc":{"start":{"line":223,"column":2},"end":{"line":241,"column":2}}},"20":{"name":"getParams","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":266,"column":2}}}},"statementMap":{"1":{"start":{"line":46,"column":4},"end":{"line":46,"column":70}},"2":{"start":{"line":55,"column":4},"end":{"line":55,"column":51}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":43}},"4":{"start":{"line":72,"column":4},"end":{"line":72,"column":32}},"5":{"start":{"line":84,"column":4},"end":{"line":84,"column":75}},"6":{"start":{"line":97,"column":4},"end":{"line":97,"column":58}},"7":{"start":{"line":106,"column":4},"end":{"line":106,"column":67}},"8":{"start":{"line":119,"column":4},"end":{"line":119,"column":54}},"9":{"start":{"line":128,"column":4},"end":{"line":128,"column":61}},"10":{"start":{"line":137,"column":4},"end":{"line":137,"column":45}},"11":{"start":{"line":146,"column":4},"end":{"line":146,"column":74}},"12":{"start":{"line":155,"column":4},"end":{"line":155,"column":50}},"13":{"start":{"line":164,"column":4},"end":{"line":164,"column":74}},"14":{"start":{"line":173,"column":4},"end":{"line":173,"column":50}},"15":{"start":{"line":182,"column":4},"end":{"line":182,"column":78}},"16":{"start":{"line":191,"column":4},"end":{"line":191,"column":53}},"17":{"start":{"line":202,"column":4},"end":{"line":202,"column":85}},"18":{"start":{"line":215,"column":4},"end":{"line":215,"column":60}},"19":{"start":{"line":233,"column":4},"end":{"line":233,"column":33}},"20":{"start":{"line":235,"column":4},"end":{"line":235,"column":7613}},"21":{"start":{"line":258,"column":4},"end":{"line":258,"column":33}},"22":{"start":{"line":260,"column":4},"end":{"line":260,"column":8256}}},"branchMap":{}},"contracts/libraries/configuration/UserConfiguration.sol":{"l":{"31":49,"47":121,"63":1853,"77":235,"91":550,"100":33,"109":119},"path":"/src/contracts/libraries/configuration/UserConfiguration.sol","s":{"1":49,"2":121,"3":1853,"4":235,"5":550,"6":33,"7":119},"b":{},"f":{"1":49,"2":121,"3":1853,"4":235,"5":550,"6":33,"7":119},"fnMap":{"1":{"name":"setBorrowing","line":26,"loc":{"start":{"line":26,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"setUsingAsCollateral","line":42,"loc":{"start":{"line":42,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"isUsingAsCollateralOrBorrowing","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"isBorrowing","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":78,"column":2}}},"5":{"name":"isUsingAsCollateral","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":92,"column":2}}},"6":{"name":"isBorrowingAny","line":99,"loc":{"start":{"line":99,"column":2},"end":{"line":101,"column":2}}},"7":{"name":"isEmpty","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":110,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1104}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":1694}},"3":{"start":{"line":63,"column":4},"end":{"line":63,"column":53}},"4":{"start":{"line":77,"column":4},"end":{"line":77,"column":53}},"5":{"start":{"line":91,"column":4},"end":{"line":91,"column":57}},"6":{"start":{"line":100,"column":4},"end":{"line":100,"column":42}},"7":{"start":{"line":109,"column":4},"end":{"line":109,"column":25}}},"branchMap":{}},"contracts/libraries/helpers/Errors.sol":{"l":{},"path":"/src/contracts/libraries/helpers/Errors.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/libraries/helpers/Helpers.sol":{"l":{"24":395},"path":"/src/contracts/libraries/helpers/Helpers.sol","s":{"1":395},"b":{},"f":{"1":395},"fnMap":{"1":{"name":"getUserCurrentDebt","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":24,"column":4},"end":{"line":24,"column":653}}},"branchMap":{}},"contracts/libraries/logic/GenericLogic.sol":{"l":{"65":33,"69":27,"72":6,"74":6,"76":6,"77":0,"80":6,"88":6,"89":0,"92":6,"96":6,"99":6,"100":3,"103":3,"109":3,"115":3,"169":119,"171":119,"172":10,"174":109,"175":1853,"176":1668,"179":185,"180":185,"182":185,"186":185,"187":185,"189":185,"190":128,"192":128,"197":128,"199":128,"200":128,"205":185,"206":63,"209":63,"213":63,"219":109,"222":109,"226":109,"231":109,"252":112,"254":64,"271":21,"273":21,"274":11,"277":10,"278":10},"path":"/src/contracts/libraries/logic/GenericLogic.sol","s":{"1":33,"2":27,"3":6,"4":6,"5":6,"6":0,"7":6,"8":6,"9":0,"10":6,"11":6,"12":6,"13":3,"14":3,"15":3,"16":3,"17":119,"18":119,"19":10,"20":109,"21":1853,"22":185,"23":185,"24":185,"25":185,"26":185,"27":185,"28":128,"29":128,"30":128,"31":128,"32":128,"33":185,"34":63,"35":63,"36":63,"37":109,"38":109,"39":109,"40":109,"41":112,"42":48,"43":64,"44":21,"45":21,"46":11,"47":10,"48":10},"b":{"1":[27,6],"2":[0,6],"3":[0,6],"4":[3,3],"5":[10,109],"6":[1668,185],"7":[128,57],"8":[63,122],"9":[48,64],"10":[11,10]},"f":{"1":33,"2":119,"3":112,"4":21},"fnMap":{"1":{"name":"balanceDecreaseAllowed","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":116,"column":2}}},"2":{"name":"calculateUserAccountData","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":238,"column":2}}},"3":{"name":"calculateHealthFactorFromBalances","line":247,"loc":{"start":{"line":247,"column":2},"end":{"line":255,"column":2}}},"4":{"name":"calculateAvailableBorrowsETH","line":266,"loc":{"start":{"line":266,"column":2},"end":{"line":279,"column":2}}}},"statementMap":{"1":{"start":{"line":65,"column":4},"end":{"line":65,"column":2530}},"2":{"start":{"line":69,"column":6},"end":{"line":69,"column":17}},"3":{"start":{"line":72,"column":4},"end":{"line":72,"column":47}},"4":{"start":{"line":74,"column":4},"end":{"line":74,"column":80}},"5":{"start":{"line":76,"column":4},"end":{"line":76,"column":2807}},"6":{"start":{"line":77,"column":6},"end":{"line":77,"column":17}},"7":{"start":{"line":80,"column":4},"end":{"line":80,"column":3008}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":3133}},"9":{"start":{"line":89,"column":6},"end":{"line":89,"column":17}},"10":{"start":{"line":92,"column":4},"end":{"line":92,"column":3245}},"11":{"start":{"line":96,"column":4},"end":{"line":96,"column":95}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":3528}},"13":{"start":{"line":100,"column":6},"end":{"line":100,"column":18}},"14":{"start":{"line":103,"column":4},"end":{"line":103,"column":3647}},"15":{"start":{"line":109,"column":4},"end":{"line":109,"column":3854}},"16":{"start":{"line":115,"column":4},"end":{"line":115,"column":87}},"17":{"start":{"line":169,"column":4},"end":{"line":169,"column":44}},"18":{"start":{"line":171,"column":4},"end":{"line":171,"column":5830}},"19":{"start":{"line":172,"column":6},"end":{"line":172,"column":38}},"20":{"start":{"line":174,"column":4},"end":{"line":174,"column":5908}},"21":{"start":{"line":175,"column":6},"end":{"line":175,"column":5971}},"22":{"start":{"line":179,"column":6},"end":{"line":179,"column":50}},"23":{"start":{"line":180,"column":6},"end":{"line":180,"column":96}},"24":{"start":{"line":182,"column":6},"end":{"line":182,"column":6227}},"25":{"start":{"line":186,"column":6},"end":{"line":186,"column":39}},"26":{"start":{"line":187,"column":6},"end":{"line":187,"column":97}},"27":{"start":{"line":189,"column":6},"end":{"line":189,"column":6481}},"28":{"start":{"line":190,"column":8},"end":{"line":190,"column":93}},"29":{"start":{"line":192,"column":8},"end":{"line":192,"column":6673}},"30":{"start":{"line":197,"column":8},"end":{"line":197,"column":95}},"31":{"start":{"line":199,"column":8},"end":{"line":199,"column":71}},"32":{"start":{"line":200,"column":8},"end":{"line":200,"column":6976}},"33":{"start":{"line":205,"column":6},"end":{"line":205,"column":7126}},"34":{"start":{"line":206,"column":8},"end":{"line":206,"column":7174}},"35":{"start":{"line":209,"column":8},"end":{"line":209,"column":7296}},"36":{"start":{"line":213,"column":8},"end":{"line":213,"column":7455}},"37":{"start":{"line":219,"column":4},"end":{"line":219,"column":7632}},"38":{"start":{"line":222,"column":4},"end":{"line":222,"column":7752}},"39":{"start":{"line":226,"column":4},"end":{"line":226,"column":7903}},"40":{"start":{"line":231,"column":4},"end":{"line":231,"column":8077}},"41":{"start":{"line":252,"column":4},"end":{"line":252,"column":49}},"42":{"start":{"line":252,"column":31},"end":{"line":252,"column":49}},"43":{"start":{"line":254,"column":4},"end":{"line":254,"column":91}},"44":{"start":{"line":271,"column":4},"end":{"line":271,"column":70}},"45":{"start":{"line":273,"column":4},"end":{"line":273,"column":9571}},"46":{"start":{"line":274,"column":6},"end":{"line":274,"column":14}},"47":{"start":{"line":277,"column":4},"end":{"line":277,"column":66}},"48":{"start":{"line":278,"column":4},"end":{"line":278,"column":30}}},"branchMap":{"1":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":4},"end":{"line":65,"column":4}},{"start":{"line":65,"column":4},"end":{"line":65,"column":4}}]},"2":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":4}},{"start":{"line":76,"column":4},"end":{"line":76,"column":4}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"4":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":4},"end":{"line":99,"column":4}},{"start":{"line":99,"column":4},"end":{"line":99,"column":4}}]},"5":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":4},"end":{"line":171,"column":4}},{"start":{"line":171,"column":4},"end":{"line":171,"column":4}}]},"6":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":6},"end":{"line":175,"column":6}},{"start":{"line":175,"column":6},"end":{"line":175,"column":6}}]},"7":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"8":{"line":205,"type":"if","locations":[{"start":{"line":205,"column":6},"end":{"line":205,"column":6}},{"start":{"line":205,"column":6},"end":{"line":205,"column":6}}]},"9":{"line":252,"type":"if","locations":[{"start":{"line":252,"column":4},"end":{"line":252,"column":4}},{"start":{"line":252,"column":4},"end":{"line":252,"column":4}}]},"10":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":4},"end":{"line":273,"column":4}},{"start":{"line":273,"column":4},"end":{"line":273,"column":4}}]}}},"contracts/libraries/logic/ReserveLogic.sol":{"l":{"85":648,"88":648,"90":370,"93":278,"97":278,"108":810,"111":810,"113":498,"116":312,"120":312,"134":11,"139":10,"151":239,"152":239,"153":239,"155":239,"162":239,"183":3,"185":3,"187":3,"188":3,"190":3,"206":17,"207":17,"209":17,"212":17,"213":17,"216":17,"217":17,"218":17,"219":17,"246":235,"248":235,"250":235,"253":235,"255":235,"267":234,"268":234,"269":234,"271":234,"272":234,"273":234,"275":234,"316":239,"318":239,"320":239,"321":239,"325":0,"328":0,"336":0,"339":0,"342":0,"347":0,"350":0,"356":0,"358":0,"374":239,"376":239,"378":239,"379":239,"382":239,"383":69,"387":69,"388":69,"390":69,"394":69,"395":39,"399":39,"400":39,"401":39,"406":239,"407":239},"path":"/src/contracts/libraries/logic/ReserveLogic.sol","s":{"1":648,"2":648,"3":370,"4":278,"5":278,"6":810,"7":810,"8":498,"9":312,"10":312,"11":11,"12":10,"13":239,"14":239,"15":239,"16":239,"17":239,"18":3,"19":3,"20":3,"21":3,"22":3,"23":17,"24":17,"25":17,"26":17,"27":17,"28":17,"29":17,"30":17,"31":17,"32":235,"33":235,"34":235,"35":235,"36":235,"37":234,"38":234,"39":234,"40":234,"41":234,"42":234,"43":234,"44":239,"45":239,"46":239,"47":239,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":239,"58":239,"59":239,"60":239,"61":239,"62":69,"63":69,"64":69,"65":69,"66":69,"67":39,"68":39,"69":39,"70":39,"71":239,"72":239},"b":{"1":[370,278],"2":[498,312],"3":[10,1],"4":[3,0],"5":[17,0],"6":[17,0],"7":[17,0],"8":[234,0],"9":[234,0],"10":[234,0],"11":[239,0],"12":[69,170],"13":[69,0],"14":[39,30],"15":[39,0]},"f":{"1":648,"2":810,"3":11,"4":239,"5":3,"6":17,"7":235,"8":239,"9":239},"fnMap":{"1":{"name":"getNormalizedIncome","line":84,"loc":{"start":{"line":84,"column":2},"end":{"line":98,"column":2}}},"2":{"name":"getNormalizedDebt","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":121,"column":2}}},"3":{"name":"getDebtTokenAddress","line":129,"loc":{"start":{"line":129,"column":2},"end":{"line":143,"column":2}}},"4":{"name":"updateState","line":150,"loc":{"start":{"line":150,"column":2},"end":{"line":169,"column":2}}},"5":{"name":"cumulateToLiquidityIndex","line":178,"loc":{"start":{"line":178,"column":2},"end":{"line":191,"column":2}}},"6":{"name":"init","line":199,"loc":{"start":{"line":199,"column":2},"end":{"line":220,"column":2}}},"7":{"name":"updateInterestRates","line":239,"loc":{"start":{"line":239,"column":2},"end":{"line":283,"column":2}}},"8":{"name":"_mintToTreasury","line":309,"loc":{"start":{"line":309,"column":2},"end":{"line":359,"column":2}}},"9":{"name":"_updateIndexes","line":368,"loc":{"start":{"line":368,"column":2},"end":{"line":408,"column":2}}}},"statementMap":{"1":{"start":{"line":85,"column":4},"end":{"line":85,"column":50}},"2":{"start":{"line":88,"column":4},"end":{"line":88,"column":3533}},"3":{"start":{"line":90,"column":6},"end":{"line":90,"column":35}},"4":{"start":{"line":93,"column":4},"end":{"line":93,"column":3745}},"5":{"start":{"line":97,"column":4},"end":{"line":97,"column":20}},"6":{"start":{"line":108,"column":4},"end":{"line":108,"column":50}},"7":{"start":{"line":111,"column":4},"end":{"line":111,"column":4417}},"8":{"start":{"line":113,"column":6},"end":{"line":113,"column":40}},"9":{"start":{"line":116,"column":4},"end":{"line":116,"column":4639}},"10":{"start":{"line":120,"column":4},"end":{"line":120,"column":20}},"11":{"start":{"line":134,"column":4},"end":{"line":134,"column":5256}},"12":{"start":{"line":139,"column":4},"end":{"line":139,"column":5559}},"13":{"start":{"line":151,"column":4},"end":{"line":151,"column":64}},"14":{"start":{"line":152,"column":4},"end":{"line":152,"column":69}},"15":{"start":{"line":153,"column":4},"end":{"line":153,"column":59}},"16":{"start":{"line":155,"column":4},"end":{"line":155,"column":6182}},"17":{"start":{"line":162,"column":4},"end":{"line":162,"column":6375}},"18":{"start":{"line":183,"column":4},"end":{"line":183,"column":88}},"19":{"start":{"line":185,"column":4},"end":{"line":185,"column":65}},"20":{"start":{"line":187,"column":4},"end":{"line":187,"column":49}},"21":{"start":{"line":188,"column":4},"end":{"line":188,"column":64}},"22":{"start":{"line":190,"column":4},"end":{"line":190,"column":43}},"23":{"start":{"line":206,"column":4},"end":{"line":206,"column":83}},"24":{"start":{"line":207,"column":4},"end":{"line":207,"column":7908}},"25":{"start":{"line":209,"column":6},"end":{"line":209,"column":55}},"26":{"start":{"line":212,"column":4},"end":{"line":212,"column":8064}},"27":{"start":{"line":213,"column":6},"end":{"line":213,"column":60}},"28":{"start":{"line":216,"column":4},"end":{"line":216,"column":40}},"29":{"start":{"line":217,"column":4},"end":{"line":217,"column":58}},"30":{"start":{"line":218,"column":4},"end":{"line":218,"column":62}},"31":{"start":{"line":219,"column":4},"end":{"line":219,"column":68}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":44}},"33":{"start":{"line":248,"column":4},"end":{"line":248,"column":63}},"34":{"start":{"line":250,"column":4},"end":{"line":250,"column":9530}},"35":{"start":{"line":253,"column":4},"end":{"line":253,"column":76}},"36":{"start":{"line":255,"column":4},"end":{"line":255,"column":9713}},"37":{"start":{"line":267,"column":4},"end":{"line":267,"column":87}},"38":{"start":{"line":268,"column":4},"end":{"line":268,"column":88}},"39":{"start":{"line":269,"column":4},"end":{"line":269,"column":92}},"40":{"start":{"line":271,"column":4},"end":{"line":271,"column":64}},"41":{"start":{"line":272,"column":4},"end":{"line":272,"column":64}},"42":{"start":{"line":273,"column":4},"end":{"line":273,"column":68}},"43":{"start":{"line":275,"column":4},"end":{"line":275,"column":10646}},"44":{"start":{"line":316,"column":4},"end":{"line":316,"column":39}},"45":{"start":{"line":318,"column":4},"end":{"line":318,"column":64}},"46":{"start":{"line":320,"column":4},"end":{"line":320,"column":12121}},"47":{"start":{"line":321,"column":6},"end":{"line":321,"column":12}},"48":{"start":{"line":325,"column":4},"end":{"line":325,"column":86}},"49":{"start":{"line":328,"column":4},"end":{"line":328,"column":12457}},"50":{"start":{"line":336,"column":4},"end":{"line":336,"column":90}},"51":{"start":{"line":339,"column":4},"end":{"line":339,"column":84}},"52":{"start":{"line":342,"column":4},"end":{"line":342,"column":12963}},"53":{"start":{"line":347,"column":4},"end":{"line":347,"column":90}},"54":{"start":{"line":350,"column":4},"end":{"line":350,"column":13330}},"55":{"start":{"line":356,"column":4},"end":{"line":356,"column":75}},"56":{"start":{"line":358,"column":4},"end":{"line":358,"column":86}},"57":{"start":{"line":374,"column":4},"end":{"line":374,"column":50}},"58":{"start":{"line":376,"column":4},"end":{"line":376,"column":63}},"59":{"start":{"line":378,"column":4},"end":{"line":378,"column":46}},"60":{"start":{"line":379,"column":4},"end":{"line":379,"column":56}},"61":{"start":{"line":382,"column":4},"end":{"line":382,"column":14442}},"62":{"start":{"line":383,"column":6},"end":{"line":383,"column":14483}},"63":{"start":{"line":387,"column":6},"end":{"line":387,"column":74}},"64":{"start":{"line":388,"column":6},"end":{"line":388,"column":77}},"65":{"start":{"line":390,"column":6},"end":{"line":390,"column":56}},"66":{"start":{"line":394,"column":6},"end":{"line":394,"column":14986}},"67":{"start":{"line":395,"column":8},"end":{"line":395,"column":15048}},"68":{"start":{"line":399,"column":8},"end":{"line":399,"column":91}},"69":{"start":{"line":400,"column":8},"end":{"line":400,"column":90}},"70":{"start":{"line":401,"column":8},"end":{"line":401,"column":68}},"71":{"start":{"line":406,"column":4},"end":{"line":406,"column":56}},"72":{"start":{"line":407,"column":4},"end":{"line":407,"column":54}}},"branchMap":{"1":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":88,"column":4}},{"start":{"line":88,"column":4},"end":{"line":88,"column":4}}]},"2":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"3":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"4":{"line":188,"type":"if","locations":[{"start":{"line":188,"column":4},"end":{"line":188,"column":4}},{"start":{"line":188,"column":4},"end":{"line":188,"column":4}}]},"5":{"line":206,"type":"if","locations":[{"start":{"line":206,"column":4},"end":{"line":206,"column":4}},{"start":{"line":206,"column":4},"end":{"line":206,"column":4}}]},"6":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"7":{"line":212,"type":"if","locations":[{"start":{"line":212,"column":4},"end":{"line":212,"column":4}},{"start":{"line":212,"column":4},"end":{"line":212,"column":4}}]},"8":{"line":267,"type":"if","locations":[{"start":{"line":267,"column":4},"end":{"line":267,"column":4}},{"start":{"line":267,"column":4},"end":{"line":267,"column":4}}]},"9":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"10":{"line":269,"type":"if","locations":[{"start":{"line":269,"column":4},"end":{"line":269,"column":4}},{"start":{"line":269,"column":4},"end":{"line":269,"column":4}}]},"11":{"line":320,"type":"if","locations":[{"start":{"line":320,"column":4},"end":{"line":320,"column":4}},{"start":{"line":320,"column":4},"end":{"line":320,"column":4}}]},"12":{"line":382,"type":"if","locations":[{"start":{"line":382,"column":4},"end":{"line":382,"column":4}},{"start":{"line":382,"column":4},"end":{"line":382,"column":4}}]},"13":{"line":388,"type":"if","locations":[{"start":{"line":388,"column":6},"end":{"line":388,"column":6}},{"start":{"line":388,"column":6},"end":{"line":388,"column":6}}]},"14":{"line":394,"type":"if","locations":[{"start":{"line":394,"column":6},"end":{"line":394,"column":6}},{"start":{"line":394,"column":6},"end":{"line":394,"column":6}}]},"15":{"line":400,"type":"if","locations":[{"start":{"line":400,"column":8},"end":{"line":400,"column":8}},{"start":{"line":400,"column":8},"end":{"line":400,"column":8}}]}}},"contracts/libraries/logic/ValidationLogic.sol":{"l":{"38":104,"40":104,"41":102,"42":102,"60":25,"62":24,"64":23,"125":63,"127":63,"134":63,"135":63,"137":63,"140":63,"146":61,"160":61,"162":55,"168":55,"172":55,"186":50,"189":0,"191":0,"200":0,"202":0,"222":20,"224":20,"226":20,"228":18,"236":18,"257":4,"259":4,"260":4,"262":4,"263":2,"265":2,"273":1,"275":1,"283":0,"304":7,"306":7,"308":7,"328":13,"329":12,"349":10,"352":2,"355":8,"356":1,"362":7,"366":7,"367":1,"373":6,"374":1,"380":5,"402":18,"405":2,"408":16,"411":0,"417":16,"418":8,"422":8,"423":1,"430":15,"431":2,"437":13,"453":9,"454":1,"460":8,"461":8,"462":2,"464":6,"465":1,"471":5},"path":"/src/contracts/libraries/logic/ValidationLogic.sol","s":{"1":104,"2":104,"3":102,"4":102,"5":25,"6":24,"7":23,"8":63,"9":63,"10":63,"11":63,"12":63,"13":63,"14":61,"15":61,"16":55,"17":55,"18":55,"19":50,"20":0,"21":0,"22":0,"23":0,"24":20,"25":20,"26":20,"27":18,"28":18,"29":4,"30":4,"31":4,"32":4,"33":2,"34":2,"35":2,"36":1,"37":1,"38":0,"39":7,"40":7,"41":7,"42":13,"43":12,"44":10,"45":2,"46":8,"47":1,"48":7,"49":7,"50":1,"51":6,"52":1,"53":5,"54":18,"55":2,"56":16,"57":0,"58":16,"59":8,"60":8,"61":1,"62":15,"63":2,"64":13,"65":9,"66":1,"67":8,"68":8,"69":2,"70":6,"71":1,"72":5},"b":{"1":[102,2],"2":[102,0],"3":[102,0],"4":[24,1],"5":[23,1],"6":[22,1],"7":[63,0],"8":[63,0],"9":[63,0],"10":[61,2],"11":[55,6],"12":[55,0],"13":[50,5],"14":[0,50],"15":[0,0],"16":[0,0],"17":[0,0],"18":[20,0],"19":[18,2],"20":[18,0],"21":[17,1],"22":[4,0],"23":[4,0],"24":[2,2],"25":[1,1],"26":[2,0],"27":[1,1],"28":[1,0],"29":[1,0],"30":[7,0],"31":[6,1],"32":[12,1],"33":[11,1],"34":[2,8],"35":[1,7],"36":[1,6],"37":[1,5],"38":[2,16],"39":[0,16],"40":[8,8],"41":[1,7],"42":[2,13],"43":[1,8],"44":[2,6],"45":[1,5]},"f":{"1":104,"2":25,"3":63,"4":20,"5":4,"6":7,"7":13,"8":10,"9":18,"10":9},"fnMap":{"1":{"name":"validateDeposit","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":43,"column":2}}},"2":{"name":"validateWithdraw","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":76,"column":2}}},"3":{"name":"validateBorrow","line":113,"loc":{"start":{"line":113,"column":2},"end":{"line":204,"column":2}}},"4":{"name":"validateRepay","line":214,"loc":{"start":{"line":214,"column":2},"end":{"line":240,"column":2}}},"5":{"name":"validateSwapRateMode","line":250,"loc":{"start":{"line":250,"column":2},"end":{"line":285,"column":2}}},"6":{"name":"validateSetUseReserveAsCollateral","line":296,"loc":{"start":{"line":296,"column":2},"end":{"line":320,"column":2}}},"7":{"name":"validateFlashloan","line":327,"loc":{"start":{"line":327,"column":2},"end":{"line":330,"column":2}}},"8":{"name":"validateLiquidationCall","line":341,"loc":{"start":{"line":341,"column":2},"end":{"line":381,"column":2}}},"9":{"name":"validateRepayWithCollateral","line":393,"loc":{"start":{"line":393,"column":2},"end":{"line":438,"column":2}}},"10":{"name":"validateSwapLiquidity","line":447,"loc":{"start":{"line":447,"column":2},"end":{"line":472,"column":2}}}},"statementMap":{"1":{"start":{"line":38,"column":4},"end":{"line":38,"column":74}},"2":{"start":{"line":40,"column":4},"end":{"line":40,"column":56}},"3":{"start":{"line":41,"column":4},"end":{"line":41,"column":46}},"4":{"start":{"line":42,"column":4},"end":{"line":42,"column":51}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":56}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":75}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":2437}},"8":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"9":{"start":{"line":127,"column":4},"end":{"line":127,"column":4488}},"10":{"start":{"line":134,"column":4},"end":{"line":134,"column":51}},"11":{"start":{"line":135,"column":4},"end":{"line":135,"column":56}},"12":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"13":{"start":{"line":140,"column":4},"end":{"line":140,"column":4827}},"14":{"start":{"line":146,"column":4},"end":{"line":146,"column":5049}},"15":{"start":{"line":160,"column":4},"end":{"line":160,"column":77}},"16":{"start":{"line":162,"column":4},"end":{"line":162,"column":5434}},"17":{"start":{"line":168,"column":4},"end":{"line":168,"column":5703}},"18":{"start":{"line":172,"column":4},"end":{"line":172,"column":5861}},"19":{"start":{"line":186,"column":4},"end":{"line":186,"column":6430}},"20":{"start":{"line":189,"column":6},"end":{"line":189,"column":82}},"21":{"start":{"line":191,"column":6},"end":{"line":191,"column":6685}},"22":{"start":{"line":200,"column":6},"end":{"line":200,"column":90}},"23":{"start":{"line":202,"column":6},"end":{"line":202,"column":89}},"24":{"start":{"line":222,"column":4},"end":{"line":222,"column":53}},"25":{"start":{"line":224,"column":4},"end":{"line":224,"column":46}},"26":{"start":{"line":226,"column":4},"end":{"line":226,"column":60}},"27":{"start":{"line":228,"column":4},"end":{"line":228,"column":8040}},"28":{"start":{"line":236,"column":4},"end":{"line":236,"column":8339}},"29":{"start":{"line":257,"column":4},"end":{"line":257,"column":96}},"30":{"start":{"line":259,"column":4},"end":{"line":259,"column":46}},"31":{"start":{"line":260,"column":4},"end":{"line":260,"column":51}},"32":{"start":{"line":262,"column":4},"end":{"line":262,"column":9332}},"33":{"start":{"line":263,"column":6},"end":{"line":263,"column":76}},"34":{"start":{"line":264,"column":11},"end":{"line":264,"column":9485}},"35":{"start":{"line":265,"column":6},"end":{"line":265,"column":80}},"36":{"start":{"line":273,"column":6},"end":{"line":273,"column":68}},"37":{"start":{"line":275,"column":6},"end":{"line":275,"column":10079}},"38":{"start":{"line":283,"column":6},"end":{"line":283,"column":55}},"39":{"start":{"line":304,"column":4},"end":{"line":304,"column":83}},"40":{"start":{"line":306,"column":4},"end":{"line":306,"column":79}},"41":{"start":{"line":308,"column":4},"end":{"line":308,"column":11408}},"42":{"start":{"line":328,"column":4},"end":{"line":328,"column":58}},"43":{"start":{"line":329,"column":4},"end":{"line":329,"column":98}},"44":{"start":{"line":349,"column":4},"end":{"line":349,"column":12893}},"45":{"start":{"line":352,"column":6},"end":{"line":352,"column":98}},"46":{"start":{"line":355,"column":4},"end":{"line":355,"column":13115}},"47":{"start":{"line":356,"column":6},"end":{"line":356,"column":13200}},"48":{"start":{"line":362,"column":4},"end":{"line":362,"column":13408}},"49":{"start":{"line":366,"column":4},"end":{"line":366,"column":13592}},"50":{"start":{"line":367,"column":6},"end":{"line":367,"column":13629}},"51":{"start":{"line":373,"column":4},"end":{"line":373,"column":13783}},"52":{"start":{"line":374,"column":6},"end":{"line":374,"column":13844}},"53":{"start":{"line":380,"column":4},"end":{"line":380,"column":79}},"54":{"start":{"line":402,"column":4},"end":{"line":402,"column":14907}},"55":{"start":{"line":405,"column":6},"end":{"line":405,"column":98}},"56":{"start":{"line":408,"column":4},"end":{"line":408,"column":15129}},"57":{"start":{"line":411,"column":6},"end":{"line":411,"column":15248}},"58":{"start":{"line":417,"column":4},"end":{"line":417,"column":15402}},"59":{"start":{"line":418,"column":6},"end":{"line":418,"column":15490}},"60":{"start":{"line":422,"column":6},"end":{"line":422,"column":15680}},"61":{"start":{"line":423,"column":8},"end":{"line":423,"column":15719}},"62":{"start":{"line":430,"column":4},"end":{"line":430,"column":15885}},"63":{"start":{"line":431,"column":6},"end":{"line":431,"column":15946}},"64":{"start":{"line":437,"column":4},"end":{"line":437,"column":79}},"65":{"start":{"line":453,"column":4},"end":{"line":453,"column":16711}},"66":{"start":{"line":454,"column":6},"end":{"line":454,"column":16748}},"67":{"start":{"line":460,"column":4},"end":{"line":460,"column":80}},"68":{"start":{"line":461,"column":4},"end":{"line":461,"column":16978}},"69":{"start":{"line":462,"column":6},"end":{"line":462,"column":98}},"70":{"start":{"line":464,"column":4},"end":{"line":464,"column":17149}},"71":{"start":{"line":465,"column":6},"end":{"line":465,"column":17177}},"72":{"start":{"line":471,"column":4},"end":{"line":471,"column":79}}},"branchMap":{"1":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":4},"end":{"line":41,"column":4}},{"start":{"line":41,"column":4},"end":{"line":41,"column":4}}]},"3":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":4},"end":{"line":42,"column":4}},{"start":{"line":42,"column":4},"end":{"line":42,"column":4}}]},"4":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":4},"end":{"line":60,"column":4}},{"start":{"line":60,"column":4},"end":{"line":60,"column":4}}]},"5":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"6":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":4},"end":{"line":64,"column":4}},{"start":{"line":64,"column":4},"end":{"line":64,"column":4}}]},"7":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":4},"end":{"line":134,"column":4}},{"start":{"line":134,"column":4},"end":{"line":134,"column":4}}]},"8":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":4},"end":{"line":135,"column":4}},{"start":{"line":135,"column":4},"end":{"line":135,"column":4}}]},"9":{"line":137,"type":"if","locations":[{"start":{"line":137,"column":4},"end":{"line":137,"column":4}},{"start":{"line":137,"column":4},"end":{"line":137,"column":4}}]},"10":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":140,"column":4}},{"start":{"line":140,"column":4},"end":{"line":140,"column":4}}]},"11":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]},"12":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":4},"end":{"line":162,"column":4}},{"start":{"line":162,"column":4},"end":{"line":162,"column":4}}]},"13":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":4},"end":{"line":172,"column":4}},{"start":{"line":172,"column":4},"end":{"line":172,"column":4}}]},"14":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":4},"end":{"line":186,"column":4}},{"start":{"line":186,"column":4},"end":{"line":186,"column":4}}]},"15":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":6},"end":{"line":189,"column":6}},{"start":{"line":189,"column":6},"end":{"line":189,"column":6}}]},"16":{"line":191,"type":"if","locations":[{"start":{"line":191,"column":6},"end":{"line":191,"column":6}},{"start":{"line":191,"column":6},"end":{"line":191,"column":6}}]},"17":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":6},"end":{"line":202,"column":6}},{"start":{"line":202,"column":6},"end":{"line":202,"column":6}}]},"18":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"19":{"line":226,"type":"if","locations":[{"start":{"line":226,"column":4},"end":{"line":226,"column":4}},{"start":{"line":226,"column":4},"end":{"line":226,"column":4}}]},"20":{"line":228,"type":"if","locations":[{"start":{"line":228,"column":4},"end":{"line":228,"column":4}},{"start":{"line":228,"column":4},"end":{"line":228,"column":4}}]},"21":{"line":236,"type":"if","locations":[{"start":{"line":236,"column":4},"end":{"line":236,"column":4}},{"start":{"line":236,"column":4},"end":{"line":236,"column":4}}]},"22":{"line":259,"type":"if","locations":[{"start":{"line":259,"column":4},"end":{"line":259,"column":4}},{"start":{"line":259,"column":4},"end":{"line":259,"column":4}}]},"23":{"line":260,"type":"if","locations":[{"start":{"line":260,"column":4},"end":{"line":260,"column":4}},{"start":{"line":260,"column":4},"end":{"line":260,"column":4}}]},"24":{"line":262,"type":"if","locations":[{"start":{"line":262,"column":4},"end":{"line":262,"column":4}},{"start":{"line":262,"column":4},"end":{"line":262,"column":4}}]},"25":{"line":263,"type":"if","locations":[{"start":{"line":263,"column":6},"end":{"line":263,"column":6}},{"start":{"line":263,"column":6},"end":{"line":263,"column":6}}]},"26":{"line":264,"type":"if","locations":[{"start":{"line":264,"column":11},"end":{"line":264,"column":11}},{"start":{"line":264,"column":11},"end":{"line":264,"column":11}}]},"27":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":6},"end":{"line":265,"column":6}},{"start":{"line":265,"column":6},"end":{"line":265,"column":6}}]},"28":{"line":273,"type":"if","locations":[{"start":{"line":273,"column":6},"end":{"line":273,"column":6}},{"start":{"line":273,"column":6},"end":{"line":273,"column":6}}]},"29":{"line":275,"type":"if","locations":[{"start":{"line":275,"column":6},"end":{"line":275,"column":6}},{"start":{"line":275,"column":6},"end":{"line":275,"column":6}}]},"30":{"line":306,"type":"if","locations":[{"start":{"line":306,"column":4},"end":{"line":306,"column":4}},{"start":{"line":306,"column":4},"end":{"line":306,"column":4}}]},"31":{"line":308,"type":"if","locations":[{"start":{"line":308,"column":4},"end":{"line":308,"column":4}},{"start":{"line":308,"column":4},"end":{"line":308,"column":4}}]},"32":{"line":328,"type":"if","locations":[{"start":{"line":328,"column":4},"end":{"line":328,"column":4}},{"start":{"line":328,"column":4},"end":{"line":328,"column":4}}]},"33":{"line":329,"type":"if","locations":[{"start":{"line":329,"column":4},"end":{"line":329,"column":4}},{"start":{"line":329,"column":4},"end":{"line":329,"column":4}}]},"34":{"line":349,"type":"if","locations":[{"start":{"line":349,"column":4},"end":{"line":349,"column":4}},{"start":{"line":349,"column":4},"end":{"line":349,"column":4}}]},"35":{"line":355,"type":"if","locations":[{"start":{"line":355,"column":4},"end":{"line":355,"column":4}},{"start":{"line":355,"column":4},"end":{"line":355,"column":4}}]},"36":{"line":366,"type":"if","locations":[{"start":{"line":366,"column":4},"end":{"line":366,"column":4}},{"start":{"line":366,"column":4},"end":{"line":366,"column":4}}]},"37":{"line":373,"type":"if","locations":[{"start":{"line":373,"column":4},"end":{"line":373,"column":4}},{"start":{"line":373,"column":4},"end":{"line":373,"column":4}}]},"38":{"line":402,"type":"if","locations":[{"start":{"line":402,"column":4},"end":{"line":402,"column":4}},{"start":{"line":402,"column":4},"end":{"line":402,"column":4}}]},"39":{"line":408,"type":"if","locations":[{"start":{"line":408,"column":4},"end":{"line":408,"column":4}},{"start":{"line":408,"column":4},"end":{"line":408,"column":4}}]},"40":{"line":417,"type":"if","locations":[{"start":{"line":417,"column":4},"end":{"line":417,"column":4}},{"start":{"line":417,"column":4},"end":{"line":417,"column":4}}]},"41":{"line":422,"type":"if","locations":[{"start":{"line":422,"column":6},"end":{"line":422,"column":6}},{"start":{"line":422,"column":6},"end":{"line":422,"column":6}}]},"42":{"line":430,"type":"if","locations":[{"start":{"line":430,"column":4},"end":{"line":430,"column":4}},{"start":{"line":430,"column":4},"end":{"line":430,"column":4}}]},"43":{"line":453,"type":"if","locations":[{"start":{"line":453,"column":4},"end":{"line":453,"column":4}},{"start":{"line":453,"column":4},"end":{"line":453,"column":4}}]},"44":{"line":461,"type":"if","locations":[{"start":{"line":461,"column":4},"end":{"line":461,"column":4}},{"start":{"line":461,"column":4},"end":{"line":461,"column":4}}]},"45":{"line":464,"type":"if","locations":[{"start":{"line":464,"column":4},"end":{"line":464,"column":4}},{"start":{"line":464,"column":4},"end":{"line":464,"column":4}}]}}},"contracts/libraries/math/MathUtils.sol":{"l":{"26":347,"28":347,"30":347,"52":672,"54":672,"55":116,"58":556,"60":556,"62":556,"64":556,"65":556,"67":556,"68":556,"70":556},"path":"/src/contracts/libraries/math/MathUtils.sol","s":{"1":347,"2":347,"3":347,"4":672,"5":672,"6":116,"7":556,"8":556,"9":556,"10":556,"11":556,"12":556,"13":556,"14":556},"b":{"1":[116,556]},"f":{"1":347,"2":672},"fnMap":{"1":{"name":"calculateLinearInterest","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"calculateCompoundedInterest","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":78}},"2":{"start":{"line":28,"column":4},"end":{"line":28,"column":85}},"3":{"start":{"line":30,"column":4},"end":{"line":30,"column":55}},"4":{"start":{"line":52,"column":4},"end":{"line":52,"column":67}},"5":{"start":{"line":54,"column":4},"end":{"line":54,"column":1957}},"6":{"start":{"line":55,"column":6},"end":{"line":55,"column":29}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":33}},"8":{"start":{"line":60,"column":4},"end":{"line":60,"column":47}},"9":{"start":{"line":62,"column":4},"end":{"line":62,"column":51}},"10":{"start":{"line":64,"column":4},"end":{"line":64,"column":62}},"11":{"start":{"line":65,"column":4},"end":{"line":65,"column":63}},"12":{"start":{"line":67,"column":4},"end":{"line":67,"column":67}},"13":{"start":{"line":68,"column":4},"end":{"line":68,"column":85}},"14":{"start":{"line":70,"column":4},"end":{"line":70,"column":86}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":54,"column":4}},{"start":{"line":54,"column":4},"end":{"line":54,"column":4}}]}}},"contracts/libraries/math/PercentageMath.sol":{"l":{"25":343,"26":148,"29":195,"31":195,"33":195,"35":195,"37":195,"47":58,"48":58,"50":58,"52":58,"54":58,"56":58,"58":58},"path":"/src/contracts/libraries/math/PercentageMath.sol","s":{"1":343,"2":148,"3":195,"4":195,"5":195,"6":195,"7":195,"8":58,"9":58,"10":58,"11":58,"12":58,"13":58,"14":58},"b":{"1":[148,195],"2":[195,0],"3":[195,0],"4":[58,0],"5":[58,0],"6":[58,0]},"f":{"1":343,"2":58},"fnMap":{"1":{"name":"percentMul","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"percentDiv","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":59,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":891}},"2":{"start":{"line":26,"column":6},"end":{"line":26,"column":14}},"3":{"start":{"line":29,"column":4},"end":{"line":29,"column":39}},"4":{"start":{"line":31,"column":4},"end":{"line":31,"column":72}},"5":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"6":{"start":{"line":35,"column":4},"end":{"line":35,"column":60}},"7":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"8":{"start":{"line":47,"column":4},"end":{"line":47,"column":52}},"9":{"start":{"line":48,"column":4},"end":{"line":48,"column":43}},"10":{"start":{"line":50,"column":4},"end":{"line":50,"column":46}},"11":{"start":{"line":52,"column":4},"end":{"line":52,"column":79}},"12":{"start":{"line":54,"column":4},"end":{"line":54,"column":27}},"13":{"start":{"line":56,"column":4},"end":{"line":56,"column":62}},"14":{"start":{"line":58,"column":4},"end":{"line":58,"column":30}}},"branchMap":{"1":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":25,"column":4}},{"start":{"line":25,"column":4},"end":{"line":25,"column":4}}]},"2":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"3":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"4":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]},"5":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"6":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]}}},"contracts/libraries/math/SafeMath.sol":{"l":{"28":450,"29":450,"31":450,"44":124,"61":212,"62":211,"64":211,"80":0,"81":0,"84":0,"85":0,"87":0,"102":0,"122":0,"123":0,"126":0,"141":0,"160":0,"161":0},"path":"/src/contracts/libraries/math/SafeMath.sol","s":{"1":450,"2":450,"3":450,"4":124,"5":212,"6":211,"7":211,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0},"b":{"1":[450,0],"2":[211,1],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0]},"f":{"1":450,"2":124,"3":212,"4":0,"5":0,"6":0,"7":0,"8":0},"fnMap":{"1":{"name":"add","line":27,"loc":{"start":{"line":27,"column":2},"end":{"line":32,"column":2}}},"2":{"name":"sub","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"sub","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":65,"column":2}}},"4":{"name":"mul","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":88,"column":2}}},"5":{"name":"div","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":103,"column":2}}},"6":{"name":"div","line":116,"loc":{"start":{"line":116,"column":2},"end":{"line":127,"column":2}}},"7":{"name":"mod","line":140,"loc":{"start":{"line":140,"column":2},"end":{"line":142,"column":2}}},"8":{"name":"mod","line":155,"loc":{"start":{"line":155,"column":2},"end":{"line":162,"column":2}}}},"statementMap":{"1":{"start":{"line":28,"column":4},"end":{"line":28,"column":21}},"2":{"start":{"line":29,"column":4},"end":{"line":29,"column":49}},"3":{"start":{"line":31,"column":4},"end":{"line":31,"column":12}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":54}},"5":{"start":{"line":61,"column":4},"end":{"line":61,"column":32}},"6":{"start":{"line":62,"column":4},"end":{"line":62,"column":21}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":12}},"8":{"start":{"line":80,"column":4},"end":{"line":80,"column":2341}},"9":{"start":{"line":81,"column":6},"end":{"line":81,"column":14}},"10":{"start":{"line":84,"column":4},"end":{"line":84,"column":21}},"11":{"start":{"line":85,"column":4},"end":{"line":85,"column":59}},"12":{"start":{"line":87,"column":4},"end":{"line":87,"column":12}},"13":{"start":{"line":102,"column":4},"end":{"line":102,"column":50}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":31}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":21}},"16":{"start":{"line":126,"column":4},"end":{"line":126,"column":12}},"17":{"start":{"line":141,"column":4},"end":{"line":141,"column":48}},"18":{"start":{"line":160,"column":4},"end":{"line":160,"column":32}},"19":{"start":{"line":161,"column":4},"end":{"line":161,"column":16}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]},"2":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":61,"column":4}},{"start":{"line":61,"column":4},"end":{"line":61,"column":4}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":4},"end":{"line":80,"column":4}},{"start":{"line":80,"column":4},"end":{"line":80,"column":4}}]},"4":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"5":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]},"6":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":4},"end":{"line":160,"column":4}},{"start":{"line":160,"column":4},"end":{"line":160,"column":4}}]}}},"contracts/libraries/math/WadRayMath.sol":{"l":{"25":1056,"33":0,"40":0,"47":0,"57":0,"58":0,"61":0,"63":0,"65":0,"67":0,"69":0,"79":64,"81":64,"83":64,"85":64,"87":64,"89":64,"91":64,"101":4935,"102":1581,"105":3354,"107":3354,"109":3354,"111":3354,"113":3354,"123":1257,"125":1257,"127":1257,"129":1257,"131":1257,"133":1257,"135":1257,"144":0,"145":0,"146":0,"148":0,"157":1134,"158":1134,"159":1134},"path":"/src/contracts/libraries/math/WadRayMath.sol","s":{"1":1056,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":64,"13":64,"14":64,"15":64,"16":64,"17":64,"18":64,"19":4935,"20":1581,"21":3354,"22":3354,"23":3354,"24":3354,"25":3354,"26":1257,"27":1257,"28":1257,"29":1257,"30":1257,"31":1257,"32":1257,"33":0,"34":0,"35":0,"36":0,"37":1134,"38":1134,"39":1134},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[64,0],"5":[64,0],"6":[64,0],"7":[1581,3354],"8":[3354,0],"9":[3354,0],"10":[1257,0],"11":[1257,0],"12":[1257,0],"13":[0,0],"14":[1134,0]},"f":{"1":1056,"2":0,"3":0,"4":0,"5":0,"6":64,"7":4935,"8":1257,"9":0,"10":1134},"fnMap":{"1":{"name":"ray","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":26,"column":2}}},"2":{"name":"wad","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"halfRay","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}},"4":{"name":"halfWad","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"5":{"name":"wadMul","line":56,"loc":{"start":{"line":56,"column":2},"end":{"line":70,"column":2}}},"6":{"name":"wadDiv","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":92,"column":2}}},"7":{"name":"rayMul","line":100,"loc":{"start":{"line":100,"column":2},"end":{"line":114,"column":2}}},"8":{"name":"rayDiv","line":122,"loc":{"start":{"line":122,"column":2},"end":{"line":136,"column":2}}},"9":{"name":"rayToWad","line":143,"loc":{"start":{"line":143,"column":2},"end":{"line":149,"column":2}}},"10":{"name":"wadToRay","line":156,"loc":{"start":{"line":156,"column":2},"end":{"line":160,"column":2}}}},"statementMap":{"1":{"start":{"line":25,"column":4},"end":{"line":25,"column":14}},"2":{"start":{"line":33,"column":4},"end":{"line":33,"column":14}},"3":{"start":{"line":40,"column":4},"end":{"line":40,"column":18}},"4":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}},"5":{"start":{"line":57,"column":4},"end":{"line":57,"column":1244}},"6":{"start":{"line":58,"column":6},"end":{"line":58,"column":14}},"7":{"start":{"line":61,"column":4},"end":{"line":61,"column":26}},"8":{"start":{"line":63,"column":4},"end":{"line":63,"column":59}},"9":{"start":{"line":65,"column":4},"end":{"line":65,"column":20}},"10":{"start":{"line":67,"column":4},"end":{"line":67,"column":55}},"11":{"start":{"line":69,"column":4},"end":{"line":69,"column":23}},"12":{"start":{"line":79,"column":4},"end":{"line":79,"column":43}},"13":{"start":{"line":81,"column":4},"end":{"line":81,"column":25}},"14":{"start":{"line":83,"column":4},"end":{"line":83,"column":28}},"15":{"start":{"line":85,"column":4},"end":{"line":85,"column":61}},"16":{"start":{"line":87,"column":4},"end":{"line":87,"column":18}},"17":{"start":{"line":89,"column":4},"end":{"line":89,"column":53}},"18":{"start":{"line":91,"column":4},"end":{"line":91,"column":21}},"19":{"start":{"line":101,"column":4},"end":{"line":101,"column":2221}},"20":{"start":{"line":102,"column":6},"end":{"line":102,"column":14}},"21":{"start":{"line":105,"column":4},"end":{"line":105,"column":26}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":59}},"23":{"start":{"line":109,"column":4},"end":{"line":109,"column":20}},"24":{"start":{"line":111,"column":4},"end":{"line":111,"column":55}},"25":{"start":{"line":113,"column":4},"end":{"line":113,"column":23}},"26":{"start":{"line":123,"column":4},"end":{"line":123,"column":43}},"27":{"start":{"line":125,"column":4},"end":{"line":125,"column":25}},"28":{"start":{"line":127,"column":4},"end":{"line":127,"column":28}},"29":{"start":{"line":129,"column":4},"end":{"line":129,"column":61}},"30":{"start":{"line":131,"column":4},"end":{"line":131,"column":18}},"31":{"start":{"line":133,"column":4},"end":{"line":133,"column":53}},"32":{"start":{"line":135,"column":4},"end":{"line":135,"column":21}},"33":{"start":{"line":144,"column":4},"end":{"line":144,"column":41}},"34":{"start":{"line":145,"column":4},"end":{"line":145,"column":34}},"35":{"start":{"line":146,"column":4},"end":{"line":146,"column":57}},"36":{"start":{"line":148,"column":4},"end":{"line":148,"column":33}},"37":{"start":{"line":157,"column":4},"end":{"line":157,"column":38}},"38":{"start":{"line":158,"column":4},"end":{"line":158,"column":71}},"39":{"start":{"line":159,"column":4},"end":{"line":159,"column":17}}},"branchMap":{"1":{"line":57,"type":"if","locations":[{"start":{"line":57,"column":4},"end":{"line":57,"column":4}},{"start":{"line":57,"column":4},"end":{"line":57,"column":4}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":4},"end":{"line":63,"column":4}},{"start":{"line":63,"column":4},"end":{"line":63,"column":4}}]},"3":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":67,"column":4}},{"start":{"line":67,"column":4},"end":{"line":67,"column":4}}]},"4":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":4},"end":{"line":79,"column":4}},{"start":{"line":79,"column":4},"end":{"line":79,"column":4}}]},"5":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":4},"end":{"line":85,"column":4}},{"start":{"line":85,"column":4},"end":{"line":85,"column":4}}]},"6":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":4},"end":{"line":89,"column":4}},{"start":{"line":89,"column":4},"end":{"line":89,"column":4}}]},"7":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":4},"end":{"line":101,"column":4}},{"start":{"line":101,"column":4},"end":{"line":101,"column":4}}]},"8":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":4},"end":{"line":107,"column":4}},{"start":{"line":107,"column":4},"end":{"line":107,"column":4}}]},"9":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":4},"end":{"line":111,"column":4}},{"start":{"line":111,"column":4},"end":{"line":111,"column":4}}]},"10":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":4},"end":{"line":123,"column":4}},{"start":{"line":123,"column":4},"end":{"line":123,"column":4}}]},"11":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":4},"end":{"line":129,"column":4}},{"start":{"line":129,"column":4},"end":{"line":129,"column":4}}]},"12":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":4},"end":{"line":133,"column":4}},{"start":{"line":133,"column":4},"end":{"line":133,"column":4}}]},"13":{"line":146,"type":"if","locations":[{"start":{"line":146,"column":4},"end":{"line":146,"column":4}},{"start":{"line":146,"column":4},"end":{"line":146,"column":4}}]},"14":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":4},"end":{"line":158,"column":4}},{"start":{"line":158,"column":4},"end":{"line":158,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol":{"l":{"26":0,"27":0,"34":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/AdminUpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0},"b":{"1":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":21,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"_willFallback","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":79}},"2":{"start":{"line":27,"column":4},"end":{"line":27,"column":20}},"3":{"start":{"line":34,"column":4},"end":{"line":34,"column":47}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":4},"end":{"line":26,"column":4}},{"start":{"line":26,"column":4},"end":{"line":26,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol":{"l":{"35":3,"36":3,"38":0,"46":0,"53":0,"62":0,"63":0,"64":0,"73":0,"90":3,"91":3,"92":3,"99":9902,"101":9902,"111":53,"113":53,"122":9899,"123":9899},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseAdminUpgradeabilityProxy.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":3,"10":3,"11":3,"12":9902,"13":53,"14":9899,"15":9899},"b":{"1":[3,0],"2":[0,0],"3":[3,0],"4":[9899,0]},"f":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":3,"7":9902,"8":53,"9":9899},"fnMap":{"1":{"name":"ifAdmin","line":34,"loc":{"start":{"line":34,"column":2},"end":{"line":40,"column":2}}},"2":{"name":"admin","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":47,"column":2}}},"3":{"name":"implementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":54,"column":2}}},"4":{"name":"changeAdmin","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":65,"column":2}}},"5":{"name":"upgradeTo","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"upgradeToAndCall","line":88,"loc":{"start":{"line":85,"column":2},"end":{"line":93,"column":2}}},"7":{"name":"_admin","line":98,"loc":{"start":{"line":98,"column":2},"end":{"line":104,"column":2}}},"8":{"name":"_setAdmin","line":110,"loc":{"start":{"line":110,"column":2},"end":{"line":116,"column":2}}},"9":{"name":"_willFallback","line":121,"loc":{"start":{"line":121,"column":2},"end":{"line":124,"column":2}}}},"statementMap":{"1":{"start":{"line":35,"column":4},"end":{"line":35,"column":1284}},"2":{"start":{"line":38,"column":6},"end":{"line":38,"column":16}},"3":{"start":{"line":46,"column":4},"end":{"line":46,"column":19}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":28}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":92}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":41}},"7":{"start":{"line":64,"column":4},"end":{"line":64,"column":22}},"8":{"start":{"line":73,"column":4},"end":{"line":73,"column":32}},"9":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"10":{"start":{"line":91,"column":4},"end":{"line":91,"column":59}},"11":{"start":{"line":92,"column":4},"end":{"line":92,"column":19}},"12":{"start":{"line":99,"column":4},"end":{"line":99,"column":29}},"13":{"start":{"line":111,"column":4},"end":{"line":111,"column":29}},"14":{"start":{"line":122,"column":4},"end":{"line":122,"column":88}},"15":{"start":{"line":123,"column":4},"end":{"line":123,"column":24}}},"branchMap":{"1":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":4},"end":{"line":35,"column":4}},{"start":{"line":35,"column":4},"end":{"line":35,"column":4}}]},"2":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"3":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":4},"end":{"line":92,"column":4}},{"start":{"line":92,"column":4},"end":{"line":92,"column":4}}]},"4":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":4},"end":{"line":122,"column":4}},{"start":{"line":122,"column":4},"end":{"line":122,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol":{"l":{"32":10005,"34":10005,"44":3,"45":3,"53":56,"58":56,"61":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol","s":{"1":10005,"2":3,"3":3,"4":56,"5":56},"b":{"1":[56,0]},"f":{"1":10005,"2":3,"3":56},"fnMap":{"1":{"name":"_implementation","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":37,"column":2}}},"2":{"name":"_upgradeTo","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"_setImplementation","line":52,"loc":{"start":{"line":52,"column":2},"end":{"line":64,"column":2}}}},"statementMap":{"1":{"start":{"line":32,"column":4},"end":{"line":32,"column":38}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":40}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":36}},"4":{"start":{"line":53,"column":4},"end":{"line":53,"column":1706}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":38}}},"branchMap":{"1":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":4},"end":{"line":53,"column":4}},{"start":{"line":53,"column":4},"end":{"line":53,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/Initializable.sol":{"l":{"31":0,"36":0,"37":0,"38":0,"39":0,"42":0,"44":0,"45":0,"56":0,"58":0,"61":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Initializable.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0,"2":0},"fnMap":{"1":{"name":"initializer","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"isConstructor","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":62,"column":2}}}},"statementMap":{"1":{"start":{"line":31,"column":4},"end":{"line":31,"column":1056}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":39}},"3":{"start":{"line":37,"column":4},"end":{"line":37,"column":1228}},"4":{"start":{"line":38,"column":6},"end":{"line":38,"column":24}},"5":{"start":{"line":39,"column":6},"end":{"line":39,"column":23}},"6":{"start":{"line":44,"column":4},"end":{"line":44,"column":1322}},"7":{"start":{"line":45,"column":6},"end":{"line":45,"column":25}},"8":{"start":{"line":56,"column":4},"end":{"line":56,"column":14}},"9":{"start":{"line":61,"column":4},"end":{"line":61,"column":18}}},"branchMap":{"1":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":4},"end":{"line":31,"column":4}},{"start":{"line":31,"column":4},"end":{"line":31,"column":4}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":4},"end":{"line":37,"column":4}},{"start":{"line":37,"column":4},"end":{"line":37,"column":4}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol":{"l":{"30":53,"31":53,"32":53,"33":53,"40":9899},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":9899},"b":{"1":[53,0],"2":[53,0]},"f":{"1":53,"2":9899},"fnMap":{"1":{"name":"initialize","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":34,"column":2}}},"2":{"name":"_willFallback","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":41,"column":2}}}},"statementMap":{"1":{"start":{"line":30,"column":4},"end":{"line":30,"column":43}},"2":{"start":{"line":31,"column":4},"end":{"line":31,"column":59}},"3":{"start":{"line":32,"column":4},"end":{"line":32,"column":79}},"4":{"start":{"line":33,"column":4},"end":{"line":33,"column":19}},"5":{"start":{"line":40,"column":4},"end":{"line":40,"column":47}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":4},"end":{"line":30,"column":4}},{"start":{"line":30,"column":4},"end":{"line":30,"column":4}}]},"2":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":4},"end":{"line":32,"column":4}},{"start":{"line":32,"column":4},"end":{"line":32,"column":4}}]}}},"contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol":{"l":{"21":53,"22":53,"23":53,"24":53,"25":53,"26":53},"path":"/src/contracts/libraries/openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol","s":{"1":53,"2":53,"3":53,"4":53,"5":53,"6":53},"b":{"1":[53,0],"2":[53,0],"3":[53,0],"4":[53,0]},"f":{"1":53},"fnMap":{"1":{"name":"initialize","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":28,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":43}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":97}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":29}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":1119}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":51}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":22,"type":"if","locations":[{"start":{"line":22,"column":4},"end":{"line":22,"column":4}},{"start":{"line":22,"column":4},"end":{"line":22,"column":4}}]},"3":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":4},"end":{"line":24,"column":4}},{"start":{"line":24,"column":4},"end":{"line":24,"column":4}}]},"4":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":6},"end":{"line":26,"column":6}},{"start":{"line":26,"column":6},"end":{"line":26,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/Proxy.sol":{"l":{"17":9899,"33":9899,"69":9899,"70":9899},"path":"/src/contracts/libraries/openzeppelin-upgradeability/Proxy.sol","s":{"1":9899,"2":9899,"3":9899},"b":{},"f":{"1":9899,"2":9899,"3":9899,"4":9899},"fnMap":{"1":{"name":null,"line":16,"loc":{"start":{"line":16,"column":2},"end":{"line":18,"column":2}}},"2":{"name":"_delegate","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":55,"column":2}}},"3":{"name":"_willFallback","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":62,"column":45}}},"4":{"name":"_fallback","line":68,"loc":{"start":{"line":68,"column":2},"end":{"line":71,"column":2}}}},"statementMap":{"1":{"start":{"line":17,"column":4},"end":{"line":17,"column":14}},"2":{"start":{"line":69,"column":4},"end":{"line":69,"column":18}},"3":{"start":{"line":70,"column":4},"end":{"line":70,"column":31}}},"branchMap":{}},"contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol":{"l":{"21":0,"22":0,"23":0,"24":0,"25":0},"path":"/src/contracts/libraries/openzeppelin-upgradeability/UpgradeabilityProxy.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":2},"end":{"line":27,"column":2}}}},"statementMap":{"1":{"start":{"line":21,"column":4},"end":{"line":21,"column":97}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":29}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":1038}},"4":{"start":{"line":24,"column":6},"end":{"line":24,"column":51}},"5":{"start":{"line":25,"column":6},"end":{"line":25,"column":21}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":4}},{"start":{"line":21,"column":4},"end":{"line":21,"column":4}}]},"2":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":4},"end":{"line":23,"column":4}},{"start":{"line":23,"column":4},"end":{"line":23,"column":4}}]},"3":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":6},"end":{"line":25,"column":6}},{"start":{"line":25,"column":6},"end":{"line":25,"column":6}}]}}},"contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol":{"l":{"33":56,"34":56,"39":56,"40":56,"41":56,"42":56,"45":56,"47":56,"48":56,"63":56,"65":56,"68":56},"path":"/src/contracts/libraries/openzeppelin-upgradeability/VersionedInitializable.sol","s":{"1":56,"2":56,"3":56,"4":56,"5":56,"6":56,"7":56,"8":56,"9":56,"10":56},"b":{"1":[56,0],"2":[56,0],"3":[56,0]},"f":{"1":56,"2":56},"fnMap":{"1":{"name":"initializer","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":50,"column":2}}},"2":{"name":"isConstructor","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":69,"column":2}}}},"statementMap":{"1":{"start":{"line":33,"column":4},"end":{"line":33,"column":36}},"2":{"start":{"line":34,"column":4},"end":{"line":34,"column":1202}},"3":{"start":{"line":39,"column":4},"end":{"line":39,"column":39}},"4":{"start":{"line":40,"column":4},"end":{"line":40,"column":1396}},"5":{"start":{"line":41,"column":6},"end":{"line":41,"column":24}},"6":{"start":{"line":42,"column":6},"end":{"line":42,"column":39}},"7":{"start":{"line":47,"column":4},"end":{"line":47,"column":1506}},"8":{"start":{"line":48,"column":6},"end":{"line":48,"column":25}},"9":{"start":{"line":63,"column":4},"end":{"line":63,"column":14}},"10":{"start":{"line":68,"column":4},"end":{"line":68,"column":18}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":4},"end":{"line":40,"column":4}},{"start":{"line":40,"column":4},"end":{"line":40,"column":4}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":47,"column":4}},{"start":{"line":47,"column":4},"end":{"line":47,"column":4}}]}}},"contracts/misc/AaveProtocolTestHelpers.sol":{"l":{"18":3,"22":1,"23":1,"24":1,"25":1,"26":17,"33":1,"37":2,"38":2,"39":2,"40":2,"41":34,"42":34,"47":2},"path":"/src/contracts/misc/AaveProtocolTestHelpers.sol","s":{"1":3,"2":1,"3":1,"4":1,"5":1,"6":17,"7":1,"8":2,"9":2,"10":2,"11":2,"12":34,"13":34,"14":2},"b":{},"f":{"1":3,"2":1,"3":2},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":2}}},"2":{"name":"getAllReservesTokens","line":21,"loc":{"start":{"line":21,"column":2},"end":{"line":34,"column":2}}},"3":{"name":"getAllATokens","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":48,"column":2}}}},"statementMap":{"1":{"start":{"line":18,"column":4},"end":{"line":18,"column":41}},"2":{"start":{"line":22,"column":4},"end":{"line":22,"column":73}},"3":{"start":{"line":23,"column":4},"end":{"line":23,"column":50}},"4":{"start":{"line":24,"column":4},"end":{"line":24,"column":72}},"5":{"start":{"line":25,"column":4},"end":{"line":25,"column":904}},"6":{"start":{"line":26,"column":6},"end":{"line":26,"column":961}},"7":{"start":{"line":33,"column":4},"end":{"line":33,"column":25}},"8":{"start":{"line":37,"column":4},"end":{"line":37,"column":73}},"9":{"start":{"line":38,"column":4},"end":{"line":38,"column":50}},"10":{"start":{"line":39,"column":4},"end":{"line":39,"column":65}},"11":{"start":{"line":40,"column":4},"end":{"line":40,"column":1486}},"12":{"start":{"line":41,"column":6},"end":{"line":41,"column":79}},"13":{"start":{"line":42,"column":6},"end":{"line":42,"column":1624}},"14":{"start":{"line":47,"column":4},"end":{"line":47,"column":18}}},"branchMap":{}},"contracts/misc/Address.sol":{"l":{"29":99,"30":99,"32":99,"35":99,"55":0,"58":0,"59":0},"path":"/src/contracts/misc/Address.sol","s":{"1":99,"2":99,"3":99,"4":0,"5":0,"6":0},"b":{"1":[0,0],"2":[0,0]},"f":{"1":99,"2":0},"fnMap":{"1":{"name":"isContract","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":36,"column":2}}},"2":{"name":"sendValue","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":60,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":20}},"2":{"start":{"line":30,"column":4},"end":{"line":30,"column":92}},"3":{"start":{"line":35,"column":4},"end":{"line":35,"column":55}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":76}},"5":{"start":{"line":58,"column":4},"end":{"line":58,"column":56}},"6":{"start":{"line":59,"column":4},"end":{"line":59,"column":81}}},"branchMap":{"1":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":4},"end":{"line":55,"column":4}},{"start":{"line":55,"column":4},"end":{"line":55,"column":4}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":4},"end":{"line":59,"column":4}},{"start":{"line":59,"column":4},"end":{"line":59,"column":4}}]}}},"contracts/misc/ChainlinkProxyPriceProvider.sol":{"l":{"37":3,"38":3,"48":0,"55":0,"62":3,"63":3,"64":72,"65":72,"72":3,"73":3,"79":0,"81":0,"82":0,"84":0,"85":0,"86":0,"88":0,"96":0,"97":0,"98":0,"100":0,"107":0,"113":0},"path":"/src/contracts/misc/ChainlinkProxyPriceProvider.sol","s":{"1":3,"2":3,"3":0,"4":0,"5":3,"6":3,"7":72,"8":72,"9":3,"10":3,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0},"b":{"1":[3,0],"2":[0,0],"3":[0,0]},"f":{"1":3,"2":0,"3":0,"4":3,"5":3,"6":0,"7":0,"8":0,"9":0},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":39,"column":2}}},"2":{"name":"setAssetSources","line":46,"loc":{"start":{"line":44,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"setFallbackOracle","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"4":{"name":"_setAssetsSources","line":61,"loc":{"start":{"line":61,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"_setFallbackOracle","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":74,"column":2}}},"6":{"name":"getAssetPrice","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"getAssetsPrices","line":95,"loc":{"start":{"line":95,"column":2},"end":{"line":101,"column":2}}},"8":{"name":"getSourceOfAsset","line":106,"loc":{"start":{"line":106,"column":2},"end":{"line":108,"column":2}}},"9":{"name":"getFallbackOracle","line":112,"loc":{"start":{"line":112,"column":2},"end":{"line":114,"column":2}}}},"statementMap":{"1":{"start":{"line":37,"column":4},"end":{"line":37,"column":37}},"2":{"start":{"line":38,"column":4},"end":{"line":38,"column":37}},"3":{"start":{"line":48,"column":4},"end":{"line":48,"column":37}},"4":{"start":{"line":55,"column":4},"end":{"line":55,"column":37}},"5":{"start":{"line":62,"column":4},"end":{"line":62,"column":73}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":2670}},"7":{"start":{"line":64,"column":6},"end":{"line":64,"column":64}},"8":{"start":{"line":65,"column":6},"end":{"line":65,"column":52}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":55}},"10":{"start":{"line":73,"column":4},"end":{"line":73,"column":46}},"11":{"start":{"line":79,"column":4},"end":{"line":79,"column":54}},"12":{"start":{"line":81,"column":4},"end":{"line":81,"column":3446}},"13":{"start":{"line":82,"column":6},"end":{"line":82,"column":49}},"14":{"start":{"line":84,"column":6},"end":{"line":84,"column":64}},"15":{"start":{"line":85,"column":6},"end":{"line":85,"column":3621}},"16":{"start":{"line":86,"column":8},"end":{"line":86,"column":29}},"17":{"start":{"line":88,"column":8},"end":{"line":88,"column":51}},"18":{"start":{"line":96,"column":4},"end":{"line":96,"column":58}},"19":{"start":{"line":97,"column":4},"end":{"line":97,"column":4032}},"20":{"start":{"line":98,"column":6},"end":{"line":98,"column":41}},"21":{"start":{"line":100,"column":4},"end":{"line":100,"column":17}},"22":{"start":{"line":107,"column":4},"end":{"line":107,"column":40}},"23":{"start":{"line":113,"column":4},"end":{"line":113,"column":35}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":4},"end":{"line":62,"column":4}},{"start":{"line":62,"column":4},"end":{"line":62,"column":4}}]},"2":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":81,"column":4}},{"start":{"line":81,"column":4},"end":{"line":81,"column":4}}]},"3":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":6},"end":{"line":85,"column":6}},{"start":{"line":85,"column":6},"end":{"line":85,"column":6}}]}}},"contracts/misc/Context.sol":{"l":{"16":4,"20":0,"21":0},"path":"/src/contracts/misc/Context.sol","s":{"1":4,"2":0},"b":{},"f":{"1":4,"2":0},"fnMap":{"1":{"name":"_msgSender","line":15,"loc":{"start":{"line":15,"column":2},"end":{"line":17,"column":2}}},"2":{"name":"_msgData","line":19,"loc":{"start":{"line":19,"column":2},"end":{"line":22,"column":2}}}},"statementMap":{"1":{"start":{"line":16,"column":4},"end":{"line":16,"column":21}},"2":{"start":{"line":21,"column":4},"end":{"line":21,"column":19}}},"branchMap":{}},"contracts/misc/IERC20DetailedBytes.sol":{"l":{},"path":"/src/contracts/misc/IERC20DetailedBytes.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/misc/SafeERC20.sol":{"l":{"27":99,"36":0,"44":0,"48":0,"52":99,"55":99,"56":99,"58":97,"61":97},"path":"/src/contracts/misc/SafeERC20.sol","s":{"1":99,"2":0,"3":0,"4":0,"5":99,"6":99,"7":99,"8":97,"9":97},"b":{"1":[0,0],"2":[99,0],"3":[97,2],"4":[97,0],"5":[97,0]},"f":{"1":99,"2":0,"3":0,"4":99},"fnMap":{"1":{"name":"safeTransfer","line":22,"loc":{"start":{"line":22,"column":2},"end":{"line":28,"column":2}}},"2":{"name":"safeTransferFrom","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":37,"column":2}}},"3":{"name":"safeApprove","line":39,"loc":{"start":{"line":39,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"callOptionalReturn","line":51,"loc":{"start":{"line":51,"column":2},"end":{"line":63,"column":2}}}},"statementMap":{"1":{"start":{"line":27,"column":4},"end":{"line":27,"column":88}},"2":{"start":{"line":36,"column":4},"end":{"line":36,"column":98}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1254}},"4":{"start":{"line":48,"column":4},"end":{"line":48,"column":92}},"5":{"start":{"line":52,"column":4},"end":{"line":52,"column":74}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":71}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":55}},"8":{"start":{"line":58,"column":4},"end":{"line":58,"column":1845}},"9":{"start":{"line":61,"column":6},"end":{"line":61,"column":90}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":4},"end":{"line":52,"column":4}},{"start":{"line":52,"column":4},"end":{"line":52,"column":4}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]},"4":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":4},"end":{"line":58,"column":4}},{"start":{"line":58,"column":4},"end":{"line":58,"column":4}}]},"5":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":6},"end":{"line":61,"column":6}},{"start":{"line":61,"column":6},"end":{"line":61,"column":6}}]}}},"contracts/misc/WalletBalanceProvider.sol":{"l":{"26":3,"34":0,"45":0,"46":0,"48":0,"63":0,"65":0,"66":0,"67":0,"68":0,"69":0,"71":0,"76":0,"87":0,"89":0,"91":0,"93":0,"94":0,"96":0,"97":0,"98":0,"100":0,"103":0},"path":"/src/contracts/misc/WalletBalanceProvider.sol","s":{"1":3,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0]},"f":{"1":3,"2":0,"3":0,"4":0},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":2},"end":{"line":27,"column":2}}},"2":{"name":"balanceOf","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":50,"column":2}}},"3":{"name":"batchBalanceOf","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":77,"column":2}}},"4":{"name":"getUserWalletBalances","line":82,"loc":{"start":{"line":82,"column":2},"end":{"line":104,"column":2}}}},"statementMap":{"1":{"start":{"line":26,"column":4},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":4},"end":{"line":45,"column":1672}},"3":{"start":{"line":46,"column":6},"end":{"line":46,"column":42}},"4":{"start":{"line":48,"column":6},"end":{"line":48,"column":14}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":75}},"6":{"start":{"line":65,"column":4},"end":{"line":65,"column":2271}},"7":{"start":{"line":66,"column":6},"end":{"line":66,"column":2324}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":43}},"9":{"start":{"line":68,"column":8},"end":{"line":68,"column":2425}},"10":{"start":{"line":69,"column":10},"end":{"line":69,"column":32}},"11":{"start":{"line":71,"column":10},"end":{"line":71,"column":63}},"12":{"start":{"line":76,"column":4},"end":{"line":76,"column":19}},"13":{"start":{"line":87,"column":4},"end":{"line":87,"column":64}},"14":{"start":{"line":89,"column":4},"end":{"line":89,"column":50}},"15":{"start":{"line":91,"column":4},"end":{"line":91,"column":62}},"16":{"start":{"line":93,"column":4},"end":{"line":93,"column":3026}},"17":{"start":{"line":94,"column":6},"end":{"line":94,"column":89}},"18":{"start":{"line":96,"column":6},"end":{"line":96,"column":3174}},"19":{"start":{"line":97,"column":8},"end":{"line":97,"column":22}},"20":{"start":{"line":100,"column":6},"end":{"line":100,"column":47}},"21":{"start":{"line":103,"column":4},"end":{"line":103,"column":31}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":4},"end":{"line":34,"column":4}},{"start":{"line":34,"column":4},"end":{"line":34,"column":4}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"3":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":68,"column":8}},{"start":{"line":68,"column":8},"end":{"line":68,"column":8}}]},"4":{"line":96,"type":"if","locations":[{"start":{"line":96,"column":6},"end":{"line":96,"column":6}},{"start":{"line":96,"column":6},"end":{"line":96,"column":6}}]}}},"contracts/tokenization/AToken.sol":{"l":{"45":211,"46":207,"57":54,"58":54,"59":54,"63":17,"71":17,"74":17,"78":17,"88":17,"89":17,"90":17,"104":42,"107":41,"110":41,"111":41,"126":105,"129":105,"130":105,"134":0,"137":0,"138":0,"155":2,"170":641,"180":333,"195":0,"205":3,"207":3,"208":0,"211":3,"219":0,"229":4,"245":58,"246":56,"268":6,"270":5,"271":3,"272":3,"279":3,"280":0,"281":0,"298":6,"299":4,"302":4,"304":4,"306":4,"320":4,"327":0},"path":"/src/contracts/tokenization/AToken.sol","s":{"1":211,"2":54,"3":54,"4":54,"5":17,"6":17,"7":17,"8":17,"9":17,"10":17,"11":42,"12":41,"13":41,"14":41,"15":105,"16":105,"17":105,"18":0,"19":0,"20":0,"21":2,"22":641,"23":333,"24":0,"25":3,"26":3,"27":0,"28":3,"29":0,"30":4,"31":58,"32":56,"33":6,"34":5,"35":3,"36":3,"37":3,"38":0,"39":0,"40":6,"41":4,"42":4,"43":4,"44":4,"45":4},"b":{"1":[207,4],"2":[0,3],"3":[5,1],"4":[3,2],"5":[0,3],"6":[4,2],"7":[2,2]},"f":{"1":211,"2":54,"3":17,"4":17,"5":42,"6":105,"7":0,"8":2,"9":641,"10":333,"11":0,"12":3,"13":0,"14":4,"15":58,"16":6,"17":6,"18":4},"fnMap":{"1":{"name":"onlyLendingPool","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":47,"column":2}}},"2":{"name":"constructor","line":56,"loc":{"start":{"line":49,"column":2},"end":{"line":60,"column":2}}},"3":{"name":"getRevision","line":62,"loc":{"start":{"line":62,"column":2},"end":{"line":64,"column":2}}},"4":{"name":"initialize","line":70,"loc":{"start":{"line":66,"column":2},"end":{"line":91,"column":2}}},"5":{"name":"burn","line":103,"loc":{"start":{"line":98,"column":2},"end":{"line":112,"column":2}}},"6":{"name":"mint","line":124,"loc":{"start":{"line":120,"column":2},"end":{"line":131,"column":2}}},"7":{"name":"mintToTreasury","line":133,"loc":{"start":{"line":133,"column":2},"end":{"line":139,"column":2}}},"8":{"name":"transferOnLiquidation","line":152,"loc":{"start":{"line":148,"column":2},"end":{"line":156,"column":2}}},"9":{"name":"balanceOf","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":171,"column":2}}},"10":{"name":"scaledBalanceOf","line":179,"loc":{"start":{"line":179,"column":2},"end":{"line":181,"column":2}}},"11":{"name":"getScaledUserBalanceAndSupply","line":189,"loc":{"start":{"line":189,"column":2},"end":{"line":196,"column":2}}},"12":{"name":"totalSupply","line":204,"loc":{"start":{"line":204,"column":2},"end":{"line":212,"column":2}}},"13":{"name":"scaledTotalSupply","line":218,"loc":{"start":{"line":218,"column":2},"end":{"line":220,"column":2}}},"14":{"name":"isTransferAllowed","line":228,"loc":{"start":{"line":228,"column":2},"end":{"line":230,"column":2}}},"15":{"name":"transferUnderlyingTo","line":242,"loc":{"start":{"line":239,"column":2},"end":{"line":247,"column":2}}},"16":{"name":"permit","line":259,"loc":{"start":{"line":259,"column":2},"end":{"line":282,"column":2}}},"17":{"name":"_transfer","line":292,"loc":{"start":{"line":292,"column":2},"end":{"line":307,"column":2}}},"18":{"name":"_transfer","line":315,"loc":{"start":{"line":315,"column":2},"end":{"line":321,"column":2}}}},"statementMap":{"1":{"start":{"line":45,"column":4},"end":{"line":45,"column":75}},"2":{"start":{"line":57,"column":4},"end":{"line":57,"column":14}},"3":{"start":{"line":58,"column":4},"end":{"line":58,"column":52}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":52}},"5":{"start":{"line":63,"column":4},"end":{"line":63,"column":26}},"6":{"start":{"line":71,"column":4},"end":{"line":71,"column":19}},"7":{"start":{"line":78,"column":4},"end":{"line":78,"column":2480}},"8":{"start":{"line":88,"column":4},"end":{"line":88,"column":22}},"9":{"start":{"line":89,"column":4},"end":{"line":89,"column":26}},"10":{"start":{"line":90,"column":4},"end":{"line":90,"column":40}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":36}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":78}},"13":{"start":{"line":110,"column":4},"end":{"line":110,"column":43}},"14":{"start":{"line":111,"column":4},"end":{"line":111,"column":62}},"15":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}},"16":{"start":{"line":129,"column":4},"end":{"line":129,"column":43}},"17":{"start":{"line":130,"column":4},"end":{"line":130,"column":34}},"18":{"start":{"line":134,"column":4},"end":{"line":134,"column":53}},"19":{"start":{"line":137,"column":4},"end":{"line":137,"column":63}},"20":{"start":{"line":138,"column":4},"end":{"line":138,"column":54}},"21":{"start":{"line":155,"column":4},"end":{"line":155,"column":36}},"22":{"start":{"line":170,"column":4},"end":{"line":170,"column":98}},"23":{"start":{"line":180,"column":4},"end":{"line":180,"column":32}},"24":{"start":{"line":195,"column":4},"end":{"line":195,"column":55}},"25":{"start":{"line":205,"column":4},"end":{"line":205,"column":53}},"26":{"start":{"line":207,"column":4},"end":{"line":207,"column":6560}},"27":{"start":{"line":208,"column":6},"end":{"line":208,"column":14}},"28":{"start":{"line":211,"column":4},"end":{"line":211,"column":96}},"29":{"start":{"line":219,"column":4},"end":{"line":219,"column":30}},"30":{"start":{"line":229,"column":4},"end":{"line":229,"column":78}},"31":{"start":{"line":245,"column":4},"end":{"line":245,"column":64}},"32":{"start":{"line":246,"column":4},"end":{"line":246,"column":17}},"33":{"start":{"line":268,"column":4},"end":{"line":268,"column":48}},"34":{"start":{"line":270,"column":4},"end":{"line":270,"column":61}},"35":{"start":{"line":271,"column":4},"end":{"line":271,"column":46}},"36":{"start":{"line":272,"column":4},"end":{"line":272,"column":8691}},"37":{"start":{"line":279,"column":4},"end":{"line":279,"column":68}},"38":{"start":{"line":280,"column":4},"end":{"line":280,"column":44}},"39":{"start":{"line":281,"column":4},"end":{"line":281,"column":34}},"40":{"start":{"line":298,"column":4},"end":{"line":298,"column":9504}},"41":{"start":{"line":299,"column":6},"end":{"line":299,"column":74}},"42":{"start":{"line":302,"column":4},"end":{"line":302,"column":77}},"43":{"start":{"line":304,"column":4},"end":{"line":304,"column":50}},"44":{"start":{"line":306,"column":4},"end":{"line":306,"column":49}},"45":{"start":{"line":320,"column":4},"end":{"line":320,"column":36}}},"branchMap":{"1":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":4},"end":{"line":45,"column":4}},{"start":{"line":45,"column":4},"end":{"line":45,"column":4}}]},"2":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":4},"end":{"line":207,"column":4}},{"start":{"line":207,"column":4},"end":{"line":207,"column":4}}]},"3":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":4},"end":{"line":268,"column":4}},{"start":{"line":268,"column":4},"end":{"line":268,"column":4}}]},"4":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":4},"end":{"line":270,"column":4}},{"start":{"line":270,"column":4},"end":{"line":270,"column":4}}]},"5":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":4},"end":{"line":279,"column":4}},{"start":{"line":279,"column":4},"end":{"line":279,"column":4}}]},"6":{"line":298,"type":"if","locations":[{"start":{"line":298,"column":4},"end":{"line":298,"column":4}},{"start":{"line":298,"column":4},"end":{"line":298,"column":4}}]},"7":{"line":299,"type":"if","locations":[{"start":{"line":299,"column":6},"end":{"line":299,"column":6}},{"start":{"line":299,"column":6},"end":{"line":299,"column":6}}]}}},"contracts/tokenization/base/DebtTokenBase.sol":{"l":{"29":99,"30":95,"44":108,"45":108,"59":36,"60":36,"61":36,"65":0,"73":0,"74":0,"75":0,"85":0,"86":0,"87":0,"91":0,"92":0,"93":0,"101":0,"102":0,"103":0,"104":0,"113":0,"114":0,"115":0,"124":0,"125":0,"126":0},"path":"/src/contracts/tokenization/base/DebtTokenBase.sol","s":{"1":99,"2":108,"3":108,"4":36,"5":36,"6":36,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0},"b":{"1":[95,4]},"f":{"1":99,"2":108,"3":36,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},"fnMap":{"1":{"name":"onlyLendingPool","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":31,"column":2}}},"2":{"name":"constructor","line":43,"loc":{"start":{"line":37,"column":2},"end":{"line":46,"column":2}}},"3":{"name":"initialize","line":58,"loc":{"start":{"line":54,"column":2},"end":{"line":62,"column":2}}},"4":{"name":"underlyingAssetAddress","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"5":{"name":"transfer","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":76,"column":2}}},"6":{"name":"allowance","line":78,"loc":{"start":{"line":78,"column":2},"end":{"line":88,"column":2}}},"7":{"name":"approve","line":90,"loc":{"start":{"line":90,"column":2},"end":{"line":94,"column":2}}},"8":{"name":"transferFrom","line":96,"loc":{"start":{"line":96,"column":2},"end":{"line":105,"column":2}}},"9":{"name":"increaseAllowance","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":116,"column":2}}},"10":{"name":"decreaseAllowance","line":118,"loc":{"start":{"line":118,"column":2},"end":{"line":127,"column":2}}}},"statementMap":{"1":{"start":{"line":29,"column":4},"end":{"line":29,"column":75}},"2":{"start":{"line":44,"column":4},"end":{"line":44,"column":28}},"3":{"start":{"line":45,"column":4},"end":{"line":45,"column":44}},"4":{"start":{"line":59,"column":4},"end":{"line":59,"column":17}},"5":{"start":{"line":60,"column":4},"end":{"line":60,"column":21}},"6":{"start":{"line":61,"column":4},"end":{"line":61,"column":25}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":27}},"8":{"start":{"line":75,"column":4},"end":{"line":75,"column":35}},"9":{"start":{"line":87,"column":4},"end":{"line":87,"column":36}},"10":{"start":{"line":93,"column":4},"end":{"line":93,"column":35}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":35}},"12":{"start":{"line":115,"column":4},"end":{"line":115,"column":36}},"13":{"start":{"line":126,"column":4},"end":{"line":126,"column":36}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":4},"end":{"line":29,"column":4}},{"start":{"line":29,"column":4},"end":{"line":29,"column":4}}]}}},"contracts/tokenization/IncentivizedERC20.sol":{"l":{"34":162,"35":162,"36":162,"37":162,"44":67,"51":88,"58":0,"65":2318,"72":2652,"82":4,"83":2,"84":2,"100":4,"109":0,"110":0,"125":0,"126":0,"131":0,"132":0,"142":0,"143":0,"157":0,"165":0,"173":4,"174":4,"176":4,"178":4,"179":4,"180":4,"181":4,"183":4,"184":0,"185":0,"186":0,"187":0,"193":131,"195":131,"197":131,"198":131,"200":131,"201":131,"203":131,"204":0,"209":67,"211":67,"213":67,"214":67,"216":67,"217":67,"219":66,"220":0,"229":0,"230":0,"232":0,"233":0,"237":54,"241":54,"245":54},"path":"/src/contracts/tokenization/IncentivizedERC20.sol","s":{"1":162,"2":162,"3":162,"4":162,"5":67,"6":88,"7":0,"8":2318,"9":2652,"10":4,"11":2,"12":2,"13":4,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":4,"25":4,"26":4,"27":4,"28":4,"29":4,"30":4,"31":4,"32":0,"33":0,"34":0,"35":0,"36":131,"37":131,"38":131,"39":131,"40":131,"41":131,"42":131,"43":0,"44":67,"45":67,"46":67,"47":67,"48":67,"49":67,"50":66,"51":0,"52":0,"53":0,"54":0,"55":0,"56":54,"57":54,"58":54},"b":{"1":[4,0],"2":[4,0],"3":[0,4],"4":[0,0],"5":[131,0],"6":[0,131],"7":[67,0],"8":[0,66],"9":[0,0],"10":[0,0]},"f":{"1":162,"2":67,"3":88,"4":0,"5":2318,"6":2652,"7":4,"8":4,"9":0,"10":0,"11":0,"12":0,"13":4,"14":131,"15":67,"16":0,"17":54,"18":54,"19":54,"20":202},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":38,"column":2}}},"2":{"name":"name","line":43,"loc":{"start":{"line":43,"column":2},"end":{"line":45,"column":2}}},"3":{"name":"symbol","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":2}}},"4":{"name":"decimals","line":57,"loc":{"start":{"line":57,"column":2},"end":{"line":59,"column":2}}},"5":{"name":"totalSupply","line":64,"loc":{"start":{"line":64,"column":2},"end":{"line":66,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":2}}},"7":{"name":"transfer","line":81,"loc":{"start":{"line":81,"column":2},"end":{"line":85,"column":2}}},"8":{"name":"allowance","line":93,"loc":{"start":{"line":93,"column":2},"end":{"line":101,"column":2}}},"9":{"name":"approve","line":108,"loc":{"start":{"line":108,"column":2},"end":{"line":111,"column":2}}},"10":{"name":"transferFrom","line":120,"loc":{"start":{"line":120,"column":2},"end":{"line":133,"column":2}}},"11":{"name":"increaseAllowance","line":141,"loc":{"start":{"line":141,"column":2},"end":{"line":144,"column":2}}},"12":{"name":"decreaseAllowance","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":166,"column":2}}},"13":{"name":"_transfer","line":168,"loc":{"start":{"line":168,"column":2},"end":{"line":190,"column":2}}},"14":{"name":"_mint","line":192,"loc":{"start":{"line":192,"column":2},"end":{"line":206,"column":2}}},"15":{"name":"_burn","line":208,"loc":{"start":{"line":208,"column":2},"end":{"line":222,"column":2}}},"16":{"name":"_approve","line":224,"loc":{"start":{"line":224,"column":2},"end":{"line":234,"column":2}}},"17":{"name":"_setName","line":236,"loc":{"start":{"line":236,"column":2},"end":{"line":238,"column":2}}},"18":{"name":"_setSymbol","line":240,"loc":{"start":{"line":240,"column":2},"end":{"line":242,"column":2}}},"19":{"name":"_setDecimals","line":244,"loc":{"start":{"line":244,"column":2},"end":{"line":246,"column":2}}},"20":{"name":"_beforeTokenTransfer","line":248,"loc":{"start":{"line":248,"column":2},"end":{"line":252,"column":22}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":15}},"2":{"start":{"line":35,"column":4},"end":{"line":35,"column":19}},"3":{"start":{"line":36,"column":4},"end":{"line":36,"column":23}},"4":{"start":{"line":37,"column":4},"end":{"line":37,"column":74}},"5":{"start":{"line":44,"column":4},"end":{"line":44,"column":16}},"6":{"start":{"line":51,"column":4},"end":{"line":51,"column":18}},"7":{"start":{"line":58,"column":4},"end":{"line":58,"column":20}},"8":{"start":{"line":65,"column":4},"end":{"line":65,"column":23}},"9":{"start":{"line":72,"column":4},"end":{"line":72,"column":29}},"10":{"start":{"line":82,"column":4},"end":{"line":82,"column":45}},"11":{"start":{"line":83,"column":4},"end":{"line":83,"column":48}},"12":{"start":{"line":84,"column":4},"end":{"line":84,"column":15}},"13":{"start":{"line":100,"column":4},"end":{"line":100,"column":38}},"14":{"start":{"line":109,"column":4},"end":{"line":109,"column":42}},"15":{"start":{"line":110,"column":4},"end":{"line":110,"column":15}},"16":{"start":{"line":125,"column":4},"end":{"line":125,"column":39}},"17":{"start":{"line":126,"column":4},"end":{"line":126,"column":3648}},"18":{"start":{"line":131,"column":4},"end":{"line":131,"column":44}},"19":{"start":{"line":132,"column":4},"end":{"line":132,"column":15}},"20":{"start":{"line":142,"column":4},"end":{"line":142,"column":86}},"21":{"start":{"line":143,"column":4},"end":{"line":143,"column":15}},"22":{"start":{"line":157,"column":4},"end":{"line":157,"column":4675}},"23":{"start":{"line":165,"column":4},"end":{"line":165,"column":15}},"24":{"start":{"line":173,"column":4},"end":{"line":173,"column":73}},"25":{"start":{"line":174,"column":4},"end":{"line":174,"column":74}},"26":{"start":{"line":176,"column":4},"end":{"line":176,"column":50}},"27":{"start":{"line":178,"column":4},"end":{"line":178,"column":48}},"28":{"start":{"line":179,"column":4},"end":{"line":179,"column":93}},"29":{"start":{"line":180,"column":4},"end":{"line":180,"column":54}},"30":{"start":{"line":181,"column":4},"end":{"line":181,"column":58}},"31":{"start":{"line":183,"column":4},"end":{"line":183,"column":5459}},"32":{"start":{"line":184,"column":6},"end":{"line":184,"column":40}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":78}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":5642}},"35":{"start":{"line":187,"column":8},"end":{"line":187,"column":86}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":68}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":52}},"38":{"start":{"line":197,"column":4},"end":{"line":197,"column":41}},"39":{"start":{"line":198,"column":4},"end":{"line":198,"column":44}},"40":{"start":{"line":200,"column":4},"end":{"line":200,"column":50}},"41":{"start":{"line":201,"column":4},"end":{"line":201,"column":53}},"42":{"start":{"line":203,"column":4},"end":{"line":203,"column":6176}},"43":{"start":{"line":204,"column":6},"end":{"line":204,"column":83}},"44":{"start":{"line":209,"column":4},"end":{"line":209,"column":70}},"45":{"start":{"line":211,"column":4},"end":{"line":211,"column":52}},"46":{"start":{"line":213,"column":4},"end":{"line":213,"column":41}},"47":{"start":{"line":214,"column":4},"end":{"line":214,"column":44}},"48":{"start":{"line":216,"column":4},"end":{"line":216,"column":50}},"49":{"start":{"line":217,"column":4},"end":{"line":217,"column":91}},"50":{"start":{"line":219,"column":4},"end":{"line":219,"column":6766}},"51":{"start":{"line":220,"column":6},"end":{"line":220,"column":83}},"52":{"start":{"line":229,"column":4},"end":{"line":229,"column":71}},"53":{"start":{"line":230,"column":4},"end":{"line":230,"column":71}},"54":{"start":{"line":232,"column":4},"end":{"line":232,"column":39}},"55":{"start":{"line":233,"column":4},"end":{"line":233,"column":41}},"56":{"start":{"line":237,"column":4},"end":{"line":237,"column":18}},"57":{"start":{"line":241,"column":4},"end":{"line":241,"column":22}},"58":{"start":{"line":245,"column":4},"end":{"line":245,"column":26}}},"branchMap":{"1":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"2":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":4},"end":{"line":174,"column":4}},{"start":{"line":174,"column":4},"end":{"line":174,"column":4}}]},"3":{"line":183,"type":"if","locations":[{"start":{"line":183,"column":4},"end":{"line":183,"column":4}},{"start":{"line":183,"column":4},"end":{"line":183,"column":4}}]},"4":{"line":186,"type":"if","locations":[{"start":{"line":186,"column":6},"end":{"line":186,"column":6}},{"start":{"line":186,"column":6},"end":{"line":186,"column":6}}]},"5":{"line":193,"type":"if","locations":[{"start":{"line":193,"column":4},"end":{"line":193,"column":4}},{"start":{"line":193,"column":4},"end":{"line":193,"column":4}}]},"6":{"line":203,"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":203,"column":4}},{"start":{"line":203,"column":4},"end":{"line":203,"column":4}}]},"7":{"line":209,"type":"if","locations":[{"start":{"line":209,"column":4},"end":{"line":209,"column":4}},{"start":{"line":209,"column":4},"end":{"line":209,"column":4}}]},"8":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":4},"end":{"line":219,"column":4}},{"start":{"line":219,"column":4},"end":{"line":219,"column":4}}]},"9":{"line":229,"type":"if","locations":[{"start":{"line":229,"column":4},"end":{"line":229,"column":4}},{"start":{"line":229,"column":4},"end":{"line":229,"column":4}}]},"10":{"line":230,"type":"if","locations":[{"start":{"line":230,"column":4},"end":{"line":230,"column":4}},{"start":{"line":230,"column":4},"end":{"line":230,"column":4}}]}}},"contracts/tokenization/interfaces/IAToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IAToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IScaledBalanceToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IScaledBalanceToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IStableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IStableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/interfaces/IVariableDebtToken.sol":{"l":{},"path":"/src/contracts/tokenization/interfaces/IVariableDebtToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/tokenization/StableDebtToken.sol":{"l":{"39":17,"47":363,"55":343,"64":343,"72":488,"73":488,"74":488,"75":366,"77":122,"81":122,"104":27,"107":27,"114":27,"115":27,"116":27,"118":27,"121":27,"126":27,"127":27,"131":27,"134":27,"139":27,"142":27,"144":27,"160":17,"167":17,"173":17,"174":8,"175":8,"177":9,"178":9,"184":17,"185":11,"186":11,"190":6,"193":17,"195":17,"196":0,"198":17,"202":17,"204":17,"222":44,"224":44,"225":22,"229":22,"231":22,"242":331,"243":331,"250":235,"251":235,"258":414,"265":331,"274":343,"284":980,"286":980,"287":781,"290":199,"295":199,"306":27,"307":27,"309":27,"310":0,"322":17,"323":17,"325":17,"326":0},"path":"/src/contracts/tokenization/StableDebtToken.sol","s":{"1":17,"2":363,"3":343,"4":343,"5":488,"6":488,"7":488,"8":366,"9":122,"10":122,"11":27,"12":27,"13":27,"14":27,"15":27,"16":27,"17":27,"18":27,"19":27,"20":27,"21":27,"22":27,"23":27,"24":27,"25":17,"26":17,"27":17,"28":8,"29":8,"30":9,"31":9,"32":17,"33":11,"34":11,"35":6,"36":17,"37":17,"38":0,"39":17,"40":17,"41":17,"42":44,"43":44,"44":22,"45":22,"46":22,"47":331,"48":331,"49":235,"50":235,"51":414,"52":331,"53":343,"54":980,"55":980,"56":781,"57":199,"58":199,"59":27,"60":27,"61":27,"62":0,"63":17,"64":17,"65":17,"66":0},"b":{"1":[366,122],"2":[27,0],"3":[8,9],"4":[11,6],"5":[0,17],"6":[22,22],"7":[781,199],"8":[0,27],"9":[0,17]},"f":{"1":54,"2":17,"3":363,"4":343,"5":343,"6":488,"7":27,"8":17,"9":44,"10":331,"11":235,"12":414,"13":331,"14":343,"15":980,"16":27,"17":17},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":2},"end":{"line":32,"column":85}}},"2":{"name":"getRevision","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":2}}},"3":{"name":"getAverageStableRate","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":2}}},"4":{"name":"getUserLastUpdated","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":2}}},"5":{"name":"getUserStableRate","line":63,"loc":{"start":{"line":63,"column":2},"end":{"line":65,"column":2}}},"6":{"name":"balanceOf","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":82,"column":2}}},"7":{"name":"mint","line":103,"loc":{"start":{"line":99,"column":2},"end":{"line":152,"column":2}}},"8":{"name":"burn","line":159,"loc":{"start":{"line":159,"column":2},"end":{"line":205,"column":2}}},"9":{"name":"_calculateBalanceIncrease","line":213,"loc":{"start":{"line":213,"column":2},"end":{"line":236,"column":2}}},"10":{"name":"getSupplyData","line":241,"loc":{"start":{"line":241,"column":2},"end":{"line":244,"column":2}}},"11":{"name":"getTotalSupplyAndAvgRate","line":249,"loc":{"start":{"line":249,"column":2},"end":{"line":252,"column":2}}},"12":{"name":"totalSupply","line":257,"loc":{"start":{"line":257,"column":2},"end":{"line":259,"column":2}}},"13":{"name":"getTotalSupplyLastUpdated","line":264,"loc":{"start":{"line":264,"column":2},"end":{"line":266,"column":2}}},"14":{"name":"principalBalanceOf","line":273,"loc":{"start":{"line":273,"column":2},"end":{"line":275,"column":2}}},"15":{"name":"_calcTotalSupply","line":283,"loc":{"start":{"line":283,"column":2},"end":{"line":296,"column":2}}},"16":{"name":"_mint","line":304,"loc":{"start":{"line":304,"column":3},"end":{"line":312,"column":2}}},"17":{"name":"_burn","line":320,"loc":{"start":{"line":320,"column":2},"end":{"line":328,"column":2}}}},"statementMap":{"1":{"start":{"line":39,"column":4},"end":{"line":39,"column":30}},"2":{"start":{"line":47,"column":4},"end":{"line":47,"column":25}},"3":{"start":{"line":55,"column":4},"end":{"line":55,"column":28}},"4":{"start":{"line":64,"column":4},"end":{"line":64,"column":27}},"5":{"start":{"line":72,"column":4},"end":{"line":72,"column":53}},"6":{"start":{"line":73,"column":4},"end":{"line":73,"column":44}},"7":{"start":{"line":74,"column":4},"end":{"line":74,"column":2428}},"8":{"start":{"line":75,"column":6},"end":{"line":75,"column":14}},"9":{"start":{"line":77,"column":4},"end":{"line":77,"column":2482}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":51}},"11":{"start":{"line":104,"column":4},"end":{"line":104,"column":29}},"12":{"start":{"line":107,"column":4},"end":{"line":107,"column":3360}},"13":{"start":{"line":114,"column":4},"end":{"line":114,"column":38}},"14":{"start":{"line":115,"column":4},"end":{"line":115,"column":45}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":67}},"16":{"start":{"line":118,"column":4},"end":{"line":118,"column":39}},"17":{"start":{"line":121,"column":4},"end":{"line":121,"column":3848}},"18":{"start":{"line":126,"column":4},"end":{"line":126,"column":79}},"19":{"start":{"line":127,"column":4},"end":{"line":127,"column":40}},"20":{"start":{"line":131,"column":4},"end":{"line":131,"column":70}},"21":{"start":{"line":134,"column":4},"end":{"line":134,"column":4342}},"22":{"start":{"line":139,"column":4},"end":{"line":139,"column":64}},"23":{"start":{"line":142,"column":4},"end":{"line":142,"column":43}},"24":{"start":{"line":144,"column":4},"end":{"line":144,"column":4640}},"25":{"start":{"line":160,"column":4},"end":{"line":160,"column":5054}},"26":{"start":{"line":167,"column":4},"end":{"line":167,"column":42}},"27":{"start":{"line":173,"column":4},"end":{"line":173,"column":5510}},"28":{"start":{"line":174,"column":6},"end":{"line":174,"column":23}},"29":{"start":{"line":175,"column":6},"end":{"line":175,"column":21}},"30":{"start":{"line":177,"column":7},"end":{"line":177,"column":69}},"31":{"start":{"line":178,"column":6},"end":{"line":178,"column":5715}},"32":{"start":{"line":184,"column":4},"end":{"line":184,"column":5865}},"33":{"start":{"line":185,"column":6},"end":{"line":185,"column":25}},"34":{"start":{"line":186,"column":6},"end":{"line":186,"column":26}},"35":{"start":{"line":190,"column":6},"end":{"line":190,"column":48}},"36":{"start":{"line":193,"column":4},"end":{"line":193,"column":50}},"37":{"start":{"line":195,"column":4},"end":{"line":195,"column":6147}},"38":{"start":{"line":196,"column":6},"end":{"line":196,"column":61}},"39":{"start":{"line":198,"column":6},"end":{"line":198,"column":61}},"40":{"start":{"line":202,"column":4},"end":{"line":202,"column":43}},"41":{"start":{"line":204,"column":4},"end":{"line":204,"column":81}},"42":{"start":{"line":222,"column":4},"end":{"line":222,"column":60}},"43":{"start":{"line":224,"column":4},"end":{"line":224,"column":7006}},"44":{"start":{"line":225,"column":6},"end":{"line":225,"column":22}},"45":{"start":{"line":229,"column":4},"end":{"line":229,"column":75}},"46":{"start":{"line":231,"column":4},"end":{"line":231,"column":7228}},"47":{"start":{"line":242,"column":4},"end":{"line":242,"column":36}},"48":{"start":{"line":243,"column":4},"end":{"line":243,"column":91}},"49":{"start":{"line":250,"column":4},"end":{"line":250,"column":36}},"50":{"start":{"line":251,"column":4},"end":{"line":251,"column":47}},"51":{"start":{"line":258,"column":4},"end":{"line":258,"column":43}},"52":{"start":{"line":265,"column":4},"end":{"line":265,"column":32}},"53":{"start":{"line":274,"column":4},"end":{"line":274,"column":32}},"54":{"start":{"line":284,"column":4},"end":{"line":284,"column":49}},"55":{"start":{"line":286,"column":4},"end":{"line":286,"column":8975}},"56":{"start":{"line":287,"column":6},"end":{"line":287,"column":14}},"57":{"start":{"line":290,"column":4},"end":{"line":290,"column":9031}},"58":{"start":{"line":295,"column":4},"end":{"line":295,"column":52}},"59":{"start":{"line":306,"column":4},"end":{"line":306,"column":50}},"60":{"start":{"line":307,"column":4},"end":{"line":307,"column":53}},"61":{"start":{"line":309,"column":4},"end":{"line":309,"column":9637}},"62":{"start":{"line":310,"column":6},"end":{"line":310,"column":83}},"63":{"start":{"line":322,"column":4},"end":{"line":322,"column":50}},"64":{"start":{"line":323,"column":4},"end":{"line":323,"column":91}},"65":{"start":{"line":325,"column":4},"end":{"line":325,"column":10249}},"66":{"start":{"line":326,"column":6},"end":{"line":326,"column":83}}},"branchMap":{"1":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":4},"end":{"line":74,"column":4}},{"start":{"line":74,"column":4},"end":{"line":74,"column":4}}]},"2":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":4},"end":{"line":126,"column":4}},{"start":{"line":126,"column":4},"end":{"line":126,"column":4}}]},"3":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":4},"end":{"line":173,"column":4}},{"start":{"line":173,"column":4},"end":{"line":173,"column":4}}]},"4":{"line":184,"type":"if","locations":[{"start":{"line":184,"column":4},"end":{"line":184,"column":4}},{"start":{"line":184,"column":4},"end":{"line":184,"column":4}}]},"5":{"line":195,"type":"if","locations":[{"start":{"line":195,"column":4},"end":{"line":195,"column":4}},{"start":{"line":195,"column":4},"end":{"line":195,"column":4}}]},"6":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":4},"end":{"line":224,"column":4}},{"start":{"line":224,"column":4},"end":{"line":224,"column":4}}]},"7":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":4},"end":{"line":286,"column":4}},{"start":{"line":286,"column":4},"end":{"line":286,"column":4}}]},"8":{"line":309,"type":"if","locations":[{"start":{"line":309,"column":4},"end":{"line":309,"column":4}},{"start":{"line":309,"column":4},"end":{"line":309,"column":4}}]},"9":{"line":325,"type":"if","locations":[{"start":{"line":325,"column":4},"end":{"line":325,"column":4}},{"start":{"line":325,"column":4},"end":{"line":325,"column":4}}]}}},"contracts/tokenization/VariableDebtToken.sol":{"l":{"34":17,"42":460,"44":460,"45":323,"48":137,"63":26,"65":26,"66":26,"79":25,"81":25,"82":25,"90":343,"98":673,"106":331,"116":0},"path":"/src/contracts/tokenization/VariableDebtToken.sol","s":{"1":17,"2":460,"3":460,"4":323,"5":137,"6":26,"7":26,"8":26,"9":25,"10":25,"11":25,"12":343,"13":673,"14":331,"15":0},"b":{"1":[323,137]},"f":{"1":54,"2":17,"3":460,"4":26,"5":25,"6":343,"7":673,"8":331,"9":0},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":21,"column":2},"end":{"line":27,"column":85}}},"2":{"name":"getRevision","line":33,"loc":{"start":{"line":33,"column":2},"end":{"line":35,"column":2}}},"3":{"name":"balanceOf","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"4":{"name":"mint","line":61,"loc":{"start":{"line":57,"column":2},"end":{"line":67,"column":2}}},"5":{"name":"burn","line":78,"loc":{"start":{"line":74,"column":2},"end":{"line":83,"column":2}}},"6":{"name":"scaledBalanceOf","line":89,"loc":{"start":{"line":89,"column":2},"end":{"line":91,"column":2}}},"7":{"name":"totalSupply","line":97,"loc":{"start":{"line":97,"column":2},"end":{"line":99,"column":2}}},"8":{"name":"scaledTotalSupply","line":105,"loc":{"start":{"line":105,"column":2},"end":{"line":107,"column":2}}},"9":{"name":"getScaledUserBalanceAndSupply","line":115,"loc":{"start":{"line":115,"column":2},"end":{"line":117,"column":2}}}},"statementMap":{"1":{"start":{"line":34,"column":4},"end":{"line":34,"column":30}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":49}},"3":{"start":{"line":44,"column":4},"end":{"line":44,"column":1484}},"4":{"start":{"line":45,"column":6},"end":{"line":45,"column":14}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":88}},"6":{"start":{"line":63,"column":4},"end":{"line":63,"column":36}},"7":{"start":{"line":65,"column":4},"end":{"line":65,"column":43}},"8":{"start":{"line":66,"column":4},"end":{"line":66,"column":34}},"9":{"start":{"line":79,"column":4},"end":{"line":79,"column":36}},"10":{"start":{"line":81,"column":4},"end":{"line":81,"column":43}},"11":{"start":{"line":82,"column":4},"end":{"line":82,"column":34}},"12":{"start":{"line":90,"column":4},"end":{"line":90,"column":32}},"13":{"start":{"line":98,"column":4},"end":{"line":98,"column":94}},"14":{"start":{"line":106,"column":4},"end":{"line":106,"column":30}},"15":{"start":{"line":116,"column":4},"end":{"line":116,"column":55}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}}} \ No newline at end of file diff --git a/test/addresses-provider-registry.spec.ts b/test/addresses-provider-registry.spec.ts index 37a0978e..dd7db8e0 100644 --- a/test/addresses-provider-registry.spec.ts +++ b/test/addresses-provider-registry.spec.ts @@ -51,5 +51,43 @@ makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => { expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, " Invalid addresses"); }); + + it('Tries to remove a unregistered addressesProvider', async () => { + + const {PROVIDER_NOT_REGISTERED} = ProtocolErrors; + + const {users, registry} = testEnv; + + await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(PROVIDER_NOT_REGISTERED); + + }); + + it('Tries to remove a unregistered addressesProvider', async () => { + + const {PROVIDER_NOT_REGISTERED} = ProtocolErrors; + + const {users, registry} = testEnv; + + await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(PROVIDER_NOT_REGISTERED); + + }); + + it('Tries to add an already added addressesProvider with a different id. Should overwrite the previous id', async () => { + + const {users, registry, addressesProvider} = testEnv; + + await registry.registerAddressesProvider(addressesProvider.address,"2"); + + const providers = await registry.getAddressesProvidersList(); + + const id = await registry.isAddressesProviderRegistered(addressesProvider.address); + + expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list"); + + expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list"); + expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, " Invalid addresses"); + + }); + }); From 6ee4b2725ba698894103a3e6ee1c55ec89cf5950 Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 24 Sep 2020 10:00:17 +0200 Subject: [PATCH 57/79] Fix order of calculation of the interest rates --- .../lendingpool/LendingPoolCollateralManager.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/lendingpool/LendingPoolCollateralManager.sol b/contracts/lendingpool/LendingPoolCollateralManager.sol index fad590be..75f4f659 100644 --- a/contracts/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/lendingpool/LendingPoolCollateralManager.sol @@ -374,6 +374,14 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor //updating collateral reserve indexes collateralReserve.updateState(); + //updating collateral reserve interest rates + collateralReserve.updateInterestRates( + collateral, + address(vars.collateralAtoken), + 0, + vars.maxCollateralToLiquidate + ); + vars.collateralAtoken.burn( user, receiver, @@ -424,14 +432,6 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor ); } - //updating collateral reserve - collateralReserve.updateInterestRates( - collateral, - address(vars.collateralAtoken), - 0, - vars.maxCollateralToLiquidate - ); - emit RepaidWithCollateral( collateral, principal, From 6e7787d23c07e8d55a2a2ccb78af4f2f3536975c Mon Sep 17 00:00:00 2001 From: The3D Date: Thu, 24 Sep 2020 18:20:17 +0200 Subject: [PATCH 58/79] initial fix --- contracts/libraries/logic/GenericLogic.sol | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index 4b64e85f..69810f69 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -10,6 +10,8 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {WadRayMath} from '../math/WadRayMath.sol'; import {PercentageMath} from '../math/PercentageMath.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; +import "@nomiclabs/buidler/console.sol"; + /** * @title GenericLogic library @@ -29,11 +31,10 @@ library GenericLogic { struct balanceDecreaseAllowedLocalVars { uint256 decimals; - uint256 ltv; + uint256 liquidationThreshold; uint256 collateralBalanceETH; uint256 borrowBalanceETH; - uint256 currentLiquidationThreshold; - uint256 reserveLiquidationThreshold; + uint256 avgLiquidationThreshold; uint256 amountToDecreaseETH; uint256 collateralBalancefterDecrease; uint256 liquidationThresholdAfterDecrease; @@ -71,9 +72,10 @@ library GenericLogic { balanceDecreaseAllowedLocalVars memory vars; - (vars.ltv, , , vars.decimals) = reservesData[asset].configuration.getParams(); - if (vars.ltv == 0) { + (, vars.liquidationThreshold, , vars.decimals) = reservesData[asset].configuration.getParams(); + + if (vars.liquidationThreshold == 0) { return true; //if reserve is not used as collateral, no reasons to block the transfer } @@ -81,7 +83,7 @@ library GenericLogic { vars.collateralBalanceETH, vars.borrowBalanceETH, , - vars.currentLiquidationThreshold, + vars.avgLiquidationThreshold, ) = calculateUserAccountData(user, reservesData, userConfig, reserves, oracle); @@ -102,8 +104,8 @@ library GenericLogic { vars.liquidationThresholdAfterDecrease = vars .collateralBalanceETH - .mul(vars.currentLiquidationThreshold) - .sub(vars.amountToDecreaseETH.mul(vars.reserveLiquidationThreshold)) + .mul(vars.avgLiquidationThreshold) + .sub(vars.amountToDecreaseETH.mul(vars.liquidationThreshold)) .div(vars.collateralBalancefterDecrease); uint256 healthFactorAfterDecrease = calculateHealthFactorFromBalances( From fb0f533ae9d6f24be79f9e7af703bf789b12d143 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 10:55:58 +0200 Subject: [PATCH 59/79] Changes usage of the ltv in calculateUserAccountData --- contracts/libraries/logic/GenericLogic.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index 69810f69..fa54c928 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -188,7 +188,7 @@ library GenericLogic { vars.tokenUnit = 10**vars.decimals; vars.reserveUnitPrice = IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress); - if (vars.ltv != 0 && userConfig.isUsingAsCollateral(vars.i)) { + if (vars.liquidationThreshold != 0 && userConfig.isUsingAsCollateral(vars.i)) { vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(user); uint256 liquidityBalanceETH = vars From 687b13f019b02fa6e8bd6630725c216abeedccc3 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 10:57:26 +0200 Subject: [PATCH 60/79] Formatting, removed console import --- contracts/libraries/logic/GenericLogic.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index fa54c928..c63a4b16 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -72,7 +72,6 @@ library GenericLogic { balanceDecreaseAllowedLocalVars memory vars; - (, vars.liquidationThreshold, , vars.decimals) = reservesData[asset].configuration.getParams(); if (vars.liquidationThreshold == 0) { From e328cf048214d8eaaaa7e0f46fde62c102c32cc5 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 10:57:51 +0200 Subject: [PATCH 61/79] Formatting, removed console import --- contracts/libraries/logic/GenericLogic.sol | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index c63a4b16..d1a7d6ce 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -10,8 +10,6 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol'; import {WadRayMath} from '../math/WadRayMath.sol'; import {PercentageMath} from '../math/PercentageMath.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; -import "@nomiclabs/buidler/console.sol"; - /** * @title GenericLogic library @@ -63,10 +61,7 @@ library GenericLogic { address[] calldata reserves, address oracle ) external view returns (bool) { - if ( - !userConfig.isBorrowingAny() || - !userConfig.isUsingAsCollateral(reservesData[asset].id) - ) { + if (!userConfig.isBorrowingAny() || !userConfig.isUsingAsCollateral(reservesData[asset].id)) { return true; } @@ -255,7 +250,7 @@ library GenericLogic { return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH); } - /** + /** * @dev calculates the equivalent amount in ETH that an user can borrow, depending on the available collateral and the * average Loan To Value. * @param collateralBalanceETH the total collateral balance From 35044941b034b18e4ef8e6a1347410fe01ef9220 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 11:20:12 +0200 Subject: [PATCH 62/79] Fix test related to the LTV change --- .../flash-liquidation-with-collateral.spec.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/test/flash-liquidation-with-collateral.spec.ts b/test/flash-liquidation-with-collateral.spec.ts index 3b20f79c..15dac674 100644 --- a/test/flash-liquidation-with-collateral.spec.ts +++ b/test/flash-liquidation-with-collateral.spec.ts @@ -833,12 +833,13 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn await oracle.setAssetPrice(dai.address, daiPrice); }); - it('User 5 deposits WETH and DAI, then borrows USDC at Variable, then disables WETH as collateral', async () => { + it('User 4 deposits WETH, LEND and DAI, then borrows USDC at Variable, then disables WETH as collateral', async () => { const {pool, weth, dai, usdc, users} = testEnv; const user = users[4]; const amountWETHToDeposit = parseEther('10'); - const amountDAIToDeposit = parseEther('60'); - const amountToBorrow = parseUnits('65', 6); + const amountDAIToDeposit = parseEther('100'); + + const amountToBorrow = parseUnits('75', 6); await weth.connect(user.signer).mint(amountWETHToDeposit); await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL); @@ -851,8 +852,8 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address); }); - it('Liquidator tries to liquidates User 5 USDC loan by swapping his WETH collateral, should revert due WETH collateral disabled', async () => { - const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv; + it('Liquidator tries to liquidate User 5 USDC loan by swapping his WETH collateral, should revert due WETH collateral disabled', async () => { + const {pool, weth, dai, usdc, users, mockSwapAdapter, oracle} = testEnv; const user = users[4]; const liquidator = users[5]; @@ -874,6 +875,14 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn expect(wethUserDataBefore.usageAsCollateralEnabled).to.be.false; + //drop the price to set the HF below 1 + const daiPrice = await oracle.getAssetPrice(dai.address); + + await oracle.setAssetPrice( + dai.address, + new BigNumber(daiPrice.toString()).multipliedBy(0.9).toFixed(0) + ); + // Liquidator should NOT be able to liquidate himself with WETH, even if is disabled await mockSwapAdapter.setAmountToReturn(amountToRepay); await expect( @@ -888,6 +897,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn '0x' ) ).to.be.revertedWith(COLLATERAL_CANNOT_BE_LIQUIDATED); + const repayWithCollateralTimestamp = await timeLatest(); const {userData: wethUserDataAfter} = await getContractsData( From f0191909a247079c9746dcc003745feb67588e63 Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 11:51:35 +0200 Subject: [PATCH 63/79] Added more setUseReserveAsCollateral() scenarios tests --- .../scenarios/set-use-as-collateral.json | 97 ++++++++++++++++++- test/scenario.spec.ts | 2 +- 2 files changed, 95 insertions(+), 4 deletions(-) diff --git a/test/helpers/scenarios/set-use-as-collateral.json b/test/helpers/scenarios/set-use-as-collateral.json index 614c8ddb..871a78b9 100644 --- a/test/helpers/scenarios/set-use-as-collateral.json +++ b/test/helpers/scenarios/set-use-as-collateral.json @@ -43,7 +43,7 @@ ] }, { - "description": "User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)", + "description": "User 1 Deposits 2 WETH, disables WETH as collateral, borrows 400 DAI (revert expected)", "actions": [ { "name": "mint", @@ -96,7 +96,7 @@ ] }, { - "description": "User 1 enables ETH as collateral, borrows 400 DAI", + "description": "User 1 enables WETH as collateral, borrows 400 DAI", "actions": [ { "name": "setUseAsCollateral", @@ -120,7 +120,7 @@ ] }, { - "description": "User 1 disables ETH as collateral (revert expected)", + "description": "User 1 disables WETH as collateral (revert expected)", "actions": [ { "name": "setUseAsCollateral", @@ -134,6 +134,97 @@ "revertMessage": "User deposit is already being used as collateral" } ] + }, + { + "description": "User 1 Deposits 1000 LEND, disables WETH as collateral. Should revert as 1000 LEND are not enough to cover the debt (revert expected)", + "actions": [ + { + "name": "mint", + "args": { + "reserve": "LEND", + "amount": "1000", + "user": "1" + }, + "expected": "success" + }, + { + "name": "approve", + "args": { + "reserve": "LEND", + "user": "1" + }, + "expected": "success" + }, + { + "name": "deposit", + "args": { + "reserve": "LEND", + + "amount": "1000", + "user": "1" + }, + "expected": "success" + }, + { + "name": "setUseAsCollateral", + "args": { + "reserve": "WETH", + + "user": "1", + "useAsCollateral": "false" + }, + "expected": "revert" + } + ] + }, + { + "description": "User 1 Deposits 64000 more LEND (enough to cover the DAI debt), disables WETH as collateral", + "actions": [ + { + "name": "mint", + "args": { + "reserve": "LEND", + "amount": "64000", + "user": "1" + }, + "expected": "success" + }, + { + "name": "deposit", + "args": { + "reserve": "LEND", + + "amount": "64000", + "user": "1" + }, + "expected": "success" + }, + { + "name": "setUseAsCollateral", + "args": { + "reserve": "WETH", + + "user": "1", + "useAsCollateral": "false" + }, + "expected": "success" + } + ] + }, + { + "description": "User 1 disables LEND as collateral (revert expected)", + "actions": [ + { + "name": "setUseAsCollateral", + "args": { + "reserve": "LEND", + + "user": "1", + "useAsCollateral": "false" + }, + "expected": "User deposit is already being used as collateral" + } + ] } ] } diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 54fe7433..3bff8c6b 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = []; +const selectedScenarios: string[] = ['set-use-as-collateral.json']; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 6d1fede2c9a129b11937fb8b0454f6b3f26cfe4d Mon Sep 17 00:00:00 2001 From: The3D Date: Fri, 25 Sep 2020 13:48:42 +0200 Subject: [PATCH 64/79] Removed selected scenario from the scenario file --- test/scenario.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/scenario.spec.ts b/test/scenario.spec.ts index 3bff8c6b..54fe7433 100644 --- a/test/scenario.spec.ts +++ b/test/scenario.spec.ts @@ -10,7 +10,7 @@ import {executeStory} from './helpers/scenario-engine'; const scenarioFolder = './test/helpers/scenarios/'; -const selectedScenarios: string[] = ['set-use-as-collateral.json']; +const selectedScenarios: string[] = []; fs.readdirSync(scenarioFolder).forEach((file) => { if (selectedScenarios.length > 0 && !selectedScenarios.includes(file)) return; From 099532ee48cd35d7669c995839ee56f8ec265ed9 Mon Sep 17 00:00:00 2001 From: eboado Date: Tue, 29 Sep 2020 16:31:21 +0200 Subject: [PATCH 65/79] - Added general setter and getter of address to LendingPoolAddressesProvider. - Adapted style of LendingPoolAddressesProviderRegistry, adding public getter function in the process. --- .../LendingPoolAddressesProvider.sol | 41 ++++++++++++++++--- .../LendingPoolAddressesProviderRegistry.sol | 39 ++++++++++++------ .../ILendingPoolAddressesProvider.sol | 11 ++++- .../ILendingPoolAddressesProviderRegistry.sol | 7 +++- test/lending-pool-addresses-provider.spec.ts | 12 ++++++ 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/contracts/configuration/LendingPoolAddressesProvider.sol b/contracts/configuration/LendingPoolAddressesProvider.sol index 0cc67297..90fe8555 100644 --- a/contracts/configuration/LendingPoolAddressesProvider.sol +++ b/contracts/configuration/LendingPoolAddressesProvider.sol @@ -30,12 +30,41 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider bytes32 private constant LENDING_RATE_ORACLE = 'LENDING_RATE_ORACLE'; bytes32 private constant WALLET_BALANCE_PROVIDER = 'WALLET_BALANCE_PROVIDER'; + /** + * @dev Sets an address for an id, allowing to cover it or not with a proxy + * @param id The id + * @param newAddress The address to set, pass address(0) if a proxy is needed + * @param implementationAddress The address of the implementation if we want it covered by a proxy + * address(0) if we don't want a proxy covering + */ + function setAddress( + bytes32 id, + address newAddress, + address implementationAddress + ) external override onlyOwner { + if (implementationAddress != address(0)) { + _updateImpl(id, implementationAddress); + emit AddressSet(id, implementationAddress, true); + } else { + _addresses[id] = newAddress; + emit AddressSet(id, newAddress, false); + } + } + + /** + * @dev Returns an address by id + * @return The address + */ + function getAddress(bytes32 id) public override view returns (address) { + return _addresses[id]; + } + /** * @dev returns the address of the LendingPool proxy * @return the lending pool proxy address **/ function getLendingPool() external override view returns (address) { - return _addresses[LENDING_POOL]; + return getAddress(LENDING_POOL); } /** @@ -52,7 +81,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider * @return the lending pool configurator proxy address **/ function getLendingPoolConfigurator() external override view returns (address) { - return _addresses[LENDING_POOL_CONFIGURATOR]; + return getAddress(LENDING_POOL_CONFIGURATOR); } /** @@ -72,7 +101,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider **/ function getLendingPoolCollateralManager() external override view returns (address) { - return _addresses[LENDING_POOL_COLLATERAL_MANAGER]; + return getAddress(LENDING_POOL_COLLATERAL_MANAGER); } /** @@ -90,7 +119,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider **/ function getAaveAdmin() external override view returns (address) { - return _addresses[AAVE_ADMIN]; + return getAddress(AAVE_ADMIN); } function setAaveAdmin(address aaveAdmin) external override onlyOwner { @@ -99,7 +128,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider } function getPriceOracle() external override view returns (address) { - return _addresses[PRICE_ORACLE]; + return getAddress(PRICE_ORACLE); } function setPriceOracle(address priceOracle) external override onlyOwner { @@ -108,7 +137,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider } function getLendingRateOracle() external override view returns (address) { - return _addresses[LENDING_RATE_ORACLE]; + return getAddress(LENDING_RATE_ORACLE); } function setLendingRateOracle(address lendingRateOracle) external override onlyOwner { diff --git a/contracts/configuration/LendingPoolAddressesProviderRegistry.sol b/contracts/configuration/LendingPoolAddressesProviderRegistry.sol index ee0caf16..edc719ef 100644 --- a/contracts/configuration/LendingPoolAddressesProviderRegistry.sol +++ b/contracts/configuration/LendingPoolAddressesProviderRegistry.sol @@ -14,8 +14,8 @@ import {Errors} from '../libraries/helpers/Errors.sol'; **/ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesProviderRegistry { - mapping(address => uint256) addressesProviders; - address[] addressesProvidersList; + mapping(address => uint256) private _addressesProviders; + address[] private _addressesProvidersList; /** * @dev returns if an addressesProvider is registered or not @@ -28,7 +28,7 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP view returns (uint256) { - return addressesProviders[provider]; + return _addressesProviders[provider]; } /** @@ -36,13 +36,13 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP * @return the list of addressesProviders **/ function getAddressesProvidersList() external override view returns (address[] memory) { - uint256 maxLength = addressesProvidersList.length; + uint256 maxLength = _addressesProvidersList.length; address[] memory activeProviders = new address[](maxLength); - for (uint256 i = 0; i < addressesProvidersList.length; i++) { - if (addressesProviders[addressesProvidersList[i]] > 0) { - activeProviders[i] = addressesProvidersList[i]; + for (uint256 i = 0; i < _addressesProvidersList.length; i++) { + if (_addressesProviders[_addressesProvidersList[i]] > 0) { + activeProviders[i] = _addressesProvidersList[i]; } } @@ -54,7 +54,7 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP * @param provider the pool address to be registered **/ function registerAddressesProvider(address provider, uint256 id) external override onlyOwner { - addressesProviders[provider] = id; + _addressesProviders[provider] = id; _addToAddressesProvidersList(provider); emit AddressesProviderRegistered(provider); } @@ -64,8 +64,8 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP * @param provider the pool address to be unregistered **/ function unregisterAddressesProvider(address provider) external override onlyOwner { - require(addressesProviders[provider] > 0, Errors.PROVIDER_NOT_REGISTERED); - addressesProviders[provider] = 0; + require(_addressesProviders[provider] > 0, Errors.PROVIDER_NOT_REGISTERED); + _addressesProviders[provider] = 0; emit AddressesProviderUnregistered(provider); } @@ -74,12 +74,25 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP * @param provider the pool address to be added **/ function _addToAddressesProvidersList(address provider) internal { - for (uint256 i = 0; i < addressesProvidersList.length; i++) { - if (addressesProvidersList[i] == provider) { + for (uint256 i = 0; i < _addressesProvidersList.length; i++) { + if (_addressesProvidersList[i] == provider) { return; } } - addressesProvidersList.push(provider); + _addressesProvidersList.push(provider); + } + + /** + * @dev Returns the id on an `addressesProvider` or address(0) if not registered + * @return The id or address(0) + */ + function getAddressesProviderIdByAddress(address addressesProvider) + external + override + view + returns (uint256) + { + return _addressesProviders[addressesProvider]; } } diff --git a/contracts/interfaces/ILendingPoolAddressesProvider.sol b/contracts/interfaces/ILendingPoolAddressesProvider.sol index 9f78edfe..53ed9873 100644 --- a/contracts/interfaces/ILendingPoolAddressesProvider.sol +++ b/contracts/interfaces/ILendingPoolAddressesProvider.sol @@ -7,7 +7,6 @@ pragma solidity ^0.6.8; */ interface ILendingPoolAddressesProvider { - //events event LendingPoolUpdated(address indexed newAddress); event AaveAdminUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress); @@ -15,8 +14,16 @@ interface ILendingPoolAddressesProvider { event EthereumAddressUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress); - event ProxyCreated(bytes32 id, address indexed newAddress); + event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy); + + function setAddress( + bytes32 id, + address newAddress, + address impl + ) external; + + function getAddress(bytes32 id) external view returns (address); function getLendingPool() external view returns (address); diff --git a/contracts/interfaces/ILendingPoolAddressesProviderRegistry.sol b/contracts/interfaces/ILendingPoolAddressesProviderRegistry.sol index ec26dd07..87c0c651 100644 --- a/contracts/interfaces/ILendingPoolAddressesProviderRegistry.sol +++ b/contracts/interfaces/ILendingPoolAddressesProviderRegistry.sol @@ -5,9 +5,7 @@ pragma solidity ^0.6.8; * @title ILendingPoolAddressesProvider interface * @notice provides the interface to fetch the LendingPoolCore address **/ - interface ILendingPoolAddressesProviderRegistry { - //events event AddressesProviderRegistered(address indexed newAddress); event AddressesProviderUnregistered(address indexed newAddress); @@ -15,6 +13,11 @@ interface ILendingPoolAddressesProviderRegistry { function isAddressesProviderRegistered(address provider) external view returns (uint256); + function getAddressesProviderIdByAddress(address addressesProvider) + external + view + returns (uint256); + function registerAddressesProvider(address provider, uint256 id) external; function unregisterAddressesProvider(address provider) external; diff --git a/test/lending-pool-addresses-provider.spec.ts b/test/lending-pool-addresses-provider.spec.ts index 5721ff97..f2dcfa91 100644 --- a/test/lending-pool-addresses-provider.spec.ts +++ b/test/lending-pool-addresses-provider.spec.ts @@ -2,6 +2,10 @@ import {expect} from 'chai'; import {createRandomAddress} from '../helpers/misc-utils'; import {makeSuite, TestEnv} from './helpers/make-suite'; import {ProtocolErrors} from '../helpers/types'; +import {ethers} from 'ethers'; +import {ZERO_ADDRESS} from '../helpers/constants'; + +const {utils} = ethers; makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => { it('Test the accessibility of the LendingPoolAddressesProvider', async () => { @@ -21,5 +25,13 @@ makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => { ]) { await expect(contractFunction(mockAddress)).to.be.revertedWith(INVALID_OWNER_REVERT_MSG); } + + await expect( + addressesProvider.setAddress( + utils.keccak256(utils.toUtf8Bytes('RANDOM_ID')), + mockAddress, + ZERO_ADDRESS + ) + ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG); }); }); From 33437695107853a68a3d9f72208f2bcc59024d9e Mon Sep 17 00:00:00 2001 From: eboado Date: Tue, 29 Sep 2020 17:00:51 +0200 Subject: [PATCH 66/79] - Added setter tests for setAddress() on LendingPoolAddressesProvider --- test/lending-pool-addresses-provider.spec.ts | 54 ++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/lending-pool-addresses-provider.spec.ts b/test/lending-pool-addresses-provider.spec.ts index f2dcfa91..07f99c38 100644 --- a/test/lending-pool-addresses-provider.spec.ts +++ b/test/lending-pool-addresses-provider.spec.ts @@ -4,6 +4,8 @@ import {makeSuite, TestEnv} from './helpers/make-suite'; import {ProtocolErrors} from '../helpers/types'; import {ethers} from 'ethers'; import {ZERO_ADDRESS} from '../helpers/constants'; +import {waitForTx} from './__setup.spec'; +import {deployLendingPool} from '../helpers/contracts-helpers'; const {utils} = ethers; @@ -34,4 +36,56 @@ makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => { ) ).to.be.revertedWith(INVALID_OWNER_REVERT_MSG); }); + + it('Tests adding both a proxied and non-proxied addres with `setAddress()`', async () => { + const {addressesProvider, users} = testEnv; + const {INVALID_OWNER_REVERT_MSG} = ProtocolErrors; + + const currentAddressesProviderOwner = users[1]; + + const mockNonProxiedAddress = createRandomAddress(); + const nonProxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_NON_PROXIED')); + + const mockLendingPool = await deployLendingPool(); + const proxiedAddressId = utils.keccak256(utils.toUtf8Bytes('RANDOM_PROXIED')); + + const nonProxiedAddressSetReceipt = await waitForTx( + await addressesProvider + .connect(currentAddressesProviderOwner.signer) + .setAddress(nonProxiedAddressId, mockNonProxiedAddress, ZERO_ADDRESS) + ); + + expect(mockNonProxiedAddress.toLowerCase()).to.be.equal( + (await addressesProvider.getAddress(nonProxiedAddressId)).toLowerCase() + ); + + if (!nonProxiedAddressSetReceipt.events || nonProxiedAddressSetReceipt.events?.length < 1) { + throw new Error('INVALID_EVENT_EMMITED'); + } + + expect(nonProxiedAddressSetReceipt.events[0].event).to.be.equal('AddressSet'); + expect(nonProxiedAddressSetReceipt.events[0].args?.id).to.be.equal(nonProxiedAddressId); + expect(nonProxiedAddressSetReceipt.events[0].args?.newAddress).to.be.equal( + mockNonProxiedAddress + ); + expect(nonProxiedAddressSetReceipt.events[0].args?.hasProxy).to.be.equal(false); + + const proxiedAddressSetReceipt = await waitForTx( + await addressesProvider + .connect(currentAddressesProviderOwner.signer) + .setAddress(proxiedAddressId, ZERO_ADDRESS, mockLendingPool.address) + ); + + if (!proxiedAddressSetReceipt.events || proxiedAddressSetReceipt.events?.length < 2) { + throw new Error('INVALID_EVENT_EMMITED'); + } + + expect(proxiedAddressSetReceipt.events[0].event).to.be.equal('ProxyCreated'); + expect(proxiedAddressSetReceipt.events[1].event).to.be.equal('AddressSet'); + expect(proxiedAddressSetReceipt.events[1].args?.id).to.be.equal(proxiedAddressId); + expect(proxiedAddressSetReceipt.events[1].args?.newAddress).to.be.equal( + mockLendingPool.address + ); + expect(proxiedAddressSetReceipt.events[1].args?.hasProxy).to.be.equal(true); + }); }); From d56a7a27797dedae3822e0ae914be469c2733eda Mon Sep 17 00:00:00 2001 From: eboado Date: Wed, 30 Sep 2020 11:24:22 +0200 Subject: [PATCH 67/79] Misc changes on ReserveConfiguration: - Fixed unprecise STABLE_BORROWING_MASK. - Added constant for start bit positions of the different configurations. --- .../configuration/ReserveConfiguration.sol | 113 +++++++++++------- 1 file changed, 71 insertions(+), 42 deletions(-) diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 66fa21f4..7b3e44f7 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -20,40 +20,32 @@ library ReserveConfiguration { uint256 constant ACTIVE_MASK = 0xFFFFFEFFFFFFFFFFFFFF; uint256 constant FROZEN_MASK = 0xFFFFFDFFFFFFFFFFFFFF; uint256 constant BORROWING_MASK = 0xFFFFFBFFFFFFFFFFFFFF; - uint256 constant STABLE_BORROWING_MASK = 0xFFFF07FFFFFFFFFFFFFF; + uint256 constant STABLE_BORROWING_MASK = 0xFFFFF7FFFFFFFFFFFFFF; uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFF; + /// @dev For the LTV, the start bit is 0 (up to 15), but we don't declare it as for 0 no bit movement is needed + uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16; + uint256 constant LIQUIDATION_BONUS_START_BIT_POSITION = 32; + uint256 constant RESERVE_DECIMALS_START_BIT_POSITION = 48; + uint256 constant IS_ACTIVE_START_BIT_POSITION = 56; + uint256 constant IS_FROZEN_START_BIT_POSITION = 57; + uint256 constant BORROWING_ENABLED_START_BIT_POSITION = 58; + uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59; + uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64; + struct Map { //bit 0-15: LTV //bit 16-31: Liq. threshold //bit 32-47: Liq. bonus //bit 48-55: Decimals //bit 56: Reserve is active - //bit 57: reserve is freezed + //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled //bit 64-79: reserve factor uint256 data; } - /** - * @dev sets the reserve factor of the reserve - * @param self the reserve configuration - * @param reserveFactor the reserve factor - **/ - function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) internal pure { - - self.data = (self.data & RESERVE_FACTOR_MASK) | reserveFactor << 64; - } - - /** - * @dev gets the reserve factor of the reserve - * @param self the reserve configuration - * @return the reserve factor - **/ - function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { - return (self.data & ~RESERVE_FACTOR_MASK) >> 64; - } /** * @dev sets the Loan to Value of the reserve * @param self the reserve configuration @@ -81,7 +73,9 @@ library ReserveConfiguration { internal pure { - self.data = (self.data & LIQUIDATION_THRESHOLD_MASK) | (threshold << 16); + self.data = + (self.data & LIQUIDATION_THRESHOLD_MASK) | + (threshold << LIQUIDATION_THRESHOLD_START_BIT_POSITION); } /** @@ -94,7 +88,7 @@ library ReserveConfiguration { view returns (uint256) { - return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> 16; + return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION; } /** @@ -103,7 +97,9 @@ library ReserveConfiguration { * @param bonus the new liquidation bonus **/ function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure { - self.data = (self.data & LIQUIDATION_BONUS_MASK) | (bonus << 32); + self.data = + (self.data & LIQUIDATION_BONUS_MASK) | + (bonus << LIQUIDATION_BONUS_START_BIT_POSITION); } /** @@ -116,7 +112,7 @@ library ReserveConfiguration { view returns (uint256) { - return (self.data & ~LIQUIDATION_BONUS_MASK) >> 32; + return (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION; } /** @@ -125,7 +121,7 @@ library ReserveConfiguration { * @param decimals the decimals **/ function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure { - self.data = (self.data & DECIMALS_MASK) | (decimals << 48); + self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION); } /** @@ -134,7 +130,7 @@ library ReserveConfiguration { * @return the decimals of the asset **/ function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) { - return (self.data & ~DECIMALS_MASK) >> 48; + return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION; } /** @@ -143,7 +139,9 @@ library ReserveConfiguration { * @param active the active state **/ function setActive(ReserveConfiguration.Map memory self, bool active) internal pure { - self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << 56); + self.data = + (self.data & ACTIVE_MASK) | + (uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION); } /** @@ -152,7 +150,7 @@ library ReserveConfiguration { * @return the active state **/ function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) { - return ((self.data & ~ACTIVE_MASK) >> 56) != 0; + return ((self.data & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION) != 0; } /** @@ -161,7 +159,9 @@ library ReserveConfiguration { * @param frozen the frozen state **/ function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure { - self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << 57); + self.data = + (self.data & FROZEN_MASK) | + (uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION); } /** @@ -170,7 +170,7 @@ library ReserveConfiguration { * @return the frozen state **/ function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) { - return ((self.data & ~FROZEN_MASK) >> 57) != 0; + return ((self.data & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION) != 0; } /** @@ -179,7 +179,9 @@ library ReserveConfiguration { * @param enabled true if the borrowing needs to be enabled, false otherwise **/ function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure { - self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 58); + self.data = + (self.data & BORROWING_MASK) | + (uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION); } /** @@ -188,7 +190,7 @@ library ReserveConfiguration { * @return the borrowing state **/ function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) { - return ((self.data & ~BORROWING_MASK) >> 58) != 0; + return ((self.data & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION) != 0; } /** @@ -197,9 +199,12 @@ library ReserveConfiguration { * @param enabled true if the stable rate borrowing needs to be enabled, false otherwise **/ function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) - internal pure + internal + pure { - self.data = (self.data & STABLE_BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 59); + self.data = + (self.data & STABLE_BORROWING_MASK) | + (uint256(enabled ? 1 : 0) << STABLE_BORROWING_ENABLED_START_BIT_POSITION); } /** @@ -212,7 +217,31 @@ library ReserveConfiguration { view returns (bool) { - return ((self.data & ~STABLE_BORROWING_MASK) >> 59) != 0; + return + ((self.data & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION) != 0; + } + + /** + * @dev sets the reserve factor of the reserve + * @param self the reserve configuration + * @param reserveFactor the reserve factor + **/ + function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor) + internal + pure + { + self.data = + (self.data & RESERVE_FACTOR_MASK) | + (reserveFactor << RESERVE_FACTOR_START_BIT_POSITION); + } + + /** + * @dev gets the reserve factor of the reserve + * @param self the reserve configuration + * @return the reserve factor + **/ + function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) { + return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION; } /** @@ -233,10 +262,10 @@ library ReserveConfiguration { uint256 dataLocal = self.data; return ( - (dataLocal & ~ACTIVE_MASK) >> 56 != 0, - (dataLocal & ~FROZEN_MASK) >> 57 != 0, - (dataLocal & ~BORROWING_MASK) >> 58 != 0, - (dataLocal & ~STABLE_BORROWING_MASK) >> 59 != 0 + (dataLocal & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0, + (dataLocal & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0, + (dataLocal & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0, + (dataLocal & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0 ); } @@ -259,9 +288,9 @@ library ReserveConfiguration { return ( dataLocal & ~LTV_MASK, - (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> 16, - (dataLocal & ~LIQUIDATION_BONUS_MASK) >> 32, - (dataLocal & ~DECIMALS_MASK) >> 48 + (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, + (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, + (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION ); } } From e86cf9fe0a12552ffef0b43da397352dd5813a76 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 10:23:02 +0200 Subject: [PATCH 68/79] Fixes liquidation bonus mask, adds comment on reserved bits --- contracts/libraries/configuration/ReserveConfiguration.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/libraries/configuration/ReserveConfiguration.sol b/contracts/libraries/configuration/ReserveConfiguration.sol index 7b3e44f7..5053c0fd 100644 --- a/contracts/libraries/configuration/ReserveConfiguration.sol +++ b/contracts/libraries/configuration/ReserveConfiguration.sol @@ -15,7 +15,7 @@ import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; library ReserveConfiguration { uint256 constant LTV_MASK = 0xFFFFFFFFFFFFFFFF0000; uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFFFFFFF0000FFFF; - uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFF0000FFFFFFFF; + uint256 constant LIQUIDATION_BONUS_MASK = 0xFFFFFFFF0000FFFFFFFF; uint256 constant DECIMALS_MASK = 0xFFFFFF00FFFFFFFFFFFF; uint256 constant ACTIVE_MASK = 0xFFFFFEFFFFFFFFFFFFFF; uint256 constant FROZEN_MASK = 0xFFFFFDFFFFFFFFFFFFFF; @@ -42,6 +42,7 @@ library ReserveConfiguration { //bit 57: reserve is frozen //bit 58: borrowing is enabled //bit 59: stable rate borrowing enabled + //bit 60-63: reserved //bit 64-79: reserve factor uint256 data; } From 4d991e6709729f696cea234bb1ccfe858d100cd8 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 10:59:33 +0200 Subject: [PATCH 69/79] Updated tests on freeze, borrowingEnabled --- test/configurator.spec.ts | 45 +++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 0fa3289c..8c24d43d 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -42,8 +42,27 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Freezes the ETH reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.freezeReserve(weth.address); - const {isFreezed} = await pool.getReserveConfigurationData(weth.address); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); expect(isFreezed).to.be.equal(true); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); }); it('Unfreezes the ETH reserve', async () => { @@ -73,8 +92,28 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Deactivates the ETH reserve for borrowing', async () => { const {configurator, pool, weth} = testEnv; await configurator.disableBorrowingOnReserve(weth.address); - const {borrowingEnabled} = await pool.getReserveConfigurationData(weth.address); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed + } = await pool.getReserveConfigurationData(weth.address); + expect(borrowingEnabled).to.be.equal(false); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); + }); it('Activates the ETH reserve for borrowing', async () => { @@ -180,7 +219,6 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN); }); - it('Changes the reserve factor of the reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.setReserveFactor(weth.address, '1000'); @@ -196,7 +234,6 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { ).to.be.revertedWith(CALLER_NOT_AAVE_ADMIN); }); - it('Changes liquidation threshold of the reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.setLiquidationThreshold(weth.address, '75'); From bad45772c145f0b431cef39d0324cd2fe3dba5dc Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:02:34 +0200 Subject: [PATCH 70/79] Updated tests on unfreeze --- test/configurator.spec.ts | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 8c24d43d..d83f5d71 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -51,7 +51,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed + isFreezed, } = await pool.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(true); @@ -62,15 +62,34 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { expect(liquidationThreshold).to.be.equal(8000); expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(true); - expect(reserveFactor).to.be.equal(0); + expect(reserveFactor).to.be.equal(0); }); it('Unfreezes the ETH reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.unfreezeReserve(weth.address); - const {isFreezed} = await pool.getReserveConfigurationData(weth.address); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); }); it('Check the onlyAaveAdmin on freezeReserve ', async () => { @@ -101,7 +120,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { stableBorrowRateEnabled, borrowingEnabled, isActive, - isFreezed + isFreezed, } = await pool.getReserveConfigurationData(weth.address); expect(borrowingEnabled).to.be.equal(false); @@ -113,7 +132,6 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(true); expect(reserveFactor).to.be.equal(0); - }); it('Activates the ETH reserve for borrowing', async () => { From 450cdfa95c197d8d44f8c3fed70095b84e3c49f2 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:03:51 +0200 Subject: [PATCH 71/79] Updated tests on enableBorrowingOnReserve --- test/configurator.spec.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index d83f5d71..de6fbd76 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -137,9 +137,30 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Activates the ETH reserve for borrowing', async () => { const {configurator, pool, weth} = testEnv; await configurator.enableBorrowingOnReserve(weth.address, true); - const {borrowingEnabled} = await pool.getReserveConfigurationData(weth.address); const {variableBorrowIndex} = await pool.getReserveData(weth.address); + + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); + expect(variableBorrowIndex.toString()).to.be.equal(RAY); }); From 3fd4003aa039c1aa44673ae8415f1e5a3d05dc6c Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:20:45 +0200 Subject: [PATCH 72/79] Added test on deactivate as collateral --- test/configurator.spec.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index de6fbd76..4253b51f 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -183,8 +183,27 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Deactivates the ETH reserve as collateral', async () => { const {configurator, pool, weth} = testEnv; await configurator.disableReserveAsCollateral(weth.address); - const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(weth.address); - expect(usageAsCollateralEnabled).to.be.equal(false); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(0); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); }); it('Activates the ETH reserve as collateral', async () => { From 35db5833faab26aa2c1e67386b7d3e756546f576 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:27:53 +0200 Subject: [PATCH 73/79] Added test on disable stable borrow rate --- test/configurator.spec.ts | 46 +++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 4253b51f..5b5bbe8c 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -208,10 +208,29 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Activates the ETH reserve as collateral', async () => { const {configurator, pool, weth} = testEnv; - await configurator.enableReserveAsCollateral(weth.address, '75', '80', '105'); + await configurator.enableReserveAsCollateral(weth.address, '7500', '8000', '10500'); - const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(weth.address); - expect(usageAsCollateralEnabled).to.be.equal(true); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); }); it('Check the onlyAaveAdmin on disableReserveAsCollateral ', async () => { @@ -235,8 +254,27 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Disable stable borrow rate on the ETH reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.disableReserveStableRate(weth.address); - const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(weth.address); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(false); + expect(reserveFactor).to.be.equal(0); }); it('Enables stable borrow rate on the ETH reserve', async () => { From b30ccd6dd288e39a2c8a42ee2b71dddfcd0e78ed Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:28:46 +0200 Subject: [PATCH 74/79] Added test on disable stable borrow rate --- test/configurator.spec.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 5b5bbe8c..865e2b8a 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -280,9 +280,27 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Enables stable borrow rate on the ETH reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.enableReserveStableRate(weth.address); - const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(weth.address); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(7500); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(true); - }); + expect(reserveFactor).to.be.equal(0); }); it('Check the onlyAaveAdmin on disableReserveStableRate', async () => { const {configurator, users, weth} = testEnv; From d77e5ce5be2a4814ffa960a7c3634563f555bc9b Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:30:10 +0200 Subject: [PATCH 75/79] Added test on disable stable borrow rate --- test/configurator.spec.ts | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 865e2b8a..6da90661 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -320,10 +320,29 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Changes LTV of the reserve', async () => { const {configurator, pool, weth} = testEnv; - await configurator.setLtv(weth.address, '60'); - const {ltv} = await pool.getReserveConfigurationData(weth.address); - expect(ltv.toString()).to.be.bignumber.equal('60', 'Invalid LTV'); - }); + await configurator.setLtv(weth.address, '6000'); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(6000); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(0); + }); it('Check the onlyAaveAdmin on setLtv', async () => { const {configurator, users, weth} = testEnv; From b88bdc8c2c47930e94b35d23da796bf4573c1bde Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:34:50 +0200 Subject: [PATCH 76/79] updated test on liquidation threshold, reserve factor --- test/configurator.spec.ts | 58 +++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 6da90661..82982ec6 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -300,7 +300,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { expect(liquidationThreshold).to.be.equal(8000); expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(true); - expect(reserveFactor).to.be.equal(0); }); + expect(reserveFactor).to.be.equal(0); + }); it('Check the onlyAaveAdmin on disableReserveStableRate', async () => { const {configurator, users, weth} = testEnv; @@ -321,7 +322,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Changes LTV of the reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.setLtv(weth.address, '6000'); - const { + const { decimals, ltv, liquidationBonus, @@ -342,7 +343,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { expect(liquidationBonus).to.be.equal(10500); expect(stableBorrowRateEnabled).to.be.equal(true); expect(reserveFactor).to.be.equal(0); - }); + }); it('Check the onlyAaveAdmin on setLtv', async () => { const {configurator, users, weth} = testEnv; @@ -355,8 +356,27 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Changes the reserve factor of the reserve', async () => { const {configurator, pool, weth} = testEnv; await configurator.setReserveFactor(weth.address, '1000'); - const {reserveFactor} = await pool.getReserveConfigurationData(weth.address); - expect(reserveFactor.toString()).to.be.bignumber.equal('1000', 'Invalid reserve factor'); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(6000); + expect(liquidationThreshold).to.be.equal(8000); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(1000); }); it('Check the onlyLendingPoolManager on setReserveFactor', async () => { @@ -369,12 +389,28 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Changes liquidation threshold of the reserve', async () => { const {configurator, pool, weth} = testEnv; - await configurator.setLiquidationThreshold(weth.address, '75'); - const {liquidationThreshold} = await pool.getReserveConfigurationData(weth.address); - expect(liquidationThreshold.toString()).to.be.bignumber.equal( - '75', - 'Invalid Liquidation threshold' - ); + await configurator.setLiquidationThreshold(weth.address, '7500'); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(6000); + expect(liquidationThreshold).to.be.equal(7500); + expect(liquidationBonus).to.be.equal(10500); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(1000); }); it('Check the onlyAaveAdmin on setLiquidationThreshold', async () => { From f3852d7081e5bb40e6df84f6b9de83a774f30fde Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 11:36:29 +0200 Subject: [PATCH 77/79] Updated test on liquidation bonus --- test/configurator.spec.ts | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/test/configurator.spec.ts b/test/configurator.spec.ts index 82982ec6..3ed53984 100644 --- a/test/configurator.spec.ts +++ b/test/configurator.spec.ts @@ -423,12 +423,28 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => { it('Changes liquidation bonus of the reserve', async () => { const {configurator, pool, weth} = testEnv; - await configurator.setLiquidationBonus(weth.address, '110'); - const {liquidationBonus} = await pool.getReserveConfigurationData(weth.address); - expect(liquidationBonus.toString()).to.be.bignumber.equal( - '110', - 'Invalid Liquidation discount' - ); + await configurator.setLiquidationBonus(weth.address, '11000'); + const { + decimals, + ltv, + liquidationBonus, + liquidationThreshold, + reserveFactor, + stableBorrowRateEnabled, + borrowingEnabled, + isActive, + isFreezed, + } = await pool.getReserveConfigurationData(weth.address); + + expect(borrowingEnabled).to.be.equal(true); + expect(isActive).to.be.equal(true); + expect(isFreezed).to.be.equal(false); + expect(decimals).to.be.equal(18); + expect(ltv).to.be.equal(6000); + expect(liquidationThreshold).to.be.equal(7500); + expect(liquidationBonus).to.be.equal(11000); + expect(stableBorrowRateEnabled).to.be.equal(true); + expect(reserveFactor).to.be.equal(1000); }); it('Check the onlyAaveAdmin on setLiquidationBonus', async () => { From 24a4980496b5ac5d3cf09b5660560fb320b4aeb2 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 15:51:48 +0200 Subject: [PATCH 78/79] Refactored reservesList to a mapping --- contracts/interfaces/ILendingPool.sol | 2 +- contracts/lendingpool/LendingPool.sol | 45 +++++++++++++------ .../LendingPoolCollateralManager.sol | 9 +++- contracts/lendingpool/LendingPoolStorage.sol | 18 ++------ contracts/libraries/logic/GenericLogic.sol | 10 +++-- contracts/libraries/logic/ValidationLogic.sol | 12 +++-- contracts/misc/AaveProtocolTestHelpers.sol | 4 +- contracts/misc/WalletBalanceProvider.sol | 2 +- deployed-contracts.json | 6 +-- 9 files changed, 65 insertions(+), 43 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 66d4542a..3fc461b6 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -428,7 +428,7 @@ interface ILendingPool { uint256 amount ) external view returns (bool); - function getReserves() external view returns (address[] memory); + function getReservesList() external view returns (address[] memory); /** * @dev Set the _pause state diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 6afb3eed..1a5b8152 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -144,6 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -424,6 +425,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -753,6 +755,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -793,10 +796,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id); } - function getReserves() external override view returns (address[] memory) { - return _reservesList; - } - receive() external payable { revert(); } @@ -889,6 +888,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, userConfig, _reservesList, + _reservesCount, oracle ); @@ -948,16 +948,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @dev adds a reserve to the array of the _reserves address **/ function _addReserveToList(address asset) internal { - bool reserveAlreadyAdded = false; - require(_reservesList.length < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); - for (uint256 i = 0; i < _reservesList.length; i++) - if (_reservesList[i] == asset) { - reserveAlreadyAdded = true; - } - if (!reserveAlreadyAdded) { - _reserves[asset].id = uint8(_reservesList.length); - _reservesList.push(asset); - } + + require(_reservesCount < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); + + _reserves[asset].id = uint8(_reservesCount); + _reservesList[_reservesCount] = asset; + + _reservesCount++; } /** @@ -1004,6 +1001,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); } @@ -1029,4 +1027,23 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage function paused() external override view returns (bool) { return _paused; } + + /** + * @dev returns the list of the initialized reserves + **/ + function getReservesList() external override view returns (address[] memory) { + address[] memory _activeReserves = new address[](_reservesCount); + + for(uint256 i = 0; i < _reservesCount; i++){ + _activeReserves[i] = _reservesList[i]; + } + return _activeReserves; + } + + /** + * @dev returns the addresses provider + **/ + function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { + return _addressesProvider; + } } diff --git a/contracts/lendingpool/LendingPoolCollateralManager.sol b/contracts/lendingpool/LendingPoolCollateralManager.sol index 75f4f659..1e5488a4 100644 --- a/contracts/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/lendingpool/LendingPoolCollateralManager.sol @@ -154,6 +154,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -325,6 +326,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -412,7 +414,11 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor vars.actualAmountToLiquidate, 0 ); - IERC20(principal).safeTransferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate); + IERC20(principal).safeTransferFrom( + receiver, + vars.principalAToken, + vars.actualAmountToLiquidate + ); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( @@ -528,6 +534,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); diff --git a/contracts/lendingpool/LendingPoolStorage.sol b/contracts/lendingpool/LendingPoolStorage.sol index 1f1e6d2e..c2fb6111 100644 --- a/contracts/lendingpool/LendingPoolStorage.sol +++ b/contracts/lendingpool/LendingPoolStorage.sol @@ -18,22 +18,12 @@ contract LendingPoolStorage { // debt token address => user who gives allowance => user who receives allowance => amount mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; - address[] internal _reservesList; + // the list of the available reserves, structured as a mapping for gas savings reasons + mapping(uint256 => address) internal _reservesList; + + uint256 internal _reservesCount; bool internal _flashLiquidationLocked; bool internal _paused; - /** - * @dev returns the list of the initialized reserves - **/ - function getReservesList() external view returns (address[] memory) { - return _reservesList; - } - - /** - * @dev returns the addresses provider - **/ - function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { - return _addressesProvider; - } } diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index d1a7d6ce..5c7dc3dc 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -58,7 +58,8 @@ library GenericLogic { uint256 amount, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map calldata userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view returns (bool) { if (!userConfig.isBorrowingAny() || !userConfig.isUsingAsCollateral(reservesData[asset].id)) { @@ -79,7 +80,7 @@ library GenericLogic { , vars.avgLiquidationThreshold, - ) = calculateUserAccountData(user, reservesData, userConfig, reserves, oracle); + ) = calculateUserAccountData(user, reservesData, userConfig, reserves, reservesCount, oracle); if (vars.borrowBalanceETH == 0) { return true; //no borrows - no reasons to block the transfer @@ -149,7 +150,8 @@ library GenericLogic { address user, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map memory userConfig, - address[] memory reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) internal @@ -167,7 +169,7 @@ library GenericLogic { if (userConfig.isEmpty()) { return (0, 0, 0, 0, uint256(-1)); } - for (vars.i = 0; vars.i < reserves.length; vars.i++) { + for (vars.i = 0; vars.i < reservesCount; vars.i++) { if (!userConfig.isUsingAsCollateralOrBorrowing(vars.i)) { continue; } diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol index 4ffa49f2..ee13232b 100644 --- a/contracts/libraries/logic/ValidationLogic.sol +++ b/contracts/libraries/logic/ValidationLogic.sol @@ -54,7 +54,8 @@ library ValidationLogic { uint256 userBalance, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0); @@ -69,6 +70,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ), Errors.TRANSFER_NOT_ALLOWED @@ -119,7 +121,8 @@ library ValidationLogic { uint256 maxStableLoanPercent, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { ValidateBorrowLocalVars memory vars; @@ -154,6 +157,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ); @@ -298,7 +302,8 @@ library ValidationLogic { address reserveAddress, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender); @@ -313,6 +318,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ), Errors.DEPOSIT_ALREADY_IN_USE diff --git a/contracts/misc/AaveProtocolTestHelpers.sol b/contracts/misc/AaveProtocolTestHelpers.sol index 7b91bec2..75778f42 100644 --- a/contracts/misc/AaveProtocolTestHelpers.sol +++ b/contracts/misc/AaveProtocolTestHelpers.sol @@ -20,7 +20,7 @@ contract AaveProtocolTestHelpers { function getAllReservesTokens() external view returns (TokenData[] memory) { ILendingPool pool = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); TokenData[] memory reservesTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { reservesTokens[i] = TokenData({ @@ -35,7 +35,7 @@ contract AaveProtocolTestHelpers { function getAllATokens() external view returns (TokenData[] memory) { ILendingPool pool = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { (address aTokenAddress, , ) = pool.getReserveTokensAddresses(reserves[i]); diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index c52b5f21..1c46922a 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -86,7 +86,7 @@ contract WalletBalanceProvider { { ILendingPool pool = ILendingPool(_provider.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); uint256[] memory balances = new uint256[](reserves.length); diff --git a/deployed-contracts.json b/deployed-contracts.json index dd305039..ca9221df 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -608,7 +608,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd", + "address": "0xa89E20284Bd638F31b0011D0fC754Fc9d2fa73e3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -636,7 +636,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544", + "address": "0xaA935993065F2dDB1d13623B1941C7AEE3A60F23", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -650,7 +650,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040", + "address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { From 9fdfc8bf26e94ec230889502cc92477dbd37bde7 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 18:20:44 +0200 Subject: [PATCH 79/79] Added check if the reserve was already added --- contracts/lendingpool/LendingPool.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 1a5b8152..6016ee95 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -951,10 +951,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage require(_reservesCount < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); + bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0]==asset; + + if(!reserveAlreadyAdded){ _reserves[asset].id = uint8(_reservesCount); _reservesList[_reservesCount] = asset; _reservesCount++; + } } /**