mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge remote-tracking branch 'origin/master' into feat/74
# Conflicts: # contracts/interfaces/ILendingPool.sol # contracts/lendingpool/LendingPool.sol # test/flashloan.spec.ts
This commit is contained in:
commit
e0660bda7b
|
@ -9,9 +9,9 @@ pragma solidity ^0.6.8;
|
|||
**/
|
||||
interface IFlashLoanReceiver {
|
||||
function executeOperation(
|
||||
address reserve,
|
||||
uint256 amount,
|
||||
uint256 fee,
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata premiums,
|
||||
bytes calldata params
|
||||
) external returns (bool);
|
||||
}
|
||||
|
|
|
@ -99,16 +99,17 @@ interface ILendingPool {
|
|||
/**
|
||||
* @dev emitted when a flashloan is executed
|
||||
* @param target the address of the flashLoanReceiver
|
||||
* @param reserve the address of the reserve
|
||||
* @param amount the amount requested
|
||||
* @param totalPremium the total fee on the amount
|
||||
* @param assets the address of the assets being flashborrowed
|
||||
* @param amounts the amount requested
|
||||
* @param premiums the total fee on the amount
|
||||
* @param referralCode the referral code of the caller
|
||||
**/
|
||||
event FlashLoan(
|
||||
address indexed target,
|
||||
address indexed reserve,
|
||||
uint256 amount,
|
||||
uint256 totalPremium,
|
||||
uint256 mode,
|
||||
address[] assets,
|
||||
uint256[] amounts,
|
||||
uint256[] premiums,
|
||||
uint16 referralCode
|
||||
);
|
||||
/**
|
||||
|
@ -264,16 +265,17 @@ interface ILendingPool {
|
|||
* as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
|
||||
* that must be kept into consideration. For further details please visit https://developers.aave.com
|
||||
* @param receiver The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
|
||||
* @param reserve the address of the principal reserve
|
||||
* @param amount the amount requested for this flashloan
|
||||
* @param assets the address of the principal reserve
|
||||
* @param amounts the amount requested for this flashloan
|
||||
* @param mode the flashloan mode
|
||||
* @param params a bytes array to be sent to the flashloan executor
|
||||
* @param referralCode the referral code of the caller
|
||||
**/
|
||||
function flashLoan(
|
||||
address receiver,
|
||||
address reserve,
|
||||
uint256 amount,
|
||||
uint256 debtType,
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256 mode,
|
||||
address onBehalfOf,
|
||||
bytes calldata params,
|
||||
uint16 referralCode
|
||||
|
|
|
@ -262,15 +262,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
|
||||
|
||||
//default to max amount
|
||||
uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
if (amount < paybackAmount) {
|
||||
paybackAmount = amount;
|
||||
}
|
||||
|
||||
ValidationLogic.validateRepay(
|
||||
reserve,
|
||||
amount,
|
||||
|
@ -280,6 +271,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
variableDebt
|
||||
);
|
||||
|
||||
//default to max amount
|
||||
uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
if (amount < paybackAmount) {
|
||||
paybackAmount = amount;
|
||||
}
|
||||
|
||||
reserve.updateState();
|
||||
|
||||
//burns an equivalent amount of debt tokens
|
||||
|
@ -356,9 +356,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev rebalances the stable interest rate of a user if current liquidity rate > user stable rate.
|
||||
* this is regulated by Aave to ensure that the protocol is not abused, and the user is paying a fair
|
||||
* rate. Anyone can call this function.
|
||||
* @dev rebalances the stable interest rate of a user. Users can be rebalanced if the following conditions are satisfied:
|
||||
* 1. Usage ratio is above 95%
|
||||
* 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been
|
||||
* borrowed at a stable rate and depositors are not earning enough.
|
||||
* @param asset the address of the reserve
|
||||
* @param user the address of the user to be rebalanced
|
||||
**/
|
||||
|
@ -373,7 +374,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
uint256 stableBorrowBalance = IERC20(stableDebtToken).balanceOf(user);
|
||||
|
||||
//if the utilization rate is below 95%, no rebalances are needed
|
||||
//if the usage ratio is below 95%, no rebalances are needed
|
||||
uint256 totalBorrows = stableDebtToken
|
||||
.totalSupply()
|
||||
.add(variableDebtToken.totalSupply())
|
||||
|
@ -417,7 +418,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
/**
|
||||
* @dev allows depositors to enable or disable a specific deposit as collateral.
|
||||
* @param asset the address of the reserve
|
||||
* @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
|
||||
* @param useAsCollateral true if the user wants to use the deposit as collateral, false otherwise.
|
||||
**/
|
||||
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external override {
|
||||
_whenNotPaused();
|
||||
|
@ -483,11 +484,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
struct FlashLoanLocalVars {
|
||||
uint256 premium;
|
||||
uint256 amountPlusPremium;
|
||||
IFlashLoanReceiver receiver;
|
||||
address aTokenAddress;
|
||||
address oracle;
|
||||
ReserveLogic.InterestRateMode debtMode;
|
||||
uint256 i;
|
||||
address currentAsset;
|
||||
address currentATokenAddress;
|
||||
uint256 currentAmount;
|
||||
uint256 currentPremium;
|
||||
uint256 currentAmountPlusPremium;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -495,8 +500,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
* as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts
|
||||
* that must be kept into consideration. For further details please visit https://developers.aave.com
|
||||
* @param receiverAddress The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface.
|
||||
* @param asset The address of the principal reserve
|
||||
* @param amount The amount requested for this flashloan
|
||||
* @param assets The addresss of the assets being flashborrowed
|
||||
* @param amounts The amounts requested for this flashloan for each asset
|
||||
* @param mode Type of the debt to open if the flash loan is not returned. 0 -> Don't open any debt, just revert, 1 -> stable, 2 -> variable
|
||||
* @param onBehalfOf If mode is not 0, then the address to take the debt onBehalfOf. The address must already have approved `msg.sender` to incur the debt on their behalf.
|
||||
* @param params Variadic packed params to pass to the receiver as extra information
|
||||
|
@ -504,61 +509,83 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
**/
|
||||
function flashLoan(
|
||||
address receiverAddress,
|
||||
address asset,
|
||||
uint256 amount,
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256 mode,
|
||||
address onBehalfOf,
|
||||
bytes calldata params,
|
||||
uint16 referralCode
|
||||
) external override {
|
||||
_whenNotPaused();
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
FlashLoanLocalVars memory vars;
|
||||
|
||||
vars.aTokenAddress = reserve.aTokenAddress;
|
||||
ValidationLogic.validateFlashloan(assets, amounts, mode);
|
||||
|
||||
vars.premium = amount.mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
|
||||
|
||||
ValidationLogic.validateFlashloan(mode, vars.premium);
|
||||
|
||||
ReserveLogic.InterestRateMode debtMode = ReserveLogic.InterestRateMode(mode);
|
||||
address[] memory aTokenAddresses = new address[](assets.length);
|
||||
uint256[] memory premiums = new uint256[](assets.length);
|
||||
|
||||
vars.receiver = IFlashLoanReceiver(receiverAddress);
|
||||
vars.debtMode = ReserveLogic.InterestRateMode(mode);
|
||||
|
||||
//transfer funds to the receiver
|
||||
IAToken(vars.aTokenAddress).transferUnderlyingTo(receiverAddress, amount);
|
||||
for (vars.i = 0; vars.i < assets.length; vars.i++) {
|
||||
aTokenAddresses[vars.i] = _reserves[assets[vars.i]].aTokenAddress;
|
||||
|
||||
premiums[vars.i] = amounts[vars.i].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000);
|
||||
|
||||
//transfer funds to the receiver
|
||||
IAToken(aTokenAddresses[vars.i]).transferUnderlyingTo(receiverAddress, amounts[vars.i]);
|
||||
}
|
||||
|
||||
//execute action of the receiver
|
||||
require(
|
||||
vars.receiver.executeOperation(asset, amount, vars.premium, params),
|
||||
vars.receiver.executeOperation(assets, amounts, premiums, params),
|
||||
Errors.INVALID_FLASH_LOAN_EXECUTOR_RETURN
|
||||
);
|
||||
|
||||
vars.amountPlusPremium = amount.add(vars.premium);
|
||||
for (vars.i = 0; vars.i < assets.length; vars.i++) {
|
||||
vars.currentAsset = assets[vars.i];
|
||||
vars.currentAmount = amounts[vars.i];
|
||||
vars.currentPremium = premiums[vars.i];
|
||||
vars.currentATokenAddress = aTokenAddresses[vars.i];
|
||||
|
||||
if (debtMode == ReserveLogic.InterestRateMode.NONE) {
|
||||
IERC20(asset).safeTransferFrom(receiverAddress, vars.aTokenAddress, vars.amountPlusPremium);
|
||||
vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
|
||||
|
||||
reserve.updateState();
|
||||
reserve.cumulateToLiquidityIndex(IERC20(vars.aTokenAddress).totalSupply(), vars.premium);
|
||||
reserve.updateInterestRates(asset, vars.aTokenAddress, vars.premium, 0);
|
||||
if (vars.debtMode == ReserveLogic.InterestRateMode.NONE) {
|
||||
_reserves[vars.currentAsset].updateState();
|
||||
_reserves[vars.currentAsset].cumulateToLiquidityIndex(
|
||||
IERC20(vars.currentATokenAddress).totalSupply(),
|
||||
vars.currentPremium
|
||||
);
|
||||
_reserves[vars.currentAsset].updateInterestRates(
|
||||
vars.currentAsset,
|
||||
vars.currentATokenAddress,
|
||||
vars.currentPremium,
|
||||
0
|
||||
);
|
||||
|
||||
emit FlashLoan(receiverAddress, asset, amount, vars.premium, referralCode);
|
||||
} else {
|
||||
//if the user didn't choose to return the funds, the system checks if there
|
||||
//is enough collateral and eventually open a position
|
||||
_executeBorrow(
|
||||
ExecuteBorrowParams(
|
||||
asset,
|
||||
msg.sender,
|
||||
onBehalfOf,
|
||||
vars.amountPlusPremium,
|
||||
mode,
|
||||
vars.aTokenAddress,
|
||||
referralCode,
|
||||
false
|
||||
)
|
||||
);
|
||||
IERC20(vars.currentAsset).safeTransferFrom(
|
||||
receiverAddress,
|
||||
vars.currentATokenAddress,
|
||||
vars.currentAmountPlusPremium
|
||||
);
|
||||
} else {
|
||||
//if the user didn't choose to return the funds, the system checks if there
|
||||
//is enough collateral and eventually open a position
|
||||
_executeBorrow(
|
||||
ExecuteBorrowParams(
|
||||
vars.currentAsset,
|
||||
msg.sender,
|
||||
onBehalfOf,
|
||||
vars.currentAmount,
|
||||
mode,
|
||||
vars.currentATokenAddress,
|
||||
referralCode,
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
emit FlashLoan(receiverAddress, mode, assets, amounts, premiums, referralCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,13 +194,6 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
|
|||
//update the principal reserve
|
||||
principalReserve.updateState();
|
||||
|
||||
principalReserve.updateInterestRates(
|
||||
principal,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate,
|
||||
0
|
||||
);
|
||||
|
||||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
|
@ -223,6 +216,13 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
|
|||
);
|
||||
}
|
||||
|
||||
principalReserve.updateInterestRates(
|
||||
principal,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate,
|
||||
0
|
||||
);
|
||||
|
||||
//if liquidator reclaims the aToken, he receives the equivalent atoken amount
|
||||
if (receiveAToken) {
|
||||
vars.collateralAtoken.transferOnLiquidation(user, msg.sender, vars.maxCollateralToLiquidate);
|
||||
|
@ -306,8 +306,8 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
|
|||
.principalCurrencyPrice
|
||||
.mul(purchaseAmount)
|
||||
.mul(10**vars.collateralDecimals)
|
||||
.div(vars.collateralPrice.mul(10**vars.principalDecimals))
|
||||
.percentMul(vars.liquidationBonus);
|
||||
.percentMul(vars.liquidationBonus)
|
||||
.div(vars.collateralPrice.mul(10**vars.principalDecimals));
|
||||
|
||||
if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) {
|
||||
collateralAmount = userCollateralBalance;
|
||||
|
|
|
@ -45,6 +45,7 @@ library Errors {
|
|||
string public constant INVALID_EQUAL_ASSETS_TO_SWAP = '56';
|
||||
string public constant NO_MORE_RESERVES_ALLOWED = '59';
|
||||
string public constant INVALID_FLASH_LOAN_EXECUTOR_RETURN = '60';
|
||||
string public constant INCONSISTENT_FLASHLOAN_PARAMS = '69';
|
||||
|
||||
// require error messages - aToken - DebtTokens
|
||||
string public constant CALLER_MUST_BE_LENDING_POOL = '28'; // 'The caller of this function must be a lending pool'
|
||||
|
|
|
@ -25,7 +25,6 @@ library GenericLogic {
|
|||
using UserConfiguration for UserConfiguration.Map;
|
||||
|
||||
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
|
||||
uint256 public constant HEALTH_FACTOR_CRITICAL_THRESHOLD = 0.98 ether;
|
||||
|
||||
struct balanceDecreaseAllowedLocalVars {
|
||||
uint256 decimals;
|
||||
|
|
|
@ -327,11 +327,16 @@ library ValidationLogic {
|
|||
/**
|
||||
* @dev validates a flashloan action
|
||||
* @param mode the flashloan mode (0 = classic flashloan, 1 = open a stable rate loan, 2 = open a variable rate loan)
|
||||
* @param premium the premium paid on the flashloan
|
||||
* @param assets the assets being flashborrowed
|
||||
* @param amounts the amounts for each asset being borrowed
|
||||
**/
|
||||
function validateFlashloan(uint256 mode, uint256 premium) internal pure {
|
||||
require(premium > 0, Errors.REQUESTED_AMOUNT_TOO_SMALL);
|
||||
function validateFlashloan(
|
||||
address[] memory assets,
|
||||
uint256[] memory amounts,
|
||||
uint256 mode
|
||||
) internal pure {
|
||||
require(mode <= uint256(ReserveLogic.InterestRateMode.VARIABLE), Errors.INVALID_FLASHLOAN_MODE);
|
||||
require(assets.length == amounts.length, Errors.INCONSISTENT_FLASHLOAN_PARAMS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,8 +14,8 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
|||
|
||||
ILendingPoolAddressesProvider internal _provider;
|
||||
|
||||
event ExecutedWithFail(address _reserve, uint256 _amount, uint256 _fee);
|
||||
event ExecutedWithSuccess(address _reserve, uint256 _amount, uint256 _fee);
|
||||
event ExecutedWithFail(address[] _assets, uint256[] _amounts, uint256[] _premiums);
|
||||
event ExecutedWithSuccess(address[] _assets, uint256[] _amounts, uint256[] _premiums);
|
||||
|
||||
bool _failExecution;
|
||||
uint256 _amountToApprove;
|
||||
|
@ -44,33 +44,40 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
|
|||
}
|
||||
|
||||
function executeOperation(
|
||||
address reserve,
|
||||
uint256 amount,
|
||||
uint256 fee,
|
||||
address[] memory assets,
|
||||
uint256[] memory amounts,
|
||||
uint256[] memory premiums,
|
||||
bytes memory params
|
||||
) public override returns (bool) {
|
||||
params;
|
||||
//mint to this contract the specific amount
|
||||
MintableERC20 token = MintableERC20(reserve);
|
||||
|
||||
//check the contract has the specified balance
|
||||
require(amount <= IERC20(reserve).balanceOf(address(this)), 'Invalid balance for the contract');
|
||||
|
||||
uint256 amountToReturn = (_amountToApprove != 0) ? _amountToApprove : amount.add(fee);
|
||||
|
||||
if (_failExecution) {
|
||||
emit ExecutedWithFail(reserve, amount, fee);
|
||||
emit ExecutedWithFail(assets, amounts, premiums);
|
||||
return !_simulateEOA;
|
||||
}
|
||||
|
||||
//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
|
||||
for (uint256 i = 0; i < assets.length; i++) {
|
||||
//mint to this contract the specific amount
|
||||
MintableERC20 token = MintableERC20(assets[i]);
|
||||
|
||||
token.mint(fee);
|
||||
//check the contract has the specified balance
|
||||
require(
|
||||
amounts[i] <= IERC20(assets[i]).balanceOf(address(this)),
|
||||
'Invalid balance for the contract'
|
||||
);
|
||||
|
||||
IERC20(reserve).approve(_addressesProvider.getLendingPool(), amountToReturn);
|
||||
uint256 amountToReturn = (_amountToApprove != 0)
|
||||
? _amountToApprove
|
||||
: amounts[i].add(premiums[i]);
|
||||
//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
|
||||
|
||||
emit ExecutedWithSuccess(reserve, amount, fee);
|
||||
token.mint(premiums[i]);
|
||||
|
||||
IERC20(assets[i]).approve(_addressesProvider.getLendingPool(), amountToReturn);
|
||||
}
|
||||
|
||||
emit ExecutedWithSuccess(assets, amounts, premiums);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -196,8 +196,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
/**
|
||||
* @dev Calculates the increase in balance since the last user interaction
|
||||
* @param user The address of the user for which the interest is being accumulated
|
||||
* @return The previous principal balance, the new principal balance, the balance increase
|
||||
* and the new user index
|
||||
* @return The previous principal balance, the new principal balance and the balance increase
|
||||
**/
|
||||
function _calculateBalanceIncrease(address user)
|
||||
internal
|
||||
|
|
|
@ -235,7 +235,7 @@
|
|||
},
|
||||
"WalletBalanceProvider": {
|
||||
"buidlerevm": {
|
||||
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4",
|
||||
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10",
|
||||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
},
|
||||
"localhost": {
|
||||
|
@ -694,17 +694,6 @@
|
|||
"deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6"
|
||||
}
|
||||
},
|
||||
"MockSwapAdapter": {
|
||||
"buidlerevm": {
|
||||
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
|
||||
},
|
||||
"coverage": {
|
||||
"address": "0xBEF0d4b9c089a5883741fC14cbA352055f35DDA2"
|
||||
},
|
||||
"localhost": {
|
||||
"address": "0x48FAde2E719B770E1783d03466dAEe98b5183538"
|
||||
}
|
||||
},
|
||||
"MockFlashRepayAdapter": {
|
||||
"buidlerevm": {
|
||||
"address": "0xDf73fC454FA018051D4a1509e63D11530A59DE10"
|
||||
|
@ -715,4 +704,4 @@
|
|||
"address": "0x2cfcA5785261fbC88EFFDd46fCFc04c22525F9e4"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -47,7 +47,6 @@ const {
|
|||
|
||||
export type MockTokenMap = {[symbol: string]: MintableERC20};
|
||||
import {ZERO_ADDRESS} from './constants';
|
||||
import {MockSwapAdapter} from '../types/MockSwapAdapter';
|
||||
import {signTypedData_v4, TypedData} from 'eth-sig-util';
|
||||
import {fromRpcSig, ECDSASignature} from 'ethereumjs-util';
|
||||
import {SignerWithAddress} from '../test/helpers/make-suite';
|
||||
|
@ -322,8 +321,6 @@ export const deployWalletBalancerProvider = async (
|
|||
}
|
||||
return instance;
|
||||
};
|
||||
export const deployMockSwapAdapter = async (addressesProvider: tEthereumAddress) =>
|
||||
await deployContract<MockSwapAdapter>(eContractid.MockSwapAdapter, [addressesProvider]);
|
||||
|
||||
export const deployAaveProtocolTestHelpers = async (
|
||||
addressesProvider: tEthereumAddress,
|
||||
|
@ -549,14 +546,6 @@ export const getMockFlashLoanReceiver = async (address?: tEthereumAddress) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const getMockSwapAdapter = async (address?: tEthereumAddress) => {
|
||||
return await getContract<MockSwapAdapter>(
|
||||
eContractid.MockSwapAdapter,
|
||||
address ||
|
||||
(await getDb().get(`${eContractid.MockSwapAdapter}.${BRE.network.name}`).value()).address
|
||||
);
|
||||
};
|
||||
|
||||
export const getLendingRateOracle = async (address?: tEthereumAddress) => {
|
||||
return await getContract<LendingRateOracle>(
|
||||
eContractid.LendingRateOracle,
|
||||
|
|
|
@ -44,7 +44,6 @@ export enum eContractid {
|
|||
LendingPoolCollateralManager = 'LendingPoolCollateralManager',
|
||||
InitializableAdminUpgradeabilityProxy = 'InitializableAdminUpgradeabilityProxy',
|
||||
MockFlashLoanReceiver = 'MockFlashLoanReceiver',
|
||||
MockSwapAdapter = 'MockSwapAdapter',
|
||||
WalletBalanceProvider = 'WalletBalanceProvider',
|
||||
AToken = 'AToken',
|
||||
MockAToken = 'MockAToken',
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
registerContractInJsonDb,
|
||||
getPairsTokenAggregator,
|
||||
initReserves,
|
||||
deployMockSwapAdapter,
|
||||
deployLendingRateOracle,
|
||||
} from '../helpers/contracts-helpers';
|
||||
import {Signer} from 'ethers';
|
||||
|
@ -239,9 +238,6 @@ const buildTestEnv = async (deployer: Signer, secondaryWallet: Signer) => {
|
|||
const mockFlashLoanReceiver = await deployMockFlashLoanReceiver(addressesProvider.address);
|
||||
await insertContractAddressInDb(eContractid.MockFlashLoanReceiver, mockFlashLoanReceiver.address);
|
||||
|
||||
const mockSwapAdapter = await deployMockSwapAdapter(addressesProvider.address);
|
||||
await insertContractAddressInDb(eContractid.MockSwapAdapter, mockSwapAdapter.address);
|
||||
|
||||
await deployWalletBalancerProvider(addressesProvider.address);
|
||||
|
||||
console.timeEnd('setup');
|
||||
|
|
|
@ -48,8 +48,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
await pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
[weth.address],
|
||||
[ethers.utils.parseEther('0.8')],
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -78,8 +78,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
const reserveDataBefore = await helpersContract.getReserveData(weth.address);
|
||||
const txResult = await pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
'1000720000000000000',
|
||||
[weth.address],
|
||||
['1000720000000000000'],
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -110,8 +110,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
[weth.address],
|
||||
[ethers.utils.parseEther('0.8')],
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -131,8 +131,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
[weth.address],
|
||||
[ethers.utils.parseEther('0.8')],
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -152,8 +152,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
[weth.address],
|
||||
[ethers.utils.parseEther('0.8')],
|
||||
4,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -181,8 +181,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
ethers.utils.parseEther('0.8'),
|
||||
[weth.address],
|
||||
[ethers.utils.parseEther('0.8')],
|
||||
2,
|
||||
caller.address,
|
||||
'0x10',
|
||||
|
@ -199,24 +199,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
const callerDebt = await wethDebtToken.balanceOf(caller.address);
|
||||
|
||||
expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
|
||||
});
|
||||
|
||||
it('tries to take a very small flashloan, which would result in 0 fees (revert expected)', async () => {
|
||||
const {pool, weth, users} = testEnv;
|
||||
const caller = users[1];
|
||||
|
||||
await expect(
|
||||
pool.connect(caller.signer).flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
'1', //1 wei loan
|
||||
2,
|
||||
caller.address,
|
||||
'0x10',
|
||||
'0'
|
||||
)
|
||||
).to.be.revertedWith(REQUESTED_AMOUNT_TOO_SMALL);
|
||||
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
|
||||
});
|
||||
|
||||
it('tries to take a flashloan that is bigger than the available liquidity (revert expected)', async () => {
|
||||
|
@ -226,8 +209,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
await expect(
|
||||
pool.connect(caller.signer).flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
'1004415000000000000', //slightly higher than the available liquidity
|
||||
[weth.address],
|
||||
['1004415000000000000'], //slightly higher than the available liquidity
|
||||
2,
|
||||
caller.address,
|
||||
'0x10',
|
||||
|
@ -242,17 +225,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
const caller = users[1];
|
||||
|
||||
await expect(
|
||||
pool
|
||||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
deployer.address,
|
||||
weth.address,
|
||||
'1000000000000000000',
|
||||
2,
|
||||
caller.address,
|
||||
'0x10',
|
||||
'0'
|
||||
)
|
||||
pool.flashLoan(deployer.address, [weth.address], ['1000000000000000000'], 2, caller.address, '0x10', '0')
|
||||
).to.be.reverted;
|
||||
});
|
||||
|
||||
|
@ -278,8 +251,8 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
await pool.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
usdc.address,
|
||||
flashloanAmount,
|
||||
[usdc.address],
|
||||
[flashloanAmount],
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
|
@ -321,9 +294,9 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
usdc.address,
|
||||
flashloanAmount,
|
||||
0,
|
||||
[usdc.address],
|
||||
[flashloanAmount],
|
||||
2,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
'0'
|
||||
|
@ -350,15 +323,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
await pool
|
||||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
usdc.address,
|
||||
flashloanAmount,
|
||||
2,
|
||||
caller.signer,
|
||||
'0x10',
|
||||
'0'
|
||||
);
|
||||
.flashLoan(_mockFlashLoanReceiver.address, [usdc.address], [flashloanAmount], 2, caller.address, '0x10', '0');
|
||||
const {variableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(
|
||||
usdc.address
|
||||
);
|
||||
|
@ -370,7 +335,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
const callerDebt = await usdcDebtToken.balanceOf(caller.address);
|
||||
|
||||
expect(callerDebt.toString()).to.be.equal('500450000', 'Invalid user debt');
|
||||
expect(callerDebt.toString()).to.be.equal('500000000', 'Invalid user debt');
|
||||
});
|
||||
|
||||
it('Caller deposits 1000 DAI as collateral, Takes a WETH flashloan with mode = 0, does not approve the transfer of the funds', async () => {
|
||||
|
@ -393,15 +358,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
await expect(
|
||||
pool
|
||||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
flashAmount,
|
||||
0,
|
||||
_mockFlashLoanReceiver.address,
|
||||
'0x10',
|
||||
'0'
|
||||
)
|
||||
.flashLoan(_mockFlashLoanReceiver.address, [weth.address], [flashAmount], 0, _mockFlashLoanReceiver.address, '0x10', '0')
|
||||
).to.be.revertedWith(SAFEERC20_LOWLEVEL_CALL);
|
||||
});
|
||||
|
||||
|
@ -416,15 +373,7 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
await pool
|
||||
.connect(caller.signer)
|
||||
.flashLoan(
|
||||
_mockFlashLoanReceiver.address,
|
||||
weth.address,
|
||||
flashAmount,
|
||||
1,
|
||||
caller.signer,
|
||||
'0x10',
|
||||
'0'
|
||||
);
|
||||
.flashLoan(_mockFlashLoanReceiver.address, [weth.address], [flashAmount], 1, caller.address, '0x10', '0');
|
||||
|
||||
const {stableDebtTokenAddress} = await helpersContract.getReserveTokensAddresses(weth.address);
|
||||
|
||||
|
@ -435,6 +384,6 @@ makeSuite('LendingPool FlashLoan function', (testEnv: TestEnv) => {
|
|||
|
||||
const callerDebt = await wethDebtToken.balanceOf(caller.address);
|
||||
|
||||
expect(callerDebt.toString()).to.be.equal('800720000000000000', 'Invalid user debt');
|
||||
expect(callerDebt.toString()).to.be.equal('800000000000000000', 'Invalid user debt');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
getMintableErc20,
|
||||
getLendingPoolConfiguratorProxy,
|
||||
getPriceOracle,
|
||||
getMockSwapAdapter,
|
||||
getLendingPoolAddressesProviderRegistry,
|
||||
} from '../../helpers/contracts-helpers';
|
||||
import {tEthereumAddress} from '../../helpers/types';
|
||||
|
@ -25,7 +24,6 @@ import bignumberChai from 'chai-bignumber';
|
|||
import {almostEqual} from './almost-equal';
|
||||
import {PriceOracle} from '../../types/PriceOracle';
|
||||
import {LendingPoolAddressesProvider} from '../../types/LendingPoolAddressesProvider';
|
||||
import {MockSwapAdapter} from '../../types/MockSwapAdapter';
|
||||
import {LendingPoolAddressesProviderRegistry} from '../../types/LendingPoolAddressesProviderRegistry';
|
||||
chai.use(bignumberChai());
|
||||
chai.use(almostEqual());
|
||||
|
@ -48,7 +46,6 @@ export interface TestEnv {
|
|||
usdc: MintableERC20;
|
||||
lend: MintableERC20;
|
||||
addressesProvider: LendingPoolAddressesProvider;
|
||||
mockSwapAdapter: MockSwapAdapter;
|
||||
registry: LendingPoolAddressesProviderRegistry;
|
||||
}
|
||||
|
||||
|
@ -73,7 +70,6 @@ const testEnv: TestEnv = {
|
|||
usdc: {} as MintableERC20,
|
||||
lend: {} as MintableERC20,
|
||||
addressesProvider: {} as LendingPoolAddressesProvider,
|
||||
mockSwapAdapter: {} as MockSwapAdapter,
|
||||
registry: {} as LendingPoolAddressesProviderRegistry,
|
||||
} as TestEnv;
|
||||
|
||||
|
@ -134,8 +130,6 @@ export async function initializeMakeSuite() {
|
|||
testEnv.usdc = await getMintableErc20(usdcAddress);
|
||||
testEnv.lend = await getMintableErc20(lendAddress);
|
||||
testEnv.weth = await getMintableErc20(wethAddress);
|
||||
|
||||
testEnv.mockSwapAdapter = await getMockSwapAdapter();
|
||||
}
|
||||
|
||||
export function makeSuite(name: string, tests: (testEnv: TestEnv) => void) {
|
||||
|
|
|
@ -186,7 +186,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
|
|||
await expect(
|
||||
pool
|
||||
.connect(caller.signer)
|
||||
.flashLoan(_mockFlashLoanReceiver.address, weth.address, flashAmount, 1, '0x10', '0')
|
||||
.flashLoan(_mockFlashLoanReceiver.address, [weth.address], [flashAmount], 1, '0x10', '0')
|
||||
).revertedWith(IS_PAUSED);
|
||||
|
||||
// Unpause pool
|
||||
|
@ -275,7 +275,7 @@ makeSuite('Pausable Pool', (testEnv: TestEnv) => {
|
|||
});
|
||||
|
||||
it('SwapBorrowRateMode', async () => {
|
||||
const {pool, weth, dai, usdc, users, configurator, mockSwapAdapter} = testEnv;
|
||||
const {pool, weth, dai, usdc, users, configurator} = testEnv;
|
||||
const user = users[1];
|
||||
const amountWETHToDeposit = parseEther('10');
|
||||
const amountDAIToDeposit = parseEther('120');
|
||||
|
|
Loading…
Reference in New Issue
Block a user