Merge pull request #108 from aave/feat/2.5-pause-one-reserve

Feat/2.5 pause one reserve
This commit is contained in:
The-3D 2021-05-31 13:55:37 +02:00 committed by GitHub
commit bfc0602736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 690 additions and 82 deletions

View File

@ -120,6 +120,18 @@ interface ILendingPoolConfigurator {
**/
event ReserveUnfrozen(address indexed asset);
/**
* @dev Emitted when a reserve is paused
* @param asset The address of the underlying asset of the reserve
**/
event ReservePaused(address indexed asset);
/**
* @dev Emitted when a reserve is unpaused
* @param asset The address of the underlying asset of the reserve
**/
event ReserveUnpaused(address indexed asset);
/**
* @dev Emitted when a reserve factor is updated
* @param asset The address of the underlying asset of the reserve
@ -221,7 +233,11 @@ interface ILendingPoolConfigurator {
* @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;
function enableBorrowingOnReserve(
address asset,
uint256 borrowCap,
bool stableBorrowRateEnabled
) external;
/**
* @dev Disables borrowing on a reserve
@ -282,6 +298,18 @@ interface ILendingPoolConfigurator {
**/
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

View File

@ -64,7 +64,7 @@ contract AaveProtocolDataProvider {
return aTokens;
}
// not returning borrow and supply caps for compatibility
// not returning borrow and supply caps for compatibility, nor pause flag
function getReserveConfigurationData(address asset)
external
view
@ -87,7 +87,7 @@ contract AaveProtocolDataProvider {
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) =
configuration.getParamsMemory();
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) =
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled, ) =
configuration.getFlagsMemory();
usageAsCollateralEnabled = liquidationThreshold > 0;
@ -103,6 +103,13 @@ contract AaveProtocolDataProvider {
.getCapsMemory();
}
function getPaused(address asset) external view returns (bool isPaused) {
(, , , , isPaused) =
ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
.getConfiguration(asset)
.getFlagsMemory();
}
function getReserveData(address asset)
external
view

View File

