Merge branch 'master' into 178-add-uniswap-adapters

This commit is contained in:
The3D 2020-12-02 10:14:03 +01:00
commit 2e23281cdc
19 changed files with 658 additions and 322 deletions

View File

@ -0,0 +1,28 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.6.12;
interface ICreditDelegationToken {
event BorrowAllowanceDelegated(
address indexed fromUser,
address indexed toUser,
address asset,
uint256 amount
);
/**
* @dev delegates borrowing power to a user on the specific debt token
* @param delegatee the address receiving the delegated borrowing power
* @param amount the maximum amount being delegated. Delegation will still
* respect the liquidation constraints (even if delegated, a delegatee cannot
* force a delegator HF to go below 1)
**/
function approveDelegation(address delegatee, uint256 amount) external;
/**
* @dev returns the borrow allowance of the user
* @param fromUser The user to giving allowance
* @param toUser The user to give allowance to
* @return the current allowance of toUser
**/
function borrowAllowance(address fromUser, address toUser) external view returns (uint256);
}

View File

@ -2,6 +2,7 @@
pragma solidity 0.6.12; pragma solidity 0.6.12;
import {ILendingPool} from '../../../interfaces/ILendingPool.sol'; import {ILendingPool} from '../../../interfaces/ILendingPool.sol';
import {ICreditDelegationToken} from '../../../interfaces/ICreditDelegationToken.sol';
import { import {
VersionedInitializable VersionedInitializable
} from '../../libraries/aave-upgradeability/VersionedInitializable.sol'; } from '../../libraries/aave-upgradeability/VersionedInitializable.sol';
@ -14,14 +15,11 @@ import {Errors} from '../../libraries/helpers/Errors.sol';
* @author Aave * @author Aave
*/ */
abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable { abstract contract DebtTokenBase is
event BorrowAllowanceDelegated( IncentivizedERC20,
address indexed fromUser, VersionedInitializable,
address indexed toUser, ICreditDelegationToken
address asset, {
uint256 amount
);
address public immutable UNDERLYING_ASSET_ADDRESS; address public immutable UNDERLYING_ASSET_ADDRESS;
ILendingPool public immutable POOL; ILendingPool public immutable POOL;
@ -73,7 +71,7 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
* respect the liquidation constraints (even if delegated, a delegatee cannot * respect the liquidation constraints (even if delegated, a delegatee cannot
* force a delegator HF to go below 1) * force a delegator HF to go below 1)
**/ **/
function approveDelegation(address delegatee, uint256 amount) external { function approveDelegation(address delegatee, uint256 amount) external override {
_borrowAllowances[_msgSender()][delegatee] = amount; _borrowAllowances[_msgSender()][delegatee] = amount;
emit BorrowAllowanceDelegated(_msgSender(), delegatee, UNDERLYING_ASSET_ADDRESS, amount); emit BorrowAllowanceDelegated(_msgSender(), delegatee, UNDERLYING_ASSET_ADDRESS, amount);
} }
@ -84,7 +82,12 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
* @param toUser The user to give allowance to * @param toUser The user to give allowance to
* @return the current allowance of toUser * @return the current allowance of toUser
**/ **/
function borrowAllowance(address fromUser, address toUser) external view returns (uint256) { function borrowAllowance(address fromUser, address toUser)
external
view
override
returns (uint256)
{
return _borrowAllowances[fromUser][toUser]; return _borrowAllowances[fromUser][toUser];
} }

View File

@ -1,9 +1,6 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
import { HardhatUserConfig } from 'hardhat/types'; import { HardhatUserConfig } from 'hardhat/types';
require('dotenv').config();
// @ts-ignore // @ts-ignore
import { accounts } from './test-wallets.js'; import { accounts } from './test-wallets.js';
import { eEthereumNetwork } from './helpers/types'; import { eEthereumNetwork } from './helpers/types';
@ -65,7 +62,7 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number
const mainnetFork = MAINNET_FORK const mainnetFork = MAINNET_FORK
? { ? {
blockNumber: 11268220, blockNumber: 11361132,
url: ALCHEMY_KEY url: ALCHEMY_KEY
? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}` ? `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_KEY}`
: `https://main.infura.io/v3/${INFURA_KEY}`, : `https://main.infura.io/v3/${INFURA_KEY}`,

View File

@ -7,7 +7,7 @@ import {
getStableAndVariableTokensHelper, getStableAndVariableTokensHelper,
} from './contracts-getters'; } from './contracts-getters';
import { rawInsertContractAddressInDb } from './contracts-helpers'; import { rawInsertContractAddressInDb } from './contracts-helpers';
import { BigNumberish } from 'ethers'; import { BigNumber, BigNumberish } from 'ethers';
import { import {
deployDefaultReserveInterestRateStrategy, deployDefaultReserveInterestRateStrategy,
deployDelegationAwareAToken, deployDelegationAwareAToken,
@ -35,8 +35,8 @@ export const initReservesByHelper = async (
treasuryAddress: tEthereumAddress, treasuryAddress: tEthereumAddress,
incentivesController: tEthereumAddress, incentivesController: tEthereumAddress,
verify: boolean verify: boolean
) => { ): Promise<BigNumber> => {
let gasUsage = BigNumber.from('0');
const stableAndVariableDeployer = await getStableAndVariableTokensHelper(); const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
const atokenAndRatesDeployer = await getATokensAndRatesHelper(); const atokenAndRatesDeployer = await getATokensAndRatesHelper();
@ -47,8 +47,8 @@ export const initReservesByHelper = async (
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address)); await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
// CHUNK CONFIGURATION // CHUNK CONFIGURATION
const tokensChunks = 4; const tokensChunks = 2;
const initChunks = 6; const initChunks = 4;
// Deploy tokens and rates that uses common aToken in chunks // Deploy tokens and rates that uses common aToken in chunks
const reservesChunks = chunk( const reservesChunks = chunk(
@ -123,17 +123,13 @@ export const initReservesByHelper = async (
// Deploy stable and variable deployers and save implementations // Deploy stable and variable deployers and save implementations
const tx1 = await waitForTx( const tx1 = await waitForTx(
await stableAndVariableDeployer.initDeployment( await stableAndVariableDeployer.initDeployment(tokens, symbols, incentivesController)
tokens,
symbols,
incentivesController
)
); );
tx1.events?.forEach((event, index) => { tx1.events?.forEach((event, index) => {
rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken); rawInsertContractAddressInDb(`stableDebt${symbols[index]}`, event?.args?.stableToken);
rawInsertContractAddressInDb(`variableDebt${symbols[index]}`, event?.args?.variableToken); rawInsertContractAddressInDb(`variableDebt${symbols[index]}`, event?.args?.variableToken);
}); });
// Deploy atokens and rate strategies and save implementations // Deploy atokens and rate strategies and save implementations
const tx2 = await waitForTx( const tx2 = await waitForTx(
await atokenAndRatesDeployer.initDeployment( await atokenAndRatesDeployer.initDeployment(
@ -150,6 +146,10 @@ export const initReservesByHelper = async (
}); });
console.log(` - Deployed aToken, DebtTokens and Strategy for: ${symbols.join(', ')} `); console.log(` - Deployed aToken, DebtTokens and Strategy for: ${symbols.join(', ')} `);
console.log(' * gasUsed: debtTokens batch', tx1.gasUsed.toString());
console.log(' * gasUsed: aTokens and Strategy batch', tx2.gasUsed.toString());
gasUsage = gasUsage.add(tx1.gasUsed).add(tx2.gasUsed);
const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || []; const stableTokens: string[] = tx1.events?.map((e) => e.args?.stableToken) || [];
const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || []; const variableTokens: string[] = tx1.events?.map((e) => e.args?.variableToken) || [];
const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || []; const aTokens: string[] = tx2.events?.map((e) => e.args?.aToken) || [];
@ -252,11 +252,15 @@ export const initReservesByHelper = async (
chunkedDecimals[chunkIndex] chunkedDecimals[chunkIndex]
) )
); );
console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`); console.log(` - Reserve ready for: ${chunkedSymbols[chunkIndex].join(', ')}`);
console.log(' * gasUsed', tx3.gasUsed.toString());
gasUsage = gasUsage.add(tx3.gasUsed);
} }
// Set deployer back as admin // Set deployer back as admin
await waitForTx(await addressProvider.setPoolAdmin(admin)); await waitForTx(await addressProvider.setPoolAdmin(admin));
return gasUsage;
}; };
export const getPairsTokenAggregator = ( export const getPairsTokenAggregator = (
@ -304,7 +308,13 @@ export const configureReservesByHelper = async (
for (const [ for (const [
assetSymbol, assetSymbol,
{ baseLTVAsCollateral, liquidationBonus, liquidationThreshold, reserveFactor, stableBorrowRateEnabled }, {
baseLTVAsCollateral,
liquidationBonus,
liquidationThreshold,
reserveFactor,
stableBorrowRateEnabled,
},
] of Object.entries(reservesParams) as [string, IReserveParams][]) { ] of Object.entries(reservesParams) as [string, IReserveParams][]) {
if (baseLTVAsCollateral === '-1') continue; if (baseLTVAsCollateral === '-1') continue;

View File

@ -354,6 +354,7 @@ export interface ICommonConfiguration {
ProtocolGlobalParams: IProtocolGlobalConfig; ProtocolGlobalParams: IProtocolGlobalConfig;
Mocks: IMocksConfig; Mocks: IMocksConfig;
ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>; ProviderRegistry: iParamsPerNetwork<tEthereumAddress | undefined>;
ProviderRegistryOwner: iParamsPerNetwork<tEthereumAddress | undefined>;
LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>; LendingRateOracleRatesCommon: iMultiPoolsAssets<IMarketRates>;
LendingRateOracle: iParamsPerNetwork<tEthereumAddress>; LendingRateOracle: iParamsPerNetwork<tEthereumAddress>;
TokenDistributor: iParamsPerNetwork<tEthereumAddress>; TokenDistributor: iParamsPerNetwork<tEthereumAddress>;

View File

@ -137,13 +137,22 @@ export const CommonsConfig: ICommonConfiguration = {
}, },
EmergencyAdminIndex: 1, EmergencyAdminIndex: 1,
ProviderRegistry: { ProviderRegistry: {
[eEthereumNetwork.kovan]: '', [eEthereumNetwork.kovan]: '0x1E40B561EC587036f9789aF83236f057D1ed2A90',
[eEthereumNetwork.ropsten]: '', [eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '', [eEthereumNetwork.main]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
[eEthereumNetwork.coverage]: '', [eEthereumNetwork.coverage]: '',
[eEthereumNetwork.hardhat]: '', [eEthereumNetwork.hardhat]: '',
[eEthereumNetwork.buidlerevm]: '', [eEthereumNetwork.buidlerevm]: '',
[eEthereumNetwork.tenderlyMain]: '', [eEthereumNetwork.tenderlyMain]: '0x52D306e36E3B6B02c153d0266ff0f85d18BCD413',
},
ProviderRegistryOwner: {
[eEthereumNetwork.kovan]: '0x85e4A467343c0dc4aDAB74Af84448D9c45D8ae6F',
[eEthereumNetwork.ropsten]: '',
[eEthereumNetwork.main]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
[eEthereumNetwork.coverage]: '',
[eEthereumNetwork.hardhat]: '',
[eEthereumNetwork.buidlerevm]: '',
[eEthereumNetwork.tenderlyMain]: '0xbd723fc4f1d737dcfc48a07fe7336766d34cad5f',
}, },
LendingRateOracle: { LendingRateOracle: {
[eEthereumNetwork.coverage]: '', [eEthereumNetwork.coverage]: '',
@ -151,8 +160,8 @@ export const CommonsConfig: ICommonConfiguration = {
[eEthereumNetwork.buidlerevm]: '', [eEthereumNetwork.buidlerevm]: '',
[eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a', [eEthereumNetwork.kovan]: '0xdCde9Bb6a49e37fA433990832AB541AE2d4FEB4a',
[eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b', [eEthereumNetwork.ropsten]: '0x05dcca805a6562c1bdd0423768754acb6993241b',
[eEthereumNetwork.main]: ZERO_ADDRESS, [eEthereumNetwork.main]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
[eEthereumNetwork.tenderlyMain]: ZERO_ADDRESS, [eEthereumNetwork.tenderlyMain]: '0x8A32f49FFbA88aba6EFF96F45D8BD1D4b3f35c7D',
}, },
TokenDistributor: { TokenDistributor: {
[eEthereumNetwork.coverage]: '', [eEthereumNetwork.coverage]: '',
@ -169,8 +178,8 @@ export const CommonsConfig: ICommonConfiguration = {
[eEthereumNetwork.buidlerevm]: '', [eEthereumNetwork.buidlerevm]: '',
[EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1', [EthereumNetwork.kovan]: '0xB8bE51E6563BB312Cbb2aa26e352516c25c26ac1',
[EthereumNetwork.ropsten]: ZERO_ADDRESS, [EthereumNetwork.ropsten]: ZERO_ADDRESS,
[EthereumNetwork.main]: ZERO_ADDRESS, [EthereumNetwork.main]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
[EthereumNetwork.tenderlyMain]: ZERO_ADDRESS, [EthereumNetwork.tenderlyMain]: '0xA50ba011c48153De246E5192C8f9258A2ba79Ca9',
}, },
FallbackOracle: { FallbackOracle: {
[eEthereumNetwork.coverage]: '', [eEthereumNetwork.coverage]: '',
@ -307,7 +316,7 @@ export const CommonsConfig: ICommonConfiguration = {
}, },
ReserveFactorTreasuryAddress: { ReserveFactorTreasuryAddress: {
[eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.coverage]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
[eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.hardhat]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
[eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.buidlerevm]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
[eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.kovan]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',
[eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c', [eEthereumNetwork.ropsten]: '0x464c71f6c2f760dda6093dcb91c24c39e5d6e18c',

View File

@ -3,14 +3,15 @@ import { IAaveConfiguration, EthereumNetwork, eEthereumNetwork } from '../../hel
import { CommonsConfig } from './commons'; import { CommonsConfig } from './commons';
import { import {
stablecoinStrategyBUSD, strategyBUSD,
stablecoinStrategyDAI, strategyDAI,
stablecoinStrategySUSD, strategySUSD,
stablecoinStrategyTUSD, strategyTUSD,
stablecoinStrategyUSDC, strategyUSDC,
stablecoinStrategyUSDT, strategyUSDT,
strategyAAVE, strategyAAVE,
strategyBase, strategyBAT,
strategyZRX,
strategyKNC, strategyKNC,
strategyLINK, strategyLINK,
strategyMANA, strategyMANA,
@ -33,9 +34,9 @@ export const AaveConfig: IAaveConfiguration = {
ProviderId: 1, ProviderId: 1,
ReservesConfig: { ReservesConfig: {
AAVE: strategyAAVE, AAVE: strategyAAVE,
BAT: strategyBase, BAT: strategyBAT,
BUSD: stablecoinStrategyBUSD, BUSD: strategyBUSD,
DAI: stablecoinStrategyDAI, DAI: strategyDAI,
ENJ: strategyREN, ENJ: strategyREN,
KNC: strategyKNC, KNC: strategyKNC,
LINK: strategyLINK, LINK: strategyLINK,
@ -43,15 +44,15 @@ export const AaveConfig: IAaveConfiguration = {
MKR: strategyMKR, MKR: strategyMKR,
REN: strategyREN, REN: strategyREN,
SNX: strategySNX, SNX: strategySNX,
SUSD: stablecoinStrategySUSD, SUSD: strategySUSD,
TUSD: stablecoinStrategyTUSD, TUSD: strategyTUSD,
UNI: strategyUNI, UNI: strategyUNI,
USDC: stablecoinStrategyUSDC, USDC: strategyUSDC,
USDT: stablecoinStrategyUSDT, USDT: strategyUSDT,
WBTC: strategyWBTC, WBTC: strategyWBTC,
WETH: strategyWETH, WETH: strategyWETH,
YFI: strategyYFI, YFI: strategyYFI,
ZRX: strategyBase, ZRX: strategyZRX,
}, },
ReserveAssets: { ReserveAssets: {
[eEthereumNetwork.buidlerevm]: {}, [eEthereumNetwork.buidlerevm]: {},

View File

@ -2,9 +2,213 @@ import BigNumber from 'bignumber.js';
import { oneRay } from '../../helpers/constants'; import { oneRay } from '../../helpers/constants';
import { eContractid, IReserveParams } from '../../helpers/types'; import { eContractid, IReserveParams } from '../../helpers/types';
export const strategyBase: IReserveParams = { export const strategyBUSD: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(), baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableRateSlope1: '0',
stableRateSlope2: '0',
baseLTVAsCollateral: '0',
liquidationThreshold: '0',
liquidationBonus: '0',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyDAI: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategySUSD: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableRateSlope1: '0',
stableRateSlope2: '0',
baseLTVAsCollateral: '0',
liquidationThreshold: '0',
liquidationBonus: '0',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};
export const strategyTUSD: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.75).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500',
liquidationThreshold: '8000',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyUSDC: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '8000',
liquidationThreshold: '8500',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyUSDT: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.9).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.02).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.60).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '8000',
liquidationThreshold: '8500',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyAAVE: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: '0',
variableRateSlope1: '0',
variableRateSlope2: '0',
stableRateSlope1: '0',
stableRateSlope2: '0',
baseLTVAsCollateral: '5000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: false,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '0'
};
export const strategyBAT: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7000',
liquidationThreshold: '7500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};
export const strategyENJ: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '5500',
liquidationThreshold: '6000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};
export const strategyWETH: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '8000',
liquidationThreshold: '8250',
liquidationBonus: '10500',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyKNC: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};
export const strategyLINK: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7000',
liquidationThreshold: '7500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};
export const strategyMANA: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(), variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(), variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(), stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
@ -16,210 +220,124 @@ export const strategyBase: IReserveParams = {
stableBorrowRateEnabled: true, stableBorrowRateEnabled: true,
reserveDecimals: '18', reserveDecimals: '18',
aTokenImpl: eContractid.AToken, aTokenImpl: eContractid.AToken,
reserveFactor: '1000' reserveFactor: '3500'
}; };
export const stablecoinStrategyBase: IReserveParams = { export const strategyMKR: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(), baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(), variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1.5).multipliedBy(oneRay).toFixed(), variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(), stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(1.5).multipliedBy(oneRay).toFixed(), stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500', baseLTVAsCollateral: '6000',
liquidationThreshold: '8000', liquidationThreshold: '6500',
liquidationBonus: '10500', liquidationBonus: '11000',
borrowingEnabled: true, borrowingEnabled: true,
stableBorrowRateEnabled: true, stableBorrowRateEnabled: true,
reserveDecimals: '18', reserveDecimals: '18',
aTokenImpl: eContractid.AToken, aTokenImpl: eContractid.AToken,
reserveFactor: '1000' reserveFactor: '2000'
}; };
export const stablecoinStrategyCentralized: IReserveParams = { export const strategyREN: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(), baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(), variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(), variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.06).multipliedBy(oneRay).toFixed(), stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(), stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500', baseLTVAsCollateral: '5500',
liquidationThreshold: '8000', liquidationThreshold: '6000',
liquidationBonus: '10500', liquidationBonus: '11000',
borrowingEnabled: true, borrowingEnabled: true,
stableBorrowRateEnabled: true, stableBorrowRateEnabled: true,
reserveDecimals: '6',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategyGovernanceTokens: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '4000',
liquidationBonus: '11500',
};
export const stablecoinStrategyBUSD: IReserveParams = {
...stablecoinStrategyCentralized,
reserveDecimals: '18', reserveDecimals: '18',
baseLTVAsCollateral: '-1', aTokenImpl: eContractid.AToken,
liquidationThreshold: '0', reserveFactor: '2000'
liquidationBonus: '0', };
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(), export const strategySNX: IReserveParams = {
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableRateSlope1: '0',
stableRateSlope2: '0',
baseLTVAsCollateral: '1500',
liquidationThreshold: '4000',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false, stableBorrowRateEnabled: false,
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(), reserveDecimals: '18',
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(), aTokenImpl: eContractid.AToken,
reserveFactor: '3500'
}; };
export const strategyAAVE: IReserveParams = { export const strategyUNI: IReserveParams = {
...strategyBase, optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '5000', baseVariableBorrowRate: '0',
variableRateSlope1: '0',
variableRateSlope2: '0',
stableRateSlope1: '0',
stableRateSlope2: '0',
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500', liquidationThreshold: '6500',
liquidationBonus: '11000', liquidationBonus: '11000',
borrowingEnabled: false, borrowingEnabled: false,
stableBorrowRateEnabled: false, stableBorrowRateEnabled: false,
reserveDecimals: '18', reserveDecimals: '18',
};
export const stablecoinStrategyDAI: IReserveParams = {
...stablecoinStrategyBase,
};
export const strategyENJ: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '5500',
stableBorrowRateEnabled: false,
};
export const strategyKNC: IReserveParams = {
...strategyBase,
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
};
export const strategyLINK: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '6500',
liquidationThreshold: '7000',
};
export const strategyMANA: IReserveParams = {
...strategyBase,
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
};
export const strategyMKR: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '3500',
};
export const strategyREN: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '5000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
};
export const stablecoinStrategySUSD: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '-1',
liquidationThreshold: '0',
liquidationBonus: '0',
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '1000'
};
export const strategySNX: IReserveParams = {
...strategyBase,
baseLTVAsCollateral: '1500',
liquidationThreshold: '4000',
baseVariableBorrowRate: new BigNumber(0.03).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.12).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(),
stableBorrowRateEnabled: false,
};
export const stablecoinStrategyTUSD: IReserveParams = {
...stablecoinStrategyCentralized,
baseVariableBorrowRate: new BigNumber(0.01).multipliedBy(oneRay).toFixed(),
variableRateSlope1: new BigNumber(0.04).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1.5).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.14).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
borrowingEnabled: true,
stableBorrowRateEnabled: false,
reserveDecimals: '18',
};
export const strategyUNI: IReserveParams = {
...strategyGovernanceTokens,
stableBorrowRateEnabled: false,
aTokenImpl: eContractid.DelegationAwareAToken, aTokenImpl: eContractid.DelegationAwareAToken,
}; reserveFactor: '2000'
export const stablecoinStrategyUSDC: IReserveParams = {
...stablecoinStrategyBase,
variableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(),
reserveDecimals: '6',
};
export const stablecoinStrategyUSDT: IReserveParams = {
...stablecoinStrategyBase,
baseLTVAsCollateral: '-1',
liquidationThreshold: '7000',
liquidationBonus: '0',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '6',
}; };
export const strategyWBTC: IReserveParams = { export const strategyWBTC: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.65).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(), baseVariableBorrowRate: '0',
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(), variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(), variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(), stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(0.6).multipliedBy(oneRay).toFixed(), stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000', baseLTVAsCollateral: '7000',
liquidationThreshold: '6500', liquidationThreshold: '7500',
liquidationBonus: '11500', liquidationBonus: '11000',
borrowingEnabled: true, borrowingEnabled: true,
stableBorrowRateEnabled: true, stableBorrowRateEnabled: true,
reserveDecimals: '8', reserveDecimals: '8',
aTokenImpl: eContractid.AToken, aTokenImpl: eContractid.AToken,
reserveFactor: '1000' reserveFactor: '2000'
}; };
export const strategyWETH: IReserveParams = { export const strategyYFI: IReserveParams = {
optimalUtilizationRate: new BigNumber(0.8).multipliedBy(oneRay).toFixed(), optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(), baseVariableBorrowRate: '0',
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(), variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(), variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(), stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(1).multipliedBy(oneRay).toFixed(), stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '7500', baseLTVAsCollateral: '4000',
liquidationThreshold: '8000', liquidationThreshold: '5500',
liquidationBonus: '10500', liquidationBonus: '11500',
borrowingEnabled: true, borrowingEnabled: true,
stableBorrowRateEnabled: true, stableBorrowRateEnabled: true,
reserveDecimals: '18', reserveDecimals: '18',
aTokenImpl: eContractid.AToken, aTokenImpl: eContractid.AToken,
reserveFactor: '1000' reserveFactor: '2000'
}; };
export const strategyYFI: IReserveParams = { export const strategyZRX: IReserveParams = {
...strategyGovernanceTokens, optimalUtilizationRate: new BigNumber(0.45).multipliedBy(oneRay).toFixed(),
}; baseVariableBorrowRate: '0',
variableRateSlope1: new BigNumber(0.07).multipliedBy(oneRay).toFixed(),
variableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
stableRateSlope1: new BigNumber(0.1).multipliedBy(oneRay).toFixed(),
stableRateSlope2: new BigNumber(3).multipliedBy(oneRay).toFixed(),
baseLTVAsCollateral: '6000',
liquidationThreshold: '6500',
liquidationBonus: '11000',
borrowingEnabled: true,
stableBorrowRateEnabled: true,
reserveDecimals: '18',
aTokenImpl: eContractid.AToken,
reserveFactor: '2000'
};

View File

@ -35,7 +35,7 @@
"aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify", "aave:ropsten:full:migration": "npm run compile && npm run hardhat:ropsten -- aave:mainnet --verify",
"aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet", "aave:fork:main:tenderly": "npm run compile && npm run hardhat:tenderly-main -- aave:mainnet",
"aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet", "aave:fork:main": "npm run compile && MAINNET_FORK=true hardhat aave:mainnet",
"aave:main:full:migration": "npm run hardhat:main -- aave:mainnet --verify", "aave:main:full:migration": "npm run compile && npm run hardhat:main -- aave:mainnet --verify",
"dev:prettier": "prettier --write .", "dev:prettier": "prettier --write .",
"ci:test": "npm run compile && npm run test", "ci:test": "npm run compile && npm run test",
"ci:clean": "rm -rf ./artifacts ./cache ./types", "ci:clean": "rm -rf ./artifacts ./cache ./types",
@ -45,12 +45,16 @@
"dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider", "dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider",
"dev:deployUniswapRepayAdapter": "npm run hardhat:kovan deploy-UniswapRepayAdapter", "dev:deployUniswapRepayAdapter": "npm run hardhat:kovan deploy-UniswapRepayAdapter",
"dev:UniswapLiquiditySwapAdapter": "npm run hardhat:kovan deploy-UniswapLiquiditySwapAdapter", "dev:UniswapLiquiditySwapAdapter": "npm run hardhat:kovan deploy-UniswapLiquiditySwapAdapter",
"main:deployUniswapRepayAdapter": "npm run hardhat:main deploy-UniswapRepayAdapter",
"main:UniswapLiquiditySwapAdapter": "npm run hardhat:main deploy-UniswapLiquiditySwapAdapter",
"kovan:verify": "npm run hardhat:kovan verify:general -- --all --pool Aave", "kovan:verify": "npm run hardhat:kovan verify:general -- --all --pool Aave",
"ropsten:verify": "npm run hardhat:ropsten verify:general -- --all --pool Aave", "ropsten:verify": "npm run hardhat:ropsten verify:general -- --all --pool Aave",
"mainnet:verify": "npm run hardhat:main verify:general -- --all --pool Aave", "mainnet:verify": "npm run hardhat:main verify:general -- --all --pool Aave",
"kovan:verify:tokens": "npm run hardhat:kovan verify:tokens -- --pool Aave", "kovan:verify:tokens": "npm run hardhat:kovan verify:tokens -- --pool Aave",
"ropsten:verify:tokens": "npm run hardhat:ropsten verify:tokens -- --pool Aave", "ropsten:verify:tokens": "npm run hardhat:ropsten verify:tokens -- --pool Aave",
"mainnet:verify:tokens": "npm run hardhat:main verify:tokens -- --pool Aave" "mainnet:verify:tokens": "npm run hardhat:main verify:tokens -- --pool Aave",
"print-config:fork:mainnet": "MAINNET_FORK=true hardhat print-config:fork",
"print-config:kovan": "hardhat --network kovan print-config --pool Aave --data-provider 0xA1901785c29cBd48bfA74e46b67C736b26054fa4"
}, },
"devDependencies": { "devDependencies": {
"@nomiclabs/buidler": "^1.4.7", "@nomiclabs/buidler": "^1.4.7",

View File

@ -0,0 +1,11 @@
import { task } from 'hardhat/config';
import { deployLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-deployments';
task('full:deploy-address-provider-registry', 'Deploy address provider registry')
.addFlag('verify', 'Verify contracts at Etherscan')
.setAction(async ({ verify }, DRE) => {
await DRE.run('set-DRE');
const contract = await deployLendingPoolAddressesProviderRegistry(verify);
console.log('Registry Address:', contract.address);
});

View File

@ -12,7 +12,13 @@ import {
getEmergencyAdmin, getEmergencyAdmin,
} from '../../helpers/configuration'; } from '../../helpers/configuration';
import { eEthereumNetwork } from '../../helpers/types'; import { eEthereumNetwork } from '../../helpers/types';
import { getLendingPoolAddressesProviderRegistry } from '../../helpers/contracts-getters'; import {
getFirstSigner,
getLendingPoolAddressesProviderRegistry,
} from '../../helpers/contracts-getters';
import { isAddress } from 'ethers/lib/utils';
import { isZeroAddress } from 'ethereumjs-util';
import { Signer } from 'ethers';
task( task(
'full:deploy-address-provider', 'full:deploy-address-provider',
@ -22,30 +28,70 @@ task(
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`) .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({ verify, pool }, DRE) => { .setAction(async ({ verify, pool }, DRE) => {
await DRE.run('set-DRE'); await DRE.run('set-DRE');
let signer: Signer;
const network = <eEthereumNetwork>DRE.network.name; const network = <eEthereumNetwork>DRE.network.name;
const poolConfig = loadPoolConfig(pool); const poolConfig = loadPoolConfig(pool);
const { ProviderId, MarketId } = poolConfig; const { ProviderId, MarketId } = poolConfig;
const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network); const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
// Deploy address provider and set genesis manager const providerRegistryOwner = getParamPerNetwork(poolConfig.ProviderRegistryOwner, network);
if (
!providerRegistryAddress ||
!isAddress(providerRegistryAddress) ||
isZeroAddress(providerRegistryAddress)
) {
throw Error('config.ProviderRegistry is missing or is not an address.');
}
if (
!providerRegistryOwner ||
!isAddress(providerRegistryOwner) ||
isZeroAddress(providerRegistryOwner)
) {
throw Error('config.ProviderRegistryOwner is missing or is not an address.');
}
// Checks if deployer address is registry owner
if (process.env.MAINNET_FORK === 'true') {
await DRE.network.provider.request({
method: 'hardhat_impersonateAccount',
params: [providerRegistryOwner],
});
signer = DRE.ethers.provider.getSigner(providerRegistryOwner);
} else {
signer = await getFirstSigner();
const deployerAddress = await signer.getAddress();
if (providerRegistryOwner !== (await signer.getAddress())) {
throw Error(
`Current signer is not provider registry owner. \nCurrent deployer address: ${deployerAddress} \nExpected address: ${poolConfig.ProviderRegistryOwner}`
);
}
}
// 1. Address Provider Registry instance
const addressesProviderRegistry = (
await getLendingPoolAddressesProviderRegistry(providerRegistryAddress)
).connect(signer);
console.log('Registry Address', addressesProviderRegistry.address);
// 2. Deploy address provider and set genesis manager
const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify); const addressesProvider = await deployLendingPoolAddressesProvider(MarketId, verify);
await waitForTx(await addressesProvider.setPoolAdmin(await getGenesisPoolAdmin(poolConfig))); // 3. Set the provider at the Registry
await waitForTx(await addressesProvider.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
console.log('Pool Admin', await addressesProvider.getPoolAdmin());
console.log('Emergency Admin', await addressesProvider.getEmergencyAdmin());
// If no provider registry is set, deploy lending pool address provider registry and register the address provider
const addressesProviderRegistry = notFalsyOrZeroAddress(providerRegistryAddress)
? await getLendingPoolAddressesProviderRegistry(providerRegistryAddress)
: await deployLendingPoolAddressesProviderRegistry(verify);
await waitForTx( await waitForTx(
await addressesProviderRegistry.registerAddressesProvider( await addressesProviderRegistry.registerAddressesProvider(
addressesProvider.address, addressesProvider.address,
ProviderId ProviderId
) )
); );
// 4. Set pool admins
await waitForTx(await addressesProvider.setPoolAdmin(await getGenesisPoolAdmin(poolConfig)));
await waitForTx(await addressesProvider.setEmergencyAdmin(await getEmergencyAdmin(poolConfig)));
console.log('Pool Admin', await addressesProvider.getPoolAdmin());
console.log('Emergency Admin', await addressesProvider.getEmergencyAdmin());
}); });

