Merge branch 'feat/token-distributor-removal' into 'master'

Removal of TokenDistributor, FeeProvider and FlashLoanVars

See merge request aave-tech/protocol-v2!18
This commit is contained in:
The-3D 2020-08-20 10:30:37 +00:00
commit 65f0ebf4f4
19 changed files with 71 additions and 492 deletions

View File

@ -24,8 +24,6 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
event EthereumAddressUpdated(address indexed newAddress);
event PriceOracleUpdated(address indexed newAddress);
event LendingRateOracleUpdated(address indexed newAddress);
event FeeProviderUpdated(address indexed newAddress);
event TokenDistributorUpdated(address indexed newAddress);
event ProxyCreated(bytes32 id, address indexed newAddress);
@ -39,9 +37,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
bytes32 private constant ETHEREUM_ADDRESS = 'ETHEREUM_ADDRESS';
bytes32 private constant PRICE_ORACLE = 'PRICE_ORACLE';
bytes32 private constant LENDING_RATE_ORACLE = 'LENDING_RATE_ORACLE';
bytes32 private constant FEE_PROVIDER = 'FEE_PROVIDER';
bytes32 private constant WALLET_BALANCE_PROVIDER = 'WALLET_BALANCE_PROVIDER';
bytes32 private constant TOKEN_DISTRIBUTOR = 'TOKEN_DISTRIBUTOR';
/**
* @dev returns the address of the LendingPool proxy
@ -77,23 +73,6 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
emit LendingPoolConfiguratorUpdated(configurator);
}
/**
* @dev returns the address of the FeeProvider proxy
* @return the address of the Fee provider proxy
**/
function getFeeProvider() external override view returns (address) {
return _addresses[FEE_PROVIDER];
}
/**
* @dev updates the implementation of the FeeProvider proxy
* @param feeProvider the new lending pool fee provider implementation
**/
function setFeeProviderImpl(address feeProvider) external override onlyOwner {
updateImplInternal(FEE_PROVIDER, feeProvider);
emit FeeProviderUpdated(feeProvider);
}
/**
* @dev returns the address of the LendingPoolLiquidationManager. Since the manager is used
* through delegateCall within the LendingPool contract, the proxy contract pattern does not work properly hence
@ -146,15 +125,6 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
emit LendingRateOracleUpdated(lendingRateOracle);
}
function getTokenDistributor() external override view returns (address) {
return _addresses[TOKEN_DISTRIBUTOR];
}
function setTokenDistributor(address tokenDistributor) external override onlyOwner {
_addresses[TOKEN_DISTRIBUTOR] = tokenDistributor;
emit TokenDistributorUpdated(tokenDistributor);
}
/**
* @dev internal function to update the implementation of a specific component of the protocol
* @param id the id of the contract to be updated

View File

@ -1,55 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
import '../interfaces/IFeeProvider.sol';
import '../libraries/math/WadRayMath.sol';
/**
* @title FeeProvider contract
* @notice Implements calculation for the fees applied by the protocol
* @author Aave
**/
contract FeeProvider is IFeeProvider, VersionedInitializable {
using WadRayMath for uint256;
// percentage of the fee to be calculated on the loan amount
uint256 public originationFeePercentage;
uint256 public constant FEE_PROVIDER_REVISION = 0x1;
function getRevision() internal override pure returns (uint256) {
return FEE_PROVIDER_REVISION;
}
/**
* @dev initializes the FeeProvider after it's added to the proxy
* @param _addressesProvider the address of the LendingPoolAddressesProvider
*/
function initialize(address _addressesProvider) public initializer {
/// @notice origination fee is set as default as 25 basis points of the loan amount (0.0025%)
originationFeePercentage = 0.0025 * 1e18;
}
/**
* @dev calculates the origination fee for every loan executed on the platform.
* @param _user can be used in the future to apply discount to the origination fee based on the
* _user account (eg. stake AAVE tokens in the lending pool, or deposit > 1M USD etc.)
* @param _amount the amount of the loan
**/
function calculateLoanOriginationFee(address _user, uint256 _amount)
external
override
view
returns (uint256)
{
return _amount.wadMul(originationFeePercentage);
}
/**
* @dev returns the origination fee percentage
**/
function getLoanOriginationFeePercentage() external override view returns (uint256) {
return originationFeePercentage;
}
}

View File

