- Added tests of repayWithCollateral(), only for self-liquidation.

This commit is contained in:
eboado 2020-09-08 15:05:53 +02:00
parent 2cbb1f5714
commit 3aa0dbc570
10 changed files with 571 additions and 7 deletions

View File

@ -0,0 +1,21 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
interface ISwapAdapter {
/**
* @dev Swaps an `amountToSwap` of an asset to another, approving a `fundsDestination` to pull the funds
* @param assetToSwapFrom Origin asset
* @param assetToSwapTo Destination asset
* @param amountToSwap How much `assetToSwapFrom` needs to be swapped
* @param fundsDestination Address that will be pulling the swapped funds
* @param params Additional variadic field to include extra params
*/
function executeOperation(
address assetToSwapFrom,
address assetToSwapTo,
uint256 amountToSwap,
address fundsDestination,
bytes calldata params
) external;
}

View File

@ -21,7 +21,7 @@ import {Helpers} from '../libraries/helpers/Helpers.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
import {ISwapAdapter} from '../interfaces/ISwapAdapter.sol';
/**
* @title LendingPoolLiquidationManager contract
@ -393,12 +393,14 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
vars.collateralAtoken.burn(user, receiver, vars.maxCollateralToLiquidate);
address principalAToken = debtReserve.aTokenAddress;
// Notifies the receiver to proceed, sending as param the underlying already transferred
IFlashLoanReceiver(receiver).executeOperation(
ISwapAdapter(receiver).executeOperation(
collateral,
address(vars.collateralAtoken),
principal,
vars.maxCollateralToLiquidate,
0,
address(this),
params
);
@ -406,11 +408,11 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
debtReserve.updateCumulativeIndexesAndTimestamp();
debtReserve.updateInterestRates(
principal,
debtReserve.aTokenAddress,
principalAToken,
vars.actualAmountToLiquidate,
0
);
IERC20(principal).transferFrom(receiver, debtReserve.aTokenAddress, vars.actualAmountToLiquidate);
IERC20(principal).transferFrom(receiver, principalAToken, vars.actualAmountToLiquidate);
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(

View File

@ -0,0 +1,43 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import {MintableERC20} from '../tokens/MintableERC20.sol';
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
import {ISwapAdapter} from '../../interfaces/ISwapAdapter.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
contract MockSwapAdapter is ISwapAdapter {
uint256 amountToReturn;
ILendingPoolAddressesProvider public addressesProvider;
event Swapped(address fromAsset, address toAsset, uint256 fromAmount, uint256 receivedAmount);
constructor(ILendingPoolAddressesProvider provider) public {
addressesProvider = provider;
}
function setAmountToReturn(uint256 amount) public {
amountToReturn = amount;
}
function executeOperation(
address assetToSwapFrom,
address assetToSwapTo,
uint256 amountToSwap,
address fundsDestination,
bytes calldata params
) external override {
params;
IERC20(assetToSwapFrom).transfer(address(1), amountToSwap); // We don't want to keep funds here
MintableERC20(assetToSwapTo).mint(amountToReturn);
IERC20(assetToSwapTo).approve(fundsDestination, amountToReturn);
emit Swapped(assetToSwapFrom, assetToSwapTo, amountToSwap, amountToReturn);
}
function burnAsset(IERC20 asset, uint256 amount) public {
uint256 amountToBurn = (amount == type(uint256).max) ? asset.balanceOf(address(this)) : amount;
asset.transfer(address(0), amountToBurn);
}
}

View File

@ -31,6 +31,7 @@ import BigNumber from 'bignumber.js';
import {Ierc20Detailed} from '../types/Ierc20Detailed';
import {StableDebtToken} from '../types/StableDebtToken';
import {VariableDebtToken} from '../types/VariableDebtToken';
import { MockSwapAdapter } from '../types/MockSwapAdapter';
export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => {
const currentNetwork = BRE.network.name;
@ -212,6 +213,11 @@ export const deployMockFlashLoanReceiver = async (addressesProvider: tEthereumAd
addressesProvider,
]);
export const deployMockSwapAdapter = async (addressesProvider: tEthereumAddress) =>
await deployContract<MockSwapAdapter>(eContractid.MockSwapAdapter, [
addressesProvider,
]);
export const deployWalletBalancerProvider = async (addressesProvider: tEthereumAddress) =>
await deployContract<WalletBalanceProvider>(eContractid.WalletBalanceProvider, [
addressesProvider,
@ -387,6 +393,15 @@ export const getMockFlashLoanReceiver = async (address?: tEthereumAddress) => {
);
};
export const getMockSwapAdapter = async (address?: tEthereumAddress) => {
return await getContract<MockSwapAdapter>(
eContractid.MockSwapAdapter,
address ||
(await getDb().get(`${eContractid.MockSwapAdapter}.${BRE.network.name}`).value())
.address
);
};
export const getLendingRateOracle = async (address?: tEthereumAddress) => {
return await getContract<LendingRateOracle>(
eContractid.LendingRateOracle,

View File

@ -32,6 +32,7 @@ export enum eContractid {
LendingPoolLiquidationManager = 'LendingPoolLiquidationManager',
InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
MockFlashLoanReceiver = 'MockFlashLoanReceiver',
MockSwapAdapter = 'MockSwapAdapter',
WalletBalanceProvider = 'WalletBalanceProvider',
AToken = 'AToken',
MockAToken = 'MockAToken',

View File

@ -13,6 +13,7 @@
"types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
"test": "buidler test",
"test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts",
"test-repay-with-collateral": "buidler test test/__setup.spec.ts test/repay-with-collateral.spec.ts",
"dev:coverage": "buidler coverage",
"dev:deployment": "buidler dev-deployment",
"dev:deployExample": "buidler deploy-Example",

View File

@ -23,6 +23,7 @@ import {
deployStableDebtToken,
deployVariableDebtToken,
deployGenericAToken,
deployMockSwapAdapter,
} from '../helpers/contracts-helpers';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {ContractTransaction, Signer} from 'ethers';
@ -503,6 +504,9 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(addressesProvider.address);
await insertContractAddressInDb(eContractid.MockFlashLoanReceiver, mockFlashLoanReceiver.address);
const mockSwapAdapter = await deployMockSwapAdapter(addressesProvider.address)
await insertContractAddressInDb(eContractid.MockSwapAdapter, mockSwapAdapter.address)
await deployWalletBalancerProvider(addressesProvider.address);
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address);

View File

@ -845,7 +845,7 @@ const getTxCostAndTimestamp = async (tx: ContractReceipt) => {
return {txCost, txTimestamp};
};
const getContractsData = async (reserve: string, user: string, testEnv: TestEnv) => {
export const getContractsData = async (reserve: string, user: string, testEnv: TestEnv) => {
const {pool} = testEnv;
const reserveData = await getReserveData(pool, reserve);
const userData = await getUserData(pool, reserve, user);

View File

@ -9,6 +9,7 @@ import {
getMintableErc20,
getLendingPoolConfiguratorProxy,
getPriceOracle,
getMockSwapAdapter,
} from '../../helpers/contracts-helpers';
import {tEthereumAddress} from '../../helpers/types';
import {LendingPool} from '../../types/LendingPool';
@ -23,6 +24,7 @@ import bignumberChai from 'chai-bignumber';
import {almostEqual} from './almost-equal';
import {PriceOracle} from '../../types/PriceOracle';
import {LendingPoolAddressesProvider} from '../../types/LendingPoolAddressesProvider';
import { MockSwapAdapter } from '../../types/MockSwapAdapter';
chai.use(bignumberChai());
chai.use(almostEqual());
@ -44,6 +46,7 @@ export interface TestEnv {
usdc: MintableErc20;
lend: MintableErc20;
addressesProvider: LendingPoolAddressesProvider;
mockSwapAdapter: MockSwapAdapter;
}
let buidlerevmSnapshotId: string = '0x1';
@ -67,6 +70,7 @@ const testEnv: TestEnv = {
usdc: {} as MintableErc20,
lend: {} as MintableErc20,
addressesProvider: {} as LendingPoolAddressesProvider,
mockSwapAdapter: {} as MockSwapAdapter
} as TestEnv;
export async function initializeMakeSuite() {
@ -125,6 +129,8 @@ export async function initializeMakeSuite() {
testEnv.usdc = await getMintableErc20(usdcAddress);
testEnv.lend = await getMintableErc20(lendAddress);
testEnv.weth = await getMintableErc20(wethAddress);
testEnv.mockSwapAdapter = await getMockSwapAdapter()
}
export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) {

View File

@ -0,0 +1,471 @@
import {TestEnv, makeSuite} from './helpers/make-suite';
import {APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants';
import {ethers} from 'ethers';
import BigNumber from 'bignumber.js';
import {
calcExpectedVariableDebtTokenBalance,
calcExpectedStableDebtTokenBalance,
} from './helpers/utils/calculations';
import {getContractsData} from './helpers/actions';
import {waitForTx} from './__setup.spec';
import {timeLatest} from '../helpers/misc-utils';
import {tEthereumAddress} from '../helpers/types';
const {expect} = require('chai');
const {parseUnits, parseEther} = ethers.utils;
const expectRepayWithCollateralEvent = (
events: ethers.Event[],
pool: tEthereumAddress,
collateral: tEthereumAddress,
borrowing: tEthereumAddress,
user: tEthereumAddress
) => {
if (!events || events.length < 14) {
expect(false, 'INVALID_EVENTS_LENGTH_ON_REPAY_COLLATERAL');
}
const repayWithCollateralEvent = events[13];
expect(repayWithCollateralEvent.address).to.be.equal(pool);
expect(`0x${repayWithCollateralEvent.topics[1].slice(26)}`.toLowerCase()).to.be.equal(
collateral.toLowerCase()
);
expect(`0x${repayWithCollateralEvent.topics[2].slice(26)}`).to.be.equal(borrowing.toLowerCase());
expect(`0x${repayWithCollateralEvent.topics[3].slice(26)}`.toLowerCase()).to.be.equal(
user.toLowerCase()
);
};
makeSuite('LendingPool. repayWithCollateral()', (testEnv: TestEnv) => {
it('User 1 provides some liquidity for others to borrow', async () => {
const {pool, weth, dai, usdc} = testEnv;
await weth.mint(parseEther('200'));
await weth.approve(pool.address, parseEther('200'));
await pool.deposit(weth.address, parseEther('200'), 0);
await dai.mint(parseEther('20000'));
await dai.approve(pool.address, parseEther('20000'));
await pool.deposit(dai.address, parseEther('20000'), 0);
await usdc.mint(parseEther('20000'));
await usdc.approve(pool.address, parseEther('20000'));
await pool.deposit(usdc.address, parseEther('20000'), 0);
});
it('User 2 deposit WETH and borrows DAI at Variable', async () => {
const {pool, weth, dai, users} = testEnv;
const user = users[1];
const amountToDeposit = ethers.utils.parseEther('1');
const amountToBorrow = ethers.utils.parseEther('20');
await weth.connect(user.signer).mint(amountToDeposit);
await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(weth.address, amountToDeposit, '0');
await pool.connect(user.signer).borrow(dai.address, amountToBorrow, 2, 0);
});
it('User 2 tries to repay his DAI Variable loan using his WETH collateral. First half the amount, after that, the rest', async () => {
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
const user = users[1];
const amountToRepay = parseEther('10');
const {userData: wethUserDataBefore} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {reserveData: daiReserveDataBefore, userData: daiUserDataBefore} = await getContractsData(
dai.address,
user.address,
testEnv
);
await mockSwapAdapter.setAmountToReturn(amountToRepay);
await waitForTx(
await pool
.connect(user.signer)
.repayWithCollateral(
weth.address,
dai.address,
user.address,
amountToRepay,
mockSwapAdapter.address,
'0x'
)
);
const repayWithCollateralTimestamp = await timeLatest();
const {userData: wethUserDataAfter} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {userData: daiUserDataAfter} = await getContractsData(dai.address, user.address, testEnv);
const collateralPrice = await oracle.getAssetPrice(weth.address);
const principalPrice = await oracle.getAssetPrice(dai.address);
const collateralDecimals = (
await pool.getReserveConfigurationData(weth.address)
).decimals.toString();
const principalDecimals = (
await pool.getReserveConfigurationData(dai.address)
).decimals.toString();
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
.times(new BigNumber(amountToRepay.toString()).times(105))
.times(new BigNumber(10).pow(collateralDecimals))
.div(
new BigNumber(collateralPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(100)
.decimalPlaces(0, BigNumber.ROUND_DOWN);
const expectedVariableDebtIncrease = calcExpectedVariableDebtTokenBalance(
daiReserveDataBefore,
daiUserDataBefore,
new BigNumber(repayWithCollateralTimestamp)
).minus(daiUserDataBefore.currentVariableDebt);
expect(daiUserDataAfter.currentVariableDebt).to.be.bignumber.almostEqual(
new BigNumber(daiUserDataBefore.currentVariableDebt)
.minus(amountToRepay.toString())
.plus(expectedVariableDebtIncrease)
.toString()
);
expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.equal(
new BigNumber(wethUserDataBefore.currentATokenBalance).minus(
expectedCollateralLiquidated.toString()
)
);
});
it('User 3 deposits WETH and borrows USDC at Variable', async () => {
const {pool, weth, usdc, users} = testEnv;
const user = users[2];
const amountToDeposit = parseEther('10');
const amountToBorrow = parseUnits('40', 6);
await weth.connect(user.signer).mint(amountToDeposit);
await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(weth.address, amountToDeposit, '0');
await pool.connect(user.signer).borrow(usdc.address, amountToBorrow, 2, 0);
});
it('User 3 repays completely his USDC loan by swapping his WETH collateral', async () => {
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
const user = users[2];
const amountToRepay = parseUnits('10', 6);
const {userData: wethUserDataBefore} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {
reserveData: usdcReserveDataBefore,
userData: usdcUserDataBefore,
} = await getContractsData(usdc.address, user.address, testEnv);
await mockSwapAdapter.setAmountToReturn(amountToRepay);
await waitForTx(
await pool
.connect(user.signer)
.repayWithCollateral(
weth.address,
usdc.address,
user.address,
amountToRepay,
mockSwapAdapter.address,
'0x'
)
);
const repayWithCollateralTimestamp = await timeLatest();
const {userData: wethUserDataAfter} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {userData: usdcUserDataAfter} = await getContractsData(
usdc.address,
user.address,
testEnv
);
const collateralPrice = await oracle.getAssetPrice(weth.address);
const principalPrice = await oracle.getAssetPrice(usdc.address);
const collateralDecimals = (
await pool.getReserveConfigurationData(weth.address)
).decimals.toString();
const principalDecimals = (
await pool.getReserveConfigurationData(usdc.address)
).decimals.toString();
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
.times(new BigNumber(amountToRepay.toString()).times(105))
.times(new BigNumber(10).pow(collateralDecimals))
.div(
new BigNumber(collateralPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(100)
.decimalPlaces(0, BigNumber.ROUND_DOWN);
const expectedVariableDebtIncrease = calcExpectedVariableDebtTokenBalance(
usdcReserveDataBefore,
usdcUserDataBefore,
new BigNumber(repayWithCollateralTimestamp)
).minus(usdcUserDataBefore.currentVariableDebt);
expect(usdcUserDataAfter.currentVariableDebt).to.be.bignumber.almostEqual(
new BigNumber(usdcUserDataBefore.currentVariableDebt)
.minus(amountToRepay.toString())
.plus(expectedVariableDebtIncrease)
.toString(),
'INVALID_DEBT_POSITION'
);
expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.equal(
new BigNumber(wethUserDataBefore.currentATokenBalance).minus(
expectedCollateralLiquidated.toString()
),
'INVALID_COLLATERAL_POSITION'
);
});
it('User tries to repay with his collateral a currency he havent borrow', async () => {
const {pool, weth, dai, users, mockSwapAdapter} = testEnv;
const user = users[2];
const amountToRepay = parseUnits('10', 6);
await expect(
pool
.connect(user.signer)
.repayWithCollateral(
weth.address,
dai.address,
user.address,
amountToRepay,
mockSwapAdapter.address,
'0x'
)
).to.be.revertedWith('revert CURRRENCY_NOT_BORROWED');
});
it('User tries to repay with his collateral all his variable debt and part of the stable', async () => {
const {pool, weth, usdc, users, mockSwapAdapter, oracle} = testEnv;
const user = users[2];
const amountToDeposit = parseEther('20');
const amountToBorrowStable = parseUnits('40', 6);
const amountToBorrowVariable = parseUnits('40', 6);
await weth.connect(user.signer).mint(amountToDeposit);
await pool.connect(user.signer).deposit(weth.address, amountToDeposit, '0');
await pool.connect(user.signer).borrow(usdc.address, amountToBorrowVariable, 2, 0);
await pool.connect(user.signer).borrow(usdc.address, amountToBorrowStable, 1, 0);
const amountToRepay = parseUnits('80', 6);
const {userData: wethUserDataBefore} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {
reserveData: usdcReserveDataBefore,
userData: usdcUserDataBefore,
} = await getContractsData(usdc.address, user.address, testEnv);
await mockSwapAdapter.setAmountToReturn(amountToRepay);
const txReceipt = await waitForTx(
await pool
.connect(user.signer)
.repayWithCollateral(
weth.address,
usdc.address,
user.address,
amountToRepay,
mockSwapAdapter.address,
'0x'
)
);
const repayWithCollateralTimestamp = await timeLatest();
const {userData: wethUserDataAfter} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {userData: usdcUserDataAfter} = await getContractsData(
usdc.address,
user.address,
testEnv
);
const collateralPrice = await oracle.getAssetPrice(weth.address);
const principalPrice = await oracle.getAssetPrice(usdc.address);
const collateralDecimals = (
await pool.getReserveConfigurationData(weth.address)
).decimals.toString();
const principalDecimals = (
await pool.getReserveConfigurationData(usdc.address)
).decimals.toString();
const expectedCollateralLiquidated = new BigNumber(principalPrice.toString())
.times(new BigNumber(amountToRepay.toString()).times(105))
.times(new BigNumber(10).pow(collateralDecimals))
.div(
new BigNumber(collateralPrice.toString()).times(new BigNumber(10).pow(principalDecimals))
)
.div(100)
.decimalPlaces(0, BigNumber.ROUND_DOWN);
const expectedVariableDebtIncrease = calcExpectedVariableDebtTokenBalance(
usdcReserveDataBefore,
usdcUserDataBefore,
new BigNumber(repayWithCollateralTimestamp)
).minus(usdcUserDataBefore.currentVariableDebt);
const expectedStableDebtIncrease = calcExpectedStableDebtTokenBalance(
usdcUserDataBefore,
new BigNumber(repayWithCollateralTimestamp)
).minus(usdcUserDataBefore.currentStableDebt);
expect(usdcUserDataAfter.currentVariableDebt).to.be.bignumber.equal(
new BigNumber(usdcUserDataBefore.currentVariableDebt)
.minus(amountToRepay.toString())
.plus(expectedVariableDebtIncrease)
.gte(0)
? new BigNumber(usdcUserDataBefore.currentVariableDebt)
.minus(amountToRepay.toString())
.plus(expectedVariableDebtIncrease)
.toString()
: '0',
'INVALID_VARIABLE_DEBT_POSITION'
);
const stableDebtRepaid = new BigNumber(usdcUserDataBefore.currentVariableDebt)
.minus(amountToRepay.toString())
.plus(expectedVariableDebtIncrease)
.abs();
expect(usdcUserDataAfter.currentStableDebt).to.be.bignumber.equal(
new BigNumber(usdcUserDataBefore.currentStableDebt)
.minus(stableDebtRepaid)
.plus(expectedStableDebtIncrease)
.gte(0)
? new BigNumber(usdcUserDataBefore.currentStableDebt)
.minus(stableDebtRepaid)
.plus(expectedStableDebtIncrease)
.toString()
: '0',
'INVALID_STABLE_DEBT_POSITION'
);
expect(wethUserDataAfter.currentATokenBalance).to.be.bignumber.equal(
new BigNumber(wethUserDataBefore.currentATokenBalance).minus(
expectedCollateralLiquidated.toString()
),
'INVALID_COLLATERAL_POSITION'
);
const eventsEmitted = txReceipt.events || [];
expectRepayWithCollateralEvent(
eventsEmitted,
pool.address,
weth.address,
usdc.address,
user.address
);
});
// WIP
it('User tries to repay a bigger amount that what can be swapped of a particular collateral, repaying only the maximum allowed by that collateral', async () => {
const {pool, weth, dai, users, mockSwapAdapter, oracle} = testEnv;
const user = users[3];
const amountToDepositWeth = parseEther('0.1');
const amountToDepositDAI = parseEther('500');
const amountToBorrowVariable = parseEther('80');
await weth.connect(user.signer).mint(amountToDepositWeth);
await dai.connect(user.signer).mint(amountToDepositDAI);
await weth.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await dai.connect(user.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
await pool.connect(user.signer).deposit(weth.address, amountToDepositWeth, '0');
await pool.connect(user.signer).deposit(dai.address, amountToDepositDAI, '0');
await pool.connect(user.signer).borrow(dai.address, amountToBorrowVariable, 2, 0);
const amountToRepay = parseEther('80');
const {userData: wethUserDataBefore} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {reserveData: daiReserveDataBefore, userData: daiUserDataBefore} = await getContractsData(
dai.address,
user.address,
testEnv
);
console.log('BEFORE');
console.log(wethUserDataBefore.currentATokenBalance.toString());
console.log(daiUserDataBefore.currentVariableDebt.toString());
console.log(daiUserDataBefore.currentStableDebt.toString());
await mockSwapAdapter.setAmountToReturn(amountToRepay);
const txReceipt = await waitForTx(
await pool
.connect(user.signer)
.repayWithCollateral(
weth.address,
dai.address,
user.address,
amountToRepay,
mockSwapAdapter.address,
'0x'
)
);
const repayWithCollateralTimestamp = await timeLatest();
const {userData: wethUserDataAfter} = await getContractsData(
weth.address,
user.address,
testEnv
);
const {userData: daiUserDataAfter} = await getContractsData(dai.address, user.address, testEnv);
console.log('AFTER');
console.log(wethUserDataAfter.currentATokenBalance.toString());
console.log(daiUserDataAfter.currentVariableDebt.toString());
console.log(daiUserDataAfter.currentStableDebt.toString());
});
});