@ -122,7 +122,8 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
reserveData.isActive,
reserveData.isFrozen,
reserveData.borrowingEnabled,
reserveData.stableBorrowRateEnabled
reserveData.stableBorrowRateEnabled,
reserveData.isPaused
) = baseData.configuration.getFlagsMemory();
reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0;
(

View File

@ -96,7 +96,7 @@ contract WalletBalanceProvider {
DataTypes.ReserveConfigurationMap memory configuration =
pool.getConfiguration(reservesWithEth[j]);
(bool isActive, , , ) = configuration.getFlagsMemory();
(bool isActive, , , , ) = configuration.getFlagsMemory();
if (!isActive) {
balances[j] = 0;

View File

@ -22,6 +22,7 @@ interface IUiPoolDataProvider {
bool stableBorrowRateEnabled;
bool isActive;
bool isFrozen;
bool isPaused;
// base data
uint128 liquidityIndex;
uint128 variableBorrowIndex;

View File

@ -465,7 +465,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
) external override whenNotPaused {
FlashLoanLocalVars memory vars;
ValidationLogic.validateFlashloan(assets, amounts);
ValidationLogic.validateFlashloan(assets, amounts, _reserves);
address[] memory aTokenAddresses = new address[](assets.length);
uint256[] memory premiums = new uint256[](assets.length);
@ -720,6 +720,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
) external override whenNotPaused {
require(msg.sender == _reserves[asset].aTokenAddress, Errors.LP_CALLER_MUST_BE_AN_ATOKEN);
ValidationLogic.validateTransfer(_reserves[asset]);
uint256 reserveId = _reserves[asset].id;
if (from != to) {

View File

@ -46,6 +46,15 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
_;
}
modifier onlyEmergencyOrPoolAdmin {
require(
_addressesProvider.getEmergencyAdmin() == msg.sender ||
_addressesProvider.getPoolAdmin() == msg.sender,
Errors.LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN
);
_;
}
uint256 internal constant CONFIGURATOR_REVISION = 0x1;
function getRevision() internal pure override returns (uint256) {
@ -126,6 +135,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
currentConfig.setDecimals(input.underlyingAssetDecimals);
currentConfig.setActive(true);
currentConfig.setPaused(false);
currentConfig.setFrozen(false);
pool.setConfiguration(input.underlyingAsset, currentConfig.data);
@ -380,6 +390,28 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit ReserveUnfrozen(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function pauseReserve(address asset) external override onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setPaused(true);
_pool.setConfiguration(asset, currentConfig.data);
emit ReservePaused(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function unpauseReserve(address asset) external override onlyEmergencyOrPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setPaused(false);
_pool.setConfiguration(asset, currentConfig.data);
emit ReserveUnpaused(asset);
}
/// @inheritdoc ILendingPoolConfigurator
function setReserveFactor(address asset, uint256 reserveFactor) external override onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);

View File

@ -18,6 +18,7 @@ library ReserveConfiguration {
uint256 constant FROZEN_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFFFFFFFFFFF; // prettier-ignore
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
@ -30,6 +31,8 @@ library ReserveConfiguration {
uint256 constant IS_FROZEN_START_BIT_POSITION = 57;
uint256 constant BORROWING_ENABLED_START_BIT_POSITION = 58;
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
uint256 constant IS_PAUSED_START_BIT_POSITION = 60;
// 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;
@ -187,6 +190,26 @@ 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
**/
function setPaused(DataTypes.ReserveConfigurationMap memory self, bool paused) internal pure {
self.data =
(self.data & PAUSED_MASK) |
(uint256(paused ? 1 : 0) << IS_PAUSED_START_BIT_POSITION);
}
/**
* @dev Gets the paused state of the reserve
* @param self The reserve configuration
* @return The paused state
**/
function getPaused(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
return (self.data & ~PAUSED_MASK) != 0;
}
/**
* @dev Enables or disables borrowing on the reserve
* @param self The reserve configuration
@ -336,6 +359,7 @@ library ReserveConfiguration {
bool,
bool,
bool,
bool,
bool
)
{
@ -345,7 +369,8 @@ library ReserveConfiguration {
(dataLocal & ~ACTIVE_MASK) != 0,
(dataLocal & ~FROZEN_MASK) != 0,
(dataLocal & ~BORROWING_MASK) != 0,
(dataLocal & ~STABLE_BORROWING_MASK) != 0
(dataLocal & ~STABLE_BORROWING_MASK) != 0,
(dataLocal & ~PAUSED_MASK) != 0
);
}
@ -447,6 +472,7 @@ library ReserveConfiguration {
bool,
bool,
bool,
bool,
bool
)
{
@ -454,7 +480,8 @@ library ReserveConfiguration {
(self.data & ~ACTIVE_MASK) != 0,
(self.data & ~FROZEN_MASK) != 0,
(self.data & ~BORROWING_MASK) != 0,
(self.data & ~STABLE_BORROWING_MASK) != 0
(self.data & ~STABLE_BORROWING_MASK) != 0,
(self.data & ~PAUSED_MASK) != 0
);
}

View File

@ -106,6 +106,8 @@ library Errors {
string public constant RC_INVALID_BORROW_CAP = '82';
string public constant VL_SUPPLY_CAP_EXCEEDED = '83';
string public constant RC_INVALID_SUPPLY_CAP = '84';
string public constant LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85';
string public constant VL_RESERVE_PAUSED = '86';
enum CollateralManagerErrors {
NO_ERROR,
@ -117,6 +119,7 @@ library Errors {
NO_ACTIVE_RESERVE,
HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD,
INVALID_EQUAL_ASSETS_TO_SWAP,
FROZEN_RESERVE
FROZEN_RESERVE,
PAUSED_RESERVE
}
}

View File

@ -42,12 +42,13 @@ library ValidationLogic {
*/
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) internal view {
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
(bool isActive, bool isFrozen, , ) = reserveConfiguration.getFlagsMemory();
(bool isActive, bool isFrozen, , , bool isPaused) = 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(!isPaused, Errors.VL_RESERVE_PAUSED);
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
require(
supplyCap == 0 ||
@ -71,8 +72,9 @@ library ValidationLogic {
require(amount != 0, Errors.VL_INVALID_AMOUNT);
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
(bool isActive, , , ) = reserve.configuration.getFlags();
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED);
}
struct ValidateBorrowLocalVars {
@ -89,6 +91,7 @@ library ValidationLogic {
uint256 borrowCap;
bool isActive;
bool isFrozen;
bool isPaused;
bool borrowingEnabled;
bool stableRateBorrowingEnabled;
}
@ -121,7 +124,7 @@ library ValidationLogic {
mapping(uint256 => address) storage reserves,
uint256 reservesCount,
address oracle
) internal view {
) external view {
ValidateBorrowLocalVars memory vars;
DataTypes.ReserveConfigurationMap memory reserveConfiguration = reserve.configuration;
@ -131,10 +134,12 @@ library ValidationLogic {
vars.isActive,
vars.isFrozen,
vars.borrowingEnabled,
vars.stableRateBorrowingEnabled
vars.stableRateBorrowingEnabled,
vars.isPaused
) = reserveConfiguration.getFlagsMemory();
require(vars.isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!vars.isPaused, Errors.VL_RESERVE_PAUSED);
require(!vars.isFrozen, Errors.VL_RESERVE_FROZEN);
require(amount != 0, Errors.VL_INVALID_AMOUNT);
@ -238,9 +243,9 @@ library ValidationLogic {
uint256 stableDebt,
uint256 variableDebt
) external view {
bool isActive = reserve.configuration.getActive();
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED);
require(amountSent > 0, Errors.VL_INVALID_AMOUNT);
@ -273,9 +278,11 @@ library ValidationLogic {
uint256 variableDebt,
DataTypes.InterestRateMode currentRateMode
) external view {
(bool isActive, bool isFrozen, , bool stableRateEnabled) = reserve.configuration.getFlags();
(bool isActive, bool isFrozen, , bool stableRateEnabled, bool isPaused) =
reserve.configuration.getFlags();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED);
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
if (currentRateMode == DataTypes.InterestRateMode.STABLE) {
@ -317,9 +324,10 @@ library ValidationLogic {
IERC20 variableDebtToken,
address aTokenAddress
) external view {
(bool isActive, , , ) = reserve.configuration.getFlags();
(bool isActive, , , , bool isPaused) = reserve.configuration.getFlags();
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
require(!isPaused, Errors.VL_RESERVE_PAUSED);
//if the usage ratio is below 95%, no rebalances are needed
uint256 totalDebt =
@ -348,6 +356,9 @@ library ValidationLogic {
*/
function validateSetUseReserveAsCollateral(DataTypes.ReserveData storage reserve) external view {
uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
bool isPaused = reserve.configuration.getPaused();
require(!isPaused, Errors.VL_RESERVE_PAUSED);
require(underlyingBalance > 0, Errors.VL_UNDERLYING_BALANCE_NOT_GREATER_THAN_0);
}
@ -357,7 +368,14 @@ 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) external pure {
function validateFlashloan(
address[] memory assets,
uint256[] memory amounts,
mapping(address => DataTypes.ReserveData) storage reservesData
) external view {
for (uint256 i = 0; i < assets.length; i++) {
require(!reservesData[assets[i]].configuration.getPaused(), Errors.VL_RESERVE_PAUSED);
}
require(assets.length == amounts.length, Errors.VL_INCONSISTENT_FLASHLOAN_PARAMS);
}
@ -386,6 +404,9 @@ library ValidationLogic {
Errors.VL_NO_ACTIVE_RESERVE
);
}
if (collateralReserve.configuration.getPaused() || principalReserve.configuration.getPaused()) {
return (uint256(Errors.CollateralManagerErrors.PAUSED_RESERVE), Errors.VL_RESERVE_PAUSED);
}
if (userHealthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD) {
return (
@ -448,4 +469,12 @@ library ValidationLogic {
Errors.VL_HEALTH_FACTOR_LOWER_THAN_LIQUIDATION_THRESHOLD
);
}
/**
* @dev Validates a transfer action
* @param reserve The reserve object
*/
function validateTransfer(DataTypes.ReserveData storage reserve) internal view {
require(!reserve.configuration.getPaused(), Errors.VL_RESERVE_PAUSED);
}
}

View File

@ -36,7 +36,8 @@ library DataTypes {
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60-63: reserved
//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

View File

@ -181,6 +181,8 @@ export enum ProtocolErrors {
RC_INVALID_BORROW_CAP = '82',
VL_SUPPLY_CAP_EXCEEDED = '83',
RC_INVALID_SUPPLY_CAP = '84',
LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85',
VL_RESERVE_PAUSED = '86',
// old

View File

@ -92,6 +92,8 @@ export const strategyMATIC: IReserveParams = {
borrowCap: '0',
supplyCap: '0',
reserveFactor: '2000',
borrowCap: '0',
supplyCap: '0',
};
export const strategyAAVE: IReserveParams = {

View File

@ -24,6 +24,8 @@
"test-scenarios": "npm run compile && npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts",
"test-subgraph:scenarios": "npm run compile && hardhat --network hardhatevm_docker test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/subgraph-scenarios.spec.ts",
"test:main:check-list": "npm run compile && FORK=main TS_NODE_TRANSPILE_ONLY=1 hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/mainnet/check-list.spec.ts",
"test:aave": "hardhat test test-suites/test-aave/__setup.spec.ts",
"test:amm": "hardhat test test-suites/test-amm/__setup.spec.ts",
"dev:coverage": "buidler compile --force && buidler coverage --network coverage",
"aave:evm:dev:migration": "npm run compile && hardhat aave:dev",
"aave:docker:full:migration": "npm run compile && npm run hardhat:docker -- aave:mainnet --skip-registry",

View File

@ -23,6 +23,8 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
RC_INVALID_RESERVE_FACTOR,
RC_INVALID_BORROW_CAP,
RC_INVALID_SUPPLY_CAP,
LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN,
VL_RESERVE_PAUSED,
} = ProtocolErrors;
it('Reverts trying to set an invalid reserve factor', async () => {
@ -65,6 +67,152 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
it('Pauses the ETH reserve by pool admin', async () => {
const { configurator, weth, helpersContract, addressesProvider, users } = testEnv;
expect(await configurator.signer.getAddress()).to.be.equal(
await addressesProvider.getPoolAdmin()
);
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 } = testEnv;
expect(users[1].address).to.be.equal(await addressesProvider.getEmergencyAdmin());
await configurator.connect(users[1].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 } = testEnv;
await configurator.connect(users[1].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 } = testEnv;
await expect(
configurator.connect(users[2].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 } = testEnv;
await expect(
configurator.connect(users[2].signer).unpauseReserve(weth.address),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN);
});
it('Freezes the ETH reserve', async () => {
const { configurator, weth, helpersContract } = testEnv;
@ -82,9 +230,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -112,9 +262,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -157,9 +309,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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(false);
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);
@ -188,9 +342,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -236,9 +392,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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(18);
expect(ltv).to.be.equal(0);
@ -266,9 +424,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -305,9 +465,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -334,9 +496,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -402,9 +566,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -446,9 +612,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);
@ -475,9 +643,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
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);

View File

@ -12,17 +12,14 @@ 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 succees', async () => {
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');

View File

@ -0,0 +1,330 @@
import { makeSuite, TestEnv } from './helpers/make-suite';
import { ProtocolErrors, RateMode } from '../../helpers/types';
import { APPROVAL_AMOUNT_LENDING_POOL, oneEther } from '../../helpers/constants';
import { convertToCurrencyDecimals } from '../../helpers/contracts-helpers';
import { parseEther, parseUnits } from 'ethers/lib/utils';
import { BigNumber } from 'bignumber.js';
import { MockFlashLoanReceiver } from '../../types/MockFlashLoanReceiver';
import { getMockFlashLoanReceiver } from '../../helpers/contracts-getters';
const { expect } = require('chai');
makeSuite('Pause Reserve', (testEnv: TestEnv) => {
let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
const {
VL_RESERVE_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 () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await dai.connect(users[0].signer).mint(amountDAItoDeposit);
// user 0 deposits 1000 DAI
await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool
.connect(users[0].signer)
.deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
const user0Balance = await aDai.balanceOf(users[0].address);
const user1Balance = await aDai.balanceOf(users[1].address);
// Configurator pauses the pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
// User 0 tries the transfer to User 1
await expect(
aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit)
).to.revertedWith(VL_RESERVE_PAUSED);
const pausedFromBalance = await aDai.balanceOf(users[0].address);
const pausedToBalance = await aDai.balanceOf(users[1].address);
expect(pausedFromBalance).to.be.equal(
user0Balance.toString(),
INVALID_TO_BALANCE_AFTER_TRANSFER
);
expect(pausedToBalance.toString()).to.be.equal(
user1Balance.toString(),
INVALID_FROM_BALANCE_AFTER_TRANSFER
);
// Configurator unpauses the pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
// User 0 succeeds transfer to User 1
await aDai.connect(users[0].signer).transfer(users[1].address, amountDAItoDeposit);
const fromBalance = await aDai.balanceOf(users[0].address);
const toBalance = await aDai.balanceOf(users[1].address);
expect(fromBalance.toString()).to.be.equal(
user0Balance.sub(amountDAItoDeposit),
INVALID_FROM_BALANCE_AFTER_TRANSFER
);
expect(toBalance.toString()).to.be.equal(
user1Balance.add(amountDAItoDeposit),
INVALID_TO_BALANCE_AFTER_TRANSFER
);
});
it('Deposit', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await dai.connect(users[0].signer).mint(amountDAItoDeposit);
// user 0 deposits 1000 DAI
await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
// Configurator pauses the pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
await expect(
pool.connect(users[0].signer).deposit(dai.address, amountDAItoDeposit, users[0].address, '0')
).to.revertedWith(VL_RESERVE_PAUSED);
// Configurator unpauses the pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
});
it('Withdraw', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
await dai.connect(users[0].signer).mint(amountDAItoDeposit);
// user 0 deposits 1000 DAI
await dai.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool
.connect(users[0].signer)
.deposit(dai.address, amountDAItoDeposit, users[0].address, '0');
// Configurator pauses the pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
// user tries to burn
await expect(
pool.connect(users[0].signer).withdraw(dai.address, amountDAItoDeposit, users[0].address)
).to.revertedWith(VL_RESERVE_PAUSED);
// Configurator unpauses the pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
});
it('Borrow', async () => {
const { pool, dai, users, configurator } = testEnv;
const user = users[1];
// Pause the pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
// Try to execute liquidation
await expect(
pool.connect(user.signer).borrow(dai.address, '1', '1', '0', user.address)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause the pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
});
it('Repay', async () => {
const { pool, dai, users, configurator } = testEnv;
const user = users[1];
// Pause the pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
// Try to execute liquidation
await expect(pool.connect(user.signer).repay(dai.address, '1', '1', user.address)).revertedWith(
VL_RESERVE_PAUSED
);
// Unpause the pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
});
it('Flash loan', async () => {
const { dai, pool, weth, users, configurator } = testEnv;
const caller = users[3];
const flashAmount = parseEther('0.8');
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
// Pause pool
await configurator.connect(users[1].signer).pauseReserve(weth.address);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
[weth.address],
[flashAmount],
[1],
caller.address,
'0x10',
'0'
)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause pool
await configurator.connect(users[1].signer).unpauseReserve(weth.address);
});
it('Liquidation call', async () => {
const { users, pool, usdc, oracle, weth, configurator, helpersContract } = testEnv;
const depositor = users[3];
const borrower = users[4];
//mints USDC to depositor
await usdc
.connect(depositor.signer)
.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
//approve protocol to access depositor wallet
await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
//user 3 deposits 1000 USDC
const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
await pool
.connect(depositor.signer)
.deposit(usdc.address, amountUSDCtoDeposit, depositor.address, '0');
//user 4 deposits 1 ETH
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
//mints WETH to borrower
await weth.connect(borrower.signer).mint(amountETHtoDeposit);
//approve protocol to access borrower wallet
await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool
.connect(borrower.signer)
.deposit(weth.address, amountETHtoDeposit, borrower.address, '0');
//user 4 borrows
const userGlobalData = await pool.getUserAccountData(borrower.address);
const usdcPrice = await oracle.getAssetPrice(usdc.address);
const amountUSDCToBorrow = await convertToCurrencyDecimals(
usdc.address,
new BigNumber(userGlobalData.availableBorrowsETH.toString())
.div(usdcPrice.toString())
.multipliedBy(0.9502)
.toFixed(0)
);
await pool
.connect(borrower.signer)
.borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0', borrower.address);
// Drops HF below 1
await oracle.setAssetPrice(
usdc.address,
new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0)
);
//mints dai to the liquidator
await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
const userReserveDataBefore = await helpersContract.getUserReserveData(
usdc.address,
borrower.address
);
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
.multipliedBy(0.5)
.toFixed(0);
// Pause pool
await configurator.connect(users[1].signer).pauseReserve(usdc.address);
// Do liquidation
await expect(
pool.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, true)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause pool
await configurator.connect(users[1].signer).unpauseReserve(usdc.address);
});
it('SwapBorrowRateMode', async () => {
const { pool, weth, dai, usdc, users, configurator } = testEnv;
const user = users[1];
const amountWETHToDeposit = parseEther('10');
const amountDAIToDeposit = parseEther('120');
const amountToBorrow = parseUnits('65', 6);
await weth.connect(user.signer).mint(amountWETHToDeposit);
await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
await dai.connect(user.signer).mint(amountDAIToDeposit);
await dai.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(dai.address, amountDAIToDeposit, user.address, '0');
await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0, user.address);
// Pause pool
await configurator.connect(users[1].signer).pauseReserve(usdc.address);
// Try to repay
await expect(
pool.connect(user.signer).swapBorrowRateMode(usdc.address, RateMode.Stable)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause pool
await configurator.connect(users[1].signer).unpauseReserve(usdc.address);
});
it('RebalanceStableBorrowRate', async () => {
const { pool, dai, users, configurator } = testEnv;
const user = users[1];
// Pause pool
await configurator.connect(users[1].signer).pauseReserve(dai.address);
await expect(
pool.connect(user.signer).rebalanceStableBorrowRate(dai.address, user.address)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause pool
await configurator.connect(users[1].signer).unpauseReserve(dai.address);
});
it('setUserUseReserveAsCollateral', async () => {
const { pool, weth, users, configurator } = testEnv;
const user = users[1];
const amountWETHToDeposit = parseEther('1');
await weth.connect(user.signer).mint(amountWETHToDeposit);
await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(weth.address, amountWETHToDeposit, user.address, '0');
// Pause pool
await configurator.connect(users[1].signer).pauseReserve(weth.address);
await expect(
pool.connect(user.signer).setUserUseReserveAsCollateral(weth.address, false)
).revertedWith(VL_RESERVE_PAUSED);
// Unpause pool
await configurator.connect(users[1].signer).unpauseReserve(weth.address);
});
});

View File

@ -187,17 +187,12 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
const collateralDecimals = (await usdc.decimals()).toString();
const principalDecimals = (await dai.decimals()).toString();
const expectedDaiAmountForUsdc = await convertToCurrencyDecimals(
dai.address,
new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(
new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
)
.toFixed(0)
);
const expectedDaiAmountForUsdc = new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)))
.toFixed(0);
// Make a deposit for user
await usdc.connect(user).mint(amountUSDCtoSwap);
@ -240,7 +235,6 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
],
[false, false]
);
await pool
.connect(user)
.flashLoan(
@ -309,17 +303,12 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
const collateralDecimals = (await usdc.decimals()).toString();
const principalDecimals = (await dai.decimals()).toString();
const expectedDaiAmountForUsdc = await convertToCurrencyDecimals(
dai.address,
new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(
new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
)
.toFixed(0)
);
const expectedDaiAmountForUsdc = new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)))
.toFixed(0);
// Make a deposit for user
await usdc.connect(user).mint(amountUSDCtoSwap);
@ -862,17 +851,12 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
const collateralDecimals = (await usdc.decimals()).toString();
const principalDecimals = (await dai.decimals()).toString();
const expectedDaiAmount = await convertToCurrencyDecimals(
dai.address,
new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(
new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
)
.toFixed(0)
);
const expectedDaiAmount = new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)))
.toFixed(0);
await mockUniswapRouter.connect(user).setAmountToReturn(usdc.address, expectedDaiAmount);
@ -1484,17 +1468,12 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
const collateralDecimals = (await usdc.decimals()).toString();
const principalDecimals = (await dai.decimals()).toString();
const expectedDaiAmountForUsdc = await convertToCurrencyDecimals(
dai.address,
new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(
new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
)
.toFixed(0)
);
const expectedDaiAmountForUsdc = new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)))
.toFixed(0);
// Make a deposit for user
await usdc.connect(user).mint(amountUSDCtoSwap);
@ -1592,17 +1571,12 @@ makeSuite('Uniswap adapters', (testEnv: TestEnv) => {
const collateralDecimals = (await usdc.decimals()).toString();
const principalDecimals = (await dai.decimals()).toString();
const expectedDaiAmountForUsdc = await convertToCurrencyDecimals(
dai.address,
new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(
new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals))
)
.toFixed(0)
);
const expectedDaiAmountForUsdc = new BigNumber(amountUSDCtoSwap.toString())
.times(
new BigNumber(usdcPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(new BigNumber(daiPrice.toString()).times(new BigNumber(10).pow(collateralDecimals)))
.toFixed(0);
// Make a deposit for user
await usdc.connect(user).mint(amountUSDCtoSwap);

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 succees', async () => {
it('User 0 deposits 1000 DAI. Configurator pauses pool. Transfers to user 1 reverts. Configurator unpauses the network and next transfer succeeds', async () => {
const { users, pool, dai, aDai, configurator } = testEnv;
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');