@ -1,220 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
import '@openzeppelin/contracts/math/SafeMath.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol';
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
import '../interfaces/IExchangeAdapter.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
/// @title TokenDistributor
/// @author Aave
/// @notice Receives tokens and manages the distribution amongst receivers
/// The usage is as follows:
/// - The distribution addresses and percentages are set up on construction
/// - The Kyber Proxy is approved for a list of tokens in construction, which will be later burnt
/// - At any moment, anyone can call distribute() with a list of token addresses in order to distribute
/// the accumulated token amounts and/or ETH in this contract to all the receivers with percentages
/// - If the address(0) is used as receiver, this contract will trade in Kyber to tokenToBurn (LEND)
/// and burn it (sending to address(0) the tokenToBurn)
contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
using SafeMath for uint256;
using PercentageMath for uint256;
using SafeERC20 for IERC20;
struct Distribution {
address[] receivers;
uint256[] percentages;
}
event DistributionUpdated(address[] receivers, uint256[] percentages);
event Distributed(address receiver, uint256 percentage, uint256 amount);
event Setup(address tokenToBurn, IExchangeAdapter exchangeAdapter, address _recipientBurn);
event Burn(uint256 amount);
uint256 public constant IMPLEMENTATION_REVISION = 0x3;
/// @notice DEPRECATED
uint256 public constant MAX_UINT = 2**256 - 1;
/// @notice DEPRECATED
uint256 public constant MAX_UINT_MINUS_ONE = (2**256 - 1) - 1;
/// @notice DEPRECATED
uint256 public constant MIN_CONVERSION_RATE = 1;
/// @notice DEPRECATED
address public constant KYBER_ETH_MOCK_ADDRESS = address(
0x00eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
);
/// @notice Defines how tokens and ETH are distributed on each call to .distribute()
Distribution private distribution;
/// @notice Instead of using 100 for percentages, higher base to have more precision in the distribution
uint256 public constant DISTRIBUTION_BASE = 10000;
/// @notice The address of the token to burn (LEND token)
address public tokenToBurn;
/// @notice Address to send tokens to "burn".
/// Because of limitations on OZ ERC20, on dev it's needed to use the 0x00000...1 address instead of address(0)
/// So this param needs to be received on construction
address public recipientBurn;
/// @notice Smart contract implementing the logic to interact with a particular exchange.
/// Will be called by DELEGATECALL
IExchangeAdapter public exchangeAdapter;
/// @notice Called by the proxy when setting this contract as implementation
function initialize(
address _recipientBurn,
address _tokenToBurn,
IExchangeAdapter _exchangeAdapter,
address[] memory _receivers,
uint256[] memory _percentages,
IERC20[] memory _tokens
) public initializer {
recipientBurn = _recipientBurn;
tokenToBurn = _tokenToBurn;
exchangeAdapter = _exchangeAdapter;
internalSetTokenDistribution(_receivers, _percentages);
approveExchange(_tokens);
emit Setup(_tokenToBurn, _exchangeAdapter, _recipientBurn);
}
/// @notice In order to receive ETH transfers
receive() external payable {}
/// @notice "Infinite" approval for all the tokens initialized
/// @param _tokens List of IERC20 to approve
function approveExchange(IERC20[] memory _tokens) public {
(bool _success, ) = address(exchangeAdapter).delegatecall(
abi.encodeWithSelector(exchangeAdapter.approveExchange.selector, _tokens)
);
}
/// @notice Distributes the whole balance of a list of _tokens balances in this contract
/// @param _tokens list of ERC20 tokens to distribute
function distribute(IERC20[] memory _tokens) public {
for (uint256 i = 0; i < _tokens.length; i++) {
uint256 _balanceToDistribute = _tokens[i].balanceOf(address(this));
if (_balanceToDistribute <= 0) {
continue;
}
internalDistributeTokenWithAmount(_tokens[i], _balanceToDistribute);
}
}
/// @notice Distributes specific amounts of a list of _tokens
/// @param _tokens list of ERC20 tokens to distribute
/// @param _amounts list of amounts to distribute per token
function distributeWithAmounts(IERC20[] memory _tokens, uint256[] memory _amounts) public {
for (uint256 i = 0; i < _tokens.length; i++) {
internalDistributeTokenWithAmount(_tokens[i], _amounts[i]);
}
}
/// @notice Distributes specific total balance's percentages of a list of _tokens
/// @param _tokens list of ERC20 tokens to distribute
/// @param _percentages list of percentages to distribute per token
function distributeWithPercentages(IERC20[] memory _tokens, uint256[] memory _percentages)
public
{
for (uint256 i = 0; i < _tokens.length; i++) {
uint256 _amountToDistribute = _tokens[i].balanceOf(address(this)).percentMul(_percentages[i]);
if (_amountToDistribute <= 0) {
continue;
}
internalDistributeTokenWithAmount(_tokens[i], _amountToDistribute);
}
}
/// @notice Sets _receivers addresses with _percentages for each one
/// @param _receivers Array of addresses receiving a percentage of the distribution, both user addresses
/// or contracts
/// @param _percentages Array of percentages each _receivers member will get
function internalSetTokenDistribution(address[] memory _receivers, uint256[] memory _percentages)
internal
{
require(_receivers.length == _percentages.length, 'Array lengths should be equal');
distribution = Distribution({receivers: _receivers, percentages: _percentages});
emit DistributionUpdated(_receivers, _percentages);
}
/// @notice Distributes a specific amount of a token owned by this contract
/// @param _token The ERC20 token to distribute
/// @param _amountToDistribute The specific amount to distribute
function internalDistributeTokenWithAmount(IERC20 _token, uint256 _amountToDistribute) internal {
address _tokenAddress = address(_token);
Distribution memory _distribution = distribution;
for (uint256 j = 0; j < _distribution.receivers.length; j++) {
uint256 _amount = _amountToDistribute.mul(_distribution.percentages[j]).div(
DISTRIBUTION_BASE
);
//avoid transfers/burns of 0 tokens
if (_amount == 0) {
continue;
}
if (_distribution.receivers[j] != address(0)) {
_token.safeTransfer(_distribution.receivers[j], _amount);
emit Distributed(_distribution.receivers[j], _distribution.percentages[j], _amount);
} else {
uint256 _amountToBurn = _amount;
// If the token to burn is already tokenToBurn, we don't trade, burning directly
if (_tokenAddress != tokenToBurn) {
(bool _success, bytes memory _result) = address(exchangeAdapter).delegatecall(
abi.encodeWithSelector(
exchangeAdapter.exchange.selector,
_tokenAddress,
tokenToBurn,
_amount,
10
)
);
require(_success, 'ERROR_ON_EXCHANGE');
_amountToBurn = abi.decode(_result, (uint256));
}
_burn(_amountToBurn);
}
}
}
/// @notice Internal function to send _amount of tokenToBurn to the 0x0 address
/// @param _amount The amount to burn
function _burn(uint256 _amount) internal {
require(
IERC20(tokenToBurn).transfer(recipientBurn, _amount),
'INTERNAL_BURN. Reverted transfer to recipientBurn address'
);
emit Burn(_amount);
}
/// @notice Returns the receivers and percentages of the contract Distribution
/// @return receivers array of addresses and percentages array on uints
function getDistribution()
public
view
returns (address[] memory receivers, uint256[] memory percentages)
{
receivers = distribution.receivers;
percentages = distribution.percentages;
}
/// @notice Gets the revision number of the contract
/// @return The revision numeric reference
function getRevision() internal override pure returns (uint256) {
return IMPLEMENTATION_REVISION;
}
}

