Revert "Merge branch 'feat/2.5-flashloan-fees-mode-debt' into feat/2.5-drop-reserve"

This reverts commit 6bc1ef13ef, reversing
changes made to 975133fd66.
This commit is contained in:
Hadrien Charlanes 2021-06-08 17:41:09 +02:00
parent 6bf5192a49
commit f06d6fc0d5
42 changed files with 1671 additions and 26926 deletions

View File

@ -461,7 +461,9 @@ interface ILendingPool {
function paused() external view returns (bool);
function updateFlashBorrowerAuthorization(address flashBorrower, bool authorized) external;
function authorizeFlashBorrower(address flashBorrower) external;
function unauthorizeFlashBorrower(address flashBorrower) external;
function isFlashBorrowerAuthorized(address flashBorrower) external view returns (bool);
}

View File

@ -227,164 +227,14 @@ interface ILendingPoolConfigurator {
**/
event RiskAdminRegistered(address indexed admin);
/**
* @dev Emitted when a risk admin is unregistered
* @param admin the unregistered admin
**/
event RiskAdminUnregistered(address indexed admin);
/**
* @dev Initializes reserves in batch
* @param input The array of reserves initialization parameters
**/
function batchInitReserve(InitReserveInput[] calldata input) external;
event FlashBorrowerAuthorized(address indexed flashBorrower);
/**
* @dev Updates the aToken implementation for the reserve
* @param input The aToken update paramenters
**/
function updateAToken(UpdateATokenInput calldata input) external;
event FlashBorrowerUnauthorized(address indexed flashBorrower);
/**
* @dev Updates the stable debt token implementation for the reserve
* @param input The stableDebtToken update parameters
**/
function updateStableDebtToken(UpdateDebtTokenInput calldata input) external;
/**
* @dev Updates the variable debt token implementation for the asset
* @param input The variableDebtToken update parameters
**/
function updateVariableDebtToken(UpdateDebtTokenInput calldata input) external;
/**
* @dev Enables borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
* @param borrowCap The borrow cap for this specific asset, in absolute units of tokens
* @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve
**/
function enableBorrowingOnReserve(
address asset,
uint256 borrowCap,
bool stableBorrowRateEnabled
) external;
/**
* @dev Disables borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function disableBorrowingOnReserve(address asset) external;
/**
* @dev Configures the reserve collateralization parameters
* all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00%
* @param asset The address of the underlying asset of the reserve
* @param ltv The loan to value of the asset when used as collateral
* @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
* @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
* means the liquidator will receive a 5% bonus
**/
function configureReserveAsCollateral(
address asset,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus
) external;
/**
* @dev Enable stable rate borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function enableReserveStableRate(address asset) external;
/**
* @dev Disable stable rate borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function disableReserveStableRate(address asset) external;
/**
* @dev Activates a reserve
* @param asset The address of the underlying asset of the reserve
**/
function activateReserve(address asset) external;
/**
* @dev Deactivates a reserve
* @param asset The address of the underlying asset of the reserve
**/
function deactivateReserve(address asset) external;
/**
* @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap
* but allows repayments, liquidations, rate rebalances and withdrawals
* @param asset The address of the underlying asset of the reserve
**/
function freezeReserve(address asset) external;
/**
* @dev Unfreezes a reserve
* @param asset The address of the underlying asset of the reserve
**/
function unfreezeReserve(address asset) external;
/**
* @dev Pauses a reserve. A paused reserve allow now user moves such as deposit, borrow, repay, swap interestrate, liquidate
* @param asset The address of the underlying asset of the reserve
**/
function pauseReserve(address asset) external;
/**
* @dev Unpauses a reserve
* @param asset The address of the underlying asset of the reserve
**/
function unpauseReserve(address asset) external;
/**
* @dev Updates the reserve factor of a reserve
* @param asset The address of the underlying asset of the reserve
* @param reserveFactor The new reserve factor of the reserve
**/
function setReserveFactor(address asset, uint256 reserveFactor) external;
/**
* @dev Sets the interest rate strategy of a reserve
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The new address of the interest strategy contract
**/
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external;
/**
* @dev pauses or unpauses all the actions of the protocol, including aToken transfers
* @param val true if protocol needs to be paused, false otherwise
**/
function setPoolPause(bool val) external;
/**
* @dev Updates the borrow cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param borrowCap The new borrow of the reserve
**/
function setBorrowCap(address asset, uint256 borrowCap) external;
/**
* @dev Updates the supply cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param supplyCap The new supply of the reserve
**/
function setSupplyCap(address asset, uint256 supplyCap) external;
/**
* @dev Registers a new admin with rights on risk related configurations
* @param admin The address of the admin to register
**/
function registerRiskAdmin(address admin) external;
/**
* @dev Unegisters a risk admin
* @param admin The address of the admin to unregister
**/
function unregisterRiskAdmin(address admin) external;
/**

View File

@ -436,6 +436,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
uint256 currentAmountPlusPremium;
address debtToken;
uint256 flashloanPremiumTotal;
bool isDebtMode;
}
/**
@ -492,27 +493,28 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
vars.currentPremium = premiums[vars.i];
vars.currentATokenAddress = aTokenAddresses[vars.i];
vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
vars.isDebtMode =
DataTypes.InterestRateMode(modes[vars.i]) != DataTypes.InterestRateMode.NONE;
_reserves[vars.currentAsset].updateState();
_reserves[vars.currentAsset].cumulateToLiquidityIndex(
IERC20(vars.currentATokenAddress).totalSupply(),
vars.currentPremium
);
_reserves[vars.currentAsset].updateInterestRates(
vars.currentAsset,
vars.currentATokenAddress,
vars.currentAmountPlusPremium,
0
);
if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
_reserves[vars.currentAsset].updateState();
_reserves[vars.currentAsset].updateInterestRates(
vars.currentAsset,
vars.currentATokenAddress,
vars.currentAmountPlusPremium,
0
);
IERC20(vars.currentAsset).safeTransferFrom(
receiverAddress,
vars.currentATokenAddress,
vars.isDebtMode ? vars.currentPremium : vars.currentAmountPlusPremium
);
IERC20(vars.currentAsset).safeTransferFrom(
receiverAddress,
vars.currentATokenAddress,
vars.currentAmountPlusPremium
);
} else {
if (vars.isDebtMode) {
// If the user chose to not return the funds, the system checks if there is enough collateral and
// eventually opens a debt position
_executeBorrow(
@ -520,7 +522,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
vars.currentAsset,
msg.sender,
onBehalfOf,
vars.currentAmountPlusPremium,
vars.currentAmount,
modes[vars.i],
vars.currentATokenAddress,
referralCode,
@ -848,12 +850,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
}
}
function updateFlashBorrowerAuthorization(address flashBorrower, bool authorized)
function authorizeFlashBorrower(address flashBorrower)
external
override
onlyLendingPoolConfigurator
{
_authorizedFlashBorrowers[flashBorrower] = authorized;
_authorizedFlashBorrowers[flashBorrower] = true;
}
function unauthorizeFlashBorrower(address flashBorrower)
external
override
onlyLendingPoolConfigurator
{
_authorizedFlashBorrowers[flashBorrower] = false;
}
function isFlashBorrowerAuthorized(address flashBorrower) external view override returns (bool) {

View File

@ -30,19 +30,19 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
using PercentageMath for uint256;
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
ILendingPoolAddressesProvider internal _addressesProvider;
ILendingPool internal _pool;
ILendingPoolAddressesProvider internal addressesProvider;
ILendingPool internal pool;
mapping(address => bool) private _riskAdmins;
modifier onlyPoolAdmin {
require(_addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN);
require(addressesProvider.getPoolAdmin() == msg.sender, Errors.CALLER_NOT_POOL_ADMIN);
_;
}
modifier onlyEmergencyAdmin {
require(
_addressesProvider.getEmergencyAdmin() == msg.sender,
addressesProvider.getEmergencyAdmin() == msg.sender,
Errors.LPC_CALLER_NOT_EMERGENCY_ADMIN
);
_;
@ -50,8 +50,8 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
modifier onlyEmergencyOrPoolAdmin {
require(
_addressesProvider.getEmergencyAdmin() == msg.sender ||
_addressesProvider.getPoolAdmin() == msg.sender,
addressesProvider.getEmergencyAdmin() == msg.sender ||
addressesProvider.getPoolAdmin() == msg.sender,
Errors.LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN
);
_;
@ -59,7 +59,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
modifier onlyRiskOrPoolAdmins {
require(
_riskAdmins[msg.sender] || _addressesProvider.getPoolAdmin() == msg.sender,
_riskAdmins[msg.sender] || addressesProvider.getPoolAdmin() == msg.sender,
Errors.LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
);
_;
@ -72,13 +72,15 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
function initialize(ILendingPoolAddressesProvider provider) public initializer {
_addressesProvider = provider;
_pool = ILendingPool(_addressesProvider.getLendingPool());
addressesProvider = provider;
pool = ILendingPool(addressesProvider.getLendingPool());
}
/// @inheritdoc ILendingPoolConfigurator
function batchInitReserve(InitReserveInput[] calldata input) external override onlyPoolAdmin {
ILendingPool cachedPool = _pool;
/**
* @dev Initializes reserves in batch
**/
function batchInitReserve(InitReserveInput[] calldata input) external onlyPoolAdmin {
ILendingPool cachedPool = pool;
for (uint256 i = 0; i < input.length; i++) {
_initReserve(cachedPool, input[i]);
}
@ -165,9 +167,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit ReserveDropped(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function updateAToken(UpdateATokenInput calldata input) external override onlyPoolAdmin {
ILendingPool cachedPool = _pool;
/**
* @dev Updates the aToken implementation for the reserve
**/
function updateAToken(UpdateATokenInput calldata input) external onlyPoolAdmin {
ILendingPool cachedPool = pool;
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
@ -191,13 +195,11 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit ATokenUpgraded(input.asset, reserveData.aTokenAddress, input.implementation);
}
/// @inheritdoc ILendingPoolConfigurator
function updateStableDebtToken(UpdateDebtTokenInput calldata input)
external
override
onlyPoolAdmin
{
ILendingPool cachedPool = _pool;
/**
* @dev Updates the stable debt token implementation for the reserve
**/
function updateStableDebtToken(UpdateDebtTokenInput calldata input) external onlyPoolAdmin {
ILendingPool cachedPool = pool;
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
@ -228,13 +230,12 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
);
}
/// @inheritdoc ILendingPoolConfigurator
function updateVariableDebtToken(UpdateDebtTokenInput calldata input)
external
override
onlyPoolAdmin
{
ILendingPool cachedPool = _pool;
/**
* @dev Updates the variable debt token implementation for the asset
**/
function updateVariableDebtToken(UpdateDebtTokenInput calldata input) external onlyPoolAdmin {
ILendingPool cachedPool = pool;
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
@ -264,42 +265,56 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
);
}
/// @inheritdoc ILendingPoolConfigurator
/**
* @dev Enables borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
* @param stableBorrowRateEnabled True if stable borrow rate needs to be enabled by default on this reserve
**/
function enableBorrowingOnReserve(
address asset,
uint256 borrowCap,
bool stableBorrowRateEnabled
) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(true);
currentConfig.setBorrowCap(borrowCap);
currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit BorrowCapChanged(asset, borrowCap);
emit BorrowingEnabledOnReserve(asset, stableBorrowRateEnabled);
}
/// @inheritdoc ILendingPoolConfigurator
function disableBorrowingOnReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Disables borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function disableBorrowingOnReserve(address asset) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(false);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit BorrowingDisabledOnReserve(asset);
}
/// @inheritdoc ILendingPoolConfigurator
/**
* @dev Configures the reserve collateralization parameters
* all the values are expressed in percentages with two decimals of precision. A valid value is 10000, which means 100.00%
* @param asset The address of the underlying asset of the reserve
* @param ltv The loan to value of the asset when used as collateral
* @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
* @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
* means the liquidator will receive a 5% bonus
**/
function configureReserveAsCollateral(
address asset,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus
) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
//validation of the parameters: the LTV can
//only be lower or equal than the liquidation threshold
@ -332,178 +347,212 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
currentConfig.setLiquidationThreshold(liquidationThreshold);
currentConfig.setLiquidationBonus(liquidationBonus);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit CollateralConfigurationChanged(asset, ltv, liquidationThreshold, liquidationBonus);
}
/// @inheritdoc ILendingPoolConfigurator
function enableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Enable stable rate borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function enableReserveStableRate(address asset) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(true);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit StableRateEnabledOnReserve(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function disableReserveStableRate(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Disable stable rate borrowing on a reserve
* @param asset The address of the underlying asset of the reserve
**/
function disableReserveStableRate(address asset) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setStableRateBorrowingEnabled(false);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit StableRateDisabledOnReserve(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function activateReserve(address asset) external override onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Activates a reserve
* @param asset The address of the underlying asset of the reserve
**/
function activateReserve(address asset) external onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setActive(true);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveActivated(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function deactivateReserve(address asset) external override onlyPoolAdmin {
/**
* @dev Deactivates a reserve
* @param asset The address of the underlying asset of the reserve
**/
function deactivateReserve(address asset) external onlyPoolAdmin {
_checkNoLiquidity(asset);
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setActive(false);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveDeactivated(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function freezeReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Freezes a reserve. A frozen reserve doesn't allow any new deposit, borrow or rate swap
* but allows repayments, liquidations, rate rebalances and withdrawals
* @param asset The address of the underlying asset of the reserve
**/
function freezeReserve(address asset) external onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setFrozen(true);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveFrozen(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function unfreezeReserve(address asset) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Unfreezes a reserve
* @param asset The address of the underlying asset of the reserve
**/
function unfreezeReserve(address asset) external onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setFrozen(false);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveUnfrozen(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function pauseReserve(address asset) external override onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Pauses a reserve. A paused reserve allow now user moves such as deposit, borrow, repay, swap interestrate, liquidate
* @param asset The address of the underlying asset of the reserve
**/
function pauseReserve(address asset) external onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setPaused(true);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReservePaused(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function unpauseReserve(address asset) external override onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Unpauses a reserve
* @param asset The address of the underlying asset of the reserve
**/
function unpauseReserve(address asset) external onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setPaused(false);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveUnpaused(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function setReserveFactor(address asset, uint256 reserveFactor)
external
override
onlyRiskOrPoolAdmins
{
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Updates the reserve factor of a reserve
* @param asset The address of the underlying asset of the reserve
* @param reserveFactor The new reserve factor of the reserve
**/
function setReserveFactor(address asset, uint256 reserveFactor) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setReserveFactor(reserveFactor);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit ReserveFactorChanged(asset, reserveFactor);
}
///@inheritdoc ILendingPoolConfigurator
function setBorrowCap(address asset, uint256 borrowCap) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Updates the borrow cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param borrowCap The new borrow of the reserve
**/
function setBorrowCap(address asset, uint256 borrowCap) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setBorrowCap(borrowCap);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit BorrowCapChanged(asset, borrowCap);
}
///@inheritdoc ILendingPoolConfigurator
function setSupplyCap(address asset, uint256 supplyCap) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
/**
* @dev Updates the supply cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param supplyCap The new supply of the reserve
**/
function setSupplyCap(address asset, uint256 supplyCap) external onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setSupplyCap(supplyCap);
_pool.setConfiguration(asset, currentConfig.data);
pool.setConfiguration(asset, currentConfig.data);
emit SupplyCapChanged(asset, supplyCap);
}
///@inheritdoc ILendingPoolConfigurator
/**
* @dev Sets the interest rate strategy of a reserve
* @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The new address of the interest strategy contract
**/
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external
override
onlyRiskOrPoolAdmins
{
_pool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress);
pool.setReserveInterestRateStrategyAddress(asset, rateStrategyAddress);
emit ReserveInterestRateStrategyChanged(asset, rateStrategyAddress);
}
/// @inheritdoc ILendingPoolConfigurator
function setPoolPause(bool val) external override onlyEmergencyAdmin {
_pool.setPause(val);
/**
* @dev pauses or unpauses all the actions of the protocol, including aToken transfers
* @param val true if protocol needs to be paused, false otherwise
**/
function setPoolPause(bool val) external onlyEmergencyAdmin {
pool.setPause(val);
}
/// @inheritdoc ILendingPoolConfigurator
function registerRiskAdmin(address admin) external override onlyPoolAdmin {
_riskAdmins[admin] = true;
emit RiskAdminRegistered(admin);
}
/// @inheritdoc ILendingPoolConfigurator
function unregisterRiskAdmin(address admin) external override onlyPoolAdmin {
_riskAdmins[admin] = false;
emit RiskAdminUnregistered(admin);
}
/// @inheritdoc ILendingPoolConfigurator
function authorizeFlashBorrower(address flashBorrower) external override onlyPoolAdmin {
_pool.updateFlashBorrowerAuthorization(flashBorrower, true);
pool.authorizeFlashBorrower(flashBorrower);
emit FlashBorrowerAuthorized(flashBorrower);
}
/// @inheritdoc ILendingPoolConfigurator
function unauthorizeFlashBorrower(address flashBorrower) external override onlyPoolAdmin {
_pool.updateFlashBorrowerAuthorization(flashBorrower, false);
pool.unauthorizeFlashBorrower(flashBorrower);
emit FlashBorrowerUnauthorized(flashBorrower);
}
/// @inheritdoc ILendingPoolConfigurator
function isRiskAdmin(address admin) external view override onlyPoolAdmin returns (bool) {
return _riskAdmins[admin];
}
@ -532,7 +581,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
function _checkNoLiquidity(address asset) internal view {
DataTypes.ReserveData memory reserveData = _pool.getReserveData(asset);
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress);

View File

@ -20,8 +20,8 @@ library ReserveConfiguration {
uint256 constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
uint256 constant PAUSED_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
/// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed
uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
@ -35,15 +35,15 @@ library ReserveConfiguration {
// bits 61 62 63 unused yet
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 116;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 128;
uint256 constant MAX_VALID_LTV = 65535;
uint256 constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
uint256 constant MAX_VALID_LIQUIDATION_BONUS = 65535;
uint256 constant MAX_VALID_DECIMALS = 255;
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 constant MAX_VALID_BORROW_CAP = 68719476735;
uint256 constant MAX_VALID_SUPPLY_CAP = 68719476735;
uint256 constant MAX_VALID_BORROW_CAP = 281474976710655;
uint256 constant MAX_VALID_SUPPLY_CAP = 281474976710655;
/**
* @dev Sets the Loan to Value of the reserve
@ -190,7 +190,7 @@ library ReserveConfiguration {
return (self.data & ~FROZEN_MASK) != 0;
}
/**
/**
* @dev Sets the paused state of the reserve
* @param self The reserve configuration
* @param paused The paused state
@ -414,8 +414,8 @@ library ReserveConfiguration {
uint256 dataLocal = self.data;
return (
(dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
@ -484,30 +484,4 @@ library ReserveConfiguration {
(self.data & ~PAUSED_MASK) != 0
);
}
/**
* @dev Gets the supply cap of the reserve from a memory objet
* @param self The reserve configuration
* @return The supply cap
**/
function getSupplyCapMemory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
}
/**
* @dev Gets the borrow cap of the reserve from a memory object
* @param self The reserve configuration
* @return The borrow cap
**/
function getBorrowCapMemory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
}
}

View File

@ -40,20 +40,17 @@ library ValidationLogic {
* @param reserve The reserve object on which the user is depositing
* @param amount The amount to be deposited
*/
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) internal view {
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
(bool isActive, bool isFrozen, , , bool isPaused) = reserveConfiguration.getFlagsMemory();
(, , , uint256 reserveDecimals, ) = reserveConfiguration.getParamsMemory();
uint256 supplyCap = reserveConfiguration.getSupplyCapMemory();
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view {
(bool isActive, bool isFrozen, , , bool isPaused) = reserve.configuration.getFlags();
require(amount != 0, Errors.VL_INVALID_AMOUNT);
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED);
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
require(
supplyCap == 0 ||
IERC20(reserve.aTokenAddress).totalSupply().add(amount).div(10**reserveDecimals) <
supplyCap,
IERC20(reserve.aTokenAddress).totalSupply().add(amount).div(
10**reserve.configuration.getDecimals()
) < reserve.configuration.getSupplyCap(),
Errors.VL_SUPPLY_CAP_EXCEEDED
);
}
@ -87,8 +84,6 @@ library ValidationLogic {
uint256 healthFactor;
uint256 totalSupplyStableDebt;
uint256 totalSupplyVariableDebt;
uint256 reserveDecimals;
uint256 borrowCap;
bool isActive;
bool isFrozen;
bool isPaused;
@ -127,16 +122,13 @@ library ValidationLogic {
) external view {
ValidateBorrowLocalVars memory vars;
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
(, , , vars.reserveDecimals, ) = reserveConfiguration.getParamsMemory();
(
vars.isActive,
vars.isFrozen,
vars.borrowingEnabled,
vars.stableRateBorrowingEnabled,
vars.isPaused
) = reserveConfiguration.getFlagsMemory();
) = reserve.configuration.getFlags();
require(vars.isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!vars.isPaused, Errors.VL_RESERVE_PAUSED);
@ -152,16 +144,17 @@ library ValidationLogic {
Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
);
vars.totalSupplyStableDebt = IERC20(reserve.stableDebtTokenAddress).totalSupply();
vars.borrowCap = reserveConfiguration.getBorrowCapMemory();
vars.totalSupplyVariableDebt = IERC20(reserve.variableDebtTokenAddress).totalSupply();
(vars.totalSupplyStableDebt, ) = IStableDebtToken(reserve.stableDebtTokenAddress)
.getTotalSupplyAndAvgRate();
vars.totalSupplyVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress)
.scaledTotalSupply()
.rayMul(reserve.variableBorrowIndex);
require(
vars.borrowCap == 0 ||
vars.totalSupplyStableDebt.add(vars.totalSupplyVariableDebt).add(amount).div(
10**vars.reserveDecimals
) <
vars.borrowCap,
vars.totalSupplyStableDebt.add(vars.totalSupplyVariableDebt).add(amount).div(
10**reserve.configuration.getDecimals()
) < reserve.configuration.getBorrowCap(),
Errors.VL_BORROW_CAP_EXCEEDED
);

View File

@ -39,8 +39,8 @@ library DataTypes {
//bit 60: asset is paused
//bit 61-63: reserved
//bit 64-79: reserve factor
//bit 80-115 borrow cap, borrowCap == 0 => disabled
//bit 116-152 supply cap, supplyCap == 0 => disabled
//bit 80-127 borrow cap
//bit 128-175 borrow cap
uint256 data;
}

View File

@ -21,5 +21,3 @@ services:
ALCHEMY_KEY: ${ALCHEMY_KEY}
TENDERLY_FORK_ID: ${TENDERLY_FORK_ID}
TENDERLY_HEAD_ID: ${TENDERLY_HEAD_ID}
DEFENDER_API_KEY: ${DEFENDER_API_KEY}
DEFENDER_SECRET_KEY: ${DEFENDER_SECRET_KEY}

View File

@ -6,7 +6,7 @@ import {
ICommonConfiguration,
eNetwork,
} from './types';
import { getEthersSignersAddresses, getParamPerPool } from './contracts-helpers';
import { getParamPerPool } from './contracts-helpers';
import AaveConfig from '../markets/aave';
import MaticConfig from '../markets/matic';
import AmmConfig from '../markets/amm';
@ -66,7 +66,9 @@ export const getGenesisPoolAdmin = async (
if (targetAddress) {
return targetAddress;
}
const addressList = await getEthersSignersAddresses();
const addressList = await Promise.all(
(await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
);
const addressIndex = config.PoolAdminIndex;
return addressList[addressIndex];
};
@ -79,7 +81,9 @@ export const getEmergencyAdmin = async (
if (targetAddress) {
return targetAddress;
}
const addressList = await getEthersSignersAddresses();
const addressList = await Promise.all(
(await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
);
const addressIndex = config.EmergencyAdminIndex;
return addressList[addressIndex];
};

View File

@ -15,8 +15,8 @@ export const oneEther = new BigNumber(Math.pow(10, 18));
export const oneRay = new BigNumber(Math.pow(10, 27));
export const MAX_UINT_AMOUNT =
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
export const MAX_BORROW_CAP = '68719476735';
export const MAX_SUPPLY_CAP = '68719476735';
export const MAX_BORROW_CAP = '281474976710655';
export const MAX_SUPPLY_CAP = '281474976710655';
export const ONE_YEAR = '31536000';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';

View File

@ -137,9 +137,7 @@ export const deployGenericLogic = async (reserveLogic: Contract, verify?: boolea
linkedGenericLogicByteCode
);
const genericLogic = await (
await genericLogicFactory.connect(await getFirstSigner()).deploy()
).deployed();
const genericLogic = await (await genericLogicFactory.deploy()).deployed();
return withSaveAndVerify(genericLogic, eContractid.GenericLogic, [], verify);
};
@ -160,9 +158,7 @@ export const deployValidationLogic = async (
linkedValidationLogicByteCode
);
const validationLogic = await (
await validationLogicFactory.connect(await getFirstSigner()).deploy()
).deployed();
const validationLogic = await (await validationLogicFactory.deploy()).deployed();
return withSaveAndVerify(validationLogic, eContractid.ValidationLogic, [], verify);
};

View File

@ -32,11 +32,11 @@ import {
FlashLiquidationAdapterFactory,
} from '../types';
import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory';
import { getEthersSigners, MockTokenMap } from './contracts-helpers';
import { MockTokenMap } from './contracts-helpers';
import { DRE, getDb, notFalsyOrZeroAddress } from './misc-utils';
import { eContractid, PoolConfiguration, tEthereumAddress, TokenContractId } from './types';
export const getFirstSigner = async () => (await getEthersSigners())[0];
export const getFirstSigner = async () => (await DRE.ethers.getSigners())[0];
export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress) => {
return await LendingPoolAddressesProviderFactory.connect(

View File

@ -23,10 +23,9 @@ import { MintableERC20 } from '../types/MintableERC20';
import { Artifact } from 'hardhat/types';
import { Artifact as BuidlerArtifact } from '@nomiclabs/buidler/types';
import { verifyEtherscanContract } from './etherscan-verification';
import { getFirstSigner, getIErc20Detailed } from './contracts-getters';
import { getIErc20Detailed } from './contracts-getters';
import { usingTenderly, verifyAtTenderly } from './tenderly-utils';
import { usingPolygon, verifyAtPolygon } from './polygon-utils';
import { getDefenderRelaySigner, usingDefender } from './defender-utils';
export type MockTokenMap = { [symbol: string]: MintableERC20 };
@ -67,18 +66,11 @@ export const rawInsertContractAddressInDb = async (id: string, address: tEthereu
})
.write();
export const getEthersSigners = async (): Promise<Signer[]> => {
const ethersSigners = await Promise.all(await DRE.ethers.getSigners());
if (usingDefender()) {
const [, ...users] = ethersSigners;
return [await getDefenderRelaySigner(), ...users];
}
return ethersSigners;
};
export const getEthersSigners = async (): Promise<Signer[]> =>
await Promise.all(await DRE.ethers.getSigners());
export const getEthersSignersAddresses = async (): Promise<tEthereumAddress[]> =>
await Promise.all((await getEthersSigners()).map((signer) => signer.getAddress()));
await Promise.all((await DRE.ethers.getSigners()).map((signer) => signer.getAddress()));
export const getCurrentBlock = async () => {
return DRE.ethers.provider.getBlockNumber();
@ -91,9 +83,9 @@ export const deployContract = async <ContractType extends Contract>(
contractName: string,
args: any[]
): Promise<ContractType> => {
const contract = (await (await DRE.ethers.getContractFactory(contractName))
.connect(await getFirstSigner())
.deploy(...args)) as ContractType;
const contract = (await (await DRE.ethers.getContractFactory(contractName)).deploy(
...args
)) as ContractType;
await waitForTx(contract.deployTransaction);
await registerContractInJsonDb(<eContractid>contractName, contract);
return contract;

View File

@ -1,41 +0,0 @@
import { formatEther } from '@ethersproject/units';
import { DefenderRelaySigner, DefenderRelayProvider } from 'defender-relay-client/lib/ethers';
import { Signer } from 'ethers';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DRE, impersonateAccountsHardhat } from './misc-utils';
import { usingTenderly } from './tenderly-utils';
export const usingDefender = () => process.env.DEFENDER === 'true';
export const getDefenderRelaySigner = async () => {
const { DEFENDER_API_KEY, DEFENDER_SECRET_KEY } = process.env;
let defenderSigner: Signer;
if (!DEFENDER_API_KEY || !DEFENDER_SECRET_KEY) {
throw new Error('Defender secrets required');
}
const credentials = { apiKey: DEFENDER_API_KEY, apiSecret: DEFENDER_SECRET_KEY };
defenderSigner = new DefenderRelaySigner(credentials, new DefenderRelayProvider(credentials), {
speed: 'fast',
});
const defenderAddress = await defenderSigner.getAddress();
console.log(' - Using Defender Relay: ', defenderAddress);
// Replace signer if FORK=main is active
if (process.env.FORK === 'main') {
console.log(' - Impersonating Defender Relay');
await impersonateAccountsHardhat([defenderAddress]);
defenderSigner = await (DRE as HardhatRuntimeEnvironment).ethers.getSigner(defenderAddress);
}
// Replace signer if Tenderly network is active
if (usingTenderly()) {
console.log(' - Impersonating Defender Relay via Tenderly');
defenderSigner = await (DRE as HardhatRuntimeEnvironment).ethers.getSigner(defenderAddress);
}
console.log(' - Balance: ', formatEther(await defenderSigner.getBalance()));
return defenderSigner;
};

View File

@ -115,17 +115,3 @@ export const notFalsyOrZeroAddress = (address: tEthereumAddress | null | undefin
}
return isAddress(address) && !isZeroAddress(address);
};
export const impersonateAccountsHardhat = async (accounts: string[]) => {
if (process.env.TENDERLY === 'true') {
return;
}
// eslint-disable-next-line no-restricted-syntax
for (const account of accounts) {
// eslint-disable-next-line no-await-in-loop
await (DRE as HardhatRuntimeEnvironment).network.provider.request({
method: 'hardhat_impersonateAccount',
params: [account],
});
}
};

View File

@ -9,7 +9,7 @@ export const usingTenderly = () =>
export const verifyAtTenderly = async (id: string, instance: Contract) => {
console.log('\n- Doing Tenderly contract verification of', id);
await (DRE as any).tenderlyNetwork.verify({
await (DRE as any).tenderlyRPC.verify({
name: id,
address: instance.address,
});

View File

@ -1,3 +1,4 @@
import { MAX_BORROW_CAP, MAX_SUPPLY_CAP } from '../../helpers/constants';
import { eContractid, IReserveParams } from '../../helpers/types';
import {
@ -22,8 +23,8 @@ export const strategyBUSD: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyDAI: IReserveParams = {
@ -36,8 +37,8 @@ export const strategyDAI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategySUSD: IReserveParams = {
@ -50,8 +51,8 @@ export const strategySUSD: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyTUSD: IReserveParams = {
@ -64,8 +65,8 @@ export const strategyTUSD: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDC: IReserveParams = {
@ -78,8 +79,8 @@ export const strategyUSDC: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDT: IReserveParams = {
@ -92,8 +93,8 @@ export const strategyUSDT: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyAAVE: IReserveParams = {
@ -106,8 +107,8 @@ export const strategyAAVE: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '0',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyBAT: IReserveParams = {
@ -120,8 +121,8 @@ export const strategyBAT: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyENJ: IReserveParams = {
@ -134,8 +135,8 @@ export const strategyENJ: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWETH: IReserveParams = {
@ -148,8 +149,8 @@ export const strategyWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyKNC: IReserveParams = {
@ -162,8 +163,8 @@ export const strategyKNC: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyLINK: IReserveParams = {
@ -176,8 +177,8 @@ export const strategyLINK: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyMANA: IReserveParams = {
@ -190,8 +191,8 @@ export const strategyMANA: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyMKR: IReserveParams = {
@ -204,8 +205,8 @@ export const strategyMKR: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyREN: IReserveParams = {
@ -218,8 +219,8 @@ export const strategyREN: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategySNX: IReserveParams = {
@ -232,8 +233,8 @@ export const strategySNX: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
// Invalid borrow rates in params currently, replaced with snx params
@ -247,8 +248,8 @@ export const strategyUNI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.DelegationAwareAToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWBTC: IReserveParams = {
@ -261,8 +262,8 @@ export const strategyWBTC: IReserveParams = {
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyYFI: IReserveParams = {
@ -275,8 +276,8 @@ export const strategyYFI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyZRX: IReserveParams = {
@ -289,8 +290,8 @@ export const strategyZRX: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyXSUSHI: IReserveParams = {
@ -303,6 +304,6 @@ export const strategyXSUSHI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};

View File

@ -1,5 +1,11 @@
import { eContractid, IReserveParams } from '../../helpers/types';
import { rateStrategyAmmBase, rateStrategyStable, rateStrategyBaseOne } from './rateStrategies';
import { MAX_BORROW_CAP, MAX_SUPPLY_CAP } from '../../helpers/constants';
import { eContractid, IReserveParams} from '../../helpers/types';
import {
rateStrategyAmmBase,
rateStrategyStable,
rateStrategyBaseOne,
} from './rateStrategies';
export const strategyWETH: IReserveParams = {
strategy: rateStrategyBaseOne,
@ -11,8 +17,8 @@ export const strategyWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWBTC: IReserveParams = {
@ -25,8 +31,8 @@ export const strategyWBTC: IReserveParams = {
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyDAI: IReserveParams = {
@ -39,8 +45,8 @@ export const strategyDAI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDC: IReserveParams = {
@ -53,8 +59,8 @@ export const strategyUSDC: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDT: IReserveParams = {
@ -67,8 +73,8 @@ export const strategyUSDT: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyDAIWETH: IReserveParams = {
@ -81,8 +87,8 @@ export const strategyDAIWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWBTCWETH: IReserveParams = {
@ -95,8 +101,8 @@ export const strategyWBTCWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyAAVEWETH: IReserveParams = {
@ -109,8 +115,8 @@ export const strategyAAVEWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyBATWETH: IReserveParams = {
@ -123,8 +129,8 @@ export const strategyBATWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyDAIUSDC: IReserveParams = {
@ -137,8 +143,8 @@ export const strategyDAIUSDC: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyCRVWETH: IReserveParams = {
@ -151,8 +157,8 @@ export const strategyCRVWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyLINKWETH: IReserveParams = {
@ -165,8 +171,8 @@ export const strategyLINKWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyMKRWETH: IReserveParams = {
@ -179,8 +185,8 @@ export const strategyMKRWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyRENWETH: IReserveParams = {
@ -193,8 +199,8 @@ export const strategyRENWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategySNXWETH: IReserveParams = {
@ -207,8 +213,8 @@ export const strategySNXWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUNIWETH: IReserveParams = {
@ -221,8 +227,8 @@ export const strategyUNIWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDCWETH: IReserveParams = {
@ -235,8 +241,8 @@ export const strategyUSDCWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWBTCUSDC: IReserveParams = {
@ -249,8 +255,8 @@ export const strategyWBTCUSDC: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyYFIWETH: IReserveParams = {
@ -263,8 +269,8 @@ export const strategyYFIWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyBALWETH: IReserveParams = {
@ -277,6 +283,6 @@ export const strategyBALWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
}

View File

@ -1,5 +1,6 @@
// import BigNumber from 'bignumber.js';
// import { oneRay } from '../../helpers/constants';
import { MAX_BORROW_CAP, MAX_SUPPLY_CAP } from '../../helpers/constants';
import { eContractid, IReserveParams } from '../../helpers/types';
import {
rateStrategyStableTwo,
@ -20,8 +21,8 @@ export const strategyDAI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDC: IReserveParams = {
@ -34,8 +35,8 @@ export const strategyUSDC: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyUSDT: IReserveParams = {
@ -48,8 +49,8 @@ export const strategyUSDT: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWETH: IReserveParams = {
@ -62,8 +63,8 @@ export const strategyWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyWBTC: IReserveParams = {
@ -76,8 +77,8 @@ export const strategyWBTC: IReserveParams = {
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyMATIC: IReserveParams = {
@ -89,9 +90,9 @@ export const strategyMATIC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
borrowCap: '0',
supplyCap: '0',
reserveFactor: '2000',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
};
export const strategyAAVE: IReserveParams = {
@ -103,7 +104,7 @@ export const strategyAAVE: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
borrowCap: '0',
supplyCap: '0',
borrowCap: MAX_BORROW_CAP,
supplyCap: MAX_SUPPLY_CAP,
reserveFactor: '0',
};

26285
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -100,7 +100,7 @@
"@nomiclabs/hardhat-ethers": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.0",
"@openzeppelin/contracts": "3.1.0",
"@tenderly/hardhat-tenderly": "1.1.0-beta.5",
"@tenderly/hardhat-tenderly": "^1.1.0-beta.4",
"@typechain/ethers-v4": "1.0.0",
"@typechain/ethers-v5": "^2.0.0",
"@typechain/truffle-v4": "2.0.2",
@ -115,7 +115,6 @@
"chai": "4.2.0",
"chai-bignumber": "3.0.0",
"chai-bn": "^0.2.1",
"defender-relay-client": "^1.7.0",
"dotenv": "^8.2.0",
"eth-sig-util": "2.5.3",
"ethereum-waffle": "3.0.2",

View File

@ -3,7 +3,6 @@ import {
deployLendingPoolAddressesProvider,
deployLendingPoolAddressesProviderRegistry,
} from '../../helpers/contracts-deployments';
import { getEthersSigners } from '../../helpers/contracts-helpers';
import { waitForTx } from '../../helpers/misc-utils';
import { AaveConfig } from '../../markets/aave';
@ -15,7 +14,7 @@ task(
.setAction(async ({ verify }, localBRE) => {
await localBRE.run('set-DRE');
const admin = await (await getEthersSigners())[0].getAddress();
const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
const addressesProvider = await deployLendingPoolAddressesProvider(AaveConfig.MarketId, verify);
await waitForTx(await addressesProvider.setPoolAdmin(admin));

View File

@ -82,7 +82,7 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
if (DRE.network.name.includes('tenderly')) {
const transactionLink = `https://dashboard.tenderly.co/${DRE.config.tenderly.username}/${
DRE.config.tenderly.project
}/fork/${DRE.tenderlyNetwork.getFork()}/simulation/${DRE.tenderlyNetwork.getHead()}`;
}/fork/${DRE.tenderlyRPC.getFork()}/simulation/${DRE.tenderlyRPC.getHead()}`;
console.error('Check tx error:', transactionLink);
}
throw error;

View File

@ -84,7 +84,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
if (DRE.network.name.includes('tenderly')) {
const transactionLink = `https://dashboard.tenderly.co/${DRE.config.tenderly.username}/${
DRE.config.tenderly.project
}/fork/${DRE.tenderlyNetwork.getFork()}/simulation/${DRE.tenderlyNetwork.getHead()}`;
}/fork/${DRE.tenderlyRPC.getFork()}/simulation/${DRE.tenderlyRPC.getHead()}`;
console.error('Check tx error:', transactionLink);
}
throw error;

View File

@ -46,8 +46,8 @@ task('aave:mainnet', 'Deploy development enviroment')
}
if (usingTenderly()) {
const postDeployHead = DRE.tenderlyNetwork.getHead();
const postDeployFork = DRE.tenderlyNetwork.getFork();
const postDeployHead = DRE.tenderlyRPC.getHead();
const postDeployFork = DRE.tenderlyRPC.getFork();
console.log('Tenderly Info');
console.log('- Head', postDeployHead);
console.log('- Fork', postDeployFork);

View File

@ -46,8 +46,8 @@ task('amm:mainnet', 'Deploy development enviroment')
}
if (usingTenderly()) {
const postDeployHead = DRE.tenderlyNetwork.getHead();
const postDeployFork = DRE.tenderlyNetwork.getFork();
const postDeployHead = DRE.tenderlyRPC.getHead();
const postDeployFork = DRE.tenderlyRPC.getFork();
console.log('Tenderly Info');
console.log('- Head', postDeployHead);
console.log('- Fork', postDeployFork);

View File

@ -49,8 +49,8 @@ task('sidechain:mainnet', 'Deploy market at sidechain')
}
if (usingTenderly()) {
const postDeployHead = DRE.tenderlyNetwork.getHead();
const postDeployFork = DRE.tenderlyNetwork.getFork();
const postDeployHead = DRE.tenderlyRPC.getHead();
const postDeployFork = DRE.tenderlyRPC.getFork();
console.log('Tenderly Info');
console.log('- Head', postDeployHead);
console.log('- Fork', postDeployFork);

View File

@ -1,6 +1,12 @@
import { task } from 'hardhat/config';
import { DRE, setDRE } from '../../helpers/misc-utils';
import { EthereumNetworkNames } from '../../helpers/types';
import { usingTenderly } from '../../helpers/tenderly-utils';
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { getFirstSigner } from '../../helpers/contracts-getters';
import { formatEther } from 'ethers/lib/utils';
import { fork } from 'child_process';
import { env } from 'process';
task(`set-DRE`, `Inits the DRE, to have access to all the plugins' objects`).setAction(
async (_, _DRE) => {
@ -12,21 +18,24 @@ task(`set-DRE`, `Inits the DRE, to have access to all the plugins' objects`).set
process.env.TENDERLY === 'true'
) {
console.log('- Setting up Tenderly provider');
const net = _DRE.tenderly.network();
if (process.env.TENDERLY_FORK_ID && process.env.TENDERLY_HEAD_ID) {
console.log('- Connecting to a Tenderly Fork');
await net.setFork(process.env.TENDERLY_FORK_ID);
await net.setHead(process.env.TENDERLY_HEAD_ID);
_DRE.tenderlyRPC.setFork(process.env.TENDERLY_FORK_ID);
_DRE.tenderlyRPC.setHead(process.env.TENDERLY_HEAD_ID);
} else {
console.log('- Creating a new Tenderly Fork');
await net.initializeFork();
await _DRE.tenderlyRPC.initializeFork();
}
const provider = new _DRE.ethers.providers.Web3Provider(net);
const provider = new _DRE.ethers.providers.Web3Provider(_DRE.tenderlyRPC as any);
_DRE.ethers.provider = provider;
console.log('- Initialized Tenderly fork:');
console.log(' - Fork: ', net.getFork());
console.log(' - Head: ', net.getHead());
console.log(' - Fork: ', _DRE.tenderlyRPC.getFork());
console.log(' - Head: ', _DRE.tenderlyRPC.getHead());
console.log(' - First account:', await (await _DRE.ethers.getSigners())[0].getAddress());
console.log(
' - Balance:',
formatEther(await (await _DRE.ethers.getSigners())[0].getBalance())
);
}
console.log('- Enviroment');
@ -41,7 +50,6 @@ task(`set-DRE`, `Inits the DRE, to have access to all the plugins' objects`).set
}
}
console.log(' - Network :', _DRE.network.name);
setDRE(_DRE);
return _DRE;
}

View File

@ -4,7 +4,6 @@ import {
insertContractAddressInDb,
getEthersSigners,
registerContractInJsonDb,
getEthersSignersAddresses,
} from '../../helpers/contracts-helpers';
import {
deployLendingPoolAddressesProvider,
@ -103,7 +102,10 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
//setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
const addressList = await getEthersSignersAddresses();
// .. users[2] as risk admin .. position 3
const addressList: string[] = await Promise.all(
(await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
);
await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));

View File

@ -0,0 +1,521 @@
import BigNumber from 'bignumber.js';
import { TestEnv, makeSuite } from './helpers/make-suite';
import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../../helpers/constants';
import { convertToCurrencyDecimals, getContract } from '../../helpers/contracts-helpers';
import { ethers } from 'ethers';
import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
import { ProtocolErrors, eContractid } from '../../helpers/types';
import { VariableDebtToken } from '../../types/VariableDebtToken';
import { StableDebtToken } from '../../types/StableDebtToken';
import {
getMockFlashLoanReceiver,
getStableDebtToken,
getVariableDebtToken,
} from '../../helpers/contracts-getters';
const { expect } = require('chai');
makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
const {
VL_COLLATERAL_BALANCE_IS_0,
TRANSFER_AMOUNT_EXCEEDS_BALANCE,
LP_INVALID_FLASHLOAN_MODE,
SAFEERC20_LOWLEVEL_CALL,
LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN,
LP_BORROW_ALLOWANCE_NOT_ENOUGH,
} = ProtocolErrors;
before(async () => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
});
it('Authorize flash borowers', async () => {
const { deployer, pool, weth, configurator, users } = testEnv;
await configurator.authorizeFlashBorrower(deployer.address);
await configurator.authorizeFlashBorrower(users[1].address);
await configurator.authorizeFlashBorrower(users[2].address);
await configurator.authorizeFlashBorrower(users[3].address);
await configurator.authorizeFlashBorrower(users[4].address);
await configurator.authorizeFlashBorrower(users[5].address);
});
it('Deposits WETH into the reserve', async () => {
const { pool, weth } = testEnv;
const userAddress = await pool.signer.getAddress();
const amountToDeposit = ethers.utils.parseEther('1');
await weth.mint(amountToDeposit);
await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.deposit(weth.address, amountToDeposit, userAddress, '0');
});
it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
const { pool, helpersContract, weth } = testEnv;
await pool.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[ethers.utils.parseEther('0.8')],
[0],
_mockFlashLoanReceiver.address,
'0x10',
'0'
);
ethers.utils.parseUnits('10000');
const reserveData = await helpersContract.getReserveData(weth.address);
const currentLiquidityRate = reserveData.liquidityRate;
const currentLiquidityIndex = reserveData.liquidityIndex;
const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidity.toString()).to.be.equal('1000000000000000000');
expect(currentLiquidityRate.toString()).to.be.equal('0');
expect(currentLiquidityIndex.toString()).to.be.equal('1000000000000000000000000000');
});
it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
const { pool, helpersContract, weth } = testEnv;
const reserveDataBefore = await helpersContract.getReserveData(weth.address);
const txResult = await pool.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
['1000000000000000000'],
[0],
_mockFlashLoanReceiver.address,
'0x10',
'0'
);
const reserveData = await helpersContract.getReserveData(weth.address);
const currentLiqudityRate = reserveData.liquidityRate;
const currentLiquidityIndex = reserveData.liquidityIndex;
const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidity.toString()).to.be.equal('1000000000000000000');
expect(currentLiqudityRate.toString()).to.be.equal('0');
expect(currentLiquidityIndex.toString()).to.be.equal('1000000000000000000000000000');
});
it('Takes WETH flashloan, does not return the funds with mode = 0. (revert expected)', async () => {
const { pool, weth, users } = testEnv;
const caller = users[1];
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[ethers.utils.parseEther('0.8')],
[0],
caller.address,
'0x10',
'0'
)
).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
});
it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => {
const { pool, weth, users } = testEnv;
const caller = users[1];
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await _mockFlashLoanReceiver.setSimulateEOA(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[ethers.utils.parseEther('0.8')],
[0],
caller.address,
'0x10',
'0'
)
).to.be.revertedWith(LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN);
});
it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
const { pool, weth, users } = testEnv;
const caller = users[1];
await _mockFlashLoanReceiver.setSimulateEOA(false);
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[ethers.utils.parseEther('0.8')],
[4],
caller.address,
'0x10',
'0'
)
).to.be.reverted;
});
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, helpersContract } = testEnv;
const caller = users[1];
await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
const borrowedAmount = await convertToCurrencyDecimals(weth.address, '0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[borrowedAmount],
[2],
caller.address,
'0x10',
'0'
);
const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
weth.address
);
ethers.utils.parseUnits('10000');
const fees = 0;
const reserveData = await helpersContract.getReserveData(weth.address);
let totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidity.toString()).to.be.equal(
ethers.BigNumber.from('1000000000000000000').add(fees)
);
const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
const callerDebt = await wethDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
});
it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
const { pool, weth, users } = testEnv;
const caller = users[1];
await expect(
pool.connect(caller.signer).flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
['1000000000000000001'], //slightly higher than the available liquidity
[2],
caller.address,
'0x10',
'0'
),
TRANSFER_AMOUNT_EXCEEDS_BALANCE
).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
});
it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
const { pool, deployer, weth, users } = testEnv;
const caller = users[1];
await expect(
pool.flashLoan(
deployer.address,
[weth.address],
['1000000000000000000'],
[2],
caller.address,
'0x10',
'0'
)
).to.be.reverted;
});
it('Deposits USDC into the reserve', async () => {
const { usdc, pool } = testEnv;
const userAddress = await pool.signer.getAddress();
await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
await pool.deposit(usdc.address, amountToDeposit, userAddress, '0');
});
it('Takes out a 500 USDC flashloan, returns the funds correctly', async () => {
const { usdc, pool, helpersContract, deployer: depositor } = testEnv;
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
const reserveDataBefore = await helpersContract.getReserveData(usdc.address);
const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
await pool.flashLoan(
_mockFlashLoanReceiver.address,
[usdc.address],
[flashloanAmount],
[0],
_mockFlashLoanReceiver.address,
'0x10',
'0'
);
const reserveDataAfter = helpersContract.getReserveData(usdc.address);
const reserveData = await helpersContract.getReserveData(usdc.address);
const userData = await helpersContract.getUserReserveData(usdc.address, depositor.address);
const totalLiquidity = reserveData.availableLiquidity
.add(reserveData.totalStableDebt)
.add(reserveData.totalVariableDebt)
.toString();
const currentLiqudityRate = reserveData.liquidityRate.toString();
const currentLiquidityIndex = reserveData.liquidityIndex.toString();
const currentUserBalance = userData.currentATokenBalance.toString();
const expectedLiquidity = await convertToCurrencyDecimals(usdc.address, '1000');
expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
expect(currentLiquidityIndex).to.be.equal(
new BigNumber('1.00000').multipliedBy(oneRay).toFixed(),
'Invalid liquidity index'
);
expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
});
it('Takes out a 500 USDC flashloan with mode = 0, does not return the funds. (revert expected)', async () => {
const { usdc, pool, users } = testEnv;
const caller = users[2];
const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[usdc.address],
[flashloanAmount],
[2],
caller.address,
'0x10',
'0'
)
).to.be.revertedWith(VL_COLLATERAL_BALANCE_IS_0);
});
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, helpersContract } = testEnv;
const caller = users[2];
await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '5'));
await weth.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(weth.address, '5');
await pool.connect(caller.signer).deposit(weth.address, amountToDeposit, caller.address, '0');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
await pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[usdc.address],
[flashloanAmount],
[2],
caller.address,
'0x10',
'0'
);
const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
usdc.address
);
const usdcDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
const callerDebt = await usdcDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
});
it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
const { dai, pool, weth, users } = testEnv;
const caller = users[3];
await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
const flashAmount = ethers.utils.parseEther('0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
await _mockFlashLoanReceiver.setAmountToApprove(flashAmount.div(2));
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashAmount],
[0],
caller.address,
'0x10',
'0'
)
).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
});
it('Caller takes a WETH flashloan with mode = 1', async () => {
const { dai, pool, weth, users, helpersContract } = testEnv;
const caller = users[3];
const flashAmount = ethers.utils.parseEther('0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashAmount],
[1],
caller.address,
'0x10',
'0'
);
const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
weth.address
);
const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
const callerDebt = await wethDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
});
it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user without allowance', async () => {
const { dai, pool, weth, users, helpersContract } = testEnv;
const caller = users[5];
const onBehalfOf = users[4];
// Deposit 1000 dai for onBehalfOf user
await dai.connect(onBehalfOf.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
await dai.connect(onBehalfOf.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await pool
.connect(onBehalfOf.signer)
.deposit(dai.address, amountToDeposit, onBehalfOf.address, '0');
const flashAmount = ethers.utils.parseEther('0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashAmount],
[1],
onBehalfOf.address,
'0x10',
'0'
)
).to.be.revertedWith(LP_BORROW_ALLOWANCE_NOT_ENOUGH);
});
it('Caller takes a WETH flashloan with mode = 1 onBehalfOf user with allowance. A loan for onBehalfOf is creatd.', async () => {
const { dai, pool, weth, users, helpersContract } = testEnv;
const caller = users[5];
const onBehalfOf = users[4];
const flashAmount = ethers.utils.parseEther('0.8');
const reserveData = await pool.getReserveData(weth.address);
const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress);
// Deposited for onBehalfOf user already, delegate borrow allowance
await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashAmount],
[1],
onBehalfOf.address,
'0x10',
'0'
);
const { stableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
weth.address
);
const wethDebtToken = await getStableDebtToken(stableDebtTokenAddress);
const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
expect(onBehalfOfDebt.toString()).to.be.equal(
'800000000000000000',
'Invalid onBehalfOf user debt'
);
});
});

View File

@ -16,9 +16,10 @@ const { expect } = require('chai');
makeSuite('Borrow Cap', (testEnv: TestEnv) => {
const { VL_BORROW_CAP_EXCEEDED, RC_INVALID_BORROW_CAP } = ProtocolErrors;
const unitParse = async (token: WETH9Mocked | MintableERC20, nb: string) =>
const miliUnitToPrecision = async (token: WETH9Mocked | MintableERC20, nb: string) =>
BigNumber.from(nb).mul(BigNumber.from('10').pow((await token.decimals()) - 3));
it('Reserves should initially have borrow cap disabled (borrowCap = 0)', async () => {
it('Sets the borrow cap for Weth and DAI to 0 Units, deposits weth', async () => {
const {
configurator,
weth,
@ -29,111 +30,61 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
helpersContract,
users: [user1],
} = testEnv;
const mintedAmount = parseEther('1000000000');
// minting for main user
await dai.mint(mintedAmount);
await weth.mint(mintedAmount);
await usdc.mint(mintedAmount);
// minting for lp user
await dai.connect(user1.signer).mint(mintedAmount);
await weth.connect(user1.signer).mint(mintedAmount);
await usdc.connect(user1.signer).mint(mintedAmount);
const mintedMiliAmount = '1000000000000';
const daiMinted = await miliUnitToPrecision(dai, mintedMiliAmount);
const wethMinted = await miliUnitToPrecision(weth, mintedMiliAmount);
const usdcMinted = await miliUnitToPrecision(usdc, mintedMiliAmount);
await dai.mint(daiMinted);
await weth.mint(wethMinted);
await usdc.mint(usdcMinted);
await dai.connect(user1.signer).mint(daiMinted);
await weth.connect(user1.signer).mint(wethMinted);
await usdc.connect(user1.signer).mint(usdcMinted);
await dai.approve(pool.address, MAX_UINT_AMOUNT);
await weth.approve(pool.address, MAX_UINT_AMOUNT);
await usdc.approve(pool.address, MAX_UINT_AMOUNT);
await dai.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT);
await weth.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT);
await usdc.connect(user1.signer).approve(pool.address, MAX_UINT_AMOUNT);
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(MAX_BORROW_CAP);
expect(daiBorrowCap).to.be.equal(MAX_BORROW_CAP);
let wethBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
let wethSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(wethBorrowCap).to.be.equal(MAX_BORROW_CAP);
expect(wethSupplyCap).to.be.equal(MAX_SUPPLY_CAP);
expect(usdcBorrowCap).to.be.equal('0');
expect(daiBorrowCap).to.be.equal('0');
});
it('Should be able to borrow 10 Dai stable, 10 USDC variable', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
helpersContract,
users: [user1],
} = testEnv;
const depositedMiliAmount = (1e9).toString();
const suppliedAmount = 1000;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
await configurator.setBorrowCap(usdc.address, 0);
await configurator.setBorrowCap(dai.address, 0);
const borrowedAmount = 10;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(0);
expect(daiBorrowCap).to.be.equal(0);
// deposit collateral
await pool.deposit(
weth.address,
await unitParse(weth, precisionSuppliedAmount),
await miliUnitToPrecision(weth, depositedMiliAmount),
deployer.address,
0
);
// user 1 deposit more dai and usdc to be able to borrow
await pool
.connect(user1.signer)
.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), user1.address, 0);
await pool
.connect(user1.signer)
.deposit(usdc.address, await unitParse(usdc, precisionSuppliedAmount), user1.address, 0);
// borrow
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
2,
0,
deployer.address
);
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
1,
0,
deployer.address
);
});
it('Sets the borrow cap for Weth and DAI to 10 Units', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
helpersContract,
users: [user1],
} = testEnv;
await configurator.setBorrowCap(usdc.address, 10);
await configurator.setBorrowCap(dai.address, 10);
const usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
const daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(10);
expect(daiBorrowCap).to.be.equal(10);
await pool.connect(user1.signer).deposit(weth.address, wethMinted, user1.address, 0);
await pool.connect(user1.signer).deposit(dai.address, daiMinted, user1.address, 0);
await pool.connect(user1.signer).deposit(usdc.address, usdcMinted, user1.address, 0);
});
it('should fail to borrow any dai or usdc, stable or variable', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 10;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
2,
0,
deployer.address
@ -143,7 +94,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
2,
0,
deployer.address
@ -153,6 +104,11 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('Should fail to set the borrow cap for usdc and DAI to max cap + 1 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = Number(MAX_BORROW_CAP) + 1;
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(0);
expect(daiBorrowCap).to.be.equal(0);
await expect(configurator.setBorrowCap(usdc.address, newCap)).to.be.revertedWith(
RC_INVALID_BORROW_CAP
@ -160,16 +116,24 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await expect(configurator.setBorrowCap(dai.address, newCap)).to.be.revertedWith(
RC_INVALID_BORROW_CAP
);
usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
});
it('Sets the borrow cap for usdc and DAI to 120 Units', async () => {
it('Sets the borrow cap for usdc and DAI to 110 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '120';
const newCap = '110';
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(0);
expect(daiBorrowCap).to.be.equal(0);
await configurator.setBorrowCap(usdc.address, newCap);
await configurator.setBorrowCap(dai.address, newCap);
const usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
const daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
expect(usdcBorrowCap).to.be.equal(newCap);
expect(daiBorrowCap).to.be.equal(newCap);
@ -177,10 +141,10 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('Should succeed to borrow 10 stable dai and 10 variable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 10;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
2,
0,
deployer.address
@ -188,7 +152,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
1,
0,
deployer.address
@ -197,12 +161,12 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('should fail to borrow 100 variable dai and 100 stable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 100;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
1,
0,
deployer.address
@ -212,7 +176,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
2,
0,
deployer.address
@ -222,10 +186,10 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('Should succeed to borrow 99 variable dai and 99 stable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 99;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
2,
0,
deployer.address
@ -233,7 +197,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
1,
0,
deployer.address
@ -257,11 +221,11 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('should succeed to borrow 100 variable dai and 100 stable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 100;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
1,
0,
deployer.address
@ -269,7 +233,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
2,
0,
deployer.address
@ -293,12 +257,12 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('should fail to borrow 100 variable dai and 100 stable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 100;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
1,
0,
deployer.address
@ -308,7 +272,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
2,
0,
deployer.address
@ -333,11 +297,11 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
it('should succeed to borrow 100 variable dai and 100 stable usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const borrowedAmount = 100;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
const borrowedMilimount = (borrowedAmount * 1000).toString();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
await miliUnitToPrecision(usdc, borrowedMilimount),
1,
0,
deployer.address
@ -345,7 +309,7 @@ makeSuite('Borrow Cap', (testEnv: TestEnv) => {
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
await miliUnitToPrecision(dai, borrowedMilimount),
2,
0,
deployer.address

View File

@ -73,6 +73,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(await configurator.signer.getAddress()).to.be.equal(
await addressesProvider.getPoolAdmin()
);
await configurator.pauseReserve(weth.address);
const {
decimals,
@ -134,150 +135,14 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Pauses the ETH reserve by emergency admin', async () => {
const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } =
testEnv;
await configurator.connect(emergencyAdmin.signer).pauseReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(true);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Unpauses the ETH reserve by emergency admin ', async () => {
const { configurator, helpersContract, weth, users, emergencyAdmin } = testEnv;
await configurator.connect(emergencyAdmin.signer).unpauseReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the only admin or emergency admin can pauseReserve ', async () => {
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(riskAdmin.signer).pauseReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Check the only admin or emergency admin can unpauseReserve ', async () => {
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(riskAdmin.signer).unpauseReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Pauses the ETH reserve by the pool admin', async () => {
const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } =
testEnv;
await configurator.pauseReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(true);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Unpauses the ETH reserve by pool admin ', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.unpauseReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Pauses the ETH reserve by emergency admin', async () => {
const { configurator, weth, helpersContract, addressesProvider, users, emergencyAdmin } =
testEnv;
configurator,
weth,
helpersContract,
addressesProvider,
users,
emergencyAdmin,
} = testEnv;
await configurator.connect(emergencyAdmin.signer).pauseReserve(weth.address);
const {
decimals,
@ -355,7 +220,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Freezes the ETH reserve by pool Admin', async () => {
it('Freezes the ETH reserve', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.freezeReserve(weth.address);
@ -387,7 +252,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Unfreezes the ETH reserve by Pool admin', async () => {
it('Unfreezes the ETH reserve', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.unfreezeReserve(weth.address);
@ -418,83 +283,21 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Freezes the ETH reserve by Risk Admin', async () => {
const { configurator, weth, helpersContract, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).freezeReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(true);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Unfreezes the ETH reserve by Risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).unfreezeReserve(weth.address);
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyRiskOrPoolAdmins on freezeReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
it('Check the onlyAaveAdmin on freezeReserve ', async () => {
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).freezeReserve(weth.address),
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
configurator.connect(riskAdmin.signer).freezeReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Check the onlyRiskOrPoolAdmins on unfreezeReserve ', async () => {
const { configurator, users, weth, emergencyAdmin } = testEnv;
it('Check the onlyAaveAdmin on unfreezeReserve ', async () => {
const { configurator, users, weth, riskAdmin } = testEnv;
await expect(
configurator.connect(emergencyAdmin.signer).unfreezeReserve(weth.address),
LPC_CALLER_NOT_RISK_OR_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_RISK_OR_POOL_ADMIN);
configurator.connect(riskAdmin.signer).unfreezeReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Deactivates the ETH reserve for borrowing via pool admin', async () => {
@ -530,7 +333,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Activates the ETH reserve for borrowing via pool admin', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.enableBorrowingOnReserve(weth.address, '0', true);
await configurator.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
@ -596,7 +399,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Activates the ETH reserve for borrowing via risk admin', async () => {
const { configurator, weth, helpersContract, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).enableBorrowingOnReserve(weth.address, '0', true);
await configurator
.connect(riskAdmin.signer)
.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
@ -1011,45 +816,15 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
expect(reserveFactor).to.be.equal(1000);
});
it('Changes the reserve factor of WETH risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).setReserveFactor(weth.address, '1000');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
expect(reserveFactor).to.be.equal(1000);
});
it('Check that borrowCap cannot be set to value that exceeds the MAX_BORROW_CAP', async () => {
it('Fails to change to too high borrowCap', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.setBorrowCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(RC_INVALID_BORROW_CAP);
});
it('Check that supplyCap cannot be set to value that exceeds the MAX_SUPPLY_CAP', async () => {
it('Fails to change to too high supplyCap', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.setSupplyCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)),
@ -1178,36 +953,6 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal('3000000');
});
it('Changes the supply Cap of WETH via risk admin', async () => {
const { configurator, helpersContract, weth, riskAdmin } = testEnv;
await configurator.connect(riskAdmin.signer).setSupplyCap(weth.address, '3000000');
const {
decimals,
ltv,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
const isPaused = await helpersContract.getPaused(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
expect(isPaused).to.be.equal(false);
expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000);
expect(borrowCap).to.be.equal('3000000');
expect(supplyCap).to.be.equal('3000000');
});
it('Reverts when trying to disable the DAI reserve with liquidity on it', async () => {
const { dai, pool, configurator } = testEnv;
@ -1267,14 +1012,14 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Authorized a new flash borrower', async () => {
it('Authorized a new flashborrower', async () => {
const { dai, pool, configurator, users, riskAdmin } = testEnv;
await configurator.authorizeFlashBorrower(users[4].address);
const isFlashBorrowerAuthorized = await pool.isFlashBorrowerAuthorized(users[4].address);
expect(isFlashBorrowerAuthorized).to.be.true;
});
it('Unauthorized flash borrower', async () => {
it('Unauthorized flashborrower', async () => {
const { dai, pool, configurator, users } = testEnv;
await configurator.unauthorizeFlashBorrower(users[4].address);

View File

@ -1,7 +1,7 @@
import BigNumber from 'bignumber.js';
import { TestEnv, makeSuite } from './helpers/make-suite';
import { APPROVAL_AMOUNT_LENDING_POOL, MAX_UINT_AMOUNT, oneRay } from '../../helpers/constants';
import { APPROVAL_AMOUNT_LENDING_POOL, oneRay } from '../../helpers/constants';
import { convertToCurrencyDecimals, getContract } from '../../helpers/contracts-helpers';
import { ethers } from 'ethers';
import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
@ -31,8 +31,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
});
it('Deposits WETH and AAVE into the reserve', async () => {
const { pool, weth, aave } = testEnv;
it('Deposits WETH into the reserve', async () => {
const { pool, weth } = testEnv;
const userAddress = await pool.signer.getAddress();
const amountToDeposit = ethers.utils.parseEther('1');
@ -41,30 +41,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.deposit(weth.address, amountToDeposit, userAddress, '0');
await aave.mint(amountToDeposit);
await aave.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.deposit(aave.address, amountToDeposit, userAddress, '0');
});
it('Takes WETH flash loan with mode = 0, returns the funds correctly', async () => {
it('Takes WETH flashloan with mode = 0, returns the funds correctly', async () => {
const { pool, helpersContract, weth } = testEnv;
const flashBorrowedAmount = ethers.utils.parseEther('0.8');
const fees = new BigNumber(flashBorrowedAmount.mul(9).div(10000).toString());
let reserveData = await helpersContract.getReserveData(weth.address);
const totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
await pool.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashBorrowedAmount],
[ethers.utils.parseEther('0.8')],
[0],
_mockFlashLoanReceiver.address,
'0x10',
@ -73,63 +58,19 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
ethers.utils.parseUnits('10000');
reserveData = await helpersContract.getReserveData(weth.address);
const reserveData = await helpersContract.getReserveData(weth.address);
const currentLiquidityRate = reserveData.liquidityRate;
const currentLiquidityIndex = reserveData.liquidityIndex;
const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidityBefore.plus(fees).toString()).to.be.equal(totalLiquidityAfter.toString());
expect(totalLiquidity.toString()).to.be.equal('1000720000000000000');
expect(currentLiquidityRate.toString()).to.be.equal('0');
expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
});
it('Takes an authorized AAVE flash loan with mode = 0, returns the funds correctly', async () => {
const {
pool,
helpersContract,
aave,
configurator,
users: [, , , authorizedUser],
} = testEnv;
await configurator.authorizeFlashBorrower(authorizedUser.address);
const flashBorrowedAmount = ethers.utils.parseEther('0.8');
const fees = new BigNumber(0);
let reserveData = await helpersContract.getReserveData(aave.address);
const totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
await pool
.connect(authorizedUser.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[aave.address],
[flashBorrowedAmount],
[0],
_mockFlashLoanReceiver.address,
'0x10',
'0'
);
ethers.utils.parseUnits('10000');
reserveData = await helpersContract.getReserveData(aave.address);
const currentLiquidityRate = reserveData.liquidityRate;
const currentLiquidityIndex = reserveData.liquidityIndex;
const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidityBefore.plus(fees).toString()).to.be.equal(totalLiquidityAfter.toString());
});
it('Takes an ETH flashloan with mode = 0 as big as the available liquidity', async () => {
const { pool, helpersContract, weth } = testEnv;
@ -238,12 +179,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
let reserveData = await helpersContract.getReserveData(weth.address);
let totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
await pool
.connect(caller.signer)
.flashLoan(
@ -262,89 +197,20 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const fees = borrowedAmount.mul(9).div(10000);
reserveData = await helpersContract.getReserveData(weth.address);
const reserveData = await helpersContract.getReserveData(weth.address);
const totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
const totalLiquidity = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidityAfter.toString()).to.be.equal(
ethers.BigNumber.from(totalLiquidityBefore.toString()).add(fees)
expect(totalLiquidity.toString()).to.be.equal(
ethers.BigNumber.from('1001620648000000000').add(fees)
);
const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
const callerDebt = await wethDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal(
borrowedAmount.add(fees).toString(),
'Invalid user debt'
);
// repays debt for later, so no interest accrue
await weth.connect(caller.signer).mint(await convertToCurrencyDecimals(weth.address, '1000'));
await weth.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(caller.signer).repay(weth.address, MAX_UINT_AMOUNT, 2, caller.address);
});
it('Authorized borrower 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: [, , , authorizedUser],
helpersContract,
} = testEnv;
const caller = authorizedUser;
await dai.connect(caller.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
await dai.connect(caller.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const amountToDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await pool.connect(caller.signer).deposit(dai.address, amountToDeposit, caller.address, '0');
const borrowedAmount = await convertToCurrencyDecimals(weth.address, '0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
let reserveData = await helpersContract.getReserveData(weth.address);
let totalLiquidityBefore = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
await pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[borrowedAmount],
[2],
caller.address,
'0x10',
'0'
);
const { variableDebtTokenAddress } = await helpersContract.getReserveTokensAddresses(
weth.address
);
ethers.utils.parseUnits('10000');
const fees = 0;
reserveData = await helpersContract.getReserveData(weth.address);
let totalLiquidityAfter = new BigNumber(reserveData.availableLiquidity.toString())
.plus(reserveData.totalStableDebt.toString())
.plus(reserveData.totalVariableDebt.toString());
expect(totalLiquidityAfter.toString()).to.be.equal(totalLiquidityBefore.toString());
const wethDebtToken = await getVariableDebtToken(variableDebtTokenAddress);
const callerDebt = await wethDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
});
@ -478,7 +344,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
await _mockFlashLoanReceiver.setFailExecutionTransfer(false);
const flashloanAmount = await convertToCurrencyDecimals(usdc.address, '500');
const fees = flashloanAmount.mul(9).div(10000);
await pool
.connect(caller.signer)
@ -500,7 +365,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const callerDebt = await usdcDebtToken.balanceOf(caller.address);
expect(callerDebt.toString()).to.be.equal(flashloanAmount.add(fees), 'Invalid user debt');
expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
});
it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
@ -610,16 +475,13 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const onBehalfOf = users[4];
const flashAmount = ethers.utils.parseEther('0.8');
const fees = flashAmount.mul(9).div(10000);
const reserveData = await pool.getReserveData(weth.address);
const stableDebtToken = await getStableDebtToken(reserveData.stableDebtTokenAddress);
// Deposited for onBehalfOf user already, delegate borrow allowance
await stableDebtToken
.connect(onBehalfOf.signer)
.approveDelegation(caller.address, flashAmount.add(fees));
await stableDebtToken.connect(onBehalfOf.signer).approveDelegation(caller.address, flashAmount);
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
@ -644,7 +506,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const onBehalfOfDebt = await wethDebtToken.balanceOf(onBehalfOf.address);
expect(onBehalfOfDebt.toString()).to.be.equal(
flashAmount.add(fees),
'800000000000000000',
'Invalid onBehalfOf user debt'
);
});

View File

@ -172,7 +172,7 @@ export async function initializeMakeSuite() {
const setSnapshot = async () => {
const hre = DRE as HardhatRuntimeEnvironment;
if (usingTenderly()) {
setBuidlerevmSnapshotId((await hre.tenderlyNetwork.getHead()) || '0x1');
setBuidlerevmSnapshotId((await hre.tenderlyRPC.getHead()) || '0x1');
return;
}
setBuidlerevmSnapshotId(await evmSnapshot());
@ -181,7 +181,7 @@ const setSnapshot = async () => {
const revertHead = async () => {
const hre = DRE as HardhatRuntimeEnvironment;
if (usingTenderly()) {
await hre.tenderlyNetwork.setHead(buidlerevmSnapshotId);
await hre.tenderlyRPC.setHead(buidlerevmSnapshotId);
return;
}
await evmRevert(buidlerevmSnapshotId);

View File

@ -12,14 +12,17 @@ const { expect } = require('chai');
makeSuite('Pausable Pool', (testEnv: TestEnv) => {
let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
const { LP_IS_PAUSED, INVALID_FROM_BALANCE_AFTER_TRANSFER, INVALID_TO_BALANCE_AFTER_TRANSFER } =
ProtocolErrors;
const {
LP_IS_PAUSED,
INVALID_FROM_BALANCE_AFTER_TRANSFER,
INVALID_TO_BALANCE_AFTER_TRANSFER,
} = ProtocolErrors;
before(async () => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
});
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => {
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');

View File

@ -22,8 +22,7 @@ makeSuite('Pause Reserve', (testEnv: TestEnv) => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
});
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => {
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');

View File

@ -15,10 +15,10 @@ const { expect } = require('chai');
makeSuite('supply Cap', (testEnv: TestEnv) => {
const { VL_SUPPLY_CAP_EXCEEDED, RC_INVALID_SUPPLY_CAP } = ProtocolErrors;
const unitParse = async (token: WETH9Mocked | MintableERC20, nb: string) =>
const miliUnitToPrecision = async (token: WETH9Mocked | MintableERC20, nb: string) =>
BigNumber.from(nb).mul(BigNumber.from('10').pow((await token.decimals()) - 3));
it('Reserves should initially have supply cap disabled (supplyCap = 0)', async () => {
it('Sets the supply cap for Weth and DAI to 0 Units, deposits weth', async () => {
const {
configurator,
weth,
@ -29,101 +29,61 @@ makeSuite('supply Cap', (testEnv: TestEnv) => {
helpersContract,
users: [user1],
} = testEnv;
const mintedAmount = parseEther('1000000000');
await dai.mint(mintedAmount);
await weth.mint(mintedAmount);
await usdc.mint(mintedAmount);
await dai.approve(pool.address, MAX_UINT_AMOUNT);
await weth.approve(pool.address, MAX_UINT_AMOUNT);
await usdc.approve(pool.address, MAX_UINT_AMOUNT);
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
let usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcsupplyCap).to.be.equal(MAX_SUPPLY_CAP);
expect(daisupplyCap).to.be.equal(MAX_SUPPLY_CAP);
expect(usdcSupplyCap).to.be.equal('0');
expect(daiSupplyCap).to.be.equal('0');
});
it('Should be able to deposit 1000 Dai, 1000 USDC and 1000 Weth', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
helpersContract,
users: [user1],
} = testEnv;
const depositedMiliAmount = (1e9).toString();
const suppliedAmount = 1000;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
await configurator.setSupplyCap(usdc.address, 0);
await configurator.setSupplyCap(dai.address, 0);
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
deployer.address,
0
);
await pool.deposit(
weth.address,
await unitParse(weth, precisionSuppliedAmount),
deployer.address,
0
);
});
it('Sets the supply cap for Weth and DAI to 1000 Unit', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
helpersContract,
users: [user1],
} = testEnv;
const newCap = '1000';
await configurator.setSupplyCap(usdc.address, newCap);
await configurator.setSupplyCap(dai.address, newCap);
const usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
const daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcSupplyCap).to.be.equal(newCap);
expect(daiSupplyCap).to.be.equal(newCap);
expect(usdcsupplyCap).to.be.equal(0);
expect(daisupplyCap).to.be.equal(0);
});
it('should fail to supply any dai or usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 10;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), deployer.address, 0)
pool.deposit(
dai.address,
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
});
it('Should fail to set the supply cap for usdc and DAI to max cap + 1 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = Number(MAX_SUPPLY_CAP) + 1;
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcsupplyCap).to.be.equal(0);
expect(daisupplyCap).to.be.equal(0);
await expect(configurator.setSupplyCap(usdc.address, newCap)).to.be.revertedWith(
RC_INVALID_SUPPLY_CAP
@ -132,33 +92,38 @@ makeSuite('supply Cap', (testEnv: TestEnv) => {
RC_INVALID_SUPPLY_CAP
);
});
it('Sets the supply cap for usdc and DAI to 1110 Units', async () => {
it('Sets the supply cap for usdc and DAI to 110 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '1110';
const newCap = '110';
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcsupplyCap).to.be.equal(0);
expect(daisupplyCap).to.be.equal(0);
await configurator.setSupplyCap(usdc.address, newCap);
await configurator.setSupplyCap(dai.address, newCap);
const usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
const daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcSupplyCap).to.be.equal(newCap);
expect(daiSupplyCap).to.be.equal(newCap);
expect(usdcsupplyCap).to.be.equal(newCap);
expect(daisupplyCap).to.be.equal(newCap);
});
it('Should succeed to supply 10 dai and 10 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 10;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
);
@ -166,132 +131,144 @@ makeSuite('supply Cap', (testEnv: TestEnv) => {
it('should fail to supply 100 dai and 100 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 100;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), deployer.address, 0)
pool.deposit(
dai.address,
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
});
it('Should succeed to supply 99 dai and 99 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 99;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
);
});
it('Raises the supply cap for usdc and DAI to 2000 Units', async () => {
it('Raises the supply cap for usdc and DAI to 1000 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '2000';
const newCap = '1000';
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
await configurator.setSupplyCap(usdc.address, newCap);
await configurator.setSupplyCap(dai.address, newCap);
const usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
const daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcSupplyCap).to.be.equal(newCap);
expect(daiSupplyCap).to.be.equal(newCap);
expect(usdcsupplyCap).to.be.equal(newCap);
expect(daisupplyCap).to.be.equal(newCap);
});
it('should succeed to supply 100 dai and 100 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 100;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
);
});
it('Lowers the supply cap for usdc and DAI to 1200 Units', async () => {
it('Lowers the supply cap for usdc and DAI to 200 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '1200';
let usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
const newCap = '200';
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
await configurator.setSupplyCap(usdc.address, newCap);
await configurator.setSupplyCap(dai.address, newCap);
usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcSupplyCap).to.be.equal(newCap);
expect(daiSupplyCap).to.be.equal(newCap);
expect(usdcsupplyCap).to.be.equal(newCap);
expect(daisupplyCap).to.be.equal(newCap);
});
it('should fail to supply 100 dai and 100 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 100;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), deployer.address, 0)
pool.deposit(
dai.address,
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
});
it('Raises the supply cap for usdc and DAI to max cap Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = MAX_SUPPLY_CAP;
let usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
let usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
let daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
await configurator.setSupplyCap(usdc.address, newCap);
await configurator.setSupplyCap(dai.address, newCap);
usdcSupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daiSupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
usdcsupplyCap = (await helpersContract.getReserveCaps(usdc.address)).supplyCap;
daisupplyCap = (await helpersContract.getReserveCaps(dai.address)).supplyCap;
expect(usdcSupplyCap).to.be.equal(newCap);
expect(daiSupplyCap).to.be.equal(newCap);
expect(usdcsupplyCap).to.be.equal(newCap);
expect(daisupplyCap).to.be.equal(newCap);
});
it('should succeed to supply 100 dai and 100 usdc', async () => {
const { usdc, pool, dai, deployer, helpersContract } = testEnv;
const suppliedAmount = 100;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const suppliedMilimount = (suppliedAmount * 1000).toString();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
await miliUnitToPrecision(usdc, suppliedMilimount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
await miliUnitToPrecision(dai, suppliedMilimount),
deployer.address,
0
);

View File

@ -4,7 +4,6 @@ import {
insertContractAddressInDb,
getEthersSigners,
registerContractInJsonDb,
getEthersSignersAddresses,
} from '../../helpers/contracts-helpers';
import {
deployLendingPoolAddressesProvider,
@ -102,7 +101,9 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
await waitForTx(await addressesProvider.setPoolAdmin(aaveAdmin));
//setting users[1] as emergency admin, which is in position 2 in the DRE addresses list
const addressList = await getEthersSignersAddresses();
const addressList = await Promise.all(
(await DRE.ethers.getSigners()).map((signer) => signer.getAddress())
);
await waitForTx(await addressesProvider.setEmergencyAdmin(addressList[2]));

View File

@ -156,7 +156,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Activates the ETH reserve for borrowing', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.enableBorrowingOnReserve(weth.address, '0', true);
await configurator.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
@ -180,6 +180,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true /*strategyWETH.stableBorrowRateEnabled*/);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
});

View File

@ -163,7 +163,7 @@ export async function initializeMakeSuite() {
const setSnapshot = async () => {
const hre = DRE as HardhatRuntimeEnvironment;
if (usingTenderly()) {
setBuidlerevmSnapshotId((await hre.tenderlyNetwork.getHead()) || '0x1');
setBuidlerevmSnapshotId((await hre.tenderlyRPC.getHead()) || '0x1');
return;
}
setBuidlerevmSnapshotId(await evmSnapshot());
@ -172,7 +172,7 @@ const setSnapshot = async () => {
const revertHead = async () => {
const hre = DRE as HardhatRuntimeEnvironment;
if (usingTenderly()) {
await hre.tenderlyNetwork.setHead(buidlerevmSnapshotId);
await hre.tenderlyRPC.setHead(buidlerevmSnapshotId);
return;
}
await evmRevert(buidlerevmSnapshotId);

View File

@ -22,7 +22,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
});
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => {
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succees', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');

View File

@ -8,7 +8,7 @@
"noImplicitAny": false,
"resolveJsonModule": true
},
"include": ["./scripts", "./test", "./tasks", "./helpers", "test-suites/test-aave/uniswapAdapters.repay.spec.ts", "test-suites/test-aave/upgradeability.spec.ts", "test-suites/test-aave/variable-debt-token.spec.ts", "test-suites/test-aave/weth-gateway.spec.ts"],
"include": ["./scripts", "./test", "./tasks", "test-suites/test-aave/uniswapAdapters.repay.spec.ts", "test-suites/test-aave/upgradeability.spec.ts", "test-suites/test-aave/variable-debt-token.spec.ts", "test-suites/test-aave/weth-gateway.spec.ts"],
"files": [
"./hardhat.config.ts",
"./modules/tenderly/tenderly.d.ts",