Merge branch 'master' into fix/62

This commit is contained in:
The3D 2020-10-13 13:41:57 +02:00
commit 543c3f5c9c
69 changed files with 16415 additions and 2371 deletions

5
.gitignore vendored
View File

@ -1,14 +1,15 @@
.env
#Buidler files
cache
artifacts
types
node_modules
dist/
build/
.vscode
.idea
types
coverage
.coverage_artifacts
.coverage_cache
.coverage_contracts
.coverage_contracts

View File

@ -1,4 +1,4 @@
FROM ethereum/solc:0.6.8 as build-deps
FROM node:13
FROM node:14
COPY --from=build-deps /usr/bin/solc /usr/bin/solc

View File

@ -1,3 +1,5 @@
import path from 'path';
import fs from 'fs';
import {usePlugin} from '@nomiclabs/buidler/config';
// @ts-ignore
import {accounts} from './test-wallets.js';
@ -11,18 +13,29 @@ usePlugin('@nomiclabs/buidler-waffle');
usePlugin('@nomiclabs/buidler-etherscan');
//usePlugin('buidler-gas-reporter');
const SKIP_LOAD = process.env.SKIP_LOAD === 'true';
const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
const DEFAULT_GAS_PRICE = 10;
const HARDFORK = 'istanbul';
const INFURA_KEY = '';
const ETHERSCAN_KEY = '';
const INFURA_KEY = process.env.INFURA_KEY || '';
const ETHERSCAN_KEY = process.env.ETHERSCAN_KEY || '';
const MNEMONIC_PATH = "m/44'/60'/0'/0";
const MNEMONICS: {[network: string]: string} = {
[eEthereumNetwork.kovan]: '',
[eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '',
[eEthereumNetwork.kovan]: process.env.MNEMONIC || '',
[eEthereumNetwork.ropsten]: process.env.MNEMONIC || '',
[eEthereumNetwork.main]: process.env.MNEMONIC || '',
};
// Prevent to load scripts before compilation and typechain
if (!SKIP_LOAD) {
['misc', 'migrations', 'dev', 'full'].forEach((folder) => {
const tasksPath = path.join(__dirname, 'tasks', folder);
fs.readdirSync(tasksPath)
.filter((pth) => pth.includes('.ts'))
.forEach((task) => require(`${tasksPath}/${task}`));
});
}
const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
return {
url: `https://${networkName}.infura.io/v3/${INFURA_KEY}`,
@ -39,7 +52,7 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number
};
};
const config: any = {
const buidlerConfig: any = {
solc: {
version: '0.6.8',
optimizer: {enabled: true, runs: 200},
@ -50,7 +63,6 @@ const config: any = {
target: 'ethers-v4',
},
etherscan: {
url: 'https://api-kovan.etherscan.io/api',
apiKey: ETHERSCAN_KEY,
},
defaultNetwork: 'buidlerevm',
@ -90,4 +102,4 @@ const config: any = {
},
};
export default config;
export default buidlerConfig;

320
config/aave.ts Normal file
View File

@ -0,0 +1,320 @@
import BigNumber from 'bignumber.js';
import {oneRay} from '../helpers/constants';
import {IAaveConfiguration, EthereumNetwork, eEthereumNetwork} from '../helpers/types';
import {CommonsConfig} from './commons';
// ----------------
// POOL--SPECIFIC PARAMS
// ----------------
export const AaveConfig: IAaveConfiguration = {
...CommonsConfig,
ConfigName: 'Aave',
ProviderId: 1,
ReserveSymbols: [
'WETH',
'DAI',
'LEND',
'TUSD',
'BAT',
'USDC',
'USDT',
'SUSD',
'ZRX',
'MKR',
'WBTC',
'LINK',
'KNC',
'MANA',
'REP',
'SNX',
'BUSD',
],
ReservesConfig: {
DAI: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.05).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
TUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
},
SUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
LEND: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
BAT: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
WETH: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
LINK: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6500',
liquidationThreshold: '7000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
WBTC: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '8',
},
KNC: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
REP: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
MKR: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
MANA: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
ZRX: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
SNX: {
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
BUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
},
ReserveAssets: {
[eEthereumNetwork.buidlerevm]: {},
[eEthereumNetwork.coverage]: {},
[EthereumNetwork.kovan]: {
WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
TUSD: '0x016750AC630F711882812f24Dba6c95b9D35856d',
USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
SUSD: '0xD868790F57B39C9B2B51b12de046975f986675f9',
LEND: '0x690eAcA024935Aaff9B14b9FF9e9C8757a281f3C',
BAT: '0x2d12186Fbb9f9a8C28B3FfdD4c42920f8539D738',
REP: '0x260071C8D61DAf730758f8BD0d6370353956AE0E',
MKR: '0x61e4CAE3DA7FD189e52a4879C7B8067D7C2Cc0FA',
LINK: '0xAD5ce863aE3E4E9394Ab43d4ba0D80f419F61789',
KNC: '0x3F80c39c0b96A0945f9F0E9f55d8A8891c5671A8',
WBTC: '0x3b92f58feD223E2cB1bCe4c286BD97e42f2A12EA',
MANA: '0x738Dc6380157429e957d223e6333Dc385c85Fec7',
ZRX: '0xD0d76886cF8D952ca26177EB7CfDf83bad08C00C',
SNX: '0x7FDb81B0b8a010dd4FFc57C3fecbf145BA8Bd947',
BUSD: '0x4c6E1EFC12FDfD568186b7BAEc0A43fFfb4bCcCf',
},
[EthereumNetwork.ropsten]: {
WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
TUSD: '0xa2EA00Df6d8594DBc76b79beFe22db9043b8896F',
USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
SUSD: '0xc374eB17f665914c714Ac4cdC8AF3a3474228cc5',
LEND: '0xB47F338EC1e3857BB188E63569aeBAB036EE67c6',
BAT: '0x85B24b3517E3aC7bf72a14516160541A60cFF19d',
REP: '0xBeb13523503d35F9b3708ca577CdCCAdbFB236bD',
MKR: '0x2eA9df3bABe04451c9C3B06a2c844587c59d9C37',
LINK: '0x1a906E71FF9e28d8E01460639EB8CF0a6f0e2486',
KNC: '0xCe4aA1dE3091033Ba74FA2Ad951f6adc5E5cF361',
WBTC: '0xa0E54Ab6AA5f0bf1D62EC3526436F3c05b3348A0',
MANA: '0x78b1F763857C8645E46eAdD9540882905ff32Db7',
ZRX: '0x02d7055704EfF050323A2E5ee4ba05DB2A588959',
SNX: '0xF80Aa7e2Fda4DA065C55B8061767F729dA1476c7',
BUSD: '0xFA6adcFf6A90c11f31Bc9bb59eC0a6efB38381C6',
},
[EthereumNetwork.main]: {
WETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
DAI: '0x6b175474e89094c44da98b954eedeac495271d0f',
TUSD: '0x0000000000085d4780B73119b644AE5ecd22b376',
USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7',
SUSD: '0x57ab1ec28d129707052df4df418d58a2d46d5f51',
LEND: '0x80fB784B7eD66730e8b1DBd9820aFD29931aab03',
BAT: '0x0d8775f648430679a709e98d2b0cb6250d2887ef',
REP: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
MKR: '0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2',
LINK: '0x514910771af9ca656af840dff83e8264ecf986ca',
KNC: '0xdd974d5c2e2928dea5f71b9825b8b646686bd200',
WBTC: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599',
MANA: '0x0f5d2fb29fb7d3cfee444a200298f468908cc942',
ZRX: '0xe41d2489571d322189246dafa5ebde1f4699f498',
SNX: '0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F',
BUSD: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
},
},
};
export default AaveConfig;

261
config/commons.ts Normal file
View File

@ -0,0 +1,261 @@
import BigNumber from 'bignumber.js';
import {oneEther, oneRay, RAY} from '../helpers/constants';
import {ICommonConfiguration, EthereumNetwork, eEthereumNetwork} from '../helpers/types';
const MOCK_CHAINLINK_AGGREGATORS_PRICES = {
DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
LEND: oneEther.multipliedBy('0.00003620948469').toFixed(),
BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
MKR: oneEther.multipliedBy('2.508581').toFixed(),
REP: oneEther.multipliedBy('0.048235').toFixed(),
ZRX: oneEther.multipliedBy('0.001151').toFixed(),
WBTC: oneEther.multipliedBy('47.332685').toFixed(),
LINK: oneEther.multipliedBy('0.009955').toFixed(),
KNC: oneEther.multipliedBy('0.001072').toFixed(),
MANA: oneEther.multipliedBy('0.000158').toFixed(),
SNX: oneEther.multipliedBy('0.00442616').toFixed(),
BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
WETH: oneEther.toFixed(),
USD: '5848466240000000',
UNI_DAI_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_USDC_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_SETH_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_LEND_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_LINK_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_MKR_ETH: oneEther.multipliedBy('2.1').toFixed(),
};
// ----------------
// PROTOCOL GLOBAL PARAMS
// ----------------
export const CommonsConfig: ICommonConfiguration = {
ConfigName: 'Commons',
ProviderId: 0,
ReserveSymbols: [],
ProtocolGlobalParams: {
OptimalUtilizationRate: new BigNumber(0.8).times(RAY),
ExcessUtilizationRate: new BigNumber(0.2).times(RAY),
ApprovalAmountLendingPoolCore: '1000000000000000000000000000',
TokenDistributorPercentageBase: '10000',
MockUsdPriceInWei: '5848466240000000',
EthereumAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
NilAddress: '0x0000000000000000000000000000000000000000',
OneAddress: '0x0000000000000000000000000000000000000001',
AaveReferral: '0',
},
// ----------------
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
// ----------------
Mocks: {
ChainlinkAggregatorPrices: {
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
},
AllAssetsInitialPrices: {
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
},
},
LendingRateOracleRatesCommon: {
WETH: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
DAI: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
TUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDC: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
SUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDT: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
BAT: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LEND: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LINK: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
KNC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
REP: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MKR: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MANA: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
WBTC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
ZRX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
SNX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
BUSD: {
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
},
},
// ----------------
// COMMON PROTOCOL ADDRESSES ACROSS POOLS
// ----------------
// If lendingPoolManagerAddress is set, will take priority over lendingPoolManagerAddressIndex
AaveAdmin: {
[eEthereumNetwork.coverage]: undefined,
[eEthereumNetwork.buidlerevm]: undefined,
[eEthereumNetwork.kovan]: undefined,
[eEthereumNetwork.ropsten]: undefined,
[eEthereumNetwork.main]: undefined,
},
AaveAdminIndex: 0,
ProviderRegistry: {
[eEthereumNetwork.kovan]: '',
[eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '',
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.buidlerevm]: '',
},
LendingRateOracle: {
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.buidlerevm]: '',
[eEthereumNetwork.kovan]: '0xdcde9bb6a49e37fa433990832ab541ae2d4feb4a',
[eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
[eEthereumNetwork.main]: '0x4d728a4496e4de35f218d5a214366bde3a62b51c',
},
TokenDistributor: {
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.buidlerevm]: '',
[EthereumNetwork.kovan]: '0x971efe90088f21dc6a36f610ffed77fc19710708',
[EthereumNetwork.ropsten]: '0xeba2ea67942b8250d870b12750b594696d02fc9c',
[EthereumNetwork.main]: '0xe3d9988f676457123c5fd01297605efdd0cba1ae',
},
ChainlinkProxyPriceProvider: {
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.buidlerevm]: '',
[EthereumNetwork.kovan]: '0x276C4793F2EE3D5Bf18C5b879529dD4270BA4814',
[EthereumNetwork.ropsten]: '0x657372A559c30d236F011239fF9fbB6D76718271',
[EthereumNetwork.main]: '0x76B47460d7F7c5222cFb6b6A75615ab10895DDe4',
},
FallbackOracle: {
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.buidlerevm]: '',
[EthereumNetwork.kovan]: '0x50913E8E1c650E790F8a1E741FF9B1B1bB251dfe',
[EthereumNetwork.ropsten]: '0xAD1a978cdbb8175b2eaeC47B01404f8AEC5f4F0d',
[EthereumNetwork.main]: '0xf67a8b0e3e0ee303422f78b4c5b8da60df80a59c',
},
ChainlinkAggregator: {
[eEthereumNetwork.coverage]: {},
[eEthereumNetwork.buidlerevm]: {},
[EthereumNetwork.kovan]: {
DAI: '0x6F47077D3B6645Cb6fb7A29D280277EC1e5fFD90',
TUSD: '0x02424c54D78D48179Fd12ebFfB11c16f9CA984Ad',
USDC: '0x672c1C0d1130912D83664011E7960a42E8cA05D5',
USDT: '0xCC833A6522721B3252e7578c5BCAF65738B75Fc3',
SUSD: '0xa353F8b083F7575cfec443b5ad585D42f652E9F7',
LEND: '0xdce38940264dfbc01ad1486c21764948e511947e',
BAT: '0x2c8d01771CCDca47c103194C5860dbEA2fE61626',
REP: '0x09F4A94F44c29d4967C761bBdB89f5bD3E2c09E6',
MKR: '0x14D7714eC44F44ECD0098B39e642b246fB2c38D0',
LINK: '0xf1e71Afd1459C05A2F898502C4025be755aa844A',
KNC: '0x0893AaF58f62279909F9F6FF2E5642f53342e77F',
WBTC: '0x33E5085E92f5b53E9A193E28ad2f76bF210550BB',
MANA: '0x3c30c5c415B2410326297F0f65f5Cbb32f3aefCc',
ZRX: '0x2636cfdDB457a6C7A7D60A439F1E5a5a0C3d9c65',
SNX: '0x775E76cca1B5bc903c9a8C6f77416A35E5744664',
BUSD: '0x63294A05C9a81b1A40CAD3f2ff30617111630393',
USD: '0xD21912D8762078598283B14cbA40Cb4bFCb87581',
UNI_DAI_ETH: '0x0338C40020Bf886c11406115fD1ba205Ef1D9Ff9',
UNI_USDC_ETH: '0x7f5E5D34591e9a70D187BBA94260C30B92aC0961',
UNI_SETH_ETH: '0xc5F1eA001c1570783b3af418fa775237Eb129EDC',
UNI_LEND_ETH: '0xB996b1a11BA0aACc4deA57f7f92d1722428f2E90',
UNI_LINK_ETH: '0x267490eE9Ad21dfE839aE73A8B1c8C9A36F60d33',
UNI_MKR_ETH: '0x6eBF25AB0A18B8F6243619f1AE6b94373169A069',
},
[EthereumNetwork.ropsten]: {
DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
TUSD: '0x523ac85618df56e940534443125ef16daf785620',
USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
SUSD: '0xe054b4aee7ac7645642dd52f1c892ff0128c98f0',
LEND: '0xf7b4834fe443d1E04D757b4b089b35F5A90F2847',
BAT: '0xafd8186c962daf599f171b8600f3e19af7b52c92',
REP: '0xa949ee9ba80c0f381481f2eab538bc5547a5ac67',
MKR: '0x811B1f727F8F4aE899774B568d2e72916D91F392',
LINK: '0xb8c99b98913bE2ca4899CdcaF33a3e519C20EeEc',
KNC: '0x19d97ceb36624a31d827032d8216dd2eb15e9845',
WBTC: '0x5b8B87A0abA4be247e660B0e0143bB30Cdf566AF',
MANA: '0xDab909dedB72573c626481fC98CEE1152b81DEC2',
ZRX: '0x1d0052e4ae5b4ae4563cbac50edc3627ca0460d7',
SNX: '0xA95674a8Ed9aa9D2E445eb0024a9aa05ab44f6bf',
BUSD: '0x0A32D96Ff131cd5c3E0E5AAB645BF009Eda61564',
USD: '0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507',
UNI_DAI_ETH: '0x16048819e3f77b7112eB033624A0bA9d33743028',
UNI_USDC_ETH: '0x6952A2678D574073DB97963886c2F38CD09C8Ba3',
UNI_SETH_ETH: '0x23Ee5188806BD2D31103368B0EA0259bc6706Af1',
UNI_LEND_ETH: '0x43c44B27376Afedee06Bae2A003e979FC3B3Da6C',
UNI_LINK_ETH: '0xb60c29714146EA3539261f599Eb30f62904108Fa',
UNI_MKR_ETH: '0x594ae5421f378b8B4AF9e758C461d2A1FF990BC5',
},
[EthereumNetwork.main]: {
DAI: '0x037E8F2125bF532F3e228991e051c8A7253B642c',
TUSD: '0x73ead35fd6A572EF763B13Be65a9db96f7643577',
USDC: '0xdE54467873c3BCAA76421061036053e371721708',
USDT: '0xa874fe207DF445ff19E7482C746C4D3fD0CB9AcE',
SUSD: '0x6d626Ff97f0E89F6f983dE425dc5B24A18DE26Ea',
LEND: '0x1EeaF25f2ECbcAf204ECADc8Db7B0db9DA845327',
BAT: '0x9b4e2579895efa2b4765063310Dc4109a7641129',
REP: '0xb8b513d9cf440C1b6f5C7142120d611C94fC220c',
MKR: '0xda3d675d50ff6c555973c4f0424964e1f6a4e7d3',
LINK: '0xeCfA53A8bdA4F0c4dd39c55CC8deF3757aCFDD07',
KNC: '0xd0e785973390fF8E77a83961efDb4F271E6B8152',
WBTC: '0x0133Aa47B6197D0BA090Bf2CD96626Eb71fFd13c',
MANA: '0xc89c4ed8f52Bb17314022f6c0dCB26210C905C97',
ZRX: '0xA0F9D94f060836756FFC84Db4C78d097cA8C23E8',
SNX: '0xE23d1142dE4E83C08bb048bcab54d50907390828',
BUSD: '0x5d4BB541EED49D0290730b4aB332aA46bd27d888',
USD: '0x59b826c214aBa7125bFA52970d97736c105Cc375',
UNI_DAI_ETH: '0x1bAB293850289Bf161C5DA79ff3d1F02A950555b',
UNI_USDC_ETH: '0x444315Ee92F2bb3579293C17B07194227fA99bF0',
UNI_SETH_ETH: '0x517D40E49660c7705b2e99eEFA6d7B0E9Ba5BF10',
UNI_LEND_ETH: '0xF4C8Db2d999b024bBB6c6022566503eD41f2AC1E',
UNI_LINK_ETH: '0xE2A639Beb647d7F709ca805ABa760bBEfdbE37e3',
UNI_MKR_ETH: '0xEe40a5E8F3732bE6ECDb5A90e23D0b7bF0D4a73c',
},
},
ReserveAssets: {
[eEthereumNetwork.coverage]: {},
[eEthereumNetwork.buidlerevm]: {},
[EthereumNetwork.main]: {},
[EthereumNetwork.kovan]: {},
[EthereumNetwork.ropsten]: {},
},
ReservesConfig: {},
ATokenDomainSeparator: {
[eEthereumNetwork.coverage]:
'0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
[eEthereumNetwork.buidlerevm]:
'0x76cbbf8aa4b11a7c207dd79ccf8c394f59475301598c9a083f8258b4fafcfa86',
[eEthereumNetwork.kovan]: '',
[eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '',
},
};

