More fixes, some stable tests fail WIP

This commit is contained in:
Zer0dot 2021-02-02 17:44:46 -05:00
parent 19436c055e
commit 9431541593
7 changed files with 260 additions and 76 deletions

View File

@ -26,6 +26,9 @@ import {UserConfiguration} from '../libraries/configuration/UserConfiguration.so
import {DataTypes} from '../libraries/types/DataTypes.sol'; import {DataTypes} from '../libraries/types/DataTypes.sol';
import {LendingPoolStorage} from './LendingPoolStorage.sol'; import {LendingPoolStorage} from './LendingPoolStorage.sol';
// TEST
import { console } from 'hardhat/console.sol';
/** /**
* @title LendingPool contract * @title LendingPool contract
* @dev Main point of interaction with an Aave protocol's market * @dev Main point of interaction with an Aave protocol's market
@ -206,7 +209,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
address onBehalfOf address onBehalfOf
) external override whenNotPaused { ) external override whenNotPaused {
DataTypes.ReserveData storage reserve = _reserves[asset]; DataTypes.ReserveData storage reserve = _reserves[asset];
_executeBorrow( _executeBorrow(
ExecuteBorrowParams( ExecuteBorrowParams(
asset, asset,

View File

@ -16,6 +16,8 @@ import {Helpers} from '../helpers/Helpers.sol';
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol'; import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
import {DataTypes} from '../types/DataTypes.sol'; import {DataTypes} from '../types/DataTypes.sol';
import {console} from 'hardhat/console.sol';
/** /**
* @title ReserveLogic library * @title ReserveLogic library
* @author Aave * @author Aave
@ -194,7 +196,7 @@ library ValidationLogic {
//check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve //check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED); require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
console.log("Reserve aToken balance on borrowing address:", IERC20(reserve.aTokenAddress).balanceOf(userAddress));
require( require(
!userConfig.isUsingAsCollateral(reserve.id) || !userConfig.isUsingAsCollateral(reserve.id) ||
reserve.configuration.getLtv() == 0 || reserve.configuration.getLtv() == 0 ||

View File

@ -298,79 +298,111 @@ export const deployDefaultReserveInterestRateStrategy = async (
export const deployStableDebtToken = async ( export const deployStableDebtToken = async (
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress], args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
verify: boolean verify: boolean
) => ) => {
withSaveAndVerify( const instance = await withSaveAndVerify(
await new StableDebtTokenFactory(await getFirstSigner()).deploy(), await new StableDebtTokenFactory(await getFirstSigner()).deploy(),
eContractid.StableDebtToken, eContractid.StableDebtToken,
args, [],
verify verify
); );
await instance.initialize(
args[0],
args[1],
args[2],
"18",
args[3],
args[4]
);
return instance;
}
export const deployVariableDebtToken = async ( export const deployVariableDebtToken = async (
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress], args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress],
verify: boolean verify: boolean
) => ) => {
withSaveAndVerify( const instance = await withSaveAndVerify(
await new VariableDebtTokenFactory(await getFirstSigner()).deploy(), await new VariableDebtTokenFactory(await getFirstSigner()).deploy(),
eContractid.VariableDebtToken, eContractid.VariableDebtToken,
args, [],
verify verify
); );
await instance.initialize(
args[0],
args[1],
args[2],
"18",
args[3],
args[4]
);
return instance;
}
export const deployGenericAToken = async ( export const deployGenericAToken = async (
[poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol,incentivesController]: [ [poolAddress, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
tEthereumAddress,
tEthereumAddress, tEthereumAddress,
tEthereumAddress, tEthereumAddress,
tEthereumAddress, tEthereumAddress,
string, string,
string, string
tEthereumAddress
], ],
verify: boolean verify: boolean
) => { ) => {
const args: [ const instance = await withSaveAndVerify(
tEthereumAddress,
tEthereumAddress,
string,
string,
tEthereumAddress,
tEthereumAddress
] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
return withSaveAndVerify(
await new ATokenFactory(await getFirstSigner()).deploy(), await new ATokenFactory(await getFirstSigner()).deploy(),
eContractid.AToken, eContractid.AToken,
args, [],
verify verify
); );
await instance.initialize(
poolAddress,
treasuryAddress,
underlyingAssetAddress,
incentivesController,
"18",
name,
symbol
);
return instance;
}; };
export const deployDelegationAwareAToken = async ( export const deployDelegationAwareAToken = async (
[poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController]: [ [pool, underlyingAssetAddress, treasuryAddress, incentivesController, name, symbol]: [
tEthereumAddress,
tEthereumAddress, tEthereumAddress,
tEthereumAddress, tEthereumAddress,
tEthereumAddress, tEthereumAddress,
string, string,
string, string
tEthereumAddress
], ],
verify: boolean verify: boolean
) => { ) => {
const args: [ const instance = await withSaveAndVerify(
tEthereumAddress,
tEthereumAddress,
string,
string,
tEthereumAddress,
tEthereumAddress
] = [poolAddress, underlyingAssetAddress, treasuryAddress, name, symbol, incentivesController];
return withSaveAndVerify(
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(), await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(),
eContractid.DelegationAwareAToken, eContractid.DelegationAwareAToken,
args, [],
verify verify
); );
await instance.initialize(
pool,
treasuryAddress,
underlyingAssetAddress,
incentivesController,
"18",
name,
symbol
)
return instance;
}; };
export const deployAllMockTokens = async (verify?: boolean) => { export const deployAllMockTokens = async (verify?: boolean) => {
@ -447,16 +479,29 @@ export const deployWETHGateway = async (
); );
export const deployMockStableDebtToken = async ( export const deployMockStableDebtToken = async (
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress], args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
verify?: boolean verify?: boolean
) => ) => {
withSaveAndVerify( const instance = await withSaveAndVerify(
await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(), await new MockStableDebtTokenFactory(await getFirstSigner()).deploy(),
eContractid.MockStableDebtToken, eContractid.MockStableDebtToken,
args, [],
verify verify
); );
await instance.initialize(
args[0],
args[1],
args[2],
"18",
args[3],
args[4]
);
return instance;
}
export const deployWETHMocked = async (verify?: boolean) => export const deployWETHMocked = async (verify?: boolean) =>
withSaveAndVerify( withSaveAndVerify(
await new WETH9MockedFactory(await getFirstSigner()).deploy(), await new WETH9MockedFactory(await getFirstSigner()).deploy(),
@ -466,26 +511,53 @@ export const deployWETHMocked = async (verify?: boolean) =>
); );
export const deployMockVariableDebtToken = async ( export const deployMockVariableDebtToken = async (
args: [tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress], args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string],
verify?: boolean verify?: boolean
) => ) => {
withSaveAndVerify( const instance = await withSaveAndVerify(
await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(), await new MockVariableDebtTokenFactory(await getFirstSigner()).deploy(),
eContractid.MockVariableDebtToken, eContractid.MockVariableDebtToken,
args, [],
verify verify
); );
await instance.initialize(
args[0],
args[1],
args[2],
"18",
args[3],
args[4]
);
return instance;
}
export const deployMockAToken = async ( export const deployMockAToken = async (
args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress], args: [tEthereumAddress, tEthereumAddress, tEthereumAddress,tEthereumAddress, string, string],
verify?: boolean verify?: boolean
) => ) => {
withSaveAndVerify( const instance = await withSaveAndVerify(
await new MockATokenFactory(await getFirstSigner()).deploy(), await new MockATokenFactory(await getFirstSigner()).deploy(),
eContractid.MockAToken, eContractid.MockAToken,
args, [],
verify verify
); );
await instance.initialize(
args[0],
args[2],
args[1],
args[3],
"18",
args[4],
args[5],
);
return instance;
}
export const deploySelfdestructTransferMock = async (verify?: boolean) => export const deploySelfdestructTransferMock = async (verify?: boolean) =>
withSaveAndVerify( withSaveAndVerify(

View File

@ -231,11 +231,11 @@ export const initReservesByHelper = async (
treasury: treasuryAddress, treasury: treasuryAddress,
incentivesController: ZERO_ADDRESS, incentivesController: ZERO_ADDRESS,
underlyingAssetName: reserveSymbols[i], underlyingAssetName: reserveSymbols[i],
aTokenName: `Aave Interest Bearing ${reserveSymbols[i]}`, aTokenName: `Aave interest bearing ${reserveSymbols[i]}`,
aTokenSymbol: `a${reserveSymbols[i]}`, aTokenSymbol: `a${reserveSymbols[i]}`,
variableDebtTokenName: `Aave Variable Debt ${reserveSymbols[i]}`, variableDebtTokenName: `Aave variable debt bearing ${reserveSymbols[i]}`,
variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`, variableDebtTokenSymbol: `variableDebt${reserveSymbols[i]}`,
stableDebtTokenName: `Aave Stable Debt ${reserveSymbols[i]}`, stableDebtTokenName: `Aave stable debt bearing ${reserveSymbols[i]}`,
stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}` stableDebtTokenSymbol: `stableDebt${reserveSymbols[i]}`
}); });
} }
@ -263,9 +263,9 @@ export const initReservesByHelper = async (
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
treasuryAddress, treasuryAddress,
ZERO_ADDRESS,
`Aave interest bearing ${symbol}`, `Aave interest bearing ${symbol}`,
`a${symbol}`, `a${symbol}`,
ZERO_ADDRESS,
], ],
verify verify
); );
@ -273,9 +273,9 @@ export const initReservesByHelper = async (
[ [
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
ZERO_ADDRESS, // Incentives controller
`Aave stable debt bearing ${symbol}`, `Aave stable debt bearing ${symbol}`,
`stableDebt${symbol}`, `stableDebt${symbol}`
ZERO_ADDRESS,
], ],
verify verify
); );
@ -283,9 +283,9 @@ export const initReservesByHelper = async (
[ [
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
ZERO_ADDRESS, // Incentives controller
`Aave variable debt bearing ${symbol}`, `Aave variable debt bearing ${symbol}`,
`variableDebt${symbol}`, `variableDebt${symbol}`,
ZERO_ADDRESS,
], ],
verify verify
); );
@ -573,9 +573,9 @@ export const initTokenReservesByHelper = async (
[ [
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
ZERO_ADDRESS, // Incentives controller
`Aave stable debt bearing ${symbol}`, `Aave stable debt bearing ${symbol}`,
`stableDebt${symbol}`, `stableDebt${symbol}`
ZERO_ADDRESS,
], ],
verify verify
); );
@ -586,9 +586,9 @@ export const initTokenReservesByHelper = async (
[ [
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
ZERO_ADDRESS, // Incentives Controller
`Aave variable debt bearing ${symbol}`, `Aave variable debt bearing ${symbol}`,
`variableDebt${symbol}`, `variableDebt${symbol}`
ZERO_ADDRESS,
], ],
verify verify
); );
@ -604,9 +604,9 @@ export const initTokenReservesByHelper = async (
poolAddress, poolAddress,
tokenAddresses[symbol], tokenAddresses[symbol],
treasuryAddress, treasuryAddress,
`Aave interest bearing ${symbol}`,
`a${symbol}`,
ZERO_ADDRESS, ZERO_ADDRESS,
`Aave interest bearing ${symbol}`,
`a${symbol}`
], ],
verify verify
); );

View File

@ -9,6 +9,7 @@ import { DRE } from '../helpers/misc-utils';
import { import {
ConfigNames, ConfigNames,
getATokenDomainSeparatorPerNetwork, getATokenDomainSeparatorPerNetwork,
getTreasuryAddress,
loadPoolConfig, loadPoolConfig,
} from '../helpers/configuration'; } from '../helpers/configuration';
import { waitForTx } from '../helpers/misc-utils'; import { waitForTx } from '../helpers/misc-utils';
@ -19,6 +20,7 @@ import {
import { DelegationAwareATokenFactory } from '../types'; import { DelegationAwareATokenFactory } from '../types';
import { DelegationAwareAToken } from '../types/DelegationAwareAToken'; import { DelegationAwareAToken } from '../types/DelegationAwareAToken';
import { MintableDelegationERC20 } from '../types/MintableDelegationERC20'; import { MintableDelegationERC20 } from '../types/MintableDelegationERC20';
import AaveConfig from '../markets/aave';
const { parseEther } = ethers.utils; const { parseEther } = ethers.utils;
@ -33,11 +35,11 @@ makeSuite('AToken: underlying delegation', (testEnv: TestEnv) => {
delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']); delegationERC20 = await deployMintableDelegationERC20(['DEL', 'DEL', '18']);
delegationAToken = await deployDelegationAwareAToken( delegationAToken = await deployDelegationAwareAToken(
[pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL'], [pool.address, delegationERC20.address, await getTreasuryAddress(AaveConfig), ZERO_ADDRESS, 'aDEL', 'aDEL'],
false false
); );
await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL'); //await delegationAToken.initialize(pool.address, ZERO_ADDRESS, delegationERC20.address, ZERO_ADDRESS, '18', 'aDEL', 'aDEL');
console.log((await delegationAToken.decimals()).toString()); console.log((await delegationAToken.decimals()).toString());
}); });

View File

@ -161,6 +161,9 @@ export const deposit = async (
if (sendValue) { if (sendValue) {
txOptions.value = await convertToCurrencyDecimals(reserve, sendValue); txOptions.value = await convertToCurrencyDecimals(reserve, sendValue);
} }
//console.log("Depositing %s %s, expecting %s", amountToDeposit.toString(), reserveSymbol, expectedResult);
if (expectedResult === 'success') { if (expectedResult === 'success') {
const txResult = await waitForTx( const txResult = await waitForTx(
await pool await pool
@ -348,7 +351,7 @@ export const borrow = async (
); );
const amountToBorrow = await convertToCurrencyDecimals(reserve, amount); const amountToBorrow = await convertToCurrencyDecimals(reserve, amount);
//console.log("Borrowing %s %s with rate mode %s expecting", amountToBorrow.toString(), reserveSymbol, interestRateMode, expectedResult);
if (expectedResult === 'success') { if (expectedResult === 'success') {
const txResult = await waitForTx( const txResult = await waitForTx(
await pool await pool

View File

@ -10,6 +10,7 @@ import {
getAToken, getAToken,
getMockStableDebtToken, getMockStableDebtToken,
getMockVariableDebtToken, getMockVariableDebtToken,
getStableDebtToken,
getVariableDebtToken, getVariableDebtToken,
} from '../helpers/contracts-getters'; } from '../helpers/contracts-getters';
import { import {
@ -30,25 +31,25 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
pool.address, pool.address,
dai.address, dai.address,
ZERO_ADDRESS, ZERO_ADDRESS,
ZERO_ADDRESS,
'Aave Interest bearing DAI updated', 'Aave Interest bearing DAI updated',
'aDAI', 'aDAI',
ZERO_ADDRESS,
]); ]);
const stableDebtTokenInstance = await deployMockStableDebtToken([ const stableDebtTokenInstance = await deployMockStableDebtToken([
pool.address, pool.address,
dai.address, dai.address,
ZERO_ADDRESS,
'Aave stable debt bearing DAI updated', 'Aave stable debt bearing DAI updated',
'stableDebtDAI', 'stableDebtDAI',
ZERO_ADDRESS,
]); ]);
const variableDebtTokenInstance = await deployMockVariableDebtToken([ const variableDebtTokenInstance = await deployMockVariableDebtToken([
pool.address, pool.address,
dai.address, dai.address,
ZERO_ADDRESS,
'Aave variable debt bearing DAI updated', 'Aave variable debt bearing DAI updated',
'variableDebtDAI', 'variableDebtDAI',
ZERO_ADDRESS,
]); ]);
newATokenAddress = aTokenInstance.address; newATokenAddress = aTokenInstance.address;
@ -59,8 +60,26 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => { it('Tries to update the DAI Atoken implementation with a different address than the lendingPoolManager', async () => {
const {dai, configurator, users} = testEnv; const {dai, configurator, users} = testEnv;
const name = await (await getAToken(newATokenAddress)).name();
const symbol = await (await getAToken(newATokenAddress)).symbol();
const updateATokenInputParams: {
asset: string;
treasury: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
treasury: ZERO_ADDRESS,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newATokenAddress,
};
await expect( await expect(
configurator.connect(users[1].signer).updateAToken(dai.address, newATokenAddress) configurator.connect(users[1].signer).updateAToken(updateATokenInputParams)
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
}); });
@ -68,8 +87,24 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
const {dai, configurator, aDai} = testEnv; const {dai, configurator, aDai} = testEnv;
const name = await (await getAToken(newATokenAddress)).name(); const name = await (await getAToken(newATokenAddress)).name();
const symbol = await (await getAToken(newATokenAddress)).symbol();
await configurator.updateAToken(dai.address, newATokenAddress); const updateATokenInputParams: {
asset: string;
treasury: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
treasury: ZERO_ADDRESS,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newATokenAddress,
};
await configurator.updateAToken(updateATokenInputParams);
const tokenName = await aDai.name(); const tokenName = await aDai.name();
@ -79,19 +114,53 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => { it('Tries to update the DAI Stable debt token implementation with a different address than the lendingPoolManager', async () => {
const {dai, configurator, users} = testEnv; const {dai, configurator, users} = testEnv;
const name = await (await getStableDebtToken(newStableTokenAddress)).name();
const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
const updateDebtTokenInput: {
asset: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newStableTokenAddress,
}
await expect( await expect(
configurator configurator
.connect(users[1].signer) .connect(users[1].signer)
.updateStableDebtToken(dai.address, newStableTokenAddress) .updateStableDebtToken(updateDebtTokenInput)
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
}); });
it('Upgrades the DAI stable debt token implementation ', async () => { it('Upgrades the DAI stable debt token implementation ', async () => {
const {dai, configurator, pool, helpersContract} = testEnv; const {dai, configurator, pool, helpersContract} = testEnv;
const name = await (await getAToken(newATokenAddress)).name(); const name = await (await getStableDebtToken(newStableTokenAddress)).name();
const symbol = await (await getStableDebtToken(newStableTokenAddress)).symbol();
await configurator.updateStableDebtToken(dai.address, newStableTokenAddress);
const updateDebtTokenInput: {
asset: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newStableTokenAddress,
}
await configurator.updateStableDebtToken(updateDebtTokenInput);
const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address); const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);
@ -104,20 +173,53 @@ makeSuite('Upgradeability', (testEnv: TestEnv) => {
it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => { it('Tries to update the DAI variable debt token implementation with a different address than the lendingPoolManager', async () => {
const {dai, configurator, users} = testEnv; const {dai, configurator, users} = testEnv;
const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
const updateDebtTokenInput: {
asset: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newVariableTokenAddress,
}
await expect( await expect(
configurator configurator
.connect(users[1].signer) .connect(users[1].signer)
.updateVariableDebtToken(dai.address, newVariableTokenAddress) .updateVariableDebtToken(updateDebtTokenInput)
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN); ).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
}); });
it('Upgrades the DAI variable debt token implementation ', async () => { it('Upgrades the DAI variable debt token implementation ', async () => {
const {dai, configurator, pool, helpersContract} = testEnv; const {dai, configurator, pool, helpersContract} = testEnv;
const name = await (await getVariableDebtToken(newVariableTokenAddress)).name();
const symbol = await (await getVariableDebtToken(newVariableTokenAddress)).symbol();
const updateDebtTokenInput: {
asset: string;
incentivesController: string;
name: string;
symbol: string;
implementation: string;
} = {
asset: dai.address,
incentivesController: ZERO_ADDRESS,
name: name,
symbol: symbol,
implementation: newVariableTokenAddress,
}
//const name = await (await getAToken(newATokenAddress)).name();
const name = await (await getAToken(newATokenAddress)).name(); await configurator.updateVariableDebtToken(updateDebtTokenInput);
await configurator.updateVariableDebtToken(dai.address, newVariableTokenAddress);
const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address); const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(dai.address);