View File

@ -0,0 +1,77 @@
import { task } from 'hardhat/config';
import { ConfigNames, loadPoolConfig } from '../../helpers/configuration';
import {
getAaveProtocolDataProvider,
getLendingPoolAddressesProvider,
getLendingPoolAddressesProviderRegistry,
} from '../../helpers/contracts-getters';
import { getParamPerNetwork } from '../../helpers/contracts-helpers';
import { DRE } from '../../helpers/misc-utils';
import { eEthereumNetwork } from '../../helpers/types';
task('print-config', 'Inits the DRE, to have access to all the plugins')
.addParam('dataProvider', 'Address of AaveProtocolDataProvider')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({ pool, dataProvider }, localBRE) => {
await localBRE.run('set-DRE');
const network =
process.env.MAINNET_FORK === 'true'
? eEthereumNetwork.main
: (localBRE.network.name as eEthereumNetwork);
const poolConfig = loadPoolConfig(pool);
const providerRegistryAddress = getParamPerNetwork(poolConfig.ProviderRegistry, network);
const providerRegistry = await getLendingPoolAddressesProviderRegistry(providerRegistryAddress);
const providers = await providerRegistry.getAddressesProvidersList();
const addressesProvider = await getLendingPoolAddressesProvider(providers[0]); // Checks first provider
console.log('Addresses Providers', providers.join(', '));
console.log('Market Id: ', await addressesProvider.getMarketId());
console.log('LendingPool Proxy:', await addressesProvider.getLendingPool());
console.log(
'Lending Pool Collateral Manager',
await addressesProvider.getLendingPoolCollateralManager()
);
console.log(
'Lending Pool Configurator proxy',
await addressesProvider.getLendingPoolConfigurator()
);
console.log('Pool admin', await addressesProvider.getPoolAdmin());
console.log('Emergency admin', await addressesProvider.getEmergencyAdmin());
console.log('Price Oracle', await addressesProvider.getPriceOracle());
console.log('Lending Rate Oracle', await addressesProvider.getLendingRateOracle());
console.log('Lending Pool Data Provider', dataProvider);
const protocolDataProvider = await getAaveProtocolDataProvider(dataProvider);
const fields = [
'decimals',
'ltv',
'liquidationThreshold',
'liquidationBonus',
'reserveFactor',
'usageAsCollateralEnabled',
'borrowingEnabled',
'stableBorrowRateEnabled',
'isActive',
'isFrozen',
];
const tokensFields = ['aToken', 'stableDebtToken', 'variableDebtToken'];
for (const [symbol, address] of Object.entries(
getParamPerNetwork(poolConfig.ReserveAssets, network)
)) {
console.log(`- ${symbol} asset config`);
console.log(` - reserve address: ${address}`);
const reserveData = await protocolDataProvider.getReserveConfigurationData(address);
const tokensAddresses = await protocolDataProvider.getReserveTokensAddresses(address);
fields.forEach((field, index) => {
console.log(` - ${field}:`, reserveData[index].toString());
});
tokensFields.forEach((field, index) => {
console.log(` - ${field}:`, tokensAddresses[index]);
});
}
});

