mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Initial commit
This commit is contained in:
parent
9ac6bfa90b
commit
1d02b7f5e3
|
@ -8,7 +8,7 @@ import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||||
|
|
||||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||||
import '../interfaces/IExchangeAdapter.sol';
|
import '../interfaces/IExchangeAdapter.sol';
|
||||||
import '../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||||
|
|
||||||
/// @title TokenDistributor
|
/// @title TokenDistributor
|
||||||
|
@ -24,7 +24,7 @@ import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||||
contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using PercentageMath for uint256;
|
using PercentageMath for uint256;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
struct Distribution {
|
struct Distribution {
|
||||||
address[] receivers;
|
address[] receivers;
|
||||||
|
@ -102,7 +102,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
||||||
/// @param _tokens list of ERC20 tokens to distribute
|
/// @param _tokens list of ERC20 tokens to distribute
|
||||||
function distribute(IERC20[] memory _tokens) public {
|
function distribute(IERC20[] memory _tokens) public {
|
||||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||||
uint256 _balanceToDistribute = _tokens[i].universalBalanceOf(address(this));
|
uint256 _balanceToDistribute = _tokens[i].balanceOf(address(this));
|
||||||
|
|
||||||
if (_balanceToDistribute <= 0) {
|
if (_balanceToDistribute <= 0) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -128,7 +128,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
||||||
public
|
public
|
||||||
{
|
{
|
||||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||||
uint256 _amountToDistribute = _tokens[i].universalBalanceOf(address(this)).percentMul(
|
uint256 _amountToDistribute = _tokens[i].balanceOf(address(this)).percentMul(
|
||||||
_percentages[i]
|
_percentages[i]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_distribution.receivers[j] != address(0)) {
|
if (_distribution.receivers[j] != address(0)) {
|
||||||
_token.universalTransfer(_distribution.receivers[j], _amount);
|
_token.safeTransfer(_distribution.receivers[j], _amount);
|
||||||
emit Distributed(_distribution.receivers[j], _distribution.percentages[j], _amount);
|
emit Distributed(_distribution.receivers[j], _distribution.percentages[j], _amount);
|
||||||
} else {
|
} else {
|
||||||
uint256 _amountToBurn = _amount;
|
uint256 _amountToBurn = _amount;
|
||||||
|
|
|
@ -5,11 +5,11 @@ import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
import '../interfaces/IFlashLoanReceiver.sol';
|
import '../interfaces/IFlashLoanReceiver.sol';
|
||||||
import '../../interfaces/ILendingPoolAddressesProvider.sol';
|
import '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||||
import '../../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import '@nomiclabs/buidler/console.sol';
|
import '@nomiclabs/buidler/console.sol';
|
||||||
|
|
||||||
abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
|
abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
|
|
||||||
ILendingPoolAddressesProvider public addressesProvider;
|
ILendingPoolAddressesProvider public addressesProvider;
|
||||||
|
@ -33,14 +33,7 @@ abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
|
||||||
address _reserve,
|
address _reserve,
|
||||||
uint256 _amount
|
uint256 _amount
|
||||||
) internal {
|
) internal {
|
||||||
IERC20(_reserve).universalTransfer(_destination, _amount);
|
IERC20(_reserve).safeTransfer(_destination, _amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBalanceInternal(address _target, address _reserve) internal view returns (uint256) {
|
|
||||||
if (IERC20(_reserve).isETH()) {
|
|
||||||
return _target.balance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return IERC20(_reserve).balanceOf(_target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import '../libraries/GenericLogic.sol';
|
||||||
import '../libraries/ValidationLogic.sol';
|
import '../libraries/ValidationLogic.sol';
|
||||||
import '../libraries/ReserveConfiguration.sol';
|
import '../libraries/ReserveConfiguration.sol';
|
||||||
import '../libraries/UserConfiguration.sol';
|
import '../libraries/UserConfiguration.sol';
|
||||||
import '../libraries/UniversalERC20.sol';
|
|
||||||
import '../tokenization/interfaces/IStableDebtToken.sol';
|
import '../tokenization/interfaces/IStableDebtToken.sol';
|
||||||
import '../tokenization/interfaces/IVariableDebtToken.sol';
|
import '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||||
|
|
||||||
|
@ -25,6 +24,7 @@ import '../interfaces/IFeeProvider.sol';
|
||||||
import '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
import '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||||
import './LendingPoolLiquidationManager.sol';
|
import './LendingPoolLiquidationManager.sol';
|
||||||
import '../interfaces/IPriceOracleGetter.sol';
|
import '../interfaces/IPriceOracleGetter.sol';
|
||||||
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import '@nomiclabs/buidler/console.sol';
|
import '@nomiclabs/buidler/console.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +49,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
|
|
||||||
LendingPoolAddressesProvider public addressesProvider;
|
LendingPoolAddressesProvider public addressesProvider;
|
||||||
IFeeProvider feeProvider;
|
IFeeProvider feeProvider;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
mapping(address => ReserveLogic.ReserveData) internal reserves;
|
mapping(address => ReserveLogic.ReserveData) internal reserves;
|
||||||
mapping(address => UserConfiguration.Map) internal usersConfig;
|
mapping(address => UserConfiguration.Map) internal usersConfig;
|
||||||
|
@ -280,7 +280,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
aToken.mintOnDeposit(msg.sender, _amount);
|
aToken.mintOnDeposit(msg.sender, _amount);
|
||||||
|
|
||||||
//transfer to the aToken contract
|
//transfer to the aToken contract
|
||||||
IERC20(_reserve).universalTransferFrom(msg.sender, address(aToken), _amount, true);
|
IERC20(_reserve).safeTransferFrom(msg.sender, address(aToken), _amount);
|
||||||
|
|
||||||
//solium-disable-next-line
|
//solium-disable-next-line
|
||||||
emit Deposit(_reserve, msg.sender, _amount, _referralCode, block.timestamp);
|
emit Deposit(_reserve, msg.sender, _amount, _referralCode, block.timestamp);
|
||||||
|
@ -457,22 +457,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
|
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
IERC20(_reserve).universalTransferFrom(
|
IERC20(_reserve).safeTransferFrom(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
reserve.aTokenAddress,
|
reserve.aTokenAddress,
|
||||||
vars.paybackAmount,
|
vars.paybackAmount
|
||||||
false
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (IERC20(_reserve).isETH()) {
|
|
||||||
//send excess ETH back to the caller if needed
|
|
||||||
uint256 exceedAmount = msg.value.sub(vars.paybackAmount);
|
|
||||||
|
|
||||||
if (exceedAmount > 0) {
|
|
||||||
IERC20(_reserve).universalTransfer(msg.sender, exceedAmount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
emit Repay(
|
emit Repay(
|
||||||
_reserve,
|
_reserve,
|
||||||
_onBehalfOf,
|
_onBehalfOf,
|
||||||
|
@ -673,7 +663,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
vars.aTokenAddress = payable(reserve.aTokenAddress);
|
vars.aTokenAddress = payable(reserve.aTokenAddress);
|
||||||
|
|
||||||
//check that the reserve has enough available liquidity
|
//check that the reserve has enough available liquidity
|
||||||
vars.availableLiquidityBefore = IERC20(_reserve).universalBalanceOf(vars.aTokenAddress);
|
vars.availableLiquidityBefore = IERC20(_reserve).balanceOf(vars.aTokenAddress);
|
||||||
|
|
||||||
//calculate amount fee
|
//calculate amount fee
|
||||||
vars.amountFee = _amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
|
vars.amountFee = _amount.mul(FLASHLOAN_FEE_TOTAL).div(10000);
|
||||||
|
@ -702,7 +692,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
receiver.executeOperation(_reserve, vars.aTokenAddress, _amount, vars.amountFee, _params);
|
receiver.executeOperation(_reserve, vars.aTokenAddress, _amount, vars.amountFee, _params);
|
||||||
|
|
||||||
//check that the actual balance of the core contract includes the returned amount
|
//check that the actual balance of the core contract includes the returned amount
|
||||||
uint256 availableLiquidityAfter = IERC20(_reserve).universalBalanceOf(vars.aTokenAddress);
|
uint256 availableLiquidityAfter = IERC20(_reserve).balanceOf(vars.aTokenAddress);
|
||||||
|
|
||||||
require(
|
require(
|
||||||
availableLiquidityAfter == vars.availableLiquidityBefore.add(vars.amountFee),
|
availableLiquidityAfter == vars.availableLiquidityBefore.add(vars.amountFee),
|
||||||
|
@ -798,7 +788,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
||||||
{
|
{
|
||||||
ReserveLogic.ReserveData memory reserve = reserves[_reserve];
|
ReserveLogic.ReserveData memory reserve = reserves[_reserve];
|
||||||
return (
|
return (
|
||||||
IERC20(_reserve).universalBalanceOf(reserve.aTokenAddress),
|
IERC20(_reserve).balanceOf(reserve.aTokenAddress),
|
||||||
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
|
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
|
||||||
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
||||||
reserve.currentLiquidityRate,
|
reserve.currentLiquidityRate,
|
||||||
|
|
|
@ -18,10 +18,10 @@ import '../interfaces/IPriceOracleGetter.sol';
|
||||||
import '../libraries/GenericLogic.sol';
|
import '../libraries/GenericLogic.sol';
|
||||||
import '../libraries/Helpers.sol';
|
import '../libraries/Helpers.sol';
|
||||||
import '../libraries/ReserveLogic.sol';
|
import '../libraries/ReserveLogic.sol';
|
||||||
import '../libraries/UniversalERC20.sol';
|
|
||||||
import '../libraries/ReserveConfiguration.sol';
|
import '../libraries/ReserveConfiguration.sol';
|
||||||
import '../libraries/UserConfiguration.sol';
|
import '../libraries/UserConfiguration.sol';
|
||||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||||
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title LendingPoolLiquidationManager contract
|
* @title LendingPoolLiquidationManager contract
|
||||||
|
@ -29,7 +29,7 @@ import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||||
* @notice Implements the liquidation function.
|
* @notice Implements the liquidation function.
|
||||||
**/
|
**/
|
||||||
contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializable {
|
contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializable {
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
using PercentageMath for uint256;
|
using PercentageMath for uint256;
|
||||||
|
@ -205,7 +205,7 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
||||||
|
|
||||||
//if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
|
//if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
|
||||||
if (!_receiveAToken) {
|
if (!_receiveAToken) {
|
||||||
uint256 currentAvailableCollateral = IERC20(_collateral).universalBalanceOf(
|
uint256 currentAvailableCollateral = IERC20(_collateral).balanceOf(
|
||||||
address(vars.collateralAtoken)
|
address(vars.collateralAtoken)
|
||||||
);
|
);
|
||||||
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
||||||
|
@ -252,11 +252,10 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
||||||
}
|
}
|
||||||
|
|
||||||
//transfers the principal currency to the aToken
|
//transfers the principal currency to the aToken
|
||||||
IERC20(_reserve).universalTransferFrom(
|
IERC20(_reserve).safeTransferFrom(
|
||||||
msg.sender,
|
msg.sender,
|
||||||
principalReserve.aTokenAddress,
|
principalReserve.aTokenAddress,
|
||||||
vars.actualAmountToLiquidate,
|
vars.actualAmountToLiquidate
|
||||||
true
|
|
||||||
);
|
);
|
||||||
|
|
||||||
emit LiquidationCall(
|
emit LiquidationCall(
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
import {MathUtils} from './MathUtils.sol';
|
import {MathUtils} from './MathUtils.sol';
|
||||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||||
import {UniversalERC20} from './UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import '@nomiclabs/buidler/console.sol';
|
||||||
library ReserveLogic {
|
library ReserveLogic {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
using Address for address;
|
using Address for address;
|
||||||
using ReserveLogic for ReserveLogic.ReserveData;
|
using ReserveLogic for ReserveLogic.ReserveData;
|
||||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||||
|
@ -253,7 +253,7 @@ library ReserveLogic {
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
IERC20(_reserveAddress).universalBalanceOf(address(this)).add(_reserve.getTotalBorrows());
|
IERC20(_reserveAddress).balanceOf(address(this)).add(_reserve.getTotalBorrows());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -272,7 +272,7 @@ library ReserveLogic {
|
||||||
uint256 currentAvgStableRate = IStableDebtToken(_reserve.stableDebtTokenAddress)
|
uint256 currentAvgStableRate = IStableDebtToken(_reserve.stableDebtTokenAddress)
|
||||||
.getAverageStableRate();
|
.getAverageStableRate();
|
||||||
|
|
||||||
uint256 balance = IERC20(_reserveAddress).universalBalanceOf(_reserve.aTokenAddress);
|
uint256 balance = IERC20(_reserveAddress).balanceOf(_reserve.aTokenAddress);
|
||||||
|
|
||||||
(
|
(
|
||||||
uint256 newLiquidityRate,
|
uint256 newLiquidityRate,
|
||||||
|
@ -348,7 +348,7 @@ library ReserveLogic {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
uint256 availableLiquidity = IERC20(_reserveAddress).balanceOf(address(this));
|
||||||
|
|
||||||
return totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
|
return totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,174 +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/SafeERC20.sol';
|
|
||||||
import '@nomiclabs/buidler/console.sol';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @title UniversalERC20 library
|
|
||||||
* @author Aave inspired by @k06a (Anton Bukov)
|
|
||||||
* original version: https://github.com/CryptoManiacsZone/1inchProtocol/blob/master/contracts/UniversalERC20.sol
|
|
||||||
* @dev Provides unified interface for ERC20 and native ETH operations
|
|
||||||
**/
|
|
||||||
library UniversalERC20 {
|
|
||||||
using SafeMath for uint256;
|
|
||||||
using SafeERC20 for IERC20;
|
|
||||||
|
|
||||||
IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000);
|
|
||||||
// @notice mock address of ETH
|
|
||||||
IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
|
|
||||||
|
|
||||||
uint256 private constant DEFAULT_TRANSFER_GAS = 50000;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Moves amount of asset from caller to recipient
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @param to asset recipient
|
|
||||||
* @param amount to move
|
|
||||||
**/
|
|
||||||
function universalTransfer(
|
|
||||||
IERC20 token,
|
|
||||||
address to,
|
|
||||||
uint256 amount
|
|
||||||
) internal {
|
|
||||||
if (amount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isETH(token)) {
|
|
||||||
(bool result, ) = payable(to).call{value: amount, gas: DEFAULT_TRANSFER_GAS}('');
|
|
||||||
require(result, 'ETH_TRANSFER_FAILED');
|
|
||||||
} else {
|
|
||||||
token.safeTransfer(to, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Moves amount of asset from sender to recipient
|
|
||||||
* in terms of ETH it redirects amount in transaction to recipient
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @param from asset sender
|
|
||||||
* @param to asset recipient
|
|
||||||
* @param amount to move
|
|
||||||
* @param returnExcess if true returns exceeded amount to sender
|
|
||||||
**/
|
|
||||||
function universalTransferFrom(
|
|
||||||
IERC20 token,
|
|
||||||
address from,
|
|
||||||
address to,
|
|
||||||
uint256 amount,
|
|
||||||
bool returnExcess
|
|
||||||
) internal {
|
|
||||||
if (amount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isETH(token)) {
|
|
||||||
require(msg.value >= amount, 'Wrong usage of ETH.universalTransferFrom()'); // TODO: think one more time from == msg.sender
|
|
||||||
if (to != address(this)) {
|
|
||||||
(bool result, ) = payable(to).call{value: amount, gas: DEFAULT_TRANSFER_GAS}('');
|
|
||||||
require(result, 'ETH_TRANSFER_FAILED');
|
|
||||||
}
|
|
||||||
if (returnExcess && msg.value > amount) {
|
|
||||||
(bool result, ) = address(uint160(from)).call.value(msg.value.sub(amount)).gas(
|
|
||||||
DEFAULT_TRANSFER_GAS
|
|
||||||
)('');
|
|
||||||
require(result, 'ETH_TRANSFER_FAILED');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
token.safeTransferFrom(from, to, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Moves amount of asset from caller to this contract
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @param amount to move
|
|
||||||
**/
|
|
||||||
function universalTransferFromSenderToThis(
|
|
||||||
IERC20 token,
|
|
||||||
uint256 amount,
|
|
||||||
bool returnExcess
|
|
||||||
) internal {
|
|
||||||
if (amount == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isETH(token)) {
|
|
||||||
require(msg.value >= amount, 'The amount and the value sent to deposit do not match');
|
|
||||||
if (returnExcess) {
|
|
||||||
// Return remainder if exist
|
|
||||||
(bool result, ) = msg.sender.call{value: msg.value.sub(amount), gas: DEFAULT_TRANSFER_GAS}(
|
|
||||||
''
|
|
||||||
);
|
|
||||||
require(result, 'ETH_TRANSFER_FAILED');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
token.safeTransferFrom(msg.sender, address(this), amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Sets the allowance over the caller's tokens to recipient address.
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @param to allowance recipient
|
|
||||||
* @param amount of the allowance
|
|
||||||
**/
|
|
||||||
function universalApprove(
|
|
||||||
IERC20 token,
|
|
||||||
address to,
|
|
||||||
uint256 amount
|
|
||||||
) internal {
|
|
||||||
if (!isETH(token)) {
|
|
||||||
if (amount > 0 && token.allowance(address(this), to) > 0) {
|
|
||||||
token.safeApprove(to, 0);
|
|
||||||
}
|
|
||||||
token.safeApprove(to, amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Returns the amount of underlying asset owned by address
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @param who address to check
|
|
||||||
* @return balance of the who address
|
|
||||||
**/
|
|
||||||
function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) {
|
|
||||||
if (isETH(token)) {
|
|
||||||
return who.balance;
|
|
||||||
} else {
|
|
||||||
return token.balanceOf(who);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Returns decimals of underlying asset
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @return decimals
|
|
||||||
**/
|
|
||||||
function universalDecimals(IERC20 token) internal view returns (uint256) {
|
|
||||||
if (isETH(token)) {
|
|
||||||
return 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
(bool success, bytes memory data) = address(token).staticcall.gas(10000)(
|
|
||||||
abi.encodeWithSignature('decimals()')
|
|
||||||
);
|
|
||||||
if (!success || data.length == 0) {
|
|
||||||
(success, data) = address(token).staticcall.gas(10000)(abi.encodeWithSignature('DECIMALS()'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (success && data.length > 0) ? abi.decode(data, (uint256)) : 18;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dev Checks is underlying asset ETH or not
|
|
||||||
* @param token underlying asset address
|
|
||||||
* @return boolean
|
|
||||||
**/
|
|
||||||
function isETH(IERC20 token) internal pure returns (bool) {
|
|
||||||
return (address(token) == address(ETH_ADDRESS));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@ import {ReserveLogic} from './ReserveLogic.sol';
|
||||||
import {GenericLogic} from './GenericLogic.sol';
|
import {GenericLogic} from './GenericLogic.sol';
|
||||||
import {WadRayMath} from './WadRayMath.sol';
|
import {WadRayMath} from './WadRayMath.sol';
|
||||||
import {PercentageMath} from './PercentageMath.sol';
|
import {PercentageMath} from './PercentageMath.sol';
|
||||||
import {UniversalERC20} from './UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||||
import {UserConfiguration} from './UserConfiguration.sol';
|
import {UserConfiguration} from './UserConfiguration.sol';
|
||||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||||
|
@ -26,7 +26,7 @@ library ValidationLogic {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
using PercentageMath for uint256;
|
using PercentageMath for uint256;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||||
using UserConfiguration for UserConfiguration.Map;
|
using UserConfiguration for UserConfiguration.Map;
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ library ValidationLogic {
|
||||||
|
|
||||||
require(msg.sender == _reserve.aTokenAddress, '31');
|
require(msg.sender == _reserve.aTokenAddress, '31');
|
||||||
|
|
||||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).universalBalanceOf(
|
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(
|
||||||
address(_reserve.aTokenAddress)
|
address(_reserve.aTokenAddress)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ library ValidationLogic {
|
||||||
);
|
);
|
||||||
|
|
||||||
//check that the amount is available in the reserve
|
//check that the amount is available in the reserve
|
||||||
vars.availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(
|
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(
|
||||||
address(_reserve.aTokenAddress)
|
address(_reserve.aTokenAddress)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -238,11 +238,6 @@ library ValidationLogic {
|
||||||
_amountSent != uint256(-1) || msg.sender == _onBehalfOf,
|
_amountSent != uint256(-1) || msg.sender == _onBehalfOf,
|
||||||
'To repay on behalf of an user an explicit amount to repay is needed'
|
'To repay on behalf of an user an explicit amount to repay is needed'
|
||||||
);
|
);
|
||||||
|
|
||||||
require(
|
|
||||||
!IERC20(_reserveAddress).isETH() || _msgValue >= _actualPaybackAmount,
|
|
||||||
'Invalid msg.value sent for the repayment'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,7 +6,7 @@ import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
|
|
||||||
import '../interfaces/IPriceOracleGetter.sol';
|
import '../interfaces/IPriceOracleGetter.sol';
|
||||||
import '../interfaces/IChainlinkAggregator.sol';
|
import '../interfaces/IChainlinkAggregator.sol';
|
||||||
import '../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
|
|
||||||
/// @title ChainlinkProxyPriceProvider
|
/// @title ChainlinkProxyPriceProvider
|
||||||
/// @author Aave
|
/// @author Aave
|
||||||
|
@ -16,7 +16,7 @@ import '../libraries/UniversalERC20.sol';
|
||||||
/// - Owned by the Aave governance system, allowed to add sources for assets, replace them
|
/// - Owned by the Aave governance system, allowed to add sources for assets, replace them
|
||||||
/// and change the fallbackOracle
|
/// and change the fallbackOracle
|
||||||
contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
event AssetSourceUpdated(address indexed asset, address indexed source);
|
event AssetSourceUpdated(address indexed asset, address indexed source);
|
||||||
event FallbackOracleUpdated(address indexed fallbackOracle);
|
event FallbackOracleUpdated(address indexed fallbackOracle);
|
||||||
|
@ -77,9 +77,6 @@ contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
||||||
/// @param _asset The asset address
|
/// @param _asset The asset address
|
||||||
function getAssetPrice(address _asset) public override view returns (uint256) {
|
function getAssetPrice(address _asset) public override view returns (uint256) {
|
||||||
IChainlinkAggregator source = assetsSources[_asset];
|
IChainlinkAggregator source = assetsSources[_asset];
|
||||||
if (IERC20(_asset).isETH()) {
|
|
||||||
return 1 ether;
|
|
||||||
} else {
|
|
||||||
// If there is no registered source for the asset, call the fallbackOracle
|
// If there is no registered source for the asset, call the fallbackOracle
|
||||||
if (address(source) == address(0)) {
|
if (address(source) == address(0)) {
|
||||||
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
||||||
|
@ -91,7 +88,6 @@ contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
||||||
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @notice Gets a list of prices from a list of assets addresses
|
/// @notice Gets a list of prices from a list of assets addresses
|
||||||
|
|
|
@ -6,7 +6,7 @@ import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
|
|
||||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||||
import '../lendingpool/LendingPool.sol';
|
import '../lendingpool/LendingPool.sol';
|
||||||
import '../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @title WalletBalanceProvider contract
|
* @title WalletBalanceProvider contract
|
||||||
|
@ -18,7 +18,7 @@ import '../libraries/UniversalERC20.sol';
|
||||||
contract WalletBalanceProvider {
|
contract WalletBalanceProvider {
|
||||||
using Address for address payable;
|
using Address for address payable;
|
||||||
using Address for address;
|
using Address for address;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
LendingPoolAddressesProvider provider;
|
LendingPoolAddressesProvider provider;
|
||||||
|
|
||||||
|
@ -65,14 +65,10 @@ contract WalletBalanceProvider {
|
||||||
for (uint256 i = 0; i < _users.length; i++) {
|
for (uint256 i = 0; i < _users.length; i++) {
|
||||||
for (uint256 j = 0; j < _tokens.length; j++) {
|
for (uint256 j = 0; j < _tokens.length; j++) {
|
||||||
uint256 _offset = i * _tokens.length;
|
uint256 _offset = i * _tokens.length;
|
||||||
if (IERC20(_tokens[j]).isETH()) {
|
if (!_tokens[j].isContract()) {
|
||||||
balances[_offset + j] = _users[i].balance; // ETH balance
|
revert('INVALID_TOKEN');
|
||||||
} else {
|
} else {
|
||||||
if (!_tokens[j].isContract()) {
|
balances[_offset + j] = balanceOf(_users[i], _tokens[j]);
|
||||||
revert('INVALID_TOKEN');
|
|
||||||
} else {
|
|
||||||
balances[_offset + j] = balanceOf(_users[i], _tokens[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,11 +97,7 @@ contract WalletBalanceProvider {
|
||||||
balances[j] = 0;
|
balances[j] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (IERC20(reserves[j]).isETH()) {
|
|
||||||
balances[j] = balanceOf(_user, reserves[j]);
|
balances[j] = balanceOf(_user, reserves[j]);
|
||||||
} else {
|
|
||||||
balances[j] = _user.balance; // ETH balance
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (reserves, balances);
|
return (reserves, balances);
|
||||||
|
|
|
@ -6,11 +6,11 @@ import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||||
|
|
||||||
import '../../flashloan/base/FlashLoanReceiverBase.sol';
|
import '../../flashloan/base/FlashLoanReceiverBase.sol';
|
||||||
import '../tokens/MintableERC20.sol';
|
import '../tokens/MintableERC20.sol';
|
||||||
import '../../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
|
|
||||||
contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
||||||
using SafeMath for uint256;
|
using SafeMath for uint256;
|
||||||
using UniversalERC20 for IERC20;
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
|
event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
|
||||||
event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
|
event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
|
||||||
|
@ -35,7 +35,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
||||||
|
|
||||||
//check the contract has the specified balance
|
//check the contract has the specified balance
|
||||||
require(
|
require(
|
||||||
_amount <= getBalanceInternal(address(this), _reserve),
|
_amount <= IERC20(_reserve).balanceOf(address(this)),
|
||||||
'Invalid balance for the contract'
|
'Invalid balance for the contract'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -47,9 +47,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
||||||
//execution does not fail - mint tokens and return them to the _destination
|
//execution does not fail - mint tokens and return them to the _destination
|
||||||
//note: if the reserve is eth, the mock contract must receive at least _fee ETH before calling executeOperation
|
//note: if the reserve is eth, the mock contract must receive at least _fee ETH before calling executeOperation
|
||||||
|
|
||||||
if (!IERC20(_reserve).isETH()) {
|
token.mint(_fee);
|
||||||
token.mint(_fee);
|
|
||||||
}
|
|
||||||
|
|
||||||
//returning amount + fee to the destination
|
//returning amount + fee to the destination
|
||||||
transferFundsBackInternal(_reserve, _destination, _amount.add(_fee));
|
transferFundsBackInternal(_reserve, _destination, _amount.add(_fee));
|
||||||
|
|
|
@ -4,7 +4,7 @@ pragma solidity ^0.6.8;
|
||||||
import {ERC20} from './ERC20.sol';
|
import {ERC20} from './ERC20.sol';
|
||||||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||||
import {UniversalERC20} from '../libraries/UniversalERC20.sol';
|
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||||
import {
|
import {
|
||||||
VersionedInitializable
|
VersionedInitializable
|
||||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||||
|
@ -19,7 +19,7 @@ import '@nomiclabs/buidler/console.sol';
|
||||||
*/
|
*/
|
||||||
contract AToken is VersionedInitializable, ERC20 {
|
contract AToken is VersionedInitializable, ERC20 {
|
||||||
using WadRayMath for uint256;
|
using WadRayMath for uint256;
|
||||||
using UniversalERC20 for ERC20;
|
using SafeERC20 for ERC20;
|
||||||
|
|
||||||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||||
|
|
||||||
|
@ -702,17 +702,14 @@ contract AToken is VersionedInitializable, ERC20 {
|
||||||
onlyLendingPool
|
onlyLendingPool
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
ERC20(underlyingAssetAddress).universalTransfer(_target, _amount);
|
ERC20(underlyingAssetAddress).safeTransfer(_target, _amount);
|
||||||
return _amount;
|
return _amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev receive() function for aTokens who hold ETH as the underlying asset
|
* @dev aTokens should not receive ETH
|
||||||
**/
|
**/
|
||||||
receive() external payable {
|
receive() external payable {
|
||||||
require(
|
revert();
|
||||||
ERC20(underlyingAssetAddress).isETH(),
|
|
||||||
'Transfers are only allowed if the underlying asset is ETH'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
||||||
uint256 previousBalance,
|
uint256 previousBalance,
|
||||||
uint256 currentBalance,
|
uint256 currentBalance,
|
||||||
uint256 balanceIncrease
|
uint256 balanceIncrease
|
||||||
) = _calculateCumulatedBalance(_user);
|
) = _calculateBalanceIncrease(_user);
|
||||||
|
|
||||||
uint256 supplyBeforeBurn = totalSupply.add(balanceIncrease);
|
uint256 supplyBeforeBurn = totalSupply.add(balanceIncrease);
|
||||||
uint256 supplyAfterBurn = supplyBeforeBurn.sub(_amount);
|
uint256 supplyAfterBurn = supplyBeforeBurn.sub(_amount);
|
||||||
|
|
|
@ -99,7 +99,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
||||||
uint256 previousBalance,
|
uint256 previousBalance,
|
||||||
uint256 currentBalance,
|
uint256 currentBalance,
|
||||||
uint256 balanceIncrease
|
uint256 balanceIncrease
|
||||||
) = _calculateCumulatedBalance(_user);
|
) = _calculateBalanceIncrease(_user);
|
||||||
|
|
||||||
_mint(_user, _amount.add(balanceIncrease));
|
_mint(_user, _amount.add(balanceIncrease));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user