mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'fix/17' into 'master'
Resolve "Get rid of ETH specific code" Closes #17 See merge request aave-tech/protocol-v2!13
This commit is contained in:
commit
45d12fd43d
|
@ -8,7 +8,7 @@ import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
|||
|
||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import '../interfaces/IExchangeAdapter.sol';
|
||||
import '../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||
|
||||
/// @title TokenDistributor
|
||||
|
@ -24,7 +24,7 @@ import {PercentageMath} from '../libraries/PercentageMath.sol';
|
|||
contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
||||
using SafeMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
struct Distribution {
|
||||
address[] receivers;
|
||||
|
@ -102,7 +102,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
|||
/// @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].universalBalanceOf(address(this));
|
||||
uint256 _balanceToDistribute = _tokens[i].balanceOf(address(this));
|
||||
|
||||
if (_balanceToDistribute <= 0) {
|
||||
continue;
|
||||
|
@ -128,7 +128,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
|||
public
|
||||
{
|
||||
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]
|
||||
);
|
||||
|
||||
|
@ -170,7 +170,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
|||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
uint256 _amountToBurn = _amount;
|
||||
|
|
|
@ -5,11 +5,11 @@ import '@openzeppelin/contracts/math/SafeMath.sol';
|
|||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '../interfaces/IFlashLoanReceiver.sol';
|
||||
import '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import '../../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
using SafeMath for uint256;
|
||||
|
||||
ILendingPoolAddressesProvider public addressesProvider;
|
||||
|
@ -33,14 +33,7 @@ abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
|
|||
address _reserve,
|
||||
uint256 _amount
|
||||
) 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/ReserveConfiguration.sol';
|
||||
import '../libraries/UserConfiguration.sol';
|
||||
import '../libraries/UniversalERC20.sol';
|
||||
import '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
|
||||
|
@ -25,6 +24,7 @@ import '../interfaces/IFeeProvider.sol';
|
|||
import '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||
import './LendingPoolLiquidationManager.sol';
|
||||
import '../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
|
||||
LendingPoolAddressesProvider public addressesProvider;
|
||||
IFeeProvider feeProvider;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
mapping(address => ReserveLogic.ReserveData) internal reserves;
|
||||
mapping(address => UserConfiguration.Map) internal usersConfig;
|
||||
|
@ -280,7 +280,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
aToken.mintOnDeposit(msg.sender, _amount);
|
||||
|
||||
//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
|
||||
emit Deposit(_reserve, msg.sender, _amount, _referralCode, block.timestamp);
|
||||
|
@ -457,22 +457,12 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
usersConfig[_onBehalfOf].setBorrowing(reserve.index, false);
|
||||
}
|
||||
|
||||
IERC20(_reserve).universalTransferFrom(
|
||||
IERC20(_reserve).safeTransferFrom(
|
||||
msg.sender,
|
||||
reserve.aTokenAddress,
|
||||
vars.paybackAmount,
|
||||
false
|
||||
vars.paybackAmount
|
||||
);
|
||||
|
||||
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(
|
||||
_reserve,
|
||||
_onBehalfOf,
|
||||
|
@ -673,7 +663,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
vars.aTokenAddress = payable(reserve.aTokenAddress);
|
||||
|
||||
//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
|
||||
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);
|
||||
|
||||
//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(
|
||||
availableLiquidityAfter == vars.availableLiquidityBefore.add(vars.amountFee),
|
||||
|
@ -798,7 +788,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
{
|
||||
ReserveLogic.ReserveData memory reserve = reserves[_reserve];
|
||||
return (
|
||||
IERC20(_reserve).universalBalanceOf(reserve.aTokenAddress),
|
||||
IERC20(_reserve).balanceOf(reserve.aTokenAddress),
|
||||
IERC20(reserve.stableDebtTokenAddress).totalSupply(),
|
||||
IERC20(reserve.variableDebtTokenAddress).totalSupply(),
|
||||
reserve.currentLiquidityRate,
|
||||
|
|
|
@ -18,10 +18,10 @@ import '../interfaces/IPriceOracleGetter.sol';
|
|||
import '../libraries/GenericLogic.sol';
|
||||
import '../libraries/Helpers.sol';
|
||||
import '../libraries/ReserveLogic.sol';
|
||||
import '../libraries/UniversalERC20.sol';
|
||||
import '../libraries/ReserveConfiguration.sol';
|
||||
import '../libraries/UserConfiguration.sol';
|
||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolLiquidationManager contract
|
||||
|
@ -29,7 +29,7 @@ import {PercentageMath} from '../libraries/PercentageMath.sol';
|
|||
* @notice Implements the liquidation function.
|
||||
**/
|
||||
contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializable {
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath 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 (!_receiveAToken) {
|
||||
uint256 currentAvailableCollateral = IERC20(_collateral).universalBalanceOf(
|
||||
uint256 currentAvailableCollateral = IERC20(_collateral).balanceOf(
|
||||
address(vars.collateralAtoken)
|
||||
);
|
||||
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
||||
|
@ -252,11 +252,10 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
|||
}
|
||||
|
||||
//transfers the principal currency to the aToken
|
||||
IERC20(_reserve).universalTransferFrom(
|
||||
IERC20(_reserve).safeTransferFrom(
|
||||
msg.sender,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate,
|
||||
true
|
||||
vars.actualAmountToLiquidate
|
||||
);
|
||||
|
||||
emit LiquidationCall(
|
||||
|
|
|
@ -5,7 +5,7 @@ import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
|||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {MathUtils} from './MathUtils.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 {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||
|
||||
|
@ -24,7 +24,7 @@ import '@nomiclabs/buidler/console.sol';
|
|||
library ReserveLogic {
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
using Address for address;
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
|
@ -253,7 +253,7 @@ library ReserveLogic {
|
|||
returns (uint256)
|
||||
{
|
||||
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)
|
||||
.getAverageStableRate();
|
||||
|
||||
uint256 balance = IERC20(_reserveAddress).universalBalanceOf(_reserve.aTokenAddress);
|
||||
uint256 balance = IERC20(_reserveAddress).balanceOf(_reserve.aTokenAddress);
|
||||
|
||||
(
|
||||
uint256 newLiquidityRate,
|
||||
|
@ -348,7 +348,7 @@ library ReserveLogic {
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint256 availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(address(this));
|
||||
uint256 availableLiquidity = IERC20(_reserveAddress).balanceOf(address(this));
|
||||
|
||||
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 {WadRayMath} from './WadRayMath.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 {UserConfiguration} from './UserConfiguration.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
|
@ -26,7 +26,7 @@ library ValidationLogic {
|
|||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
|
||||
|
@ -59,7 +59,7 @@ library ValidationLogic {
|
|||
|
||||
require(msg.sender == _reserve.aTokenAddress, '31');
|
||||
|
||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).universalBalanceOf(
|
||||
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(
|
||||
address(_reserve.aTokenAddress)
|
||||
);
|
||||
|
||||
|
@ -135,7 +135,7 @@ library ValidationLogic {
|
|||
);
|
||||
|
||||
//check that the amount is available in the reserve
|
||||
vars.availableLiquidity = IERC20(_reserveAddress).universalBalanceOf(
|
||||
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(
|
||||
address(_reserve.aTokenAddress)
|
||||
);
|
||||
|
||||
|
@ -238,11 +238,6 @@ library ValidationLogic {
|
|||
_amountSent != uint256(-1) || msg.sender == _onBehalfOf,
|
||||
'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/IChainlinkAggregator.sol';
|
||||
import '../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
|
||||
/// @title ChainlinkProxyPriceProvider
|
||||
/// @author Aave
|
||||
|
@ -16,7 +16,7 @@ import '../libraries/UniversalERC20.sol';
|
|||
/// - Owned by the Aave governance system, allowed to add sources for assets, replace them
|
||||
/// and change the fallbackOracle
|
||||
contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
event AssetSourceUpdated(address indexed asset, address indexed source);
|
||||
event FallbackOracleUpdated(address indexed fallbackOracle);
|
||||
|
@ -77,9 +77,6 @@ contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
|||
/// @param _asset The asset address
|
||||
function getAssetPrice(address _asset) public override view returns (uint256) {
|
||||
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 (address(source) == address(0)) {
|
||||
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
||||
|
@ -91,7 +88,6 @@ contract ChainlinkProxyPriceProvider is IPriceOracleGetter, Ownable {
|
|||
return IPriceOracleGetter(fallbackOracle).getAssetPrice(_asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @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 '../lendingpool/LendingPool.sol';
|
||||
import '../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
|
||||
/**
|
||||
* @title WalletBalanceProvider contract
|
||||
|
@ -18,7 +18,7 @@ import '../libraries/UniversalERC20.sol';
|
|||
contract WalletBalanceProvider {
|
||||
using Address for address payable;
|
||||
using Address for address;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
LendingPoolAddressesProvider provider;
|
||||
|
||||
|
@ -65,14 +65,10 @@ contract WalletBalanceProvider {
|
|||
for (uint256 i = 0; i < _users.length; i++) {
|
||||
for (uint256 j = 0; j < _tokens.length; j++) {
|
||||
uint256 _offset = i * _tokens.length;
|
||||
if (IERC20(_tokens[j]).isETH()) {
|
||||
balances[_offset + j] = _users[i].balance; // ETH balance
|
||||
if (!_tokens[j].isContract()) {
|
||||
revert('INVALID_TOKEN');
|
||||
} else {
|
||||
if (!_tokens[j].isContract()) {
|
||||
revert('INVALID_TOKEN');
|
||||
} else {
|
||||
balances[_offset + j] = balanceOf(_users[i], _tokens[j]);
|
||||
}
|
||||
balances[_offset + j] = balanceOf(_users[i], _tokens[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,11 +97,7 @@ contract WalletBalanceProvider {
|
|||
balances[j] = 0;
|
||||
continue;
|
||||
}
|
||||
if (IERC20(reserves[j]).isETH()) {
|
||||
balances[j] = balanceOf(_user, reserves[j]);
|
||||
} else {
|
||||
balances[j] = _user.balance; // ETH balance
|
||||
}
|
||||
}
|
||||
|
||||
return (reserves, balances);
|
||||
|
|
|
@ -6,11 +6,11 @@ import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
|||
|
||||
import '../../flashloan/base/FlashLoanReceiverBase.sol';
|
||||
import '../tokens/MintableERC20.sol';
|
||||
import '../../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
|
||||
contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
||||
using SafeMath for uint256;
|
||||
using UniversalERC20 for IERC20;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
event ExecutedWithFail(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
|
||||
require(
|
||||
_amount <= getBalanceInternal(address(this), _reserve),
|
||||
_amount <= IERC20(_reserve).balanceOf(address(this)),
|
||||
'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
|
||||
//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
|
||||
transferFundsBackInternal(_reserve, _destination, _amount.add(_fee));
|
||||
|
|
|
@ -4,7 +4,7 @@ pragma solidity ^0.6.8;
|
|||
import {ERC20} from './ERC20.sol';
|
||||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import {UniversalERC20} from '../libraries/UniversalERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
|
@ -19,7 +19,7 @@ import '@nomiclabs/buidler/console.sol';
|
|||
*/
|
||||
contract AToken is VersionedInitializable, ERC20 {
|
||||
using WadRayMath for uint256;
|
||||
using UniversalERC20 for ERC20;
|
||||
using SafeERC20 for ERC20;
|
||||
|
||||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||
|
||||
|
@ -702,17 +702,14 @@ contract AToken is VersionedInitializable, ERC20 {
|
|||
onlyLendingPool
|
||||
returns (uint256)
|
||||
{
|
||||
ERC20(underlyingAssetAddress).universalTransfer(_target, _amount);
|
||||
ERC20(underlyingAssetAddress).safeTransfer(_target, _amount);
|
||||
return _amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev receive() function for aTokens who hold ETH as the underlying asset
|
||||
* @dev aTokens should not receive ETH
|
||||
**/
|
||||
receive() external payable {
|
||||
require(
|
||||
ERC20(underlyingAssetAddress).isETH(),
|
||||
'Transfers are only allowed if the underlying asset is ETH'
|
||||
);
|
||||
revert();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"MintableERC20": {
|
||||
"buidlerevm": {
|
||||
"address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
|
||||
"address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"LendingPoolAddressesProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
|
||||
"address": "0xa4bcDF64Cdd5451b6ac3743B414124A6299B65FF",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -21,7 +21,7 @@
|
|||
},
|
||||
"LendingPoolAddressesProviderRegistry": {
|
||||
"buidlerevm": {
|
||||
"address": "0x22474D350EC2dA53D717E30b96e9a2B7628Ede5b",
|
||||
"address": "0x5A0773Ff307Bf7C71a832dBB5312237fD3437f9F",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -31,7 +31,7 @@
|
|||
},
|
||||
"FeeProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x852e3718A320aD93Ad8692E8D663d247e4c1b400"
|
||||
"address": "0xD9273d497eDBC967F39d419461CfcF382a0A822e"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x0f2cE53B3410a2007d6C4ad8940Ffa5AdCC2916C"
|
||||
|
@ -49,7 +49,7 @@
|
|||
},
|
||||
"LendingPoolConfigurator": {
|
||||
"buidlerevm": {
|
||||
"address": "0xA10958a24032283FbE2D23cedf264d6eC9411CBA"
|
||||
"address": "0x9EC0480CF106d6dc1c7849BA141a56F874170F97"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x0ca5E5B6F09C97f30Ed6e5E99be65A38eE7edfaB"
|
||||
|
@ -62,7 +62,7 @@
|
|||
},
|
||||
"LendingPool": {
|
||||
"buidlerevm": {
|
||||
"address": "0x2C4603396dE2F08642354A3A102760827FfFe113"
|
||||
"address": "0x6642B57e4265BAD868C17Fc1d1F4F88DBBA04Aa8"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x7FE8419fACf45dFa93d471644e87122923EC9D94"
|
||||
|
@ -70,7 +70,7 @@
|
|||
},
|
||||
"PriceOracle": {
|
||||
"buidlerevm": {
|
||||
"address": "0xE4C10Db67595aF2Cb4166c8C274e0140f7E43059",
|
||||
"address": "0x099d9fF8F818290C8b5B7Db5bFca84CEebd2714c",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -80,7 +80,7 @@
|
|||
},
|
||||
"MockAggregator": {
|
||||
"buidlerevm": {
|
||||
"address": "0xEC1C93A9f6a9e18E97784c76aC52053587FcDB89",
|
||||
"address": "0xAF6BA11790D1942625C0c2dA07da19AB63845cfF",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -90,7 +90,7 @@
|
|||
},
|
||||
"ChainlinkProxyPriceProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x7B6C3e5486D9e6959441ab554A889099eed76290",
|
||||
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -100,7 +100,7 @@
|
|||
},
|
||||
"LendingRateOracle": {
|
||||
"buidlerevm": {
|
||||
"address": "0xD83D2773a7873ae2b5f8Fb92097e20a8C64F691E",
|
||||
"address": "0xf91aC1098F3b154671Ce83290114aaE45ac0225f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -110,7 +110,7 @@
|
|||
},
|
||||
"DefaultReserveInterestRateStrategy": {
|
||||
"buidlerevm": {
|
||||
"address": "0x09d728F76D543DB1925f7d1Fd8823e4e82700F99",
|
||||
"address": "0x09d7cb7a0606a7f10DC8a37b3e0E420F39f0FAF1",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -146,7 +146,7 @@
|
|||
},
|
||||
"TokenDistributor": {
|
||||
"buidlerevm": {
|
||||
"address": "0x03A6802eF9060a8E1f0e56Bafc9C9AB1A26a1f06"
|
||||
"address": "0x22B37db37e9992728245A7dD0536892AF9bA1baB"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x39f713653d31a8e0D7a51061F1159861290e65Fd"
|
||||
|
@ -154,7 +154,7 @@
|
|||
},
|
||||
"InitializableAdminUpgradeabilityProxy": {
|
||||
"buidlerevm": {
|
||||
"address": "0x03A6802eF9060a8E1f0e56Bafc9C9AB1A26a1f06",
|
||||
"address": "0x22B37db37e9992728245A7dD0536892AF9bA1baB",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -164,7 +164,7 @@
|
|||
},
|
||||
"MockFlashLoanReceiver": {
|
||||
"buidlerevm": {
|
||||
"address": "0x9D37fB22EA7d655f12E68DABBf6B6585A00774C3"
|
||||
"address": "0x850Fae11E1313e6C23Db7c2410Ec0985d9Ea325A"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0xC4e948241c7A63d1f21fD98D652aE4B59180e07F"
|
||||
|
@ -172,7 +172,7 @@
|
|||
},
|
||||
"WalletBalanceProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x2005823e074313cd644035557bF4FFa0ca0Bddff",
|
||||
"address": "0x22058276Dd278bD037591805E62E797012d666f6",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -222,7 +222,7 @@
|
|||
},
|
||||
"USDC": {
|
||||
"buidlerevm": {
|
||||
"address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
|
||||
"address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -232,7 +232,7 @@
|
|||
},
|
||||
"USDT": {
|
||||
"buidlerevm": {
|
||||
"address": "0x3619DbE27d7c1e7E91aA738697Ae7Bc5FC3eACA5",
|
||||
"address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -242,7 +242,7 @@
|
|||
},
|
||||
"SUSD": {
|
||||
"buidlerevm": {
|
||||
"address": "0x038B86d9d8FAFdd0a02ebd1A476432877b0107C8",
|
||||
"address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -252,7 +252,7 @@
|
|||
},
|
||||
"ZRX": {
|
||||
"buidlerevm": {
|
||||
"address": "0x1A1FEe7EeD918BD762173e4dc5EfDB8a78C924A8",
|
||||
"address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -262,7 +262,7 @@
|
|||
},
|
||||
"MKR": {
|
||||
"buidlerevm": {
|
||||
"address": "0x500D1d6A4c7D8Ae28240b47c8FCde034D827fD5e",
|
||||
"address": "0xc4905364b78a742ccce7B890A89514061E47068D",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -272,7 +272,7 @@
|
|||
},
|
||||
"WBTC": {
|
||||
"buidlerevm": {
|
||||
"address": "0xc4905364b78a742ccce7B890A89514061E47068D",
|
||||
"address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -282,7 +282,7 @@
|
|||
},
|
||||
"LINK": {
|
||||
"buidlerevm": {
|
||||
"address": "0xD6C850aeBFDC46D7F4c207e445cC0d6B0919BDBe",
|
||||
"address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -292,7 +292,7 @@
|
|||
},
|
||||
"KNC": {
|
||||
"buidlerevm": {
|
||||
"address": "0x8B5B7a6055E54a36fF574bbE40cf2eA68d5554b3",
|
||||
"address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -302,7 +302,7 @@
|
|||
},
|
||||
"MANA": {
|
||||
"buidlerevm": {
|
||||
"address": "0xEcc0a6dbC0bb4D51E4F84A315a9e5B0438cAD4f0",
|
||||
"address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -312,7 +312,7 @@
|
|||
},
|
||||
"REP": {
|
||||
"buidlerevm": {
|
||||
"address": "0x20Ce94F404343aD2752A2D01b43fa407db9E0D00",
|
||||
"address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -322,7 +322,7 @@
|
|||
},
|
||||
"SNX": {
|
||||
"buidlerevm": {
|
||||
"address": "0x1d80315fac6aBd3EfeEbE97dEc44461ba7556160",
|
||||
"address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -332,7 +332,7 @@
|
|||
},
|
||||
"BUSD": {
|
||||
"buidlerevm": {
|
||||
"address": "0x2D8553F9ddA85A9B3259F6Bf26911364B85556F5",
|
||||
"address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -342,7 +342,7 @@
|
|||
},
|
||||
"USD": {
|
||||
"buidlerevm": {
|
||||
"address": "0x52d3b94181f8654db2530b0fEe1B19173f519C52",
|
||||
"address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -352,7 +352,7 @@
|
|||
},
|
||||
"UNI_DAI_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0xd15468525c35BDBC1eD8F2e09A00F8a173437f2f",
|
||||
"address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -362,7 +362,7 @@
|
|||
},
|
||||
"UNI_USDC_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0x7e35Eaf7e8FBd7887ad538D4A38Df5BbD073814a",
|
||||
"address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -372,7 +372,7 @@
|
|||
},
|
||||
"UNI_SETH_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0x5bcb88A0d20426e451332eE6C4324b0e663c50E0",
|
||||
"address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -382,7 +382,7 @@
|
|||
},
|
||||
"UNI_LINK_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0x3521eF8AaB0323004A6dD8b03CE890F4Ea3A13f5",
|
||||
"address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -392,7 +392,7 @@
|
|||
},
|
||||
"UNI_MKR_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0x53369fd4680FfE3DfF39Fc6DDa9CfbfD43daeA2E",
|
||||
"address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -402,7 +402,7 @@
|
|||
},
|
||||
"UNI_LEND_ETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0xB00cC45B4a7d3e1FEE684cFc4417998A1c183e6d",
|
||||
"address": "0x58F132FBB86E21545A4Bace3C19f1C05d86d7A22",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -412,7 +412,7 @@
|
|||
},
|
||||
"AaveProtocolTestHelpers": {
|
||||
"buidlerevm": {
|
||||
"address": "0x850Fae11E1313e6C23Db7c2410Ec0985d9Ea325A"
|
||||
"address": "0x6D3540a9F1a769bfd91A4A33169a8361aa82dC0F"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x26af54A97F214dB563711B0670c4FbA2Eb935E37"
|
||||
|
@ -420,7 +420,7 @@
|
|||
},
|
||||
"StableDebtToken": {
|
||||
"buidlerevm": {
|
||||
"address": "0xb2B548BE73010C188C083c510d255Aed74843b05",
|
||||
"address": "0x5Ea694f66BD0CBd08FC7967af01b67Dcef68cC5c",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -430,7 +430,7 @@
|
|||
},
|
||||
"VariableDebtToken": {
|
||||
"buidlerevm": {
|
||||
"address": "0x5Ea694f66BD0CBd08FC7967af01b67Dcef68cC5c",
|
||||
"address": "0xd4e934C2749CA8C1618659D02E7B28B074bf4df7",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -444,13 +444,19 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"buidlerevm": {
|
||||
"address": "0xd4e934C2749CA8C1618659D02E7B28B074bf4df7",
|
||||
"address": "0x8280D40C9E9F04229D2435EAad6e0011309ce81B",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"MockAToken": {
|
||||
"buidlerevm": {
|
||||
"address": "0xccdf1DECe9c9631081b952Cd51A579E75c33C565",
|
||||
"address": "0x7f23223A2FAf869962B38f5eC4aAB7f37454A45e",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"WETH": {
|
||||
"buidlerevm": {
|
||||
"address": "0xf784709d2317D872237C4bC22f867d1BAe2913AB",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ export const APPROVAL_AMOUNT_LENDING_POOL = '1000000000000000000000000000';
|
|||
export const TOKEN_DISTRIBUTOR_PERCENTAGE_BASE = '10000';
|
||||
export const MOCK_USD_PRICE_IN_WEI = '5848466240000000';
|
||||
export const USD_ADDRESS = '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96';
|
||||
export const MOCK_ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
||||
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
|
||||
export const AAVE_REFERRAL = '0';
|
||||
|
@ -92,6 +91,7 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES: iAssetAggregatorBase<string> = {
|
|||
MANA: oneEther.multipliedBy('0.000158').toFixed(),
|
||||
SNX: oneEther.multipliedBy('0.00442616').toFixed(),
|
||||
BUSD: oneEther.multipliedBy('0.00736484').toFixed(),
|
||||
WETH: oneEther.toFixed(),
|
||||
USD: MOCK_USD_PRICE_IN_WEI,
|
||||
UNI_DAI_ETH: oneEther.multipliedBy('2.1').toFixed(),
|
||||
UNI_USDC_ETH: oneEther.multipliedBy('2.1').toFixed(),
|
||||
|
@ -103,11 +103,10 @@ export const MOCK_CHAINLINK_AGGREGATORS_PRICES: iAssetAggregatorBase<string> = {
|
|||
|
||||
export const ALL_ASSETS_INITIAL_PRICES: iAssetBase<string> = {
|
||||
...MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
ETH: oneEther.toFixed(),
|
||||
};
|
||||
|
||||
export const LENDING_RATE_ORACLE_RATES_COMMON: iAavePoolAssets<IMarketRates> = {
|
||||
ETH: {
|
||||
WETH: {
|
||||
borrowRate: oneRay.multipliedBy(0.03).toFixed(),
|
||||
},
|
||||
DAI: {
|
||||
|
@ -255,7 +254,7 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
|
|||
stableBorrowRateEnabled: true,
|
||||
reserveDecimals: '18',
|
||||
},
|
||||
ETH: {
|
||||
WETH: {
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
|
||||
|
@ -387,7 +386,7 @@ export const getReservesConfigByPool = (pool: AavePools): iMultiPoolsAssets<IRes
|
|||
},
|
||||
},
|
||||
[AavePools.secondary]: {
|
||||
ETH: {
|
||||
WETH: {
|
||||
baseVariableBorrowRate: new BigNumber(0).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope1: new BigNumber(0.08).multipliedBy(oneRay).toFixed(),
|
||||
variableRateSlope2: new BigNumber(0.5).multipliedBy(oneRay).toFixed(),
|
||||
|
|
|
@ -29,7 +29,6 @@ import {MockFlashLoanReceiver} from '../types/MockFlashLoanReceiver';
|
|||
import {WalletBalanceProvider} from '../types/WalletBalanceProvider';
|
||||
import {AToken} from '../types/AToken';
|
||||
import {AaveProtocolTestHelpers} from '../types/AaveProtocolTestHelpers';
|
||||
import {MOCK_ETH_ADDRESS} from './constants';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {Ierc20Detailed} from '../types/Ierc20Detailed';
|
||||
import {StableDebtToken} from '../types/StableDebtToken';
|
||||
|
@ -261,7 +260,10 @@ export const deployStableDebtToken = async ([
|
|||
underlyingAsset,
|
||||
poolAddress,
|
||||
]: [string, string, string, tEthereumAddress, tEthereumAddress]) => {
|
||||
const token = await deployContract<StableDebtToken>(eContractid.StableDebtToken, [poolAddress, underlyingAsset]);
|
||||
const token = await deployContract<StableDebtToken>(eContractid.StableDebtToken, [
|
||||
poolAddress,
|
||||
underlyingAsset,
|
||||
]);
|
||||
|
||||
await token.init(name, symbol, decimals);
|
||||
|
||||
|
@ -275,7 +277,10 @@ export const deployVariableDebtToken = async ([
|
|||
underlyingAsset,
|
||||
poolAddress,
|
||||
]: [string, string, string, tEthereumAddress, tEthereumAddress]) => {
|
||||
const token = await deployContract<VariableDebtToken>(eContractid.VariableDebtToken, [poolAddress, underlyingAsset]);
|
||||
const token = await deployContract<VariableDebtToken>(eContractid.VariableDebtToken, [
|
||||
poolAddress,
|
||||
underlyingAsset,
|
||||
]);
|
||||
|
||||
await token.init(name, symbol, decimals);
|
||||
|
||||
|
@ -466,25 +471,16 @@ export const getParamPerPool = <T>({proto, secondary}: iParamsPerPool<T>, pool:
|
|||
};
|
||||
|
||||
export const convertToCurrencyDecimals = async (tokenAddress: tEthereumAddress, amount: string) => {
|
||||
const isEth = tokenAddress === MOCK_ETH_ADDRESS;
|
||||
let decimals = '18';
|
||||
|
||||
if (!isEth) {
|
||||
const token = await getIErc20Detailed(tokenAddress);
|
||||
decimals = (await token.decimals()).toString();
|
||||
}
|
||||
const token = await getIErc20Detailed(tokenAddress);
|
||||
let decimals = (await token.decimals()).toString();
|
||||
|
||||
return ethers.utils.parseUnits(amount, decimals);
|
||||
};
|
||||
|
||||
export const convertToCurrencyUnits = async (tokenAddress: string, amount: string) => {
|
||||
const isEth = tokenAddress === MOCK_ETH_ADDRESS;
|
||||
|
||||
let decimals = new BigNumber(18);
|
||||
if (!isEth) {
|
||||
const token = await getIErc20Detailed(tokenAddress);
|
||||
decimals = new BigNumber(await token.decimals());
|
||||
}
|
||||
const token = await getIErc20Detailed(tokenAddress);
|
||||
let decimals = new BigNumber(await token.decimals());
|
||||
const currencyUnit = new BigNumber(10).pow(decimals);
|
||||
const amountInCurrencyUnits = new BigNumber(amount).div(currencyUnit);
|
||||
return amountInCurrencyUnits.toFixed();
|
||||
|
|
|
@ -73,7 +73,7 @@ export type tStringTokenSmallUnits = string; // 1 wei, or 1 basic unit of USDC,
|
|||
export type tBigNumberTokenSmallUnits = BigNumber;
|
||||
|
||||
export interface iAssetBase<T> {
|
||||
ETH: T;
|
||||
WETH: T;
|
||||
DAI: T;
|
||||
TUSD: T;
|
||||
USDC: T;
|
||||
|
@ -107,7 +107,7 @@ export type iAssetsWithoutUSD<T> = Omit<iAssetBase<T>, 'USD'>;
|
|||
|
||||
export type iAavePoolAssets<T> = Pick<
|
||||
iAssetsWithoutUSD<T>,
|
||||
| 'ETH'
|
||||
| 'WETH'
|
||||
| 'DAI'
|
||||
| 'TUSD'
|
||||
| 'USDC'
|
||||
|
@ -124,6 +124,7 @@ export type iAavePoolAssets<T> = Pick<
|
|||
| 'ZRX'
|
||||
| 'SNX'
|
||||
| 'BUSD'
|
||||
| 'WETH'
|
||||
>;
|
||||
|
||||
export type iUniAssets<T> = Pick<
|
||||
|
@ -133,7 +134,7 @@ export type iUniAssets<T> = Pick<
|
|||
|
||||
export type iAaveSecondPoolAssets<T> = Pick<
|
||||
iAssetBase<T>,
|
||||
| 'ETH'
|
||||
| 'WETH'
|
||||
| 'DAI'
|
||||
| 'USDC'
|
||||
| 'USDT'
|
||||
|
@ -156,7 +157,7 @@ export enum TokenContractId {
|
|||
LEND = 'LEND',
|
||||
TUSD = 'TUSD',
|
||||
BAT = 'BAT',
|
||||
ETH = 'ETH',
|
||||
WETH = 'WETH',
|
||||
USDC = 'USDC',
|
||||
USDT = 'USDT',
|
||||
SUSD = 'SUSD',
|
||||
|
|
|
@ -45,7 +45,6 @@ import {MintableErc20} from '../types/MintableErc20';
|
|||
import {
|
||||
MOCK_USD_PRICE_IN_WEI,
|
||||
ALL_ASSETS_INITIAL_PRICES,
|
||||
MOCK_ETH_ADDRESS,
|
||||
USD_ADDRESS,
|
||||
MOCK_CHAINLINK_AGGREGATORS_PRICES,
|
||||
LENDING_RATE_ORACLE_RATES_COMMON,
|
||||
|
@ -67,7 +66,6 @@ const deployAllMockTokens = async (deployer: Signer) => {
|
|||
const secondaryConfigData = getReservesConfigByPool(AavePools.secondary);
|
||||
|
||||
for (const tokenSymbol of Object.keys(TokenContractId)) {
|
||||
if (tokenSymbol !== 'ETH') {
|
||||
let decimals = 18;
|
||||
|
||||
let configData = (<any>protoConfigData)[tokenSymbol];
|
||||
|
@ -86,7 +84,6 @@ const deployAllMockTokens = async (deployer: Signer) => {
|
|||
configData ? configData.reserveDecimals : 18,
|
||||
]);
|
||||
await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]);
|
||||
}
|
||||
}
|
||||
|
||||
return tokens;
|
||||
|
@ -225,16 +222,16 @@ const initReserves = async (
|
|||
]);
|
||||
|
||||
const stableDebtToken = await deployStableDebtToken([
|
||||
`Aave stable debt bearing ${assetSymbol}`,
|
||||
`stableDebt${assetSymbol}`,
|
||||
`Aave stable debt bearing ${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
`stableDebt${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
reserveDecimals,
|
||||
tokenAddress,
|
||||
lendingPool.address,
|
||||
]);
|
||||
|
||||
const variableDebtToken = await deployVariableDebtToken([
|
||||
`Aave variable debt bearing ${assetSymbol}`,
|
||||
`stableDebt${assetSymbol}`,
|
||||
`Aave variable debt bearing ${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
`variableDebt${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
reserveDecimals,
|
||||
tokenAddress,
|
||||
lendingPool.address,
|
||||
|
@ -243,9 +240,9 @@ const initReserves = async (
|
|||
const aToken = await deployGenericAToken([
|
||||
lendingPool.address,
|
||||
tokenAddress,
|
||||
`Aave interest bearing ${assetSymbol}`,
|
||||
`a${assetSymbol}`
|
||||
]);
|
||||
`Aave interest bearing ${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
`a${assetSymbol === "WETH" ? "ETH" : assetSymbol}`,
|
||||
]);
|
||||
|
||||
|
||||
if (process.env.POOL === AavePools.secondary) {
|
||||
|
@ -400,7 +397,7 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
|||
await setInitialAssetPricesInOracle(
|
||||
ALL_ASSETS_INITIAL_PRICES,
|
||||
{
|
||||
ETH: MOCK_ETH_ADDRESS,
|
||||
WETH: mockTokens.WETH.address,
|
||||
DAI: mockTokens.DAI.address,
|
||||
TUSD: mockTokens.TUSD.address,
|
||||
USDC: mockTokens.USDC.address,
|
||||
|
@ -461,7 +458,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
|||
|
||||
const {USD, ...tokensAddressesWithoutUsd} = allTokenAddresses;
|
||||
const allReservesAddresses = {
|
||||
ETH: MOCK_ETH_ADDRESS,
|
||||
...tokensAddressesWithoutUsd,
|
||||
};
|
||||
await setInitialMarketRatesInRatesOracle(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {
|
||||
APPROVAL_AMOUNT_LENDING_POOL,
|
||||
MOCK_ETH_ADDRESS,
|
||||
AAVE_REFERRAL,
|
||||
MAX_UINT_AMOUNT,
|
||||
ZERO_ADDRESS,
|
||||
|
@ -76,7 +75,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('User 0 transfers back to user 1', async () => {
|
||||
const {users, aDai, dai} = testEnv;
|
||||
const {users, aDai, dai, weth} = testEnv;
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '500');
|
||||
|
||||
await aDai.connect(users[0].signer).transfer(users[1].address, aDAItoTransfer);
|
||||
|
@ -91,31 +90,33 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
);
|
||||
});
|
||||
|
||||
it('User 0 deposits 1 ETH and user tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)', async () => {
|
||||
const {users, pool} = testEnv;
|
||||
it('User 0 deposits 1 WETH and user 1 tries to borrow, but the aTokens received as a transfer are not available as collateral (revert expected)', async () => {
|
||||
const {users, pool, weth} = testEnv;
|
||||
|
||||
await weth.connect(users[0].signer).mint(await convertToCurrencyDecimals(weth.address, '1'));
|
||||
|
||||
await weth.connect(users[0].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool
|
||||
.connect(users[0].signer)
|
||||
.deposit(MOCK_ETH_ADDRESS, ethers.utils.parseEther('1.0'), '0', {
|
||||
value: ethers.utils.parseEther('1.0'),
|
||||
});
|
||||
.deposit(weth.address, ethers.utils.parseEther('1.0'), '0');
|
||||
await expect(
|
||||
pool
|
||||
.connect(users[1].signer)
|
||||
.borrow(MOCK_ETH_ADDRESS, ethers.utils.parseEther('0.1'), RateMode.Stable, AAVE_REFERRAL),
|
||||
.borrow(weth.address, ethers.utils.parseEther('0.1'), RateMode.Stable, AAVE_REFERRAL),
|
||||
ZERO_COLLATERAL
|
||||
).to.be.revertedWith(ZERO_COLLATERAL);
|
||||
});
|
||||
|
||||
it('User 1 sets the DAI as collateral and borrows, tries to transfer everything back to user 0 (revert expected)', async () => {
|
||||
const {users, pool, aDai, dai} = testEnv;
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
await pool.connect(users[1].signer).setUserUseReserveAsCollateral(dai.address, true);
|
||||
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(dai.address, '1000');
|
||||
|
||||
await pool
|
||||
.connect(users[1].signer)
|
||||
.borrow(MOCK_ETH_ADDRESS, ethers.utils.parseEther('0.1'), RateMode.Stable, AAVE_REFERRAL);
|
||||
.borrow(weth.address, ethers.utils.parseEther('0.1'), RateMode.Stable, AAVE_REFERRAL);
|
||||
|
||||
await expect(
|
||||
aDai.connect(users[1].signer).transfer(users[0].address, aDAItoTransfer),
|
||||
|
@ -124,7 +125,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('User 0 tries to transfer 0 balance (revert expected)', async () => {
|
||||
const {users, pool, aDai, dai} = testEnv;
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
await expect(
|
||||
aDai.connect(users[0].signer).transfer(users[1].address, '0'),
|
||||
TRANSFERRED_AMOUNT_GT_ZERO
|
||||
|
@ -132,12 +133,15 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('User 1 repays the borrow, transfers aDAI back to user 0', async () => {
|
||||
const {users, pool, aDai, dai} = testEnv;
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
|
||||
await weth.connect(users[1].signer).mint(await convertToCurrencyDecimals(weth.address, '2'));
|
||||
|
||||
await weth.connect(users[1].signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool
|
||||
.connect(users[1].signer)
|
||||
.repay(MOCK_ETH_ADDRESS, MAX_UINT_AMOUNT, RateMode.Stable, users[1].address, {
|
||||
value: ethers.utils.parseEther('1'),
|
||||
});
|
||||
.repay(weth.address, MAX_UINT_AMOUNT, RateMode.Stable, users[1].address);
|
||||
|
||||
const aDAItoTransfer = await convertToCurrencyDecimals(aDai.address, '1000');
|
||||
|
||||
|
@ -159,7 +163,7 @@ makeSuite('AToken: Transfer', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('User 0 redirects interest to user 2, transfers 500 aDAI to user 1. User 1 redirects to user 3. User 0 transfers another 100 aDAI', async () => {
|
||||
const {users, pool, aDai, dai} = testEnv;
|
||||
const {users, pool, aDai, dai, weth} = testEnv;
|
||||
|
||||
let aDAItoTransfer = await convertToCurrencyDecimals(aDai.address, '500');
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {TestEnv, makeSuite} from './helpers/make-suite';
|
||||
import {MOCK_ETH_ADDRESS, RAY, APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants';
|
||||
import {RAY, APPROVAL_AMOUNT_LENDING_POOL} from '../helpers/constants';
|
||||
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
|
||||
import {ProtocolErrors} from '../helpers/types';
|
||||
|
||||
|
@ -9,219 +9,219 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
|
|||
const {INVALID_POOL_MANAGER_CALLER_MSG} = ProtocolErrors;
|
||||
|
||||
it('Deactivates the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.deactivateReserve(MOCK_ETH_ADDRESS);
|
||||
const {isActive} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.deactivateReserve(weth.address);
|
||||
const {isActive} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(isActive).to.be.equal(false);
|
||||
});
|
||||
|
||||
it('Rectivates the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.activateReserve(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.activateReserve(weth.address);
|
||||
|
||||
const {isActive} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {isActive} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(isActive).to.be.equal(true);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on deactivateReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).deactivateReserve(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).deactivateReserve(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on activateReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).activateReserve(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).activateReserve(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Freezes the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.freezeReserve(MOCK_ETH_ADDRESS);
|
||||
const {isFreezed} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.freezeReserve(weth.address);
|
||||
const {isFreezed} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(isFreezed).to.be.equal(true);
|
||||
});
|
||||
|
||||
it('Unfreezes the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.unfreezeReserve(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.unfreezeReserve(weth.address);
|
||||
|
||||
const {isFreezed} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {isFreezed} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(isFreezed).to.be.equal(false);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on freezeReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).freezeReserve(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).freezeReserve(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on unfreezeReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).unfreezeReserve(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).unfreezeReserve(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Deactivates the ETH reserve for borrowing', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.disableBorrowingOnReserve(MOCK_ETH_ADDRESS);
|
||||
const {borrowingEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.disableBorrowingOnReserve(weth.address);
|
||||
const {borrowingEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(borrowingEnabled).to.be.equal(false);
|
||||
});
|
||||
|
||||
it('Activates the ETH reserve for borrowing', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.enableBorrowingOnReserve(MOCK_ETH_ADDRESS, true);
|
||||
const {borrowingEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {variableBorrowIndex} = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.enableBorrowingOnReserve(weth.address, true);
|
||||
const {borrowingEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
const {variableBorrowIndex} = await pool.getReserveData(weth.address);
|
||||
expect(borrowingEnabled).to.be.equal(true);
|
||||
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on disableBorrowingOnReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).disableBorrowingOnReserve(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).disableBorrowingOnReserve(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on enableBorrowingOnReserve ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).enableBorrowingOnReserve(MOCK_ETH_ADDRESS, true),
|
||||
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, true),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Deactivates the ETH reserve as collateral', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.disableReserveAsCollateral(MOCK_ETH_ADDRESS);
|
||||
const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.disableReserveAsCollateral(weth.address);
|
||||
const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(usageAsCollateralEnabled).to.be.equal(false);
|
||||
});
|
||||
|
||||
it('Activates the ETH reserve as collateral', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.enableReserveAsCollateral(MOCK_ETH_ADDRESS, '75', '80', '105');
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.enableReserveAsCollateral(weth.address, '75', '80', '105');
|
||||
|
||||
const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {usageAsCollateralEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(usageAsCollateralEnabled).to.be.equal(true);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on disableReserveAsCollateral ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).disableReserveAsCollateral(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).disableReserveAsCollateral(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on enableReserveAsCollateral ', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator
|
||||
.connect(users[2].signer)
|
||||
.enableReserveAsCollateral(MOCK_ETH_ADDRESS, '75', '80', '105'),
|
||||
.enableReserveAsCollateral(weth.address, '75', '80', '105'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Disable stable borrow rate on the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.disableReserveStableRate(MOCK_ETH_ADDRESS);
|
||||
const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.disableReserveStableRate(weth.address);
|
||||
const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(stableBorrowRateEnabled).to.be.equal(false);
|
||||
});
|
||||
|
||||
it('Enables stable borrow rate on the ETH reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.enableReserveStableRate(MOCK_ETH_ADDRESS);
|
||||
const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.enableReserveStableRate(weth.address);
|
||||
const {stableBorrowRateEnabled} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(stableBorrowRateEnabled).to.be.equal(true);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on disableReserveStableRate', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).disableReserveStableRate(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).disableReserveStableRate(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on enableReserveStableRate', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).enableReserveStableRate(MOCK_ETH_ADDRESS),
|
||||
configurator.connect(users[2].signer).enableReserveStableRate(weth.address),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Changes LTV of the reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.setLtv(MOCK_ETH_ADDRESS, '60');
|
||||
const {ltv}: any = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.setLtv(weth.address, '60');
|
||||
const {ltv}: any = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(ltv).to.be.bignumber.equal('60', 'Invalid LTV');
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on setLtv', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).setLtv(MOCK_ETH_ADDRESS, '75'),
|
||||
configurator.connect(users[2].signer).setLtv(weth.address, '75'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Changes liquidation threshold of the reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.setLiquidationThreshold(MOCK_ETH_ADDRESS, '75');
|
||||
const {liquidationThreshold}: any = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.setLiquidationThreshold(weth.address, '75');
|
||||
const {liquidationThreshold}: any = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(liquidationThreshold).to.be.bignumber.equal('75', 'Invalid Liquidation threshold');
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on setLiquidationThreshold', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).setLiquidationThreshold(MOCK_ETH_ADDRESS, '80'),
|
||||
configurator.connect(users[2].signer).setLiquidationThreshold(weth.address, '80'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Changes liquidation bonus of the reserve', async () => {
|
||||
const {configurator, pool} = testEnv;
|
||||
await configurator.setLiquidationBonus(MOCK_ETH_ADDRESS, '110');
|
||||
const {liquidationBonus} = await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS);
|
||||
const {configurator, pool, weth} = testEnv;
|
||||
await configurator.setLiquidationBonus(weth.address, '110');
|
||||
const {liquidationBonus} = await pool.getReserveConfigurationData(weth.address);
|
||||
expect(liquidationBonus).to.be.bignumber.equal('110', 'Invalid Liquidation discount');
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on setLiquidationBonus', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).setLiquidationBonus(MOCK_ETH_ADDRESS, '80'),
|
||||
configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on setReserveDecimals', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).setReserveDecimals(MOCK_ETH_ADDRESS, '80'),
|
||||
configurator.connect(users[2].signer).setReserveDecimals(weth.address, '80'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
||||
it('Check the onlyLendingPoolManager on setLiquidationBonus', async () => {
|
||||
const {configurator, users} = testEnv;
|
||||
const {configurator, users, weth} = testEnv;
|
||||
await expect(
|
||||
configurator.connect(users[2].signer).setLiquidationBonus(MOCK_ETH_ADDRESS, '80'),
|
||||
configurator.connect(users[2].signer).setLiquidationBonus(weth.address, '80'),
|
||||
INVALID_POOL_MANAGER_CALLER_MSG
|
||||
).to.be.revertedWith(INVALID_POOL_MANAGER_CALLER_MSG);
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {TestEnv, makeSuite} from './helpers/make-suite';
|
||||
import {MOCK_ETH_ADDRESS, APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
|
||||
import {APPROVAL_AMOUNT_LENDING_POOL, oneRay} from '../helpers/constants';
|
||||
import {
|
||||
convertToCurrencyDecimals,
|
||||
getMockFlashLoanReceiver,
|
||||
|
@ -29,34 +29,29 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('Deposits ETH into the reserve', async () => {
|
||||
const {pool} = testEnv;
|
||||
const {pool, weth} = testEnv;
|
||||
const amountToDeposit = ethers.utils.parseEther('1');
|
||||
|
||||
await pool.deposit(MOCK_ETH_ADDRESS, amountToDeposit, '0', {
|
||||
value: amountToDeposit,
|
||||
});
|
||||
await weth.mint(amountToDeposit);
|
||||
|
||||
await weth.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool.deposit(weth.address, amountToDeposit, '0');
|
||||
});
|
||||
|
||||
it('Takes ETH flashloan, returns the funds correctly', async () => {
|
||||
const {pool, deployer} = testEnv;
|
||||
|
||||
// move funds to the MockFlashLoanReceiver contract to pay the fee
|
||||
await deployer.signer.sendTransaction({
|
||||
value: ethers.utils.parseEther('0.5'),
|
||||
to: _mockFlashLoanReceiver.address,
|
||||
});
|
||||
const {pool, deployer, weth} = testEnv;
|
||||
|
||||
await pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
'0x10'
|
||||
);
|
||||
|
||||
ethers.utils.parseUnits('10000');
|
||||
|
||||
const reserveData: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const tokenDistributorBalance = await BRE.ethers.provider.getBalance(_tokenDistributor.address);
|
||||
const reserveData: any = await pool.getReserveData(weth.address);
|
||||
|
||||
const currentLiquidityRate = reserveData.liquidityRate;
|
||||
const currentLiquidityIndex = reserveData.liquidityIndex;
|
||||
|
@ -65,30 +60,28 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.plus(reserveData.totalBorrowsStable)
|
||||
.plus(reserveData.totalBorrowsVariable);
|
||||
|
||||
const tokenDistributorBalance = await weth.balanceOf(_tokenDistributor.address);
|
||||
|
||||
|
||||
expect(totalLiquidity.toString()).to.be.equal('1000504000000000000');
|
||||
expect(currentLiquidityRate.toString()).to.be.equal('0');
|
||||
expect(currentLiquidityIndex.toString()).to.be.equal('1000504000000000000000000000');
|
||||
expect(tokenDistributorBalance.toString()).to.be.equal('216000000000000');
|
||||
expect(tokenDistributorBalance).to.be.equal('216000000000000');
|
||||
});
|
||||
|
||||
it('Takes an ETH flashloan as big as the available liquidity', async () => {
|
||||
const {pool, deployer} = testEnv;
|
||||
|
||||
// move funds to the MockFlashLoanReceiver contract to pay the fee
|
||||
await deployer.signer.sendTransaction({
|
||||
value: ethers.utils.parseEther('0.5'),
|
||||
to: _mockFlashLoanReceiver.address,
|
||||
});
|
||||
const {pool, deployer, weth} = testEnv;
|
||||
|
||||
const txResult = await pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
'1000504000000000000',
|
||||
'0x10'
|
||||
);
|
||||
|
||||
const reserveData: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const tokenDistributorBalance = await BRE.ethers.provider.getBalance(_tokenDistributor.address);
|
||||
const reserveData: any = await pool.getReserveData(weth.address);
|
||||
const tokenDistributorBalance = await weth.balanceOf(_tokenDistributor.address);
|
||||
|
||||
|
||||
const currentLiqudityRate = reserveData.liquidityRate;
|
||||
const currentLiquidityIndex = reserveData.liquidityIndex;
|
||||
|
@ -103,21 +96,17 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
expect(tokenDistributorBalance.toString()).to.be.equal('486136080000000');
|
||||
});
|
||||
|
||||
it('Takes ETH flashloan, does not return the funds (revert expected)', async () => {
|
||||
const {pool, deployer} = testEnv;
|
||||
it('Takes WETH flashloan, does not return the funds (revert expected)', async () => {
|
||||
const {pool, deployer, weth} = testEnv;
|
||||
|
||||
// move funds to the MockFlashLoanReceiver contract to pay the fee
|
||||
await deployer.signer.sendTransaction({
|
||||
value: ethers.utils.parseEther('0.5'),
|
||||
to: _mockFlashLoanReceiver.address,
|
||||
});
|
||||
|
||||
await _mockFlashLoanReceiver.setFailExecutionTransfer(true);
|
||||
|
||||
await expect(
|
||||
pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
'0x10'
|
||||
)
|
||||
|
@ -125,12 +114,12 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
|
||||
const {pool} = testEnv;
|
||||
const {pool, weth} = testEnv;
|
||||
|
||||
await expect(
|
||||
pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
'1', //1 wei loan
|
||||
'0x10'
|
||||
)
|
||||
|
@ -138,12 +127,12 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
|
||||
const {pool} = testEnv;
|
||||
const {pool, weth} = testEnv;
|
||||
|
||||
await expect(
|
||||
pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
'1004415000000000000', //slightly higher than the available liquidity
|
||||
'0x10'
|
||||
),
|
||||
|
@ -152,9 +141,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('tries to take a flashloan using a non contract address as receiver (revert expected)', async () => {
|
||||
const {pool, deployer} = testEnv;
|
||||
const {pool, deployer, weth} = testEnv;
|
||||
|
||||
await expect(pool.flashLoan(deployer.address, MOCK_ETH_ADDRESS, '1000000000000000000', '0x10'))
|
||||
await expect(pool.flashLoan(deployer.address, weth.address, '1000000000000000000', '0x10'))
|
||||
.to.be.reverted;
|
||||
});
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import {
|
|||
convertToCurrencyDecimals,
|
||||
getAToken,
|
||||
} from '../../helpers/contracts-helpers';
|
||||
import {MOCK_ETH_ADDRESS, ONE_YEAR, MAX_UINT_AMOUNT} from '../../helpers/constants';
|
||||
import {ONE_YEAR, MAX_UINT_AMOUNT} from '../../helpers/constants';
|
||||
import {TestEnv, SignerWithAddress} from './make-suite';
|
||||
import {BRE, increaseTime, timeLatest} from '../../helpers/misc-utils';
|
||||
|
||||
|
@ -115,10 +115,6 @@ export const configuration: ActionsConfig = <ActionsConfig>{};
|
|||
export const mint = async (reserveSymbol: string, amount: string, user: SignerWithAddress) => {
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
if (MOCK_ETH_ADDRESS.toLowerCase() === reserve.toLowerCase()) {
|
||||
throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
|
||||
}
|
||||
|
||||
const token = await getMintableErc20(reserve);
|
||||
|
||||
await waitForTx(
|
||||
|
@ -130,10 +126,6 @@ export const approve = async (reserveSymbol: string, user: SignerWithAddress, te
|
|||
const {pool} = testEnv;
|
||||
const reserve = await getReserveAddressFromSymbol(reserveSymbol);
|
||||
|
||||
if (MOCK_ETH_ADDRESS.toLowerCase() === reserve.toLowerCase()) {
|
||||
throw 'Cannot mint ethereum. Mint action is most likely not needed in this story';
|
||||
}
|
||||
|
||||
const token = await getMintableErc20(reserve);
|
||||
|
||||
await token.connect(user.signer).approve(pool.address, '100000000000000000000000000000');
|
||||
|
@ -162,13 +154,9 @@ export const deposit = async (
|
|||
testEnv
|
||||
);
|
||||
|
||||
if (MOCK_ETH_ADDRESS === reserve) {
|
||||
if (sendValue) {
|
||||
const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
|
||||
txOptions.value = valueToSend;
|
||||
} else {
|
||||
txOptions.value = amountToDeposit;
|
||||
}
|
||||
if (sendValue) {
|
||||
const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
|
||||
txOptions.value = valueToSend;
|
||||
}
|
||||
if (expectedResult === 'success') {
|
||||
const txResult = await waitForTx(
|
||||
|
@ -413,26 +401,9 @@ export const repay = async (
|
|||
|
||||
const txOptions: any = {};
|
||||
|
||||
if (MOCK_ETH_ADDRESS === reserve) {
|
||||
if (sendValue) {
|
||||
const valueToSend =
|
||||
rateMode == RateMode.Stable
|
||||
? userDataBefore.currentStableDebt
|
||||
: userDataBefore.currentVariableDebt;
|
||||
|
||||
if (sendValue !== '-1') {
|
||||
const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
|
||||
txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
|
||||
} else {
|
||||
txOptions.value =
|
||||
'0x' +
|
||||
valueToSend
|
||||
.plus((await convertToCurrencyDecimals(reserve, '0.1')).toString())
|
||||
.toString(16); //add 0.1 ETH to the repayment amount to cover for accrued interest during tx execution
|
||||
}
|
||||
} else {
|
||||
txOptions.value = amountToRepay;
|
||||
}
|
||||
if (sendValue) {
|
||||
const valueToSend = await convertToCurrencyDecimals(reserve, sendValue);
|
||||
txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16);
|
||||
}
|
||||
|
||||
if (expectedResult === 'success') {
|
||||
|
|
|
@ -35,6 +35,8 @@ export interface TestEnv {
|
|||
configurator: LendingPoolConfigurator;
|
||||
oracle: PriceOracle;
|
||||
helpersContract: AaveProtocolTestHelpers;
|
||||
weth: MintableErc20;
|
||||
aEth: AToken;
|
||||
dai: MintableErc20;
|
||||
aDai: AToken;
|
||||
usdc: MintableErc20;
|
||||
|
@ -56,6 +58,8 @@ const testEnv: TestEnv = {
|
|||
configurator: {} as LendingPoolConfigurator,
|
||||
helpersContract: {} as AaveProtocolTestHelpers,
|
||||
oracle: {} as PriceOracle,
|
||||
weth: {} as MintableErc20,
|
||||
aEth: {} as AToken,
|
||||
dai: {} as MintableErc20,
|
||||
aDai: {} as AToken,
|
||||
usdc: {} as MintableErc20,
|
||||
|
@ -92,25 +96,34 @@ export async function initializeMakeSuite() {
|
|||
(aToken) => aToken.symbol === 'aDAI'
|
||||
)?.tokenAddress;
|
||||
|
||||
|
||||
const aEthAddress = (await testEnv.helpersContract.getAllATokens()).find(
|
||||
(aToken) => aToken.symbol === 'aETH'
|
||||
)?.tokenAddress;
|
||||
|
||||
const reservesTokens = await testEnv.helpersContract.getAllReservesTokens();
|
||||
|
||||
const daiAddress = reservesTokens.find((token) => token.symbol === 'DAI')?.tokenAddress;
|
||||
const usdcAddress = reservesTokens.find((token) => token.symbol === 'USDC')?.tokenAddress;
|
||||
const lendAddress = reservesTokens.find((token) => token.symbol === 'LEND')?.tokenAddress;
|
||||
const wethAddress = reservesTokens.find((token) => token.symbol === 'WETH')?.tokenAddress;
|
||||
|
||||
if (!aDaiAddress) {
|
||||
console.log(`atoken-modifiers.spec: aDAI not correctly initialized`);
|
||||
if (!aDaiAddress || !aEthAddress) {
|
||||
console.log(`atoken-modifiers.spec: aTokens not correctly initialized`);
|
||||
process.exit(1);
|
||||
}
|
||||
if (!daiAddress || !usdcAddress || !lendAddress) {
|
||||
if (!daiAddress || !usdcAddress || !lendAddress || ! wethAddress) {
|
||||
console.log(`atoken-modifiers.spec: USDC or DAI not correctly initialized`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
testEnv.aDai = await getAToken(aDaiAddress);
|
||||
testEnv.aEth = await getAToken(aEthAddress);
|
||||
|
||||
testEnv.dai = await getMintableErc20(daiAddress);
|
||||
testEnv.usdc = await getMintableErc20(usdcAddress);
|
||||
testEnv.lend = await getMintableErc20(lendAddress);
|
||||
testEnv.weth = await getMintableErc20(wethAddress);
|
||||
}
|
||||
|
||||
export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Test cases for the deposit function.",
|
||||
"stories": [
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with rate mode NONE (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -31,13 +31,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -55,7 +72,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and tries to borrow 100 DAI with an invalid rate mode (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -83,13 +100,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Test cases for the borrow function, stable mode.",
|
||||
"stories": [
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and borrows 100 DAI at stable rate",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at stable rate",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -31,13 +31,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -161,7 +178,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 ETH each and borrow 100 DAI at stable rate. Everything is repaid, user 0 redeems",
|
||||
"description": "User 0 deposits 1000 DAI, user 1,2,3,4 deposit 1 WETH each and borrow 100 DAI at stable rate. Everything is repaid, user 0 redeems",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -189,13 +206,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -210,13 +244,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "2",
|
||||
"sendValue": "1"
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -231,13 +282,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "3",
|
||||
"sendValue": "1"
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -252,13 +320,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "4"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "4"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "4",
|
||||
"sendValue": "1"
|
||||
"user": "4"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -401,7 +486,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 2 ETH and borrow 100 DAI at stable rate first, then 100 DAI at variable rate, repays everything. User 0 redeems",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 2 WETH and borrow 100 DAI at stable rate first, then 100 DAI at variable rate, repays everything. User 0 redeems",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -429,13 +514,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "2",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "2",
|
||||
"user": "1",
|
||||
"sendValue": "2"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 ETH as collateral and borrows 100 DAI at variable rate",
|
||||
"description": "User 0 deposits 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -62,13 +62,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -187,7 +204,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "1"
|
||||
},
|
||||
|
@ -196,30 +214,64 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 2 deposits a small amount of ETH to account for rounding errors",
|
||||
"description": "User 2 deposits a small amount of WETH to account for rounding errors",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "0.001",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.001",
|
||||
"user": "2",
|
||||
"sendValue": "0.001"
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1 ETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate",
|
||||
"description": "User 0 deposits 1 WETH, user 1 deposits 100 LINK as collateral and borrows 0.5 ETH at variable rate",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "0",
|
||||
"sendValue": "1"
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -253,7 +305,8 @@
|
|||
{
|
||||
"name": "borrow",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.5",
|
||||
"borrowRateMode": "variable",
|
||||
"user": "1",
|
||||
|
@ -269,48 +322,29 @@
|
|||
{
|
||||
"name": "repay",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
"amount": "0",
|
||||
"user": "1",
|
||||
"onBehalfOf": "1",
|
||||
"borrowRateMode": "variable",
|
||||
"sendValue": "0"
|
||||
"borrowRateMode": "variable"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "Amount must be greater than 0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 tries to repay without sending any ETH value (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "repay",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"amount": "-1",
|
||||
"user": "1",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "0"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "Invalid msg.value sent for the repayment"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 2 tries to repay everything on behalf of user 1 using uint(-1) (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "repay",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "2",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "-1"
|
||||
"onBehalfOf": "1"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "To repay on behalf of an user an explicit amount to repay is needed"
|
||||
|
@ -318,46 +352,81 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 3 repays a small amount of ETH on behalf of user 1",
|
||||
"description": "User 3 repays a small amount of WETH on behalf of user 1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "repay",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.2",
|
||||
"user": "3",
|
||||
"borrowRateMode": "variable",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "0.2"
|
||||
"onBehalfOf": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 repays the ETH borrow after one year",
|
||||
"description": "User 1 repays the WETH borrow after one year",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "repay",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"borrowRateMode": "variable",
|
||||
"user": "1",
|
||||
"onBehalfOf": "1",
|
||||
"sendValue": "-1"
|
||||
"onBehalfOf": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 redeems the deposited ETH plus interest",
|
||||
"description": "User 0 redeems the deposited WETH plus interest",
|
||||
"actions": [
|
||||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "0"
|
||||
},
|
||||
|
@ -412,7 +481,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 USDC, user 1 deposits 1 ETH as collateral and borrows 100 USDC at variable rate",
|
||||
"description": "User 0 deposits 1000 USDC, user 1 deposits 1 WETH as collateral and borrows 100 USDC at variable rate",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -440,13 +509,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -533,7 +619,7 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
"amount": "-1",
|
||||
"user": "1"
|
||||
},
|
||||
|
@ -586,13 +672,30 @@
|
|||
{
|
||||
"description": "user 3 deposits 0.1 ETH collateral to borrow 100 DAI; 0.1 ETH is not enough to borrow 100 DAI (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "0.1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.1",
|
||||
"user": "3",
|
||||
"sendValue": "0.1"
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -615,7 +718,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "3"
|
||||
},
|
||||
|
@ -668,13 +772,30 @@
|
|||
{
|
||||
"description": "user 3 deposits 0.1 ETH collateral to borrow 100 USDC; 0.1 ETH is not enough to borrow 100 USDC (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.1",
|
||||
"user": "3",
|
||||
"sendValue": "0.1"
|
||||
"user": "3"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -697,7 +818,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "3"
|
||||
},
|
||||
|
@ -706,7 +828,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1000 DAI, user 6 deposits 2 ETH and borrow 100 DAI at variable rate first, then 100 DAI at stable rate, repays everything. User 0 redeems",
|
||||
"description": "User 0 deposits 1000 DAI, user 6 deposits 2 WETH and borrow 100 DAI at variable rate first, then 100 DAI at stable rate, repays everything. User 0 redeems",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -734,13 +856,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "2",
|
||||
"user": "6"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "6"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "2",
|
||||
"user": "6",
|
||||
"sendValue": "2"
|
||||
"user": "6"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -127,30 +127,64 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 deposits 1 ETH in an empty reserve",
|
||||
"description": "User 0 deposits 1 WETH in an empty reserve",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "0",
|
||||
"sendValue": "1"
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 deposits 1 ETH after user 0",
|
||||
"description": "User 1 deposits 1 WETH after user 0",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
|
@ -159,10 +193,20 @@
|
|||
{
|
||||
"description": "User 1 deposits 0 ETH (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0",
|
||||
"user": "1"
|
||||
},
|
||||
|
@ -185,38 +229,6 @@
|
|||
"revertMessage": "Amount must be greater than 0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 tries to deposit ETH without sending any value",
|
||||
"actions": [
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "0"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "The amount and the value sent to deposit do not match"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "User 1 tries to deposit ETH by sending less value than required",
|
||||
"actions": [
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "0.5"
|
||||
},
|
||||
"expected": "revert",
|
||||
"revertMessage": "The amount and the value sent to deposit do not match"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -45,13 +45,30 @@
|
|||
{
|
||||
"description": "User 1 deposits 1 ETH, borrows 100 DAI, repays after one year. Users 0 deposits another 1000 DAI. Redirected balance of user 2 is updated",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "2",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "2",
|
||||
"user": "1",
|
||||
"sendValue": "2"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -47,13 +47,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -107,13 +124,30 @@
|
|||
{
|
||||
"description": "User 2 deposits ETH and borrows the remaining DAI, causing the stable rates to rise (liquidity rate < user 1 borrow rate). User 0 tries to rebalance user 1 (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "5",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "5",
|
||||
"user": "2",
|
||||
"sendValue": "5"
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -142,13 +176,30 @@
|
|||
{
|
||||
"description": "User 2 borrows more DAI, causing the liquidity rate to rise above user 1 stable borrow rate User 0 rebalances user 1",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "3",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "3",
|
||||
"user": "2",
|
||||
"sendValue": "3"
|
||||
"user": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -60,15 +60,32 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "Users 1 deposits 1 ETH, borrows 100 DAI, tries to redeem the 1 ETH deposited (revert expected)",
|
||||
"description": "Users 1 deposits 1 WETH, borrows 100 DAI, tries to redeem the 1 WETH deposited (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
@ -85,7 +102,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "1"
|
||||
},
|
||||
|
|
|
@ -121,15 +121,32 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "User 0 Deposits 1 ETH in an empty reserve",
|
||||
"description": "User 0 Deposits 1 WETH in an empty reserve",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "0",
|
||||
"sendValue": "1"
|
||||
"user": "0"
|
||||
},
|
||||
"expected": "success"
|
||||
}
|
||||
|
@ -141,7 +158,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "0.5",
|
||||
"user": "0"
|
||||
},
|
||||
|
@ -155,7 +173,8 @@
|
|||
{
|
||||
"name": "redeem",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "-1",
|
||||
"user": "0"
|
||||
},
|
||||
|
@ -222,7 +241,7 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 ETH, borrows 100 DAI. User 1 tries to redeem all the USDC",
|
||||
"description": "Users 0 deposits 1000 DAI, user 1 Deposit 1000 USDC and 1 WETH, borrows 100 DAI. User 1 tries to redeem all the USDC",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
|
@ -276,13 +295,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "1",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "1",
|
||||
"user": "1",
|
||||
"sendValue": "1"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -45,20 +45,38 @@
|
|||
{
|
||||
"description": "User 1 Deposits 2 ETH, disables ETH as collateral, borrows 400 DAI (revert expected)",
|
||||
"actions": [
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "2",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "2",
|
||||
"user": "1",
|
||||
"sendValue": "2"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "setUseAsCollateral",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"user": "1",
|
||||
"useAsCollateral": "false"
|
||||
},
|
||||
|
@ -80,20 +98,10 @@
|
|||
{
|
||||
"description": "User 1 enables ETH as collateral, borrows 400 DAI",
|
||||
"actions": [
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"amount": "2",
|
||||
"user": "1",
|
||||
"sendValue": "2"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "setUseAsCollateral",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
"user": "1",
|
||||
"useAsCollateral": "true"
|
||||
},
|
||||
|
@ -117,7 +125,8 @@
|
|||
{
|
||||
"name": "setUseAsCollateral",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"user": "1",
|
||||
"useAsCollateral": "false"
|
||||
},
|
||||
|
|
|
@ -61,13 +61,30 @@
|
|||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"amount": "2",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "approve",
|
||||
"args": {
|
||||
"reserve": "WETH",
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
{
|
||||
"name": "deposit",
|
||||
"args": {
|
||||
"reserve": "ETH",
|
||||
"reserve": "WETH",
|
||||
|
||||
"amount": "2",
|
||||
"user": "1",
|
||||
"sendValue": "2"
|
||||
"user": "1"
|
||||
},
|
||||
"expected": "success"
|
||||
},
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
getMintableErc20,
|
||||
getAToken,
|
||||
} from '../../../helpers/contracts-helpers';
|
||||
import {MOCK_ETH_ADDRESS, ZERO_ADDRESS} from '../../../helpers/constants';
|
||||
import {ZERO_ADDRESS} from '../../../helpers/constants';
|
||||
import {tEthereumAddress} from '../../../helpers/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {getDb, BRE} from '../../../helpers/misc-utils';
|
||||
|
@ -22,14 +22,9 @@ export const getReserveData = async (
|
|||
|
||||
const rate = (await rateOracle.getMarketBorrowRate(reserve)).toString();
|
||||
|
||||
const isEthReserve = reserve === MOCK_ETH_ADDRESS;
|
||||
let symbol = 'ETH';
|
||||
let decimals = new BigNumber(18);
|
||||
if (!isEthReserve) {
|
||||
const token = await getIErc20Detailed(reserve);
|
||||
symbol = await token.symbol();
|
||||
decimals = new BigNumber(await token.decimals());
|
||||
}
|
||||
const token = await getIErc20Detailed(reserve);
|
||||
const symbol = await token.symbol();
|
||||
const decimals = new BigNumber(await token.decimals());
|
||||
|
||||
const totalLiquidity = new BigNumber(data.availableLiquidity)
|
||||
.plus(data.totalBorrowsStable)
|
||||
|
@ -82,14 +77,8 @@ export const getUserData = async (
|
|||
interestRedirectionAddress,
|
||||
] = aTokenData;
|
||||
|
||||
let walletBalance;
|
||||
|
||||
if (reserve === MOCK_ETH_ADDRESS) {
|
||||
walletBalance = new BigNumber((await BRE.ethers.provider.getBalance(user)).toString());
|
||||
} else {
|
||||
const token = await getMintableErc20(reserve);
|
||||
walletBalance = new BigNumber((await token.balanceOf(user)).toString());
|
||||
}
|
||||
const token = await getMintableErc20(reserve);
|
||||
const walletBalance = new BigNumber((await token.balanceOf(user)).toString());
|
||||
|
||||
return {
|
||||
principalATokenBalance: new BigNumber(principalATokenBalance),
|
||||
|
@ -112,14 +101,13 @@ export const getUserData = async (
|
|||
};
|
||||
|
||||
export const getReserveAddressFromSymbol = async (symbol: string) => {
|
||||
if (symbol.toUpperCase() === 'ETH') {
|
||||
return MOCK_ETH_ADDRESS;
|
||||
}
|
||||
|
||||
|
||||
const token = await getMintableErc20(
|
||||
(await getDb().get(`${symbol}.${BRE.network.name}`).value()).address
|
||||
);
|
||||
|
||||
|
||||
if (!token) {
|
||||
throw `Could not find instance for contract ${symbol}`;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import {BRE} from '../helpers/misc-utils';
|
||||
import {APPROVAL_AMOUNT_LENDING_POOL, MOCK_ETH_ADDRESS, oneEther} from '../helpers/constants';
|
||||
import {APPROVAL_AMOUNT_LENDING_POOL, oneEther} from '../helpers/constants';
|
||||
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
|
||||
import {makeSuite} from './helpers/make-suite';
|
||||
import {ProtocolErrors, RateMode} from '../helpers/types';
|
||||
|
@ -20,8 +20,8 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
|
||||
} = ProtocolErrors;
|
||||
|
||||
it('LIQUIDATION - Deposits ETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
|
||||
const {dai, users, pool, oracle} = testEnv;
|
||||
it('LIQUIDATION - Deposits WETH, borrows DAI/Check liquidation fails because health factor is above 1', async () => {
|
||||
const {dai, weth, users, pool, oracle} = testEnv;
|
||||
const depositor = users[0];
|
||||
const borrower = users[1];
|
||||
|
||||
|
@ -35,15 +35,20 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
const amountDAItoDeposit = await convertToCurrencyDecimals(dai.address, '1000');
|
||||
await pool.connect(depositor.signer).deposit(dai.address, amountDAItoDeposit, '0');
|
||||
|
||||
//user 2 deposits 1 ETH
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(MOCK_ETH_ADDRESS, '1');
|
||||
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
||||
|
||||
//mints WETH to borrower
|
||||
await weth.connect(borrower.signer).mint(amountETHtoDeposit);
|
||||
|
||||
//approve protocol to access borrower wallet
|
||||
await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
//user 2 deposits 1 WETH
|
||||
await pool
|
||||
.connect(borrower.signer)
|
||||
.deposit(MOCK_ETH_ADDRESS, amountETHtoDeposit, '0', {value: amountETHtoDeposit});
|
||||
.deposit(weth.address, amountETHtoDeposit, '0');
|
||||
|
||||
await pool.connect(borrower.signer).deposit(MOCK_ETH_ADDRESS, amountETHtoDeposit, '0', {
|
||||
value: amountETHtoDeposit,
|
||||
});
|
||||
|
||||
//user 2 borrows
|
||||
const userGlobalData = await pool.getUserAccountData(borrower.address);
|
||||
|
@ -70,7 +75,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
|
||||
//someone tries to liquidate user 2
|
||||
await expect(
|
||||
pool.liquidationCall(MOCK_ETH_ADDRESS, dai.address, borrower.address, 1, true)
|
||||
pool.liquidationCall(weth.address, dai.address, borrower.address, 1, true)
|
||||
).to.be.revertedWith(HF_IS_NOT_BELLOW_THRESHOLD);
|
||||
});
|
||||
|
||||
|
@ -91,13 +96,13 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
});
|
||||
|
||||
it('LIQUIDATION - Tries to liquidate a different currency than the loan principal', async () => {
|
||||
const {pool, users} = testEnv;
|
||||
const {pool, users, weth} = testEnv;
|
||||
const borrower = users[1];
|
||||
//user 2 tries to borrow
|
||||
await expect(
|
||||
pool.liquidationCall(
|
||||
MOCK_ETH_ADDRESS,
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
weth.address,
|
||||
borrower.address,
|
||||
oneEther.toString(),
|
||||
true
|
||||
|
@ -106,7 +111,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
});
|
||||
|
||||
it('LIQUIDATION - Tries to liquidate a different collateral than the borrower collateral', async () => {
|
||||
const {pool, dai, users} = testEnv;
|
||||
const {pool, dai, weth, users} = testEnv;
|
||||
const borrower = users[1];
|
||||
|
||||
await expect(
|
||||
|
@ -115,7 +120,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
});
|
||||
|
||||
it('LIQUIDATION - Liquidates the borrow', async () => {
|
||||
const {pool, dai, users, oracle} = testEnv;
|
||||
const {pool, dai, weth, users, oracle} = testEnv;
|
||||
const borrower = users[1];
|
||||
|
||||
//mints dai to the caller
|
||||
|
@ -126,7 +131,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
await dai.approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
const daiReserveDataBefore = await getReserveData(pool, dai.address);
|
||||
const ethReserveDataBefore = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
||||
|
||||
const userReserveDataBefore = await getUserData(pool, dai.address, borrower.address);
|
||||
|
||||
|
@ -135,7 +140,7 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
.toFixed(0);
|
||||
|
||||
const tx = await pool.liquidationCall(
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
dai.address,
|
||||
borrower.address,
|
||||
amountToLiquidate,
|
||||
|
@ -147,13 +152,13 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||
|
||||
const daiReserveDataAfter = await pool.getReserveData(dai.address);
|
||||
const ethReserveDataAfter = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
||||
|
||||
const collateralPrice = (await oracle.getAssetPrice(MOCK_ETH_ADDRESS)).toString();
|
||||
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
||||
const principalPrice = (await oracle.getAssetPrice(dai.address)).toString();
|
||||
|
||||
const collateralDecimals = (
|
||||
await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS)
|
||||
await pool.getReserveConfigurationData(weth.address)
|
||||
).decimals.toString();
|
||||
const principalDecimals = (
|
||||
await pool.getReserveConfigurationData(dai.address)
|
||||
|
@ -215,8 +220,8 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
);
|
||||
});
|
||||
|
||||
it('User 3 deposits 1000 USDC, user 4 1 ETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||
const {users, pool, usdc, oracle, addressesProvider} = testEnv;
|
||||
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||
const {users, pool, usdc, oracle, weth} = testEnv;
|
||||
const depositor = users[3];
|
||||
const borrower = users[4];
|
||||
//mints USDC to depositor
|
||||
|
@ -233,9 +238,15 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
await pool.connect(depositor.signer).deposit(usdc.address, amountUSDCtoDeposit, '0');
|
||||
|
||||
//user 4 deposits 1 ETH
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(MOCK_ETH_ADDRESS, '1');
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
||||
|
||||
await pool.connect(borrower.signer).deposit(MOCK_ETH_ADDRESS, amountETHtoDeposit, '0', {
|
||||
//mints WETH to borrower
|
||||
await weth.connect(borrower.signer).mint(amountETHtoDeposit);
|
||||
|
||||
//approve protocol to access borrower wallet
|
||||
await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool.connect(borrower.signer).deposit(weth.address, amountETHtoDeposit, '0', {
|
||||
value: amountETHtoDeposit,
|
||||
});
|
||||
|
||||
|
@ -273,14 +284,14 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
const userReserveDataBefore = await pool.getUserReserveData(usdc.address, borrower.address);
|
||||
|
||||
const usdcReserveDataBefore = await pool.getReserveData(usdc.address);
|
||||
const ethReserveDataBefore = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataBefore = await pool.getReserveData(weth.address);
|
||||
|
||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt.toString())
|
||||
.div(2)
|
||||
.toFixed(0);
|
||||
|
||||
await pool.liquidationCall(
|
||||
MOCK_ETH_ADDRESS,
|
||||
weth.address,
|
||||
usdc.address,
|
||||
borrower.address,
|
||||
amountToLiquidate,
|
||||
|
@ -292,13 +303,13 @@ makeSuite('LendingPool liquidation - liquidator receiving aToken', (testEnv) =>
|
|||
const userGlobalDataAfter = await pool.getUserAccountData(borrower.address);
|
||||
|
||||
const usdcReserveDataAfter = await pool.getReserveData(usdc.address);
|
||||
const ethReserveDataAfter = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataAfter = await pool.getReserveData(weth.address);
|
||||
|
||||
const collateralPrice = (await oracle.getAssetPrice(MOCK_ETH_ADDRESS)).toString();
|
||||
const collateralPrice = (await oracle.getAssetPrice(weth.address)).toString();
|
||||
const principalPrice = (await oracle.getAssetPrice(usdc.address)).toString();
|
||||
|
||||
const collateralDecimals = (
|
||||
await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS)
|
||||
await pool.getReserveConfigurationData(weth.address)
|
||||
).decimals.toString();
|
||||
const principalDecimals = (
|
||||
await pool.getReserveConfigurationData(usdc.address)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import BigNumber from 'bignumber.js';
|
||||
|
||||
import {BRE} from '../helpers/misc-utils';
|
||||
import {APPROVAL_AMOUNT_LENDING_POOL, MOCK_ETH_ADDRESS, oneEther} from '../helpers/constants';
|
||||
import {APPROVAL_AMOUNT_LENDING_POOL, oneEther} from '../helpers/constants';
|
||||
import {convertToCurrencyDecimals} from '../helpers/contracts-helpers';
|
||||
import {makeSuite} from './helpers/make-suite';
|
||||
import {ProtocolErrors, RateMode} from '../helpers/types';
|
||||
|
@ -50,8 +50,8 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
THE_COLLATERAL_CHOSEN_CANNOT_BE_LIQUIDATED,
|
||||
} = ProtocolErrors;
|
||||
|
||||
it('LIQUIDATION - Deposits ETH, borrows DAI', async () => {
|
||||
const {dai, users, pool, oracle} = testEnv;
|
||||
it('LIQUIDATION - Deposits WETH, borrows DAI', async () => {
|
||||
const {dai, weth, users, pool, oracle} = testEnv;
|
||||
const depositor = users[0];
|
||||
const borrower = users[1];
|
||||
|
||||
|
@ -66,9 +66,15 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
|
||||
await pool.connect(depositor.signer).deposit(dai.address, amountDAItoDeposit, '0');
|
||||
//user 2 deposits 1 ETH
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(MOCK_ETH_ADDRESS, '1');
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
||||
|
||||
await pool.connect(borrower.signer).deposit(MOCK_ETH_ADDRESS, amountETHtoDeposit, '0', {
|
||||
//mints WETH to borrower
|
||||
await weth.connect(borrower.signer).mint(await convertToCurrencyDecimals(weth.address, '1000'));
|
||||
|
||||
//approve protocol to access the borrower wallet
|
||||
await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool.connect(borrower.signer).deposit(weth.address, amountETHtoDeposit, '0', {
|
||||
value: amountETHtoDeposit,
|
||||
});
|
||||
|
||||
|
@ -98,7 +104,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
});
|
||||
|
||||
it('LIQUIDATION - Drop the health factor below 1', async () => {
|
||||
const {dai, users, pool, oracle} = testEnv;
|
||||
const {dai, weth, users, pool, oracle} = testEnv;
|
||||
const borrower = users[1];
|
||||
|
||||
const daiPrice = await oracle.getAssetPrice(dai.address);
|
||||
|
@ -117,7 +123,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
});
|
||||
|
||||
it('LIQUIDATION - Liquidates the borrow', async () => {
|
||||
const {dai, users, pool, oracle} = testEnv;
|
||||
const {dai, weth, users, pool, oracle} = testEnv;
|
||||
const liquidator = users[3];
|
||||
const borrower = users[1];
|
||||
|
||||
|
@ -128,7 +134,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
await dai.connect(liquidator.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
const daiReserveDataBefore: any = await pool.getReserveData(dai.address);
|
||||
const ethReserveDataBefore: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataBefore: any = await pool.getReserveData(weth.address);
|
||||
|
||||
const userReserveDataBefore: any = await getUserData(pool, dai.address, borrower.address);
|
||||
|
||||
|
@ -138,18 +144,18 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
|
||||
const tx = await pool
|
||||
.connect(liquidator.signer)
|
||||
.liquidationCall(MOCK_ETH_ADDRESS, dai.address, borrower.address, amountToLiquidate, false);
|
||||
.liquidationCall(weth.address, dai.address, borrower.address, amountToLiquidate, false);
|
||||
|
||||
const userReserveDataAfter: any = await getUserData(pool, dai.address, borrower.address);
|
||||
|
||||
const daiReserveDataAfter: any = await pool.getReserveData(dai.address);
|
||||
const ethReserveDataAfter: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataAfter: any = await pool.getReserveData(weth.address);
|
||||
|
||||
const collateralPrice = await oracle.getAssetPrice(MOCK_ETH_ADDRESS);
|
||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||
const principalPrice = await oracle.getAssetPrice(dai.address);
|
||||
|
||||
const collateralDecimals = (
|
||||
await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS)
|
||||
await pool.getReserveConfigurationData(weth.address)
|
||||
).decimals.toString();
|
||||
const principalDecimals = (
|
||||
await pool.getReserveConfigurationData(dai.address)
|
||||
|
@ -207,8 +213,8 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
);
|
||||
});
|
||||
|
||||
it('User 3 deposits 1000 USDC, user 4 1 ETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||
const {usdc, users, pool, oracle, addressesProvider} = testEnv;
|
||||
it('User 3 deposits 1000 USDC, user 4 1 WETH, user 4 borrows - drops HF, liquidates the borrow', async () => {
|
||||
const {usdc, users, pool, oracle, weth} = testEnv;
|
||||
|
||||
const depositor = users[3];
|
||||
const borrower = users[4];
|
||||
|
@ -228,9 +234,15 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
await pool.connect(depositor.signer).deposit(usdc.address, amountUSDCtoDeposit, '0');
|
||||
|
||||
//borrower deposits 1 ETH
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(MOCK_ETH_ADDRESS, '1');
|
||||
const amountETHtoDeposit = await convertToCurrencyDecimals(weth.address, '1');
|
||||
|
||||
await pool.connect(borrower.signer).deposit(MOCK_ETH_ADDRESS, amountETHtoDeposit, '0', {
|
||||
//mints WETH to borrower
|
||||
await weth.connect(borrower.signer).mint(await convertToCurrencyDecimals(weth.address, '1000'));
|
||||
|
||||
//approve protocol to access the borrower wallet
|
||||
await weth.connect(borrower.signer).approve(pool.address, APPROVAL_AMOUNT_LENDING_POOL);
|
||||
|
||||
await pool.connect(borrower.signer).deposit(weth.address, amountETHtoDeposit, '0', {
|
||||
value: amountETHtoDeposit,
|
||||
});
|
||||
|
||||
|
@ -272,7 +284,7 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
);
|
||||
|
||||
const usdcReserveDataBefore: any = await pool.getReserveData(usdc.address);
|
||||
const ethReserveDataBefore: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataBefore: any = await pool.getReserveData(weth.address);
|
||||
|
||||
const amountToLiquidate = new BigNumber(userReserveDataBefore.currentStableDebt)
|
||||
.div(2)
|
||||
|
@ -281,20 +293,20 @@ makeSuite('LendingPool liquidation - liquidator receiving the underlying asset',
|
|||
|
||||
await pool
|
||||
.connect(liquidator.signer)
|
||||
.liquidationCall(MOCK_ETH_ADDRESS, usdc.address, borrower.address, amountToLiquidate, false);
|
||||
.liquidationCall(weth.address, usdc.address, borrower.address, amountToLiquidate, false);
|
||||
|
||||
const userReserveDataAfter: any = await pool.getUserReserveData(usdc.address, borrower.address);
|
||||
|
||||
const userGlobalDataAfter: any = await pool.getUserAccountData(borrower.address);
|
||||
|
||||
const usdcReserveDataAfter: any = await pool.getReserveData(usdc.address);
|
||||
const ethReserveDataAfter: any = await pool.getReserveData(MOCK_ETH_ADDRESS);
|
||||
const ethReserveDataAfter: any = await pool.getReserveData(weth.address);
|
||||
|
||||
const collateralPrice = await oracle.getAssetPrice(MOCK_ETH_ADDRESS);
|
||||
const collateralPrice = await oracle.getAssetPrice(weth.address);
|
||||
const principalPrice = await oracle.getAssetPrice(usdc.address);
|
||||
|
||||
const collateralDecimals = (
|
||||
await pool.getReserveConfigurationData(MOCK_ETH_ADDRESS)
|
||||
await pool.getReserveConfigurationData(weth.address)
|
||||
).decimals.toString();
|
||||
const principalDecimals = (
|
||||
await pool.getReserveConfigurationData(usdc.address)
|
||||
|
|
|
@ -4,7 +4,7 @@ import {configuration as calculationsConfiguration} from './helpers/utils/calcul
|
|||
import fs from 'fs';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import {makeSuite} from './helpers/make-suite';
|
||||
import {MOCK_ETH_ADDRESS, getReservesConfigByPool} from '../helpers/constants';
|
||||
import {getReservesConfigByPool} from '../helpers/constants';
|
||||
import {AavePools, iAavePoolAssets, IReserveParams} from '../helpers/types';
|
||||
import {executeStory} from './helpers/scenario-engine';
|
||||
|
||||
|
@ -26,7 +26,6 @@ fs.readdirSync(scenarioFolder).forEach((file) => {
|
|||
calculationsConfiguration.reservesParams = <iAavePoolAssets<IReserveParams>>(
|
||||
getReservesConfigByPool(AavePools.proto)
|
||||
);
|
||||
calculationsConfiguration.ethereumAddress = MOCK_ETH_ADDRESS;
|
||||
});
|
||||
|
||||
for (const story of scenario.stories) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user