2020-06-18 14:36:37 +00:00
|
|
|
import BigNumber from 'bignumber.js';
|
|
|
|
|
|
|
|
import {BRE} from '../helpers/misc-utils';
|
2020-08-13 11:06:23 +00:00
|
|
|
import {APPROVAL_AMOUNT_LENDING_POOL, oneEther} from '../helpers/constants';
|
2020-06-18 14:36:37 +00:00
|
|
|
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
|
|
|
|
import {makeSuite} from './helpers/make-suite';
|
|
|
|
import {ProtocolErrors, RateMode} from '../helpers/types';
|
2020-07-13 08:54:08 +00:00
|
|
|
import {calcExpectedVariableDebtTokenBalance} from './helpers/utils/calculations';
|
|
|
|
import {getUserData, getReserveData} from './helpers/utils/helpers';
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
const chai = require('chai');
|
|
|
|
const {expect} = chai;
|
2020-06-18 14:36:37 +00:00
|
|
|
|
|
|
|
makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) => {
|
|
|
|
const {
|
|
|
|
HF_IS_NOT_BELLOW_THRESHOLD,
|
|
|
|
INVALID_HF,
|
|
|
|
USER_DID_NOT_BORROW_SPECIFIED,
|
2020-08-05 22:46:22 +00:00
|
|
|
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
|
2020-06-18 14:36:37 +00:00
|
|
|
} = ProtocolErrors;
|
|
|
|
|
2020-08-13 17:25:29 +00:00
|
|
|
it('LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
|
2020-08-13 11:06:23 +00:00
|
|
|
const {dai, weth, users, pool, oracle} = testEnv;
|
2020-06-18 14:36:37 +00:00
|
|
|
const depositor = users[0];
|
|
|
|
const borrower = users[1];
|
|
|
|
|
|
|
|
//mints DAI to depositor
|
|
|
|
await dai.connect(depositor.signer).mint(await convertToCurrencyDecimals(dai.address, '1000'));
|
|
|
|
|
|
|
|
//approve protocol to access depositor wallet
|
2020-06-20 23:40:03 +00:00
|
|
|
await dai.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
|
|
|
//user 1 deposits 1000 DAI
|
|
|
|
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
|
|
|
|
await pool.connect(depositor.signer).deposit(dai.address, amountDAItoDeposit, '0');
|
|
|
|
|
2020-08-13 11:06:23 +00:00
|
|
|
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
2020-08-19 12:23:41 +00:00
|
|
|
|
2020-08-13 17:25:29 +00:00
|
|
|
//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);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
//user 2 deposits 1 WETH
|
|
|
|
await pool.connect(borrower.signer).deposit(weth.address, amountETHtoDeposit, '0');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
|
|
|
//user 2 borrows
|
|
|
|
const userGlobalData = await pool.getUserAccountData(borrower.address);
|
|
|
|
const daiPrice = await oracle.getAssetPrice(dai.address);
|
|
|
|
|
|
|
|
const amountDAIToBorrow = await convertToCurrencyDecimals(
|
|
|
|
dai.address,
|
|
|
|
new BigNumber(userGlobalData.availableBorrowsETH.toString())
|
|
|
|
.div(daiPrice.toString())
|
|
|
|
.multipliedBy(0.95)
|
|
|
|
.toFixed(0)
|
|
|
|
);
|
|
|
|
|
|
|
|
await pool
|
|
|
|
.connect(borrower.signer)
|
|
|
|
.borrow(dai.address, amountDAIToBorrow, RateMode.Variable, '0');
|
|
|
|
|
|
|
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
|
2020-07-27 14:14:21 +00:00
|
|
|
'8000',
|
2020-06-18 14:36:37 +00:00
|
|
|
'Invalid liquidation threshold'
|
|
|
|
);
|
|
|
|
|
|
|
|
//someone tries to liquidate user 2
|
|
|
|
await expect(
|
2020-08-13 11:06:23 +00:00
|
|
|
pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
|
2020-06-18 14:36:37 +00:00
|
|
|
).to.be.revertedWith(HF_IS_NOT_BELLOW_THRESHOLD);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('LIQUIDATION - Drop the health factor below 1', async () => {
|
2020-08-13 17:25:29 +00:00
|
|
|
const {dai, users, pool, oracle} = testEnv;
|
2020-06-18 14:36:37 +00:00
|
|
|
const borrower = users[1];
|
|
|
|
|
|
|
|
const daiPrice = await oracle.getAssetPrice(dai.address);
|
|
|
|
|
|
|
|
await oracle.setAssetPrice(
|
|
|
|
dai.address,
|
|
|
|
new BigNumber(daiPrice.toString()).multipliedBy(1.15).toFixed(0)
|
|
|
|
);
|
|
|
|
|
|
|
|
const userGlobalData = await pool.getUserAccountData(borrower.address);
|
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
expect(userGlobalData.healthFactor.toString()).to.be.bignumber.lt(oneEther, INVALID_HF);
|
2020-06-18 14:36:37 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('LIQUIDATION - Tries to liquidate a different currency than the loan principal', async () => {
|
2020-08-13 11:06:23 +00:00
|
|
|
const {pool, users, weth} = testEnv;
|
2020-06-18 14:36:37 +00:00
|
|
|
const borrower = users[1];
|
|
|
|
//user 2 tries to borrow
|
|
|
|
await expect(
|
2020-08-19 12:23:41 +00:00
|
|
|
pool.liquidationCall(weth.address, weth.address, borrower.address, oneEther.toString(), true)
|
2020-06-18 14:36:37 +00:00
|
|
|
).revertedWith(USER_DID_NOT_BORROW_SPECIFIED);
|
|
|
|
});
|
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
it('LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral', async () => {
|
2020-08-21 07:33:06 +00:00
|
|
|
const {pool, dai, users} = testEnv;
|
2020-07-08 15:26:50 +00:00
|
|
|
const borrower = users[1];
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
await expect(
|
|
|
|
pool.liquidationCall(dai.address, dai.address, borrower.address, oneEther.toString(), true)
|
2020-08-05 22:46:22 +00:00
|
|
|
).revertedWith(THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED);
|
2020-07-08 15:26:50 +00:00
|
|
|
});
|
2020-06-18 14:36:37 +00:00
|
|
|
|
|
|
|
it('LIQUIDATION - Liquidates the borrow', async () => {
|
2020-08-13 11:06:23 +00:00
|
|
|
const {pool, dai, weth, users, oracle} = testEnv;
|
2020-06-18 14:36:37 +00:00
|
|
|
const borrower = users[1];
|
|
|
|
|
|
|
|
//mints dai to the caller
|
|
|
|
|
|
|
|
await dai.mint(await convertToCurrencyDecimals(dai.address, '1000'));
|
|
|
|
|
|
|
|
//approve protocol to access depositor wallet
|
2020-06-20 23:40:03 +00:00
|
|
|
await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
const daiReserveDataBefore = await getReserveData(pool, dai.address);
|
2020-08-13 11:06:23 +00:00
|
|
|
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address);
|
|
|
|
|
|
|
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentVariableDebt.toString())
|
2020-06-18 14:36:37 +00:00
|
|
|
.div(2)
|
|
|
|
.toFixed(0);
|
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
const tx = await pool.liquidationCall(
|
2020-08-13 11:06:23 +00:00
|
|
|
weth.address,
|
2020-06-18 14:36:37 +00:00
|
|
|
dai.address,
|
|
|
|
borrower.address,
|
|
|
|
amountToLiquidate,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
|
|
|
const userReserveDataAfter = await pool.getUserReserveData(dai.address, borrower.address);
|
|
|
|
|
|
|
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
|
|
|
|
|
|
|
const daiReserveDataAfter = await pool.getReserveData(dai.address);
|
2020-08-13 11:06:23 +00:00
|
|
|
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-08-13 11:06:23 +00:00
|
|
|
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
2020-06-18 14:36:37 +00:00
|
|
|
const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
|
|
|
|
|
2020-07-08 15:26:50 +00:00
|
|
|
const collateralDecimals = (
|
2020-08-13 11:06:23 +00:00
|
|
|
await pool.getReserveConfigurationData(weth.address)
|
2020-07-08 15:26:50 +00:00
|
|
|
).decimals.toString();
|
|
|
|
const principalDecimals = (
|
|
|
|
await pool.getReserveConfigurationData(dai.address)
|
|
|
|
).decimals.toString();
|
2020-06-18 14:36:37 +00:00
|
|
|
|
|
|
|
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
|
|
|
.times(new BigNumber(amountToLiquidate).times(105))
|
|
|
|
.times(new BigNumber(10).pow(collateralDecimals))
|
|
|
|
.div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
|
|
|
|
.decimalPlaces(0, BigNumber.ROUND_DOWN);
|
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
if (!tx.blockNumber) {
|
|
|
|
expect(false, 'Invalid block number');
|
2020-07-08 15:26:50 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const txTimestamp = new BigNumber(
|
|
|
|
(await BRE.ethers.provider.getBlock(tx.blockNumber)).timestamp
|
|
|
|
);
|
2020-07-08 15:26:50 +00:00
|
|
|
|
|
|
|
const variableDebtBeforeTx = calcExpectedVariableDebtTokenBalance(
|
|
|
|
daiReserveDataBefore,
|
2020-07-13 08:54:08 +00:00
|
|
|
userReserveDataBefore,
|
|
|
|
txTimestamp
|
2020-07-08 15:26:50 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
|
2020-06-18 14:36:37 +00:00
|
|
|
oneEther.toFixed(0),
|
|
|
|
'Invalid health factor'
|
|
|
|
);
|
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
expect(userReserveDataAfter.currentVariableDebt.toString()).to.be.bignumber.almostEqual(
|
2020-07-13 08:54:08 +00:00
|
|
|
new BigNumber(variableDebtBeforeTx).minus(amountToLiquidate).toFixed(0),
|
2020-06-18 14:36:37 +00:00
|
|
|
'Invalid user borrow balance after liquidation'
|
|
|
|
);
|
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
expect(daiReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
|
2020-06-18 14:36:37 +00:00
|
|
|
new BigNumber(daiReserveDataBefore.availableLiquidity.toString())
|
|
|
|
.plus(amountToLiquidate)
|
|
|
|
.toFixed(0),
|
|
|
|
'Invalid principal available liquidity'
|
|
|
|
);
|
|
|
|
|
2020-07-15 14:44:20 +00:00
|
|
|
//the liquidity index of the principal reserve needs to be bigger than the index before
|
|
|
|
expect(daiReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gt(
|
|
|
|
daiReserveDataBefore.liquidityIndex.toString(),
|
|
|
|
'Invalid liquidity index'
|
|
|
|
);
|
|
|
|
|
|
|
|
//the principal APY after a liquidation needs to be lower than the APY before
|
|
|
|
expect(daiReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
|
|
|
|
daiReserveDataBefore.liquidityRate.toString(),
|
|
|
|
'Invalid liquidity APY'
|
|
|
|
);
|
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
|
2020-07-07 15:14:44 +00:00
|
|
|
new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
|
2020-06-18 14:36:37 +00:00
|
|
|
'Invalid collateral available liquidity'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2020-08-13 17:25:29 +00:00
|
|
|
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
2020-08-13 11:06:23 +00:00
|
|
|
const {users, pool, usdc, oracle, weth} = testEnv;
|
2020-07-13 08:54:08 +00:00
|
|
|
const depositor = users[3];
|
|
|
|
const borrower = users[4];
|
|
|
|
//mints USDC to depositor
|
|
|
|
await usdc
|
|
|
|
.connect(depositor.signer)
|
|
|
|
.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//approve protocol to access depositor wallet
|
|
|
|
await usdc.connect(depositor.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//user 3 deposits 1000 USDC
|
|
|
|
const amountUSDCtoDeposit = await convertToCurrencyDecimals(usdc.address, '1000');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
await pool.connect(depositor.signer).deposit(usdc.address, amountUSDCtoDeposit, '0');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//user 4 deposits 1 ETH
|
2020-08-13 11:06:23 +00:00
|
|
|
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-08-13 17:25:29 +00:00
|
|
|
//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);
|
2020-08-19 12:23:41 +00:00
|
|
|
|
2020-08-20 12:32:20 +00:00
|
|
|
await pool.connect(borrower.signer).deposit(weth.address, amountETHtoDeposit, '0');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//user 4 borrows
|
|
|
|
const userGlobalData = await pool.getUserAccountData(borrower.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const usdcPrice = await oracle.getAssetPrice(usdc.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const amountUSDCToBorrow = await convertToCurrencyDecimals(
|
|
|
|
usdc.address,
|
|
|
|
new BigNumber(userGlobalData.availableBorrowsETH.toString())
|
|
|
|
.div(usdcPrice.toString())
|
|
|
|
.multipliedBy(0.95)
|
|
|
|
.toFixed(0)
|
|
|
|
);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
await pool
|
|
|
|
.connect(borrower.signer)
|
|
|
|
.borrow(usdc.address, amountUSDCToBorrow, RateMode.Stable, '0');
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//drops HF below 1
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
await oracle.setAssetPrice(
|
|
|
|
usdc.address,
|
|
|
|
new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0)
|
|
|
|
);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//mints dai to the liquidator
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
await usdc.mint(await convertToCurrencyDecimals(usdc.address, '1000'));
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
//approve protocol to access depositor wallet
|
|
|
|
await usdc.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const usdcReserveDataBefore = await pool.getReserveData(usdc.address);
|
2020-08-13 11:06:23 +00:00
|
|
|
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
|
|
|
.div(2)
|
|
|
|
.toFixed(0);
|
2020-06-18 14:36:37 +00:00
|
|
|
|
2020-07-13 08:54:08 +00:00
|
|
|
await pool.liquidationCall(
|
2020-08-13 11:06:23 +00:00
|
|
|
weth.address,
|
2020-07-13 08:54:08 +00:00
|
|
|
usdc.address,
|
|
|
|
borrower.address,
|
|
|
|
amountToLiquidate,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
|
|
|
|
const userReserveDataAfter = await pool.getUserReserveData(usdc.address, borrower.address);
|
|
|
|
|
|
|
|
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
|
|
|
|
|
|
|
const usdcReserveDataAfter = await pool.getReserveData(usdc.address);
|
2020-08-13 11:06:23 +00:00
|
|
|
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
2020-07-13 08:54:08 +00:00
|
|
|
|
2020-08-13 11:06:23 +00:00
|
|
|
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
2020-07-13 08:54:08 +00:00
|
|
|
const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
|
|
|
|
|
|
|
|
const collateralDecimals = (
|
2020-08-13 11:06:23 +00:00
|
|
|
await pool.getReserveConfigurationData(weth.address)
|
2020-07-13 08:54:08 +00:00
|
|
|
).decimals.toString();
|
|
|
|
const principalDecimals = (
|
|
|
|
await pool.getReserveConfigurationData(usdc.address)
|
|
|
|
).decimals.toString();
|
|
|
|
|
|
|
|
const expectedCollateralLiquidated = new BigNumber(principalPrice)
|
|
|
|
.times(new BigNumber(amountToLiquidate).times(105))
|
|
|
|
.times(new BigNumber(10).pow(collateralDecimals))
|
|
|
|
.div(new BigNumber(collateralPrice).times(new BigNumber(10).pow(principalDecimals)))
|
|
|
|
.decimalPlaces(0, BigNumber.ROUND_DOWN);
|
|
|
|
|
|
|
|
expect(userGlobalDataAfter.healthFactor.toString()).to.be.bignumber.gt(
|
|
|
|
oneEther.toFixed(0),
|
|
|
|
'Invalid health factor'
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(userReserveDataAfter.currentStableDebt.toString()).to.be.bignumber.almostEqual(
|
|
|
|
new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
|
|
|
.minus(amountToLiquidate)
|
|
|
|
.toFixed(0),
|
|
|
|
'Invalid user borrow balance after liquidation'
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(usdcReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
|
|
|
|
new BigNumber(usdcReserveDataBefore.availableLiquidity.toString())
|
|
|
|
.plus(amountToLiquidate)
|
|
|
|
.toFixed(0),
|
|
|
|
'Invalid principal available liquidity'
|
|
|
|
);
|
|
|
|
|
2020-07-15 14:44:20 +00:00
|
|
|
//the liquidity index of the principal reserve needs to be bigger than the index before
|
|
|
|
expect(usdcReserveDataAfter.liquidityIndex.toString()).to.be.bignumber.gt(
|
|
|
|
usdcReserveDataBefore.liquidityIndex.toString(),
|
|
|
|
'Invalid liquidity index'
|
|
|
|
);
|
|
|
|
|
|
|
|
//the principal APY after a liquidation needs to be lower than the APY before
|
|
|
|
expect(usdcReserveDataAfter.liquidityRate.toString()).to.be.bignumber.lt(
|
|
|
|
usdcReserveDataBefore.liquidityRate.toString(),
|
|
|
|
'Invalid liquidity APY'
|
|
|
|
);
|
|
|
|
|
2020-08-19 12:23:41 +00:00
|
|
|
expect(ethReserveDataAfter.availableLiquidity.toString()).to.be.bignumber.almostEqual(
|
2020-07-13 08:54:08 +00:00
|
|
|
new BigNumber(ethReserveDataBefore.availableLiquidity.toString()).toFixed(0),
|
|
|
|
'Invalid collateral available liquidity'
|
|
|
|
);
|
|
|
|
});
|
2020-06-18 14:36:37 +00:00
|
|
|
});
|