View File

@ -0,0 +1,12 @@
import { task } from 'hardhat/config';
import { getAaveProtocolDataProvider } from '../../helpers/contracts-getters';
task('print-config:fork', 'Deploy development enviroment')
.addFlag('verify', 'Verify contracts at Etherscan')
.setAction(async ({ verify }, DRE) => {
await DRE.run('set-DRE');
await DRE.run('aave:mainnet');
const dataProvider = await getAaveProtocolDataProvider();
await DRE.run('print-config', { dataProvider: dataProvider.address, pool: 'Aave' });
});

View File

@ -1,23 +1,23 @@
import {task} from 'hardhat/config'; import { task } from 'hardhat/config';
import {loadPoolConfig, ConfigNames, getWethAddress} from '../../helpers/configuration'; import { loadPoolConfig, ConfigNames, getWethAddress } from '../../helpers/configuration';
import {ZERO_ADDRESS} from '../../helpers/constants'; import { ZERO_ADDRESS } from '../../helpers/constants';
import { import {
getAddressById, getAddressById,
getLendingPool, getLendingPool,
getLendingPoolAddressesProvider, getLendingPoolAddressesProvider,
getLendingPoolConfiguratorProxy, getLendingPoolConfiguratorProxy,
} from '../../helpers/contracts-getters'; } from '../../helpers/contracts-getters';
import {getParamPerNetwork} from '../../helpers/contracts-helpers'; import { getParamPerNetwork } from '../../helpers/contracts-helpers';
import {verifyContract} from '../../helpers/etherscan-verification'; import { verifyContract } from '../../helpers/etherscan-verification';
import {eEthereumNetwork, ICommonConfiguration, IReserveParams} from '../../helpers/types'; import { eEthereumNetwork, ICommonConfiguration, IReserveParams } from '../../helpers/types';
task('verify:tokens', 'Deploy oracles for dev enviroment') task('verify:tokens', 'Deploy oracles for dev enviroment')
.addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`) .addParam('pool', `Pool name to retrieve configuration, supported: ${Object.values(ConfigNames)}`)
.setAction(async ({verify, all, pool}, localDRE) => { .setAction(async ({ verify, all, pool }, localDRE) => {
await localDRE.run('set-DRE'); await localDRE.run('set-DRE');
const network = localDRE.network.name as eEthereumNetwork; const network = localDRE.network.name as eEthereumNetwork;
const poolConfig = loadPoolConfig(pool); const poolConfig = loadPoolConfig(pool);
const {ReserveAssets, ReservesConfig} = poolConfig as ICommonConfiguration; const { ReserveAssets, ReservesConfig } = poolConfig as ICommonConfiguration;
const addressesProvider = await getLendingPoolAddressesProvider(); const addressesProvider = await getLendingPoolAddressesProvider();
const lendingPoolProxy = await getLendingPool(); const lendingPoolProxy = await getLendingPool();
@ -40,6 +40,7 @@ task('verify:tokens', 'Deploy oracles for dev enviroment')
} }
const { const {
optimalUtilizationRate,
baseVariableBorrowRate, baseVariableBorrowRate,
variableRateSlope1, variableRateSlope1,
variableRateSlope2, variableRateSlope2,
@ -64,6 +65,7 @@ task('verify:tokens', 'Deploy oracles for dev enviroment')
console.log(`\n- Verifying Strategy rate...\n`); console.log(`\n- Verifying Strategy rate...\n`);
await verifyContract(interestRateStrategyAddress, [ await verifyContract(interestRateStrategyAddress, [
addressesProvider.address, addressesProvider.address,
optimalUtilizationRate,
baseVariableBorrowRate, baseVariableBorrowRate,
variableRateSlope1, variableRateSlope1,
variableRateSlope2, variableRateSlope2,

View File

@ -2,6 +2,7 @@ import {TestEnv, makeSuite} from './helpers/make-suite';
import {APPROVAL_AMOUNT_LENDING_POOL, RAY} from '../helpers/constants'; import {APPROVAL_AMOUNT_LENDING_POOL, 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 { strategyWETH } from '../markets/aave/reservesConfigs';
const {expect} = require('chai'); const {expect} = require('chai');
@ -58,7 +59,10 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
}); });
it('Freezes the ETH reserve', async () => { it('Freezes the ETH reserve', async () => {
const {configurator, pool, weth, helpersContract} = testEnv; const {configurator, weth, helpersContract} = testEnv;
await configurator.freezeReserve(weth.address); await configurator.freezeReserve(weth.address);
const { const {
decimals, decimals,
@ -75,12 +79,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(true); expect(isFrozen).to.be.equal(true);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Unfreezes the ETH reserve', async () => { it('Unfreezes the ETH reserve', async () => {
@ -102,12 +106,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Check the onlyAaveAdmin on freezeReserve ', async () => { it('Check the onlyAaveAdmin on freezeReserve ', async () => {
@ -144,12 +148,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(false); expect(borrowingEnabled).to.be.equal(false);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Activates the ETH reserve for borrowing', async () => { it('Activates the ETH reserve for borrowing', async () => {
@ -172,12 +176,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(variableBorrowIndex.toString()).to.be.equal(RAY); expect(variableBorrowIndex.toString()).to.be.equal(RAY);
}); });
@ -222,12 +226,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(liquidationThreshold).to.be.equal(0); expect(liquidationThreshold).to.be.equal(0);
expect(liquidationBonus).to.be.equal(0); expect(liquidationBonus).to.be.equal(0);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Activates the ETH reserve as collateral', async () => { it('Activates the ETH reserve as collateral', async () => {
const {configurator, helpersContract, weth} = testEnv; const {configurator, helpersContract, weth} = testEnv;
await configurator.configureReserveAsCollateral(weth.address, '7500', '8000', '10500'); await configurator.configureReserveAsCollateral(weth.address, '8000', '8250', '10500');
const { const {
decimals, decimals,
@ -244,12 +248,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => { it('Check the onlyAaveAdmin on configureReserveAsCollateral ', async () => {
@ -280,12 +284,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(false); expect(stableBorrowRateEnabled).to.be.equal(false);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Enables stable borrow rate on the ETH reserve', async () => { it('Enables stable borrow rate on the ETH reserve', async () => {
@ -306,12 +310,12 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(true);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });
it('Check the onlyAaveAdmin on disableReserveStableRate', async () => { it('Check the onlyAaveAdmin on disableReserveStableRate', async () => {
@ -348,11 +352,11 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(borrowingEnabled).to.be.equal(true); expect(borrowingEnabled).to.be.equal(true);
expect(isActive).to.be.equal(true); expect(isActive).to.be.equal(true);
expect(isFrozen).to.be.equal(false); expect(isFrozen).to.be.equal(false);
expect(decimals).to.be.equal(18); expect(decimals).to.be.equal(strategyWETH.reserveDecimals);
expect(ltv).to.be.equal(7500); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(8000); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(10500); expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true); expect(stableBorrowRateEnabled).to.be.equal(strategyWETH.stableBorrowRateEnabled);
expect(reserveFactor).to.be.equal(1000); expect(reserveFactor).to.be.equal(1000);
}); });

View File

@ -14,7 +14,7 @@ import {
getUniswapLiquiditySwapAdapter, getUniswapLiquiditySwapAdapter,
getUniswapRepayAdapter, getUniswapRepayAdapter,
} from '../../helpers/contracts-getters'; } from '../../helpers/contracts-getters';
import { tEthereumAddress } from '../../helpers/types'; import { eEthereumNetwork, tEthereumAddress } from '../../helpers/types';
import { LendingPool } from '../../types/LendingPool'; import { LendingPool } from '../../types/LendingPool';
import { AaveProtocolDataProvider } from '../../types/AaveProtocolDataProvider'; import { AaveProtocolDataProvider } from '../../types/AaveProtocolDataProvider';
import { MintableERC20 } from '../../types/MintableERC20'; import { MintableERC20 } from '../../types/MintableERC20';
@ -31,9 +31,11 @@ import { LendingPoolAddressesProviderRegistry } from '../../types/LendingPoolAdd
import { getEthersSigners } from '../../helpers/contracts-helpers'; import { getEthersSigners } from '../../helpers/contracts-helpers';
import { UniswapLiquiditySwapAdapter } from '../../types/UniswapLiquiditySwapAdapter'; import { UniswapLiquiditySwapAdapter } from '../../types/UniswapLiquiditySwapAdapter';
import { UniswapRepayAdapter } from '../../types/UniswapRepayAdapter'; import { UniswapRepayAdapter } from '../../types/UniswapRepayAdapter';
import { getParamPerNetwork } from '../../helpers/contracts-helpers';
import { WETH9Mocked } from '../../types/WETH9Mocked'; import { WETH9Mocked } from '../../types/WETH9Mocked';
import { WETHGateway } from '../../types/WETHGateway'; import { WETHGateway } from '../../types/WETHGateway';
import { solidity } from 'ethereum-waffle'; import { solidity } from 'ethereum-waffle';
import { AaveConfig } from '../../markets/aave';
chai.use(bignumberChai()); chai.use(bignumberChai());
chai.use(almostEqual()); chai.use(almostEqual());
@ -108,9 +110,16 @@ export async function initializeMakeSuite() {
testEnv.configurator = await getLendingPoolConfiguratorProxy(); testEnv.configurator = await getLendingPoolConfiguratorProxy();
testEnv.oracle = await getPriceOracle();
testEnv.addressesProvider = await getLendingPoolAddressesProvider(); testEnv.addressesProvider = await getLendingPoolAddressesProvider();
testEnv.registry = await getLendingPoolAddressesProviderRegistry();
if (process.env.MAINNET_FORK === 'true') {
testEnv.registry = await getLendingPoolAddressesProviderRegistry(
getParamPerNetwork(AaveConfig.ProviderRegistry, eEthereumNetwork.main)
);
} else {
testEnv.registry = await getLendingPoolAddressesProviderRegistry();
testEnv.oracle = await getPriceOracle();
}
testEnv.helpersContract = await getAaveProtocolDataProvider(); testEnv.helpersContract = await getAaveProtocolDataProvider();

View File

@ -1,12 +1,5 @@
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { import { ONE_YEAR, RAY, MAX_UINT_AMOUNT, PERCENTAGE_FACTOR } from '../../../helpers/constants';
ONE_YEAR,
RAY,
MAX_UINT_AMOUNT,
OPTIMAL_UTILIZATION_RATE,
EXCESS_UTILIZATION_RATE,
PERCENTAGE_FACTOR,
} from '../../../helpers/constants';
import { import {
IReserveParams, IReserveParams,
iAavePoolAssets, iAavePoolAssets,
@ -527,11 +520,10 @@ export const calcExpectedReserveDataAfterRepay = (
//due to accumulation errors, the total stable debt might be smaller than the last user debt. //due to accumulation errors, the total stable debt might be smaller than the last user debt.
//in this case we simply set the total supply and avg stable rate to 0. //in this case we simply set the total supply and avg stable rate to 0.
if (expectedReserveData.principalStableDebt.lt(0)) { if (expectedReserveData.totalStableDebt.lt(0)) {
expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = new BigNumber( expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
0 0
); );
expectedReserveData.averageStableBorrowRate = new BigNumber(0);
} else { } else {
expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate( expectedReserveData.averageStableBorrowRate = calcExpectedAverageStableBorrowRate(
reserveDataBeforeAction.averageStableBorrowRate, reserveDataBeforeAction.averageStableBorrowRate,
@ -539,6 +531,15 @@ export const calcExpectedReserveDataAfterRepay = (
amountRepaidBN.negated(), amountRepaidBN.negated(),
userDataBeforeAction.stableBorrowRate userDataBeforeAction.stableBorrowRate
); );
//also due to accumulation errors, the final avg stable rate when the last user repays might be negative.
//if that is the case, it means a small leftover of total stable debt is left, which can be erased.
if (expectedReserveData.averageStableBorrowRate.lt(0)) {
expectedReserveData.principalStableDebt = expectedReserveData.totalStableDebt = expectedReserveData.averageStableBorrowRate = new BigNumber(
0
);
}
} }
expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt; expectedReserveData.scaledVariableDebt = reserveDataBeforeAction.scaledVariableDebt;
@ -1210,6 +1211,7 @@ export const calcExpectedInterestRates = (
): BigNumber[] => { ): BigNumber[] => {
const { reservesParams } = configuration; const { reservesParams } = configuration;
const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol); const reserveIndex = Object.keys(reservesParams).findIndex((value) => value === reserveSymbol);
const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[ const [, reserveConfiguration] = (Object.entries(reservesParams) as [string, IReserveParams][])[
reserveIndex reserveIndex
@ -1218,10 +1220,12 @@ export const calcExpectedInterestRates = (
let stableBorrowRate: BigNumber = marketStableRate; let stableBorrowRate: BigNumber = marketStableRate;
let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate); let variableBorrowRate: BigNumber = new BigNumber(reserveConfiguration.baseVariableBorrowRate);
if (utilizationRate.gt(OPTIMAL_UTILIZATION_RATE)) { const optimalRate = new BigNumber(reserveConfiguration.optimalUtilizationRate);
const excessRate = new BigNumber(RAY).minus(optimalRate);
if (utilizationRate.gt(optimalRate)) {
const excessUtilizationRateRatio = utilizationRate const excessUtilizationRateRatio = utilizationRate
.minus(OPTIMAL_UTILIZATION_RATE) .minus(reserveConfiguration.optimalUtilizationRate)
.rayDiv(EXCESS_UTILIZATION_RATE); .rayDiv(excessRate);
stableBorrowRate = stableBorrowRate stableBorrowRate = stableBorrowRate
.plus(reserveConfiguration.stableRateSlope1) .plus(reserveConfiguration.stableRateSlope1)
@ -1237,13 +1241,13 @@ export const calcExpectedInterestRates = (
} else { } else {
stableBorrowRate = stableBorrowRate.plus( stableBorrowRate = stableBorrowRate.plus(
new BigNumber(reserveConfiguration.stableRateSlope1).rayMul( new BigNumber(reserveConfiguration.stableRateSlope1).rayMul(
utilizationRate.rayDiv(new BigNumber(OPTIMAL_UTILIZATION_RATE)) utilizationRate.rayDiv(new BigNumber(optimalRate))
) )
); );
variableBorrowRate = variableBorrowRate.plus( variableBorrowRate = variableBorrowRate.plus(
utilizationRate utilizationRate
.rayDiv(OPTIMAL_UTILIZATION_RATE) .rayDiv(optimalRate)
.rayMul(new BigNumber(reserveConfiguration.variableRateSlope1)) .rayMul(new BigNumber(reserveConfiguration.variableRateSlope1))
); );
} }

View File

@ -20,7 +20,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
LP_IS_PAUSED, LP_IS_PAUSED,
} = ProtocolErrors; } = ProtocolErrors;
it('LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => { it('Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
const { dai, weth, users, pool, oracle } = testEnv; const { dai, weth, users, pool, oracle } = testEnv;
const depositor = users[0]; const depositor = users[0];
const borrower = users[1]; const borrower = users[1];
@ -69,7 +69,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal( expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
'8000', '8250',
'Invalid liquidation threshold' 'Invalid liquidation threshold'
); );
@ -79,7 +79,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
).to.be.revertedWith(LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD); ).to.be.revertedWith(LPCM_HEALTH_FACTOR_NOT_BELOW_THRESHOLD);
}); });
it('LIQUIDATION - Drop the health factor below 1', async () => { it('Drop the health factor below 1', async () => {
const { dai, users, pool, oracle } = testEnv; const { dai, users, pool, oracle } = testEnv;
const borrower = users[1]; const borrower = users[1];
@ -98,7 +98,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
); );
}); });
it('LIQUIDATION - Tries to liquidate a different currency than the loan principal', async () => { it('Tries to liquidate a different currency than the loan principal', async () => {
const { pool, users, weth } = testEnv; const { pool, users, weth } = testEnv;
const borrower = users[1]; const borrower = users[1];
//user 2 tries to borrow //user 2 tries to borrow
@ -107,7 +107,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
).revertedWith(LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER); ).revertedWith(LPCM_SPECIFIED_CURRENCY_NOT_BORROWED_BY_USER);
}); });
it('LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral', async () => { it('Tries to liquidate a different collateral than the borrower collateral', async () => {
const { pool, dai, users } = testEnv; const { pool, dai, users } = testEnv;
const borrower = users[1]; const borrower = users[1];
@ -116,7 +116,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
).revertedWith(LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED); ).revertedWith(LPCM_COLLATERAL_CANNOT_BE_LIQUIDATED);
}); });
it('LIQUIDATION - Liquidates the borrow', async () => { it('Liquidates the borrow', async () => {
const { pool, dai, weth, aWETH, aDai, users, oracle, helpersContract, deployer } = testEnv; const { pool, dai, weth, aWETH, aDai, users, oracle, helpersContract, deployer } = testEnv;
const borrower = users[1]; const borrower = users[1];
@ -284,7 +284,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
await oracle.setAssetPrice( await oracle.setAssetPrice(
usdc.address, usdc.address,
new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0) new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
); );
//mints dai to the liquidator //mints dai to the liquidator

View File

@ -46,7 +46,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
await configurator.activateReserve(dai.address); await configurator.activateReserve(dai.address);
}); });
it('LIQUIDATION - Deposits WETH, borrows DAI', async () => { it('Deposits WETH, borrows DAI', async () => {
const {dai, weth, users, pool, oracle} = testEnv; const {dai, weth, users, pool, oracle} = testEnv;
const depositor = users[0]; const depositor = users[0];
const borrower = users[1]; const borrower = users[1];
@ -96,12 +96,12 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address); const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal( expect(userGlobalDataAfter.currentLiquidationThreshold.toString()).to.be.bignumber.equal(
'8000', '8250',
INVALID_HF INVALID_HF
); );
}); });
it('LIQUIDATION - Drop the health factor below 1', async () => { it('Drop the health factor below 1', async () => {
const {dai, weth, users, pool, oracle} = testEnv; const {dai, weth, users, pool, oracle} = testEnv;
const borrower = users[1]; const borrower = users[1];
@ -109,7 +109,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
await oracle.setAssetPrice( await oracle.setAssetPrice(
dai.address, dai.address,
new BigNumber(daiPrice.toString()).multipliedBy(1.25).toFixed(0) new BigNumber(daiPrice.toString()).multipliedBy(1.18).toFixed(0)
); );
const userGlobalData = await pool.getUserAccountData(borrower.address); const userGlobalData = await pool.getUserAccountData(borrower.address);
@ -120,7 +120,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
); );
}); });
it('LIQUIDATION - Liquidates the borrow', async () => { it('Liquidates the borrow', async () => {
const {dai, weth, users, pool, oracle, helpersContract} = testEnv; const {dai, weth, users, pool, oracle, helpersContract} = testEnv;
const liquidator = users[3]; const liquidator = users[3];
const borrower = users[1]; const borrower = users[1];
@ -280,7 +280,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
//drops HF below 1 //drops HF below 1
await oracle.setAssetPrice( await oracle.setAssetPrice(
usdc.address, usdc.address,
new BigNumber(usdcPrice.toString()).multipliedBy(1.2).toFixed(0) new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0)
); );
//mints dai to the liquidator //mints dai to the liquidator
@ -402,7 +402,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
//drops HF below 1 //drops HF below 1
await oracle.setAssetPrice( await oracle.setAssetPrice(
usdc.address, usdc.address,
new BigNumber(usdcPrice.toString()).multipliedBy(1.12).toFixed(0) new BigNumber(usdcPrice.toString()).multipliedBy(1.14).toFixed(0)
); );
//mints usdc to the liquidator //mints usdc to the liquidator