View File

@ -1,16 +0,0 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8;
/**
* @title IFeeProvider interface
* @notice Interface for the Aave fee provider.
**/
interface IFeeProvider {
function calculateLoanOriginationFee(address _user, uint256 _amount)
external
view
returns (uint256);
function getLoanOriginationFeePercentage() external view returns (uint256);
}

View File

@ -15,14 +15,6 @@ interface ILendingPoolAddressesProvider {
function setLendingPoolConfiguratorImpl(address configurator) external;
function getTokenDistributor() external view returns (address);
function setTokenDistributor(address tokenDistributor) external;
function getFeeProvider() external view returns (address);
function setFeeProviderImpl(address feeProvider) external;
function getLendingPoolLiquidationManager() external view returns (address);
function setLendingPoolLiquidationManager(address manager) external;

View File

@ -20,7 +20,6 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
@ -44,10 +43,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint256 private constant REBALANCE_DOWN_RATE_DELTA = (1e27) / 5;
uint256 private constant MAX_STABLE_RATE_BORROW_SIZE_PERCENT = 25;
uint256 private constant FLASHLOAN_FEE_TOTAL = 9;
uint256 private constant FLASHLOAN_FEE_PROTOCOL = 3000;
LendingPoolAddressesProvider public addressesProvider;
IFeeProvider feeProvider;
using SafeERC20 for IERC20;
mapping(address => ReserveLogic.ReserveData) internal reserves;
@ -161,7 +158,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
* @param _reserve the address of the reserve
* @param _amount the amount requested
* @param _totalFee the total fee on the amount
* @param _protocolFee the part of the fee for the protocol
* @param _timestamp the timestamp of the action
**/
event FlashLoan(
@ -169,7 +165,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
address indexed _reserve,
uint256 _amount,
uint256 _totalFee,
uint256 _protocolFee,
uint256 _timestamp
);
@ -245,7 +240,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
**/
function initialize(LendingPoolAddressesProvider _addressesProvider) public initializer {
addressesProvider = _addressesProvider;
feeProvider = IFeeProvider(addressesProvider.getFeeProvider());
}
/**
@ -264,7 +258,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
ValidationLogic.validateDeposit(reserve, _amount);
AToken aToken = AToken(payable(reserve.aTokenAddress));
AToken aToken = AToken(reserve.aTokenAddress);
bool isFirstDeposit = aToken.balanceOf(msg.sender) == 0;
@ -644,15 +638,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
}
}
struct FlashLoanLocalVars {
uint256 availableLiquidityBefore;
uint256 totalFeeBips;
uint256 protocolFeeBips;
uint256 amountFee;
uint256 protocolFee;
address payable aTokenAddress;
}
/**
* @dev allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
@ -667,29 +652,21 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
uint256 _amount,
bytes memory _params
) public nonReentrant {
FlashLoanLocalVars memory vars;
ReserveLogic.ReserveData storage reserve = reserves[_reserve];
vars.aTokenAddress = payable(reserve.aTokenAddress);
address payable aTokenAddress = payable(reserve.aTokenAddress);
//check that the reserve has enough available liquidity
vars.availableLiquidityBefore = IERC20(_reserve).balanceOf(vars.aTokenAddress);
uint256 availableLiquidityBefore = IERC20(_reserve).balanceOf(aTokenAddress);
//calculate amount fee
vars.amountFee = _amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
//protocol fee is the part of the amountFee reserved for the protocol - the rest goes to depositors
vars.protocolFee = vars.amountFee.mul(FLASHLOAN_FEE_PROTOCOL).div(10000);
uint256 amountFee = _amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
require(
vars.availableLiquidityBefore >= _amount,
availableLiquidityBefore >= _amount,
'There is not enough liquidity available to borrow'
);
require(
vars.amountFee > 0 && vars.protocolFee > 0,
'The requested amount is too small for a FlashLoan.'
);
require(amountFee > 0, 'The requested amount is too small for a FlashLoan.');
//get the FlashLoanReceiver instance
IFlashLoanReceiver receiver = IFlashLoanReceiver(_receiver);
@ -697,34 +674,23 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
address payable userPayable = address(uint160(_receiver));
//transfer funds to the receiver
AToken(vars.aTokenAddress).transferUnderlyingTo(userPayable, _amount);
AToken(aTokenAddress).transferUnderlyingTo(userPayable, _amount);
//execute action of the receiver
receiver.executeOperation(_reserve, vars.aTokenAddress, _amount, vars.amountFee, _params);
receiver.executeOperation(_reserve, aTokenAddress, _amount, amountFee, _params);
//check that the actual balance of the core contract includes the returned amount
uint256 availableLiquidityAfter = IERC20(_reserve).balanceOf(vars.aTokenAddress);
uint256 availableLiquidityAfter = IERC20(_reserve).balanceOf(aTokenAddress);
require(
availableLiquidityAfter == vars.availableLiquidityBefore.add(vars.amountFee),
availableLiquidityAfter == availableLiquidityBefore.add(amountFee),
'The actual balance of the protocol is inconsistent'
);
reserve.updateStateOnFlashLoan(
_reserve,
vars.availableLiquidityBefore,
vars.amountFee.sub(vars.protocolFee),
vars.protocolFee
);
//transfer funds to the receiver
AToken(vars.aTokenAddress).transferUnderlyingTo(
addressesProvider.getTokenDistributor(),
vars.protocolFee
);
reserve.updateStateOnFlashLoan(_reserve, availableLiquidityBefore, amountFee);
//solium-disable-next-line
emit FlashLoan(_receiver, _reserve, _amount, vars.amountFee, vars.protocolFee, block.timestamp);
emit FlashLoan(_receiver, _reserve, _amount, amountFee, block.timestamp);
}
/**

View File

@ -22,7 +22,6 @@ import {Helpers} from '../libraries/helpers/Helpers.sol';
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
/**
* @title LendingPoolLiquidationManager contract
@ -40,7 +39,6 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
using UserConfiguration for UserConfiguration.Map;
LendingPoolAddressesProvider public addressesProvider;
IFeeProvider feeProvider;
mapping(address => ReserveLogic.ReserveData) internal reserves;
mapping(address => UserConfiguration.Map) internal usersConfig;

View File

@ -6,7 +6,6 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {ReserveLogic} from '../logic/ReserveLogic.sol';
import {WadRayMath} from '../math/WadRayMath.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
/**
* @title ReserveConfiguration library

View File

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

View File

@ -10,7 +10,6 @@ import {UserConfiguration} from '../configuration/UserConfiguration.sol';
import {WadRayMath} from '../math/WadRayMath.sol';
import {PercentageMath} from '../math/PercentageMath.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
/**
* @title GenericLogic library

View File

@ -208,8 +208,7 @@ library ReserveLogic {
ReserveData storage _reserve,
address _reserveAddress,
uint256 _availableLiquidityBefore,
uint256 _income,
uint256 _protocolFee
uint256 _income
) external {
//compounding the cumulated interest
_reserve.updateCumulativeIndexesAndTimestamp();

View File

@ -12,7 +12,6 @@ import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
import {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
/**
* @title ReserveLogic library

View File

@ -31,7 +31,8 @@
},
"FeeProvider": {
"buidlerevm": {
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
"address": "0xFAe0fd738dAbc8a0426F47437322b6d026A9FD95",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
@ -49,7 +50,7 @@
},
"LendingPoolConfigurator": {
"buidlerevm": {
"address": "0x9EC0480CF106d6dc1c7849BA141a56F874170F97"
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
},
"localhost": {
"address": "0x9EC0480CF106d6dc1c7849BA141a56F874170F97"
@ -62,7 +63,7 @@
},
"LendingPool": {
"buidlerevm": {
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
},
"localhost": {
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
@ -70,7 +71,7 @@
},
"PriceOracle": {
"buidlerevm": {
"address": "0x099d9fF8F818290C8b5B7Db5bFca84CEebd2714c",
"address": "0x1750499D05Ed1674d822430FB960d5F6731fDf64",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -80,7 +81,7 @@
},
"MockAggregator": {
"buidlerevm": {
"address": "0xAF6BA11790D1942625C0c2dA07da19AB63845cfF",
"address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -90,7 +91,7 @@
},
"ChainlinkProxyPriceProvider": {
"buidlerevm": {
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"address": "0x7B6C3e5486D9e6959441ab554A889099eed76290",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -100,7 +101,7 @@
},
"LendingRateOracle": {
"buidlerevm": {
"address": "0xf91aC1098F3b154671Ce83290114aaE45ac0225f",
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -110,7 +111,7 @@
},
"DefaultReserveInterestRateStrategy": {
"buidlerevm": {
"address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
"address": "0x626FdE749F9d499d3777320CAf29484B624ab84a",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -146,7 +147,8 @@
},
"TokenDistributor": {
"buidlerevm": {
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
@ -164,7 +166,7 @@
},
"MockFlashLoanReceiver": {
"buidlerevm": {
"address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60"
"address": "0x2B681757d757fbB80cc51c6094cEF5eE75bF55aA"
},
"localhost": {
"address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60"
@ -172,7 +174,7 @@
},
"WalletBalanceProvider": {
"buidlerevm": {
"address": "0x392E5355a0e88Bd394F717227c752670fb3a8020",
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -412,7 +414,7 @@
},
"AaveProtocolTestHelpers": {
"buidlerevm": {
"address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460"
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
},
"localhost": {
"address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460"
@ -420,7 +422,7 @@
},
"StableDebtToken": {
"buidlerevm": {
"address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
"address": "0xB660Fdd109a95718cB9d20E3A89EE6cE342aDcB6",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -430,7 +432,7 @@
},
"VariableDebtToken": {
"buidlerevm": {
"address": "0x5f7134cd38C826a7649f9Cc47dda24d834DD2967",
"address": "0x830bceA96E56DBC1F8578f75fBaC0AF16B32A07d",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -444,13 +446,13 @@
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"buidlerevm": {
"address": "0xE91bBe8ee03560E3dda2786f95335F5399813Ca0",
"address": "0xA0AB1cB92A4AF81f84dCd258155B5c25D247b54E",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
}
},
"MockAToken": {
"buidlerevm": {
"address": "0xD4B5A49d5bA242572ec3f4A8E52B97a10AF2543a",
"address": "0x3bDA11B584dDff7F66E0cFe1da1562c92B45db60",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -470,7 +472,7 @@
},
"MockStableDebtToken": {
"buidlerevm": {
"address": "0x6aaF7e94e099291a94ed8E245c90f4766CE9bB7C",
"address": "0x392E5355a0e88Bd394F717227c752670fb3a8020",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {
@ -480,7 +482,7 @@
},
"MockVariableDebtToken": {
"buidlerevm": {
"address": "0x40A939911b662656C0EE71c19B954DB1911Dc8e3",
"address": "0x3b050AFb4ac4ACE646b31fF3639C1CD43aC31460",
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
},
"localhost": {

View File

@ -13,7 +13,6 @@ import {
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {MintableErc20} from '../types/MintableErc20';
import {LendingPoolAddressesProviderRegistry} from '../types/LendingPoolAddressesProviderRegistry';
import {FeeProvider} from '../types/FeeProvider';
import {LendingPoolConfigurator} from '../types/LendingPoolConfigurator';
import {readArtifact} from '@nomiclabs/buidler/plugins';
import {Artifact} from '@nomiclabs/buidler/types';
@ -23,7 +22,6 @@ import {MockAggregator} from '../types/MockAggregator';
import {LendingRateOracle} from '../types/LendingRateOracle';
import {DefaultReserveInterestRateStrategy} from '../types/DefaultReserveInterestRateStrategy';
import {LendingPoolLiquidationManager} from '../types/LendingPoolLiquidationManager';
import {TokenDistributor} from '../types/TokenDistributor';
import {InitializableAdminUpgradeabilityProxy} from '../types/InitializableAdminUpgradeabilityProxy';
import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
import {WalletBalanceProvider} from '../types/WalletBalanceProvider';
@ -102,9 +100,6 @@ export const deployLendingPoolAddressesProviderRegistry = async () =>
[]
);
export const deployFeeProvider = async () =>
await deployContract<FeeProvider>(eContractid.FeeProvider, []);
export const deployLendingPoolConfigurator = async () =>
await deployContract<LendingPoolConfigurator>(eContractid.LendingPoolConfigurator, []);
@ -206,9 +201,6 @@ export const deployLendingPoolLiquidationManager = async () => {
return (await liquidationManager.deployed()) as LendingPoolLiquidationManager;
};
export const deployTokenDistributor = async () =>
await deployContract<TokenDistributor>(eContractid.TokenDistributor, []);
export const deployInitializableAdminUpgradeabilityProxy = async () =>
await deployContract<InitializableAdminUpgradeabilityProxy>(
eContractid.InitializableAdminUpgradeabilityProxy,
@ -335,13 +327,6 @@ export const getLendingPool = async (address?: tEthereumAddress) => {
);
};
export const getFeeProvider = async (address?: tEthereumAddress) => {
return await getContract<FeeProvider>(
eContractid.FeeProvider,
address || (await getDb().get(`${eContractid.FeeProvider}.${BRE.network.name}`).value()).address
);
};
export const getPriceOracle = async (address?: tEthereumAddress) => {
return await getContract<PriceOracle>(
eContractid.PriceOracle,
@ -402,14 +387,6 @@ export const getMockFlashLoanReceiver = async (address?: tEthereumAddress) => {
);
};
export const getTokenDistributor = async (address?: tEthereumAddress) => {
return await getContract<TokenDistributor>(
eContractid.TokenDistributor,
address ||
(await getDb().get(`${eContractid.TokenDistributor}.${BRE.network.name}`).value()).address
);
};
export const getLendingRateOracle = async (address?: tEthereumAddress) => {
return await getContract<LendingRateOracle>(
eContractid.LendingRateOracle,

View File

@ -17,12 +17,10 @@ export enum eContractid {
LendingPoolAddressesProvider = 'LendingPoolAddressesProvider',
MintableERC20 = 'MintableERC20',
LendingPoolAddressesProviderRegistry = 'LendingPoolAddressesProviderRegistry',
FeeProvider = 'FeeProvider',
LendingPoolParametersProvider = 'LendingPoolParametersProvider',
LendingPoolConfigurator = 'LendingPoolConfigurator',
ValidationLogic = 'ValidationLogic',
ReserveLogic = 'ReserveLogic',
UserLogic = 'UserLogic',
GenericLogic = 'GenericLogic',
LendingPool = 'LendingPool',
PriceOracle = 'PriceOracle',
@ -32,7 +30,6 @@ export enum eContractid {
ChainlinkProxyPriceProvider = 'ChainlinkProxyPriceProvider',
DefaultReserveInterestRateStrategy = 'DefaultReserveInterestRateStrategy',
LendingPoolLiquidationManager = 'LendingPoolLiquidationManager',
TokenDistributor = 'TokenDistributor',
InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
MockFlashLoanReceiver = 'MockFlashLoanReceiver',
WalletBalanceProvider = 'WalletBalanceProvider',

23
package-lock.json generated
View File

@ -7524,6 +7524,7 @@
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
@ -9990,6 +9991,17 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -13213,6 +13225,7 @@
"dev": true,
"optional": true,
"requires": {
"scrypt": "^6.0.2",
"scryptsy": "^1.2.1"
}
},
@ -18633,6 +18646,16 @@
}
}
},
"scrypt": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz",
"integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=",
"dev": true,
"optional": true,
"requires": {
"nan": "^2.0.8"
}
},
"scrypt-js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",

View File

@ -4,7 +4,6 @@ import {
deployLendingPoolAddressesProvider,
deployMintableErc20,
deployLendingPoolAddressesProviderRegistry,
deployFeeProvider,
deployLendingPoolConfigurator,
deployLendingPool,
deployPriceOracle,
@ -14,11 +13,8 @@ import {
deployLendingRateOracle,
deployDefaultReserveInterestRateStrategy,
deployLendingPoolLiquidationManager,
deployTokenDistributor,
deployInitializableAdminUpgradeabilityProxy,
deployMockFlashLoanReceiver,
deployWalletBalancerProvider,
getFeeProvider,
getLendingPool,
insertContractAddressInDb,
deployAaveProtocolTestHelpers,
@ -29,7 +25,7 @@ import {
deployGenericAToken,
} from '../helpers/contracts-helpers';
import {LendingPoolAddressesProvider} from '../types/LendingPoolAddressesProvider';
import {Wallet, ContractTransaction, ethers, Signer} from 'ethers';
import {ContractTransaction, Signer} from 'ethers';
import {
TokenContractId,
eContractid,
@ -62,7 +58,7 @@ import path from 'path';
import fs from 'fs';
['misc'].forEach((folder) => {
const tasksPath = path.join('/src/', 'tasks', folder);
const tasksPath = path.join(__dirname, '../', 'tasks', folder);
fs.readdirSync(tasksPath).forEach((task) => require(`${tasksPath}/${task}`));
});
@ -364,11 +360,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
await addressesProviderRegistry.registerAddressesProvider(addressesProvider.address, 0)
);
const feeProviderImpl = await deployFeeProvider();
await waitForTx(await addressesProvider.setFeeProviderImpl(feeProviderImpl.address));
const feeProviderProxy = await getFeeProvider(await addressesProvider.getFeeProvider());
await insertContractAddressInDb(eContractid.FeeProvider, feeProviderProxy.address);
const lendingPoolImpl = await deployLendingPool();
console.log('Deployed lending pool, address:', lendingPoolImpl.address);
@ -509,29 +500,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
await addressesProvider.setLendingPoolLiquidationManager(liquidationManager.address)
);
const {receivers, percentages} = getFeeDistributionParamsCommon(lendingPoolManager);
const tokenDistributorImpl = await deployTokenDistributor();
const tokenDistributorProxy = await deployInitializableAdminUpgradeabilityProxy();
const implementationParams = tokenDistributorImpl.interface.encodeFunctionData('initialize', [
ZERO_ADDRESS,
tokensAddressesWithoutUsd.LEND,
'0x0000000000000000000000000000000000000000', // TODO: finish removal
receivers,
percentages,
Object.values(tokensAddressesWithoutUsd),
]);
await waitForTx(
await tokenDistributorProxy['initialize(address,address,bytes)'](
tokenDistributorImpl.address,
await secondaryWallet.getAddress(),
implementationParams
)
);
await waitForTx(await addressesProvider.setTokenDistributor(tokenDistributorProxy.address));
await insertContractAddressInDb(eContractid.TokenDistributor, tokenDistributorProxy.address);
const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(addressesProvider.address);
await insertContractAddressInDb(eContractid.MockFlashLoanReceiver, mockFlashLoanReceiver.address);

View File

@ -1,14 +1,8 @@
import {TestEnv, makeSuite} from './helpers/make-suite';
import {APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
import {
convertToCurrencyDecimals,
getMockFlashLoanReceiver,
getTokenDistributor,
} from '../helpers/contracts-helpers';
import {convertToCurrencyDecimals, getMockFlashLoanReceiver} from '../helpers/contracts-helpers';
import {ethers} from 'ethers';
import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
import {TokenDistributor} from '../types/TokenDistributor';
import {BRE} from '../helpers/misc-utils';
import {ProtocolErrors} from '../helpers/types';
import BigNumber from 'bignumber.js';
@ -16,7 +10,6 @@ const {expect} = require('chai');
makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
let _mockFlashLoanReceiver = {} as MockFlashLoanReceiver;
let _tokenDistributor = {} as TokenDistributor;
const {
INCONSISTENT_PROTOCOL_BALANCE,
TOO_SMALL_FLASH_LOAN,
@ -25,7 +18,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
before(async () => {
_mockFlashLoanReceiver = await getMockFlashLoanReceiver();
_tokenDistributor = await getTokenDistributor();
});
it('Deposits ETH into the reserve', async () => {
@ -60,26 +52,26 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
.plus(reserveData.totalBorrowsStable.toString())
.plus(reserveData.totalBorrowsVariable.toString());
const tokenDistributorBalance = await weth.balanceOf(_tokenDistributor.address);
expect(totalLiquidity.toString()).to.be.equal('1000504000000000000');
expect(totalLiquidity.toString()).to.be.equal('1000720000000000000');
expect(currentLiquidityRate.toString()).to.be.equal('0');
expect(currentLiquidityIndex.toString()).to.be.equal('1000504000000000000000000000');
expect(tokenDistributorBalance).to.be.equal('216000000000000');
expect(currentLiquidityIndex.toString()).to.be.equal('1000720000000000000000000000');
});
it('Takes an ETH flashloan as big as the available liquidity', async () => {
const {pool, deployer, weth} = testEnv;
const {pool, weth} = testEnv;
const reserveDataBefore = await pool.getReserveData(weth.address);
console.log("Total liquidity is ", reserveDataBefore.availableLiquidity.toString());
const txResult = await pool.flashLoan(
_mockFlashLoanReceiver.address,
weth.address,
'1000504000000000000',
'1000720000000000000',
'0x10'
);
const reserveData = await pool.getReserveData(weth.address);
const tokenDistributorBalance = await weth.balanceOf(_tokenDistributor.address);
const currentLiqudityRate = reserveData.liquidityRate;
const currentLiquidityIndex = reserveData.liquidityIndex;
@ -88,10 +80,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
.plus(reserveData.totalBorrowsStable.toString())
.plus(reserveData.totalBorrowsVariable.toString());
expect(totalLiquidity.toString()).to.be.equal('1001134317520000000');
expect(totalLiquidity.toString()).to.be.equal('1001620648000000000');
expect(currentLiqudityRate.toString()).to.be.equal('0');
expect(currentLiquidityIndex.toString()).to.be.equal('1001134317520000000000000000');
expect(tokenDistributorBalance.toString()).to.be.equal('486136080000000');
expect(currentLiquidityIndex.toString()).to.be.equal('1001620648000000000000000000');
});
it('Takes WETH flashloan, does not return the funds (revert expected)', async () => {
@ -180,22 +171,15 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
const currentLiquidityIndex = reserveData.liquidityIndex.toString();
const currentUserBalance = userData.currentATokenBalance.toString();
const expectedLiquidity = ethers.utils.parseEther('1000.315');
const tokenDistributorBalance = await dai.balanceOf(_tokenDistributor.address);
const expectedLiquidity = ethers.utils.parseEther('1000.450');
expect(totalLiquidity).to.be.equal(expectedLiquidity, 'Invalid total liquidity');
expect(currentLiqudityRate).to.be.equal('0', 'Invalid liquidity rate');
expect(currentLiquidityIndex).to.be.equal(
new BigNumber('1.000315').multipliedBy(oneRay).toFixed(),
new BigNumber('1.00045').multipliedBy(oneRay).toFixed(),
'Invalid liquidity index'
);
expect(currentUserBalance.toString()).to.be.equal(expectedLiquidity, 'Invalid user balance');
expect(tokenDistributorBalance.toString()).to.be.equal(
ethers.utils.parseEther('0.135'),
'Invalid token distributor balance'
);
});
it('Takes out a 500 DAI flashloan, does not return the funds (revert expected)', async () => {

View File

@ -12,7 +12,6 @@ makeSuite('LendingPoolAddressesProvider', (testEnv: TestEnv) => {
await addressesProvider.transferOwnership(users[1].address);
for (const contractFunction of [
addressesProvider.setFeeProviderImpl,
addressesProvider.setLendingPoolImpl,
addressesProvider.setLendingPoolConfiguratorImpl,
addressesProvider.setLendingPoolLiquidationManager,