From 95e9c3588cdeff1038e57d702c2936158c0f2664 Mon Sep 17 00:00:00 2001 From: David Racero Date: Wed, 14 Jul 2021 16:41:32 +0200 Subject: [PATCH] feat: support custom quote currencies. Added base scripts for custom atokens and rates. --- contracts/misc/AaveOracleV2.sol | 125 ++++++++++++++++++++++ hardhat.config.ts | 2 +- helper-hardhat-config.ts | 6 +- helpers/configuration.ts | 33 +++--- helpers/constants.ts | 2 + helpers/contracts-deployments.ts | 99 +++++++++++++++-- helpers/contracts-getters.ts | 147 +++++++++++++++++--------- helpers/contracts-helpers.ts | 43 ++++++-- helpers/init-helpers.ts | 170 ++++++++---------------------- helpers/misc-utils.ts | 23 ++++ helpers/types.ts | 20 ++-- markets/aave/commons.ts | 44 ++++---- markets/aave/index.ts | 2 +- markets/aave/reservesConfigs.ts | 44 ++++---- markets/amm/commons.ts | 41 +++---- markets/amm/index.ts | 5 +- markets/matic/commons.ts | 2 + markets/xdai/commons.ts | 1 + tasks/dev/3_lending_pool.ts | 8 +- tasks/dev/4_oracles.ts | 25 +++-- tasks/dev/5_initialize.ts | 8 +- tasks/full/2_lending_pool.ts | 4 +- tasks/full/3_oracles.ts | 29 +++-- tasks/full/6-initialize.ts | 1 + tasks/helpers/deploy-new-asset.ts | 15 +-- 25 files changed, 592 insertions(+), 307 deletions(-) create mode 100644 contracts/misc/AaveOracleV2.sol diff --git a/contracts/misc/AaveOracleV2.sol b/contracts/misc/AaveOracleV2.sol new file mode 100644 index 00000000..8af3b08e --- /dev/null +++ b/contracts/misc/AaveOracleV2.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: agpl-3.0 +pragma solidity 0.6.12; + +import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol'; +import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol'; + +import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; +import {IChainlinkAggregator} from '../interfaces/IChainlinkAggregator.sol'; +import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol'; + +/// @title AaveOracleV2 +/// @author Aave +/// @notice Proxy smart contract to get the price of an asset from a price source, with Chainlink Aggregator +/// smart contracts as primary option +/// - If the returned price by a Chainlink aggregator is <= 0, the call is forwarded to a fallbackOracle +/// - Owned by the Aave governance system, allowed to add sources for assets, replace them +/// and change the fallbackOracle +contract AaveOracleV2 is IPriceOracleGetter, Ownable { + using SafeERC20 for IERC20; + + event QuoteCurrencySet(address indexed quoteCurrency, uint256 quoteUnit); + event AssetSourceUpdated(address indexed asset, address indexed source); + event FallbackOracleUpdated(address indexed fallbackOracle); + + mapping(address => IChainlinkAggregator) private assetsSources; + IPriceOracleGetter private _fallbackOracle; + address public immutable QUOTE_CURRENCY; + uint256 public immutable QUOTE_CURRENCY_UNIT; + + /// @notice Constructor + /// @param assets The addresses of the assets + /// @param sources The address of the source of each asset + /// @param fallbackOracle The address of the fallback oracle to use if the data of an + /// aggregator is not consistent + constructor( + address[] memory assets, + address[] memory sources, + address fallbackOracle, + address quoteCurrency, + uint256 quoteCurrencyUnits + ) public { + _setFallbackOracle(fallbackOracle); + _setAssetsSources(assets, sources); + QUOTE_CURRENCY = quoteCurrency; + QUOTE_CURRENCY_UNIT = quoteCurrencyUnits; + emit QuoteCurrencySet(quoteCurrency, quoteCurrencyUnits); + } + + /// @notice External function called by the Aave governance to set or replace sources of assets + /// @param assets The addresses of the assets + /// @param sources The address of the source of each asset + function setAssetSources(address[] calldata assets, address[] calldata sources) + external + onlyOwner + { + _setAssetsSources(assets, sources); + } + + /// @notice Sets the fallbackOracle + /// - Callable only by the Aave governance + /// @param fallbackOracle The address of the fallbackOracle + function setFallbackOracle(address fallbackOracle) external onlyOwner { + _setFallbackOracle(fallbackOracle); + } + + /// @notice Internal function to set the sources for each asset + /// @param assets The addresses of the assets + /// @param sources The address of the source of each asset + function _setAssetsSources(address[] memory assets, address[] memory sources) internal { + require(assets.length == sources.length, 'INCONSISTENT_PARAMS_LENGTH'); + for (uint256 i = 0; i < assets.length; i++) { + assetsSources[assets[i]] = IChainlinkAggregator(sources[i]); + emit AssetSourceUpdated(assets[i], sources[i]); + } + } + + /// @notice Internal function to set the fallbackOracle + /// @param fallbackOracle The address of the fallbackOracle + function _setFallbackOracle(address fallbackOracle) internal { + _fallbackOracle = IPriceOracleGetter(fallbackOracle); + emit FallbackOracleUpdated(fallbackOracle); + } + + /// @notice Gets an asset price by address + /// @param asset The asset address + function getAssetPrice(address asset) public view override returns (uint256) { + IChainlinkAggregator source = assetsSources[asset]; + + if (asset == QUOTE_CURRENCY) { + return QUOTE_CURRENCY_UNIT; + } else if (address(source) == address(0)) { + return _fallbackOracle.getAssetPrice(asset); + } else { + int256 price = IChainlinkAggregator(source).latestAnswer(); + if (price > 0) { + return uint256(price); + } else { + return _fallbackOracle.getAssetPrice(asset); + } + } + } + + /// @notice Gets a list of prices from a list of assets addresses + /// @param assets The list of assets addresses + function getAssetsPrices(address[] calldata assets) external view returns (uint256[] memory) { + uint256[] memory prices = new uint256[](assets.length); + for (uint256 i = 0; i < assets.length; i++) { + prices[i] = getAssetPrice(assets[i]); + } + return prices; + } + + /// @notice Gets the address of the source for an asset address + /// @param asset The address of the asset + /// @return address The address of the source + function getSourceOfAsset(address asset) external view returns (address) { + return address(assetsSources[asset]); + } + + /// @notice Gets the address of the fallback oracle + /// @return address The addres of the fallback oracle + function getFallbackOracle() external view returns (address) { + return address(_fallbackOracle); + } +} diff --git a/hardhat.config.ts b/hardhat.config.ts index dc47392f..5b263e36 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -102,7 +102,7 @@ const buidlerConfig: HardhatUserConfig = { kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42), ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3), main: getCommonNetworkConfig(eEthereumNetwork.main, 1), - tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.tenderlyMain, 3030), + tenderly: getCommonNetworkConfig(eEthereumNetwork.tenderly, 3030), matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137), mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001), xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100), diff --git a/helper-hardhat-config.ts b/helper-hardhat-config.ts index 6747c444..374b9403 100644 --- a/helper-hardhat-config.ts +++ b/helper-hardhat-config.ts @@ -46,7 +46,7 @@ export const NETWORKS_RPC_URL: iParamsPerNetwork = { [eEthereumNetwork.coverage]: 'http://localhost:8555', [eEthereumNetwork.hardhat]: 'http://localhost:8545', [eEthereumNetwork.buidlerevm]: 'http://localhost:8545', - [eEthereumNetwork.tenderlyMain]: `https://rpc.tenderly.co/fork/${TENDERLY_FORK_ID}`, + [eEthereumNetwork.tenderly]: `https://rpc.tenderly.co/fork/`, [ePolygonNetwork.mumbai]: 'https://rpc-mumbai.maticvigil.com', [ePolygonNetwork.matic]: 'https://rpc-mainnet.matic.network', [eXDaiNetwork.xdai]: 'https://rpc.xdaichain.com/', @@ -61,7 +61,7 @@ export const NETWORKS_DEFAULT_GAS: iParamsPerNetwork = { [eEthereumNetwork.coverage]: 65 * GWEI, [eEthereumNetwork.hardhat]: 65 * GWEI, [eEthereumNetwork.buidlerevm]: 65 * GWEI, - [eEthereumNetwork.tenderlyMain]: 0.01 * GWEI, + [eEthereumNetwork.tenderly]: 1 * GWEI, [ePolygonNetwork.mumbai]: 1 * GWEI, [ePolygonNetwork.matic]: 1 * GWEI, [eXDaiNetwork.xdai]: 1 * GWEI, @@ -76,7 +76,7 @@ export const BLOCK_TO_FORK: iParamsPerNetwork = { [eEthereumNetwork.coverage]: undefined, [eEthereumNetwork.hardhat]: undefined, [eEthereumNetwork.buidlerevm]: undefined, - [eEthereumNetwork.tenderlyMain]: 12406069, + [eEthereumNetwork.tenderly]: undefined, [ePolygonNetwork.mumbai]: undefined, [ePolygonNetwork.matic]: undefined, [eXDaiNetwork.xdai]: undefined, diff --git a/helpers/configuration.ts b/helpers/configuration.ts index 5ba2c386..eb33d135 100644 --- a/helpers/configuration.ts +++ b/helpers/configuration.ts @@ -3,14 +3,15 @@ import { iMultiPoolsAssets, IReserveParams, PoolConfiguration, - ICommonConfiguration, eNetwork, + IBaseConfiguration, } from './types'; import { getEthersSignersAddresses, getParamPerPool } from './contracts-helpers'; import AaveConfig from '../markets/aave'; import MaticConfig from '../markets/matic'; import AvalancheConfig from '../markets/avalanche'; import AmmConfig from '../markets/amm'; + import { CommonsConfig } from '../markets/aave/commons'; import { DRE, filterMapBy } from './misc-utils'; import { tEthereumAddress } from './types'; @@ -66,7 +67,7 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets => { const currentNetwork = process.env.FORK ? process.env.FORK : DRE.network.name; const targetAddress = getParamPerNetwork(config.PoolAdmin, currentNetwork); @@ -78,9 +79,7 @@ export const getGenesisPoolAdmin = async ( return addressList[addressIndex]; }; -export const getEmergencyAdmin = async ( - config: ICommonConfiguration -): Promise => { +export const getEmergencyAdmin = async (config: IBaseConfiguration): Promise => { const currentNetwork = process.env.FORK ? process.env.FORK : DRE.network.name; const targetAddress = getParamPerNetwork(config.EmergencyAdmin, currentNetwork); if (targetAddress) { @@ -91,19 +90,17 @@ export const getEmergencyAdmin = async ( return addressList[addressIndex]; }; -export const getTreasuryAddress = async ( - config: ICommonConfiguration -): Promise => { +export const getTreasuryAddress = async (config: IBaseConfiguration): Promise => { const currentNetwork = process.env.FORK ? process.env.FORK : DRE.network.name; return getParamPerNetwork(config.ReserveFactorTreasuryAddress, currentNetwork); }; export const getATokenDomainSeparatorPerNetwork = ( network: eNetwork, - config: ICommonConfiguration + config: IBaseConfiguration ): tEthereumAddress => getParamPerNetwork(config.ATokenDomainSeparator, network); -export const getWethAddress = async (config: ICommonConfiguration) => { +export const getWethAddress = async (config: IBaseConfiguration) => { const currentNetwork = process.env.FORK ? process.env.FORK : DRE.network.name; const wethAddress = getParamPerNetwork(config.WETH, currentNetwork); if (wethAddress) { @@ -116,7 +113,7 @@ export const getWethAddress = async (config: ICommonConfiguration) => { return weth.address; }; -export const getWrappedNativeTokenAddress = async (config: ICommonConfiguration) => { +export const getWrappedNativeTokenAddress = async (config: IBaseConfiguration) => { const currentNetwork = process.env.MAINNET_FORK === 'true' ? 'main' : DRE.network.name; const wethAddress = getParamPerNetwork(config.WrappedNativeToken, currentNetwork); if (wethAddress) { @@ -129,7 +126,7 @@ export const getWrappedNativeTokenAddress = async (config: ICommonConfiguration) return weth.address; }; -export const getLendingRateOracles = (poolConfig: ICommonConfiguration) => { +export const getLendingRateOracles = (poolConfig: IBaseConfiguration) => { const { ProtocolGlobalParams: { UsdAddress }, LendingRateOracleRatesCommon, @@ -141,3 +138,15 @@ export const getLendingRateOracles = (poolConfig: ICommonConfiguration) => { Object.keys(ReserveAssets[network]).includes(key) ); }; + +export const getQuoteCurrency = async (config: IBaseConfiguration) => { + switch (config.OracleQuoteCurrency) { + case 'ETH': + case 'WETH': + return getWethAddress(config); + case 'USD': + return config.ProtocolGlobalParams.UsdAddress; + default: + throw `Quote ${config.OracleQuoteCurrency} currency not set. Add a new case to getQuoteCurrency switch`; + } +}; diff --git a/helpers/constants.ts b/helpers/constants.ts index acd1d14d..c1defc3c 100644 --- a/helpers/constants.ts +++ b/helpers/constants.ts @@ -1,4 +1,5 @@ import BigNumber from 'bignumber.js'; +import { eEthereumNetwork } from './types'; // ---------------- // MATH @@ -12,6 +13,7 @@ export const RAY = new BigNumber(10).exponentiatedBy(27).toFixed(); export const HALF_RAY = new BigNumber(RAY).multipliedBy(0.5).toFixed(); export const WAD_RAY_RATIO = Math.pow(10, 9).toString(); export const oneEther = new BigNumber(Math.pow(10, 18)); +export const oneUsd = new BigNumber(Math.pow(10, 8)); export const oneRay = new BigNumber(Math.pow(10, 27)); export const MAX_UINT_AMOUNT = '115792089237316195423570985008687907853269984665640564039457584007913129639935'; diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 2d764885..ef8c729e 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -1,5 +1,5 @@ import { Contract } from 'ethers'; -import { DRE } from './misc-utils'; +import { DRE, notFalsyOrZeroAddress } from './misc-utils'; import { tEthereumAddress, eContractid, @@ -13,9 +13,8 @@ import { } from './types'; import { MintableERC20 } from '../types/MintableERC20'; import { MockContract } from 'ethereum-waffle'; -import { getReservesConfigByPool } from './configuration'; +import { ConfigNames, getReservesConfigByPool, loadPoolConfig } from './configuration'; import { getFirstSigner } from './contracts-getters'; -import { ZERO_ADDRESS } from './constants'; import { AaveProtocolDataProviderFactory, ATokenFactory, @@ -49,6 +48,7 @@ import { WETH9MockedFactory, WETHGatewayFactory, FlashLiquidationAdapterFactory, + AaveOracleV2Factory, } from '../types'; import { withSaveAndVerify, @@ -57,6 +57,7 @@ import { insertContractAddressInDb, deployContract, verifyContract, + getOptionalParamAddressPerNetwork, } from './contracts-helpers'; import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory'; import { MintableDelegationERC20 } from '../types/MintableDelegationERC20'; @@ -64,6 +65,7 @@ import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins' import { HardhatRuntimeEnvironment } from 'hardhat/types'; import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory'; import { UiPoolDataProvider } from '../types'; +import { eNetwork } from './types'; export const deployUiPoolDataProvider = async ( [incentivesController, aaveOracle]: [tEthereumAddress, tEthereumAddress], @@ -233,6 +235,17 @@ export const deployAaveOracle = async ( verify ); +export const deployAaveOracleV2 = async ( + args: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress, tEthereumAddress, string], + verify?: boolean +) => + withSaveAndVerify( + await new AaveOracleV2Factory(await getFirstSigner()).deploy(...args), + eContractid.AaveOracleV2, + args, + verify + ); + export const deployLendingPoolCollateralManager = async (verify?: boolean) => { const collateralManagerImpl = await new LendingPoolCollateralManagerFactory( await getFirstSigner() @@ -351,20 +364,20 @@ export const deployVariableDebtToken = async ( return instance; }; -export const deployGenericStableDebtToken = async () => +export const deployGenericStableDebtToken = async (verify?: boolean) => withSaveAndVerify( await new StableDebtTokenFactory(await getFirstSigner()).deploy(), eContractid.StableDebtToken, [], - false + verify ); -export const deployGenericVariableDebtToken = async () => +export const deployGenericVariableDebtToken = async (verify?: boolean) => withSaveAndVerify( await new VariableDebtTokenFactory(await getFirstSigner()).deploy(), eContractid.VariableDebtToken, [], - false + verify ); export const deployGenericAToken = async ( @@ -637,3 +650,75 @@ export const deployFlashLiquidationAdapter = async ( args, verify ); + +export const chooseATokenDeployment = (id: eContractid) => { + switch (id) { + case eContractid.AToken: + return deployGenericATokenImpl; + case eContractid.DelegationAwareAToken: + return deployDelegationAwareATokenImpl; + default: + throw Error(`Missing aToken implementation deployment script for: ${id}`); + } +}; + +export const deployATokenImplementations = async ( + pool: ConfigNames, + reservesConfig: { [key: string]: IReserveParams }, + verify = false +) => { + const poolConfig = loadPoolConfig(pool); + const network = DRE.network.name; + + // Obtain the different AToken implementations of all reserves inside the Market config + const aTokenImplementations = [ + ...Object.entries(reservesConfig).reduce>((acc, [, entry]) => { + acc.add(entry.aTokenImpl); + return acc; + }, new Set()), + ]; + + console.log(aTokenImplementations); + + for (let x = 0; x < aTokenImplementations.length; x++) { + const aTokenAddress = getOptionalParamAddressPerNetwork( + poolConfig[aTokenImplementations[x].toString()], + network + ); + if (!notFalsyOrZeroAddress(aTokenAddress)) { + const deployImplementationMethod = chooseATokenDeployment(aTokenImplementations[x]); + console.log(`Deploying implementation`, aTokenImplementations[x]); + await deployImplementationMethod(verify); + } + } + + // Debt tokens, for now all Market configs follows same implementations + const genericStableDebtTokenAddress = getOptionalParamAddressPerNetwork( + poolConfig.StableDebtTokenImplementation, + network + ); + const geneticVariableDebtTokenAddress = getOptionalParamAddressPerNetwork( + poolConfig.VariableDebtTokenImplementation, + network + ); + + if (!notFalsyOrZeroAddress(genericStableDebtTokenAddress)) { + await deployGenericStableDebtToken(verify); + } + if (!notFalsyOrZeroAddress(geneticVariableDebtTokenAddress)) { + await deployGenericVariableDebtToken(verify); + } +}; + +export const deployRateStrategy = async ( + strategyName: string, + args: [tEthereumAddress, string, string, string, string, string, string], + verify: boolean +): Promise => { + switch (strategyName) { + default: + return await ( + await deployDefaultReserveInterestRateStrategy(args, verify) + ).address; + } +}; diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts index b441363c..21641d97 100644 --- a/helpers/contracts-getters.ts +++ b/helpers/contracts-getters.ts @@ -33,7 +33,7 @@ import { } from '../types'; import { IERC20DetailedFactory } from '../types/IERC20DetailedFactory'; import { getEthersSigners, MockTokenMap } from './contracts-helpers'; -import { DRE, getDb, notFalsyOrZeroAddress } from './misc-utils'; +import { DRE, getDb, notFalsyOrZeroAddress, omit } from './misc-utils'; import { eContractid, PoolConfiguration, tEthereumAddress, TokenContractId } from './types'; export const getFirstSigner = async () => (await getEthersSigners())[0]; @@ -41,16 +41,18 @@ export const getFirstSigner = async () => (await getEthersSigners())[0]; export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress) => { return await LendingPoolAddressesProviderFactory.connect( address || - (await getDb().get(`${eContractid.LendingPoolAddressesProvider}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.LendingPoolAddressesProvider}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); }; export const getLendingPoolConfiguratorProxy = async (address?: tEthereumAddress) => { return await LendingPoolConfiguratorFactory.connect( address || - (await getDb().get(`${eContractid.LendingPoolConfigurator}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.LendingPoolConfigurator}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); }; @@ -58,14 +60,18 @@ export const getLendingPoolConfiguratorProxy = async (address?: tEthereumAddress export const getLendingPool = async (address?: tEthereumAddress) => await LendingPoolFactory.connect( address || - (await getDb().get(`${eContractid.LendingPool}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.LendingPool}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getPriceOracle = async (address?: tEthereumAddress) => await PriceOracleFactory.connect( address || - (await getDb().get(`${eContractid.PriceOracle}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.PriceOracle}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -78,36 +84,45 @@ export const getAToken = async (address?: tEthereumAddress) => export const getStableDebtToken = async (address?: tEthereumAddress) => await StableDebtTokenFactory.connect( address || - (await getDb().get(`${eContractid.StableDebtToken}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.StableDebtToken}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getVariableDebtToken = async (address?: tEthereumAddress) => await VariableDebtTokenFactory.connect( address || - (await getDb().get(`${eContractid.VariableDebtToken}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.VariableDebtToken}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getMintableERC20 = async (address: tEthereumAddress) => await MintableERC20Factory.connect( address || - (await getDb().get(`${eContractid.MintableERC20}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.MintableERC20}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getIErc20Detailed = async (address: tEthereumAddress) => await IERC20DetailedFactory.connect( address || - (await getDb().get(`${eContractid.IERC20Detailed}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.IERC20Detailed}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getAaveProtocolDataProvider = async (address?: tEthereumAddress) => await AaveProtocolDataProviderFactory.connect( address || - (await getDb().get(`${eContractid.AaveProtocolDataProvider}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.AaveProtocolDataProvider}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -125,15 +140,18 @@ export const getInterestRateStrategy = async (address?: tEthereumAddress) => export const getMockFlashLoanReceiver = async (address?: tEthereumAddress) => await MockFlashLoanReceiverFactory.connect( address || - (await getDb().get(`${eContractid.MockFlashLoanReceiver}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.MockFlashLoanReceiver}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getLendingRateOracle = async (address?: tEthereumAddress) => await LendingRateOracleFactory.connect( address || - (await getDb().get(`${eContractid.LendingRateOracle}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.LendingRateOracle}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -166,23 +184,37 @@ export const getAllMockedTokens = async () => { return tokens; }; +export const getQuoteCurrencies = (oracleQuoteCurrency: string): string[] => { + switch (oracleQuoteCurrency) { + case 'USD': + return ['USD']; + case 'ETH': + case 'WETH': + default: + return ['ETH', 'WETH']; + } +}; + export const getPairsTokenAggregator = ( allAssetsAddresses: { [tokenSymbol: string]: tEthereumAddress; }, - aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress } + aggregatorsAddresses: { [tokenSymbol: string]: tEthereumAddress }, + oracleQuoteCurrency: string ): [string[], string[]] => { - const { ETH, WETH, ...assetsAddressesWithoutEth } = allAssetsAddresses; + const assetsWithoutQuoteCurrency = omit( + allAssetsAddresses, + getQuoteCurrencies(oracleQuoteCurrency) + ); - const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => { + const pairs = Object.entries(assetsWithoutQuoteCurrency).map(([tokenSymbol, tokenAddress]) => { //if (true/*tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH' && tokenSymbol !== 'LpWETH'*/) { const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex( (value) => value === tokenSymbol ); - const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [ - string, - tEthereumAddress - ][])[aggregatorAddressIndex]; + const [, aggregatorAddress] = ( + Object.entries(aggregatorsAddresses) as [string, tEthereumAddress][] + )[aggregatorAddressIndex]; return [tokenAddress, aggregatorAddress]; //} }) as [string, string][]; @@ -208,14 +240,18 @@ export const getLendingPoolAddressesProviderRegistry = async (address?: tEthereu export const getReserveLogic = async (address?: tEthereumAddress) => await ReserveLogicFactory.connect( address || - (await getDb().get(`${eContractid.ReserveLogic}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.ReserveLogic}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getGenericLogic = async (address?: tEthereumAddress) => await GenericLogicFactory.connect( address || - (await getDb().get(`${eContractid.GenericLogic}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.GenericLogic}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -233,15 +269,18 @@ export const getStableAndVariableTokensHelper = async (address?: tEthereumAddres export const getATokensAndRatesHelper = async (address?: tEthereumAddress) => await ATokensAndRatesHelperFactory.connect( address || - (await getDb().get(`${eContractid.ATokensAndRatesHelper}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.ATokensAndRatesHelper}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getWETHGateway = async (address?: tEthereumAddress) => await WETHGatewayFactory.connect( address || - (await getDb().get(`${eContractid.WETHGateway}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.WETHGateway}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -260,23 +299,27 @@ export const getMockAToken = async (address?: tEthereumAddress) => export const getMockVariableDebtToken = async (address?: tEthereumAddress) => await MockVariableDebtTokenFactory.connect( address || - (await getDb().get(`${eContractid.MockVariableDebtToken}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.MockVariableDebtToken}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getMockStableDebtToken = async (address?: tEthereumAddress) => await MockStableDebtTokenFactory.connect( address || - (await getDb().get(`${eContractid.MockStableDebtToken}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.MockStableDebtToken}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getSelfdestructTransferMock = async (address?: tEthereumAddress) => await SelfdestructTransferFactory.connect( address || - (await getDb().get(`${eContractid.SelfdestructTransferMock}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.SelfdestructTransferMock}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -286,15 +329,18 @@ export const getProxy = async (address: tEthereumAddress) => export const getLendingPoolImpl = async (address?: tEthereumAddress) => await LendingPoolFactory.connect( address || - (await getDb().get(`${eContractid.LendingPoolImpl}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.LendingPoolImpl}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getLendingPoolConfiguratorImpl = async (address?: tEthereumAddress) => await LendingPoolConfiguratorFactory.connect( address || - (await getDb().get(`${eContractid.LendingPoolConfiguratorImpl}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.LendingPoolConfiguratorImpl}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -312,16 +358,18 @@ export const getLendingPoolCollateralManagerImpl = async (address?: tEthereumAdd export const getWalletProvider = async (address?: tEthereumAddress) => await WalletBalanceProviderFactory.connect( address || - (await getDb().get(`${eContractid.WalletBalanceProvider}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.WalletBalanceProvider}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getLendingPoolCollateralManager = async (address?: tEthereumAddress) => await LendingPoolCollateralManagerFactory.connect( address || - (await getDb().get(`${eContractid.LendingPoolCollateralManager}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.LendingPoolCollateralManager}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); @@ -337,30 +385,35 @@ export const getAaveOracle = async (address?: tEthereumAddress) => export const getMockUniswapRouter = async (address?: tEthereumAddress) => await MockUniswapV2Router02Factory.connect( address || - (await getDb().get(`${eContractid.MockUniswapV2Router02}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.MockUniswapV2Router02}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getUniswapLiquiditySwapAdapter = async (address?: tEthereumAddress) => await UniswapLiquiditySwapAdapterFactory.connect( address || - (await getDb().get(`${eContractid.UniswapLiquiditySwapAdapter}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.UniswapLiquiditySwapAdapter}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getUniswapRepayAdapter = async (address?: tEthereumAddress) => await UniswapRepayAdapterFactory.connect( address || - (await getDb().get(`${eContractid.UniswapRepayAdapter}.${DRE.network.name}`).value()).address, + ( + await getDb().get(`${eContractid.UniswapRepayAdapter}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); export const getFlashLiquidationAdapter = async (address?: tEthereumAddress) => await FlashLiquidationAdapterFactory.connect( address || - (await getDb().get(`${eContractid.FlashLiquidationAdapter}.${DRE.network.name}`).value()) - .address, + ( + await getDb().get(`${eContractid.FlashLiquidationAdapter}.${DRE.network.name}`).value() + ).address, await getFirstSigner() ); diff --git a/helpers/contracts-helpers.ts b/helpers/contracts-helpers.ts index 57becdad..fd310e90 100644 --- a/helpers/contracts-helpers.ts +++ b/helpers/contracts-helpers.ts @@ -2,7 +2,7 @@ import { Contract, Signer, utils, ethers, BigNumberish } from 'ethers'; import { signTypedData_v4 } from 'eth-sig-util'; import { fromRpcSig, ECDSASignature } from 'ethereumjs-util'; import BigNumber from 'bignumber.js'; -import { getDb, DRE, waitForTx } from './misc-utils'; +import { getDb, DRE, waitForTx, notFalsyOrZeroAddress } from './misc-utils'; import { tEthereumAddress, eContractid, @@ -14,7 +14,6 @@ import { ePolygonNetwork, eXDaiNetwork, eNetwork, - iParamsPerNetworkAll, iEthereumParamsPerNetwork, iPolygonParamsPerNetwork, iXDaiParamsPerNetwork, @@ -28,6 +27,8 @@ import { verifyEtherscanContract } from './etherscan-verification'; import { getFirstSigner, getIErc20Detailed } from './contracts-getters'; import { usingTenderly, verifyAtTenderly } from './tenderly-utils'; import { usingPolygon, verifyAtPolygon } from './polygon-utils'; +import { ConfigNames, loadPoolConfig } from './configuration'; +import { ZERO_ADDRESS } from './constants'; import { getDefenderRelaySigner, usingDefender } from './defender-utils'; export type MockTokenMap = { [symbol: string]: MintableERC20 }; @@ -144,7 +145,7 @@ export const linkBytecode = (artifact: BuidlerArtifact | Artifact, libraries: an }; export const getParamPerNetwork = (param: iParamsPerNetwork, network: eNetwork) => { - const { main, ropsten, kovan, coverage, buidlerevm, tenderlyMain } = + const { main, ropsten, kovan, coverage, buidlerevm, tenderly } = param as iEthereumParamsPerNetwork; const { matic, mumbai } = param as iPolygonParamsPerNetwork; const { xdai } = param as iXDaiParamsPerNetwork; @@ -166,8 +167,8 @@ export const getParamPerNetwork = (param: iParamsPerNetwork, network: eNet return ropsten; case eEthereumNetwork.main: return main; - case eEthereumNetwork.tenderlyMain: - return tenderlyMain; + case eEthereumNetwork.tenderly: + return tenderly; case ePolygonNetwork.matic: return matic; case ePolygonNetwork.mumbai: @@ -181,7 +182,17 @@ export const getParamPerNetwork = (param: iParamsPerNetwork, network: eNet } }; -export const getParamPerPool = ({ proto, amm, matic, avalanche }: iParamsPerPool, pool: AavePools) => { +export const getOptionalParamAddressPerNetwork = ( + param: iParamsPerNetwork | undefined | null, + network: eNetwork +) => { + if (!param) { + return ZERO_ADDRESS; + } + return getParamPerNetwork(param, network); +}; + +export const getParamPerPool = ({ proto, amm, matic }: iParamsPerPool, pool: AavePools) => { switch (pool) { case AavePools.proto: return proto; @@ -345,3 +356,23 @@ export const verifyContract = async ( } return instance; }; + +export const getContractAddressWithJsonFallback = async ( + id: string, + pool: ConfigNames +): Promise => { + const poolConfig = loadPoolConfig(pool); + const network = DRE.network.name; + const db = getDb(); + + const contractAtMarketConfig = getOptionalParamAddressPerNetwork(poolConfig[id], network); + if (notFalsyOrZeroAddress(contractAtMarketConfig)) { + return contractAtMarketConfig; + } + + const contractAtDb = await getDb().get(`${id}.${DRE.network.name}`).value(); + if (contractAtDb?.address) { + return contractAtDb.address as tEthereumAddress; + } + throw Error(`Missing contract address ${id} at Market config and JSON local db`); +}; diff --git a/helpers/init-helpers.ts b/helpers/init-helpers.ts index a3035692..6f1de0ab 100644 --- a/helpers/init-helpers.ts +++ b/helpers/init-helpers.ts @@ -1,48 +1,31 @@ import { eContractid, - eEthereumNetwork, eNetwork, iMultiPoolsAssets, IReserveParams, tEthereumAddress, } from './types'; import { AaveProtocolDataProvider } from '../types/AaveProtocolDataProvider'; -import { chunk, DRE, getDb, waitForTx } from './misc-utils'; +import { chunk, getDb, waitForTx } from './misc-utils'; import { - getAaveProtocolDataProvider, getAToken, getATokensAndRatesHelper, - getFirstSigner, getLendingPoolAddressesProvider, getLendingPoolConfiguratorProxy, - getStableAndVariableTokensHelper, } from './contracts-getters'; -import { rawInsertContractAddressInDb } from './contracts-helpers'; -import { BigNumber, BigNumberish, Signer } from 'ethers'; import { - deployDefaultReserveInterestRateStrategy, - deployDelegationAwareAToken, - deployDelegationAwareATokenImpl, - deployGenericAToken, - deployGenericATokenImpl, - deployGenericStableDebtToken, - deployGenericVariableDebtToken, - deployStableDebtToken, - deployVariableDebtToken, -} from './contracts-deployments'; -import { ZERO_ADDRESS } from './constants'; -import { isZeroAddress } from 'ethereumjs-util'; -import { DefaultReserveInterestRateStrategy, DelegationAwareAToken } from '../types'; -import { config } from 'process'; + getContractAddressWithJsonFallback, + rawInsertContractAddressInDb, +} from './contracts-helpers'; +import { BigNumberish } from 'ethers'; +import { ConfigNames } from './configuration'; +import { deployRateStrategy } from './contracts-deployments'; -export const chooseATokenDeployment = (id: eContractid) => { - switch (id) { - case eContractid.AToken: - return deployGenericAToken; - case eContractid.DelegationAwareAToken: - return deployDelegationAwareAToken; +export const getATokenExtraParams = async (aTokenName: string, tokenAddress: tEthereumAddress) => { + console.log(aTokenName); + switch (aTokenName) { default: - throw Error(`Missing aToken deployment script for: ${id}`); + return '0x10'; } }; @@ -56,19 +39,15 @@ export const initReservesByHelper = async ( admin: tEthereumAddress, treasuryAddress: tEthereumAddress, incentivesController: tEthereumAddress, + poolName: ConfigNames, verify: boolean -): Promise => { - let gasUsage = BigNumber.from('0'); - const stableAndVariableDeployer = await getStableAndVariableTokensHelper(); - +) => { const addressProvider = await getLendingPoolAddressesProvider(); // CHUNK CONFIGURATION - const initChunks = 4; + const initChunks = 1; // Initialize variables for future reserves initialization - let reserveTokens: string[] = []; - let reserveInitDecimals: string[] = []; let reserveSymbols: string[] = []; let initInputParams: { @@ -101,49 +80,8 @@ export const initReservesByHelper = async ( ]; let rateStrategies: Record = {}; let strategyAddresses: Record = {}; - let strategyAddressPerAsset: Record = {}; - let aTokenType: Record = {}; - let delegationAwareATokenImplementationAddress = ''; - let aTokenImplementationAddress = ''; - let stableDebtTokenImplementationAddress = ''; - let variableDebtTokenImplementationAddress = ''; - // NOT WORKING ON MATIC, DEPLOYING INDIVIDUAL IMPLs INSTEAD - // const tx1 = await waitForTx( - // await stableAndVariableDeployer.initDeployment([ZERO_ADDRESS], ["1"]) - // ); - // console.log(tx1.events); - // tx1.events?.forEach((event, index) => { - // stableDebtTokenImplementationAddress = event?.args?.stableToken; - // variableDebtTokenImplementationAddress = event?.args?.variableToken; - // rawInsertContractAddressInDb(`stableDebtTokenImpl`, stableDebtTokenImplementationAddress); - // rawInsertContractAddressInDb(`variableDebtTokenImpl`, variableDebtTokenImplementationAddress); - // }); - //gasUsage = gasUsage.add(tx1.gasUsed); - stableDebtTokenImplementationAddress = await (await deployGenericStableDebtToken()).address; - variableDebtTokenImplementationAddress = await (await deployGenericVariableDebtToken()).address; - - const aTokenImplementation = await deployGenericATokenImpl(verify); - aTokenImplementationAddress = aTokenImplementation.address; - rawInsertContractAddressInDb(`aTokenImpl`, aTokenImplementationAddress); - - const delegatedAwareReserves = Object.entries(reservesParams).filter( - ([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken - ) as [string, IReserveParams][]; - - if (delegatedAwareReserves.length > 0) { - const delegationAwareATokenImplementation = await deployDelegationAwareATokenImpl(verify); - delegationAwareATokenImplementationAddress = delegationAwareATokenImplementation.address; - rawInsertContractAddressInDb( - `delegationAwareATokenImpl`, - delegationAwareATokenImplementationAddress - ); - } - - const reserves = Object.entries(reservesParams).filter( - ([_, { aTokenImpl }]) => - aTokenImpl === eContractid.DelegationAwareAToken || aTokenImpl === eContractid.AToken - ) as [string, IReserveParams][]; + const reserves = Object.entries(reservesParams); for (let [symbol, params] of reserves) { if (!tokenAddresses[symbol]) { @@ -170,52 +108,41 @@ export const initReservesByHelper = async ( stableRateSlope1, stableRateSlope2, ]; - strategyAddresses[strategy.name] = ( - await deployDefaultReserveInterestRateStrategy(rateStrategies[strategy.name], verify) - ).address; + 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]); } - strategyAddressPerAsset[symbol] = strategyAddresses[strategy.name]; - console.log('Strategy address for asset %s: %s', symbol, strategyAddressPerAsset[symbol]); - - if (aTokenImpl === eContractid.AToken) { - aTokenType[symbol] = 'generic'; - } else if (aTokenImpl === eContractid.DelegationAwareAToken) { - aTokenType[symbol] = 'delegation aware'; - } - - reserveInitDecimals.push(reserveDecimals); - reserveTokens.push(tokenAddresses[symbol]); + // Prepare input parameters reserveSymbols.push(symbol); - } - - for (let i = 0; i < reserveSymbols.length; i++) { - let aTokenToUse: string; - if (aTokenType[reserveSymbols[i]] === 'generic') { - aTokenToUse = aTokenImplementationAddress; - } else { - aTokenToUse = delegationAwareATokenImplementationAddress; - } - initInputParams.push({ - aTokenImpl: aTokenToUse, - stableDebtTokenImpl: stableDebtTokenImplementationAddress, - variableDebtTokenImpl: variableDebtTokenImplementationAddress, - underlyingAssetDecimals: reserveInitDecimals[i], - interestRateStrategyAddress: strategyAddressPerAsset[reserveSymbols[i]], - underlyingAsset: reserveTokens[i], + 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], treasury: treasuryAddress, - incentivesController, - underlyingAssetName: reserveSymbols[i], - aTokenName: `${aTokenNamePrefix} ${reserveSymbols[i]}`, - aTokenSymbol: `a${symbolPrefix}${reserveSymbols[i]}`, - variableDebtTokenName: `${variableDebtTokenNamePrefix} ${symbolPrefix}${reserveSymbols[i]}`, - variableDebtTokenSymbol: `variableDebt${symbolPrefix}${reserveSymbols[i]}`, - stableDebtTokenName: `${stableDebtTokenNamePrefix} ${reserveSymbols[i]}`, - stableDebtTokenSymbol: `stableDebt${symbolPrefix}${reserveSymbols[i]}`, - params: '0x10', + 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]), }); } @@ -224,7 +151,6 @@ export const initReservesByHelper = async ( const chunkedInitInputParams = chunk(initInputParams, initChunks); const configurator = await getLendingPoolConfiguratorProxy(); - //await waitForTx(await addressProvider.setPoolAdmin(admin)); console.log(`- Reserves initialization in ${chunkedInitInputParams.length} txs`); for (let chunkIndex = 0; chunkIndex < chunkedInitInputParams.length; chunkIndex++) { @@ -234,10 +160,7 @@ export const initReservesByHelper = async ( console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`); console.log(' * gasUsed', tx3.gasUsed.toString()); - //gasUsage = gasUsage.add(tx3.gasUsed); } - - return gasUsage; // Deprecated }; export const getPairsTokenAggregator = ( @@ -253,10 +176,9 @@ export const getPairsTokenAggregator = ( const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex( (value) => value === tokenSymbol ); - const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [ - string, - tEthereumAddress - ][])[aggregatorAddressIndex]; + const [, aggregatorAddress] = ( + Object.entries(aggregatorsAddresses) as [string, tEthereumAddress][] + )[aggregatorAddressIndex]; return [tokenAddress, aggregatorAddress]; } }) as [string, string][]; diff --git a/helpers/misc-utils.ts b/helpers/misc-utils.ts index 0315dfe0..c0456a0c 100644 --- a/helpers/misc-utils.ts +++ b/helpers/misc-utils.ts @@ -9,6 +9,8 @@ import { BuidlerRuntimeEnvironment } from '@nomiclabs/buidler/types'; import { tEthereumAddress } from './types'; import { isAddress } from 'ethers/lib/utils'; import { isZeroAddress } from 'ethereumjs-util'; +import { SignerWithAddress } from '../test-suites/test-aave/helpers/make-suite'; +import { usingTenderly } from './tenderly-utils'; export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed(); @@ -116,6 +118,27 @@ export const notFalsyOrZeroAddress = (address: tEthereumAddress | null | undefin return isAddress(address) && !isZeroAddress(address); }; +export const impersonateAddress = async (address: tEthereumAddress): Promise => { + if (!usingTenderly()) { + await (DRE as HardhatRuntimeEnvironment).network.provider.request({ + method: 'hardhat_impersonateAccount', + params: [address], + }); + } + const signer = await DRE.ethers.provider.getSigner(address); + + return { + signer, + address, + }; +}; + +export const omit = (obj: T, keys: U[]): Omit => + (Object.keys(obj) as U[]).reduce( + (acc, curr) => (keys.includes(curr) ? acc : { ...acc, [curr]: obj[curr] }), + {} as Omit + ); + export const impersonateAccountsHardhat = async (accounts: string[]) => { if (process.env.TENDERLY === 'true') { return; diff --git a/helpers/types.ts b/helpers/types.ts index e2052c7f..53338c21 100644 --- a/helpers/types.ts +++ b/helpers/types.ts @@ -13,7 +13,7 @@ export enum eEthereumNetwork { main = 'main', coverage = 'coverage', hardhat = 'hardhat', - tenderlyMain = 'tenderlyMain', + tenderly = 'tenderly', } export enum ePolygonNetwork { @@ -96,6 +96,7 @@ export enum eContractid { UniswapLiquiditySwapAdapter = 'UniswapLiquiditySwapAdapter', UniswapRepayAdapter = 'UniswapRepayAdapter', FlashLiquidationAdapter = 'FlashLiquidationAdapter', + AaveOracleV2 = 'AaveOracleV2', } /* @@ -425,7 +426,7 @@ export interface iEthereumParamsPerNetwork { [eEthereumNetwork.ropsten]: T; [eEthereumNetwork.main]: T; [eEthereumNetwork.hardhat]: T; - [eEthereumNetwork.tenderlyMain]: T; + [eEthereumNetwork.tenderly]: T; } export interface iPolygonParamsPerNetwork { @@ -485,7 +486,7 @@ export interface ILendingRate { borrowRate: string; } -export interface ICommonConfiguration { +export interface IBaseConfiguration { MarketId: string; ATokenNamePrefix: string; StableDebtTokenNamePrefix: string; @@ -493,7 +494,6 @@ export interface ICommonConfiguration { SymbolPrefix: string; ProviderId: number; ProtocolGlobalParams: IProtocolGlobalConfig; - Mocks: IMocksConfig; ProviderRegistry: iParamsPerNetwork; ProviderRegistryOwner: iParamsPerNetwork; LendingPoolCollateralManager: iParamsPerNetwork; @@ -509,14 +509,22 @@ export interface ICommonConfiguration { PoolAdminIndex: number; EmergencyAdmin: iParamsPerNetwork; EmergencyAdminIndex: number; - ReserveAssets: iParamsPerNetwork>; - ReservesConfig: iMultiPoolsAssets; ATokenDomainSeparator: iParamsPerNetwork; WETH: iParamsPerNetwork; WrappedNativeToken: iParamsPerNetwork; WethGateway: iParamsPerNetwork; ReserveFactorTreasuryAddress: iParamsPerNetwork; IncentivesController: iParamsPerNetwork; + StableDebtTokenImplementation?: iParamsPerNetwork; + VariableDebtTokenImplementation?: iParamsPerNetwork; + ReserveAssets: iParamsPerNetwork>; + OracleQuoteCurrency: string; + OracleQuoteUnit: string; +} + +export interface ICommonConfiguration extends IBaseConfiguration { + ReservesConfig: iMultiPoolsAssets; + Mocks: IMocksConfig; } export interface IAaveConfiguration extends ICommonConfiguration { diff --git a/markets/aave/commons.ts b/markets/aave/commons.ts index 134e37eb..d0a34bcd 100644 --- a/markets/aave/commons.ts +++ b/markets/aave/commons.ts @@ -1,10 +1,8 @@ -import BigNumber from 'bignumber.js'; import { - oneEther, oneRay, - RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES, + oneEther, } from '../../helpers/constants'; import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types'; @@ -19,6 +17,8 @@ export const CommonsConfig: ICommonConfiguration = { VariableDebtTokenNamePrefix: 'Aave variable debt bearing', SymbolPrefix: '', ProviderId: 0, // Overriden in index.ts + OracleQuoteCurrency: 'ETH', + OracleQuoteUnit: oneEther.toString(), ProtocolGlobalParams: { TokenDistributorPercentageBase: '10000', MockUsdPriceInWei: '5848466240000000', @@ -113,7 +113,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: undefined, [eEthereumNetwork.ropsten]: undefined, [eEthereumNetwork.main]: undefined, - [eEthereumNetwork.tenderlyMain]: undefined, + [eEthereumNetwork.tenderly]: undefined, }, PoolAdminIndex: 0, EmergencyAdmin: { @@ -123,7 +123,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: undefined, [eEthereumNetwork.ropsten]: undefined, [eEthereumNetwork.main]: undefined, - [eEthereumNetwork.tenderlyMain]: undefined, + [eEthereumNetwork.tenderly]: undefined, }, EmergencyAdminIndex: 1, ProviderRegistry: { @@ -133,7 +133,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.coverage]: '', [eEthereumNetwork.hardhat]: '', [eEthereumNetwork.buidlerevm]: '', - [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413', + [eEthereumNetwork.tenderly]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413', }, ProviderRegistryOwner: { [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F', @@ -142,7 +142,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.coverage]: '', [eEthereumNetwork.hardhat]: '', [eEthereumNetwork.buidlerevm]: '', - [eEthereumNetwork.tenderlyMain]: '0xB9062896ec3A615a4e4444DF183F0531a77218AE', + [eEthereumNetwork.tenderly]: '0xB9062896ec3A615a4e4444DF183F0531a77218AE', }, LendingRateOracle: { [eEthereumNetwork.coverage]: '', @@ -151,7 +151,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', //'0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b', [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', - [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', + [eEthereumNetwork.tenderly]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', }, LendingPoolCollateralManager: { [eEthereumNetwork.coverage]: '', @@ -160,7 +160,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', - [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', + [eEthereumNetwork.tenderly]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', }, LendingPoolConfigurator: { [eEthereumNetwork.coverage]: '', @@ -169,7 +169,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, LendingPool: { [eEthereumNetwork.coverage]: '', @@ -178,7 +178,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, WethGateway: { [eEthereumNetwork.coverage]: '', @@ -187,7 +187,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, TokenDistributor: { [eEthereumNetwork.coverage]: '', @@ -196,7 +196,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708', [eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c', [eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', - [eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', + [eEthereumNetwork.tenderly]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', }, AaveOracle: { [eEthereumNetwork.coverage]: '', @@ -205,7 +205,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', //'0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1', [eEthereumNetwork.ropsten]: ZERO_ADDRESS, [eEthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', - [eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', + [eEthereumNetwork.tenderly]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', }, FallbackOracle: { [eEthereumNetwork.coverage]: '', @@ -214,7 +214,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe', [eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d', [eEthereumNetwork.main]: ZERO_ADDRESS, - [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS, + [eEthereumNetwork.tenderly]: ZERO_ADDRESS, }, ChainlinkAggregator: { [eEthereumNetwork.coverage]: {}, @@ -287,7 +287,7 @@ export const CommonsConfig: ICommonConfiguration = { USD: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419', xSUSHI: '0x9b26214bEC078E68a394AaEbfbffF406Ce14893F', }, - [eEthereumNetwork.tenderlyMain]: { + [eEthereumNetwork.tenderly]: { AAVE: '0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012', BAT: '0x0d16d4528239e9ee52fa531af613AcdB23D88c94', BUSD: '0x614715d2Af89E6EC99A233818275142cE88d1Cfd', @@ -318,7 +318,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.main]: {}, [eEthereumNetwork.kovan]: {}, [eEthereumNetwork.ropsten]: {}, - [eEthereumNetwork.tenderlyMain]: {}, + [eEthereumNetwork.tenderly]: {}, }, ReservesConfig: {}, ATokenDomainSeparator: { @@ -331,7 +331,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, WETH: { [eEthereumNetwork.coverage]: '', // deployed in local evm @@ -340,7 +340,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab', [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + [eEthereumNetwork.tenderly]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, WrappedNativeToken: { [eEthereumNetwork.coverage]: '', // deployed in local evm @@ -349,7 +349,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab', [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + [eEthereumNetwork.tenderly]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, ReserveFactorTreasuryAddress: { [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', @@ -358,7 +358,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', - [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', + [eEthereumNetwork.tenderly]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', }, IncentivesController: { [eEthereumNetwork.coverage]: ZERO_ADDRESS, @@ -367,6 +367,6 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: ZERO_ADDRESS, [eEthereumNetwork.ropsten]: ZERO_ADDRESS, [eEthereumNetwork.main]: ZERO_ADDRESS, - [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS, + [eEthereumNetwork.tenderly]: ZERO_ADDRESS, }, }; diff --git a/markets/aave/index.ts b/markets/aave/index.ts index 2ff2be79..72f25152 100644 --- a/markets/aave/index.ts +++ b/markets/aave/index.ts @@ -128,7 +128,7 @@ export const AaveConfig: IAaveConfiguration = { ZRX: '0xE41d2489571d322189246DaFA5ebDe1F4699F498', xSUSHI: '0x8798249c2E607446EfB7Ad49eC89dD1865Ff4272', }, - [eEthereumNetwork.tenderlyMain]: { + [eEthereumNetwork.tenderly]: { AAVE: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53', diff --git a/markets/aave/reservesConfigs.ts b/markets/aave/reservesConfigs.ts index a29e16d7..b41ae417 100644 --- a/markets/aave/reservesConfigs.ts +++ b/markets/aave/reservesConfigs.ts @@ -1,6 +1,6 @@ import { eContractid, IReserveParams } from '../../helpers/types'; -import { +import { rateStrategyStableOne, rateStrategyStableTwo, rateStrategyStableThree, @@ -21,7 +21,7 @@ export const strategyBUSD: IReserveParams = { stableBorrowRateEnabled: false, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategyDAI: IReserveParams = { @@ -33,7 +33,7 @@ export const strategyDAI: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategySUSD: IReserveParams = { @@ -45,7 +45,7 @@ export const strategySUSD: IReserveParams = { stableBorrowRateEnabled: false, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyTUSD: IReserveParams = { @@ -57,7 +57,7 @@ export const strategyTUSD: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategyUSDC: IReserveParams = { @@ -69,7 +69,7 @@ export const strategyUSDC: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '6', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategyUSDT: IReserveParams = { @@ -81,7 +81,7 @@ export const strategyUSDT: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '6', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategyAAVE: IReserveParams = { @@ -93,7 +93,7 @@ export const strategyAAVE: IReserveParams = { stableBorrowRateEnabled: false, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '0' + reserveFactor: '0', }; export const strategyBAT: IReserveParams = { @@ -105,7 +105,7 @@ export const strategyBAT: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyENJ: IReserveParams = { @@ -117,7 +117,7 @@ export const strategyENJ: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyWETH: IReserveParams = { @@ -129,7 +129,7 @@ export const strategyWETH: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '1000' + reserveFactor: '1000', }; export const strategyKNC: IReserveParams = { @@ -141,7 +141,7 @@ export const strategyKNC: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyLINK: IReserveParams = { @@ -153,7 +153,7 @@ export const strategyLINK: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyMANA: IReserveParams = { @@ -165,7 +165,7 @@ export const strategyMANA: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '3500' + reserveFactor: '3500', }; export const strategyMKR: IReserveParams = { @@ -177,7 +177,7 @@ export const strategyMKR: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyREN: IReserveParams = { @@ -189,7 +189,7 @@ export const strategyREN: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategySNX: IReserveParams = { @@ -201,7 +201,7 @@ export const strategySNX: IReserveParams = { stableBorrowRateEnabled: false, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '3500' + reserveFactor: '3500', }; // Invalid borrow rates in params currently, replaced with snx params @@ -214,7 +214,7 @@ export const strategyUNI: IReserveParams = { stableBorrowRateEnabled: false, reserveDecimals: '18', aTokenImpl: eContractid.DelegationAwareAToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyWBTC: IReserveParams = { @@ -226,7 +226,7 @@ export const strategyWBTC: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '8', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyYFI: IReserveParams = { @@ -238,7 +238,7 @@ export const strategyYFI: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyZRX: IReserveParams = { @@ -250,7 +250,7 @@ export const strategyZRX: IReserveParams = { stableBorrowRateEnabled: true, reserveDecimals: '18', aTokenImpl: eContractid.AToken, - reserveFactor: '2000' + reserveFactor: '2000', }; export const strategyXSUSHI: IReserveParams = { @@ -263,4 +263,4 @@ export const strategyXSUSHI: IReserveParams = { reserveDecimals: '18', aTokenImpl: eContractid.AToken, reserveFactor: '3500', -}; \ No newline at end of file +}; diff --git a/markets/amm/commons.ts b/markets/amm/commons.ts index 8be1f2c0..39fca1d0 100644 --- a/markets/amm/commons.ts +++ b/markets/amm/commons.ts @@ -5,6 +5,7 @@ import { RAY, ZERO_ADDRESS, MOCK_CHAINLINK_AGGREGATORS_PRICES, + oneUsd, } from '../../helpers/constants'; import { ICommonConfiguration, eEthereumNetwork } from '../../helpers/types'; @@ -19,6 +20,8 @@ export const CommonsConfig: ICommonConfiguration = { VariableDebtTokenNamePrefix: 'Aave AMM Market variable debt', SymbolPrefix: 'Amm', ProviderId: 0, // Overriden in index.ts + OracleQuoteCurrency: 'ETH', + OracleQuoteUnit: oneEther.toString(), ProtocolGlobalParams: { TokenDistributorPercentageBase: '10000', MockUsdPriceInWei: '5848466240000000', @@ -116,7 +119,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: undefined, [eEthereumNetwork.ropsten]: undefined, [eEthereumNetwork.main]: undefined, - [eEthereumNetwork.tenderlyMain]: undefined, + [eEthereumNetwork.tenderly]: undefined, }, PoolAdminIndex: 0, EmergencyAdmin: { @@ -126,7 +129,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: undefined, [eEthereumNetwork.ropsten]: undefined, [eEthereumNetwork.main]: undefined, - [eEthereumNetwork.tenderlyMain]: undefined, + [eEthereumNetwork.tenderly]: undefined, }, EmergencyAdminIndex: 1, ProviderRegistry: { @@ -136,7 +139,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.coverage]: '', [eEthereumNetwork.hardhat]: '', [eEthereumNetwork.buidlerevm]: '', - [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413', + [eEthereumNetwork.tenderly]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413', }, ProviderRegistryOwner: { [eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F', @@ -145,7 +148,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.coverage]: '', [eEthereumNetwork.hardhat]: '', [eEthereumNetwork.buidlerevm]: '', - [eEthereumNetwork.tenderlyMain]: '0xB9062896ec3A615a4e4444DF183F0531a77218AE', + [eEthereumNetwork.tenderly]: '0xB9062896ec3A615a4e4444DF183F0531a77218AE', }, LendingRateOracle: { [eEthereumNetwork.coverage]: '', @@ -154,7 +157,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0xd00Bd28FAdDa9d5658D1D4e0c151973146C7A533', //'0xE48F95873855bfd97BF89572DDf5cBC44D9c545b' [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b', [eEthereumNetwork.main]: '', //'0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', // Need to re-deploy because of onlyOwner - [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', + [eEthereumNetwork.tenderly]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D', }, LendingPoolCollateralManager: { [eEthereumNetwork.coverage]: '', @@ -163,7 +166,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x9269b6453d0d75370c4c85e5a42977a53efdb72a', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', - [eEthereumNetwork.tenderlyMain]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', + [eEthereumNetwork.tenderly]: '0xbd4765210d4167CE2A5b87280D9E8Ee316D5EC7C', }, LendingPoolConfigurator: { [eEthereumNetwork.coverage]: '', @@ -172,7 +175,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x36eB31800aa67a9c50df1d56EE01981A6E14Cce5', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, LendingPool: { [eEthereumNetwork.coverage]: '', @@ -181,7 +184,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x78142De7a1930412E9e50dEB3b80dB284c2dFa3A', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, WethGateway: { [eEthereumNetwork.coverage]: '', @@ -190,7 +193,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x1c4A1cC35A477aa1cF35DF671d93ACc04d8131E0', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, TokenDistributor: { [eEthereumNetwork.coverage]: '', @@ -199,7 +202,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708', [eEthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c', [eEthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', - [eEthereumNetwork.tenderlyMain]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', + [eEthereumNetwork.tenderly]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae', }, AaveOracle: { [eEthereumNetwork.coverage]: '', @@ -208,7 +211,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', // Need to re-deploy because of onlyOwner [eEthereumNetwork.ropsten]: ZERO_ADDRESS, [eEthereumNetwork.main]: '', //'0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', // Need to re-deploy because of onlyOwner - [eEthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', + [eEthereumNetwork.tenderly]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9', }, FallbackOracle: { [eEthereumNetwork.coverage]: '', @@ -217,7 +220,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe', [eEthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d', [eEthereumNetwork.main]: ZERO_ADDRESS, - [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS, + [eEthereumNetwork.tenderly]: ZERO_ADDRESS, }, ChainlinkAggregator: { [eEthereumNetwork.coverage]: {}, @@ -270,7 +273,7 @@ export const CommonsConfig: ICommonConfiguration = { BptBALWETH: '0x2e4e78936b100be6Ef85BCEf7FB25bC770B02B85', USD: '0x9326BFA02ADD2366b30bacB125260Af641031331', }, - [eEthereumNetwork.tenderlyMain]: { + [eEthereumNetwork.tenderly]: { USDT: '0xEe9F2375b4bdF6387aa8265dD4FB8F16512A1d46', WBTC: '0xdeb288F737066589598e9214E782fa5A8eD689e8', USDC: '0x986b5E1e1755e3C2440e960477f25201B0a8bbD4', @@ -301,7 +304,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.main]: {}, [eEthereumNetwork.kovan]: {}, [eEthereumNetwork.ropsten]: {}, - [eEthereumNetwork.tenderlyMain]: {}, + [eEthereumNetwork.tenderly]: {}, }, ReservesConfig: {}, ATokenDomainSeparator: { @@ -314,7 +317,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '', [eEthereumNetwork.ropsten]: '', [eEthereumNetwork.main]: '', - [eEthereumNetwork.tenderlyMain]: '', + [eEthereumNetwork.tenderly]: '', }, WETH: { [eEthereumNetwork.coverage]: '', // deployed in local evm @@ -323,7 +326,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab', [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + [eEthereumNetwork.tenderly]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, WrappedNativeToken: { [eEthereumNetwork.coverage]: '', // deployed in local evm @@ -332,7 +335,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0xd0a1e359811322d97991e03f863a0c30c2cf029c', [eEthereumNetwork.ropsten]: '0xc778417e063141139fce010982780140aa0cd5ab', [eEthereumNetwork.main]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - [eEthereumNetwork.tenderlyMain]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + [eEthereumNetwork.tenderly]: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', }, ReserveFactorTreasuryAddress: { [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', @@ -341,7 +344,7 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.main]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', - [eEthereumNetwork.tenderlyMain]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', + [eEthereumNetwork.tenderly]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', }, IncentivesController: { [eEthereumNetwork.coverage]: ZERO_ADDRESS, @@ -350,6 +353,6 @@ export const CommonsConfig: ICommonConfiguration = { [eEthereumNetwork.kovan]: ZERO_ADDRESS, [eEthereumNetwork.ropsten]: ZERO_ADDRESS, [eEthereumNetwork.main]: ZERO_ADDRESS, - [eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS, + [eEthereumNetwork.tenderly]: ZERO_ADDRESS, }, }; diff --git a/markets/amm/index.ts b/markets/amm/index.ts index e42dbdec..37bc46b6 100644 --- a/markets/amm/index.ts +++ b/markets/amm/index.ts @@ -83,8 +83,7 @@ export const AmmConfig: IAmmConfiguration = { BptWBTCWETH: '0x110569E3261bC0934dA637b019f6f1b6F50ec574', BptBALWETH: '0xad01D8e0Fa9EAA8Fe76dA30CFb1BCe12707aE6c5', }, - [eEthereumNetwork.ropsten]: { - }, + [eEthereumNetwork.ropsten]: {}, [eEthereumNetwork.main]: { DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F', USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', @@ -108,7 +107,7 @@ export const AmmConfig: IAmmConfiguration = { BptWBTCWETH: '0x1efF8aF5D577060BA4ac8A29A13525bb0Ee2A3D5', BptBALWETH: '0x59A19D8c652FA0284f44113D0ff9aBa70bd46fB4', }, - [eEthereumNetwork.tenderlyMain]: { + [eEthereumNetwork.tenderly]: { DAI: '0x6B175474E89094C44Da98b954EedeAC495271d0F', USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', USDT: '0xdAC17F958D2ee523a2206206994597C13D831ec7', diff --git a/markets/matic/commons.ts b/markets/matic/commons.ts index 8a0274a0..dc6fb173 100644 --- a/markets/matic/commons.ts +++ b/markets/matic/commons.ts @@ -19,6 +19,8 @@ export const CommonsConfig: ICommonConfiguration = { VariableDebtTokenNamePrefix: 'Aave Matic Market variable debt', SymbolPrefix: 'm', ProviderId: 0, // Overriden in index.ts + OracleQuoteCurrency: 'ETH', + OracleQuoteUnit: oneEther.toString(), ProtocolGlobalParams: { TokenDistributorPercentageBase: '10000', MockUsdPriceInWei: '5848466240000000', diff --git a/markets/xdai/commons.ts b/markets/xdai/commons.ts index ee9f1f9f..856dd50a 100644 --- a/markets/xdai/commons.ts +++ b/markets/xdai/commons.ts @@ -19,6 +19,7 @@ export const CommonsConfig: ICommonConfiguration = { VariableDebtTokenNamePrefix: 'Aave XDAI Market variable debt', SymbolPrefix: 'm', ProviderId: 0, // Overriden in index.ts + OracleQuoteCurrency: 'ETH', ProtocolGlobalParams: { TokenDistributorPercentageBase: '10000', MockUsdPriceInWei: '5848466240000000', diff --git a/tasks/dev/3_lending_pool.ts b/tasks/dev/3_lending_pool.ts index 9936abfa..5f4336c6 100644 --- a/tasks/dev/3_lending_pool.ts +++ b/tasks/dev/3_lending_pool.ts @@ -1,5 +1,6 @@ import { task } from 'hardhat/config'; import { + deployATokenImplementations, deployATokensAndRatesHelper, deployLendingPool, deployLendingPoolConfigurator, @@ -13,13 +14,15 @@ import { getLendingPoolConfiguratorProxy, } from '../../helpers/contracts-getters'; import { insertContractAddressInDb } from '../../helpers/contracts-helpers'; +import { ConfigNames, loadPoolConfig } from '../../helpers/configuration'; task('dev:deploy-lending-pool', 'Deploy lending pool for dev enviroment') .addFlag('verify', 'Verify contracts at Etherscan') - .setAction(async ({ verify }, localBRE) => { + .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`) + .setAction(async ({ verify, pool }, localBRE) => { await localBRE.run('set-DRE'); - const addressesProvider = await getLendingPoolAddressesProvider(); + const poolConfig = loadPoolConfig(pool); const lendingPoolImpl = await deployLendingPool(verify); @@ -55,4 +58,5 @@ task('dev:deploy-lending-pool', 'Deploy lending pool for dev enviroment') [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address], verify ); + await deployATokenImplementations(pool, poolConfig.ReservesConfig, verify); }); diff --git a/tasks/dev/4_oracles.ts b/tasks/dev/4_oracles.ts index 23c24133..44a657af 100644 --- a/tasks/dev/4_oracles.ts +++ b/tasks/dev/4_oracles.ts @@ -1,7 +1,7 @@ import { task } from 'hardhat/config'; import { deployPriceOracle, - deployAaveOracle, + deployAaveOracleV2, deployLendingRateOracle, } from '../../helpers/contracts-deployments'; import { @@ -12,14 +12,19 @@ import { import { ICommonConfiguration, iAssetBase, TokenContractId } from '../../helpers/types'; import { waitForTx } from '../../helpers/misc-utils'; import { getAllAggregatorsAddresses, getAllTokenAddresses } from '../../helpers/mock-helpers'; -import { ConfigNames, loadPoolConfig, getWethAddress } from '../../helpers/configuration'; +import { + ConfigNames, + loadPoolConfig, + getWethAddress, + getQuoteCurrency, +} from '../../helpers/configuration'; import { getAllMockedTokens, getLendingPoolAddressesProvider, getPairsTokenAggregator, } from '../../helpers/contracts-getters'; -task('dev:deploy-oracles', 'Deploy oracles for dev enviroment') +task('dev:deploy-oracles', 'Deploy oracles for dev environment') .addFlag('verify', 'Verify contracts at Etherscan') .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`) .setAction(async ({ verify, pool }, localBRE) => { @@ -29,6 +34,7 @@ task('dev:deploy-oracles', 'Deploy oracles for dev enviroment') Mocks: { AllAssetsInitialPrices }, ProtocolGlobalParams: { UsdAddress, MockUsdPriceInWei }, LendingRateOracleRatesCommon, + OracleQuoteCurrency, } = poolConfig as ICommonConfiguration; const defaultTokenList = { @@ -54,11 +60,18 @@ task('dev:deploy-oracles', 'Deploy oracles for dev enviroment') const [tokens, aggregators] = getPairsTokenAggregator( allTokenAddresses, - allAggregatorsAddresses + allAggregatorsAddresses, + OracleQuoteCurrency ); - await deployAaveOracle( - [tokens, aggregators, fallbackOracle.address, await getWethAddress(poolConfig)], + await deployAaveOracleV2( + [ + tokens, + aggregators, + fallbackOracle.address, + await getQuoteCurrency(poolConfig), + pool.OracleQuoteUnit, + ], verify ); await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address)); diff --git a/tasks/dev/5_initialize.ts b/tasks/dev/5_initialize.ts index f36a4e09..c791656f 100644 --- a/tasks/dev/5_initialize.ts +++ b/tasks/dev/5_initialize.ts @@ -40,6 +40,7 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.') VariableDebtTokenNamePrefix, SymbolPrefix, WethGateway, + ReservesConfig, } = poolConfig; const mockTokens = await getAllMockedTokens(); const allTokenAddresses = getAllTokenAddresses(mockTokens); @@ -52,14 +53,12 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.') const testHelpers = await deployAaveProtocolDataProvider(addressesProvider.address, verify); - const reservesParams = getReservesConfigByPool(AavePools.proto); - const admin = await addressesProvider.getPoolAdmin(); const treasuryAddress = await getTreasuryAddress(poolConfig); await initReservesByHelper( - reservesParams, + ReservesConfig, protoPoolReservesAddresses, ATokenNamePrefix, StableDebtTokenNamePrefix, @@ -68,9 +67,10 @@ task('dev:initialize-lending-pool', 'Initialize lending pool configuration.') admin, treasuryAddress, ZERO_ADDRESS, + pool, verify ); - await configureReservesByHelper(reservesParams, protoPoolReservesAddresses, testHelpers, admin); + await configureReservesByHelper(ReservesConfig, protoPoolReservesAddresses, testHelpers, admin); const collateralManager = await deployLendingPoolCollateralManager(verify); await waitForTx( diff --git a/tasks/full/2_lending_pool.ts b/tasks/full/2_lending_pool.ts index e318846e..ac930251 100644 --- a/tasks/full/2_lending_pool.ts +++ b/tasks/full/2_lending_pool.ts @@ -1,6 +1,7 @@ import { task } from 'hardhat/config'; import { getParamPerNetwork, insertContractAddressInDb } from '../../helpers/contracts-helpers'; import { + deployATokenImplementations, deployATokensAndRatesHelper, deployLendingPool, deployLendingPoolConfigurator, @@ -78,11 +79,12 @@ task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment') [lendingPoolProxy.address, addressesProvider.address, lendingPoolConfiguratorProxy.address], verify ); + await deployATokenImplementations(pool, poolConfig.ReservesConfig, verify); } catch (error) { if (DRE.network.name.includes('tenderly')) { const transactionLink = `https://dashboard.tenderly.co/${DRE.config.tenderly.username}/${ DRE.config.tenderly.project - }/fork/${DRE.tenderlyNetwork.getFork()}/simulation/${DRE.tenderlyNetwork.getHead()}`; + }/fork/${DRE.tenderly.network().getFork()}/simulation/${DRE.tenderly.network().getHead()}`; console.error('Check tx error:', transactionLink); } throw error; diff --git a/tasks/full/3_oracles.ts b/tasks/full/3_oracles.ts index df06f34c..740cf1df 100644 --- a/tasks/full/3_oracles.ts +++ b/tasks/full/3_oracles.ts @@ -1,6 +1,6 @@ import { task } from 'hardhat/config'; import { getParamPerNetwork } from '../../helpers/contracts-helpers'; -import { deployAaveOracle, deployLendingRateOracle } from '../../helpers/contracts-deployments'; +import { deployAaveOracleV2, deployLendingRateOracle } from '../../helpers/contracts-deployments'; import { setInitialMarketRatesInRatesOracleByHelper } from '../../helpers/oracles-helpers'; import { ICommonConfiguration, eNetwork, SymbolMap } from '../../helpers/types'; import { waitForTx, notFalsyOrZeroAddress } from '../../helpers/misc-utils'; @@ -10,6 +10,7 @@ import { getWethAddress, getGenesisPoolAdmin, getLendingRateOracles, + getQuoteCurrency, } from '../../helpers/configuration'; import { getAaveOracle, @@ -17,7 +18,8 @@ import { getLendingRateOracle, getPairsTokenAggregator, } from '../../helpers/contracts-getters'; -import { AaveOracle, LendingRateOracle } from '../../types'; +import { AaveOracle, AaveOracleV2, LendingRateOracle } from '../../types'; +import { isAddress } from 'ethers/lib/utils'; task('full:deploy-oracles', 'Deploy oracles for dev enviroment') .addFlag('verify', 'Verify contracts at Etherscan') @@ -46,16 +48,27 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment') ...reserveAssets, USD: UsdAddress, }; - const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators); + const [tokens, aggregators] = getPairsTokenAggregator( + tokensToWatch, + chainlinkAggregators, + poolConfig.OracleQuoteCurrency + ); - let aaveOracle: AaveOracle; + let aaveOracle: AaveOracle | AaveOracleV2; let lendingRateOracle: LendingRateOracle; if (notFalsyOrZeroAddress(aaveOracleAddress)) { aaveOracle = await await getAaveOracle(aaveOracleAddress); + await waitForTx(await aaveOracle.setAssetSources(tokens, aggregators)); } else { - aaveOracle = await deployAaveOracle( - [tokens, aggregators, fallbackOracleAddress, await getWethAddress(poolConfig)], + aaveOracle = await deployAaveOracleV2( + [ + tokens, + aggregators, + fallbackOracleAddress, + await getQuoteCurrency(poolConfig), + poolConfig.OracleQuoteUnit, + ], verify ); await waitForTx(await aaveOracle.setAssetSources(tokens, aggregators)); @@ -74,7 +87,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment') ); } - console.log('Aave Oracle: %s', lendingRateOracle.address); + console.log('Aave Oracle: %s', aaveOracle.address); console.log('Lending Rate Oracle: %s', lendingRateOracle.address); // Register the proxy price provider on the addressesProvider @@ -84,7 +97,7 @@ task('full:deploy-oracles', 'Deploy oracles for dev enviroment') if (DRE.network.name.includes('tenderly')) { const transactionLink = `https://dashboard.tenderly.co/${DRE.config.tenderly.username}/${ DRE.config.tenderly.project - }/fork/${DRE.tenderlyNetwork.getFork()}/simulation/${DRE.tenderlyNetwork.getHead()}`; + }/fork/${DRE.tenderly.network().getFork()}/simulation/${DRE.tenderly.network().getHead()}`; console.error('Check tx error:', transactionLink); } throw error; diff --git a/tasks/full/6-initialize.ts b/tasks/full/6-initialize.ts index bfe2925e..f315f36b 100644 --- a/tasks/full/6-initialize.ts +++ b/tasks/full/6-initialize.ts @@ -66,6 +66,7 @@ task('full:initialize-lending-pool', 'Initialize lending pool configuration.') admin, treasuryAddress, incentivesController, + pool, verify ); await configureReservesByHelper(ReservesConfig, reserveAssets, testHelpers, admin); diff --git a/tasks/helpers/deploy-new-asset.ts b/tasks/helpers/deploy-new-asset.ts index 718b6372..86b4958a 100644 --- a/tasks/helpers/deploy-new-asset.ts +++ b/tasks/helpers/deploy-new-asset.ts @@ -3,9 +3,9 @@ import { eEthereumNetwork } from '../../helpers/types'; import { getTreasuryAddress } from '../../helpers/configuration'; import * as marketConfigs from '../../markets/aave'; import * as reserveConfigs from '../../markets/aave/reservesConfigs'; -import { chooseATokenDeployment } from '../../helpers/init-helpers'; import { getLendingPoolAddressesProvider } from './../../helpers/contracts-getters'; import { + chooseATokenDeployment, deployDefaultReserveInterestRateStrategy, deployStableDebtToken, deployVariableDebtToken, @@ -47,18 +47,7 @@ WRONG RESERVE ASSET SETUP: LENDING_POOL_ADDRESS_PROVIDER[network] ); const poolAddress = await addressProvider.getLendingPool(); - const treasuryAddress = await getTreasuryAddress(marketConfigs.AaveConfig); - const aToken = await deployCustomAToken( - [ - poolAddress, - reserveAssetAddress, - treasuryAddress, - ZERO_ADDRESS, // Incentives Controller - `Aave interest bearing ${symbol}`, - `a${symbol}`, - ], - verify - ); + const aToken = await deployCustomAToken(verify); const stableDebt = await deployStableDebtToken( [ poolAddress,