Merge branch 'protocol-2.5' into fix/130-refactor-lp-configurator

This commit is contained in:
The3D 2021-05-28 20:21:34 +02:00
commit fe2e799fcf
21 changed files with 1213 additions and 95 deletions

View File

@ -31,6 +31,8 @@ contract ATokensAndRatesHelper is Ownable {
uint256 liquidationThreshold;
uint256 liquidationBonus;
uint256 reserveFactor;
uint256 borrowCap;
uint256 supplyCap;
bool stableBorrowingEnabled;
bool borrowingEnabled;
}
@ -77,9 +79,11 @@ contract ATokensAndRatesHelper is Ownable {
if (inputParams[i].borrowingEnabled) {
configurator.enableBorrowingOnReserve(
inputParams[i].asset,
inputParams[i].borrowCap,
inputParams[i].stableBorrowingEnabled
);
}
configurator.setSupplyCap(inputParams[i].asset, inputParams[i].supplyCap);
configurator.setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor);
}
}

View File

@ -127,6 +127,20 @@ interface ILendingPoolConfigurator {
**/
event ReserveFactorChanged(address indexed asset, uint256 factor);
/**
* @dev Emitted when the borrow cap of a reserve is updated
* @param asset The address of the underlying asset of the reserve
* @param borrowCap The new borrow cap
**/
event BorrowCapChanged(address indexed asset, uint256 borrowCap);
/**
* @dev Emitted when the supply cap of a reserve is updated
* @param asset The address of the underlying asset of the reserve
* @param supplyCap The new supply cap
**/
event SupplyCapChanged(address indexed asset, uint256 supplyCap);
/**
* @dev Emitted when the reserve decimals are updated
* @param asset The address of the underlying asset of the reserve
@ -204,9 +218,10 @@ interface ILendingPoolConfigurator {
/**
* @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, bool stableBorrowRateEnabled) external;
function enableBorrowingOnReserve(address asset, uint256 borrowCap, bool stableBorrowRateEnabled) external;
/**
* @dev Disables borrowing on a reserve
@ -287,4 +302,18 @@ interface ILendingPoolConfigurator {
* @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;
}

View File

@ -64,6 +64,7 @@ contract AaveProtocolDataProvider {
return aTokens;
}
// not returning borrow and supply caps for compatibility
function getReserveConfigurationData(address asset)
external
view
@ -80,18 +81,28 @@ contract AaveProtocolDataProvider {
bool isFrozen
)
{
DataTypes.ReserveConfigurationMap memory configuration =
DataTypes.ReserveConfigurationMap memory configuration =
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
.getParamsMemory();
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) =
configuration.getParamsMemory();
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) = configuration
.getFlagsMemory();
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) =
configuration.getFlagsMemory();
usageAsCollateralEnabled = liquidationThreshold > 0;
}
function getReserveCaps(address asset)
external
view
returns (uint256 borrowCap, uint256 supplyCap) {
(borrowCap, supplyCap) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
.getConfiguration(asset)
.getCapsMemory();
}
function getReserveData(address asset)
external
view

View File

@ -114,6 +114,10 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
reserveData.decimals,
reserveData.reserveFactor
) = baseData.configuration.getParamsMemory();
(
reserveData.borrowCap,
reserveData.supplyCap
) = baseData.configuration.getCapsMemory();
(
reserveData.isActive,
reserveData.isFrozen,

View File

@ -15,6 +15,8 @@ interface IUiPoolDataProvider {
uint256 reserveLiquidationThreshold;
uint256 reserveLiquidationBonus;
uint256 reserveFactor;
uint256 borrowCap;
uint256 supplyCap;
bool usageAsCollateralEnabled;
bool borrowingEnabled;
bool stableBorrowRateEnabled;

View File

@ -240,18 +240,20 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
}
/// @inheritdoc ILendingPoolConfigurator
function enableBorrowingOnReserve(address asset, bool stableBorrowRateEnabled)
external
override
onlyPoolAdmin
{
function enableBorrowingOnReserve(
address asset,
uint256 borrowCap,
bool stableBorrowRateEnabled
) external override onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setBorrowingEnabled(true);
currentConfig.setBorrowCap(borrowCap);
currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
_pool.setConfiguration(asset, currentConfig.data);
emit BorrowCapChanged(asset, borrowCap);
emit BorrowingEnabledOnReserve(asset, stableBorrowRateEnabled);
}
@ -389,7 +391,33 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit ReserveFactorChanged(asset, reserveFactor);
}
/// @inheritdoc ILendingPoolConfigurator
///@inheritdoc ILendingPoolConfigurator
function setBorrowCap(address asset, uint256 borrowCap) external override onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setBorrowCap(borrowCap);
_pool.setConfiguration(asset, currentConfig.data);
emit BorrowCapChanged(asset, borrowCap);
}
///@inheritdoc ILendingPoolConfigurator
function setSupplyCap(address asset, uint256 supplyCap) external override onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setSupplyCap(supplyCap);
_pool.setConfiguration(asset, currentConfig.data);
emit SupplyCapChanged(asset, supplyCap);
}
/**
* @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

View File

@ -19,6 +19,8 @@ library ReserveConfiguration {
uint256 constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // 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
/// @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;
@ -29,12 +31,16 @@ library ReserveConfiguration {
uint256 constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 116;
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;
/**
* @dev Sets the Loan to Value of the reserve
@ -264,6 +270,60 @@ library ReserveConfiguration {
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
}
/**
* @dev Sets the borrow cap of the reserve
* @param self The reserve configuration
* @param borrowCap The borrow cap
**/
function setBorrowCap(DataTypes.ReserveConfigurationMap memory self, uint256 borrowCap)
internal
pure
{
require(borrowCap <= MAX_VALID_BORROW_CAP, Errors.RC_INVALID_BORROW_CAP);
self.data = (self.data & BORROW_CAP_MASK) | (borrowCap << BORROW_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the borrow cap of the reserve
* @param self The reserve configuration
* @return The borrow cap
**/
function getBorrowCap(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (uint256)
{
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
}
/**
* @dev Sets the supply cap of the reserve
* @param self The reserve configuration
* @param supplyCap The supply cap
**/
function setSupplyCap(DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap)
internal
pure
{
require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.RC_INVALID_SUPPLY_CAP);
self.data = (self.data & SUPPLY_CAP_MASK) | (supplyCap << SUPPLY_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the supply cap of the reserve
* @param self The reserve configuration
* @return The supply cap
**/
function getSupplyCap(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (uint256)
{
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
}
/**
* @dev Gets the configuration flags of the reserve
* @param self The reserve configuration
@ -290,9 +350,9 @@ library ReserveConfiguration {
}
/**
* @dev Gets the configuration paramters of the reserve
* @dev Gets the configuration paramters of the reserve from storage
* @param self The reserve configuration
* @return The state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor
**/
function getParams(DataTypes.ReserveConfigurationMap storage self)
internal
@ -316,10 +376,28 @@ library ReserveConfiguration {
);
}
/**
* @dev Gets the caps paramters of the reserve from storage
* @param self The reserve configuration
* @return The state params representing borrow cap and supply cap.
**/
function getCaps(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (uint256, uint256)
{
uint256 dataLocal = self.data;
return (
(dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
/**
* @dev Gets the configuration paramters of the reserve from a memory object
* @param self The reserve configuration
* @return The state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor
**/
function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
internal
@ -341,6 +419,22 @@ library ReserveConfiguration {
);
}
/**
* @dev Gets the caps paramters of the reserve from a memory object
* @param self The reserve configuration
* @return The state params borrow cap and supply cap
**/
function getCapsMemory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256, uint256)
{
return (
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
/**
* @dev Gets the configuration flags of the reserve from a memory object
* @param self The reserve configuration
@ -363,4 +457,30 @@ library ReserveConfiguration {
(self.data & ~STABLE_BORROWING_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

@ -102,6 +102,10 @@ library Errors {
string public constant LP_NOT_CONTRACT = '78';
string public constant SDT_STABLE_DEBT_OVERFLOW = '79';
string public constant SDT_BURN_EXCEEDS_BALANCE = '80';
string public constant VL_BORROW_CAP_EXCEEDED = '81';
string public constant RC_INVALID_BORROW_CAP = '82';
string public constant VL_SUPPLY_CAP_EXCEEDED = '83';
string public constant RC_INVALID_SUPPLY_CAP = '84';
enum CollateralManagerErrors {
NO_ERROR,

View File

@ -14,6 +14,8 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
import {Errors} from '../helpers/Errors.sol';
import {Helpers} from '../helpers/Helpers.sol';
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
import {IVariableDebtToken} from '../../../interfaces/IVariableDebtToken.sol';
import {IStableDebtToken} from '../../../interfaces/IStableDebtToken.sol';
import {DataTypes} from '../types/DataTypes.sol';
/**
@ -39,14 +41,22 @@ library ValidationLogic {
* @param amount The amount to be deposited
*/
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) internal view {
(bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
(bool isActive, bool isFrozen, , ) = reserveConfiguration.getFlagsMemory();
(, , , uint256 reserveDecimals, ) = reserveConfiguration.getParamsMemory();
uint256 supplyCap = reserveConfiguration.getSupplyCapMemory();
require(amount != 0, Errors.VL_INVALID_AMOUNT);
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
require(
supplyCap == 0 ||
IERC20(reserve.aTokenAddress).totalSupply().add(amount).div(10**reserveDecimals) <
supplyCap,
Errors.VL_SUPPLY_CAP_EXCEEDED
);
}
/**
* @dev Validates a withdraw action
* @param reserve The reserve object
@ -57,7 +67,7 @@ library ValidationLogic {
DataTypes.ReserveData storage reserve,
uint256 amount,
uint256 userBalance
) internal view {
) external view {
require(amount != 0, Errors.VL_INVALID_AMOUNT);
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
@ -73,6 +83,10 @@ library ValidationLogic {
uint256 userBorrowBalanceETH;
uint256 availableLiquidity;
uint256 healthFactor;
uint256 totalSupplyStableDebt;
uint256 totalSupplyVariableDebt;
uint256 reserveDecimals;
uint256 borrowCap;
bool isActive;
bool isFrozen;
bool borrowingEnabled;
@ -110,9 +124,15 @@ library ValidationLogic {
) internal view {
ValidateBorrowLocalVars memory vars;
(vars.isActive, vars.isFrozen, vars.borrowingEnabled, vars.stableRateBorrowingEnabled) = reserve
.configuration
.getFlags();
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
(, , , vars.reserveDecimals, ) = reserveConfiguration.getParamsMemory();
(
vars.isActive,
vars.isFrozen,
vars.borrowingEnabled,
vars.stableRateBorrowingEnabled
) = reserveConfiguration.getFlagsMemory();
require(vars.isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!vars.isFrozen, Errors.VL_RESERVE_FROZEN);
@ -127,6 +147,19 @@ 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();
require(
vars.borrowCap == 0 ||
vars.totalSupplyStableDebt.add(vars.totalSupplyVariableDebt).add(amount).div(
10**vars.reserveDecimals
) <
vars.borrowCap,
Errors.VL_BORROW_CAP_EXCEEDED
);
(
vars.userCollateralBalanceETH,
vars.userBorrowBalanceETH,
@ -204,7 +237,7 @@ library ValidationLogic {
address onBehalfOf,
uint256 stableDebt,
uint256 variableDebt
) internal view {
) external view {
bool isActive = reserve.configuration.getActive();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
@ -313,9 +346,7 @@ library ValidationLogic {
* @dev Validates the action of setting an asset as collateral
* @param reserve The state of the reserve that the user is enabling or disabling as collateral
*/
function validateSetUseReserveAsCollateral(
DataTypes.ReserveData storage reserve
) external view {
function validateSetUseReserveAsCollateral(DataTypes.ReserveData storage reserve) external view {
uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
@ -326,7 +357,7 @@ library ValidationLogic {
* @param assets The assets being flashborrowed
* @param amounts The amounts for each asset being borrowed
**/
function validateFlashloan(address[] memory assets, uint256[] memory amounts) internal pure {
function validateFlashloan(address[] memory assets, uint256[] memory amounts) external pure {
require(assets.length == amounts.length, Errors.VL_INCONSISTENT_FLASHLOAN_PARAMS);
}

View File

@ -38,6 +38,8 @@ library DataTypes {
//bit 59: stable rate borrowing enabled
//bit 60-63: reserved
//bit 64-79: reserve factor
//bit 80-115 borrow cap, borrowCap == 0 => disabled
//bit 116-152 supply cap, supplyCap == 0 => disabled
uint256 data;
}

View File

@ -15,6 +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 ONE_YEAR = '31536000';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';

View File

@ -284,6 +284,8 @@ export const configureReservesByHelper = async (
liquidationThreshold: BigNumberish;
liquidationBonus: BigNumberish;
reserveFactor: BigNumberish;
borrowCap: BigNumberish;
supplyCap: BigNumberish;
stableBorrowingEnabled: boolean;
borrowingEnabled: boolean;
}[] = [];
@ -295,6 +297,8 @@ export const configureReservesByHelper = async (
liquidationBonus,
liquidationThreshold,
reserveFactor,
borrowCap,
supplyCap,
stableBorrowRateEnabled,
borrowingEnabled,
},
@ -326,9 +330,11 @@ export const configureReservesByHelper = async (
inputParams.push({
asset: tokenAddress,
baseLTV: baseLTVAsCollateral,
liquidationThreshold: liquidationThreshold,
liquidationBonus: liquidationBonus,
reserveFactor: reserveFactor,
liquidationThreshold,
liquidationBonus,
reserveFactor,
borrowCap,
supplyCap,
stableBorrowingEnabled: stableBorrowRateEnabled,
borrowingEnabled: borrowingEnabled,
});

View File

@ -177,6 +177,10 @@ export enum ProtocolErrors {
RC_INVALID_DECIMALS = '70',
RC_INVALID_RESERVE_FACTOR = '71',
LPAPR_INVALID_ADDRESSES_PROVIDER_ID = '72',
VL_BORROW_CAP_EXCEEDED = '81',
RC_INVALID_BORROW_CAP = '82',
VL_SUPPLY_CAP_EXCEEDED = '83',
RC_INVALID_SUPPLY_CAP = '84',
// old
@ -356,6 +360,7 @@ export enum TokenContractId {
export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
aTokenImpl: eContractid;
reserveFactor: string;
supplyCap: string;
strategy: IInterestRateStrategyParams;
}
@ -379,6 +384,7 @@ export interface IReserveBorrowParams {
borrowingEnabled: boolean;
stableBorrowRateEnabled: boolean;
reserveDecimals: string;
borrowCap: string;
}
export interface IReserveCollateralParams {

View File

@ -1,6 +1,6 @@
import { eContractid, IReserveParams } from '../../helpers/types';
import {
import {
rateStrategyStableOne,
rateStrategyStableTwo,
rateStrategyStableThree,
@ -21,7 +21,9 @@ export const strategyBUSD: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyDAI: IReserveParams = {
@ -33,7 +35,9 @@ export const strategyDAI: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategySUSD: IReserveParams = {
@ -45,7 +49,9 @@ export const strategySUSD: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyTUSD: IReserveParams = {
@ -57,7 +63,9 @@ export const strategyTUSD: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDC: IReserveParams = {
@ -69,7 +77,9 @@ export const strategyUSDC: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDT: IReserveParams = {
@ -81,7 +91,9 @@ export const strategyUSDT: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyAAVE: IReserveParams = {
@ -93,7 +105,9 @@ export const strategyAAVE: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '0'
reserveFactor: '0',
borrowCap: '0',
supplyCap: '0',
};
export const strategyBAT: IReserveParams = {
@ -105,7 +119,9 @@ export const strategyBAT: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyENJ: IReserveParams = {
@ -117,7 +133,9 @@ export const strategyENJ: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWETH: IReserveParams = {
@ -129,7 +147,9 @@ export const strategyWETH: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyKNC: IReserveParams = {
@ -141,7 +161,9 @@ export const strategyKNC: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyLINK: IReserveParams = {
@ -153,7 +175,9 @@ export const strategyLINK: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyMANA: IReserveParams = {
@ -165,7 +189,9 @@ export const strategyMANA: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500'
reserveFactor: '3500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyMKR: IReserveParams = {
@ -177,7 +203,9 @@ export const strategyMKR: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyREN: IReserveParams = {
@ -189,7 +217,9 @@ export const strategyREN: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategySNX: IReserveParams = {
@ -201,7 +231,9 @@ export const strategySNX: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500'
reserveFactor: '3500',
borrowCap: '0',
supplyCap: '0',
};
// Invalid borrow rates in params currently, replaced with snx params
@ -214,7 +246,9 @@ export const strategyUNI: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.DelegationAwareAToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWBTC: IReserveParams = {
@ -226,7 +260,9 @@ export const strategyWBTC: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyYFI: IReserveParams = {
@ -238,7 +274,9 @@ export const strategyYFI: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyZRX: IReserveParams = {
@ -250,7 +288,9 @@ export const strategyZRX: IReserveParams = {
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyXSUSHI: IReserveParams = {
@ -263,4 +303,6 @@ export const strategyXSUSHI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '3500',
};
borrowCap: '0',
supplyCap: '0',
};

View File

@ -1,10 +1,5 @@
import { eContractid, IReserveParams} from '../../helpers/types';
import {
rateStrategyAmmBase,
rateStrategyStable,
rateStrategyBaseOne,
} from './rateStrategies';
import { eContractid, IReserveParams } from '../../helpers/types';
import { rateStrategyAmmBase, rateStrategyStable, rateStrategyBaseOne } from './rateStrategies';
export const strategyWETH: IReserveParams = {
strategy: rateStrategyBaseOne,
@ -15,7 +10,9 @@ export const strategyWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWBTC: IReserveParams = {
@ -27,7 +24,9 @@ export const strategyWBTC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyDAI: IReserveParams = {
@ -39,7 +38,9 @@ export const strategyDAI: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDC: IReserveParams = {
@ -51,7 +52,9 @@ export const strategyUSDC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDT: IReserveParams = {
@ -63,7 +66,9 @@ export const strategyUSDT: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyDAIWETH: IReserveParams = {
@ -75,7 +80,9 @@ export const strategyDAIWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWBTCWETH: IReserveParams = {
@ -87,7 +94,9 @@ export const strategyWBTCWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyAAVEWETH: IReserveParams = {
@ -99,7 +108,9 @@ export const strategyAAVEWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '500'
reserveFactor: '500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyBATWETH: IReserveParams = {
@ -111,7 +122,9 @@ export const strategyBATWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyDAIUSDC: IReserveParams = {
@ -123,7 +136,9 @@ export const strategyDAIUSDC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyCRVWETH: IReserveParams = {
@ -135,7 +150,9 @@ export const strategyCRVWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyLINKWETH: IReserveParams = {
@ -147,7 +164,9 @@ export const strategyLINKWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyMKRWETH: IReserveParams = {
@ -159,7 +178,9 @@ export const strategyMKRWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyRENWETH: IReserveParams = {
@ -171,7 +192,9 @@ export const strategyRENWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategySNXWETH: IReserveParams = {
@ -183,7 +206,9 @@ export const strategySNXWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUNIWETH: IReserveParams = {
@ -195,7 +220,9 @@ export const strategyUNIWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDCWETH: IReserveParams = {
@ -207,7 +234,9 @@ export const strategyUSDCWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWBTCUSDC: IReserveParams = {
@ -219,7 +248,9 @@ export const strategyWBTCUSDC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyYFIWETH: IReserveParams = {
@ -231,7 +262,9 @@ export const strategyYFIWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};
export const strategyBALWETH: IReserveParams = {
@ -243,5 +276,7 @@ export const strategyBALWETH: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1500'
}
reserveFactor: '1500',
borrowCap: '0',
supplyCap: '0',
};

View File

@ -20,6 +20,8 @@ export const strategyDAI: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDC: IReserveParams = {
@ -32,6 +34,8 @@ export const strategyUSDC: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyUSDT: IReserveParams = {
@ -44,6 +48,8 @@ export const strategyUSDT: IReserveParams = {
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWETH: IReserveParams = {
@ -56,6 +62,8 @@ export const strategyWETH: IReserveParams = {
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyWBTC: IReserveParams = {
@ -68,6 +76,8 @@ export const strategyWBTC: IReserveParams = {
reserveDecimals: '8',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyMATIC: IReserveParams = {
@ -79,6 +89,8 @@ export const strategyMATIC: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
borrowCap: '0',
supplyCap: '0',
reserveFactor: '2000',
};
@ -91,5 +103,7 @@ export const strategyAAVE: IReserveParams = {
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
borrowCap: '0',
supplyCap: '0',
reserveFactor: '0',
};

View File

@ -149,7 +149,8 @@
"Andrey Kozlov <andrey@aave.com>",
"David Racero <david.k@aave.com>",
"Pol Sendra <pol@aave.com>",
"David Truong <david@aave.com>"
"David Truong <david@aave.com>",
"Hadrien Charlanes <hadrien@aave.com>"
],
"license": "AGPLv3",
"dependencies": {

View File

@ -0,0 +1,354 @@
import { TestEnv, makeSuite } from './helpers/make-suite';
import {
APPROVAL_AMOUNT_LENDING_POOL,
MAX_UINT_AMOUNT,
RAY,
MAX_BORROW_CAP,
MAX_SUPPLY_CAP,
} from '../../helpers/constants';
import { ProtocolErrors } from '../../helpers/types';
import { MintableERC20, WETH9, WETH9Mocked } from '../../types';
import { parseEther } from '@ethersproject/units';
import { BigNumber } from '@ethersproject/bignumber';
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) =>
BigNumber.from(nb).mul(BigNumber.from('10').pow((await token.decimals()) - 3));
it('Reserves should initially have borrow cap disabled (borrowCap = 0)', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
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);
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('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 suppliedAmount = 1000;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
const borrowedAmount = 10;
const precisionBorrowedAmount = (borrowedAmount * 1000).toString();
// deposit collateral
await pool.deposit(
weth.address,
await unitParse(weth, precisionSuppliedAmount),
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);
});
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();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
2,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
2,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
});
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;
await expect(configurator.setBorrowCap(usdc.address, newCap)).to.be.revertedWith(
RC_INVALID_BORROW_CAP
);
await expect(configurator.setBorrowCap(dai.address, newCap)).to.be.revertedWith(
RC_INVALID_BORROW_CAP
);
});
it('Sets the borrow cap for usdc and DAI to 120 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '120';
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;
expect(usdcBorrowCap).to.be.equal(newCap);
expect(daiBorrowCap).to.be.equal(newCap);
});
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();
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('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();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
1,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
2,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
});
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();
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('Raises the borrow cap for usdc and DAI to 1000 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '1000';
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
await configurator.setBorrowCap(usdc.address, newCap);
await configurator.setBorrowCap(dai.address, newCap);
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);
});
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();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
1,
0,
deployer.address
);
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
2,
0,
deployer.address
);
});
it('Lowers the borrow cap for usdc and DAI to 200 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '200';
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
await configurator.setBorrowCap(usdc.address, newCap);
await configurator.setBorrowCap(dai.address, newCap);
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);
});
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();
await expect(
pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
1,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
await expect(
pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
2,
0,
deployer.address
)
).to.be.revertedWith(VL_BORROW_CAP_EXCEEDED);
});
it('Raises the borrow cap for usdc and DAI to max cap Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = MAX_BORROW_CAP;
let usdcBorrowCap = (await helpersContract.getReserveCaps(usdc.address)).borrowCap;
let daiBorrowCap = (await helpersContract.getReserveCaps(dai.address)).borrowCap;
await configurator.setBorrowCap(usdc.address, newCap);
await configurator.setBorrowCap(dai.address, newCap);
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);
});
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();
await pool.borrow(
usdc.address,
await unitParse(usdc, precisionBorrowedAmount),
1,
0,
deployer.address
);
await pool.borrow(
dai.address,
await unitParse(dai, precisionBorrowedAmount),
2,
0,
deployer.address
);
});
});

View File

@ -1,8 +1,14 @@
import { TestEnv, makeSuite } from './helpers/make-suite';
import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
import {
APPROVAL_AMOUNT_LENDING_POOL,
MAX_UINT_AMOUNT,
RAY,
MAX_BORROW_CAP,
} from '../../helpers/constants';
import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
import { ProtocolErrors } from '../../helpers/types';
import { strategyWETH } from '../../markets/aave/reservesConfigs';
import { BigNumber } from '@ethersproject/bignumber';
const { expect } = require('chai');
@ -15,6 +21,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
RC_INVALID_LIQ_BONUS,
RC_INVALID_DECIMALS,
RC_INVALID_RESERVE_FACTOR,
RC_INVALID_BORROW_CAP,
RC_INVALID_SUPPLY_CAP,
} = ProtocolErrors;
it('Reverts trying to set an invalid reserve factor', async () => {
@ -73,6 +81,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -83,6 +92,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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', async () => {
@ -100,6 +111,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -110,6 +122,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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 onlyAaveAdmin on freezeReserve ', async () => {
@ -142,6 +156,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(false);
expect(isActive).to.be.equal(true);
@ -152,11 +167,13 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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('Activates the ETH reserve for borrowing', async () => {
const { configurator, weth, helpersContract } = testEnv;
await configurator.enableBorrowingOnReserve(weth.address, true);
await configurator.enableBorrowingOnReserve(weth.address, '0', true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
@ -170,6 +187,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -180,6 +198,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
});
@ -195,7 +215,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, '0', true),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
@ -215,6 +235,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -225,6 +246,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(liquidationBonus).to.be.equal(0);
expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Activates the ETH reserve as collateral', async () => {
@ -242,6 +265,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -252,6 +276,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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 onlyAaveAdmin on configureReserveAsCollateral ', async () => {
@ -278,6 +304,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -288,6 +315,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(false);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Enables stable borrow rate on the ETH reserve', async () => {
@ -304,6 +333,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -314,6 +344,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(borrowCap).to.be.equal(strategyWETH.borrowCap);
expect(supplyCap).to.be.equal(strategyWETH.supplyCap);
});
it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
@ -332,6 +364,29 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Check the onlyAaveAdmin on setReserveFactor', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).setReserveFactor(weth.address, '1000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Check the onlyAaveAdmin on setBorrowCap', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).setBorrowCap(weth.address, '3000000000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Check the onlyAaveAdmin on setSupplyCap', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).setSupplyCap(weth.address, '3000000000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Changes the reserve factor of WETH', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.setReserveFactor(weth.address, '1000');
@ -346,6 +401,51 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
isActive,
isFrozen,
} = await helpersContract.getReserveConfigurationData(weth.address);
const { borrowCap, supplyCap } = await helpersContract.getReserveCaps(weth.address);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).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(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 () => {
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 () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.setSupplyCap(weth.address, BigNumber.from(MAX_BORROW_CAP).add(1)),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(RC_INVALID_SUPPLY_CAP);
});
it('Changes the borrow Cap of WETH', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.setBorrowCap(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);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true);
@ -356,14 +456,37 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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(strategyWETH.supplyCap);
});
it('Check the onlyLendingPoolManager on setReserveFactor', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).setReserveFactor(weth.address, '2000'),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
it('Changes the supply Cap of WETH', async () => {
const { configurator, helpersContract, weth } = testEnv;
await configurator.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);
expect(borrowingEnabled).to.be.equal(true);
expect(isActive).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(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 () => {

View File

@ -0,0 +1,299 @@
import { TestEnv, makeSuite } from './helpers/make-suite';
import {
APPROVAL_AMOUNT_LENDING_POOL,
MAX_UINT_AMOUNT,
RAY,
MAX_SUPPLY_CAP,
} from '../../helpers/constants';
import { ProtocolErrors } from '../../helpers/types';
import { MintableERC20, WETH9, WETH9Mocked } from '../../types';
import { parseEther } from '@ethersproject/units';
import { BigNumber } from '@ethersproject/bignumber';
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) =>
BigNumber.from(nb).mul(BigNumber.from('10').pow((await token.decimals()) - 3));
it('Reserves should initially have supply cap disabled (supplyCap = 0)', async () => {
const {
configurator,
weth,
pool,
dai,
usdc,
deployer,
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;
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 suppliedAmount = 1000;
const precisionSuppliedAmount = (suppliedAmount * 1000).toString();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
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);
});
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();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), 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;
await expect(configurator.setSupplyCap(usdc.address, newCap)).to.be.revertedWith(
RC_INVALID_SUPPLY_CAP
);
await expect(configurator.setSupplyCap(dai.address, newCap)).to.be.revertedWith(
RC_INVALID_SUPPLY_CAP
);
});
it('Sets the supply cap for usdc and DAI to 1110 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '1110';
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);
});
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();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
deployer.address,
0
);
});
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();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), 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();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
deployer.address,
0
);
});
it('Raises the supply cap for usdc and DAI to 2000 Units', async () => {
const { configurator, usdc, pool, dai, deployer, helpersContract } = testEnv;
const newCap = '2000';
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);
});
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();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
deployer.address,
0
);
});
it('Lowers the supply cap for usdc and DAI to 1200 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;
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;
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();
await expect(
pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
)
).to.be.revertedWith(VL_SUPPLY_CAP_EXCEEDED);
await expect(
pool.deposit(dai.address, await unitParse(dai, precisionSuppliedAmount), 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;
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;
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();
await pool.deposit(
usdc.address,
await unitParse(usdc, precisionSuppliedAmount),
deployer.address,
0
);
await pool.deposit(
dai.address,
await unitParse(dai, precisionSuppliedAmount),
deployer.address,
0
);
});
});

View File

@ -1,5 +1,5 @@
import { TestEnv, makeSuite } from './helpers/make-suite';
import { APPROVAL_AMOUNT_LENDING_POOL, RAY } from '../../helpers/constants';
import { APPROVAL_AMOUNT_LENDING_POOL, MAX_BORROW_CAP, RAY } from '../../helpers/constants';
import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
import { ProtocolErrors } from '../../helpers/types';
import { strategyWETH } from '../../markets/amm/reservesConfigs';
@ -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, true);
await configurator.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true);
const { variableBorrowIndex } = await helpersContract.getReserveData(weth.address);
const {
@ -178,9 +178,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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(true/*strategyWETH.stableBorrowRateEnabled*/);
expect(stableBorrowRateEnabled).to.be.equal(true /*strategyWETH.stableBorrowRateEnabled*/);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
});
@ -195,7 +194,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
configurator
.connect(users[2].signer)
.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
@ -250,7 +251,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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(true/*strategyWETH.stableBorrowRateEnabled*/);
expect(stableBorrowRateEnabled).to.be.equal(true /*strategyWETH.stableBorrowRateEnabled*/);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
});