6
config/tokensets_v2.ts Normal file
View File

@ -0,0 +1,6 @@
import {CommonsConfig} from './commons';
export const TokenSetsConfig = {
...CommonsConfig,
// ...TokenSetsConfigStore,
};

236
config/uniswap.ts Normal file
View File

@ -0,0 +1,236 @@
import BigNumber from 'bignumber.js';
import {eEthereumNetwork, EthereumNetwork, IUniswapConfiguration} from '../helpers/types';
import {oneRay} from '../helpers/constants';
import {CommonsConfig} from './commons';
// ----------------
// POOL--SPECIFIC PARAMS
// ----------------
export const UniswapConfig: IUniswapConfiguration = {
...CommonsConfig,
ConfigName: 'Uniswap',
ProviderId: 2,
ReserveSymbols: [
'WETH',
'DAI',
'USDC',
'USDT',
'UNI_DAI_ETH',
'UNI_USDC_ETH',
'UNI_SETH_ETH',
'UNI_LINK_ETH',
'UNI_MKR_ETH',
'UNI_LEND_ETH',
],
ReservesConfig: {
WETH: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
DAI: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '6',
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '6',
},
UNI_DAI_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6800',
liquidationThreshold: '7300',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_USDC_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6800',
liquidationThreshold: '7300',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_SETH_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '4800',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_LEND_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '5100',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_LINK_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6300',
liquidationThreshold: '6800',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_MKR_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '4800',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
},
ChainlinkAggregator: {
[eEthereumNetwork.buidlerevm]: {},
[eEthereumNetwork.coverage]: {},
[EthereumNetwork.kovan]: {
DAI: '0x6F47077D3B6645Cb6fb7A29D280277EC1e5fFD90',
USDC: '0x672c1C0d1130912D83664011E7960a42E8cA05D5',
USDT: '0xCC833A6522721B3252e7578c5BCAF65738B75Fc3',
UNI_DAI_ETH: '0x0338C40020Bf886c11406115fD1ba205Ef1D9Ff9',
UNI_USDC_ETH: '0x7f5E5D34591e9a70D187BBA94260C30B92aC0961',
UNI_SETH_ETH: '0xc5F1eA001c1570783b3af418fa775237Eb129EDC',
UNI_LEND_ETH: '0xB996b1a11BA0aACc4deA57f7f92d1722428f2E90',
UNI_LINK_ETH: '0x267490eE9Ad21dfE839aE73A8B1c8C9A36F60d33',
UNI_MKR_ETH: '0x6eBF25AB0A18B8F6243619f1AE6b94373169A069',
},
[EthereumNetwork.ropsten]: {
DAI: '0x64b8e49baded7bfb2fd5a9235b2440c0ee02971b',
USDC: '0xe1480303dde539e2c241bdc527649f37c9cbef7d',
USDT: '0xc08fe0c4d97ccda6b40649c6da621761b628c288',
UNI_DAI_ETH: '0x16048819e3f77b7112eB033624A0bA9d33743028',
UNI_USDC_ETH: '0x6952A2678D574073DB97963886c2F38CD09C8Ba3',
UNI_SETH_ETH: '0x23Ee5188806BD2D31103368B0EA0259bc6706Af1',
UNI_LEND_ETH: '0x43c44B27376Afedee06Bae2A003e979FC3B3Da6C',
UNI_LINK_ETH: '0xb60c29714146EA3539261f599Eb30f62904108Fa',
UNI_MKR_ETH: '0x594ae5421f378b8B4AF9e758C461d2A1FF990BC5',
},
[EthereumNetwork.main]: {
DAI: '0x037E8F2125bF532F3e228991e051c8A7253B642c',
USDC: '0xdE54467873c3BCAA76421061036053e371721708',
USDT: '0xa874fe207DF445ff19E7482C746C4D3fD0CB9AcE',
UNI_DAI_ETH: '0x1bAB293850289Bf161C5DA79ff3d1F02A950555b',
UNI_USDC_ETH: '0x444315Ee92F2bb3579293C17B07194227fA99bF0',
UNI_SETH_ETH: '0x517D40E49660c7705b2e99eEFA6d7B0E9Ba5BF10',
UNI_LEND_ETH: '0xF4C8Db2d999b024bBB6c6022566503eD41f2AC1E',
UNI_LINK_ETH: '0xE2A639Beb647d7F709ca805ABa760bBEfdbE37e3',
UNI_MKR_ETH: '0xEe40a5E8F3732bE6ECDb5A90e23D0b7bF0D4a73c',
},
},
ReserveAssets: {
[eEthereumNetwork.buidlerevm]: {},
[eEthereumNetwork.coverage]: {},
[EthereumNetwork.kovan]: {
WETH: '0xd0a1e359811322d97991e03f863a0c30c2cf029c',
DAI: '0xFf795577d9AC8bD7D90Ee22b6C1703490b6512FD',
USDC: '0xe22da380ee6B445bb8273C81944ADEB6E8450422',
USDT: '0x13512979ADE267AB5100878E2e0f485B568328a4',
UNI_DAI_ETH: '0x2e0086b5343101203ADeE40160ca1BD91E29fF75',
UNI_USDC_ETH: '0x34eA1aB2a43ee696914fc3C0d3e517fA666B9e8D',
UNI_SETH_ETH: '0xCF457d8Bb8D8f54Af1ea1B3710231e89bd6CFbfe',
UNI_LEND_ETH: '0x7615cd666F867406C64E558B9CCC3883e7EC9BA8',
UNI_LINK_ETH: '0xFb9AAc184e79025f936E9C4EF3047Ad4889Df4a8',
UNI_MKR_ETH: '0xB31a1c30f38cD68e8177566Ef950d7bc3C81DaCF',
},
[EthereumNetwork.ropsten]: {
WETH: '0xc778417e063141139fce010982780140aa0cd5ab',
DAI: '0xf80A32A835F79D7787E8a8ee5721D0fEaFd78108',
USDC: '0x851dEf71f0e6A903375C1e536Bd9ff1684BAD802',
USDT: '0xB404c51BBC10dcBE948077F18a4B8E553D160084',
UNI_DAI_ETH: '0xC245A7d35E652Cae438A1FdB13E474DF53DBB81D',
UNI_USDC_ETH: '0x2BD65323955D08eb600074291305881d1295c4D2',
UNI_SETH_ETH: '0xed4597DCd234867d7A260AD24bAb8253F64940a5',
UNI_LEND_ETH: '0xcD5DE1EDD40aBBD6efE2C306276FF56f81Bc3151',
UNI_LINK_ETH: '0x8dcf3c8d4d69ca7C188c0A4cf219A1dcE1e510d7',
UNI_MKR_ETH: '0xd8b7B99a9205FD0D0abFB6D7a2c13Db2681bff43',
},
[EthereumNetwork.main]: {
WETH: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
DAI: '0x6b175474e89094c44da98b954eedeac495271d0f',
USDC: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
USDT: '0xdac17f958d2ee523a2206206994597c13d831ec7',
UNI_DAI_ETH: '0x2a1530c4c41db0b0b2bb646cb5eb1a67b7158667',
UNI_USDC_ETH: '0x97dec872013f6b5fb443861090ad931542878126',
UNI_SETH_ETH: '0xe9cf7887b93150d4f2da7dfc6d502b216438f244',
UNI_LEND_ETH: '0xcaa7e4656f6a2b59f5f99c745f91ab26d1210dce',
UNI_LINK_ETH: '0xf173214c720f58e03e194085b1db28b50acdeead',
UNI_MKR_ETH: '0x2c4bd064b998838076fa341a83d007fc2fa50957',
},
},
};

View File

@ -13,5 +13,5 @@ interface IFlashLoanReceiver {
uint256 amount,
uint256 fee,
bytes calldata params
) external;
) external returns (bool);
}

View File

@ -50,7 +50,6 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
//slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
uint256 internal immutable _stableRateSlope2;
constructor(
LendingPoolAddressesProvider provider,
uint256 baseVariableBorrowRate,
@ -94,9 +93,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
function getMaxVariableBorrowRate() external override view returns (uint256) {
return _baseVariableBorrowRate.add(_variableRateSlope1).add(_variableRateSlope2);
}
struct CalcInterestRatesLocalVars {
struct CalcInterestRatesLocalVars {
uint256 totalBorrows;
uint256 currentVariableBorrowRate;
uint256 currentStableBorrowRate;
@ -133,7 +131,6 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
uint256
)
{
CalcInterestRatesLocalVars memory vars;
vars.totalBorrows = totalStableDebt.add(totalVariableDebt);
@ -172,13 +169,18 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
vars.currentLiquidityRate = _getOverallBorrowRate(
totalStableDebt,
totalVariableDebt,
vars.currentVariableBorrowRate,
vars
.currentVariableBorrowRate,
averageStableBorrowRate
)
.rayMul(utilizationRate)
.percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(reserveFactor));
return (vars.currentLiquidityRate, vars.currentStableBorrowRate, vars.currentVariableBorrowRate);
return (
vars.currentLiquidityRate,
vars.currentStableBorrowRate,
vars.currentVariableBorrowRate
);
}
/**
@ -199,13 +201,9 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
if (totalBorrows == 0) return 0;
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(
currentVariableBorrowRate
);
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(
currentAverageStableBorrowRate
);
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
uint256 overallBorrowRate = weightedVariableRate.add(weightedStableRate).rayDiv(
totalBorrows.wadToRay()

View File

@ -579,7 +579,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
//execute action of the receiver
vars.receiver.executeOperation(asset, amount, vars.premium, params);
require(
vars.receiver.executeOperation(asset, amount, vars.premium, params),
Errors.INVALID_FLASH_LOAN_EXECUTOR_RETURN
);
vars.amountPlusPremium = amount.add(vars.premium);
@ -720,7 +723,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
return _reserves[asset].configuration;
}
/**
/**
* @dev returns the configuration of the user for the specific reserve
* @param user the user
* @return the configuration of the user
@ -734,7 +737,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
return _usersConfig[user];
}
/**
/**
* @dev returns the normalized income per unit of asset
* @param asset the address of the reserve
* @return the reserve normalized income
@ -757,7 +760,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
return _reserves[asset].getNormalizedDebt();
}
/**
/**
* @dev Returns if the LendingPool is paused
*/
function paused() external override view returns (bool) {
@ -810,8 +813,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
}
/**
* @dev avoids direct transfers of ETH
**/
* @dev avoids direct transfers of ETH
**/
receive() external payable {
revert();
}
@ -853,10 +856,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
}
/**
* @dev sets the configuration map of the reserve
* @param asset the address of the reserve
* @param configuration the configuration map
**/
* @dev sets the configuration map of the reserve
* @param asset the address of the reserve
* @param configuration the configuration map
**/
function setConfiguration(address asset, uint256 configuration) external override {
_onlyLendingPoolConfigurator();
_reserves[asset].configuration.data = configuration;
@ -876,6 +879,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
emit Unpaused();
}
}
// internal functions
struct ExecuteBorrowParams {
address asset;

View File

@ -25,5 +25,4 @@ contract LendingPoolStorage {
bool internal _flashLiquidationLocked;
bool internal _paused;
}

View File

@ -5,6 +5,7 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {WadRayMath} from '../math/WadRayMath.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
/**
* @title UserConfiguration library
* @author Aave

View File

@ -44,6 +44,7 @@ library Errors {
string public constant FAILED_COLLATERAL_SWAP = '55';
string public constant INVALID_EQUAL_ASSETS_TO_SWAP = '56';
string public constant NO_MORE_RESERVES_ALLOWED = '59';
string public constant INVALID_FLASH_LOAN_EXECUTOR_RETURN = '60';
// require error messages - aToken - DebtTokens
string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'

View File

@ -20,6 +20,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
bool _failExecution;
uint256 _amountToApprove;
bool _simulateEOA;
constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {}
@ -31,16 +32,25 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
_amountToApprove = amountToApprove;
}
function setSimulateEOA(bool flag) public {
_simulateEOA = flag;
}
function amountToApprove() public view returns (uint256) {
return _amountToApprove;
}
function simulateEOA() public view returns (bool) {
return _simulateEOA;
}
function executeOperation(
address reserve,
uint256 amount,
uint256 fee,
bytes memory params
) public override {
) public override returns (bool) {
params;
//mint to this contract the specific amount
MintableERC20 token = MintableERC20(reserve);
@ -51,7 +61,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
if (_failExecution) {
emit ExecutedWithFail(reserve, amount, fee);
return;
return !_simulateEOA;
}
//execution does not fail - mint tokens and return them to the _destination
@ -62,5 +72,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
IERC20(reserve).approve(_addressesProvider.getLendingPool(), amountToReturn);
emit ExecutedWithSuccess(reserve, amount, fee);
return true;
}
}

View File

@ -12,7 +12,17 @@ contract MockAToken is AToken {
string memory tokenName,
string memory tokenSymbol,
address incentivesController
) public AToken(pool, underlyingAssetAddress, reserveTreasury, tokenName, tokenSymbol, incentivesController) {}
)
public
AToken(
pool,
underlyingAssetAddress,
reserveTreasury,
tokenName,
tokenSymbol,
incentivesController
)
{}
function getRevision() internal override pure returns (uint256) {
return 0x2;

View File

@ -134,7 +134,6 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
emit Mint(user, amount, index);
}
/**
* @dev mints aTokens to reserve treasury
* only lending pools can call this function
@ -142,8 +141,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
* @param index the the last index of the reserve
*/
function mintToTreasury(uint256 amount, uint256 index) external override onlyLendingPool {
if(amount == 0){
if (amount == 0) {
return;
}

View File

@ -60,7 +60,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 amount,
uint256 index
) external override onlyLendingPool {
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);
@ -80,7 +79,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 amount,
uint256 index
) external override onlyLendingPool {
uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_BURN_AMOUNT);
@ -114,14 +112,18 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
return super.totalSupply();
}
/**
/**
* @dev returns the principal balance of the user and principal total supply.
* @param user the address of the user
* @return the principal balance of the user
* @return the principal total supply
**/
function getScaledUserBalanceAndSupply(address user) external override view returns (uint256, uint256){
function getScaledUserBalanceAndSupply(address user)
external
override
view
returns (uint256, uint256)
{
return (super.balanceOf(user), super.totalSupply());
}
}

View File

