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

3
.gitignore vendored
View File

@ -1,12 +1,13 @@
.env
#Buidler files #Buidler files
cache cache
artifacts artifacts
types
node_modules node_modules
dist/ dist/
build/ build/
.vscode .vscode
.idea .idea
types
coverage coverage
.coverage_artifacts .coverage_artifacts

View File

@ -1,4 +1,4 @@
FROM ethereum/solc:0.6.8 as build-deps 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 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'; import {usePlugin} from '@nomiclabs/buidler/config';
// @ts-ignore // @ts-ignore
import {accounts} from './test-wallets.js'; import {accounts} from './test-wallets.js';
@ -11,18 +13,29 @@ usePlugin('@nomiclabs/buidler-waffle');
usePlugin('@nomiclabs/buidler-etherscan'); usePlugin('@nomiclabs/buidler-etherscan');
//usePlugin('buidler-gas-reporter'); //usePlugin('buidler-gas-reporter');
const SKIP_LOAD = process.env.SKIP_LOAD === 'true';
const DEFAULT_BLOCK_GAS_LIMIT = 10000000; const DEFAULT_BLOCK_GAS_LIMIT = 10000000;
const DEFAULT_GAS_PRICE = 10; const DEFAULT_GAS_PRICE = 10;
const HARDFORK = 'istanbul'; const HARDFORK = 'istanbul';
const INFURA_KEY = ''; const INFURA_KEY = process.env.INFURA_KEY || '';
const ETHERSCAN_KEY = ''; const ETHERSCAN_KEY = process.env.ETHERSCAN_KEY || '';
const MNEMONIC_PATH = "m/44'/60'/0'/0"; const MNEMONIC_PATH = "m/44'/60'/0'/0";
const MNEMONICS: {[network: string]: string} = { const MNEMONICS: {[network: string]: string} = {
[eEthereumNetwork.kovan]: '', [eEthereumNetwork.kovan]: process.env.MNEMONIC || '',
[eEthereumNetwork.ropsten]: '', [eEthereumNetwork.ropsten]: process.env.MNEMONIC || '',
[eEthereumNetwork.main]: '', [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) => { const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number) => {
return { return {
url: `https://${networkName}.infura.io/v3/${INFURA_KEY}`, 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: { solc: {
version: '0.6.8', version: '0.6.8',
optimizer: {enabled: true, runs: 200}, optimizer: {enabled: true, runs: 200},
@ -50,7 +63,6 @@ const config: any = {
target: 'ethers-v4', target: 'ethers-v4',
}, },
etherscan: { etherscan: {
url: 'https://api-kovan.etherscan.io/api',
apiKey: ETHERSCAN_KEY, apiKey: ETHERSCAN_KEY,
}, },
defaultNetwork: 'buidlerevm', 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 amount,
uint256 fee, uint256 fee,
bytes calldata params 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 //slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
uint256 internal immutable _stableRateSlope2; uint256 internal immutable _stableRateSlope2;
constructor( constructor(
LendingPoolAddressesProvider provider, LendingPoolAddressesProvider provider,
uint256 baseVariableBorrowRate, uint256 baseVariableBorrowRate,
@ -96,7 +95,6 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
} }
struct CalcInterestRatesLocalVars { struct CalcInterestRatesLocalVars {
uint256 totalBorrows; uint256 totalBorrows;
uint256 currentVariableBorrowRate; uint256 currentVariableBorrowRate;
uint256 currentStableBorrowRate; uint256 currentStableBorrowRate;
@ -133,7 +131,6 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
uint256 uint256
) )
{ {
CalcInterestRatesLocalVars memory vars; CalcInterestRatesLocalVars memory vars;
vars.totalBorrows = totalStableDebt.add(totalVariableDebt); vars.totalBorrows = totalStableDebt.add(totalVariableDebt);
@ -172,13 +169,18 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
vars.currentLiquidityRate = _getOverallBorrowRate( vars.currentLiquidityRate = _getOverallBorrowRate(
totalStableDebt, totalStableDebt,
totalVariableDebt, totalVariableDebt,
vars.currentVariableBorrowRate, vars
.currentVariableBorrowRate,
averageStableBorrowRate averageStableBorrowRate
) )
.rayMul(utilizationRate) .rayMul(utilizationRate)
.percentMul(PercentageMath.PERCENTAGE_FACTOR.sub(reserveFactor)); .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; if (totalBorrows == 0) return 0;
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul( uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
currentVariableBorrowRate
);
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul( uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
currentAverageStableBorrowRate
);
uint256 overallBorrowRate = weightedVariableRate.add(weightedStableRate).rayDiv( uint256 overallBorrowRate = weightedVariableRate.add(weightedStableRate).rayDiv(
totalBorrows.wadToRay() totalBorrows.wadToRay()

View File

@ -579,7 +579,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount); IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
//execute action of the receiver //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); vars.amountPlusPremium = amount.add(vars.premium);
@ -876,6 +879,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
emit Unpaused(); emit Unpaused();
} }
} }
// internal functions // internal functions
struct ExecuteBorrowParams { struct ExecuteBorrowParams {
address asset; address asset;

View File

@ -25,5 +25,4 @@ contract LendingPoolStorage {
bool internal _flashLiquidationLocked; bool internal _flashLiquidationLocked;
bool internal _paused; 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 {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {WadRayMath} from '../math/WadRayMath.sol'; import {WadRayMath} from '../math/WadRayMath.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
/** /**
* @title UserConfiguration library * @title UserConfiguration library
* @author Aave * @author Aave

View File

@ -44,6 +44,7 @@ library Errors {
string public constant FAILED_COLLATERAL_SWAP = '55'; string public constant FAILED_COLLATERAL_SWAP = '55';
string public constant INVALID_EQUAL_ASSETS_TO_SWAP = '56'; string public constant INVALID_EQUAL_ASSETS_TO_SWAP = '56';
string public constant NO_MORE_RESERVES_ALLOWED = '59'; string public constant NO_MORE_RESERVES_ALLOWED = '59';
string public constant INVALID_FLASH_LOAN_EXECUTOR_RETURN = '60';
// require error messages - aToken - DebtTokens // require error messages - aToken - DebtTokens
string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool' 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; bool _failExecution;
uint256 _amountToApprove; uint256 _amountToApprove;
bool _simulateEOA;
constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {} constructor(ILendingPoolAddressesProvider provider) public FlashLoanReceiverBase(provider) {}
@ -31,16 +32,25 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
_amountToApprove = amountToApprove; _amountToApprove = amountToApprove;
} }
function setSimulateEOA(bool flag) public {
_simulateEOA = flag;
}
function amountToApprove() public view returns (uint256) { function amountToApprove() public view returns (uint256) {
return _amountToApprove; return _amountToApprove;
} }
function simulateEOA() public view returns (bool) {
return _simulateEOA;
}
function executeOperation( function executeOperation(
address reserve, address reserve,
uint256 amount, uint256 amount,
uint256 fee, uint256 fee,
bytes memory params bytes memory params
) public override { ) public override returns (bool) {
params;
//mint to this contract the specific amount //mint to this contract the specific amount
MintableERC20 token = MintableERC20(reserve); MintableERC20 token = MintableERC20(reserve);
@ -51,7 +61,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
if (_failExecution) { if (_failExecution) {
emit ExecutedWithFail(reserve, amount, fee); emit ExecutedWithFail(reserve, amount, fee);
return; return !_simulateEOA;
} }
//execution does not fail - mint tokens and return them to the _destination //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); IERC20(reserve).approve(_addressesProvider.getLendingPool(), amountToReturn);
emit ExecutedWithSuccess(reserve, amount, fee); emit ExecutedWithSuccess(reserve, amount, fee);
return true;
} }
} }

View File

@ -12,7 +12,17 @@ contract MockAToken is AToken {
string memory tokenName, string memory tokenName,
string memory tokenSymbol, string memory tokenSymbol,
address incentivesController 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) { function getRevision() internal override pure returns (uint256) {
return 0x2; return 0x2;

View File

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

View File

@ -60,7 +60,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 amount, uint256 amount,
uint256 index uint256 index
) external override onlyLendingPool { ) external override onlyLendingPool {
uint256 amountScaled = amount.rayDiv(index); uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT); require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);
@ -80,7 +79,6 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
uint256 amount, uint256 amount,
uint256 index uint256 index
) external override onlyLendingPool { ) external override onlyLendingPool {
uint256 amountScaled = amount.rayDiv(index); uint256 amountScaled = amount.rayDiv(index);
require(amountScaled != 0, Errors.INVALID_BURN_AMOUNT); require(amountScaled != 0, Errors.INVALID_BURN_AMOUNT);
@ -120,8 +118,12 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
* @return the principal balance of the user * @return the principal balance of the user
* @return the principal total supply * @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()); 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 value the amount to be redeemed
* @param index the last index of the reserve * @param index the last index of the reserve
**/ **/
event Burn( event Burn(address indexed from, address indexed target, uint256 value, uint256 index);
address indexed from,
address indexed target,
uint256 value,
uint256 index
);
/** /**
* @dev emitted during the transfer action * @dev emitted during the transfer action
* @param from the address from which the tokens are being transferred * @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 value the amount to be minted
* @param index the last index of the reserve * @param index the last index of the reserve
**/ **/
event BalanceTransfer( event BalanceTransfer(address indexed from, address indexed to, uint256 value, uint256 index);
address indexed from,
address indexed to,
uint256 value,
uint256 index
);
/** /**
* @dev burns the aTokens and sends the equivalent amount of underlying to the target. * @dev burns the aTokens and sends the equivalent amount of underlying to the target.
* only lending pools can call this function * only lending pools can call this function
@ -63,7 +54,6 @@ interface IAToken is IERC20, IScaledBalanceToken {
uint256 value uint256 value
) external; ) external;
function isTransferAllowed(address user, uint256 amount) external view returns (bool); function isTransferAllowed(address user, uint256 amount) external view returns (bool);
/** /**
@ -73,6 +63,4 @@ interface IAToken is IERC20, IScaledBalanceToken {
* @return the amount transferred * @return the amount transferred
**/ **/
function transferUnderlyingTo(address user, uint256 amount) external returns (uint256); function transferUnderlyingTo(address user, uint256 amount) external returns (uint256);
} }

View File

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

View File

@ -9,18 +9,13 @@ import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
* @notice defines the basic interface for a variable debt token. * @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 * @dev emitted when variable debt is burnt
* @param user the user which debt has been burned * @param user the user which debt has been burned
* @param amount the amount of debt being burned * @param amount the amount of debt being burned
* @param index the index of the user * @param index the index of the user
**/ **/
event Burn( event Burn(address indexed user, uint256 amount, uint256 index);
address indexed user,
uint256 amount,
uint256 index
);
/** /**
* @dev burns user variable debt * @dev burns user variable debt
@ -32,5 +27,4 @@ interface IVariableDebtToken is IScaledBalanceToken {
uint256 amount, uint256 amount,
uint256 index uint256 index
) external; ) external;
} }

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

@ -8,3 +8,8 @@ services:
command: npm run run-env command: npm run run-env
volumes: volumes:
- ./:/src - ./:/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 BigNumber from 'bignumber.js';
import {getParamPerNetwork, getParamPerPool} from './contracts-helpers';
// ---------------- // ----------------
// MATH // 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 oneRay = new BigNumber(Math.pow(10, 27));
export const MAX_UINT_AMOUNT = export const MAX_UINT_AMOUNT =
'115792089237316195423570985008687907853269984665640564039457584007913129639935'; '115792089237316195423570985008687907853269984665640564039457584007913129639935';
export const ONE_YEAR = '31536000';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
// ---------------- // ----------------
// PROTOCOL GLOBAL PARAMS // PROTOCOL GLOBAL PARAMS
// ---------------- // ----------------
export const OPTIMAL_UTILIZATION_RATE = new BigNumber(0.8).times(RAY); export const OPTIMAL_UTILIZATION_RATE = new BigNumber(0.8).times(RAY);
export const EXCESS_UTILIZATION_RATE = new BigNumber(0.2).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 APPROVAL_AMOUNT_LENDING_POOL = '1000000000000000000000000000';
export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000'; export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000';
export const MOCK_USD_PRICE_IN_WEI = '5848466240000000'; export const MOCK_USD_PRICE_IN_WEI = '5848466240000000';
export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96'; export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96';
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
export const AAVE_REFERRAL = '0'; 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 {Contract, Signer, utils, ethers} from 'ethers';
import {CommonsConfig} from '../config/commons';
import {getDb, BRE} from './misc-utils'; import {getDb, BRE} from './misc-utils';
import { import {
tEthereumAddress, tEthereumAddress,
@ -9,9 +9,15 @@ import {
AavePools, AavePools,
iParamsPerNetwork, iParamsPerNetwork,
iParamsPerPool, iParamsPerPool,
TokenContractId,
iMultiPoolsAssets,
IReserveParams,
ICommonConfiguration,
PoolConfiguration,
} from './types'; } from './types';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider'; import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {MintableErc20} from '../types/MintableErc20'; import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
import {LendingPoolAddressesProviderRegistry} from '../types/LendingPoolAddressesProviderRegistry'; import {LendingPoolAddressesProviderRegistry} from '../types/LendingPoolAddressesProviderRegistry';
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator'; import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
import {readArtifact} from '@nomiclabs/buidler/plugins'; import {readArtifact} from '@nomiclabs/buidler/plugins';
@ -31,10 +37,20 @@ import BigNumber from 'bignumber.js';
import {Ierc20Detailed} from '../types/Ierc20Detailed'; import {Ierc20Detailed} from '../types/Ierc20Detailed';
import {StableDebtToken} from '../types/StableDebtToken'; import {StableDebtToken} from '../types/StableDebtToken';
import {VariableDebtToken} from '../types/VariableDebtToken'; 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 {MockSwapAdapter} from '../types/MockSwapAdapter';
import {signTypedData_v4, TypedData} from 'eth-sig-util'; import {signTypedData_v4, TypedData} from 'eth-sig-util';
import {fromRpcSig, ECDSASignature} from 'ethereumjs-util'; import {fromRpcSig, ECDSASignature} from 'ethereumjs-util';
import {SignerWithAddress} from '../test/helpers/make-suite';
export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => { export const registerContractInJsonDb = async (contractId: string, contractInstance: Contract) => {
const currentNetwork = BRE.network.name; const currentNetwork = BRE.network.name;
@ -95,17 +111,38 @@ export const getContract = async <ContractType extends Contract>(
address: string address: string
): Promise<ContractType> => (await BRE.ethers.getContractAt(contractName, address)) as ContractType; ): Promise<ContractType> => (await BRE.ethers.getContractAt(contractName, address)) as ContractType;
export const deployLendingPoolAddressesProvider = async () => export const deployLendingPoolAddressesProvider = async (verify?: boolean) => {
await deployContract<LendingPoolAddressesProvider>(eContractid.LendingPoolAddressesProvider, []); const instance = await deployContract<LendingPoolAddressesProvider>(
eContractid.LendingPoolAddressesProvider,
[]
);
if (verify) {
await verifyContract(eContractid.LendingPoolAddressesProvider, instance.address, []);
}
return instance;
};
export const deployLendingPoolAddressesProviderRegistry = async () => export const deployLendingPoolAddressesProviderRegistry = async (verify?: boolean) => {
await deployContract<LendingPoolAddressesProviderRegistry>( const instance = await deployContract<LendingPoolAddressesProviderRegistry>(
eContractid.LendingPoolAddressesProviderRegistry, eContractid.LendingPoolAddressesProviderRegistry,
[] []
); );
if (verify) {
await verifyContract(eContractid.LendingPoolAddressesProviderRegistry, instance.address, []);
}
return instance;
};
export const deployLendingPoolConfigurator = async () => export const deployLendingPoolConfigurator = async (verify?: boolean) => {
await deployContract<LendingPoolConfigurator>(eContractid.LendingPoolConfigurator, []); const instance = await deployContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator,
[]
);
if (verify) {
await verifyContract(eContractid.LendingPoolConfigurator, instance.address, []);
}
return instance;
};
const deployLibrary = async (libraryId: eContractid) => { const deployLibrary = async (libraryId: eContractid) => {
const factory = await BRE.ethers.getContractFactory(libraryId); const factory = await BRE.ethers.getContractFactory(libraryId);
@ -161,87 +198,152 @@ export const linkLibrariesToArtifact = async (artifact: Artifact) => {
return factory; return factory;
}; };
export const deployLendingPool = async () => { export const deployLendingPool = async (verify?: boolean) => {
const lendingPoolArtifact = await readArtifact( const lendingPoolArtifact = await readArtifact(
BRE.config.paths.artifacts, BRE.config.paths.artifacts,
eContractid.LendingPool eContractid.LendingPool
); );
const factory = await linkLibrariesToArtifact(lendingPoolArtifact); const factory = await linkLibrariesToArtifact(lendingPoolArtifact);
const lendingPool = await factory.deploy(); 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 () => export const deployPriceOracle = async (verify?: boolean) => {
await deployContract<PriceOracle>(eContractid.PriceOracle, []); const instance = await deployContract<PriceOracle>(eContractid.PriceOracle, []);
if (verify) {
await verifyContract(eContractid.PriceOracle, instance.address, []);
}
return instance;
};
export const deployMockAggregator = async (price: tStringTokenSmallUnits) => export const deployLendingRateOracle = async (verify?: boolean) => {
await deployContract<MockAggregator>(eContractid.MockAggregator, [price]); const instance = await deployContract<LendingRateOracle>(eContractid.LendingRateOracle, []);
if (verify) {
await verifyContract(eContractid.LendingRateOracle, instance.address, []);
}
return instance;
};
export const deployChainlinkProxyPriceProvider = async ([ export const deployMockAggregator = async (price: tStringTokenSmallUnits, verify?: boolean) => {
assetsAddresses, const args = [price];
sourcesAddresses, const instance = await deployContract<MockAggregator>(eContractid.MockAggregator, args);
fallbackOracleAddress, if (verify) {
]: [tEthereumAddress[], tEthereumAddress[], tEthereumAddress]) => await verifyContract(eContractid.MockAggregator, instance.address, args);
await deployContract<MockAggregator>(eContractid.ChainlinkProxyPriceProvider, [ }
assetsAddresses, return instance;
sourcesAddresses, };
fallbackOracleAddress,
]);
export const deployLendingRateOracle = async () => export const deployChainlinkProxyPriceProvider = async (
await deployContract<LendingRateOracle>(eContractid.LendingRateOracle, []); [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( const collateralManagerArtifact = await readArtifact(
BRE.config.paths.artifacts, BRE.config.paths.artifacts,
eContractid.LendingPoolCollateralManager eContractid.LendingPoolCollateralManager
); );
const factory = await linkLibrariesToArtifact(collateralManagerArtifact); 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(); if (verify) {
return (await collateralManager.deployed()) as LendingPoolCollateralManager; await verifyContract(eContractid.LendingPoolCollateralManager, instance.address, args);
}
return instance;
}; };
export const deployInitializableAdminUpgradeabilityProxy = async () => export const deployInitializableAdminUpgradeabilityProxy = async (verify?: boolean) => {
await deployContract<InitializableAdminUpgradeabilityProxy>( const instance = await deployContract<InitializableAdminUpgradeabilityProxy>(
eContractid.InitializableAdminUpgradeabilityProxy, eContractid.InitializableAdminUpgradeabilityProxy,
[] []
); );
if (verify) {
await verifyContract(eContractid.InitializableAdminUpgradeabilityProxy, instance.address, []);
}
return instance;
};
export const deployMockFlashLoanReceiver = async (addressesProvider: tEthereumAddress) => export const deployMockFlashLoanReceiver = async (
await deployContract<MockFlashLoanReceiver>(eContractid.MockFlashLoanReceiver, [ addressesProvider: tEthereumAddress,
addressesProvider, 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) => export const deployMockSwapAdapter = async (addressesProvider: tEthereumAddress) =>
await deployContract<MockSwapAdapter>(eContractid.MockSwapAdapter, [addressesProvider]); await deployContract<MockSwapAdapter>(eContractid.MockSwapAdapter, [addressesProvider]);
export const deployWalletBalancerProvider = async (addressesProvider: tEthereumAddress) => export const deployAaveProtocolTestHelpers = async (
await deployContract<WalletBalanceProvider>(eContractid.WalletBalanceProvider, [ addressesProvider: tEthereumAddress,
addressesProvider, verify?: boolean
]); ) => {
const args = [addressesProvider];
const instance = await deployContract<AaveProtocolTestHelpers>(
eContractid.AaveProtocolTestHelpers,
args
);
export const deployAaveProtocolTestHelpers = async (addressesProvider: tEthereumAddress) => if (verify) {
await deployContract<AaveProtocolTestHelpers>(eContractid.AaveProtocolTestHelpers, [ await verifyContract(eContractid.AaveProtocolTestHelpers, instance.address, args);
addressesProvider, }
]); return instance;
};
export const deployMintableErc20 = async ([name, symbol, decimals]: [string, string, number]) => export const deployMintableERC20 = async ([name, symbol, decimals]: [string, string, number]) =>
await deployContract<MintableErc20>(eContractid.MintableERC20, [name, symbol, decimals]); await deployContract<MintableERC20>(eContractid.MintableERC20, [name, symbol, decimals]);
export const deployDefaultReserveInterestRateStrategy = async ([ export const deployDefaultReserveInterestRateStrategy = async (
addressesProvider,
baseVariableBorrowRate,
variableSlope1,
variableSlope2,
stableSlope1,
stableSlope2,
]: [tEthereumAddress, string, string, string, string, string]) =>
await deployContract<DefaultReserveInterestRateStrategy>(
eContractid.DefaultReserveInterestRateStrategy,
[ [
addressesProvider, addressesProvider,
baseVariableBorrowRate, baseVariableBorrowRate,
@ -249,63 +351,91 @@ export const deployDefaultReserveInterestRateStrategy = async ([
variableSlope2, variableSlope2,
stableSlope1, stableSlope1,
stableSlope2, 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);
export const deployStableDebtToken = async ([ if (verify) {
name, await verifyContract(id, instance.address, args);
symbol, }
underlyingAsset, return instance;
poolAddress,
incentivesController,
]: [string, string, tEthereumAddress, tEthereumAddress, tEthereumAddress]) => {
const token = await deployContract<StableDebtToken>(eContractid.StableDebtToken, [
poolAddress,
underlyingAsset,
name,
symbol,
incentivesController,
]);
return token;
}; };
export const deployVariableDebtToken = async ([ export const deployStableDebtToken = async (
name, [name, symbol, underlyingAsset, poolAddress, incentivesController]: [
symbol, string,
underlyingAsset, string,
poolAddress, tEthereumAddress,
incentivesController, tEthereumAddress,
]: [string, string, tEthereumAddress, tEthereumAddress, tEthereumAddress]) => { tEthereumAddress
const token = await deployContract<VariableDebtToken>(eContractid.VariableDebtToken, [ ],
poolAddress, verify: boolean
underlyingAsset, ) => {
name, const id = eContractid.StableDebtToken;
symbol, const args = [poolAddress, underlyingAsset, name, symbol, incentivesController];
incentivesController, const instance = await deployContract<StableDebtToken>(id, args);
]);
return token; if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
}; };
export const deployGenericAToken = async ([ export const deployVariableDebtToken = async (
poolAddress, [name, symbol, underlyingAsset, poolAddress, incentivesController]: [
underlyingAssetAddress, string,
reserveTreasuryAddress, string,
name, tEthereumAddress,
symbol, tEthereumAddress,
incentivesController, tEthereumAddress
]: [tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, tEthereumAddress]) => { ],
const token = await deployContract<AToken>(eContractid.AToken, [ verify: boolean
poolAddress, ) => {
underlyingAssetAddress, const id = eContractid.VariableDebtToken;
reserveTreasuryAddress, const args = [poolAddress, underlyingAsset, name, symbol, incentivesController];
name, const instance = await deployContract<VariableDebtToken>(id, args);
symbol,
incentivesController,
]);
return token; 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,
ZERO_ADDRESS,
name,
symbol,
incentivesController,
];
const instance = await deployContract<AToken>(id, args);
if (verify) {
await verifyContract(id, instance.address, args);
}
return instance;
}; };
export const getLendingPoolAddressesProvider = async (address?: tEthereumAddress) => { 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) => { export const getLendingPoolConfiguratorProxy = async (address?: tEthereumAddress) => {
return await getContract<LendingPoolConfigurator>( return await getContract<LendingPoolConfigurator>(
eContractid.LendingPoolConfigurator, eContractid.LendingPoolConfigurator,
@ -368,20 +489,21 @@ export const getAToken = async (address?: tEthereumAddress) => {
export const getStableDebtToken = async (address?: tEthereumAddress) => { export const getStableDebtToken = async (address?: tEthereumAddress) => {
return await getContract<AToken>( return await getContract<AToken>(
eContractid.StableDebtToken, 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) => { export const getVariableDebtToken = async (address?: tEthereumAddress) => {
return await getContract<AToken>( return await getContract<AToken>(
eContractid.VariableDebtToken, 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) => { export const getMintableErc20 = async (address: tEthereumAddress) => {
return await getContract<MintableErc20>( return await getContract<MintableERC20>(
eContractid.MintableERC20, eContractid.MintableERC20,
address || address ||
(await getDb().get(`${eContractid.MintableERC20}.${BRE.network.name}`).value()).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(); 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 = ( export const buildPermitParams = (
chainId: number, chainId: number,
token: tEthereumAddress, 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 low from 'lowdb';
import FileSync from 'lowdb/adapters/FileSync'; import FileSync from 'lowdb/adapters/FileSync';
import {WAD} from './constants'; import {WAD} from './constants';
import {Wallet} from 'ethers'; import {Wallet, ContractTransaction} from 'ethers';
import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types'; import {BuidlerRuntimeEnvironment} from '@nomiclabs/buidler/types';
export const toWad = (value: string | number) => new BigNumber(value).times(WAD).toFixed(); 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_increaseTime', [secondsToIncrease]);
await BRE.ethers.provider.send('evm_mine', []); 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 BigNumber from 'bignumber.js';
import {MockTokenMap} from './contracts-helpers';
export interface SymbolMap<T> {
[symbol: string]: T;
}
export enum eEthereumNetwork { export enum eEthereumNetwork {
buidlerevm = 'buidlerevm', buidlerevm = 'buidlerevm',
@ -8,6 +13,12 @@ export enum eEthereumNetwork {
coverage = 'coverage', coverage = 'coverage',
} }
export enum EthereumNetworkNames {
kovan = 'kovan',
ropsten = 'ropsten',
main = 'main',
}
export enum AavePools { export enum AavePools {
proto = 'proto', proto = 'proto',
secondary = 'secondary', secondary = 'secondary',
@ -43,6 +54,8 @@ export enum eContractid {
IERC20Detailed = 'IERC20Detailed', IERC20Detailed = 'IERC20Detailed',
StableDebtToken = 'StableDebtToken', StableDebtToken = 'StableDebtToken',
VariableDebtToken = 'VariableDebtToken', VariableDebtToken = 'VariableDebtToken',
FeeProvider = 'FeeProvider',
TokenDistributor = 'TokenDistributor',
} }
export enum ProtocolErrors { export enum ProtocolErrors {
@ -77,6 +90,7 @@ export enum ProtocolErrors {
REQUESTED_AMOUNT_TOO_SMALL = '25', // 'The requested amount is too small for a FlashLoan.' 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' 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' 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 // require error messages - aToken
CALLER_MUST_BE_LENDING_POOL = '28', // 'The caller of this function must be a lending pool' 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 tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC, or 1 basic unit of DAI
export type tBigNumberTokenSmallUnits = BigNumber; export type tBigNumberTokenSmallUnits = BigNumber;
export interface iAssetCommon<T> {
[key: string]: T;
}
export interface iAssetBase<T> { export interface iAssetBase<T> {
WETH: T; WETH: T;
DAI: T; DAI: T;
@ -154,7 +171,6 @@ export type iAssetsWithoutUSD<T> = Omit<iAssetBase<T>, 'USD'>;
export type iAavePoolAssets<T> = Pick< export type iAavePoolAssets<T> = Pick<
iAssetsWithoutUSD<T>, iAssetsWithoutUSD<T>,
| 'WETH'
| 'DAI' | 'DAI'
| 'TUSD' | 'TUSD'
| 'USDC' | 'USDC'
@ -193,7 +209,7 @@ export type iAaveSecondPoolAssets<T> = Pick<
| 'UNI_LINK_ETH' | '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'>; export type iAavePoolTokens<T> = Omit<iAavePoolAssets<T>, 'ETH'>;
@ -271,3 +287,75 @@ export enum RateMode {
Stable = '1', Stable = '1',
Variable = '2', 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": { "scripts": {
"run-env": "npm i && tail -f /dev/null", "run-env": "npm i && tail -f /dev/null",
"buidler": "buidler", "buidler": "buidler",
"buidler-kovan": "buidler --network kovan", "buidler:kovan": "buidler --network kovan",
"buidler-ropsten": "buidler --network ropsten", "buidler:ropsten": "buidler--network ropsten",
"buidler-main": "buidler --network main", "buidler:main": "buidler --network main",
"buidler help": "buidler help", "buidler help": "buidler help",
"compile": "buidler compile", "compile": "SKIP_LOAD=true buidler compile",
"types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'", "types-gen": "typechain --target ethers-v5 --outDir ./types './artifacts/*.json'",
"test": "buidler test", "test": "buidler test",
"test-scenarios": "buidler test test/__setup.spec.ts test/scenario.spec.ts", "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-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-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", "test-transfers": "buidler test test/__setup.spec.ts test/atoken-transfer.spec.ts",
@ -28,13 +44,13 @@
"ci:clean": "rm -rf ./artifacts ./cache ./types" "ci:clean": "rm -rf ./artifacts ./cache ./types"
}, },
"devDependencies": { "devDependencies": {
"@nomiclabs/buidler": "1.4.4", "@nomiclabs/buidler": "^1.4.7",
"@nomiclabs/buidler-ethers": "2.0.0", "@nomiclabs/buidler-ethers": "2.0.0",
"@nomiclabs/buidler-etherscan": "1.3.3", "@nomiclabs/buidler-etherscan": "^2.1.0",
"@nomiclabs/buidler-waffle": "2.0.0", "@nomiclabs/buidler-waffle": "2.0.0",
"@openzeppelin/contracts": "3.1.0", "@openzeppelin/contracts": "3.1.0",
"@typechain/ethers-v5": "^1.0.0",
"@typechain/ethers-v4": "1.0.0", "@typechain/ethers-v4": "1.0.0",
"@typechain/ethers-v5": "^1.0.0",
"@typechain/truffle-v4": "2.0.2", "@typechain/truffle-v4": "2.0.2",
"@typechain/truffle-v5": "2.0.2", "@typechain/truffle-v5": "2.0.2",
"@typechain/web3-v1": "1.0.0", "@typechain/web3-v1": "1.0.0",
@ -48,7 +64,9 @@
"chai": "4.2.0", "chai": "4.2.0",
"chai-bignumber": "3.0.0", "chai-bignumber": "3.0.0",
"chai-bn": "^0.2.1", "chai-bn": "^0.2.1",
"eth-sig-util": "2.5.3",
"ethereum-waffle": "3.0.2", "ethereum-waffle": "3.0.2",
"ethereumjs-util": "7.0.2",
"ethers": "5.0.8", "ethers": "5.0.8",
"husky": "^4.2.5", "husky": "^4.2.5",
"lowdb": "1.0.0", "lowdb": "1.0.0",
@ -62,9 +80,7 @@
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.3.0", "tslint-plugin-prettier": "^2.3.0",
"typechain": "2.0.0", "typechain": "2.0.0",
"typescript": "3.9.3", "typescript": "3.9.3"
"eth-sig-util": "2.5.3",
"ethereumjs-util": "7.0.2"
}, },
"husky": { "husky": {
"hooks": { "hooks": {
@ -86,5 +102,8 @@
"email": "andrey@aave.com" "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 {MockContract} from 'ethereum-waffle';
import { import {
deployLendingPoolAddressesProvider, deployLendingPoolAddressesProvider,
deployMintableErc20, deployMintableERC20,
deployLendingPoolAddressesProviderRegistry, deployLendingPoolAddressesProviderRegistry,
deployLendingPoolConfigurator, deployLendingPoolConfigurator,
deployLendingPool, deployLendingPool,
deployPriceOracle, deployPriceOracle,
getLendingPoolConfiguratorProxy, getLendingPoolConfiguratorProxy,
deployMockAggregator,
deployChainlinkProxyPriceProvider, deployChainlinkProxyPriceProvider,
deployLendingRateOracle,
deployDefaultReserveInterestRateStrategy,
deployLendingPoolCollateralManager, deployLendingPoolCollateralManager,
deployMockFlashLoanReceiver, deployMockFlashLoanReceiver,
deployWalletBalancerProvider, deployWalletBalancerProvider,
@ -20,52 +17,36 @@ import {
deployAaveProtocolTestHelpers, deployAaveProtocolTestHelpers,
getEthersSigners, getEthersSigners,
registerContractInJsonDb, registerContractInJsonDb,
deployStableDebtToken, getPairsTokenAggregator,
deployVariableDebtToken, initReserves,
deployGenericAToken,
deployMockSwapAdapter, deployMockSwapAdapter,
deployLendingRateOracle,
} from '../helpers/contracts-helpers'; } from '../helpers/contracts-helpers';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider'; import {Signer} from 'ethers';
import {ContractTransaction, Signer} from 'ethers'; import {TokenContractId, eContractid, tEthereumAddress, AavePools} from '../helpers/types';
import { import {MintableErc20 as MintableERC20} from '../types/MintableErc20';
TokenContractId, import {getReservesConfigByPool} from '../helpers/configuration';
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 {initializeMakeSuite} from './helpers/make-suite'; import {initializeMakeSuite} from './helpers/make-suite';
import path from 'path';
import fs from 'fs';
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers'; import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
['misc'].forEach((folder) => { import {
const tasksPath = path.join(__dirname, '../', 'tasks', folder); setInitialAssetPricesInOracle,
fs.readdirSync(tasksPath).forEach((task) => require(`${tasksPath}/${task}`)); 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 deployAllMockTokens = async (deployer: Signer) => {
const tokens: {[symbol: string]: MockContract | MintableErc20} = {}; const tokens: {[symbol: string]: MockContract | MintableERC20} = {};
const protoConfigData = getReservesConfigByPool(AavePools.proto); const protoConfigData = getReservesConfigByPool(AavePools.proto);
const secondaryConfigData = getReservesConfigByPool(AavePools.secondary); const secondaryConfigData = getReservesConfigByPool(AavePools.secondary);
@ -83,7 +64,7 @@ const deployAllMockTokens = async (deployer: Signer) => {
decimals = 18; decimals = 18;
} }
tokens[tokenSymbol] = await deployMintableErc20([ tokens[tokenSymbol] = await deployMintableERC20([
tokenSymbol, tokenSymbol,
tokenSymbol, tokenSymbol,
configData ? configData.reserveDecimals : 18, configData ? configData.reserveDecimals : 18,
@ -94,266 +75,6 @@ const deployAllMockTokens = async (deployer: Signer) => {
return tokens; 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) => { const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
console.time('setup'); console.time('setup');
const aaveAdmin = await deployer.getAddress(); const aaveAdmin = await deployer.getAddress();
@ -491,10 +212,11 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
protoPoolReservesAddresses, protoPoolReservesAddresses,
addressesProvider, addressesProvider,
lendingPoolProxy, lendingPoolProxy,
lendingPoolConfiguratorProxy,
testHelpers, testHelpers,
lendingPoolConfiguratorProxy,
AavePools.proto, AavePools.proto,
ZERO_ADDRESS ZERO_ADDRESS,
false
); );
await enableReservesToBorrow( await enableReservesToBorrow(
reservesParams, reservesParams,

View File

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

View File

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

View File

@ -1,14 +1,14 @@
import { import {MAX_UINT_AMOUNT, ZERO_ADDRESS} from '../helpers/constants';
APPROVAL_AMOUNT_LENDING_POOL,
AAVE_REFERRAL,
MAX_UINT_AMOUNT,
ZERO_ADDRESS,
} from '../helpers/constants';
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers'; import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {expect} from 'chai'; import {expect} from 'chai';
import {ethers} from 'ethers'; import {ethers} from 'ethers';
import {RateMode, ProtocolErrors} from '../helpers/types'; import {RateMode, ProtocolErrors} from '../helpers/types';
import {makeSuite, TestEnv} from './helpers/make-suite'; 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) => { makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
const { const {

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
INVALID_FLASHLOAN_MODE, INVALID_FLASHLOAN_MODE,
SAFEERC20_LOWLEVEL_CALL, SAFEERC20_LOWLEVEL_CALL,
IS_PAUSED, IS_PAUSED,
INVALID_FLASH_LOAN_EXECUTOR_RETURN,
} = ProtocolErrors; } = ProtocolErrors;
before(async () => { before(async () => {
@ -116,9 +117,30 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
).to.be.revertedWith(TRANSFER_AMOUNT_EXCEEDS_BALANCE); ).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 () => { it('Takes a WETH flashloan with an invalid mode. (revert expected)', async () => {
const {pool, weth, users} = testEnv; const {pool, weth, users} = testEnv;
const caller = users[1]; const caller = users[1];
await _mockFlashLoanReceiver.setSimulateEOA(false);
await _mockFlashLoanReceiver.setFailExecutionTransfer(true); await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
await expect( await expect(

View File

@ -24,11 +24,10 @@ import {
} from '../../helpers/contracts-helpers'; } from '../../helpers/contracts-helpers';
import {MAX_UINT_AMOUNT, ONE_YEAR} from '../../helpers/constants'; import {MAX_UINT_AMOUNT, ONE_YEAR} from '../../helpers/constants';
import {SignerWithAddress, TestEnv} from './make-suite'; 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 chai from 'chai';
import {ReserveData, UserReserveData} from './utils/interfaces'; import {ReserveData, UserReserveData} from './utils/interfaces';
import {waitForTx} from '../__setup.spec';
import {ContractReceipt} from 'ethers'; import {ContractReceipt} from 'ethers';
import {AToken} from '../../types/AToken'; import {AToken} from '../../types/AToken';
import {RateMode, tEthereumAddress} from '../../helpers/types'; import {RateMode, tEthereumAddress} from '../../helpers/types';

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +1,16 @@
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import {BRE} from '../helpers/misc-utils'; 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 {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {makeSuite} from './helpers/make-suite'; import {makeSuite} from './helpers/make-suite';
import {ProtocolErrors, RateMode} from '../helpers/types'; import {ProtocolErrors, RateMode} from '../helpers/types';
import {calcExpectedVariableDebtTokenBalance} from './helpers/utils/calculations'; import {calcExpectedVariableDebtTokenBalance} from './helpers/utils/calculations';
import {getUserData, getReserveData} from './helpers/utils/helpers'; 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 chai = require('chai');
const {expect} = chai; const {expect} = chai;

View File

@ -1,12 +1,16 @@
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import {BRE, increaseTime} from '../helpers/misc-utils'; 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 {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
import {makeSuite} from './helpers/make-suite'; import {makeSuite} from './helpers/make-suite';
import {ProtocolErrors, RateMode} from '../helpers/types'; import {ProtocolErrors, RateMode} from '../helpers/types';
import {calcExpectedStableDebtTokenBalance} from './helpers/utils/calculations'; import {calcExpectedStableDebtTokenBalance} from './helpers/utils/calculations';
import {getUserData} from './helpers/utils/helpers'; 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'; import {parseEther} from 'ethers/lib/utils';
const chai = require('chai'); const chai = require('chai');

View File

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

View File

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

View File

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