mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'master' into feat/rm-unused-imports
This commit is contained in:
commit
46bcf4b821
|
@ -3,8 +3,8 @@ pragma solidity ^0.6.8;
|
||||||
|
|
||||||
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
|
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';
|
||||||
import {
|
import {
|
||||||
InitializableAdminUpgradeabilityProxy
|
InitializableImmutableAdminUpgradeabilityProxy
|
||||||
} from '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol';
|
} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
|
||||||
|
|
||||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
|
|
||||||
|
@ -153,14 +153,14 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
||||||
function _updateImpl(bytes32 id, address newAddress) internal {
|
function _updateImpl(bytes32 id, address newAddress) internal {
|
||||||
address payable proxyAddress = payable(_addresses[id]);
|
address payable proxyAddress = payable(_addresses[id]);
|
||||||
|
|
||||||
InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy(
|
InitializableImmutableAdminUpgradeabilityProxy proxy = InitializableImmutableAdminUpgradeabilityProxy(
|
||||||
proxyAddress
|
proxyAddress
|
||||||
);
|
);
|
||||||
bytes memory params = abi.encodeWithSignature('initialize(address)', address(this));
|
bytes memory params = abi.encodeWithSignature('initialize(address)', address(this));
|
||||||
|
|
||||||
if (proxyAddress == address(0)) {
|
if (proxyAddress == address(0)) {
|
||||||
proxy = new InitializableAdminUpgradeabilityProxy();
|
proxy = new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||||
proxy.initialize(newAddress, address(this), params);
|
proxy.initialize(newAddress, params);
|
||||||
_addresses[id] = address(proxy);
|
_addresses[id] = address(proxy);
|
||||||
emit ProxyCreated(id, address(proxy));
|
emit ProxyCreated(id, address(proxy));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
pragma solidity ^0.6.8;
|
pragma solidity ^0.6.8;
|
||||||
|
|
||||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||||
|
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||||
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||||
|
|
||||||
pragma experimental ABIEncoderV2;
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
interface ILendingPool {
|
interface ILendingPool {
|
||||||
|
@ -314,52 +317,6 @@ interface ILendingPool {
|
||||||
bytes calldata params
|
bytes calldata params
|
||||||
) external;
|
) external;
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev accessory functions to fetch data from the core contract
|
|
||||||
**/
|
|
||||||
|
|
||||||
function getReserveConfigurationData(address reserve)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
uint256 decimals,
|
|
||||||
uint256 ltv,
|
|
||||||
uint256 liquidationThreshold,
|
|
||||||
uint256 liquidationBonus,
|
|
||||||
uint256 reserveFactor,
|
|
||||||
address interestRateStrategyAddress,
|
|
||||||
bool usageAsCollateralEnabled,
|
|
||||||
bool borrowingEnabled,
|
|
||||||
bool stableBorrowRateEnabled,
|
|
||||||
bool isActive,
|
|
||||||
bool isFreezed
|
|
||||||
);
|
|
||||||
|
|
||||||
function getReserveTokensAddresses(address reserve)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
address aTokenAddress,
|
|
||||||
address stableDebtTokenAddress,
|
|
||||||
address variableDebtTokenAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
function getReserveData(address reserve)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
uint256 availableLiquidity,
|
|
||||||
uint256 totalStableDebt,
|
|
||||||
uint256 totalVariableDebt,
|
|
||||||
uint256 liquidityRate,
|
|
||||||
uint256 variableBorrowRate,
|
|
||||||
uint256 stableBorrowRate,
|
|
||||||
uint256 averageStableBorrowRate,
|
|
||||||
uint256 liquidityIndex,
|
|
||||||
uint256 variableBorrowIndex,
|
|
||||||
uint40 lastUpdateTimestamp
|
|
||||||
);
|
|
||||||
|
|
||||||
function getUserAccountData(address user)
|
function getUserAccountData(address user)
|
||||||
external
|
external
|
||||||
view
|
view
|
||||||
|
@ -372,21 +329,6 @@ interface ILendingPool {
|
||||||
uint256 healthFactor
|
uint256 healthFactor
|
||||||
);
|
);
|
||||||
|
|
||||||
function getUserReserveData(address reserve, address user)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
uint256 currentATokenBalance,
|
|
||||||
uint256 currentStableDebt,
|
|
||||||
uint256 currentVariableDebt,
|
|
||||||
uint256 principalStableDebt,
|
|
||||||
uint256 scaledVariableDebt,
|
|
||||||
uint256 stableBorrowRate,
|
|
||||||
uint256 liquidityRate,
|
|
||||||
uint40 stableRateLastUpdated,
|
|
||||||
bool usageAsCollateralEnabled
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev initializes a reserve
|
* @dev initializes a reserve
|
||||||
* @param reserve the address of the reserve
|
* @param reserve the address of the reserve
|
||||||
|
@ -417,10 +359,14 @@ interface ILendingPool {
|
||||||
view
|
view
|
||||||
returns (ReserveConfiguration.Map memory);
|
returns (ReserveConfiguration.Map memory);
|
||||||
|
|
||||||
|
function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory);
|
||||||
|
|
||||||
function getReserveNormalizedIncome(address reserve) external view returns (uint256);
|
function getReserveNormalizedIncome(address reserve) external view returns (uint256);
|
||||||
|
|
||||||
function getReserveNormalizedVariableDebt(address reserve) external view returns (uint256);
|
function getReserveNormalizedVariableDebt(address reserve) external view returns (uint256);
|
||||||
|
|
||||||
|
function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
|
||||||
|
|
||||||
function balanceDecreaseAllowed(
|
function balanceDecreaseAllowed(
|
||||||
address reserve,
|
address reserve,
|
||||||
address user,
|
address user,
|
||||||
|
|
|
@ -651,103 +651,36 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev accessory functions to fetch data from the core contract
|
* @dev returns the state and configuration of the reserve
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @return the state of the reserve
|
||||||
**/
|
**/
|
||||||
|
|
||||||
function getReserveConfigurationData(address asset)
|
|
||||||
external
|
|
||||||
override
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
uint256 decimals,
|
|
||||||
uint256 ltv,
|
|
||||||
uint256 liquidationThreshold,
|
|
||||||
uint256 liquidationBonus,
|
|
||||||
uint256 reserveFactor,
|
|
||||||
address interestRateStrategyAddress,
|
|
||||||
bool usageAsCollateralEnabled,
|
|
||||||
bool borrowingEnabled,
|
|
||||||
bool stableBorrowRateEnabled,
|
|
||||||
bool isActive,
|
|
||||||
bool isFreezed
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
|
||||||
|
|
||||||
return (
|
|
||||||
reserve.configuration.getDecimals(),
|
|
||||||
reserve.configuration.getLtv(),
|
|
||||||
reserve.configuration.getLiquidationThreshold(),
|
|
||||||
reserve.configuration.getLiquidationBonus(),
|
|
||||||
reserve.configuration.getReserveFactor(),
|
|
||||||
reserve.interestRateStrategyAddress,
|
|
||||||
reserve.configuration.getLtv() != 0,
|
|
||||||
reserve.configuration.getBorrowingEnabled(),
|
|
||||||
reserve.configuration.getStableRateBorrowingEnabled(),
|
|
||||||
reserve.configuration.getActive(),
|
|
||||||
reserve.configuration.getFrozen()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getReserveTokensAddresses(address asset)
|
|
||||||
external
|
|
||||||
override
|
|
||||||
view
|
|
||||||
returns (
|
|
||||||
address aTokenAddress,
|
|
||||||
address stableDebtTokenAddress,
|
|
||||||
address variableDebtTokenAddress
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
|
||||||
|
|
||||||
return (
|
|
||||||
reserve.aTokenAddress,
|
|
||||||
reserve.stableDebtTokenAddress,
|
|
||||||
reserve.variableDebtTokenAddress
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getReserveData(address asset)
|
function getReserveData(address asset)
|
||||||
external
|
external
|
||||||
override
|
override
|
||||||
view
|
view
|
||||||
returns (
|
returns (ReserveLogic.ReserveData memory)
|
||||||
uint256 availableLiquidity,
|
|
||||||
uint256 totalStableDebt,
|
|
||||||
uint256 totalVariableDebt,
|
|
||||||
uint256 liquidityRate,
|
|
||||||
uint256 variableBorrowRate,
|
|
||||||
uint256 stableBorrowRate,
|
|
||||||
uint256 averageStableBorrowRate,
|
|
||||||
uint256 liquidityIndex,
|
|
||||||
uint256 variableBorrowIndex,
|
|
||||||
uint40 lastUpdateTimestamp
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ReserveLogic.ReserveData memory reserve = _reserves[asset];
|
return _reserves[asset];
|
||||||
|
|
||||||
return (
|
|
||||||
IERC20(asset).balanceOf(reserve.aTokenAddress),
|
|
||||||
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
|
|
||||||
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
|
||||||
reserve.currentLiquidityRate,
|
|
||||||
reserve.currentVariableBorrowRate,
|
|
||||||
reserve.currentStableBorrowRate,
|
|
||||||
IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(),
|
|
||||||
reserve.liquidityIndex,
|
|
||||||
reserve.variableBorrowIndex,
|
|
||||||
reserve.lastUpdateTimestamp
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev returns the user account data across all the reserves
|
||||||
|
* @param user the address of the user
|
||||||
|
* @return totalCollateralETH the total collateral in ETH of the user
|
||||||
|
* @return totalDebtETH the total debt in ETH of the user
|
||||||
|
* @return availableBorrowsETH the borrowing power left of the user
|
||||||
|
* @return currentLiquidationThreshold the liquidation threshold of the user
|
||||||
|
* @return ltv the loan to value of the user
|
||||||
|
* @return healthFactor the current health factor of the user
|
||||||
|
**/
|
||||||
function getUserAccountData(address user)
|
function getUserAccountData(address user)
|
||||||
external
|
external
|
||||||
override
|
override
|
||||||
view
|
view
|
||||||
returns (
|
returns (
|
||||||
uint256 totalCollateralETH,
|
uint256 totalCollateralETH,
|
||||||
uint256 totalBorrowsETH,
|
uint256 totalDebtETH,
|
||||||
uint256 availableBorrowsETH,
|
uint256 availableBorrowsETH,
|
||||||
uint256 currentLiquidationThreshold,
|
uint256 currentLiquidationThreshold,
|
||||||
uint256 ltv,
|
uint256 ltv,
|
||||||
|
@ -756,7 +689,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
totalCollateralETH,
|
totalCollateralETH,
|
||||||
totalBorrowsETH,
|
totalDebtETH,
|
||||||
ltv,
|
ltv,
|
||||||
currentLiquidationThreshold,
|
currentLiquidationThreshold,
|
||||||
healthFactor
|
healthFactor
|
||||||
|
@ -771,41 +704,117 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
|
|
||||||
availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
|
availableBorrowsETH = GenericLogic.calculateAvailableBorrowsETH(
|
||||||
totalCollateralETH,
|
totalCollateralETH,
|
||||||
totalBorrowsETH,
|
totalDebtETH,
|
||||||
ltv
|
ltv
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUserReserveData(address asset, address user)
|
/**
|
||||||
|
* @dev returns the configuration of the reserve
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @return the configuration of the reserve
|
||||||
|
**/
|
||||||
|
function getConfiguration(address asset)
|
||||||
external
|
external
|
||||||
override
|
override
|
||||||
view
|
view
|
||||||
returns (
|
returns (ReserveConfiguration.Map memory)
|
||||||
uint256 currentATokenBalance,
|
|
||||||
uint256 currentStableDebt,
|
|
||||||
uint256 currentVariableDebt,
|
|
||||||
uint256 principalStableDebt,
|
|
||||||
uint256 scaledVariableDebt,
|
|
||||||
uint256 stableBorrowRate,
|
|
||||||
uint256 liquidityRate,
|
|
||||||
uint40 stableRateLastUpdated,
|
|
||||||
bool usageAsCollateralEnabled
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
return _reserves[asset].configuration;
|
||||||
|
|
||||||
currentATokenBalance = IERC20(reserve.aTokenAddress).balanceOf(user);
|
|
||||||
(currentStableDebt, currentVariableDebt) = Helpers.getUserCurrentDebt(user, reserve);
|
|
||||||
principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user);
|
|
||||||
scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user);
|
|
||||||
liquidityRate = reserve.currentLiquidityRate;
|
|
||||||
stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user);
|
|
||||||
stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated(
|
|
||||||
user
|
|
||||||
);
|
|
||||||
usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev returns the configuration of the user across all the reserves
|
||||||
|
* @param user the user
|
||||||
|
* @return the configuration of the user
|
||||||
|
**/
|
||||||
|
function getUserConfiguration(address user)
|
||||||
|
external
|
||||||
|
override
|
||||||
|
view
|
||||||
|
returns (UserConfiguration.Map memory)
|
||||||
|
{
|
||||||
|
return _usersConfig[user];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev returns the normalized income per unit of asset
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @return the reserve normalized income
|
||||||
|
*/
|
||||||
|
function getReserveNormalizedIncome(address asset) external override view returns (uint256) {
|
||||||
|
return _reserves[asset].getNormalizedIncome();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev returns the normalized variable debt per unit of asset
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @return the reserve normalized debt
|
||||||
|
*/
|
||||||
|
function getReserveNormalizedVariableDebt(address asset)
|
||||||
|
external
|
||||||
|
override
|
||||||
|
view
|
||||||
|
returns (uint256)
|
||||||
|
{
|
||||||
|
return _reserves[asset].getNormalizedDebt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns if the LendingPool is paused
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev validate if a balance decrease for an asset is allowed
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @param user the user related to the balance decrease
|
||||||
|
* @param amount the amount being transferred/redeemed
|
||||||
|
* @return true if the balance decrease can be allowed, false otherwise
|
||||||
|
*/
|
||||||
|
function balanceDecreaseAllowed(
|
||||||
|
address asset,
|
||||||
|
address user,
|
||||||
|
uint256 amount
|
||||||
|
) external override view returns (bool) {
|
||||||
|
_whenNotPaused();
|
||||||
|
return
|
||||||
|
GenericLogic.balanceDecreaseAllowed(
|
||||||
|
asset,
|
||||||
|
user,
|
||||||
|
amount,
|
||||||
|
_reserves,
|
||||||
|
_usersConfig[user],
|
||||||
|
_reservesList,
|
||||||
|
_reservesCount,
|
||||||
|
_addressesProvider.getPriceOracle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev avoids direct transfers of ETH
|
||||||
|
**/
|
||||||
receive() external payable {
|
receive() external payable {
|
||||||
revert();
|
revert();
|
||||||
}
|
}
|
||||||
|
@ -838,7 +847,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
* @param asset the address of the reserve
|
* @param asset the address of the reserve
|
||||||
* @param rateStrategyAddress the address of the interest rate strategy contract
|
* @param rateStrategyAddress the address of the interest rate strategy contract
|
||||||
**/
|
**/
|
||||||
|
|
||||||
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
|
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
|
||||||
external
|
external
|
||||||
override
|
override
|
||||||
|
@ -847,22 +855,32 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
_reserves[asset].interestRateStrategyAddress = rateStrategyAddress;
|
_reserves[asset].interestRateStrategyAddress = rateStrategyAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev sets the configuration map of the reserve
|
||||||
|
* @param asset the address of the reserve
|
||||||
|
* @param configuration the configuration map
|
||||||
|
**/
|
||||||
function setConfiguration(address asset, uint256 configuration) external override {
|
function setConfiguration(address asset, uint256 configuration) external override {
|
||||||
_onlyLendingPoolConfigurator();
|
_onlyLendingPoolConfigurator();
|
||||||
_reserves[asset].configuration.data = configuration;
|
_reserves[asset].configuration.data = configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConfiguration(address asset)
|
/**
|
||||||
external
|
* @dev Set the _pause state
|
||||||
override
|
* @param val the boolean value to set the current pause state of LendingPool
|
||||||
view
|
*/
|
||||||
returns (ReserveConfiguration.Map memory)
|
function setPause(bool val) external override {
|
||||||
{
|
_onlyLendingPoolConfigurator();
|
||||||
return _reserves[asset].configuration;
|
|
||||||
|
_paused = val;
|
||||||
|
if (_paused) {
|
||||||
|
emit Paused();
|
||||||
|
} else {
|
||||||
|
emit Unpaused();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// internal functions
|
// internal functions
|
||||||
|
|
||||||
struct ExecuteBorrowParams {
|
struct ExecuteBorrowParams {
|
||||||
address asset;
|
address asset;
|
||||||
address user;
|
address user;
|
||||||
|
@ -969,94 +987,4 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
_reservesCount++;
|
_reservesCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev returns the normalized income per unit of asset
|
|
||||||
* @param asset the address of the reserve
|
|
||||||
* @return the reserve normalized income
|
|
||||||
*/
|
|
||||||
function getReserveNormalizedIncome(address asset) external override view returns (uint256) {
|
|
||||||
return _reserves[asset].getNormalizedIncome();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev returns the normalized variable debt per unit of asset
|
|
||||||
* @param asset the address of the reserve
|
|
||||||
* @return the reserve normalized debt
|
|
||||||
*/
|
|
||||||
function getReserveNormalizedVariableDebt(address asset)
|
|
||||||
external
|
|
||||||
override
|
|
||||||
view
|
|
||||||
returns (uint256)
|
|
||||||
{
|
|
||||||
return _reserves[asset].getNormalizedDebt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev validate if a balance decrease for an asset is allowed
|
|
||||||
* @param asset the address of the reserve
|
|
||||||
* @param user the user related to the balance decrease
|
|
||||||
* @param amount the amount being transferred/redeemed
|
|
||||||
* @return true if the balance decrease can be allowed, false otherwise
|
|
||||||
*/
|
|
||||||
function balanceDecreaseAllowed(
|
|
||||||
address asset,
|
|
||||||
address user,
|
|
||||||
uint256 amount
|
|
||||||
) external override view returns (bool) {
|
|
||||||
_whenNotPaused();
|
|
||||||
return
|
|
||||||
GenericLogic.balanceDecreaseAllowed(
|
|
||||||
asset,
|
|
||||||
user,
|
|
||||||
amount,
|
|
||||||
_reserves,
|
|
||||||
_usersConfig[user],
|
|
||||||
_reservesList,
|
|
||||||
_reservesCount,
|
|
||||||
_addressesProvider.getPriceOracle()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Set the _pause state
|
|
||||||
* @param val the boolean value to set the current pause state of LendingPool
|
|
||||||
*/
|
|
||||||
function setPause(bool val) external override {
|
|
||||||
_onlyLendingPoolConfigurator();
|
|
||||||
|
|
||||||
_paused = val;
|
|
||||||
if (_paused) {
|
|
||||||
emit Paused();
|
|
||||||
} else {
|
|
||||||
emit Unpaused();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Returns if the LendingPool is paused
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,7 +578,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
|
||||||
vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
|
vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
|
||||||
vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
|
vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
|
||||||
|
|
||||||
(, , vars.liquidationBonus, vars.collateralDecimals) = collateralReserve
|
(, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
|
||||||
.configuration
|
.configuration
|
||||||
.getParams();
|
.getParams();
|
||||||
vars.principalDecimals = principalReserve.configuration.getDecimals();
|
vars.principalDecimals = principalReserve.configuration.getDecimals();
|
||||||
|
|
|
@ -7,13 +7,14 @@ import {
|
||||||
VersionedInitializable
|
VersionedInitializable
|
||||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||||
import {
|
import {
|
||||||
InitializableAdminUpgradeabilityProxy
|
InitializableImmutableAdminUpgradeabilityProxy
|
||||||
} from '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol';
|
} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
|
||||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||||
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
||||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||||
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title LendingPoolConfigurator contract
|
* @title LendingPoolConfigurator contract
|
||||||
|
@ -260,11 +261,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
* @param implementation the address of the new aToken implementation
|
* @param implementation the address of the new aToken implementation
|
||||||
**/
|
**/
|
||||||
function updateAToken(address asset, address implementation) external onlyAaveAdmin {
|
function updateAToken(address asset, address implementation) external onlyAaveAdmin {
|
||||||
(address aTokenAddress, , ) = pool.getReserveTokensAddresses(asset);
|
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||||
|
|
||||||
_upgradeTokenImplementation(asset, aTokenAddress, implementation);
|
_upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
|
||||||
|
|
||||||
emit ATokenUpgraded(asset, aTokenAddress, implementation);
|
emit ATokenUpgraded(asset, reserveData.aTokenAddress, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,11 +274,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
* @param implementation the address of the new aToken implementation
|
* @param implementation the address of the new aToken implementation
|
||||||
**/
|
**/
|
||||||
function updateStableDebtToken(address asset, address implementation) external onlyAaveAdmin {
|
function updateStableDebtToken(address asset, address implementation) external onlyAaveAdmin {
|
||||||
(, address stableDebtToken, ) = pool.getReserveTokensAddresses(asset);
|
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||||
|
|
||||||
_upgradeTokenImplementation(asset, stableDebtToken, implementation);
|
_upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||||
|
|
||||||
emit StableDebtTokenUpgraded(asset, stableDebtToken, implementation);
|
emit StableDebtTokenUpgraded(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,11 +287,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
* @param implementation the address of the new aToken implementation
|
* @param implementation the address of the new aToken implementation
|
||||||
**/
|
**/
|
||||||
function updateVariableDebtToken(address asset, address implementation) external onlyAaveAdmin {
|
function updateVariableDebtToken(address asset, address implementation) external onlyAaveAdmin {
|
||||||
(, , address variableDebtToken) = pool.getReserveTokensAddresses(asset);
|
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||||
|
|
||||||
_upgradeTokenImplementation(asset, variableDebtToken, implementation);
|
_upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||||
|
|
||||||
emit VariableDebtTokenUpgraded(asset, variableDebtToken, implementation);
|
emit VariableDebtTokenUpgraded(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -410,20 +411,12 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
* @param asset the address of the reserve
|
* @param asset the address of the reserve
|
||||||
**/
|
**/
|
||||||
function deactivateReserve(address asset) external onlyAaveAdmin {
|
function deactivateReserve(address asset) external onlyAaveAdmin {
|
||||||
(
|
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||||
uint256 availableLiquidity,
|
|
||||||
uint256 totalStableDebt,
|
uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress);
|
||||||
uint256 totalVariableDebt,
|
|
||||||
,
|
|
||||||
,
|
|
||||||
,
|
|
||||||
,
|
|
||||||
,
|
|
||||||
,
|
|
||||||
|
|
||||||
) = pool.getReserveData(asset);
|
|
||||||
require(
|
require(
|
||||||
availableLiquidity == 0 && totalStableDebt == 0 && totalVariableDebt == 0,
|
availableLiquidity == 0 && reserveData.currentLiquidityRate == 0,
|
||||||
Errors.RESERVE_LIQUIDITY_NOT_0
|
Errors.RESERVE_LIQUIDITY_NOT_0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -558,7 +551,9 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
* @param decimals the decimals of the token
|
* @param decimals the decimals of the token
|
||||||
**/
|
**/
|
||||||
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
|
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
|
||||||
InitializableAdminUpgradeabilityProxy proxy = new InitializableAdminUpgradeabilityProxy();
|
|
||||||
|
InitializableImmutableAdminUpgradeabilityProxy proxy
|
||||||
|
= new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||||
|
|
||||||
bytes memory params = abi.encodeWithSignature(
|
bytes memory params = abi.encodeWithSignature(
|
||||||
'initialize(uint8,string,string)',
|
'initialize(uint8,string,string)',
|
||||||
|
@ -567,7 +562,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
IERC20Detailed(implementation).symbol()
|
IERC20Detailed(implementation).symbol()
|
||||||
);
|
);
|
||||||
|
|
||||||
proxy.initialize(implementation, address(this), params);
|
proxy.initialize(implementation, params);
|
||||||
|
|
||||||
return address(proxy);
|
return address(proxy);
|
||||||
}
|
}
|
||||||
|
@ -577,11 +572,13 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
||||||
address proxyAddress,
|
address proxyAddress,
|
||||||
address implementation
|
address implementation
|
||||||
) internal {
|
) internal {
|
||||||
InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy(
|
|
||||||
payable(proxyAddress)
|
|
||||||
);
|
|
||||||
|
|
||||||
(uint256 decimals, , , , , , , , , , ) = pool.getReserveConfigurationData(asset);
|
InitializableImmutableAdminUpgradeabilityProxy proxy
|
||||||
|
= InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
|
||||||
|
|
||||||
|
ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset);
|
||||||
|
|
||||||
|
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||||
|
|
||||||
bytes memory params = abi.encodeWithSignature(
|
bytes memory params = abi.encodeWithSignature(
|
||||||
'initialize(uint8,string,string)',
|
'initialize(uint8,string,string)',
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
// SPDX-License-Identifier: agpl-3.0
|
||||||
|
pragma solidity ^0.6.8;
|
||||||
|
|
||||||
|
import '../openzeppelin-upgradeability/BaseUpgradeabilityProxy.sol';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title BaseImmutableAdminUpgradeabilityProxy
|
||||||
|
* @author Aave, inspired by the OpenZeppelin upgradeability proxy pattern
|
||||||
|
* @dev This contract combines an upgradeability proxy with an authorization
|
||||||
|
* mechanism for administrative tasks. The admin role is stored in an immutable, which
|
||||||
|
* helps saving transactions costs
|
||||||
|
* All external functions in this contract must be guarded by the
|
||||||
|
* `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity
|
||||||
|
* feature proposal that would enable this to be done automatically.
|
||||||
|
*/
|
||||||
|
contract BaseImmutableAdminUpgradeabilityProxy is BaseUpgradeabilityProxy {
|
||||||
|
|
||||||
|
address immutable ADMIN;
|
||||||
|
|
||||||
|
constructor(address admin) public {
|
||||||
|
ADMIN = admin;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifier ifAdmin() {
|
||||||
|
if (msg.sender == ADMIN) {
|
||||||
|
_;
|
||||||
|
} else {
|
||||||
|
_fallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The address of the proxy admin.
|
||||||
|
*/
|
||||||
|
function admin() external ifAdmin returns (address) {
|
||||||
|
return ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The address of the implementation.
|
||||||
|
*/
|
||||||
|
function implementation() external ifAdmin returns (address) {
|
||||||
|
return _implementation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Upgrade the backing implementation of the proxy.
|
||||||
|
* Only the admin can call this function.
|
||||||
|
* @param newImplementation Address of the new implementation.
|
||||||
|
*/
|
||||||
|
function upgradeTo(address newImplementation) external ifAdmin {
|
||||||
|
_upgradeTo(newImplementation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Upgrade the backing implementation of the proxy and call a function
|
||||||
|
* on the new implementation.
|
||||||
|
* This is useful to initialize the proxied contract.
|
||||||
|
* @param newImplementation Address of the new implementation.
|
||||||
|
* @param data Data to send as msg.data in the low level call.
|
||||||
|
* It should include the signature and the parameters of the function to be called, as described in
|
||||||
|
* https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
|
||||||
|
*/
|
||||||
|
function upgradeToAndCall(address newImplementation, bytes calldata data)
|
||||||
|
external
|
||||||
|
payable
|
||||||
|
ifAdmin
|
||||||
|
{
|
||||||
|
_upgradeTo(newImplementation);
|
||||||
|
(bool success, ) = newImplementation.delegatecall(data);
|
||||||
|
require(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Only fall back when the sender is not the admin.
|
||||||
|
*/
|
||||||
|
function _willFallback() internal virtual override {
|
||||||
|
require(msg.sender != ADMIN, 'Cannot call fallback function from the proxy admin');
|
||||||
|
super._willFallback();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
// SPDX-License-Identifier: agpl-3.0
|
||||||
|
pragma solidity ^0.6.8;
|
||||||
|
|
||||||
|
import './BaseImmutableAdminUpgradeabilityProxy.sol';
|
||||||
|
import '../openzeppelin-upgradeability/InitializableUpgradeabilityProxy.sol';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title InitializableAdminUpgradeabilityProxy
|
||||||
|
* @dev Extends from BaseAdminUpgradeabilityProxy with an initializer for
|
||||||
|
* initializing the implementation, admin, and init data.
|
||||||
|
*/
|
||||||
|
contract InitializableImmutableAdminUpgradeabilityProxy is
|
||||||
|
BaseImmutableAdminUpgradeabilityProxy,
|
||||||
|
InitializableUpgradeabilityProxy
|
||||||
|
{
|
||||||
|
|
||||||
|
constructor(address admin) public BaseImmutableAdminUpgradeabilityProxy(admin) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Only fall back when the sender is not the admin.
|
||||||
|
*/
|
||||||
|
function _willFallback() internal override(BaseImmutableAdminUpgradeabilityProxy, Proxy) {
|
||||||
|
BaseImmutableAdminUpgradeabilityProxy._willFallback();
|
||||||
|
}
|
||||||
|
}
|
|
@ -276,6 +276,7 @@ library ReserveConfiguration {
|
||||||
uint256,
|
uint256,
|
||||||
uint256,
|
uint256,
|
||||||
uint256,
|
uint256,
|
||||||
|
uint256,
|
||||||
uint256
|
uint256
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -285,7 +286,57 @@ library ReserveConfiguration {
|
||||||
dataLocal & ~LTV_MASK,
|
dataLocal & ~LTV_MASK,
|
||||||
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
|
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
|
||||||
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
|
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
|
||||||
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION
|
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
|
||||||
|
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev gets the configuration paramters of the reserve from a memory object
|
||||||
|
* @param self the reserve configuration
|
||||||
|
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
||||||
|
**/
|
||||||
|
function getParamsMemory(ReserveConfiguration.Map memory self)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (
|
||||||
|
uint256,
|
||||||
|
uint256,
|
||||||
|
uint256,
|
||||||
|
uint256,
|
||||||
|
uint256
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
self.data & ~LTV_MASK,
|
||||||
|
(self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
|
||||||
|
(self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
|
||||||
|
(self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
|
||||||
|
(self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev gets the configuration flags of the reserve from a memory object
|
||||||
|
* @param self the reserve configuration
|
||||||
|
* @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled
|
||||||
|
**/
|
||||||
|
function getFlagsMemory(ReserveConfiguration.Map memory self)
|
||||||
|
internal
|
||||||
|
pure
|
||||||
|
returns (
|
||||||
|
bool,
|
||||||
|
bool,
|
||||||
|
bool,
|
||||||
|
bool
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(self.data & ~ACTIVE_MASK) >> IS_ACTIVE_START_BIT_POSITION != 0,
|
||||||
|
(self.data & ~FROZEN_MASK) >> IS_FROZEN_START_BIT_POSITION != 0,
|
||||||
|
(self.data & ~BORROWING_MASK) >> BORROWING_ENABLED_START_BIT_POSITION != 0,
|
||||||
|
(self.data & ~STABLE_BORROWING_MASK) >> STABLE_BORROWING_ENABLED_START_BIT_POSITION != 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ library GenericLogic {
|
||||||
|
|
||||||
balanceDecreaseAllowedLocalVars memory vars;
|
balanceDecreaseAllowedLocalVars memory vars;
|
||||||
|
|
||||||
(, vars.liquidationThreshold, , vars.decimals) = reservesData[asset].configuration.getParams();
|
(, vars.liquidationThreshold, , vars.decimals, ) = reservesData[asset].configuration.getParams();
|
||||||
|
|
||||||
if (vars.liquidationThreshold == 0) {
|
if (vars.liquidationThreshold == 0) {
|
||||||
return true; //if reserve is not used as collateral, no reasons to block the transfer
|
return true; //if reserve is not used as collateral, no reasons to block the transfer
|
||||||
|
@ -177,7 +177,7 @@ library GenericLogic {
|
||||||
vars.currentReserveAddress = reserves[vars.i];
|
vars.currentReserveAddress = reserves[vars.i];
|
||||||
ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
||||||
|
|
||||||
(vars.ltv, vars.liquidationThreshold, , vars.decimals) = currentReserve
|
(vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve
|
||||||
.configuration
|
.configuration
|
||||||
.getParams();
|
.getParams();
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,16 @@ pragma experimental ABIEncoderV2;
|
||||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
||||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||||
|
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||||
|
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||||
|
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||||
|
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||||
|
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||||
|
|
||||||
contract AaveProtocolTestHelpers {
|
contract AaveProtocolTestHelpers {
|
||||||
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||||
|
using UserConfiguration for UserConfiguration.Map;
|
||||||
|
|
||||||
struct TokenData {
|
struct TokenData {
|
||||||
string symbol;
|
string symbol;
|
||||||
address tokenAddress;
|
address tokenAddress;
|
||||||
|
@ -38,12 +46,128 @@ contract AaveProtocolTestHelpers {
|
||||||
address[] memory reserves = pool.getReservesList();
|
address[] memory reserves = pool.getReservesList();
|
||||||
TokenData[] memory aTokens = new TokenData[](reserves.length);
|
TokenData[] memory aTokens = new TokenData[](reserves.length);
|
||||||
for (uint256 i = 0; i < reserves.length; i++) {
|
for (uint256 i = 0; i < reserves.length; i++) {
|
||||||
(address aTokenAddress, , ) = pool.getReserveTokensAddresses(reserves[i]);
|
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
|
||||||
aTokens[i] = TokenData({
|
aTokens[i] = TokenData({
|
||||||
symbol: IERC20Detailed(aTokenAddress).symbol(),
|
symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(),
|
||||||
tokenAddress: aTokenAddress
|
tokenAddress: reserveData.aTokenAddress
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return aTokens;
|
return aTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReserveConfigurationData(address asset)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
uint256 decimals,
|
||||||
|
uint256 ltv,
|
||||||
|
uint256 liquidationThreshold,
|
||||||
|
uint256 liquidationBonus,
|
||||||
|
uint256 reserveFactor,
|
||||||
|
bool usageAsCollateralEnabled,
|
||||||
|
bool borrowingEnabled,
|
||||||
|
bool stableBorrowRateEnabled,
|
||||||
|
bool isActive,
|
||||||
|
bool isFrozen
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReserveConfiguration.Map memory configuration = ILendingPool(
|
||||||
|
ADDRESSES_PROVIDER.getLendingPool()
|
||||||
|
)
|
||||||
|
.getConfiguration(asset);
|
||||||
|
|
||||||
|
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
|
||||||
|
.getParamsMemory();
|
||||||
|
|
||||||
|
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) = configuration
|
||||||
|
.getFlagsMemory();
|
||||||
|
|
||||||
|
usageAsCollateralEnabled = liquidationThreshold > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReserveData(address asset)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
uint256 availableLiquidity,
|
||||||
|
uint256 totalStableDebt,
|
||||||
|
uint256 totalVariableDebt,
|
||||||
|
uint256 liquidityRate,
|
||||||
|
uint256 variableBorrowRate,
|
||||||
|
uint256 stableBorrowRate,
|
||||||
|
uint256 averageStableBorrowRate,
|
||||||
|
uint256 liquidityIndex,
|
||||||
|
uint256 variableBorrowIndex,
|
||||||
|
uint40 lastUpdateTimestamp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||||
|
.getReserveData(asset);
|
||||||
|
|
||||||
|
return (
|
||||||
|
IERC20Detailed(asset).balanceOf(reserve.aTokenAddress),
|
||||||
|
IERC20Detailed(reserve.stableDebtTokenAddress).totalSupply(),
|
||||||
|
IERC20Detailed(reserve.variableDebtTokenAddress).totalSupply(),
|
||||||
|
reserve.currentLiquidityRate,
|
||||||
|
reserve.currentVariableBorrowRate,
|
||||||
|
reserve.currentStableBorrowRate,
|
||||||
|
IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(),
|
||||||
|
reserve.liquidityIndex,
|
||||||
|
reserve.variableBorrowIndex,
|
||||||
|
reserve.lastUpdateTimestamp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUserReserveData(address asset, address user)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
uint256 currentATokenBalance,
|
||||||
|
uint256 currentStableDebt,
|
||||||
|
uint256 currentVariableDebt,
|
||||||
|
uint256 principalStableDebt,
|
||||||
|
uint256 scaledVariableDebt,
|
||||||
|
uint256 stableBorrowRate,
|
||||||
|
uint256 liquidityRate,
|
||||||
|
uint40 stableRateLastUpdated,
|
||||||
|
bool usageAsCollateralEnabled
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||||
|
.getReserveData(asset);
|
||||||
|
|
||||||
|
UserConfiguration.Map memory userConfig = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||||
|
.getUserConfiguration(user);
|
||||||
|
|
||||||
|
currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user);
|
||||||
|
currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user);
|
||||||
|
currentStableDebt = IERC20Detailed(reserve.stableDebtTokenAddress).balanceOf(user);
|
||||||
|
principalStableDebt = IStableDebtToken(reserve.stableDebtTokenAddress).principalBalanceOf(user);
|
||||||
|
scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress).scaledBalanceOf(user);
|
||||||
|
liquidityRate = reserve.currentLiquidityRate;
|
||||||
|
stableBorrowRate = IStableDebtToken(reserve.stableDebtTokenAddress).getUserStableRate(user);
|
||||||
|
stableRateLastUpdated = IStableDebtToken(reserve.stableDebtTokenAddress).getUserLastUpdated(
|
||||||
|
user
|
||||||
|
);
|
||||||
|
usageAsCollateralEnabled = userConfig.isUsingAsCollateral(reserve.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReserveTokensAddresses(address asset)
|
||||||
|
external
|
||||||
|
view
|
||||||
|
returns (
|
||||||
|
address aTokenAddress,
|
||||||
|
address stableDebtTokenAddress,
|
||||||
|
address variableDebtTokenAddress
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||||
|
.getReserveData(asset);
|
||||||
|
|
||||||
|
return (
|
||||||
|
reserve.aTokenAddress,
|
||||||
|
reserve.stableDebtTokenAddress,
|
||||||
|
reserve.variableDebtTokenAddress
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
// SPDX-License-Identifier: agpl-3.0
|
// SPDX-License-Identifier: agpl-3.0
|
||||||
pragma solidity ^0.6.8;
|
pragma solidity ^0.6.8;
|
||||||
|
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
||||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
|
|
||||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
|
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title WalletBalanceProvider contract
|
* @title WalletBalanceProvider contract
|
||||||
|
@ -19,6 +22,7 @@ contract WalletBalanceProvider {
|
||||||
using Address for address payable;
|
using Address for address payable;
|
||||||
using Address for address;
|
using Address for address;
|
||||||
using SafeERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||||
|
|
||||||
LendingPoolAddressesProvider internal immutable _provider;
|
LendingPoolAddressesProvider internal immutable _provider;
|
||||||
|
|
||||||
|
@ -91,7 +95,9 @@ contract WalletBalanceProvider {
|
||||||
uint256[] memory balances = new uint256[](reserves.length);
|
uint256[] memory balances = new uint256[](reserves.length);
|
||||||
|
|
||||||
for (uint256 j = 0; j < reserves.length; j++) {
|
for (uint256 j = 0; j < reserves.length; j++) {
|
||||||
(, , , , , , , , , bool isActive, ) = pool.getReserveConfigurationData(reserves[j]);
|
ReserveConfiguration.Map memory configuration = pool.getConfiguration(reserves[j]);
|
||||||
|
|
||||||
|
(bool isActive, , , ) = configuration.getFlagsMemory();
|
||||||
|
|
||||||
if (!isActive) {
|
if (!isActive) {
|
||||||
balances[j] = 0;
|
balances[j] = 0;
|
||||||
|
|
|
@ -161,7 +161,7 @@
|
||||||
},
|
},
|
||||||
"DefaultReserveInterestRateStrategy": {
|
"DefaultReserveInterestRateStrategy": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0x626FdE749F9d499d3777320CAf29484B624ab84a",
|
"address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6",
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
|
@ -220,7 +220,7 @@
|
||||||
},
|
},
|
||||||
"MockFlashLoanReceiver": {
|
"MockFlashLoanReceiver": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
|
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
"address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
|
"address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
|
||||||
|
@ -231,7 +231,7 @@
|
||||||
},
|
},
|
||||||
"WalletBalanceProvider": {
|
"WalletBalanceProvider": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10",
|
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4",
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
|
@ -567,7 +567,7 @@
|
||||||
},
|
},
|
||||||
"AaveProtocolTestHelpers": {
|
"AaveProtocolTestHelpers": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
|
"address": "0xe7536f450378748E1BD4645D3c77ec38e0F3ba28"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
|
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
|
||||||
|
@ -578,7 +578,7 @@
|
||||||
},
|
},
|
||||||
"StableDebtToken": {
|
"StableDebtToken": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6",
|
"address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
|
@ -592,7 +592,7 @@
|
||||||
},
|
},
|
||||||
"VariableDebtToken": {
|
"VariableDebtToken": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
|
"address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"localhost": {
|
"localhost": {
|
||||||
|
@ -610,7 +610,7 @@
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
|
"address": "0x5f7134cd38C826a7649f9Cc47dda24d834DD2967",
|
||||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||||
},
|
},
|
||||||
"coverage": {
|
"coverage": {
|
||||||
|
@ -676,7 +676,7 @@
|
||||||
},
|
},
|
||||||
"MockSwapAdapter": {
|
"MockSwapAdapter": {
|
||||||
"buidlerevm": {
|
"buidlerevm": {
|
||||||
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2"
|
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
|
||||||
},
|
},
|
||||||
"coverage": {
|
"coverage": {
|
||||||
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2"
|
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2"
|
||||||
|
|
|
@ -755,6 +755,7 @@ export const initReserves = async (
|
||||||
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
||||||
lendingPoolAddressesProvider: LendingPoolAddressesProvider,
|
lendingPoolAddressesProvider: LendingPoolAddressesProvider,
|
||||||
lendingPool: LendingPool,
|
lendingPool: LendingPool,
|
||||||
|
helpers: AaveProtocolTestHelpers,
|
||||||
lendingPoolConfigurator: LendingPoolConfigurator,
|
lendingPoolConfigurator: LendingPoolConfigurator,
|
||||||
aavePool: AavePools,
|
aavePool: AavePools,
|
||||||
incentivesController: tEthereumAddress,
|
incentivesController: tEthereumAddress,
|
||||||
|
@ -776,9 +777,7 @@ export const initReserves = async (
|
||||||
assetAddressIndex
|
assetAddressIndex
|
||||||
];
|
];
|
||||||
|
|
||||||
const {isActive: reserveInitialized} = await lendingPool.getReserveConfigurationData(
|
const {isActive: reserveInitialized} = await helpers.getReserveConfigurationData(tokenAddress);
|
||||||
tokenAddress
|
|
||||||
);
|
|
||||||
|
|
||||||
if (reserveInitialized) {
|
if (reserveInitialized) {
|
||||||
console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
|
console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import {iMultiPoolsAssets, IReserveParams, tEthereumAddress} from './types';
|
import {iMultiPoolsAssets, IReserveParams, tEthereumAddress} from './types';
|
||||||
import {LendingPool} from '../types/LendingPool';
|
import {LendingPool} from '../types/LendingPool';
|
||||||
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
|
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
|
||||||
|
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
|
||||||
|
|
||||||
export const enableReservesToBorrow = async (
|
export const enableReservesToBorrow = async (
|
||||||
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
||||||
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
||||||
lendingPool: LendingPool,
|
helpers: AaveProtocolTestHelpers,
|
||||||
lendingPoolConfigurator: LendingPoolConfigurator
|
lendingPoolConfigurator: LendingPoolConfigurator
|
||||||
) => {
|
) => {
|
||||||
for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries(
|
for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries(
|
||||||
|
@ -19,9 +20,9 @@ export const enableReservesToBorrow = async (
|
||||||
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
||||||
assetAddressIndex
|
assetAddressIndex
|
||||||
];
|
];
|
||||||
const {
|
const {borrowingEnabled: borrowingAlreadyEnabled} = await helpers.getReserveConfigurationData(
|
||||||
borrowingEnabled: borrowingAlreadyEnabled,
|
tokenAddress
|
||||||
} = await lendingPool.getReserveConfigurationData(tokenAddress);
|
);
|
||||||
|
|
||||||
if (borrowingAlreadyEnabled) {
|
if (borrowingAlreadyEnabled) {
|
||||||
console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`);
|
console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`);
|
||||||
|
@ -40,7 +41,7 @@ export const enableReservesToBorrow = async (
|
||||||
export const enableReservesAsCollateral = async (
|
export const enableReservesAsCollateral = async (
|
||||||
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
||||||
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
||||||
lendingPool: LendingPool,
|
helpers: AaveProtocolTestHelpers,
|
||||||
lendingPoolConfigurator: LendingPoolConfigurator
|
lendingPoolConfigurator: LendingPoolConfigurator
|
||||||
) => {
|
) => {
|
||||||
for (const [
|
for (const [
|
||||||
|
@ -55,9 +56,9 @@ export const enableReservesAsCollateral = async (
|
||||||
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
||||||
assetAddressIndex
|
assetAddressIndex
|
||||||
];
|
];
|
||||||
const {
|
const {usageAsCollateralEnabled: alreadyEnabled} = await helpers.getReserveConfigurationData(
|
||||||
usageAsCollateralEnabled: alreadyEnabled,
|
tokenAddress
|
||||||
} = await lendingPool.getReserveConfigurationData(tokenAddress);
|
);
|
||||||
|
|
||||||
if (alreadyEnabled) {
|
if (alreadyEnabled) {
|
||||||
console.log(`Reserve ${assetSymbol} is already enabled as collateral, skipping`);
|
console.log(`Reserve ${assetSymbol} is already enabled as collateral, skipping`);
|
||||||
|
|
|
@ -35,6 +35,8 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
filterMapBy(allTokenAddresses, (key: string) => !key.includes('UNI'))
|
filterMapBy(allTokenAddresses, (key: string) => !key.includes('UNI'))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address, verify);
|
||||||
|
|
||||||
const reservesParams = getReservesConfigByPool(AavePools.proto);
|
const reservesParams = getReservesConfigByPool(AavePools.proto);
|
||||||
|
|
||||||
await initReserves(
|
await initReserves(
|
||||||
|
@ -42,6 +44,7 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
addressesProvider,
|
addressesProvider,
|
||||||
lendingPoolProxy,
|
lendingPoolProxy,
|
||||||
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy,
|
lendingPoolConfiguratorProxy,
|
||||||
AavePools.proto,
|
AavePools.proto,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
|
@ -50,13 +53,13 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
await enableReservesToBorrow(
|
await enableReservesToBorrow(
|
||||||
reservesParams,
|
reservesParams,
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
await enableReservesAsCollateral(
|
await enableReservesAsCollateral(
|
||||||
reservesParams,
|
reservesParams,
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -76,7 +79,5 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
|
|
||||||
await deployWalletBalancerProvider(addressesProvider.address, verify);
|
await deployWalletBalancerProvider(addressesProvider.address, verify);
|
||||||
|
|
||||||
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address, verify);
|
|
||||||
|
|
||||||
await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address);
|
await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address);
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,12 +35,15 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
|
|
||||||
const addressesProvider = await getLendingPoolAddressesProvider();
|
const addressesProvider = await getLendingPoolAddressesProvider();
|
||||||
|
|
||||||
|
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address, verify);
|
||||||
|
|
||||||
console.log('init reserves');
|
console.log('init reserves');
|
||||||
await initReserves(
|
await initReserves(
|
||||||
ReservesConfig,
|
ReservesConfig,
|
||||||
reserveAssets,
|
reserveAssets,
|
||||||
addressesProvider,
|
addressesProvider,
|
||||||
lendingPoolProxy,
|
lendingPoolProxy,
|
||||||
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy,
|
lendingPoolConfiguratorProxy,
|
||||||
AavePools.proto,
|
AavePools.proto,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
|
@ -50,14 +53,14 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
|
||||||
await enableReservesToBorrow(
|
await enableReservesToBorrow(
|
||||||
ReservesConfig,
|
ReservesConfig,
|
||||||
reserveAssets,
|
reserveAssets,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
console.log('enable reserves as collateral');
|
console.log('enable reserves as collateral');
|
||||||
await enableReservesAsCollateral(
|
await enableReservesAsCollateral(
|
||||||
ReservesConfig,
|
ReservesConfig,
|
||||||
reserveAssets,
|
reserveAssets,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import {TokenContractId, eContractid, tEthereumAddress, AavePools} from '../help
|
||||||
import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
|
import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
|
||||||
import {getReservesConfigByPool} from '../helpers/configuration';
|
import {getReservesConfigByPool} from '../helpers/configuration';
|
||||||
import {initializeMakeSuite} from './helpers/make-suite';
|
import {initializeMakeSuite} from './helpers/make-suite';
|
||||||
|
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
setInitialAssetPricesInOracle,
|
setInitialAssetPricesInOracle,
|
||||||
|
@ -201,12 +202,17 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
|
|
||||||
const reservesParams = getReservesConfigByPool(AavePools.proto);
|
const reservesParams = getReservesConfigByPool(AavePools.proto);
|
||||||
|
|
||||||
|
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address);
|
||||||
|
|
||||||
|
await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address);
|
||||||
|
|
||||||
console.log('Initialize configuration');
|
console.log('Initialize configuration');
|
||||||
await initReserves(
|
await initReserves(
|
||||||
reservesParams,
|
reservesParams,
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
addressesProvider,
|
addressesProvider,
|
||||||
lendingPoolProxy,
|
lendingPoolProxy,
|
||||||
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy,
|
lendingPoolConfiguratorProxy,
|
||||||
AavePools.proto,
|
AavePools.proto,
|
||||||
ZERO_ADDRESS,
|
ZERO_ADDRESS,
|
||||||
|
@ -215,13 +221,13 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
await enableReservesToBorrow(
|
await enableReservesToBorrow(
|
||||||
reservesParams,
|
reservesParams,
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
await enableReservesAsCollateral(
|
await enableReservesAsCollateral(
|
||||||
reservesParams,
|
reservesParams,
|
||||||
protoPoolReservesAddresses,
|
protoPoolReservesAddresses,
|
||||||
lendingPoolProxy,
|
testHelpers,
|
||||||
lendingPoolConfiguratorProxy
|
lendingPoolConfiguratorProxy
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -238,10 +244,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
||||||
|
|
||||||
await deployWalletBalancerProvider(addressesProvider.address);
|
await deployWalletBalancerProvider(addressesProvider.address);
|
||||||
|
|
||||||
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address);
|
|
||||||
|
|
||||||
await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address);
|
|
||||||
|
|
||||||
console.timeEnd('setup');
|
console.timeEnd('setup');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ makeSuite('LendingPool SwapDeposit function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User tries to swap correct amount', async () => {
|
it('User tries to swap correct amount', async () => {
|
||||||
const {pool, weth, dai, aEth, aDai} = testEnv;
|
const {pool, weth, dai, aEth, aDai, helpersContract} = testEnv;
|
||||||
const userAddress = await pool.signer.getAddress();
|
const userAddress = await pool.signer.getAddress();
|
||||||
const amountToSwap = ethers.utils.parseEther('0.25');
|
const amountToSwap = ethers.utils.parseEther('0.25');
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ makeSuite('LendingPool SwapDeposit function', (testEnv: TestEnv) => {
|
||||||
'was received incorrect amount if reserve funds'
|
'was received incorrect amount if reserve funds'
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
(await pool.getUserReserveData(dai.address, userAddress)).usageAsCollateralEnabled
|
(await helpersContract.getUserReserveData(dai.address, userAddress)).usageAsCollateralEnabled
|
||||||
).to.be.equal(true, 'usage as collateral was not enabled on destination reserve for the user');
|
).to.be.equal(true, 'usage as collateral was not enabled on destination reserve for the user');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -13,17 +13,17 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
const {CALLER_NOT_AAVE_ADMIN, RESERVE_LIQUIDITY_NOT_0} = ProtocolErrors;
|
const {CALLER_NOT_AAVE_ADMIN, RESERVE_LIQUIDITY_NOT_0} = ProtocolErrors;
|
||||||
|
|
||||||
it('Deactivates the ETH reserve', async () => {
|
it('Deactivates the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, weth, helpersContract} = testEnv;
|
||||||
await configurator.deactivateReserve(weth.address);
|
await configurator.deactivateReserve(weth.address);
|
||||||
const {isActive} = await pool.getReserveConfigurationData(weth.address);
|
const {isActive} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
expect(isActive).to.be.equal(false);
|
expect(isActive).to.be.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Rectivates the ETH reserve', async () => {
|
it('Rectivates the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, weth, helpersContract} = testEnv;
|
||||||
await configurator.activateReserve(weth.address);
|
await configurator.activateReserve(weth.address);
|
||||||
|
|
||||||
const {isActive} = await pool.getReserveConfigurationData(weth.address);
|
const {isActive} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Freezes the ETH reserve', async () => {
|
it('Freezes the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, pool, weth, helpersContract} = testEnv;
|
||||||
await configurator.freezeReserve(weth.address);
|
await configurator.freezeReserve(weth.address);
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -55,12 +55,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(true);
|
expect(isFrozen).to.be.equal(true);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -70,7 +70,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Unfreezes the ETH reserve', async () => {
|
it('Unfreezes the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.unfreezeReserve(weth.address);
|
await configurator.unfreezeReserve(weth.address);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -82,12 +82,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -113,7 +113,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Deactivates the ETH reserve for borrowing', async () => {
|
it('Deactivates the ETH reserve for borrowing', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.disableBorrowingOnReserve(weth.address);
|
await configurator.disableBorrowingOnReserve(weth.address);
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -124,12 +124,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(false);
|
expect(borrowingEnabled).to.be.equal(false);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -139,9 +139,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Activates the ETH reserve for borrowing', async () => {
|
it('Activates the ETH reserve for borrowing', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, weth, helpersContract} = testEnv;
|
||||||
await configurator.enableBorrowingOnReserve(weth.address, true);
|
await configurator.enableBorrowingOnReserve(weth.address, true);
|
||||||
const {variableBorrowIndex} = await pool.getReserveData(weth.address);
|
const {variableBorrowIndex} = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -152,12 +152,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -185,7 +185,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Deactivates the ETH reserve as collateral', async () => {
|
it('Deactivates the ETH reserve as collateral', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.disableReserveAsCollateral(weth.address);
|
await configurator.disableReserveAsCollateral(weth.address);
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -196,12 +196,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(0);
|
expect(ltv).to.be.equal(0);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -211,7 +211,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Activates the ETH reserve as collateral', async () => {
|
it('Activates the ETH reserve as collateral', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.enableReserveAsCollateral(weth.address, '7500', '8000', '10500');
|
await configurator.enableReserveAsCollateral(weth.address, '7500', '8000', '10500');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -223,12 +223,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -256,7 +256,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Disable stable borrow rate on the ETH reserve', async () => {
|
it('Disable stable borrow rate on the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.disableReserveStableRate(weth.address);
|
await configurator.disableReserveStableRate(weth.address);
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -267,12 +267,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -282,7 +282,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Enables stable borrow rate on the ETH reserve', async () => {
|
it('Enables stable borrow rate on the ETH reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.enableReserveStableRate(weth.address);
|
await configurator.enableReserveStableRate(weth.address);
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -293,12 +293,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(7500);
|
expect(ltv).to.be.equal(7500);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -324,7 +324,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Changes LTV of the reserve', async () => {
|
it('Changes LTV of the reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.setLtv(weth.address, '6000');
|
await configurator.setLtv(weth.address, '6000');
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -335,12 +335,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(6000);
|
expect(ltv).to.be.equal(6000);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -358,7 +358,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Changes the reserve factor of the reserve', async () => {
|
it('Changes the reserve factor of the reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.setReserveFactor(weth.address, '1000');
|
await configurator.setReserveFactor(weth.address, '1000');
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -369,12 +369,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(6000);
|
expect(ltv).to.be.equal(6000);
|
||||||
expect(liquidationThreshold).to.be.equal(8000);
|
expect(liquidationThreshold).to.be.equal(8000);
|
||||||
|
@ -392,7 +392,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Changes liquidation threshold of the reserve', async () => {
|
it('Changes liquidation threshold of the reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.setLiquidationThreshold(weth.address, '7500');
|
await configurator.setLiquidationThreshold(weth.address, '7500');
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -403,12 +403,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(6000);
|
expect(ltv).to.be.equal(6000);
|
||||||
expect(liquidationThreshold).to.be.equal(7500);
|
expect(liquidationThreshold).to.be.equal(7500);
|
||||||
|
@ -426,7 +426,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Changes liquidation bonus of the reserve', async () => {
|
it('Changes liquidation bonus of the reserve', async () => {
|
||||||
const {configurator, pool, weth} = testEnv;
|
const {configurator, helpersContract, weth} = testEnv;
|
||||||
await configurator.setLiquidationBonus(weth.address, '11000');
|
await configurator.setLiquidationBonus(weth.address, '11000');
|
||||||
const {
|
const {
|
||||||
decimals,
|
decimals,
|
||||||
|
@ -437,12 +437,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
||||||
stableBorrowRateEnabled,
|
stableBorrowRateEnabled,
|
||||||
borrowingEnabled,
|
borrowingEnabled,
|
||||||
isActive,
|
isActive,
|
||||||
isFreezed,
|
isFrozen,
|
||||||
} = await pool.getReserveConfigurationData(weth.address);
|
} = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
expect(borrowingEnabled).to.be.equal(true);
|
expect(borrowingEnabled).to.be.equal(true);
|
||||||
expect(isActive).to.be.equal(true);
|
expect(isActive).to.be.equal(true);
|
||||||
expect(isFreezed).to.be.equal(false);
|
expect(isFrozen).to.be.equal(false);
|
||||||
expect(decimals).to.be.equal(18);
|
expect(decimals).to.be.equal(18);
|
||||||
expect(ltv).to.be.equal(6000);
|
expect(ltv).to.be.equal(6000);
|
||||||
expect(liquidationThreshold).to.be.equal(7500);
|
expect(liquidationThreshold).to.be.equal(7500);
|
||||||
|
|
|
@ -33,7 +33,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 5 liquidate User 3 collateral, all his variable debt and part of the stable', async () => {
|
it('User 5 liquidate User 3 collateral, all his variable debt and part of the stable', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[2];
|
const user = users[2];
|
||||||
const liquidator = users[4];
|
const liquidator = users[4];
|
||||||
const amountToDeposit = parseEther('20');
|
const amountToDeposit = parseEther('20');
|
||||||
|
@ -102,10 +102,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -208,7 +208,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 5 liquidates half the USDC loan of User 3 by swapping his WETH collateral', async () => {
|
it('User 5 liquidates half the USDC loan of User 3 by swapping his WETH collateral', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[2];
|
const user = users[2];
|
||||||
const liquidator = users[4];
|
const liquidator = users[4];
|
||||||
// Sets USDC Price higher to decrease health factor below 1
|
// Sets USDC Price higher to decrease health factor below 1
|
||||||
|
@ -267,10 +267,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -343,7 +343,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 5 liquidates all the USDC loan of User 3 by swapping his WETH collateral', async () => {
|
it('User 5 liquidates all the USDC loan of User 3 by swapping his WETH collateral', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[2];
|
const user = users[2];
|
||||||
const liquidator = users[4];
|
const liquidator = users[4];
|
||||||
// Sets USDC Price higher to decrease health factor below 1
|
// Sets USDC Price higher to decrease health factor below 1
|
||||||
|
@ -402,10 +402,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -540,7 +540,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
).to.be.revertedWith('38');
|
).to.be.revertedWith('38');
|
||||||
});
|
});
|
||||||
it('User 5 liquidates User 2 DAI Variable loan using his WETH collateral, half the amount', async () => {
|
it('User 5 liquidates User 2 DAI Variable loan using his WETH collateral, half the amount', async () => {
|
||||||
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[1];
|
const user = users[1];
|
||||||
const liquidator = users[4];
|
const liquidator = users[4];
|
||||||
|
|
||||||
|
@ -601,10 +601,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -641,7 +641,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 2 tries to repay remaining DAI Variable loan using his WETH collateral', async () => {
|
it('User 2 tries to repay remaining DAI Variable loan using his WETH collateral', async () => {
|
||||||
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[1];
|
const user = users[1];
|
||||||
|
|
||||||
const {userData: wethUserDataBefore} = await getContractsData(
|
const {userData: wethUserDataBefore} = await getContractsData(
|
||||||
|
@ -688,10 +688,10 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -724,7 +724,7 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Liquidator tries to repay 4 user a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => {
|
it('Liquidator tries to repay 4 user a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => {
|
||||||
const {pool, weth, dai, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, dai, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[3];
|
const user = users[3];
|
||||||
const liquidator = users[5];
|
const liquidator = users[5];
|
||||||
|
|
||||||
|
@ -797,11 +797,11 @@ makeSuite('LendingPool. repayWithCollateral() with liquidator', (testEnv: TestEn
|
||||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralConfig = await pool.getReserveConfigurationData(weth.address);
|
const collateralConfig = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
const collateralDecimals = collateralConfig.decimals.toString();
|
const collateralDecimals = collateralConfig.decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString();
|
const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString();
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
|
it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
|
||||||
const {pool, deployer, weth} = testEnv;
|
const {pool, helpersContract, weth} = testEnv;
|
||||||
|
|
||||||
await pool.flashLoan(
|
await pool.flashLoan(
|
||||||
_mockFlashLoanReceiver.address,
|
_mockFlashLoanReceiver.address,
|
||||||
|
@ -57,7 +57,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
|
|
||||||
ethers.utils.parseUnits('10000');
|
ethers.utils.parseUnits('10000');
|
||||||
|
|
||||||
const reserveData = await pool.getReserveData(weth.address);
|
const reserveData = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const currentLiquidityRate = reserveData.liquidityRate;
|
const currentLiquidityRate = reserveData.liquidityRate;
|
||||||
const currentLiquidityIndex = reserveData.liquidityIndex;
|
const currentLiquidityIndex = reserveData.liquidityIndex;
|
||||||
|
@ -72,9 +72,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
|
it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
|
||||||
const {pool, weth} = testEnv;
|
const {pool, helpersContract, weth} = testEnv;
|
||||||
|
|
||||||
const reserveDataBefore = await pool.getReserveData(weth.address);
|
const reserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||||
const txResult = await pool.flashLoan(
|
const txResult = await pool.flashLoan(
|
||||||
_mockFlashLoanReceiver.address,
|
_mockFlashLoanReceiver.address,
|
||||||
weth.address,
|
weth.address,
|
||||||
|
@ -84,7 +84,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
'0'
|
'0'
|
||||||
);
|
);
|
||||||
|
|
||||||
const reserveData = await pool.getReserveData(weth.address);
|
const reserveData = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const currentLiqudityRate = reserveData.liquidityRate;
|
const currentLiqudityRate = reserveData.liquidityRate;
|
||||||
const currentLiquidityIndex = reserveData.liquidityIndex;
|
const currentLiquidityIndex = reserveData.liquidityIndex;
|
||||||
|
@ -158,7 +158,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => {
|
it('Caller deposits 1000 DAI as collateral, Takes WETH flashloan with mode = 2, does not return the funds. A variable loan for caller is created', async () => {
|
||||||
const {dai, pool, weth, users} = testEnv;
|
const {dai, pool, weth, users, helpersContract} = testEnv;
|
||||||
|
|
||||||
const caller = users[1];
|
const caller = users[1];
|
||||||
|
|
||||||
|
@ -182,7 +182,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
'0x10',
|
'0x10',
|
||||||
'0'
|
'0'
|
||||||
);
|
);
|
||||||
const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
|
const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(
|
||||||
|
weth.address
|
||||||
|
);
|
||||||
|
|
||||||
const wethDebtToken = await getContract<VariableDebtToken>(
|
const wethDebtToken = await getContract<VariableDebtToken>(
|
||||||
eContractid.VariableDebtToken,
|
eContractid.VariableDebtToken,
|
||||||
|
@ -247,7 +249,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
|
it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
|
||||||
const {usdc, pool, deployer: depositor} = testEnv;
|
const {usdc, pool, helpersContract, deployer: depositor} = testEnv;
|
||||||
|
|
||||||
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
|
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
|
||||||
|
|
||||||
|
@ -262,8 +264,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
'0'
|
'0'
|
||||||
);
|
);
|
||||||
|
|
||||||
const reserveData = await pool.getReserveData(usdc.address);
|
const reserveData = await helpersContract.getReserveData(usdc.address);
|
||||||
const userData = await pool.getUserReserveData(usdc.address, depositor.address);
|
const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
|
||||||
|
|
||||||
const totalLiquidity = reserveData.availableLiquidity
|
const totalLiquidity = reserveData.availableLiquidity
|
||||||
.add(reserveData.totalStableDebt)
|
.add(reserveData.totalStableDebt)
|
||||||
|
@ -300,7 +302,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => {
|
it('Caller deposits 5 WETH as collateral, Takes a USDC flashloan with mode = 2, does not return the funds. A loan for caller is created', async () => {
|
||||||
const {usdc, pool, weth, users} = testEnv;
|
const {usdc, pool, weth, users, helpersContract} = testEnv;
|
||||||
|
|
||||||
const caller = users[2];
|
const caller = users[2];
|
||||||
|
|
||||||
|
@ -319,7 +321,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
await pool
|
await pool
|
||||||
.connect(caller.signer)
|
.connect(caller.signer)
|
||||||
.flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
|
.flashLoan(_mockFlashLoanReceiver.address, usdc.address, flashloanAmount, 2, '0x10', '0');
|
||||||
const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(usdc.address);
|
const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(
|
||||||
|
usdc.address
|
||||||
|
);
|
||||||
|
|
||||||
const usdcDebtToken = await getContract<VariableDebtToken>(
|
const usdcDebtToken = await getContract<VariableDebtToken>(
|
||||||
eContractid.VariableDebtToken,
|
eContractid.VariableDebtToken,
|
||||||
|
@ -356,7 +360,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Caller takes a WETH flashloan with mode = 1', async () => {
|
it('Caller takes a WETH flashloan with mode = 1', async () => {
|
||||||
const {dai, pool, weth, users} = testEnv;
|
const {dai, pool, weth, users, helpersContract} = testEnv;
|
||||||
|
|
||||||
const caller = users[3];
|
const caller = users[3];
|
||||||
|
|
||||||
|
@ -368,7 +372,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
||||||
.connect(caller.signer)
|
.connect(caller.signer)
|
||||||
.flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 1, '0x10', '0');
|
.flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 1, '0x10', '0');
|
||||||
|
|
||||||
const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(weth.address);
|
const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(weth.address);
|
||||||
|
|
||||||
const wethDebtToken = await getContract<StableDebtToken>(
|
const wethDebtToken = await getContract<StableDebtToken>(
|
||||||
eContractid.VariableDebtToken,
|
eContractid.VariableDebtToken,
|
||||||
|
|
|
@ -735,11 +735,11 @@ export const getContractsData = async (
|
||||||
testEnv: TestEnv,
|
testEnv: TestEnv,
|
||||||
sender?: string
|
sender?: string
|
||||||
) => {
|
) => {
|
||||||
const {pool} = testEnv;
|
const {pool, helpersContract} = testEnv;
|
||||||
|
|
||||||
const [userData, reserveData, timestamp] = await Promise.all([
|
const [userData, reserveData, timestamp] = await Promise.all([
|
||||||
getUserData(pool, reserve, user, sender || user),
|
getUserData(pool, helpersContract, reserve, user, sender || user),
|
||||||
getReserveData(pool, reserve),
|
getReserveData(helpersContract, reserve),
|
||||||
timeLatest(),
|
timeLatest(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -11,14 +11,15 @@ import {
|
||||||
import {tEthereumAddress} from '../../../helpers/types';
|
import {tEthereumAddress} from '../../../helpers/types';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import {getDb, BRE} from '../../../helpers/misc-utils';
|
import {getDb, BRE} from '../../../helpers/misc-utils';
|
||||||
|
import {AaveProtocolTestHelpers} from '../../../types/AaveProtocolTestHelpers';
|
||||||
|
|
||||||
export const getReserveData = async (
|
export const getReserveData = async (
|
||||||
pool: LendingPool,
|
helper: AaveProtocolTestHelpers,
|
||||||
reserve: tEthereumAddress
|
reserve: tEthereumAddress
|
||||||
): Promise<ReserveData> => {
|
): Promise<ReserveData> => {
|
||||||
const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([
|
const [reserveData, tokenAddresses, rateOracle, token] = await Promise.all([
|
||||||
pool.getReserveData(reserve),
|
helper.getReserveData(reserve),
|
||||||
pool.getReserveTokensAddresses(reserve),
|
helper.getReserveTokensAddresses(reserve),
|
||||||
getLendingRateOracle(),
|
getLendingRateOracle(),
|
||||||
getIErc20Detailed(reserve),
|
getIErc20Detailed(reserve),
|
||||||
]);
|
]);
|
||||||
|
@ -73,13 +74,14 @@ export const getReserveData = async (
|
||||||
|
|
||||||
export const getUserData = async (
|
export const getUserData = async (
|
||||||
pool: LendingPool,
|
pool: LendingPool,
|
||||||
|
helper: AaveProtocolTestHelpers,
|
||||||
reserve: string,
|
reserve: string,
|
||||||
user: tEthereumAddress,
|
user: tEthereumAddress,
|
||||||
sender?: tEthereumAddress
|
sender?: tEthereumAddress
|
||||||
): Promise<UserReserveData> => {
|
): Promise<UserReserveData> => {
|
||||||
const [userData, scaledATokenBalance] = await Promise.all([
|
const [userData, scaledATokenBalance] = await Promise.all([
|
||||||
pool.getUserReserveData(reserve, user),
|
helper.getUserReserveData(reserve, user),
|
||||||
getATokenUserData(reserve, user, pool),
|
getATokenUserData(reserve, user, helper),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const token = await getMintableErc20(reserve);
|
const token = await getMintableErc20(reserve);
|
||||||
|
@ -111,8 +113,13 @@ export const getReserveAddressFromSymbol = async (symbol: string) => {
|
||||||
return token.address;
|
return token.address;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getATokenUserData = async (reserve: string, user: string, pool: LendingPool) => {
|
const getATokenUserData = async (
|
||||||
const aTokenAddress: string = (await pool.getReserveTokensAddresses(reserve)).aTokenAddress;
|
reserve: string,
|
||||||
|
user: string,
|
||||||
|
helpersContract: AaveProtocolTestHelpers
|
||||||
|
) => {
|
||||||
|
const aTokenAddress: string = (await helpersContract.getReserveTokensAddresses(reserve))
|
||||||
|
.aTokenAddress;
|
||||||
|
|
||||||
const aToken = await getAToken(aTokenAddress);
|
const aToken = await getAToken(aTokenAddress);
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
it('LIQUIDATION - Liquidates the borrow', async () => {
|
it('LIQUIDATION - Liquidates the borrow', async () => {
|
||||||
const {pool, dai, weth, users, oracle} = testEnv;
|
const {pool, dai, weth, users, oracle, helpersContract} = testEnv;
|
||||||
const borrower = users[1];
|
const borrower = users[1];
|
||||||
|
|
||||||
//mints dai to the caller
|
//mints dai to the caller
|
||||||
|
@ -128,10 +128,15 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
//approve protocol to access depositor wallet
|
//approve protocol to access depositor wallet
|
||||||
await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const daiReserveDataBefore = await getReserveData(pool, dai.address);
|
const daiReserveDataBefore = await getReserveData(helpersContract, dai.address);
|
||||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address);
|
const userReserveDataBefore = await getUserData(
|
||||||
|
pool,
|
||||||
|
helpersContract,
|
||||||
|
dai.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
|
||||||
.div(2)
|
.div(2)
|
||||||
|
@ -145,21 +150,24 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const userReserveDataAfter = await pool.getUserReserveData(dai.address, borrower.address);
|
const userReserveDataAfter = await helpersContract.getUserReserveData(
|
||||||
|
dai.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||||
|
|
||||||
const daiReserveDataAfter = await pool.getReserveData(dai.address);
|
const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
|
||||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
||||||
const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
|
const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
||||||
|
@ -219,7 +227,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||||
const {users, pool, usdc, oracle, weth} = testEnv;
|
const {users, pool, usdc, oracle, weth, helpersContract} = testEnv;
|
||||||
const depositor = users[3];
|
const depositor = users[3];
|
||||||
const borrower = users[4];
|
const borrower = users[4];
|
||||||
|
|
||||||
|
@ -282,10 +290,13 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
//approve protocol to access depositor wallet
|
//approve protocol to access depositor wallet
|
||||||
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataBefore = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const usdcReserveDataBefore = await pool.getReserveData(usdc.address);
|
const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
|
||||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
||||||
.multipliedBy(0.5)
|
.multipliedBy(0.5)
|
||||||
|
@ -299,21 +310,24 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataAfter = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||||
|
|
||||||
const usdcReserveDataAfter = await pool.getReserveData(usdc.address);
|
const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
|
||||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
||||||
const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
|
const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
||||||
|
|
|
@ -123,7 +123,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
});
|
});
|
||||||
|
|
||||||
it('LIQUIDATION - Liquidates the borrow', async () => {
|
it('LIQUIDATION - Liquidates the borrow', async () => {
|
||||||
const {dai, weth, users, pool, oracle} = testEnv;
|
const {dai, weth, users, pool, oracle, helpersContract} = testEnv;
|
||||||
const liquidator = users[3];
|
const liquidator = users[3];
|
||||||
const borrower = users[1];
|
const borrower = users[1];
|
||||||
|
|
||||||
|
@ -133,10 +133,15 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
//approve protocol to access the liquidator wallet
|
//approve protocol to access the liquidator wallet
|
||||||
await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const daiReserveDataBefore = await pool.getReserveData(dai.address);
|
const daiReserveDataBefore = await helpersContract.getReserveData(dai.address);
|
||||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address);
|
const userReserveDataBefore = await getUserData(
|
||||||
|
pool,
|
||||||
|
helpersContract,
|
||||||
|
dai.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
|
const amountToLiquidate = userReserveDataBefore.currentStableDebt.div(2).toFixed(0);
|
||||||
|
|
||||||
|
@ -146,19 +151,24 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
.connect(liquidator.signer)
|
.connect(liquidator.signer)
|
||||||
.liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
|
.liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
|
||||||
|
|
||||||
const userReserveDataAfter = await getUserData(pool, dai.address, borrower.address);
|
const userReserveDataAfter = await getUserData(
|
||||||
|
pool,
|
||||||
|
helpersContract,
|
||||||
|
dai.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const daiReserveDataAfter = await pool.getReserveData(dai.address);
|
const daiReserveDataAfter = await helpersContract.getReserveData(dai.address);
|
||||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -218,7 +228,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||||
const {usdc, users, pool, oracle, weth} = testEnv;
|
const {usdc, users, pool, oracle, weth, helpersContract} = testEnv;
|
||||||
|
|
||||||
const depositor = users[3];
|
const depositor = users[3];
|
||||||
const borrower = users[4];
|
const borrower = users[4];
|
||||||
|
@ -284,10 +294,13 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
//approve protocol to access depositor wallet
|
//approve protocol to access depositor wallet
|
||||||
await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataBefore = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const usdcReserveDataBefore = await pool.getReserveData(usdc.address);
|
const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
|
||||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
const ethReserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const amountToLiquidate = BRE.ethers.BigNumber.from(
|
const amountToLiquidate = BRE.ethers.BigNumber.from(
|
||||||
userReserveDataBefore.currentStableDebt.toString()
|
userReserveDataBefore.currentStableDebt.toString()
|
||||||
|
@ -299,21 +312,24 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
.connect(liquidator.signer)
|
.connect(liquidator.signer)
|
||||||
.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
|
.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
|
||||||
|
|
||||||
const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataAfter = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||||
|
|
||||||
const usdcReserveDataAfter = await pool.getReserveData(usdc.address);
|
const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
|
||||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
const ethReserveDataAfter = await helpersContract.getReserveData(weth.address);
|
||||||
|
|
||||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -365,7 +381,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated', async () => {
|
it('User 4 deposits 1000 LEND - drops HF, liquidates the LEND, which results on a lower amount being liquidated', async () => {
|
||||||
const {lend, usdc, users, pool, oracle} = testEnv;
|
const {lend, usdc, users, pool, oracle, helpersContract} = testEnv;
|
||||||
|
|
||||||
const depositor = users[3];
|
const depositor = users[3];
|
||||||
const borrower = users[4];
|
const borrower = users[4];
|
||||||
|
@ -399,10 +415,13 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
//approve protocol to access depositor wallet
|
//approve protocol to access depositor wallet
|
||||||
await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await usdc.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataBefore = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const usdcReserveDataBefore = await pool.getReserveData(usdc.address);
|
const usdcReserveDataBefore = await helpersContract.getReserveData(usdc.address);
|
||||||
const lendReserveDataBefore = await pool.getReserveData(lend.address);
|
const lendReserveDataBefore = await helpersContract.getReserveData(lend.address);
|
||||||
|
|
||||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
||||||
.div(2)
|
.div(2)
|
||||||
|
@ -416,26 +435,26 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
||||||
.connect(liquidator.signer)
|
.connect(liquidator.signer)
|
||||||
.liquidationCall(lend.address, usdc.address, borrower.address, amountToLiquidate, false);
|
.liquidationCall(lend.address, usdc.address, borrower.address, amountToLiquidate, false);
|
||||||
|
|
||||||
const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataAfter = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||||
|
|
||||||
const usdcReserveDataAfter = await pool.getReserveData(usdc.address);
|
const usdcReserveDataAfter = await helpersContract.getReserveData(usdc.address);
|
||||||
const lendReserveDataAfter = await pool.getReserveData(lend.address);
|
const lendReserveDataAfter = await helpersContract.getReserveData(lend.address);
|
||||||
|
|
||||||
|
const lendConfiguration = await helpersContract.getReserveConfigurationData(lend.address);
|
||||||
|
const collateralDecimals = lendConfiguration.decimals.toString();
|
||||||
|
const liquidationBonus = lendConfiguration.liquidationBonus.toString();
|
||||||
|
|
||||||
const collateralDecimals = (
|
|
||||||
await pool.getReserveConfigurationData(lend.address)
|
|
||||||
).decimals.toString();
|
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = oneEther.multipliedBy('1000');
|
const expectedCollateralLiquidated = oneEther.multipliedBy('1000');
|
||||||
|
|
||||||
const liquidationBonus = (
|
|
||||||
await pool.getReserveConfigurationData(lend.address)
|
|
||||||
).liquidationBonus.toString();
|
|
||||||
|
|
||||||
const expectedPrincipal = new BigNumber(collateralPrice.toString())
|
const expectedPrincipal = new BigNumber(collateralPrice.toString())
|
||||||
.times(expectedCollateralLiquidated)
|
.times(expectedCollateralLiquidated)
|
||||||
.times(new BigNumber(10).pow(principalDecimals))
|
.times(new BigNumber(10).pow(principalDecimals))
|
||||||
|
|
|
@ -236,7 +236,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Liquidation call', async () => {
|
it('Liquidation call', async () => {
|
||||||
const {users, pool, usdc, oracle, weth, configurator} = testEnv;
|
const {users, pool, usdc, oracle, weth, configurator, helpersContract} = testEnv;
|
||||||
const depositor = users[3];
|
const depositor = users[3];
|
||||||
const borrower = users[4];
|
const borrower = users[4];
|
||||||
|
|
||||||
|
@ -295,7 +295,10 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
|
||||||
await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
|
await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
|
||||||
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||||
|
|
||||||
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
const userReserveDataBefore = await helpersContract.getUserReserveData(
|
||||||
|
usdc.address,
|
||||||
|
borrower.address
|
||||||
|
);
|
||||||
|
|
||||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
||||||
.multipliedBy(0.5)
|
.multipliedBy(0.5)
|
||||||
|
|
|
@ -129,7 +129,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 2 tries to repay his DAI Variable loan using his WETH collateral. First half the amount, after that, the rest', async () => {
|
it('User 2 tries to repay his DAI Variable loan using his WETH collateral. First half the amount, after that, the rest', async () => {
|
||||||
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[1];
|
const user = users[1];
|
||||||
|
|
||||||
const amountToRepay = parseEther('10');
|
const amountToRepay = parseEther('10');
|
||||||
|
@ -175,10 +175,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -228,7 +228,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 3 repays completely his USDC loan by swapping his WETH collateral', async () => {
|
it('User 3 repays completely his USDC loan by swapping his WETH collateral', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[2];
|
const user = users[2];
|
||||||
|
|
||||||
const amountToRepay = parseUnits('10', 6);
|
const amountToRepay = parseUnits('10', 6);
|
||||||
|
@ -275,10 +275,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -335,7 +335,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 3 tries to repay with his collateral all his variable debt and part of the stable', async () => {
|
it('User 3 tries to repay with his collateral all his variable debt and part of the stable', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[2];
|
const user = users[2];
|
||||||
|
|
||||||
const amountToDeposit = parseEther('20');
|
const amountToDeposit = parseEther('20');
|
||||||
|
@ -396,10 +396,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
@ -476,7 +476,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 4 tries to repay a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => {
|
it('User 4 tries to repay a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => {
|
||||||
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, dai, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[3];
|
const user = users[3];
|
||||||
|
|
||||||
const amountToDepositWeth = parseEther('0.1');
|
const amountToDepositWeth = parseEther('0.1');
|
||||||
|
@ -533,14 +533,15 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||||
|
|
||||||
const collateralConfig = await pool.getReserveConfigurationData(weth.address);
|
const collateralConfig = await helpersContract.getReserveConfigurationData(weth.address);
|
||||||
|
|
||||||
const collateralDecimals = collateralConfig.decimals.toString();
|
const collateralDecimals = collateralConfig.decimals.toString();
|
||||||
const principalDecimals = (
|
|
||||||
await pool.getReserveConfigurationData(dai.address)
|
|
||||||
).decimals.toString();
|
|
||||||
const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString();
|
const collateralLiquidationBonus = collateralConfig.liquidationBonus.toString();
|
||||||
|
|
||||||
|
const principalDecimals = (
|
||||||
|
await helpersContract.getReserveConfigurationData(dai.address)
|
||||||
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedDebtCovered = new BigNumber(collateralPrice.toString())
|
const expectedDebtCovered = new BigNumber(collateralPrice.toString())
|
||||||
.times(new BigNumber(wethUserDataBefore.currentATokenBalance.toString()))
|
.times(new BigNumber(wethUserDataBefore.currentATokenBalance.toString()))
|
||||||
.times(new BigNumber(10).pow(principalDecimals))
|
.times(new BigNumber(10).pow(principalDecimals))
|
||||||
|
@ -587,7 +588,7 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('User 5 tries to repay his USDC loan by swapping his WETH collateral, should not revert even with WETH collateral disabled', async () => {
|
it('User 5 tries to repay his USDC loan by swapping his WETH collateral, should not revert even with WETH collateral disabled', async () => {
|
||||||
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
|
const {pool, weth, usdc, users, mockSwapAdapter, oracle, helpersContract} = testEnv;
|
||||||
const user = users[4];
|
const user = users[4];
|
||||||
|
|
||||||
const amountToRepay = parseUnits('65', 6);
|
const amountToRepay = parseUnits('65', 6);
|
||||||
|
@ -640,10 +641,10 @@ makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
|
||||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||||
|
|
||||||
const collateralDecimals = (
|
const collateralDecimals = (
|
||||||
await pool.getReserveConfigurationData(weth.address)
|
await helpersContract.getReserveConfigurationData(weth.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
const principalDecimals = (
|
const principalDecimals = (
|
||||||
await pool.getReserveConfigurationData(usdc.address)
|
await helpersContract.getReserveConfigurationData(usdc.address)
|
||||||
).decimals.toString();
|
).decimals.toString();
|
||||||
|
|
||||||
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
|
||||||
|
|
|
@ -8,9 +8,9 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
|
||||||
const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
|
const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
|
||||||
|
|
||||||
it('Tries to invoke mint not being the LendingPool', async () => {
|
it('Tries to invoke mint not being the LendingPool', async () => {
|
||||||
const {deployer, pool, dai} = testEnv;
|
const {deployer, pool, dai, helpersContract} = testEnv;
|
||||||
|
|
||||||
const daiStableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address))
|
const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
|
||||||
.stableDebtTokenAddress;
|
.stableDebtTokenAddress;
|
||||||
|
|
||||||
const stableDebtContract = await getContract<StableDebtToken>(
|
const stableDebtContract = await getContract<StableDebtToken>(
|
||||||
|
@ -24,9 +24,9 @@ makeSuite('Stable debt token tests', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Tries to invoke burn not being the LendingPool', async () => {
|
it('Tries to invoke burn not being the LendingPool', async () => {
|
||||||
const {deployer, pool, dai} = testEnv;
|
const {deployer, dai, helpersContract} = testEnv;
|
||||||
|
|
||||||
const daiStableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address))
|
const daiStableDebtTokenAddress = (await helpersContract.getReserveTokensAddresses(dai.address))
|
||||||
.stableDebtTokenAddress;
|
.stableDebtTokenAddress;
|
||||||
|
|
||||||
const stableDebtContract = await getContract<StableDebtToken>(
|
const stableDebtContract = await getContract<StableDebtToken>(
|
||||||
|
|
|
@ -87,13 +87,13 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Upgrades the DAI stable debt token implementation ', async () => {
|
it('Upgrades the DAI stable debt token implementation ', async () => {
|
||||||
const {dai, configurator, pool} = testEnv;
|
const {dai, configurator, pool, helpersContract} = testEnv;
|
||||||
|
|
||||||
const name = await (await getAToken(newATokenAddress)).name();
|
const name = await (await getAToken(newATokenAddress)).name();
|
||||||
|
|
||||||
await configurator.updateStableDebtToken(dai.address, newStableTokenAddress);
|
await configurator.updateStableDebtToken(dai.address, newStableTokenAddress);
|
||||||
|
|
||||||
const {stableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address);
|
const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);
|
||||||
|
|
||||||
const debtToken = await getContract<MockStableDebtToken>(
|
const debtToken = await getContract<MockStableDebtToken>(
|
||||||
eContractid.MockStableDebtToken,
|
eContractid.MockStableDebtToken,
|
||||||
|
@ -116,13 +116,13 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Upgrades the DAI variable debt token implementation ', async () => {
|
it('Upgrades the DAI variable debt token implementation ', async () => {
|
||||||
const {dai, configurator, pool} = testEnv;
|
const {dai, configurator, pool, helpersContract} = testEnv;
|
||||||
|
|
||||||
const name = await (await getAToken(newATokenAddress)).name();
|
const name = await (await getAToken(newATokenAddress)).name();
|
||||||
|
|
||||||
await configurator.updateVariableDebtToken(dai.address, newVariableTokenAddress);
|
await configurator.updateVariableDebtToken(dai.address, newVariableTokenAddress);
|
||||||
|
|
||||||
const {variableDebtTokenAddress} = await pool.getReserveTokensAddresses(dai.address);
|
const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);
|
||||||
|
|
||||||
const debtToken = await getContract<MockStableDebtToken>(
|
const debtToken = await getContract<MockStableDebtToken>(
|
||||||
eContractid.MockStableDebtToken,
|
eContractid.MockStableDebtToken,
|
||||||
|
|
|
@ -8,10 +8,11 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
|
||||||
const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
|
const {CALLER_MUST_BE_LENDING_POOL} = ProtocolErrors;
|
||||||
|
|
||||||
it('Tries to invoke mint not being the LendingPool', async () => {
|
it('Tries to invoke mint not being the LendingPool', async () => {
|
||||||
const {deployer, pool, dai} = testEnv;
|
const {deployer, pool, dai, helpersContract} = testEnv;
|
||||||
|
|
||||||
const daiVariableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address))
|
const daiVariableDebtTokenAddress = (
|
||||||
.variableDebtTokenAddress;
|
await helpersContract.getReserveTokensAddresses(dai.address)
|
||||||
|
).variableDebtTokenAddress;
|
||||||
|
|
||||||
const variableDebtContract = await getContract<VariableDebtToken>(
|
const variableDebtContract = await getContract<VariableDebtToken>(
|
||||||
eContractid.VariableDebtToken,
|
eContractid.VariableDebtToken,
|
||||||
|
@ -24,10 +25,11 @@ makeSuite('Variable debt token tests', (testEnv: TestEnv) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Tries to invoke burn not being the LendingPool', async () => {
|
it('Tries to invoke burn not being the LendingPool', async () => {
|
||||||
const {deployer, pool, dai} = testEnv;
|
const {deployer, pool, dai, helpersContract} = testEnv;
|
||||||
|
|
||||||
const daiVariableDebtTokenAddress = (await pool.getReserveTokensAddresses(dai.address))
|
const daiVariableDebtTokenAddress = (
|
||||||
.variableDebtTokenAddress;
|
await helpersContract.getReserveTokensAddresses(dai.address)
|
||||||
|
).variableDebtTokenAddress;
|
||||||
|
|
||||||
const variableDebtContract = await getContract<VariableDebtToken>(
|
const variableDebtContract = await getContract<VariableDebtToken>(
|
||||||
eContractid.VariableDebtToken,
|
eContractid.VariableDebtToken,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user