aave-protocol-v2/helpers/init-helpers.ts

294 lines
9.5 KiB
TypeScript
Raw Normal View History

2020-12-01 11:39:54 +00:00
import {
eContractid,
eNetwork,
2020-12-01 11:39:54 +00:00
iMultiPoolsAssets,
IReserveParams,
tEthereumAddress,
} from './types';
import { AaveProtocolDataProvider } from '../types/AaveProtocolDataProvider';
import { chunk, getDb, waitForTx } from './misc-utils';
import {
getAToken,
getATokensAndRatesHelper,
getLendingPoolAddressesProvider,
getLendingPoolConfiguratorProxy,
} from './contracts-getters';
2020-11-19 16:46:23 +00:00
import {
getContractAddressWithJsonFallback,
rawInsertContractAddressInDb,
} from './contracts-helpers';
import { BigNumberish } from 'ethers';
import { ConfigNames } from './configuration';
import { deployRateStrategy } from './contracts-deployments';
export const getATokenExtraParams = async (aTokenName: string, tokenAddress: tEthereumAddress) => {
console.log(aTokenName);
switch (aTokenName) {
2020-11-20 11:11:57 +00:00
default:
return '0x10';
2020-11-20 11:11:57 +00:00
}
};
2020-10-23 13:18:01 +00:00
export const initReservesByHelper = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: { [symbol: string]: tEthereumAddress },
2021-02-19 20:50:06 +00:00
aTokenNamePrefix: string,
stableDebtTokenNamePrefix: string,
variableDebtTokenNamePrefix: string,
symbolPrefix: string,
admin: tEthereumAddress,
2020-11-27 15:40:00 +00:00
treasuryAddress: tEthereumAddress,
2020-11-19 16:46:23 +00:00
incentivesController: tEthereumAddress,
poolName: ConfigNames,
2020-11-19 16:46:23 +00:00
verify: boolean
) => {
const addressProvider = await getLendingPoolAddressesProvider();
// CHUNK CONFIGURATION
const initChunks = 1;
2020-10-23 13:18:01 +00:00
// Initialize variables for future reserves initialization
2020-11-19 16:46:23 +00:00
let reserveSymbols: string[] = [];
let initInputParams: {
aTokenImpl: string;
stableDebtTokenImpl: string;
variableDebtTokenImpl: string;
underlyingAssetDecimals: BigNumberish;
interestRateStrategyAddress: string;
underlyingAsset: string;
treasury: string;
incentivesController: string;
underlyingAssetName: string;
aTokenName: string;
aTokenSymbol: string;
variableDebtTokenName: string;
variableDebtTokenSymbol: string;
stableDebtTokenName: string;
stableDebtTokenSymbol: string;
2021-02-26 18:18:38 +00:00
params: string;
}[] = [];
let strategyRates: [
string, // addresses provider
string,
string,
string,
string,
string,
string
];
let rateStrategies: Record<string, typeof strategyRates> = {};
let strategyAddresses: Record<string, tEthereumAddress> = {};
const reserves = Object.entries(reservesParams);
2020-11-20 11:11:57 +00:00
for (let [symbol, params] of reserves) {
if (!tokenAddresses[symbol]) {
console.log(`- Skipping init of ${symbol} due token address is not set at markets config`);
continue;
}
const { strategy, aTokenImpl, reserveDecimals } = params;
2020-11-19 16:46:23 +00:00
const {
2020-11-20 11:11:57 +00:00
optimalUtilizationRate,
2020-11-19 16:46:23 +00:00
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
} = strategy;
if (!strategyAddresses[strategy.name]) {
// Strategy does not exist, create a new one
rateStrategies[strategy.name] = [
addressProvider.address,
2020-11-20 11:11:57 +00:00
optimalUtilizationRate,
2020-11-19 16:46:23 +00:00
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
];
strategyAddresses[strategy.name] = await deployRateStrategy(
strategy.name,
rateStrategies[strategy.name],
verify
);
// This causes the last strategy to be printed twice, once under "DefaultReserveInterestRateStrategy"
// and once under the actual `strategyASSET` key.
rawInsertContractAddressInDb(strategy.name, strategyAddresses[strategy.name]);
}
// Prepare input parameters
2020-11-20 11:11:57 +00:00
reserveSymbols.push(symbol);
2021-02-06 02:51:12 +00:00
initInputParams.push({
aTokenImpl: await getContractAddressWithJsonFallback(aTokenImpl, poolName),
stableDebtTokenImpl: await getContractAddressWithJsonFallback(
eContractid.StableDebtToken,
poolName
),
variableDebtTokenImpl: await getContractAddressWithJsonFallback(
eContractid.VariableDebtToken,
poolName
),
underlyingAssetDecimals: reserveDecimals,
interestRateStrategyAddress: strategyAddresses[strategy.name],
underlyingAsset: tokenAddresses[symbol],
2021-02-06 02:51:12 +00:00
treasury: treasuryAddress,
incentivesController: incentivesController,
underlyingAssetName: symbol,
aTokenName: `${aTokenNamePrefix} ${symbol}`,
aTokenSymbol: `a${symbolPrefix}${symbol}`,
variableDebtTokenName: `${variableDebtTokenNamePrefix} ${symbolPrefix}${symbol}`,
variableDebtTokenSymbol: `variableDebt${symbolPrefix}${symbol}`,
stableDebtTokenName: `${stableDebtTokenNamePrefix} ${symbol}`,
stableDebtTokenSymbol: `stableDebt${symbolPrefix}${symbol}`,
params: await getATokenExtraParams(aTokenImpl, tokenAddresses[symbol]),
2021-02-06 02:51:12 +00:00
});
}
// Deploy init reserves per chunks
2020-11-19 16:46:23 +00:00
const chunkedSymbols = chunk(reserveSymbols, initChunks);
2021-02-06 02:51:12 +00:00
const chunkedInitInputParams = chunk(initInputParams, initChunks);
const configurator = await getLendingPoolConfiguratorProxy();
2021-02-06 02:51:12 +00:00
console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`);
for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) {
2020-10-23 13:18:01 +00:00
const tx3 = await waitForTx(
2021-05-10 13:56:47 +00:00
await configurator.batchInitReserve(chunkedInitInputParams[chunkIndex])
2020-10-23 13:18:01 +00:00
);
console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
console.log(' * gasUsed', tx3.gasUsed.toString());
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 }
2020-10-26 09:41:24 +00:00
): [string[], string[]] => {
const { ETH, USD, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses;
2020-10-26 09:41:24 +00:00
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];
2020-10-26 09:41:24 +00:00
return [tokenAddress, aggregatorAddress];
}
}) as [string, string][];
const mappedPairs = pairs.map(([asset]) => asset);
const mappedAggregators = pairs.map(([, source]) => source);
return [mappedPairs, mappedAggregators];
};
export const configureReservesByHelper = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: { [symbol: string]: tEthereumAddress },
helpers: AaveProtocolDataProvider,
admin: tEthereumAddress
) => {
const addressProvider = await getLendingPoolAddressesProvider();
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
const tokens: string[] = [];
const symbols: string[] = [];
2021-02-06 02:51:12 +00:00
const inputParams: {
asset: string;
baseLTV: BigNumberish;
liquidationThreshold: BigNumberish;
liquidationBonus: BigNumberish;
reserveFactor: BigNumberish;
stableBorrowingEnabled: boolean;
borrowingEnabled: boolean;
}[] = [];
2020-10-26 09:41:24 +00:00
for (const [
assetSymbol,
{
baseLTVAsCollateral,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
borrowingEnabled,
},
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (!tokenAddresses[assetSymbol]) {
console.log(
`- Skipping init of ${assetSymbol} due token address is not set at markets config`
);
continue;
}
if (baseLTVAsCollateral === '-1') 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
];
const { usageAsCollateralEnabled: alreadyEnabled } = await helpers.getReserveConfigurationData(
tokenAddress
);
2020-10-26 09:41:24 +00:00
if (alreadyEnabled) {
console.log(`- Reserve ${assetSymbol} is already enabled as collateral, skipping`);
continue;
}
// Push data
inputParams.push({
asset: tokenAddress,
baseLTV: baseLTVAsCollateral,
liquidationThreshold: liquidationThreshold,
liquidationBonus: liquidationBonus,
reserveFactor: reserveFactor,
stableBorrowingEnabled: stableBorrowRateEnabled,
borrowingEnabled: borrowingEnabled,
});
tokens.push(tokenAddress);
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));
// Deploy init per chunks
const enableChunks = 20;
const chunkedSymbols = chunk(symbols, enableChunks);
const chunkedInputParams = chunk(inputParams, enableChunks);
2021-02-06 02:51:12 +00:00
console.log(`- Configure reserves in ${chunkedInputParams.length} txs`);
for (let chunkIndex = 0; chunkIndex < chunkedInputParams.length; chunkIndex++) {
await waitForTx(
await atokenAndRatesDeployer.configureReserves(chunkedInputParams[chunkIndex])
2020-10-26 09:41:24 +00:00
);
console.log(` - Init for: ${chunkedSymbols[chunkIndex].join(', ')}`);
2020-10-26 09:41:24 +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
}
};
2020-12-01 11:39:54 +00:00
const getAddressById = async (
id: string,
network: eNetwork
2020-12-01 11:39:54 +00:00
): Promise<tEthereumAddress | undefined> =>
(await getDb().get(`${id}.${network}`).value())?.address || undefined;
2021-02-10 23:47:31 +00:00
// Function deprecated
const isErc20SymbolCorrect = async (token: tEthereumAddress, symbol: string) => {
const erc20 = await getAToken(token); // using aToken for ERC20 interface
const erc20Symbol = await erc20.symbol();
return symbol === erc20Symbol;
};