2020-05-29 16:45:37 +00:00
|
|
|
// SPDX-License-Identifier: agpl-3.0
|
2020-11-20 10:45:20 +00:00
|
|
|
pragma solidity 0.6.12;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-10-12 12:25:03 +00:00
|
|
|
pragma experimental ABIEncoderV2;
|
|
|
|
|
2020-10-15 13:41:56 +00:00
|
|
|
import {Address} from '../dependencies/openzeppelin/contracts/Address.sol';
|
|
|
|
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-11-06 14:32:51 +00:00
|
|
|
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
2020-08-20 12:32:20 +00:00
|
|
|
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
2020-10-15 13:41:56 +00:00
|
|
|
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
2020-11-23 10:28:57 +00:00
|
|
|
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
2020-11-24 13:53:34 +00:00
|
|
|
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
2020-05-29 16:45:37 +00:00
|
|
|
|
|
|
|
/**
|
2020-06-20 23:40:03 +00:00
|
|
|
* @title WalletBalanceProvider contract
|
|
|
|
* @author Aave, influenced by https://github.com/wbobeirne/eth-balance-checker/blob/master/contracts/BalanceChecker.sol
|
|
|
|
* @notice Implements a logic of getting multiple tokens balance for one user address
|
|
|
|
* @dev NOTE: THIS CONTRACT IS NOT USED WITHIN THE AAVE PROTOCOL. It's an accessory contract used to reduce the number of calls
|
|
|
|
* towards the blockchain from the Aave backend.
|
|
|
|
**/
|
2020-05-29 16:45:37 +00:00
|
|
|
contract WalletBalanceProvider {
|
2020-06-20 23:40:03 +00:00
|
|
|
using Address for address payable;
|
|
|
|
using Address for address;
|
2020-08-12 17:36:58 +00:00
|
|
|
using SafeERC20 for IERC20;
|
2020-11-24 15:17:27 +00:00
|
|
|
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-11-06 14:06:52 +00:00
|
|
|
address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-08-20 10:44:51 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
@dev Fallback function, don't accept any ETH
|
|
|
|
**/
|
2020-06-20 23:40:03 +00:00
|
|
|
receive() external payable {
|
|
|
|
//only contracts can send ETH to the core
|
|
|
|
require(msg.sender.isContract(), '22');
|
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
|
2020-06-20 23:40:03 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
@dev Check the token balance of a wallet in a token contract
|
|
|
|
|
|
|
|
Returns the balance of the token for user. Avoids possible errors:
|
|
|
|
- return 0 on non-contract address
|
|
|
|
**/
|
2020-08-21 12:00:10 +00:00
|
|
|
function balanceOf(address user, address token) public view returns (uint256) {
|
2020-11-06 15:01:19 +00:00
|
|
|
if (token == MOCK_ETH_ADDRESS) {
|
|
|
|
return user.balance; // ETH balance
|
|
|
|
// check if token is actually a contract
|
|
|
|
} else if (token.isContract()) {
|
2020-08-21 12:00:10 +00:00
|
|
|
return IERC20(token).balanceOf(user);
|
2020-06-20 23:40:03 +00:00
|
|
|
}
|
2020-11-06 15:01:19 +00:00
|
|
|
revert('INVALID_TOKEN');
|
2020-06-20 23:40:03 +00:00
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
|
2020-07-10 09:20:15 +00:00
|
|
|
/**
|
2020-07-13 08:54:08 +00:00
|
|
|
* @notice Fetches, for a list of _users and _tokens (ETH included with mock address), the balances
|
2020-08-21 12:00:10 +00:00
|
|
|
* @param users The list of users
|
|
|
|
* @param tokens The list of tokens
|
2020-07-13 08:54:08 +00:00
|
|
|
* @return And array with the concatenation of, for each user, his/her balances
|
|
|
|
**/
|
2020-08-21 12:00:10 +00:00
|
|
|
function batchBalanceOf(address[] calldata users, address[] calldata tokens)
|
|
|
|
external
|
2020-06-20 23:40:03 +00:00
|
|
|
view
|
|
|
|
returns (uint256[] memory)
|
|
|
|
{
|
2020-08-21 12:00:10 +00:00
|
|
|
uint256[] memory balances = new uint256[](users.length * tokens.length);
|
2020-06-20 23:40:03 +00:00
|
|
|
|
2020-08-21 12:00:10 +00:00
|
|
|
for (uint256 i = 0; i < users.length; i++) {
|
|
|
|
for (uint256 j = 0; j < tokens.length; j++) {
|
2020-11-06 15:01:19 +00:00
|
|
|
balances[i * tokens.length + j] = balanceOf(users[i], tokens[j]);
|
2020-06-20 23:40:03 +00:00
|
|
|
}
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|
|
|
|
|
2020-06-20 23:40:03 +00:00
|
|
|
return balances;
|
|
|
|
}
|
2020-07-13 08:54:08 +00:00
|
|
|
|
2020-06-20 23:40:03 +00:00
|
|
|
/**
|
2020-05-29 16:45:37 +00:00
|
|
|
@dev provides balances of user wallet for all reserves available on the pool
|
|
|
|
*/
|
2020-11-20 10:32:17 +00:00
|
|
|
function getUserWalletBalances(address provider, address user)
|
2020-08-21 12:00:10 +00:00
|
|
|
external
|
2020-06-20 23:40:03 +00:00
|
|
|
view
|
|
|
|
returns (address[] memory, uint256[] memory)
|
|
|
|
{
|
2020-11-20 10:32:17 +00:00
|
|
|
ILendingPool pool = ILendingPool(ILendingPoolAddressesProvider(provider).getLendingPool());
|
2020-06-20 23:40:03 +00:00
|
|
|
|
2020-10-06 13:51:48 +00:00
|
|
|
address[] memory reserves = pool.getReservesList();
|
2020-11-06 12:51:08 +00:00
|
|
|
address[] memory reservesWithEth = new address[](reserves.length + 1);
|
|
|
|
for (uint256 i = 0; i < reserves.length; i++) {
|
|
|
|
reservesWithEth[i] = reserves[i];
|
|
|
|
}
|
|
|
|
reservesWithEth[reserves.length] = MOCK_ETH_ADDRESS;
|
2020-06-20 23:40:03 +00:00
|
|
|
|
2020-11-06 12:51:08 +00:00
|
|
|
uint256[] memory balances = new uint256[](reservesWithEth.length);
|
2020-06-20 23:40:03 +00:00
|
|
|
|
2020-11-06 15:23:18 +00:00
|
|
|
for (uint256 j = 0; j < reserves.length; j++) {
|
2020-11-24 15:17:27 +00:00
|
|
|
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
2020-10-12 12:25:03 +00:00
|
|
|
|
|
|
|
(bool isActive, , , ) = configuration.getFlagsMemory();
|
2020-06-20 23:40:03 +00:00
|
|
|
|
|
|
|
if (!isActive) {
|
|
|
|
balances[j] = 0;
|
|
|
|
continue;
|
|
|
|
}
|
2020-11-06 15:01:19 +00:00
|
|
|
balances[j] = balanceOf(user, reservesWithEth[j]);
|
2020-05-29 16:45:37 +00:00
|
|
|
}
|
2020-11-10 08:33:53 +00:00
|
|
|
balances[reserves.length] = balanceOf(user, MOCK_ETH_ADDRESS);
|
2020-06-20 23:40:03 +00:00
|
|
|
|
2020-11-06 15:01:19 +00:00
|
|
|
return (reservesWithEth, balances);
|
2020-06-20 23:40:03 +00:00
|
|
|
}
|
|
|
|
}
|