@ -11,12 +11,7 @@ interface IAToken is IERC20, IScaledBalanceToken {
* @param value the amount to be redeemed
* @param index the last index of the reserve
**/
event Burn(
address indexed from,
address indexed target,
uint256 value,
uint256 index
);
event Burn(address indexed from, address indexed target, uint256 value, uint256 index);
/**
* @dev emitted during the transfer action
* @param from the address from which the tokens are being transferred
@ -24,12 +19,8 @@ interface IAToken is IERC20, IScaledBalanceToken {
* @param value the amount to be minted
* @param index the last index of the reserve
**/
event BalanceTransfer(
address indexed from,
address indexed to,
uint256 value,
uint256 index
);
event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
/**
* @dev burns the aTokens and sends the equivalent amount of underlying to the target.
* only lending pools can call this function
@ -63,7 +54,6 @@ interface IAToken is IERC20, IScaledBalanceToken {
uint256 value
) external;
function isTransferAllowed(address user, uint256 amount) external view returns (bool);
/**
@ -73,6 +63,4 @@ interface IAToken is IERC20, IScaledBalanceToken {
* @return the amount transferred
**/
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
}

View File

@ -1,9 +1,7 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
interface IScaledBalanceToken {
/**
* @dev emitted after the mint action
* @param from the address performing the mint

View File

@ -8,21 +8,16 @@ import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
* @author Aave
* @notice defines the basic interface for a variable debt token.
**/
interface IVariableDebtToken is IScaledBalanceToken {
interface IVariableDebtToken is IScaledBalanceToken {
/**
* @dev emitted when variable debt is burnt
* @param user the user which debt has been burned
* @param amount the amount of debt being burned
* @param index the index of the user
**/
event Burn(
address indexed user,
uint256 amount,
uint256 index
);
event Burn(address indexed user, uint256 amount, uint256 index);
/**
/**
* @dev burns user variable debt
* @param user the user which debt is burnt
* @param index the variable debt index of the reserve
@ -32,5 +27,4 @@ interface IVariableDebtToken is IScaledBalanceToken {
uint256 amount,
uint256 index
) external;
}

File diff suppressed because one or more lines are too long

View File

@ -25,6 +25,10 @@
"coverage": {
"address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"kovan": {
"address": "0x20e080B395341B3b617E893c281c7E999C942276",
"deployer": "0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F"
}
},
"LendingPoolAddressesProviderRegistry": {
@ -39,6 +43,10 @@
"coverage": {
"address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"kovan": {
"address": "0x00219a2958f758122106Bb8A801AFc1B70897663",
"deployer": "0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F"
}
},
"FeeProvider": {
@ -65,10 +73,10 @@
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
},
"localhost": {
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
"address": "0x65e0Cd5B8904A02f2e00BC6f58bf881998D54BDe"
},
"coverage": {
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
"kovan": {
"address": "0x50C9d3aD9399c1EEf6DDeadF8e57fF69994F552e"
}
},
"LendingPoolDataProvider": {
@ -81,10 +89,10 @@
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
},
"localhost": {
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
"address": "0x5d12dDe3286D94E0d85F9D3B01B7099cfA0aBCf1"
},
"coverage": {
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
"kovan": {
"address": "0x6d1e69bB0578699dd955Eefbf23aAC65c0DA5cE7"
}
},
"PriceOracle": {
@ -127,6 +135,10 @@
"coverage": {
"address": "0x7B6C3e5486D9e6959441ab554A889099eed76290",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"kovan": {
"address": "0x18a107d4fa249Efefd4DAf9A76EEE3b6366701AA",
"deployer": "0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F"
}
},
"LendingRateOracle": {
@ -141,6 +153,10 @@
"coverage": {
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"kovan": {
"address": "0xac6Eb7B1083D39eC695a3898C2f782E7c7C64973",
"deployer": "0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F"
}
},
"DefaultReserveInterestRateStrategy": {
@ -185,7 +201,7 @@
},
"TokenDistributor": {
"buidlerevm": {
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10",
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -194,7 +210,7 @@
},
"InitializableAdminUpgradeabilityProxy": {
"buidlerevm": {
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4",
"address": "0xC6bA6049F86d528698B5924B8fC2FE7289D38578",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {

View File

@ -1,4 +1,4 @@
version: "3.5"
version: '3.5'
services:
contracts-env:
build:

View File

@ -8,3 +8,8 @@ services:
command: npm run run-env
volumes:
- ./:/src
environment:
MNEMONIC: ${MNEMONIC}
ETHERSCAN_KEY: ${ETHERSCAN_KEY}
INFURA_KEY: ${INFURA_KEY}
ETHERSCAN_NETWORK: ${ETHERSCAN_NETWORK}

82
helpers/configuration.ts Normal file
View File

@ -0,0 +1,82 @@
import {
AavePools,
iMultiPoolsAssets,
IReserveParams,
PoolConfiguration,
iBasicDistributionParams,
ICommonConfiguration,
eEthereumNetwork,
} from './types';
import {getParamPerPool} from './contracts-helpers';
import {AaveConfig} from '../config/aave';
import {UniswapConfig} from '../config/uniswap';
import {CommonsConfig} from '../config/commons';
import {ZERO_ADDRESS} from './constants';
import {BRE} from './misc-utils';
import {tEthereumAddress} from './types';
import {getParamPerNetwork} from './contracts-helpers';
export enum ConfigNames {
Commons = 'Commons',
Aave = 'Aave',
Uniswap = 'Uniswap',
}
export const loadPoolConfig = (configName: ConfigNames): PoolConfiguration => {
switch (configName) {
case ConfigNames.Aave:
return AaveConfig;
case ConfigNames.Uniswap:
return UniswapConfig;
case ConfigNames.Commons:
return CommonsConfig;
default:
throw new Error(`Unsupported pool configuration: ${Object.values(ConfigNames)}`);
}
};
// ----------------
// PROTOCOL PARAMS PER POOL
// ----------------
export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IReserveParams> =>
getParamPerPool<iMultiPoolsAssets<IReserveParams>>(
{
[AavePools.proto]: {
...AaveConfig.ReservesConfig,
},
[AavePools.secondary]: {
...UniswapConfig.ReservesConfig,
},
},
pool
);
export const getFeeDistributionParamsCommon = (
receiver: tEthereumAddress
): iBasicDistributionParams => {
const receivers = [receiver, ZERO_ADDRESS];
const percentages = ['2000', '8000'];
return {
receivers,
percentages,
};
};
export const getGenesisAaveAdmin = async (config: ICommonConfiguration) => {
const currentNetwork = BRE.network.name;
const targetAddress = getParamPerNetwork(config.AaveAdmin, <eEthereumNetwork>currentNetwork);
if (targetAddress) {
return targetAddress;
}
const addressList = await Promise.all(
(await BRE.ethers.getSigners()).map((signer) => signer.getAddress())
);
const addressIndex = config.AaveAdminIndex;
return addressList[addressIndex];
};
export const getATokenDomainSeparatorPerNetwork = (
network: eEthereumNetwork,
config: ICommonConfiguration
): tEthereumAddress => getParamPerNetwork<tEthereumAddress>(config.ATokenDomainSeparator, network);

View File

@ -1,17 +1,4 @@
import {
AavePools,
eEthereumNetwork,
iAavePoolAssets,
iAssetAggregatorBase,
iAssetBase,
iBasicDistributionParams,
IMarketRates,
iMultiPoolsAssets,
IReserveParams,
tEthereumAddress,
} from './types';
import BigNumber from 'bignumber.js';
import {getParamPerNetwork, getParamPerPool} from './contracts-helpers';
// ----------------
// MATH
@ -26,521 +13,17 @@ export const oneEther = new BigNumber(Math.pow(10, 18));
export const oneRay = new BigNumber(Math.pow(10, 27));
export const MAX_UINT_AMOUNT =
'115792089237316195423570985008687907853269984665640564039457584007913129639935';
export const ONE_YEAR = '31536000';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
// ----------------
// PROTOCOL GLOBAL PARAMS
// ----------------
export const OPTIMAL_UTILIZATION_RATE = new BigNumber(0.8).times(RAY);
export const EXCESS_UTILIZATION_RATE = new BigNumber(0.2).times(RAY);
export const ONE_YEAR = '31536000';
export const APPROVAL_AMOUNT_LENDING_POOL = '1000000000000000000000000000';
export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000';
export const MOCK_USD_PRICE_IN_WEI = '5848466240000000';
export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
export const AAVE_REFERRAL = '0';
// ----------------
// COMMON PROTOCOL PARAMS ACROSS POOLS AND NETWORKS
// ----------------
export const ALL_AAVE_RESERVES_SYMBOLS = [
[
'ETH',
'DAI',
'LEND',
'TUSD',
'BAT',
'USDC',
'USDT',
'SUSD',
'ZRX',
'MKR',
'WBTC',
'LINK',
'KNC',
'MANA',
'REP',
'SNX',
'BUSD',
'UNI_DAI_ETH',
'UNI_USDC_ETH',
'UNI_SETH_ETH',
'UNI_LINK_ETH',
'UNI_MKR_ETH',
'UNI_LEND_ETH',
],
];
export const MOCK_CHAINLINK_AGGREGATORS_PRICES: iAssetAggregatorBase<string> = {
DAI: oneEther.multipliedBy('0.00369068412860').toFixed(),
TUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
USDC: oneEther.multipliedBy('0.00367714136416').toFixed(),
LEND: oneEther.multipliedBy('0.00003620948469').toFixed(),
BAT: oneEther.multipliedBy('0.00137893825230').toFixed(),
USDT: oneEther.multipliedBy('0.00369068412860').toFixed(),
SUSD: oneEther.multipliedBy('0.00364714136416').toFixed(),
MKR: oneEther.multipliedBy('2.508581').toFixed(),
REP: oneEther.multipliedBy('0.048235').toFixed(),
ZRX: oneEther.multipliedBy('0.001151').toFixed(),
WBTC: oneEther.multipliedBy('47.332685').toFixed(),
LINK: oneEther.multipliedBy('0.009955').toFixed(),
KNC: oneEther.multipliedBy('0.001072').toFixed(),
MANA: oneEther.multipliedBy('0.000158').toFixed(),
SNX: oneEther.multipliedBy('0.00442616').toFixed(),
BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
WETH: oneEther.toFixed(),
USD: MOCK_USD_PRICE_IN_WEI,
UNI_DAI_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_USDC_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_SETH_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_LEND_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_LINK_ETH: oneEther.multipliedBy('2.1').toFixed(),
UNI_MKR_ETH: oneEther.multipliedBy('2.1').toFixed(),
};
export const ALL_ASSETS_INITIAL_PRICES: iAssetBase<string> = {
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
};
export const LENDING_RATE_ORACLE_RATES_COMMON: iAavePoolAssets<IMarketRates> = {
WETH: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
DAI: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
TUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDC: {
borrowRate: oneRay.multipliedBy(0.039).toFixed(),
},
SUSD: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
USDT: {
borrowRate: oneRay.multipliedBy(0.035).toFixed(),
},
BAT: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LEND: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
LINK: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
KNC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
REP: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MKR: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
MANA: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
WBTC: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
ZRX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
SNX: {
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
},
BUSD: {
borrowRate: oneRay.multipliedBy(0.05).toFixed(),
},
};
export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IReserveParams> =>
getParamPerPool<iMultiPoolsAssets<IReserveParams>>(
{
[AavePools.proto]: {
DAI: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.05).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
TUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
},
SUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
LEND: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
BAT: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
WETH: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
LINK: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6500',
liquidationThreshold: '7000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
WBTC: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '8',
},
KNC: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
REP: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
MKR: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
MANA: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
ZRX: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
},
SNX: {
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
BUSD: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
},
[AavePools.secondary]: {
WETH: {
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
DAI: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
USDC: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '6',
},
USDT: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '6',
},
UNI_DAI_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6800',
liquidationThreshold: '7300',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_USDC_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6800',
liquidationThreshold: '7300',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_SETH_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '4800',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_LEND_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '5100',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_LINK_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6300',
liquidationThreshold: '6800',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
UNI_MKR_ETH: {
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.16).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '4800',
liquidationThreshold: '6600',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
},
},
},
pool
);
export const getFeeDistributionParamsCommon = (
receiver: tEthereumAddress
): iBasicDistributionParams => {
const receivers = [receiver, ZERO_ADDRESS];
const percentages = ['2000', '8000'];
return {
receivers,
percentages,
};
};
export const getATokenDomainSeparatorPerNetwork = (network: eEthereumNetwork): tEthereumAddress =>
getParamPerNetwork<tEthereumAddress>(
{
[eEthereumNetwork.coverage]:
'0x95b73a72c6ecf4ccbbba5178800023260bad8e75cdccdb8e4827a2977a37c820',
[eEthereumNetwork.buidlerevm]:
'0x76cbbf8aa4b11a7c207dd79ccf8c394f59475301598c9a083f8258b4fafcfa86',
[eEthereumNetwork.kovan]: '',
[eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '',
},
network
);

View File

@ -1,5 +1,5 @@
import {Contract, Signer, utils, ethers} from 'ethers';
import {CommonsConfig} from '../config/commons';
import {getDb, BRE} from './misc-utils';
import {
tEthereumAddress,
@ -9,9 +9,15 @@ import {
AavePools,
iParamsPerNetwork,
iParamsPerPool,
TokenContractId,
iMultiPoolsAssets,
IReserveParams,
ICommonConfiguration,
PoolConfiguration,
} from './types';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {MintableErc20} from '../types/MintableErc20';
import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
import {LendingPoolAddressesProviderRegistry} from '../types/LendingPoolAddressesProviderRegistry';
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
import {readArtifact} from '@nomiclabs/buidler/plugins';
@ -31,10 +37,20 @@ import BigNumber from 'bignumber.js';
import {Ierc20Detailed} from '../types/Ierc20Detailed';
import {StableDebtToken} from '../types/StableDebtToken';
import {VariableDebtToken} from '../types/VariableDebtToken';
import { ZERO_ADDRESS } from './constants';
import {MockContract} from 'ethereum-waffle';
import {getReservesConfigByPool} from './configuration';
import {verifyContract} from './etherscan-verification';
const {
ProtocolGlobalParams: {UsdAddress},
} = CommonsConfig;
export type MockTokenMap = {[symbol: string]: MintableERC20};
import {ZERO_ADDRESS} from './constants';
import {MockSwapAdapter} from '../types/MockSwapAdapter';
import {signTypedData_v4, TypedData} from 'eth-sig-util';
import {fromRpcSig, ECDSASignature} from 'ethereumjs-util';
import {SignerWithAddress} from '../test/helpers/make-suite';
export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => {
const currentNetwork = BRE.network.name;
@ -95,17 +111,38 @@ export const getContract = async <ContractType extends Contract>(
address: string
): Promise<ContractType> => (await BRE.ethers.getContractAt(contractName, address)) as ContractType;
export const deployLendingPoolAddressesProvider = async () =>
await deployContract<LendingPoolAddressesProvider>(eContractid.LendingPoolAddressesProvider, []);
export const deployLendingPoolAddressesProvider = async (verify?: boolean) => {
const instance = await deployContract<LendingPoolAddressesProvider>(
eContractid.LendingPoolAddressesProvider,
[]
);
if (verify) {
await verifyContract(eContractid.LendingPoolAddressesProvider, instance.address, []);
}
return instance;
};
export const deployLendingPoolAddressesProviderRegistry = async () =>
await deployContract<LendingPoolAddressesProviderRegistry>(
export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) => {
const instance = await deployContract<LendingPoolAddressesProviderRegistry>(
eContractid.LendingPoolAddressesProviderRegistry,
[]
);
if (verify) {
await verifyContract(eContractid.LendingPoolAddressesProviderRegistry, instance.address, []);
}
return instance;
};
export const deployLendingPoolConfigurator = async () =>
await deployContract<LendingPoolConfigurator>(eContractid.LendingPoolConfigurator, []);
export const deployLendingPoolConfigurator = async (verify?: boolean) => {
const instance = await deployContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator,
[]
);
if (verify) {
await verifyContract(eContractid.LendingPoolConfigurator, instance.address, []);
}
return instance;
};
const deployLibrary = async (libraryId: eContractid) => {
const factory = await BRE.ethers.getContractFactory(libraryId);
@ -161,151 +198,244 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
return factory;
};
export const deployLendingPool = async () => {
export const deployLendingPool = async (verify?: boolean) => {
const lendingPoolArtifact = await readArtifact(
BRE.config.paths.artifacts,
eContractid.LendingPool
);
const factory = await linkLibrariesToArtifact(lendingPoolArtifact);
const lendingPool = await factory.deploy();
return (await lendingPool.deployed()) as LendingPool;
const instance = (await lendingPool.deployed()) as LendingPool;
if (verify) {
await verifyContract(eContractid.LendingPool, instance.address, []);
}
return instance;
};
export const deployPriceOracle = async () =>
await deployContract<PriceOracle>(eContractid.PriceOracle, []);
export const deployPriceOracle = async (verify?: boolean) => {
const instance = await deployContract<PriceOracle>(eContractid.PriceOracle, []);
if (verify) {
await verifyContract(eContractid.PriceOracle, instance.address, []);
}
return instance;
};
export const deployMockAggregator = async (price: tStringTokenSmallUnits) =>
await deployContract<MockAggregator>(eContractid.MockAggregator, [price]);
export const deployLendingRateOracle = async (verify?: boolean) => {
const instance = await deployContract<LendingRateOracle>(eContractid.LendingRateOracle, []);
if (verify) {
await verifyContract(eContractid.LendingRateOracle, instance.address, []);
}
return instance;
};
export const deployChainlinkProxyPriceProvider = async ([
assetsAddresses,
sourcesAddresses,
fallbackOracleAddress,
]: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress]) =>
await deployContract<MockAggregator>(eContractid.ChainlinkProxyPriceProvider, [
assetsAddresses,
sourcesAddresses,
fallbackOracleAddress,
]);
export const deployMockAggregator = async (price: tStringTokenSmallUnits, verify?: boolean) => {
const args = [price];
const instance = await deployContract<MockAggregator>(eContractid.MockAggregator, args);
if (verify) {
await verifyContract(eContractid.MockAggregator, instance.address, args);
}
return instance;
};
export const deployLendingRateOracle = async () =>
await deployContract<LendingRateOracle>(eContractid.LendingRateOracle, []);
export const deployChainlinkProxyPriceProvider = async (
[assetsAddresses, sourcesAddresses, fallbackOracleAddress]: [
tEthereumAddress[],
tEthereumAddress[],
tEthereumAddress
],
verify?: boolean
) => {
const args = [assetsAddresses, sourcesAddresses, fallbackOracleAddress];
const instance = await deployContract<MockAggregator>(
eContractid.ChainlinkProxyPriceProvider,
args
);
if (verify) {
await verifyContract(eContractid.MockAggregator, instance.address, args);
}
return instance;
};
export const deployLendingPoolCollateralManager = async () => {
export const getChainlingProxyPriceProvider = async (address?: tEthereumAddress) =>
await getContract<MockAggregator>(
eContractid.ChainlinkProxyPriceProvider,
address ||
(await getDb().get(`${eContractid.ChainlinkProxyPriceProvider}.${BRE.network.name}`).value())
.address
);
export const deployLendingPoolCollateralManager = async (verify?: boolean) => {
const collateralManagerArtifact = await readArtifact(
BRE.config.paths.artifacts,
eContractid.LendingPoolCollateralManager
);
const factory = await linkLibrariesToArtifact(collateralManagerArtifact);
const args: string[] = [];
const collateralManager = await factory.deploy(args);
const instance = (await collateralManager.deployed()) as LendingPoolCollateralManager;
const collateralManager = await factory.deploy();
return (await collateralManager.deployed()) as LendingPoolCollateralManager;
if (verify) {
await verifyContract(eContractid.LendingPoolCollateralManager, instance.address, args);
}
return instance;
};
export const deployInitializableAdminUpgradeabilityProxy = async () =>
await deployContract<InitializableAdminUpgradeabilityProxy>(
export const deployInitializableAdminUpgradeabilityProxy = async (verify?: boolean) => {
const instance = await deployContract<InitializableAdminUpgradeabilityProxy>(
eContractid.InitializableAdminUpgradeabilityProxy,
[]
);
if (verify) {
await verifyContract(eContractid.InitializableAdminUpgradeabilityProxy, instance.address, []);
}
return instance;
};
export const deployMockFlashLoanReceiver = async (addressesProvider: tEthereumAddress) =>
await deployContract<MockFlashLoanReceiver>(eContractid.MockFlashLoanReceiver, [
addressesProvider,
]);
export const deployMockFlashLoanReceiver = async (
addressesProvider: tEthereumAddress,
verify?: boolean
) => {
const args = [addressesProvider];
const instance = await deployContract<MockFlashLoanReceiver>(
eContractid.MockFlashLoanReceiver,
args
);
if (verify) {
await verifyContract(eContractid.MockFlashLoanReceiver, instance.address, args);
}
return instance;
};
export const deployWalletBalancerProvider = async (
addressesProvider: tEthereumAddress,
verify?: boolean
) => {
const args = [addressesProvider];
const instance = await deployContract<WalletBalanceProvider>(
eContractid.WalletBalanceProvider,
args
);
if (verify) {
await verifyContract(eContractid.WalletBalanceProvider, instance.address, args);
}
return instance;
};
export const deployMockSwapAdapter = async (addressesProvider: tEthereumAddress) =>
await deployContract<MockSwapAdapter>(eContractid.MockSwapAdapter, [addressesProvider]);
export const deployWalletBalancerProvider = async (addressesProvider: tEthereumAddress) =>
await deployContract<WalletBalanceProvider>(eContractid.WalletBalanceProvider, [
addressesProvider,
]);
export const deployAaveProtocolTestHelpers = async (addressesProvider: tEthereumAddress) =>
await deployContract<AaveProtocolTestHelpers>(eContractid.AaveProtocolTestHelpers, [
addressesProvider,
]);
export const deployMintableErc20 = async ([name, symbol, decimals]: [string, string, number]) =>
await deployContract<MintableErc20>(eContractid.MintableERC20, [name, symbol, decimals]);
export const deployDefaultReserveInterestRateStrategy = async ([
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]: [tEthereumAddress, string, string, string, string, string]) =>
await deployContract<DefaultReserveInterestRateStrategy>(
eContractid.DefaultReserveInterestRateStrategy,
[
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]
export const deployAaveProtocolTestHelpers = async (
addressesProvider: tEthereumAddress,
verify?: boolean
) => {
const args = [addressesProvider];
const instance = await deployContract<AaveProtocolTestHelpers>(
eContractid.AaveProtocolTestHelpers,
args
);
export const deployStableDebtToken = async ([
name,
symbol,
underlyingAsset,
poolAddress,
incentivesController,
]: [string, string, tEthereumAddress, tEthereumAddress, tEthereumAddress]) => {
const token = await deployContract<StableDebtToken>(eContractid.StableDebtToken, [
poolAddress,
underlyingAsset,
name,
symbol,
incentivesController,
]);
return token;
if (verify) {
await verifyContract(eContractid.AaveProtocolTestHelpers, instance.address, args);
}
return instance;
};
export const deployVariableDebtToken = async ([
name,
symbol,
underlyingAsset,
poolAddress,
incentivesController,
]: [string, string, tEthereumAddress, tEthereumAddress, tEthereumAddress]) => {
const token = await deployContract<VariableDebtToken>(eContractid.VariableDebtToken, [
poolAddress,
underlyingAsset,
name,
symbol,
incentivesController,
]);
export const deployMintableERC20 = async ([name, symbol, decimals]: [string, string, number]) =>
await deployContract<MintableERC20>(eContractid.MintableERC20, [name, symbol, decimals]);
return token;
export const deployDefaultReserveInterestRateStrategy = async (
[
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]: [tEthereumAddress, string, string, string, string, string],
verify: boolean
) => {
const id = eContractid.DefaultReserveInterestRateStrategy;
const args = [
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
];
const instance = await deployContract<DefaultReserveInterestRateStrategy>(id, args);
if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
};
export const deployGenericAToken = async ([
poolAddress,
underlyingAssetAddress,
reserveTreasuryAddress,
name,
symbol,
incentivesController,
]: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress]) => {
const token = await deployContract<AToken>(eContractid.AToken, [
export const deployStableDebtToken = async (
[name, symbol, underlyingAsset, poolAddress, incentivesController]: [
string,
string,
tEthereumAddress,
tEthereumAddress,
tEthereumAddress
],
verify: boolean
) => {
const id = eContractid.StableDebtToken;
const args = [poolAddress, underlyingAsset, name, symbol, incentivesController];
const instance = await deployContract<StableDebtToken>(id, args);
if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
};
export const deployVariableDebtToken = async (
[name, symbol, underlyingAsset, poolAddress, incentivesController]: [
string,
string,
tEthereumAddress,
tEthereumAddress,
tEthereumAddress
],
verify: boolean
) => {
const id = eContractid.VariableDebtToken;
const args = [poolAddress, underlyingAsset, name, symbol, incentivesController];
const instance = await deployContract<VariableDebtToken>(id, args);
if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
};
export const deployGenericAToken = async (
[poolAddress, underlyingAssetAddress, name, symbol, incentivesController]: [
tEthereumAddress,
tEthereumAddress,
string,
string,
tEthereumAddress
],
verify: boolean
) => {
const id = eContractid.AToken;
const args = [
poolAddress,
underlyingAssetAddress,
reserveTreasuryAddress,
ZERO_ADDRESS,
name,
symbol,
incentivesController,
]);
];
const instance = await deployContract<AToken>(id, args);
return token;
if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
};
export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress) => {
@ -317,15 +447,6 @@ export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress
);
};
export const getLendingPoolAddressesProviderRegistry = async (address?: tEthereumAddress) => {
return await getContract<LendingPoolAddressesProviderRegistry>(
eContractid.LendingPoolAddressesProviderRegistry,
address ||
(await getDb().get(`${eContractid.LendingPoolAddressesProviderRegistry}.${BRE.network.name}`).value())
.address
);
};
export const getLendingPoolConfiguratorProxy = async (address?: tEthereumAddress) => {
return await getContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator,
@ -368,20 +489,21 @@ export const getAToken = async (address?: tEthereumAddress) => {
export const getStableDebtToken = async (address?: tEthereumAddress) => {
return await getContract<AToken>(
eContractid.StableDebtToken,
address || (await getDb().get(`${eContractid.StableDebtToken}.${BRE.network.name}`).value()).address
address ||
(await getDb().get(`${eContractid.StableDebtToken}.${BRE.network.name}`).value()).address
);
};
export const getVariableDebtToken = async (address?: tEthereumAddress) => {
return await getContract<AToken>(
eContractid.VariableDebtToken,
address || (await getDb().get(`${eContractid.VariableDebtToken}.${BRE.network.name}`).value()).address
address ||
(await getDb().get(`${eContractid.VariableDebtToken}.${BRE.network.name}`).value()).address
);
};
export const getMintableErc20 = async (address: tEthereumAddress) => {
return await getContract<MintableErc20>(
return await getContract<MintableERC20>(
eContractid.MintableERC20,
address ||
(await getDb().get(`${eContractid.MintableERC20}.${BRE.network.name}`).value()).address
@ -511,6 +633,255 @@ export const convertToCurrencyUnits = async (tokenAddress: string, amount: strin
return amountInCurrencyUnits.toFixed();
};
export const deployAllMockTokens = async (verify?: boolean) => {
const tokens: {[symbol: string]: MockContract | MintableERC20} = {};
const protoConfigData = getReservesConfigByPool(AavePools.proto);
const secondaryConfigData = getReservesConfigByPool(AavePools.secondary);
for (const tokenSymbol of Object.keys(TokenContractId)) {
let decimals = 18;
let configData = (<any>protoConfigData)[tokenSymbol];
if (!configData) {
configData = (<any>secondaryConfigData)[tokenSymbol];
}
if (!configData) {
decimals = 18;
}
tokens[tokenSymbol] = await deployMintableERC20([
tokenSymbol,
tokenSymbol,
configData ? configData.reserveDecimals : 18,
]);
await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
if (verify) {
await verifyContract(eContractid.MintableERC20, tokens[tokenSymbol].address, []);
}
}
return tokens;
};
export const deployMockTokens = async (config: PoolConfiguration, verify?: boolean) => {
const tokens: {[symbol: string]: MockContract | MintableERC20} = {};
const defaultDecimals = 18;
const configData = config.ReservesConfig;
for (const tokenSymbol of Object.keys(config.ReserveSymbols)) {
tokens[tokenSymbol] = await deployMintableERC20([
tokenSymbol,
tokenSymbol,
Number(configData[tokenSymbol as keyof iMultiPoolsAssets<IReserveParams>].reserveDecimals) ||
defaultDecimals,
]);
await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
if (verify) {
await verifyContract(eContractid.MintableERC20, tokens[tokenSymbol].address, []);
}
}
return tokens;
};
export const getMockedTokens = async (config: PoolConfiguration) => {
const tokenSymbols = config.ReserveSymbols;
const db = getDb();
const tokens: MockTokenMap = await tokenSymbols.reduce<Promise<MockTokenMap>>(
async (acc, tokenSymbol) => {
const accumulator = await acc;
const address = db.get(`${tokenSymbol.toUpperCase()}.${BRE.network.name}`).value().address;
accumulator[tokenSymbol] = await getContract<MintableERC20>(
eContractid.MintableERC20,
address
);
return Promise.resolve(acc);
},
Promise.resolve({})
);
return tokens;
};
export const getAllMockedTokens = async () => {
const db = getDb();
const tokens: MockTokenMap = await Object.keys(TokenContractId).reduce<Promise<MockTokenMap>>(
async (acc, tokenSymbol) => {
const accumulator = await acc;
const address = db.get(`${tokenSymbol.toUpperCase()}.${BRE.network.name}`).value().address;
accumulator[tokenSymbol] = await getContract<MintableERC20>(
eContractid.MintableERC20,
address
);
return Promise.resolve(acc);
},
Promise.resolve({})
);
return tokens;
};
export const getPairsTokenAggregator = (
allAssetsAddresses: {
[tokenSymbol: string]: tEthereumAddress;
},
aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
): [string[], string[]] => {
const {ETH, USD, WETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
if (tokenSymbol !== 'WETH' && tokenSymbol !== 'ETH') {
const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
(value) => value === tokenSymbol
);
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
string,
tEthereumAddress
][])[aggregatorAddressIndex];
return [tokenAddress, aggregatorAddress];
}
}) as [string, string][];
const mappedPairs = pairs.map(([asset]) => asset);
const mappedAggregators = pairs.map(([, source]) => source);
return [mappedPairs, mappedAggregators];
};
export const initReserves = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
lendingPoolAddressesProvider: LendingPoolAddressesProvider,
lendingPool: LendingPool,
helpers: AaveProtocolTestHelpers,
lendingPoolConfigurator: LendingPoolConfigurator,
aavePool: AavePools,
incentivesController: tEthereumAddress,
verify: boolean
) => {
if (aavePool !== AavePools.proto && aavePool !== AavePools.secondary) {
console.log(`Invalid Aave pool ${aavePool}`);
process.exit(1);
}
for (let [assetSymbol, {reserveDecimals}] of Object.entries(reservesParams) as [
string,
IReserveParams
][]) {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
assetAddressIndex
];
const {isActive: reserveInitialized} = await helpers.getReserveConfigurationData(tokenAddress);
if (reserveInitialized) {
console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
continue;
}
try {
const reserveParamIndex = Object.keys(reservesParams).findIndex(
(value) => value === assetSymbol
);
const [
,
{
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
},
] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
console.log('deploy def reserve');
const rateStrategyContract = await deployDefaultReserveInterestRateStrategy(
[
lendingPoolAddressesProvider.address,
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
],
verify
);
console.log('deploy stable deb totken ', assetSymbol);
const stableDebtToken = await deployStableDebtToken(
[
`Aave stable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`stableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
tokenAddress,
lendingPool.address,
incentivesController,
],
verify
);
console.log('deploy var deb totken ', assetSymbol);
const variableDebtToken = await deployVariableDebtToken(
[
`Aave variable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`variableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
tokenAddress,
lendingPool.address,
incentivesController,
],
verify
);
console.log('deploy a token ', assetSymbol);
const aToken = await deployGenericAToken(
[
lendingPool.address,
tokenAddress,
`Aave interest bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`a${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
incentivesController,
],
verify
);
if (process.env.POOL === AavePools.secondary) {
if (assetSymbol.search('UNI') === -1) {
assetSymbol = `Uni${assetSymbol}`;
} else {
assetSymbol = assetSymbol.replace(/_/g, '').replace('UNI', 'Uni');
}
}
console.log('init reserve currency ', assetSymbol);
await lendingPoolConfigurator.initReserve(
tokenAddress,
aToken.address,
stableDebtToken.address,
variableDebtToken.address,
reserveDecimals,
rateStrategyContract.address
);
} catch (e) {
console.log(`Reserve initialization for ${assetSymbol} failed with error ${e}. Skipped.`);
}
}
};
export const getLendingPoolAddressesProviderRegistry = async (address?: tEthereumAddress) => {
return await getContract<LendingPoolAddressesProviderRegistry>(
eContractid.LendingPoolAddressesProviderRegistry,
address ||
(
await getDb()
.get(`${eContractid.LendingPoolAddressesProviderRegistry}.${BRE.network.name}`)
.value()
).address
);
};
export const buildPermitParams = (
chainId: number,
token: tEthereumAddress,

View File

@ -0,0 +1,104 @@
import {exit} from 'process';
import fs from 'fs';
import {file} from 'tmp-promise';
import {BRE} from './misc-utils';
export const SUPPORTED_ETHERSCAN_NETWORKS = ['main', 'ropsten', 'kovan'];
export const getEtherscanPath = async (contractName: string) => {
const compilerInput = await BRE.run('compile:get-compiler-input');
const paths = Object.keys(compilerInput.sources);
const path = paths.find((p) => p.includes(contractName));
if (!path) {
throw new Error(
`Contract path not found for ${contractName}. Check if smart contract file is equal to contractName input.`
);
}
return `${path}:${contractName}`;
};
function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
export const verifyContract = async (
contractName: string,
address: string,
constructorArguments: (string | string[])[],
libraries?: string
) => {
const currentNetwork = BRE.network.name;
if (!process.env.ETHERSCAN_KEY) {
throw Error('Missing process.env.ETHERSCAN_KEY.');
}
if (!SUPPORTED_ETHERSCAN_NETWORKS.includes(currentNetwork)) {
throw Error(
`Current network ${currentNetwork} not supported. Please change to one of the next networks: ${SUPPORTED_ETHERSCAN_NETWORKS.toString()}`
);
}
const etherscanPath = await getEtherscanPath(contractName);
try {
console.log(
'[ETHERSCAN][WARNING] Delaying Etherscan verification due their API can not find newly deployed contracts'
);
const msDelay = 3000;
const times = 60;
// Write a temporal file to host complex parameters for buidler-etherscan https://github.com/nomiclabs/buidler/tree/development/packages/buidler-etherscan#complex-arguments
const {fd, path, cleanup} = await file({
prefix: 'verify-params-',
postfix: '.js',
});
fs.writeSync(fd, `module.exports = ${JSON.stringify([...constructorArguments])};`);
const params = {
contractName: etherscanPath,
address: address,
libraries,
constructorArgs: path,
};
await runTaskWithRetry('verify', params, times, msDelay, cleanup);
} catch (error) {}
};
export const runTaskWithRetry = async (
task: string,
params: any,
times: number,
msDelay: number,
cleanup: () => void
) => {
let counter = times;
await delay(msDelay);
try {
if (times) {
await BRE.run(task, params);
cleanup();
} else {
cleanup();
console.error('[ERROR] Errors after all the retries, check the logs for more information.');
}
} catch (error) {
counter--;
console.info(`[INFO] Retrying attemps: ${counter}.`);
console.error('[ERROR]', error.message);
await runTaskWithRetry(task, params, counter, msDelay, cleanup);
}
};
export const checkVerification = () => {
const currentNetwork = BRE.network.name;
if (!process.env.ETHERSCAN_KEY) {
console.error('Missing process.env.ETHERSCAN_KEY.');
exit(3);
}
if (!SUPPORTED_ETHERSCAN_NETWORKS.includes(currentNetwork)) {
console.error(
`Current network ${currentNetwork} not supported. Please change to one of the next networks: ${SUPPORTED_ETHERSCAN_NETWORKS.toString()}`
);
exit(5);
}
};

81
helpers/init-helpers.ts Normal file
View File

@ -0,0 +1,81 @@
import {iMultiPoolsAssets, IReserveParams, tEthereumAddress} from './types';
import {LendingPool} from '../types/LendingPool';
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
export const enableReservesToBorrow = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
helpers: AaveProtocolTestHelpers,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries(
reservesParams
) as [string, IReserveParams][]) {
if (!borrowingEnabled) continue;
try {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
assetAddressIndex
];
const {borrowingEnabled: borrowingAlreadyEnabled} = await helpers.getReserveConfigurationData(
tokenAddress
);
if (borrowingAlreadyEnabled) {
console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`);
continue;
}
await lendingPoolConfigurator.enableBorrowingOnReserve(tokenAddress, stableBorrowRateEnabled);
} catch (e) {
console.log(
`Enabling reserve for borrowings for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
export const enableReservesAsCollateral = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
helpers: AaveProtocolTestHelpers,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [
assetSymbol,
{baseLTVAsCollateral, liquidationBonus, liquidationThreshold},
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (baseLTVAsCollateral === '-1') continue;
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
);
if (alreadyEnabled) {
console.log(`Reserve ${assetSymbol} is already enabled as collateral, skipping`);
continue;
}
try {
await lendingPoolConfigurator.enableReserveAsCollateral(
tokenAddress,
baseLTVAsCollateral,
liquidationThreshold,
liquidationBonus
);
} catch (e) {
console.log(
`Enabling reserve as collateral for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};

View File

@ -3,7 +3,7 @@ import BN = require('bn.js');
import low from 'lowdb';
import FileSync from 'lowdb/adapters/FileSync';
import {WAD} from './constants';
import {Wallet} from 'ethers';
import {Wallet, ContractTransaction} from 'ethers';
import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types';
export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed();
@ -40,3 +40,13 @@ export const increaseTime = async (secondsToIncrease: number) => {
await BRE.ethers.provider.send('evm_increaseTime', [secondsToIncrease]);
await BRE.ethers.provider.send('evm_mine', []);
};
export const waitForTx = async (tx: ContractTransaction) => await tx.wait();
export const filterMapBy = (raw: {[key: string]: any}, fn: (key: string) => boolean) =>
Object.keys(raw)
.filter(fn)
.reduce<{[key: string]: any}>((obj, key) => {
obj[key] = raw[key];
return obj;
}, {});

22
helpers/mock-helpers.ts Normal file
View File

@ -0,0 +1,22 @@
import {tEthereumAddress} from './types';
import {MockAggregator} from '../types/MockAggregator';
import {MockTokenMap} from './contracts-helpers';
export const getAllTokenAddresses = (mockTokens: MockTokenMap) =>
Object.entries(mockTokens).reduce(
(accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, tokenContract]) => ({
...accum,
[tokenSymbol]: tokenContract.address,
}),
{}
);
export const getAllAggregatorsAddresses = (mockAggregators: {
[tokenSymbol: string]: MockAggregator;
}) =>
Object.entries(mockAggregators).reduce(
(accum: {[tokenSymbol: string]: tEthereumAddress}, [tokenSymbol, aggregator]) => ({
...accum,
[tokenSymbol]: aggregator.address,
}),
{}
);

View File

@ -0,0 +1,99 @@
import {
tEthereumAddress,
iMultiPoolsAssets,
IMarketRates,
iAssetBase,
iAssetAggregatorBase,
eContractid,
SymbolMap,
} from './types';
import {LendingRateOracle} from '../types/LendingRateOracle';
import {PriceOracle} from '../types/PriceOracle';
import {MockAggregator} from '../types/MockAggregator';
import {deployMockAggregator, getContract, MockTokenMap} from './contracts-helpers';
import {waitForTx} from './misc-utils';
import {verifyContract} from './etherscan-verification';
export const setInitialMarketRatesInRatesOracle = async (
marketRates: iMultiPoolsAssets<IMarketRates>,
assetsAddresses: {[x: string]: tEthereumAddress},
lendingRateOracleInstance: LendingRateOracle
) => {
for (const [assetSymbol, {borrowRate}] of Object.entries(marketRates) as [
string,
IMarketRates
][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
assetAddressIndex
];
await lendingRateOracleInstance.setMarketBorrowRate(assetAddress, borrowRate);
console.log('added Market Borrow Rate for: ', assetSymbol);
}
};
export const setInitialAssetPricesInOracle = async (
prices: iAssetBase<tEthereumAddress>,
assetsAddresses: iAssetBase<tEthereumAddress>,
priceOracleInstance: PriceOracle
) => {
for (const [assetSymbol, price] of Object.entries(prices) as [string, string][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
assetAddressIndex
];
await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
}
};
export const setAssetPricesInOracle = async (
prices: SymbolMap<string>,
assetsAddresses: SymbolMap<tEthereumAddress>,
priceOracleInstance: PriceOracle
) => {
for (const [assetSymbol, price] of Object.entries(prices) as [string, string][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
assetAddressIndex
];
await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
}
};
export const deployMockAggregators = async (initialPrices: SymbolMap<string>, verify?: boolean) => {
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
for (const tokenContractName of Object.keys(initialPrices)) {
if (tokenContractName !== 'ETH') {
const priceIndex = Object.keys(initialPrices).findIndex(
(value) => value === tokenContractName
);
const [, price] = (Object.entries(initialPrices) as [string, string][])[priceIndex];
aggregators[tokenContractName] = await deployMockAggregator(price, verify);
}
}
return aggregators;
};
export const deployAllMockAggregators = async (
initialPrices: iAssetAggregatorBase<string>,
verify?: boolean
) => {
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
for (const tokenContractName of Object.keys(initialPrices)) {
if (tokenContractName !== 'ETH') {
const priceIndex = Object.keys(initialPrices).findIndex(
(value) => value === tokenContractName
);
const [, price] = (Object.entries(initialPrices) as [string, string][])[priceIndex];
aggregators[tokenContractName] = await deployMockAggregator(price, verify);
}
}
return aggregators;
};

View File

@ -1,4 +1,9 @@
import BigNumber from 'bignumber.js';
import {MockTokenMap} from './contracts-helpers';
export interface SymbolMap<T> {
[symbol: string]: T;
}
export enum eEthereumNetwork {
buidlerevm = 'buidlerevm',
@ -8,6 +13,12 @@ export enum eEthereumNetwork {
coverage = 'coverage',
}
export enum EthereumNetworkNames {
kovan = 'kovan',
ropsten = 'ropsten',
main = 'main',
}
export enum AavePools {
proto = 'proto',
secondary = 'secondary',
@ -43,6 +54,8 @@ export enum eContractid {
IERC20Detailed = 'IERC20Detailed',
StableDebtToken = 'StableDebtToken',
VariableDebtToken = 'VariableDebtToken',
FeeProvider = 'FeeProvider',
TokenDistributor = 'TokenDistributor',
}
export enum ProtocolErrors {
@ -77,6 +90,7 @@ export enum ProtocolErrors {
REQUESTED_AMOUNT_TOO_SMALL = '25', // 'The requested amount is too small for a FlashLoan.'
INCONSISTENT_PROTOCOL_ACTUAL_BALANCE = '26', // 'The actual balance of the protocol is inconsistent'
CALLER_NOT_LENDING_POOL_CONFIGURATOR = '27', // 'The actual balance of the protocol is inconsistent'
INVALID_FLASH_LOAN_EXECUTOR_RETURN = '60', // The flash loan received returned 0 (EOA)
// require error messages - aToken
CALLER_MUST_BE_LENDING_POOL = '28', // 'The caller of this function must be a lending pool'
@ -119,6 +133,9 @@ export type tBigNumberTokenBigUnits = BigNumber;
export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI
export type tBigNumberTokenSmallUnits = BigNumber;
export interface iAssetCommon<T> {
[key: string]: T;
}
export interface iAssetBase<T> {
WETH: T;
DAI: T;
@ -154,7 +171,6 @@ export type iAssetsWithoutUSD<T> = Omit<iAssetBase<T>, 'USD'>;
export type iAavePoolAssets<T> = Pick<
iAssetsWithoutUSD<T>,
| 'WETH'
| 'DAI'
| 'TUSD'
| 'USDC'
@ -193,7 +209,7 @@ export type iAaveSecondPoolAssets<T> = Pick<
| 'UNI_LINK_ETH'
>;
export type iMultiPoolsAssets<T> = iAavePoolAssets<T> | iAaveSecondPoolAssets<T>;
export type iMultiPoolsAssets<T> = iAssetCommon<T> | iAavePoolAssets<T> | iAaveSecondPoolAssets<T>;
export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, 'ETH'>;
@ -271,3 +287,75 @@ export enum RateMode {
Stable = '1',
Variable = '2',
}
export interface ObjectString {
[key: string]: string;
}
export enum EthereumNetwork {
kovan = 'kovan',
ropsten = 'ropsten',
development = 'development',
main = 'main',
coverage = 'soliditycoverage',
}
export interface IProtocolGlobalConfig {
OptimalUtilizationRate: BigNumber;
ExcessUtilizationRate: BigNumber;
ApprovalAmountLendingPoolCore: string;
TokenDistributorPercentageBase: string;
MockUsdPriceInWei: string;
EthereumAddress: tEthereumAddress;
UsdAddress: tEthereumAddress;
NilAddress: tEthereumAddress;
OneAddress: tEthereumAddress;
AaveReferral: string;
}
export interface IMocksConfig {
ChainlinkAggregatorPrices: iAssetBase<string>;
AllAssetsInitialPrices: iAssetBase<string>;
}
export interface ILendingRateOracleRatesCommon {
[token: string]: ILendingRate;
}
export interface ILendingRate {
borrowRate: string;
}
export interface ICommonConfiguration {
ConfigName: string;
ProviderId: number;
ReserveSymbols: string[];
ProtocolGlobalParams: IProtocolGlobalConfig;
Mocks: IMocksConfig;
ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
TokenDistributor: iParamsPerNetwork<tEthereumAddress>;
ChainlinkProxyPriceProvider: iParamsPerNetwork<tEthereumAddress>;
FallbackOracle: iParamsPerNetwork<tEthereumAddress>;
ChainlinkAggregator: iParamsPerNetwork<ITokenAddress>;
AaveAdmin: iParamsPerNetwork<tEthereumAddress | undefined>;
AaveAdminIndex: number;
ReserveAssets: iParamsPerNetwork<SymbolMap<tEthereumAddress>>;
ReservesConfig: iMultiPoolsAssets<IReserveParams>;
ATokenDomainSeparator: iParamsPerNetwork<string>;
}
export interface IAaveConfiguration extends ICommonConfiguration {
ReservesConfig: iAavePoolAssets<IReserveParams>;
}
export interface IUniswapConfiguration extends ICommonConfiguration {
ReservesConfig: iAaveSecondPoolAssets<IReserveParams>;
}
export interface ITokenAddress {
[token: string]: tEthereumAddress;
}
export type PoolConfiguration = ICommonConfiguration | IAaveConfiguration | IUniswapConfiguration;

7550
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,14 +5,30 @@
"scripts": {
"run-env": "npm i && tail -f /dev/null",
"buidler": "buidler",
"buidler-kovan": "buidler --network kovan",
"buidler-ropsten": "buidler --network ropsten",
"buidler-main": "buidler --network main",
"buidler:kovan": "buidler --network kovan",
"buidler:ropsten": "buidler--network ropsten",
"buidler:main": "buidler --network main",
"buidler help": "buidler help",
"compile": "buidler compile",
"compile": "SKIP_LOAD=true buidler compile",
"types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
"test": "buidler test",
"test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts",
"aave:evm:dev:migration": "buidler aave:dev",
"aave:evm:full:migration": "buidler aave:full",
"aave:kovan:dev:migration": "npm run buidler:kovan -- aave:dev --verify",
"aave:kovan:full:migration": "npm run buidler:kovan -- aave:full --verify",
"aave:ropsten:dev:migration": "npm run buidler:ropsten -- aave:dev --verify",
"aave:ropsten:full:migration": "npm run buidler:ropsten -- aave:full --verify",
"aave:main:dev:migration": "npm run buidler:main -- aave:dev --verify",
"aave:main:full:migration": "npm run buidler:main -- aave:full --verify",
"uniswap:evm:dev:migration": "buidler uniswap:dev",
"uniswap:evm:full:migration": "buidler uniswap:full --verify",
"uniswap:kovan:dev:migration": "npm run buidler:kovan -- uniswap:dev --verify",
"uniswap:kovan:full:migration": "npm run buidler:kovan -- uniswap:full --verify",
"uniswap:ropsten:dev:migration": "npm run buidler:ropsten -- uniswap:dev --verify",
"uniswap:ropsten:full:migration": "npm run buidler:ropsten -- uniswap:full --verify",
"uniswap:main:dev:migration": "npm run buidler:main -- uniswap:dev --verify",
"uniswap:main:full:migration": "npm run buidler:main -- uniswap:full --verify",
"test-repay-with-collateral": "buidler test test/__setup.spec.ts test/repay-with-collateral.spec.ts",
"test-liquidate-with-collateral": "buidler test test/__setup.spec.ts test/flash-liquidation-with-collateral.spec.ts",
"test-transfers": "buidler test test/__setup.spec.ts test/atoken-transfer.spec.ts",
@ -28,13 +44,13 @@
"ci:clean": "rm -rf ./artifacts ./cache ./types"
},
"devDependencies": {
"@nomiclabs/buidler": "1.4.4",
"@nomiclabs/buidler": "^1.4.7",
"@nomiclabs/buidler-ethers": "2.0.0",
"@nomiclabs/buidler-etherscan": "1.3.3",
"@nomiclabs/buidler-etherscan": "^2.1.0",
"@nomiclabs/buidler-waffle": "2.0.0",
"@openzeppelin/contracts": "3.1.0",
"@typechain/ethers-v5": "^1.0.0",
"@typechain/ethers-v4": "1.0.0",
"@typechain/ethers-v5": "^1.0.0",
"@typechain/truffle-v4": "2.0.2",
"@typechain/truffle-v5": "2.0.2",
"@typechain/web3-v1": "1.0.0",
@ -48,7 +64,9 @@
"chai": "4.2.0",
"chai-bignumber": "3.0.0",
"chai-bn": "^0.2.1",
"eth-sig-util": "2.5.3",
"ethereum-waffle": "3.0.2",
"ethereumjs-util": "7.0.2",
"ethers": "5.0.8",
"husky": "^4.2.5",
"lowdb": "1.0.0",
@ -62,9 +80,7 @@
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.3.0",
"typechain": "2.0.0",
"typescript": "3.9.3",
"eth-sig-util": "2.5.3",
"ethereumjs-util": "7.0.2"
"typescript": "3.9.3"
},
"husky": {
"hooks": {
@ -86,5 +102,8 @@
"email": "andrey@aave.com"
}
],
"license": "AGPLv3"
"license": "AGPLv3",
"dependencies": {
"tmp-promise": "^3.0.2"
}
}

View File

@ -0,0 +1,8 @@
import {task} from '@nomiclabs/buidler/config';
import {deployAllMockTokens} from '../../helpers/contracts-helpers';
task('dev:deploy-mock-tokens', 'Deploy mock tokens for dev enviroment')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
await localBRE.run('set-bre');
await deployAllMockTokens(verify);
});

View File

@ -0,0 +1,25 @@
import {task} from '@nomiclabs/buidler/config';
import {
deployLendingPoolAddressesProvider,
deployLendingPoolAddressesProviderRegistry,
} from '../../helpers/contracts-helpers';
import {waitForTx} from '../../helpers/misc-utils';
task(
'dev:deploy-address-provider',
'Deploy address provider, registry and fee provider for dev enviroment'
)
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
await localBRE.run('set-bre');
const admin = await (await localBRE.ethers.getSigners())[0].getAddress();
const addressesProvider = await deployLendingPoolAddressesProvider(verify);
await waitForTx(await addressesProvider.setAaveAdmin(admin));
const addressesProviderRegistry = await deployLendingPoolAddressesProviderRegistry(verify);
await waitForTx(
await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 0)
);
});

View File

@ -0,0 +1,44 @@
import {task} from '@nomiclabs/buidler/config';
import {
deployLendingPool,
getLendingPoolAddressesProvider,
getLendingPool,
insertContractAddressInDb,
deployLendingPoolConfigurator,
getLendingPoolConfiguratorProxy,
} from '../../helpers/contracts-helpers';
import {eContractid} from '../../helpers/types';
import {waitForTx} from '../../helpers/misc-utils';
task('dev:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
await localBRE.run('set-bre');
const addressesProvider = await getLendingPoolAddressesProvider();
const lendingPoolImpl = await deployLendingPool(verify);
// Set lending pool impl to Address Provider
await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
const address = await addressesProvider.getLendingPool();
const lendingPoolProxy = await getLendingPool(address);
await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
// Set lending pool conf impl to Address Provider
await waitForTx(
await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
);
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
await addressesProvider.getLendingPoolConfigurator()
);
await insertContractAddressInDb(
eContractid.LendingPoolConfigurator,
lendingPoolConfiguratorProxy.address
);
});

74
tasks/dev/4_oracles.ts Normal file
View File

@ -0,0 +1,74 @@
import {task} from '@nomiclabs/buidler/config';
import {
getLendingPoolAddressesProvider,
deployPriceOracle,
getMockedTokens,
getPairsTokenAggregator,
deployChainlinkProxyPriceProvider,
deployLendingRateOracle,
getAllMockedTokens,
} from '../../helpers/contracts-helpers';
import {
setInitialAssetPricesInOracle,
setInitialMarketRatesInRatesOracle,
deployAllMockAggregators,
} from '../../helpers/oracles-helpers';
import {ICommonConfiguration, iAssetBase, TokenContractId} from '../../helpers/types';
import {waitForTx} from '../../helpers/misc-utils';
import {getAllAggregatorsAddresses, getAllTokenAddresses} from '../../helpers/mock-helpers';
import {ConfigNames, loadPoolConfig} from '../../helpers/configuration';
task('dev:deploy-oracles', 'Deploy oracles for dev enviroment')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({verify, pool}, localBRE) => {
await localBRE.run('set-bre');
const poolConfig = loadPoolConfig(pool);
const {
Mocks: {ChainlinkAggregatorPrices, AllAssetsInitialPrices},
ProtocolGlobalParams: {UsdAddress, MockUsdPriceInWei},
LendingRateOracleRatesCommon,
} = poolConfig as ICommonConfiguration;
const defaultTokenList = {
...Object.fromEntries(Object.keys(TokenContractId).map((symbol) => [symbol, ''])),
USD: UsdAddress,
} as iAssetBase<string>;
const mockTokens = await getAllMockedTokens();
const mockTokensAddress = Object.keys(mockTokens).reduce<iAssetBase<string>>((prev, curr) => {
prev[curr as keyof iAssetBase<string>] = mockTokens[curr].address;
return prev;
}, defaultTokenList);
const addressesProvider = await getLendingPoolAddressesProvider();
const fallbackOracle = await deployPriceOracle(verify);
await waitForTx(await fallbackOracle.setEthUsdPrice(MockUsdPriceInWei));
await setInitialAssetPricesInOracle(AllAssetsInitialPrices, mockTokensAddress, fallbackOracle);
const mockAggregators = await deployAllMockAggregators(ChainlinkAggregatorPrices, verify);
const allTokenAddresses = getAllTokenAddresses(mockTokens);
const allAggregatorsAddresses = getAllAggregatorsAddresses(mockAggregators);
const [tokens, aggregators] = getPairsTokenAggregator(
allTokenAddresses,
allAggregatorsAddresses
);
await deployChainlinkProxyPriceProvider([tokens, aggregators, fallbackOracle.address], verify);
await waitForTx(await addressesProvider.setPriceOracle(fallbackOracle.address));
const lendingRateOracle = await deployLendingRateOracle(verify);
await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
const allReservesAddresses = {
...tokensAddressesWithoutUsd,
};
await setInitialMarketRatesInRatesOracle(
LendingRateOracleRatesCommon,
allReservesAddresses,
lendingRateOracle
);
});

83
tasks/dev/5_initialize.ts Normal file
View File

@ -0,0 +1,83 @@
import {task} from '@nomiclabs/buidler/config';
import {
getLendingPoolAddressesProvider,
initReserves,
deployLendingPoolCollateralManager,
insertContractAddressInDb,
deployMockFlashLoanReceiver,
deployWalletBalancerProvider,
deployAaveProtocolTestHelpers,
getLendingPool,
getLendingPoolConfiguratorProxy,
getAllMockedTokens,
} from '../../helpers/contracts-helpers';
import {getReservesConfigByPool} from '../../helpers/configuration';
import {tEthereumAddress, AavePools, eContractid} from '../../helpers/types';
import {waitForTx, filterMapBy} from '../../helpers/misc-utils';
import {enableReservesToBorrow, enableReservesAsCollateral} from '../../helpers/init-helpers';
import {getAllTokenAddresses} from '../../helpers/mock-helpers';
import {ZERO_ADDRESS} from '../../helpers/constants';
task('dev:initialize-lending-pool', 'Initialize lending pool configuration.')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
await localBRE.run('set-bre');
const mockTokens = await getAllMockedTokens();
const lendingPoolProxy = await getLendingPool();
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy();
const allTokenAddresses = getAllTokenAddresses(mockTokens);
const addressesProvider = await getLendingPoolAddressesProvider();
const protoPoolReservesAddresses = <{[symbol: string]: tEthereumAddress}>(
filterMapBy(allTokenAddresses, (key: string) => !key.includes('UNI'))
);
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address, verify);
const reservesParams = getReservesConfigByPool(AavePools.proto);
await initReserves(
reservesParams,
protoPoolReservesAddresses,
addressesProvider,
lendingPoolProxy,
testHelpers,
lendingPoolConfiguratorProxy,
AavePools.proto,
ZERO_ADDRESS,
verify
);
await enableReservesToBorrow(
reservesParams,
protoPoolReservesAddresses,
testHelpers,
lendingPoolConfiguratorProxy
);
await enableReservesAsCollateral(
reservesParams,
protoPoolReservesAddresses,
testHelpers,
lendingPoolConfiguratorProxy
);
const collateralManager = await deployLendingPoolCollateralManager(verify);
await waitForTx(
await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
);
const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(
addressesProvider.address,
verify
);
await insertContractAddressInDb(
eContractid.MockFlashLoanReceiver,
mockFlashLoanReceiver.address
);
await deployWalletBalancerProvider(addressesProvider.address, verify);
await insertContractAddressInDb(eContractid.AaveProtocolTestHelpers, testHelpers.address);
});

View File

@ -0,0 +1,40 @@
import {task} from '@nomiclabs/buidler/config';
import {
deployLendingPoolAddressesProvider,
deployLendingPoolAddressesProviderRegistry,
getParamPerNetwork,
getLendingPoolAddressesProviderRegistry,
} from '../../helpers/contracts-helpers';
import {waitForTx} from '../../helpers/misc-utils';
import {ConfigNames, loadPoolConfig, getGenesisAaveAdmin} from '../../helpers/configuration';
import {eEthereumNetwork} from '../../helpers/types';
task(
'full:deploy-address-provider',
'Deploy address provider, registry and fee provider for dev enviroment'
)
.addFlag('verify', 'Verify contracts at Etherscan')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({verify, pool}, localBRE) => {
await localBRE.run('set-bre');
const network = <eEthereumNetwork>localBRE.network.name;
const poolConfig = loadPoolConfig(pool);
const {ProviderId} = poolConfig;
const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
// Deploy address provider and set genesis manager
const addressesProvider = await deployLendingPoolAddressesProvider(verify);
await waitForTx(await addressesProvider.setAaveAdmin(await getGenesisAaveAdmin(poolConfig)));
// If no provider registry is set, deploy lending pool address provider registry and register the address provider
const addressesProviderRegistry = !providerRegistryAddress
? await deployLendingPoolAddressesProviderRegistry(verify)
: await getLendingPoolAddressesProviderRegistry(providerRegistryAddress);
await waitForTx(
await addressesProviderRegistry.registerAddressesProvider(
addressesProvider.address,
ProviderId
)
);
});

View File

@ -0,0 +1,47 @@
import {task} from '@nomiclabs/buidler/config';
import {
deployLendingPool,
getLendingPoolAddressesProvider,
getLendingPool,
insertContractAddressInDb,
deployLendingPoolConfigurator,
getLendingPoolConfiguratorProxy,
} from '../../helpers/contracts-helpers';
import {eContractid} from '../../helpers/types';
import {waitForTx} from '../../helpers/misc-utils';
task('full:deploy-lending-pool', 'Deploy lending pool for dev enviroment')
.addFlag('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
await localBRE.run('set-bre');
const addressesProvider = await getLendingPoolAddressesProvider();
// Deploy lending pool
const lendingPoolImpl = await deployLendingPool(verify);
// Set lending pool impl to address provider
await waitForTx(await addressesProvider.setLendingPoolImpl(lendingPoolImpl.address));
const address = await addressesProvider.getLendingPool();
const lendingPoolProxy = await getLendingPool(address);
await insertContractAddressInDb(eContractid.LendingPool, lendingPoolProxy.address);
// Deploy lending pool configurator
const lendingPoolConfiguratorImpl = await deployLendingPoolConfigurator(verify);
// Set lending pool conf impl to Address Provider
await waitForTx(
await addressesProvider.setLendingPoolConfiguratorImpl(lendingPoolConfiguratorImpl.address)
);
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy(
await addressesProvider.getLendingPoolConfigurator()
);
await insertContractAddressInDb(
eContractid.LendingPoolConfigurator,
lendingPoolConfiguratorProxy.address
);
});

69
tasks/full/3_oracles.ts Normal file
View File

@ -0,0 +1,69 @@
import {task} from '@nomiclabs/buidler/config';
import {
getLendingPoolAddressesProvider,
getPairsTokenAggregator,
deployChainlinkProxyPriceProvider,
deployLendingRateOracle,
getParamPerNetwork,
} from '../../helpers/contracts-helpers';
import {setInitialMarketRatesInRatesOracle} from '../../helpers/oracles-helpers';
import {ICommonConfiguration, eEthereumNetwork, SymbolMap} from '../../helpers/types';
import {waitForTx, filterMapBy} from '../../helpers/misc-utils';
import {ConfigNames, loadPoolConfig} from '../../helpers/configuration';
import {exit} from 'process';
task('full:deploy-oracles', 'Deploy oracles for dev enviroment')
.addFlag('verify', 'Verify contracts at Etherscan')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({verify, pool}, localBRE) => {
try {
await localBRE.run('set-bre');
const network = <eEthereumNetwork>localBRE.network.name;
const poolConfig = loadPoolConfig(pool);
const {
ProtocolGlobalParams: {UsdAddress},
LendingRateOracleRatesCommon,
ReserveAssets,
ReserveSymbols,
FallbackOracle,
ChainlinkAggregator,
} = poolConfig as ICommonConfiguration;
const lendingRateOracles = filterMapBy(LendingRateOracleRatesCommon, (key) =>
ReserveSymbols.includes(key)
);
const addressesProvider = await getLendingPoolAddressesProvider();
const fallbackOracle = await getParamPerNetwork(FallbackOracle, network);
const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
const chainlinkAggregators = await getParamPerNetwork(ChainlinkAggregator, network);
const tokensToWatch: SymbolMap<string> = {
...reserveAssets,
USD: UsdAddress,
};
const [tokens, aggregators] = getPairsTokenAggregator(tokensToWatch, chainlinkAggregators);
const chainlinkProviderPriceProvider = await deployChainlinkProxyPriceProvider(
[tokens, aggregators, fallbackOracle],
verify
);
await waitForTx(
await addressesProvider.setPriceOracle(chainlinkProviderPriceProvider.address)
);
const lendingRateOracle = await deployLendingRateOracle(verify);
await waitForTx(await addressesProvider.setLendingRateOracle(lendingRateOracle.address));
const {USD, ...tokensAddressesWithoutUsd} = tokensToWatch;
await setInitialMarketRatesInRatesOracle(
lendingRateOracles,
tokensAddressesWithoutUsd,
lendingRateOracle
);
} catch (err) {
console.error(err);
exit(1);
}
});

View File

@ -0,0 +1,79 @@
import {task} from '@nomiclabs/buidler/config';
import {
getLendingPoolAddressesProvider,
initReserves,
deployLendingPoolCollateralManager,
insertContractAddressInDb,
deployWalletBalancerProvider,
deployAaveProtocolTestHelpers,
getLendingPool,
getLendingPoolConfiguratorProxy,
getParamPerNetwork,
} from '../../helpers/contracts-helpers';
import {loadPoolConfig, ConfigNames} from '../../helpers/configuration';
import {AavePools, eContractid, eEthereumNetwork, ICommonConfiguration} from '../../helpers/types';
import {waitForTx} from '../../helpers/misc-utils';
import {enableReservesToBorrow, enableReservesAsCollateral} from '../../helpers/init-helpers';
import {ZERO_ADDRESS} from '../../helpers/constants';
import {exit} from 'process';
task('full:initialize-lending-pool', 'Initialize lending pool configuration.')
.addFlag('verify', 'Verify contracts at Etherscan')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({verify, pool}, localBRE) => {
try {
await localBRE.run('set-bre');
console.log('init');
const network = <eEthereumNetwork>localBRE.network.name;
const poolConfig = loadPoolConfig(pool);
const {ReserveAssets, ReservesConfig} = poolConfig as ICommonConfiguration;
const reserveAssets = await getParamPerNetwork(ReserveAssets, network);
const lendingPoolProxy = await getLendingPool();
const lendingPoolConfiguratorProxy = await getLendingPoolConfiguratorProxy();
const addressesProvider = await getLendingPoolAddressesProvider();
const testHelpers = await deployAaveProtocolTestHelpers(addressesProvider.address, verify);
console.log('init reserves');
await initReserves(
ReservesConfig,
reserveAssets,
addressesProvider,
lendingPoolProxy,
testHelpers,
lendingPoolConfiguratorProxy,
AavePools.proto,
ZERO_ADDRESS,
verify
);
console.log('enable reserves');
await enableReservesToBorrow(
ReservesConfig,
reserveAssets,
testHelpers,
lendingPoolConfiguratorProxy
);
console.log('enable reserves as collateral');
await enableReservesAsCollateral(
ReservesConfig,
reserveAssets,
testHelpers,
lendingPoolConfiguratorProxy
);
console.log('deploy coll manager');
const collateralManager = await deployLendingPoolCollateralManager(verify);
await waitForTx(
await addressesProvider.setLendingPoolCollateralManager(collateralManager.address)
);
console.log('deploy bal provicer');
await deployWalletBalancerProvider(addressesProvider.address, verify);
} catch (err) {
console.error(err);
exit(1);
}
});

View File

@ -0,0 +1,35 @@
import {task} from '@nomiclabs/buidler/config';
import {checkVerification} from '../../helpers/etherscan-verification';
import {ConfigNames} from '../../helpers/configuration';
task('aave:dev', 'Deploy development enviroment')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
const POOL_NAME = ConfigNames.Aave;
await localBRE.run('set-bre');
// Prevent loss of gas verifying all the needed ENVs for Etherscan verification
if (verify) {
checkVerification();
}
console.log('Migration started\n');
console.log('1. Deploy mock tokens');
await localBRE.run('dev:deploy-mock-tokens', {verify});
console.log('2. Deploy address provider');
await localBRE.run('dev:deploy-address-provider', {verify});
console.log('3. Deploy lending pool');
await localBRE.run('dev:deploy-lending-pool', {verify});
console.log('4. Deploy oracles');
await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
console.log('5. Initialize lending pool');
await localBRE.run('dev:initialize-lending-pool', {verify});
console.log('\nFinished migration');
});

View File

@ -0,0 +1,34 @@
import {task} from '@nomiclabs/buidler/config';
import {checkVerification} from '../../helpers/etherscan-verification';
import {ConfigNames} from '../../helpers/configuration';
import {EthereumNetworkNames} from '../../helpers/types';
task('aave:full', 'Deploy development enviroment')
.addFlag('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
const POOL_NAME = ConfigNames.Aave;
const network = <EthereumNetworkNames>localBRE.network.name;
await localBRE.run('set-bre');
// Prevent loss of gas verifying all the needed ENVs for Etherscan verification
if (verify) {
checkVerification();
}
console.log('Migration started\n');
console.log('1. Deploy address provider');
await localBRE.run('full:deploy-address-provider', {verify, pool: POOL_NAME});
console.log('2. Deploy lending pool');
await localBRE.run('full:deploy-lending-pool', {verify});
console.log('3. Deploy oracles');
await localBRE.run('full:deploy-oracles', {verify, pool: POOL_NAME});
console.log('4. Initialize lending pool');
await localBRE.run('full:initialize-lending-pool', {verify, pool: POOL_NAME});
console.log('\nFinished migrations');
});

View File

@ -0,0 +1,35 @@
import {task} from '@nomiclabs/buidler/config';
import {checkVerification} from '../../helpers/etherscan-verification';
import {ConfigNames} from '../../helpers/configuration';
task('uniswap:dev', 'Deploy development enviroment')
.addOptionalParam('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
const POOL_NAME = ConfigNames.Uniswap;
await localBRE.run('set-bre');
// Prevent loss of gas verifying all the needed ENVs for Etherscan verification
if (verify) {
checkVerification();
}
console.log('Migration started\n');
console.log('1. Deploy mock tokens');
await localBRE.run('dev:deploy-mock-tokens', {verify});
console.log('2. Deploy address provider');
await localBRE.run('dev:deploy-address-provider', {verify});
console.log('3. Deploy lending pool');
await localBRE.run('dev:deploy-lending-pool', {verify});
console.log('4. Deploy oracles');
await localBRE.run('dev:deploy-oracles', {verify, pool: POOL_NAME});
console.log('5. Initialize lending pool');
await localBRE.run('dev:initialize-lending-pool', {verify});
console.log('\nFinished migration');
});

View File

@ -0,0 +1,32 @@
import {task} from '@nomiclabs/buidler/config';
import {checkVerification} from '../../helpers/etherscan-verification';
import {ConfigNames} from '../../helpers/configuration';
task('uniswap:full', 'Deploy development enviroment')
.addFlag('verify', 'Verify contracts at Etherscan')
.setAction(async ({verify}, localBRE) => {
const POOL_NAME = ConfigNames.Uniswap;
await localBRE.run('set-bre');
// Prevent loss of gas verifying all the needed ENVs for Etherscan verification
if (verify) {
checkVerification();
}
console.log('Migration started\n');
console.log('1. Deploy address provider');
await localBRE.run('full:deploy-address-provider', {verify, pool: POOL_NAME});
console.log('2. Deploy lending pool');
await localBRE.run('full:deploy-lending-pool', {verify});
console.log('3. Deploy oracles');
await localBRE.run('full:deploy-oracles', {verify, pool: POOL_NAME});
console.log('4. Initialize lending pool');
await localBRE.run('full:initialize-lending-pool', {verify, pool: POOL_NAME});
console.log('\nFinished migrations');
});

35
tasks/misc/verify-sc.ts Normal file
View File

@ -0,0 +1,35 @@
import {task} from '@nomiclabs/buidler/config';
import {verifyContract, checkVerification} from '../../helpers/etherscan-verification';
interface VerifyParams {
contractName: string;
address: string;
constructorArguments: string[];
libraries: string;
}
task('verify-sc', 'Inits the BRE, to have access to all the plugins')
.addParam('contractName', 'Name of the Solidity smart contract')
.addParam('address', 'Ethereum address of the smart contract')
.addOptionalParam(
'libraries',
'Stringified JSON object in format of {library1: "0x2956356cd2a2bf3202f771f50d3d14a367b48071"}'
)
.addOptionalVariadicPositionalParam(
'constructorArguments',
'arguments for contract constructor',
[]
)
.setAction(
async (
{contractName, address, constructorArguments = [], libraries}: VerifyParams,
localBRE
) => {
await localBRE.run('set-bre');
checkVerification();
const result = await verifyContract(contractName, address, constructorArguments, libraries);
return result;
}
);

View File

@ -2,16 +2,13 @@ import rawBRE from '@nomiclabs/buidler';
import {MockContract} from 'ethereum-waffle';
import {
deployLendingPoolAddressesProvider,
deployMintableErc20,
deployMintableERC20,
deployLendingPoolAddressesProviderRegistry,
deployLendingPoolConfigurator,
deployLendingPool,
deployPriceOracle,
getLendingPoolConfiguratorProxy,
deployMockAggregator,
deployChainlinkProxyPriceProvider,
deployLendingRateOracle,
deployDefaultReserveInterestRateStrategy,
deployLendingPoolCollateralManager,
deployMockFlashLoanReceiver,
deployWalletBalancerProvider,
@ -20,52 +17,36 @@ import {
deployAaveProtocolTestHelpers,
getEthersSigners,
registerContractInJsonDb,
deployStableDebtToken,
deployVariableDebtToken,
deployGenericAToken,
getPairsTokenAggregator,
initReserves,
deployMockSwapAdapter,
deployLendingRateOracle,
} from '../helpers/contracts-helpers';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {ContractTransaction, Signer} from 'ethers';
import {
TokenContractId,
eContractid,
iAssetBase,
tEthereumAddress,
iAssetAggregatorBase,
IMarketRates,
iMultiPoolsAssets,
AavePools,
IReserveParams,
} from '../helpers/types';
import {MintableErc20} from '../types/MintableErc20';
import {
MOCK_USD_PRICE_IN_WEI,
ALL_ASSETS_INITIAL_PRICES,
USD_ADDRESS,
MOCK_CHAINLINK_AGGREGATORS_PRICES,
LENDING_RATE_ORACLE_RATES_COMMON,
getReservesConfigByPool,
getFeeDistributionParamsCommon,
ZERO_ADDRESS,
} from '../helpers/constants';
import {PriceOracle} from '../types/PriceOracle';
import {MockAggregator} from '../types/MockAggregator';
import {LendingRateOracle} from '../types/LendingRateOracle';
import {LendingPool} from '../types/LendingPool';
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
import {Signer} from 'ethers';
import {TokenContractId, eContractid, tEthereumAddress, AavePools} from '../helpers/types';
import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
import {getReservesConfigByPool} from '../helpers/configuration';
import {initializeMakeSuite} from './helpers/make-suite';
import path from 'path';
import fs from 'fs';
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
['misc'].forEach((folder) => {
const tasksPath = path.join(__dirname, '../', 'tasks', folder);
fs.readdirSync(tasksPath).forEach((task) => require(`${tasksPath}/${task}`));
});
import {
setInitialAssetPricesInOracle,
setInitialMarketRatesInRatesOracle,
deployAllMockAggregators,
} from '../helpers/oracles-helpers';
import {waitForTx} from '../helpers/misc-utils';
import {enableReservesToBorrow, enableReservesAsCollateral} from '../helpers/init-helpers';
import {AaveConfig} from '../config/aave';
import {ZERO_ADDRESS} from '../helpers/constants';
const MOCK_USD_PRICE_IN_WEI = AaveConfig.ProtocolGlobalParams.MockUsdPriceInWei;
const ALL_ASSETS_INITIAL_PRICES = AaveConfig.Mocks.AllAssetsInitialPrices;
const USD_ADDRESS = AaveConfig.ProtocolGlobalParams.UsdAddress;
const MOCK_CHAINLINK_AGGREGATORS_PRICES = AaveConfig.Mocks.ChainlinkAggregatorPrices;
const LENDING_RATE_ORACLE_RATES_COMMON = AaveConfig.LendingRateOracleRatesCommon;
const deployAllMockTokens = async (deployer: Signer) => {
const tokens: {[symbol: string]: MockContract | MintableErc20} = {};
const tokens: {[symbol: string]: MockContract | MintableERC20} = {};
const protoConfigData = getReservesConfigByPool(AavePools.proto);
const secondaryConfigData = getReservesConfigByPool(AavePools.secondary);
@ -83,7 +64,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
decimals = 18;
}
tokens[tokenSymbol] = await deployMintableErc20([
tokens[tokenSymbol] = await deployMintableERC20([
tokenSymbol,
tokenSymbol,
configData ? configData.reserveDecimals : 18,
@ -94,266 +75,6 @@ const deployAllMockTokens = async (deployer: Signer) => {
return tokens;
};
const setInitialAssetPricesInOracle = async (
prices: iAssetBase<tEthereumAddress>,
assetsAddresses: iAssetBase<tEthereumAddress>,
priceOracleInstance: PriceOracle
) => {
for (const [assetSymbol, price] of Object.entries(prices) as [string, string][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
assetAddressIndex
];
await waitForTx(await priceOracleInstance.setAssetPrice(assetAddress, price));
}
};
const deployAllMockAggregators = async (initialPrices: iAssetAggregatorBase<string>) => {
const aggregators: {[tokenSymbol: string]: MockAggregator} = {};
for (const tokenContractName of Object.keys(initialPrices)) {
if (tokenContractName !== 'ETH') {
const priceIndex = Object.keys(initialPrices).findIndex(
(value) => value === tokenContractName
);
const [, price] = (Object.entries(initialPrices) as [string, string][])[priceIndex];
aggregators[tokenContractName] = await deployMockAggregator(price);
}
}
return aggregators;
};
const getPairsTokenAggregator = (
allAssetsAddresses: {
[tokenSymbol: string]: tEthereumAddress;
},
aggregatorsAddresses: {[tokenSymbol: string]: tEthereumAddress}
): [string[], string[]] => {
const {ETH, ...assetsAddressesWithoutEth} = allAssetsAddresses;
const pairs = Object.entries(assetsAddressesWithoutEth).map(([tokenSymbol, tokenAddress]) => {
if (tokenSymbol !== 'ETH') {
const aggregatorAddressIndex = Object.keys(aggregatorsAddresses).findIndex(
(value) => value === tokenSymbol
);
const [, aggregatorAddress] = (Object.entries(aggregatorsAddresses) as [
string,
tEthereumAddress
][])[aggregatorAddressIndex];
return [tokenAddress, aggregatorAddress];
}
});
const mappedPairs = pairs.map(([asset]) => asset);
const mappedAggregators = pairs.map(([, source]) => source);
return [mappedPairs, mappedAggregators];
};
const setInitialMarketRatesInRatesOracle = async (
marketRates: iMultiPoolsAssets<IMarketRates>,
assetsAddresses: {[x: string]: tEthereumAddress},
lendingRateOracleInstance: LendingRateOracle
) => {
for (const [assetSymbol, {borrowRate}] of Object.entries(marketRates) as [
string,
IMarketRates
][]) {
const assetAddressIndex = Object.keys(assetsAddresses).findIndex(
(value) => value === assetSymbol
);
const [, assetAddress] = (Object.entries(assetsAddresses) as [string, string][])[
assetAddressIndex
];
await lendingRateOracleInstance.setMarketBorrowRate(assetAddress, borrowRate);
}
};
const initReserves = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
lendingPoolAddressesProvider: LendingPoolAddressesProvider,
lendingPool: LendingPool,
lendingPoolConfigurator: LendingPoolConfigurator,
helpersContract: AaveProtocolTestHelpers,
aavePool: AavePools,
incentivesController: tEthereumAddress
) => {
if (aavePool !== AavePools.proto && aavePool !== AavePools.secondary) {
console.log(`Invalid Aave pool ${aavePool}`);
process.exit(1);
}
for (let [assetSymbol, {reserveDecimals}] of Object.entries(reservesParams) as [
string,
IReserveParams
][]) {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
assetAddressIndex
];
const {isActive: reserveInitialized} = await helpersContract.getReserveConfigurationData(
tokenAddress
);
if (reserveInitialized) {
console.log(`Reserve ${assetSymbol} is already active, skipping configuration`);
continue;
}
try {
const reserveParamIndex = Object.keys(reservesParams).findIndex(
(value) => value === assetSymbol
);
const [
,
{
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
},
] = (Object.entries(reservesParams) as [string, IReserveParams][])[reserveParamIndex];
const rateStrategyContract = await deployDefaultReserveInterestRateStrategy([
lendingPoolAddressesProvider.address,
baseVariableBorrowRate,
variableRateSlope1,
variableRateSlope2,
stableRateSlope1,
stableRateSlope2,
]);
const stableDebtToken = await deployStableDebtToken([
`Aave stable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`stableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
tokenAddress,
lendingPool.address,
incentivesController,
]);
const variableDebtToken = await deployVariableDebtToken([
`Aave variable debt bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`variableDebt${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
tokenAddress,
lendingPool.address,
incentivesController,
]);
const aToken = await deployGenericAToken([
lendingPool.address,
tokenAddress,
ZERO_ADDRESS,
`Aave interest bearing ${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
`a${assetSymbol === 'WETH' ? 'ETH' : assetSymbol}`,
incentivesController,
]);
if (process.env.POOL === AavePools.secondary) {
if (assetSymbol.search('UNI') === -1) {
assetSymbol = `Uni${assetSymbol}`;
} else {
assetSymbol = assetSymbol.replace(/_/g, '').replace('UNI', 'Uni');
}
}
await lendingPoolConfigurator.initReserve(
tokenAddress,
aToken.address,
stableDebtToken.address,
variableDebtToken.address,
reserveDecimals,
rateStrategyContract.address
);
} catch (e) {
console.log(`Reserve initialization for ${assetSymbol} failed with error ${e}. Skipped.`);
}
}
};
const enableReservesToBorrow = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
helpersContract: AaveProtocolTestHelpers,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [assetSymbol, {borrowingEnabled, stableBorrowRateEnabled}] of Object.entries(
reservesParams
) as [string, IReserveParams][]) {
if (!borrowingEnabled) continue;
try {
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
assetAddressIndex
];
const {
borrowingEnabled: borrowingAlreadyEnabled,
} = await helpersContract.getReserveConfigurationData(tokenAddress);
if (borrowingAlreadyEnabled) {
console.log(`Reserve ${assetSymbol} is already enabled for borrowing, skipping`);
continue;
}
await lendingPoolConfigurator.enableBorrowingOnReserve(tokenAddress, stableBorrowRateEnabled);
} catch (e) {
console.log(
`Enabling reserve for borrowings for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
const enableReservesAsCollateral = async (
reservesParams: iMultiPoolsAssets<IReserveParams>,
tokenAddresses: {[symbol: string]: tEthereumAddress},
helpersContract: AaveProtocolTestHelpers,
lendingPoolConfigurator: LendingPoolConfigurator
) => {
for (const [
assetSymbol,
{baseLTVAsCollateral, liquidationBonus, liquidationThreshold},
] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (baseLTVAsCollateral === '-1') continue;
const assetAddressIndex = Object.keys(tokenAddresses).findIndex(
(value) => value === assetSymbol
);
const [, tokenAddress] = (Object.entries(tokenAddresses) as [string, string][])[
assetAddressIndex
];
const {
usageAsCollateralEnabled: alreadyEnabled,
} = await helpersContract.getReserveConfigurationData(tokenAddress);
if (alreadyEnabled) {
console.log(`Reserve ${assetSymbol} is already enabled as collateral, skipping`);
continue;
}
try {
await lendingPoolConfigurator.enableReserveAsCollateral(
tokenAddress,
baseLTVAsCollateral,
liquidationThreshold,
liquidationBonus
);
} catch (e) {
console.log(
`Enabling reserve as collateral for ${assetSymbol} failed with error ${e}. Skipped.`
);
}
}
};
export const waitForTx = async (tx: ContractTransaction) => await tx.wait();
const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
console.time('setup');
const aaveAdmin = await deployer.getAddress();
@ -491,10 +212,11 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
protoPoolReservesAddresses,
addressesProvider,
lendingPoolProxy,
lendingPoolConfiguratorProxy,
testHelpers,
lendingPoolConfiguratorProxy,
AavePools.proto,
ZERO_ADDRESS
ZERO_ADDRESS,
false
);
await enableReservesToBorrow(
reservesParams,

View File

@ -6,88 +6,88 @@ import {ProtocolErrors} from '../helpers/types';
const {expect} = require('chai');
makeSuite('AddressesProviderRegistry', (testEnv: TestEnv) => {
it('Checks the addresses provider is added to the registry', async () => {
const {addressesProvider, registry} = testEnv;
const providers = await registry.getAddressesProvidersList();
expect(providers.length).to.be.equal(1, "Invalid length of the addresses providers list");
expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list");
expect(providers.length).to.be.equal(1, 'Invalid length of the addresses providers list');
expect(providers[0].toString()).to.be.equal(
addressesProvider.address,
' Invalid addresses provider added to the list'
);
});
it('Registers a new mock addresses provider', async () => {
const {users, registry} = testEnv;
//simulating an addresses provider using the users[1] wallet address
await registry.registerAddressesProvider(users[1].address, "2");
await registry.registerAddressesProvider(users[1].address, '2');
const providers = await registry.getAddressesProvidersList();
expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list");
expect(providers[1].toString()).to.be.equal(users[1].address, " Invalid addresses provider added to the list");
expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
expect(providers[1].toString()).to.be.equal(
users[1].address,
' Invalid addresses provider added to the list'
);
});
it('Removes the mock addresses provider', async () => {
const {users, registry, addressesProvider} = testEnv;
//checking the isAddressesProviderRegistered function
const id = await registry.isAddressesProviderRegistered(users[1].address);
expect(id).to.be.equal("2", "Invalid isRegistered return value");
expect(id).to.be.equal('2', 'Invalid isRegistered return value');
await registry.unregisterAddressesProvider(users[1].address);
const providers = await registry.getAddressesProvidersList();
expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list");
expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list");
expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, " Invalid addresses");
expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
expect(providers[0].toString()).to.be.equal(
addressesProvider.address,
' Invalid addresses provider added to the list'
);
expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
});
it('Tries to remove a unregistered addressesProvider', async () => {
const {PROVIDER_NOT_REGISTERED} = ProtocolErrors;
const {users, registry} = testEnv;
await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(PROVIDER_NOT_REGISTERED);
await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
PROVIDER_NOT_REGISTERED
);
});
it('Tries to remove a unregistered addressesProvider', async () => {
const {PROVIDER_NOT_REGISTERED} = ProtocolErrors;
const {users, registry} = testEnv;
await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(PROVIDER_NOT_REGISTERED);
await expect(registry.unregisterAddressesProvider(users[2].address)).to.be.revertedWith(
PROVIDER_NOT_REGISTERED
);
});
it('Tries to add an already added addressesProvider with a different id. Should overwrite the previous id', async () => {
const {users, registry, addressesProvider} = testEnv;
await registry.registerAddressesProvider(addressesProvider.address,"2");
await registry.registerAddressesProvider(addressesProvider.address, '2');
const providers = await registry.getAddressesProvidersList();
const id = await registry.isAddressesProviderRegistered(addressesProvider.address);
expect(providers.length).to.be.equal(2, "Invalid length of the addresses providers list");
expect(providers[0].toString()).to.be.equal(addressesProvider.address, " Invalid addresses provider added to the list");
expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, " Invalid addresses");
expect(providers.length).to.be.equal(2, 'Invalid length of the addresses providers list');
expect(providers[0].toString()).to.be.equal(
addressesProvider.address,
' Invalid addresses provider added to the list'
);
expect(providers[1].toString()).to.be.equal(ZERO_ADDRESS, ' Invalid addresses');
});
});

View File

@ -7,7 +7,9 @@ makeSuite('AToken: Modifiers', (testEnv: TestEnv) => {
it('Tries to invoke mint not being the LendingPool', async () => {
const {deployer, aDai} = testEnv;
await expect(aDai.mint(deployer.address, '1', '1')).to.be.revertedWith(CALLER_MUST_BE_LENDING_POOL);
await expect(aDai.mint(deployer.address, '1', '1')).to.be.revertedWith(
CALLER_MUST_BE_LENDING_POOL
);
});
it('Tries to invoke burn not being the LendingPool', async () => {

View File

@ -1,23 +1,27 @@
import {
MAX_UINT_AMOUNT,
ZERO_ADDRESS,
getATokenDomainSeparatorPerNetwork,
} from '../helpers/constants';
import {MAX_UINT_AMOUNT, ZERO_ADDRESS} from '../helpers/constants';
import {BUIDLEREVM_CHAINID} from '../helpers/buidler-constants';
import {buildPermitParams, getSignatureFromTypedData} from '../helpers/contracts-helpers';
import {expect} from 'chai';
import {ethers} from 'ethers';
import {eEthereumNetwork} from '../helpers/types';
import {makeSuite, TestEnv} from './helpers/make-suite';
import {BRE} from '../helpers/misc-utils';
import {waitForTx} from './__setup.spec';
import {BUIDLEREVM_CHAINID} from '../helpers/buidler-constants';
import {
ConfigNames,
getATokenDomainSeparatorPerNetwork,
loadPoolConfig,
} from '../helpers/configuration';
import {waitForTx} from '../helpers/misc-utils';
const {parseEther} = ethers.utils;
makeSuite('AToken: Permit', (testEnv: TestEnv) => {
const poolConfig = loadPoolConfig(ConfigNames.Commons);
it('Checks the domain separator', async () => {
const DOMAIN_SEPARATOR_ENCODED = getATokenDomainSeparatorPerNetwork(
eEthereumNetwork.buidlerevm
eEthereumNetwork.buidlerevm,
poolConfig
);
const {aDai} = testEnv;

View File

@ -1,14 +1,14 @@
import {
APPROVAL_AMOUNT_LENDING_POOL,
AAVE_REFERRAL,
MAX_UINT_AMOUNT,
ZERO_ADDRESS,
} from '../helpers/constants';
import {MAX_UINT_AMOUNT, ZERO_ADDRESS} from '../helpers/constants';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {expect} from 'chai';
import {ethers} from 'ethers';
import {RateMode, ProtocolErrors} from '../helpers/types';
import {makeSuite, TestEnv} from './helpers/make-suite';
import {CommonsConfig} from '../config/commons';
const APPROVAL_AMOUNT_LENDING_POOL =
CommonsConfig.ProtocolGlobalParams.ApprovalAmountLendingPoolCore;
const AAVE_REFERRAL = CommonsConfig.ProtocolGlobalParams.AaveReferral;
makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
const {

View File

@ -6,7 +6,7 @@ import {ethers} from 'ethers';
import {APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants';
import {getContractsData, getTxCostAndTimestamp} from './helpers/actions';
import {calcExpectedATokenBalance} from './helpers/utils/calculations';
import {waitForTx} from './__setup.spec';
import {waitForTx} from '../helpers/misc-utils';
import {advanceBlock, timeLatest} from '../helpers/misc-utils';
const {expect} = require('chai');

View File

@ -1,7 +1,11 @@
import {TestEnv, makeSuite} from './helpers/make-suite';
import {RAY, APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants';
import {RAY} from '../helpers/constants';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {ProtocolErrors} from '../helpers/types';
import {CommonsConfig} from '../config/commons';
const APPROVAL_AMOUNT_LENDING_POOL =
CommonsConfig.ProtocolGlobalParams.ApprovalAmountLendingPoolCore;
const {expect} = require('chai');

View File

@ -7,8 +7,7 @@ import {
calcExpectedStableDebtTokenBalance,
} from './helpers/utils/calculations';
import {getContractsData} from './helpers/actions';
import {waitForTx} from './__setup.spec';
import {timeLatest, BRE, increaseTime} from '../helpers/misc-utils';
import {timeLatest, BRE, increaseTime, waitForTx} from '../helpers/misc-utils';
import {ProtocolErrors} from '../helpers/types';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {expectRepayWithCollateralEvent} from './repay-with-collateral.spec';

View File

@ -24,6 +24,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
INVALID_FLASHLOAN_MODE,
SAFEERC20_LOWLEVEL_CALL,
IS_PAUSED,
INVALID_FLASH_LOAN_EXECUTOR_RETURN,
} = ProtocolErrors;
before(async () => {
@ -116,9 +117,30 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE);
});
it('Takes WETH flashloan, simulating a receiver as EOA (revert expected)', async () => {
const {pool, weth, users} = testEnv;
const caller = users[1];
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await _mockFlashLoanReceiver.setSimulateEOA(true);
await expect(
pool
.connect(caller.signer)
.flashLoan(
_mockFlashLoanReceiver.address,
weth.address,
ethers.utils.parseEther('0.8'),
0,
'0x10',
'0'
)
).to.be.revertedWith(INVALID_FLASH_LOAN_EXECUTOR_RETURN);
});
it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
const {pool, weth, users} = testEnv;
const caller = users[1];
await _mockFlashLoanReceiver.setSimulateEOA(false);
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect(

View File

@ -24,11 +24,10 @@ import {
} from '../../helpers/contracts-helpers';
import {MAX_UINT_AMOUNT, ONE_YEAR} from '../../helpers/constants';
import {SignerWithAddress, TestEnv} from './make-suite';
import {BRE, increaseTime, timeLatest} from '../../helpers/misc-utils';
import {BRE, increaseTime, timeLatest, waitForTx} from '../../helpers/misc-utils';
import chai from 'chai';
import {ReserveData, UserReserveData} from './utils/interfaces';
import {waitForTx} from '../__setup.spec';
import {ContractReceipt} from 'ethers';
import {AToken} from '../../types/AToken';
import {RateMode, tEthereumAddress} from '../../helpers/types';

View File

@ -15,7 +15,7 @@ import {
import {tEthereumAddress} from '../../helpers/types';
import {LendingPool} from '../../types/LendingPool';
import {AaveProtocolTestHelpers} from '../../types/AaveProtocolTestHelpers';
import {MintableErc20} from '../../types/MintableErc20';
import {MintableErc20 as MintableERC20} from '../../types/MintableErc20';
import {AToken} from '../../types/AToken';
import {LendingPoolConfigurator} from '../../types/LendingPoolConfigurator';
@ -41,12 +41,12 @@ export interface TestEnv {
configurator: LendingPoolConfigurator;
oracle: PriceOracle;
helpersContract: AaveProtocolTestHelpers;
weth: MintableErc20;
weth: MintableERC20;
aEth: AToken;
dai: MintableErc20;
dai: MintableERC20;
aDai: AToken;
usdc: MintableErc20;
lend: MintableErc20;
usdc: MintableERC20;
lend: MintableERC20;
addressesProvider: LendingPoolAddressesProvider;
mockSwapAdapter: MockSwapAdapter;
registry: LendingPoolAddressesProviderRegistry;
@ -66,12 +66,12 @@ const testEnv: TestEnv = {
configurator: {} as LendingPoolConfigurator,
helpersContract: {} as AaveProtocolTestHelpers,
oracle: {} as PriceOracle,
weth: {} as MintableErc20,
weth: {} as MintableERC20,
aEth: {} as AToken,
dai: {} as MintableErc20,
dai: {} as MintableERC20,
aDai: {} as AToken,
usdc: {} as MintableErc20,
lend: {} as MintableErc20,
usdc: {} as MintableERC20,
lend: {} as MintableERC20,
addressesProvider: {} as LendingPoolAddressesProvider,
mockSwapAdapter: {} as MockSwapAdapter,
registry: {} as LendingPoolAddressesProviderRegistry,

View File

@ -318,7 +318,6 @@ export const calcExpectedReserveDataAfterBorrow = (
expectedReserveData.lastUpdateTimestamp = txTimestamp;
if (borrowRateMode == RateMode.Stable) {
expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
const expectedVariableDebtAfterTx = expectedReserveData.scaledVariableDebt.rayMul(
@ -392,7 +391,6 @@ export const calcExpectedReserveDataAfterBorrow = (
expectedReserveData.totalLiquidity
);
} else {
expectedReserveData.principalStableDebt = reserveDataBeforeAction.principalStableDebt;
const totalStableDebtAfterTx = calcExpectedStableDebtTokenBalance(
@ -605,7 +603,6 @@ export const calcExpectedUserDataAfterBorrow = (
const amountBorrowedBN = new BigNumber(amountBorrowed);
if (interestRateMode == RateMode.Stable) {
const stableDebtUntilTx = calcExpectedStableDebtTokenBalance(
userDataBeforeAction.principalStableDebt,
userDataBeforeAction.stableBorrowRate,
@ -631,9 +628,7 @@ export const calcExpectedUserDataAfterBorrow = (
);
expectedUserData.scaledVariableDebt = userDataBeforeAction.scaledVariableDebt;
} else {
expectedUserData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt.plus(
amountBorrowedBN.rayDiv(expectedDataAfterAction.variableBorrowIndex)
);

View File

@ -23,8 +23,8 @@ export interface ReserveData {
availableLiquidity: BigNumber;
totalStableDebt: BigNumber;
totalVariableDebt: BigNumber;
principalStableDebt: BigNumber,
scaledVariableDebt: BigNumber,
principalStableDebt: BigNumber;
scaledVariableDebt: BigNumber;
averageStableBorrowRate: BigNumber;
variableBorrowRate: BigNumber;
stableBorrowRate: BigNumber;

View File

@ -4,7 +4,7 @@ import {makeSuite, TestEnv} from './helpers/make-suite';
import {ProtocolErrors} from '../helpers/types';
import {ethers} from 'ethers';
import {ZERO_ADDRESS} from '../helpers/constants';
import {waitForTx} from './__setup.spec';
import {waitForTx} from '../helpers/misc-utils';
import {deployLendingPool} from '../helpers/contracts-helpers';
const {utils} = ethers;

View File

@ -1,12 +1,16 @@
import BigNumber from 'bignumber.js';
import {BRE} from '../helpers/misc-utils';
import {APPROVAL_AMOUNT_LENDING_POOL, oneEther} from '../helpers/constants';
import {oneEther} from '../helpers/constants';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {makeSuite} from './helpers/make-suite';
import {ProtocolErrors, RateMode} from '../helpers/types';
import {calcExpectedVariableDebtTokenBalance} from './helpers/utils/calculations';
import {getUserData, getReserveData} from './helpers/utils/helpers';
import {CommonsConfig} from '../config/commons';
const APPROVAL_AMOUNT_LENDING_POOL =
CommonsConfig.ProtocolGlobalParams.ApprovalAmountLendingPoolCore;
const chai = require('chai');
const {expect} = chai;

View File

@ -1,12 +1,16 @@
import BigNumber from 'bignumber.js';
import {BRE, increaseTime} from '../helpers/misc-utils';
import {APPROVAL_AMOUNT_LENDING_POOL, oneEther} from '../helpers/constants';
import {oneEther} from '../helpers/constants';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {makeSuite} from './helpers/make-suite';
import {ProtocolErrors, RateMode} from '../helpers/types';
import {calcExpectedStableDebtTokenBalance} from './helpers/utils/calculations';
import {getUserData} from './helpers/utils/helpers';
import {CommonsConfig} from '../config/commons';
const APPROVAL_AMOUNT_LENDING_POOL =
CommonsConfig.ProtocolGlobalParams.ApprovalAmountLendingPoolCore;
import {parseEther} from 'ethers/lib/utils';
const chai = require('chai');

View File

@ -7,10 +7,8 @@ import {
calcExpectedStableDebtTokenBalance,
} from './helpers/utils/calculations';
import {getContractsData} from './helpers/actions';
import {waitForTx} from './__setup.spec';
import {timeLatest} from '../helpers/misc-utils';
import {timeLatest, waitForTx} from '../helpers/misc-utils';
import {ProtocolErrors, tEthereumAddress} from '../helpers/types';
import {parse} from 'path';
const {expect} = require('chai');
const {parseUnits, parseEther} = ethers.utils;

View File

@ -4,7 +4,7 @@ import {configuration as calculationsConfiguration} from './helpers/utils/calcul
import fs from 'fs';
import BigNumber from 'bignumber.js';
import {makeSuite} from './helpers/make-suite';
import {getReservesConfigByPool} from '../helpers/constants';
import {getReservesConfigByPool} from '../helpers/configuration';
import {AavePools, iAavePoolAssets, IReserveParams} from '../helpers/types';
import {executeStory} from './helpers/scenario-engine';

View File

@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "ES2019",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,