2020-11-10 13:18:48 +00:00
|
|
|
import {eContractid, iMultiPoolsAssets, IReserveParams, tEthereumAddress} from './types';
|
2020-08-21 11:07:32 +00:00
|
|
|
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
|
2020-11-10 14:19:47 +00:00
|
|
|
import {AaveProtocolDataProvider} from '../types/AaveProtocolDataProvider';
|
2020-10-15 17:19:02 +00:00
|
|
|
import {
|
2020-10-26 16:43:10 +00:00
|
|
|
deployATokensAndRatesHelper,
|
|
|
|
deployStableAndVariableTokensHelper,
|
2020-10-16 09:27:09 +00:00
|
|
|
} from './contracts-deployments';
|
2020-10-23 16:38:27 +00:00
|
|
|
import {chunk, waitForTx} from './misc-utils';
|
2020-10-27 09:58:51 +00:00
|
|
|
import {
|
|
|
|
getATokensAndRatesHelper,
|
|
|
|
getLendingPoolAddressesProvider,
|
|
|
|
getStableAndVariableTokensHelper,
|
|
|
|
} from './contracts-getters';
|
2020-11-10 13:18:48 +00:00
|
|
|
import {insertContractAddressInDb, rawInsertContractAddressInDb} from './contracts-helpers';
|
2020-10-15 17:19:02 +00:00
|
|
|
|
2020-10-23 13:18:01 +00:00
|
|
|
export const initReservesByHelper = async (
|
|
|
|
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
|
|
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
2020-10-23 16:38:27 +00:00
|
|
|
admin: tEthereumAddress,
|
2020-10-27 09:58:51 +00:00
|
|
|
incentivesController: tEthereumAddress
|
2020-10-23 13:18:01 +00:00
|
|
|
) => {
|
2020-10-27 09:58:51 +00:00
|
|
|
const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
|
|
|
|
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
|
|
|
|
|
|
|
|
const addressProvider = await getLendingPoolAddressesProvider();
|
2020-10-23 13:18:01 +00:00
|
|
|
|
2020-10-23 16:38:27 +00:00
|
|
|
// Set aTokenAndRatesDeployer as temporal admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
2020-10-23 13:18:01 +00:00
|
|
|
|
2020-10-23 16:38:27 +00:00
|
|
|
// CHUNK CONFIGURATION
|
2020-10-27 09:58:51 +00:00
|
|
|
const tokensChunks = 4;
|
2020-10-23 16:38:27 +00:00
|
|
|
const initChunks = 6;
|
2020-10-23 13:18:01 +00:00
|
|
|
|
2020-10-23 16:38:27 +00:00
|
|
|
// Deploy tokens and rates in chunks
|
|
|
|
const reservesChunks = chunk(
|
|
|
|
Object.entries(reservesParams) as [string, IReserveParams][],
|
|
|
|
tokensChunks
|
|
|
|
);
|
|
|
|
// Initialize variables for future reserves initialization
|
|
|
|
let deployedStableTokens: string[] = [];
|
|
|
|
let deployedVariableTokens: string[] = [];
|
|
|
|
let deployedATokens: string[] = [];
|
|
|
|
let deployedRates: string[] = [];
|
|
|
|
let reserveTokens: string[] = [];
|
|
|
|
let reserveInitDecimals: string[] = [];
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
`- Token deployments in ${reservesChunks.length * 2} txs instead of ${
|
|
|
|
Object.entries(reservesParams).length * 4
|
|
|
|
} txs`
|
|
|
|
);
|
|
|
|
for (let reservesChunk of reservesChunks) {
|
|
|
|
// Prepare data
|
|
|
|
const tokens: string[] = [];
|
|
|
|
const symbols: string[] = [];
|
|
|
|
const strategyRates: string[][] = [];
|
|
|
|
const reservesDecimals: string[] = [];
|
|
|
|
|
|
|
|
for (let [assetSymbol, {reserveDecimals}] of reservesChunk) {
|
|
|
|
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
|
|
|
|
(value) => value === assetSymbol
|
|
|
|
);
|
|
|
|
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
|
|
|
assetAddressIndex
|
|
|
|
];
|
|
|
|
|
|
|
|
const reserveParamIndex = Object.keys(reservesParams).findIndex(
|
|
|
|
(value) => value === assetSymbol
|
|
|
|
);
|
|
|
|
const [
|
|
|
|
,
|
|
|
|
{
|
|
|
|
baseVariableBorrowRate,
|
|
|
|
variableRateSlope1,
|
|
|
|
variableRateSlope2,
|
|
|
|
stableRateSlope1,
|
|
|
|
stableRateSlope2,
|
|
|
|
},
|
|
|
|
] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
|
|
|
|
// Add to lists
|
|
|
|
tokens.push(tokenAddress);
|
2020-10-28 10:27:16 +00:00
|
|
|
symbols.push(assetSymbol);
|
2020-10-23 16:38:27 +00:00
|
|
|
strategyRates.push([
|
2020-10-23 13:18:01 +00:00
|
|
|
baseVariableBorrowRate,
|
|
|
|
variableRateSlope1,
|
|
|
|
variableRateSlope2,
|
|
|
|
stableRateSlope1,
|
|
|
|
stableRateSlope2,
|
2020-10-23 16:38:27 +00:00
|
|
|
]);
|
|
|
|
reservesDecimals.push(reserveDecimals);
|
|
|
|
}
|
|
|
|
|
2020-11-10 13:18:48 +00:00
|
|
|
// Deploy stable and variable deployers and save implementations
|
2020-10-23 13:18:01 +00:00
|
|
|
const tx1 = await waitForTx(
|
2020-10-23 16:38:27 +00:00
|
|
|
await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
|
2020-10-23 13:18:01 +00:00
|
|
|
);
|
2020-11-10 13:18:48 +00:00
|
|
|
tx1.events?.forEach((event, index) => {
|
|
|
|
rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken);
|
|
|
|
rawInsertContractAddressInDb(`variableDebt${symbols[index]}`, event?.args?.variableToken);
|
|
|
|
});
|
|
|
|
// Deploy atokens and rate strategies and save implementations
|
2020-10-23 13:18:01 +00:00
|
|
|
const tx2 = await waitForTx(
|
|
|
|
await atokenAndRatesDeployer.initDeployment(
|
2020-10-23 16:38:27 +00:00
|
|
|
tokens,
|
|
|
|
symbols,
|
|
|
|
strategyRates,
|
|
|
|
incentivesController
|
2020-10-23 13:18:01 +00:00
|
|
|
)
|
|
|
|
);
|
2020-11-10 13:18:48 +00:00
|
|
|
tx2.events?.forEach((event, index) => {
|
|
|
|
rawInsertContractAddressInDb(`a${symbols[index]}`, event?.args?.aToken);
|
|
|
|
rawInsertContractAddressInDb(`strategy${symbols[index]}`, event?.args?.strategy);
|
|
|
|
});
|
|
|
|
|
2020-10-23 16:38:27 +00:00
|
|
|
console.log(` - Deployed aToken, DebtTokens and Strategy for: ${symbols.join(', ')} `);
|
|
|
|
const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
|
|
|
|
const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
|
2020-10-23 13:18:01 +00:00
|
|
|
const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
|
|
|
|
const strategies: string[] = tx2.events?.map((e) => e.args?.strategy) || [];
|
2020-10-23 16:38:27 +00:00
|
|
|
|
|
|
|
deployedStableTokens = [...deployedStableTokens, ...stableTokens];
|
|
|
|
deployedVariableTokens = [...deployedVariableTokens, ...variableTokens];
|
|
|
|
deployedATokens = [...deployedATokens, ...aTokens];
|
|
|
|
deployedRates = [...deployedRates, ...strategies];
|
|
|
|
reserveInitDecimals = [...reserveInitDecimals, ...reservesDecimals];
|
|
|
|
reserveTokens = [...reserveTokens, ...tokens];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deploy init reserves per chunks
|
|
|
|
const chunkedStableTokens = chunk(deployedStableTokens, initChunks);
|
|
|
|
const chunkedVariableTokens = chunk(deployedVariableTokens, initChunks);
|
|
|
|
const chunkedAtokens = chunk(deployedATokens, initChunks);
|
|
|
|
const chunkedRates = chunk(deployedRates, initChunks);
|
|
|
|
const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
|
|
|
|
const chunkedSymbols = chunk(Object.keys(tokenAddresses), initChunks);
|
|
|
|
|
2020-10-26 09:41:24 +00:00
|
|
|
console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
|
2020-10-23 16:38:27 +00:00
|
|
|
for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
|
2020-10-23 13:18:01 +00:00
|
|
|
const tx3 = await waitForTx(
|
|
|
|
await atokenAndRatesDeployer.initReserve(
|
2020-10-23 16:38:27 +00:00
|
|
|
chunkedStableTokens[chunkIndex],
|
|
|
|
chunkedVariableTokens[chunkIndex],
|
|
|
|
chunkedAtokens[chunkIndex],
|
|
|
|
chunkedRates[chunkIndex],
|
|
|
|
chunkedDecimals[chunkIndex]
|
2020-10-23 13:18:01 +00:00
|
|
|
)
|
|
|
|
);
|
2020-10-23 16:38:27 +00:00
|
|
|
console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
2020-10-23 13:18:01 +00:00
|
|
|
}
|
2020-10-23 16:38:27 +00:00
|
|
|
|
|
|
|
// Set deployer back as admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(admin));
|
2020-10-23 13:18:01 +00:00
|
|
|
};
|
2020-10-26 09:41:24 +00:00
|
|
|
|
|
|
|
export const getPairsTokenAggregator = (
|
|
|
|
allAssetsAddresses: {
|
|
|
|
[tokenSymbol: string]: tEthereumAddress;
|
|
|
|
},
|
|
|
|
aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
|
|
|
|
): [string[], string[]] => {
|
|
|
|
const {ETH, USD, WETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
|
|
|
|
|
|
|
|
const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
|
|
|
|
if (tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH') {
|
|
|
|
const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
|
|
|
|
(value) => value === tokenSymbol
|
|
|
|
);
|
|
|
|
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
|
|
|
|
string,
|
|
|
|
tEthereumAddress
|
|
|
|
][])[aggregatorAddressIndex];
|
|
|
|
return [tokenAddress, aggregatorAddress];
|
|
|
|
}
|
|
|
|
}) as [string, string][];
|
|
|
|
|
|
|
|
const mappedPairs = pairs.map(([asset]) => asset);
|
|
|
|
const mappedAggregators = pairs.map(([, source]) => source);
|
|
|
|
|
|
|
|
return [mappedPairs, mappedAggregators];
|
|
|
|
};
|
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
export const enableReservesToBorrowByHelper = async (
|
2020-10-26 09:41:24 +00:00
|
|
|
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
|
|
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
2020-11-10 14:19:47 +00:00
|
|
|
helpers: AaveProtocolDataProvider,
|
2020-10-26 16:43:10 +00:00
|
|
|
admin: tEthereumAddress
|
2020-10-26 09:41:24 +00:00
|
|
|
) => {
|
2020-10-26 16:43:10 +00:00
|
|
|
const addressProvider = await getLendingPoolAddressesProvider();
|
|
|
|
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
|
|
|
|
const tokens: string[] = [];
|
|
|
|
const symbols: string[] = [];
|
|
|
|
const stableEnabled: boolean[] = [];
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
// Prepare data
|
|
|
|
for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries(
|
|
|
|
reservesParams
|
|
|
|
) as [string, IReserveParams][]) {
|
|
|
|
if (!borrowingEnabled) continue;
|
2020-10-26 09:41:24 +00:00
|
|
|
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
|
|
|
|
(value) => value === assetSymbol
|
|
|
|
);
|
|
|
|
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
|
|
|
assetAddressIndex
|
|
|
|
];
|
2020-10-26 16:43:10 +00:00
|
|
|
const {borrowingEnabled: borrowingAlreadyEnabled} = await helpers.getReserveConfigurationData(
|
|
|
|
tokenAddress
|
|
|
|
);
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
if (borrowingAlreadyEnabled) {
|
|
|
|
console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`);
|
2020-10-26 09:41:24 +00:00
|
|
|
continue;
|
|
|
|
}
|
2020-10-26 16:43:10 +00:00
|
|
|
tokens.push(tokenAddress);
|
|
|
|
stableEnabled.push(stableBorrowRateEnabled);
|
|
|
|
symbols.push(assetSymbol);
|
|
|
|
}
|
|
|
|
if (tokens.length) {
|
|
|
|
// Set aTokenAndRatesDeployer as temporal admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
2020-10-26 16:43:10 +00:00
|
|
|
|
|
|
|
// Deploy init per chunks
|
|
|
|
const stableChunks = 20;
|
|
|
|
const chunkedTokens = chunk(tokens, stableChunks);
|
|
|
|
const chunkedSymbols = chunk(symbols, stableChunks);
|
|
|
|
const chunkedStableEnabled = chunk(stableEnabled, stableChunks);
|
|
|
|
|
|
|
|
console.log(`- Borrow stable initialization in ${chunkedTokens.length} txs`);
|
|
|
|
for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
|
|
|
|
try {
|
|
|
|
await waitForTx(
|
|
|
|
await atokenAndRatesDeployer.enableBorrowingOnReserves(
|
|
|
|
chunkedTokens[chunkIndex],
|
|
|
|
chunkedStableEnabled[chunkIndex],
|
|
|
|
{gasLimit: 12000000}
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
throw error;
|
|
|
|
}
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
console.log(` - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
|
|
|
}
|
|
|
|
// Set deployer back as admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(admin));
|
2020-10-26 16:43:10 +00:00
|
|
|
}
|
|
|
|
};
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
export const enableReservesAsCollateralByHelper = async (
|
|
|
|
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
|
|
|
tokenAddresses: {[symbol: string]: tEthereumAddress},
|
2020-11-10 14:19:47 +00:00
|
|
|
helpers: AaveProtocolDataProvider,
|
2020-10-26 16:43:10 +00:00
|
|
|
admin: tEthereumAddress
|
|
|
|
) => {
|
|
|
|
const addressProvider = await getLendingPoolAddressesProvider();
|
|
|
|
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
|
|
|
|
const tokens: string[] = [];
|
|
|
|
const symbols: string[] = [];
|
|
|
|
const baseLTVA: string[] = [];
|
|
|
|
const liquidationThresholds: string[] = [];
|
|
|
|
const liquidationBonuses: string[] = [];
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
for (const [
|
|
|
|
assetSymbol,
|
|
|
|
{baseLTVAsCollateral, liquidationBonus, liquidationThreshold},
|
|
|
|
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
|
|
|
|
if (baseLTVAsCollateral === '-1') continue;
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
|
|
|
|
(value) => value === assetSymbol
|
|
|
|
);
|
|
|
|
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
|
|
|
|
assetAddressIndex
|
|
|
|
];
|
|
|
|
const {usageAsCollateralEnabled: alreadyEnabled} = await helpers.getReserveConfigurationData(
|
|
|
|
tokenAddress
|
|
|
|
);
|
2020-10-26 09:41:24 +00:00
|
|
|
|
2020-10-26 16:43:10 +00:00
|
|
|
if (alreadyEnabled) {
|
|
|
|
console.log(`- Reserve ${assetSymbol} is already enabled as collateral, skipping`);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// Push data
|
|
|
|
tokens.push(tokenAddress);
|
|
|
|
symbols.push(assetSymbol);
|
|
|
|
baseLTVA.push(baseLTVAsCollateral);
|
|
|
|
liquidationThresholds.push(liquidationThreshold);
|
|
|
|
liquidationBonuses.push(liquidationBonus);
|
|
|
|
}
|
|
|
|
if (tokens.length) {
|
|
|
|
// Set aTokenAndRatesDeployer as temporal admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
2020-10-26 16:43:10 +00:00
|
|
|
|
|
|
|
// Deploy init per chunks
|
|
|
|
const enableChunks = 20;
|
|
|
|
const chunkedTokens = chunk(tokens, enableChunks);
|
|
|
|
const chunkedSymbols = chunk(symbols, enableChunks);
|
|
|
|
const chunkedBase = chunk(baseLTVA, enableChunks);
|
|
|
|
const chunkedliquidationThresholds = chunk(liquidationThresholds, enableChunks);
|
|
|
|
const chunkedliquidationBonuses = chunk(liquidationBonuses, enableChunks);
|
|
|
|
|
|
|
|
console.log(`- Enable reserve as collateral in ${chunkedTokens.length} txs`);
|
|
|
|
for (let chunkIndex = 0; chunkIndex < chunkedTokens.length; chunkIndex++) {
|
|
|
|
await waitForTx(
|
|
|
|
await atokenAndRatesDeployer.enableReservesAsCollateral(
|
|
|
|
chunkedTokens[chunkIndex],
|
|
|
|
chunkedBase[chunkIndex],
|
|
|
|
chunkedliquidationThresholds[chunkIndex],
|
|
|
|
chunkedliquidationBonuses[chunkIndex],
|
|
|
|
{gasLimit: 12000000}
|
|
|
|
)
|
2020-10-26 09:41:24 +00:00
|
|
|
);
|
2020-10-26 16:43:10 +00:00
|
|
|
console.log(` - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
|
2020-10-26 09:41:24 +00:00
|
|
|
}
|
2020-10-26 16:43:10 +00:00
|
|
|
// Set deployer back as admin
|
2020-11-05 11:35:50 +00:00
|
|
|
await waitForTx(await addressProvider.setPoolAdmin(admin));
|
2020-10-26 09:41:24 +00:00
|
|
|
}
|
|
|
|
};
|