- Improved docs on LendingPool and interface

This commit is contained in:
eboado 2020-11-23 10:58:04 +01:00
parent 0c6ec03cec
commit f98335cb68
5 changed files with 355 additions and 298 deletions

View File

@ -1,20 +1,20 @@
// SPDX-License-Identifier: agpl-3.0 // SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.6.8; pragma solidity ^0.6.8;
pragma experimental ABIEncoderV2;
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol'; import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol'; import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol'; import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
pragma experimental ABIEncoderV2;
interface ILendingPool { interface ILendingPool {
/** /**
* @dev emitted on deposit * @dev Emitted on deposit()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user * @param user The address initiating the deposit
* @param amount the amount to be deposited * @param onBehalfOf The beneficiary of the deposit, receiving the aTokens
* @param referral the referral number of the action * @param amount The amount deposited
* @param referral The referral code used
**/ **/
event Deposit( event Deposit(
address indexed reserve, address indexed reserve,
@ -25,22 +25,24 @@ interface ILendingPool {
); );
/** /**
* @dev emitted during a withdraw action. * @dev Emitted on withdraw()
* @param reserve the address of the reserve * @param reserve The address of the underlyng asset being withdrawn
* @param user the address of the user * @param user The address initiating the withdrawal, owner of aTokens
* @param to address that will receive the underlying * @param to Address that will receive the underlying
* @param amount the amount to be withdrawn * @param amount The amount to be withdrawn
**/ **/
event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount); event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);
/** /**
* @dev emitted on borrow * @dev Emitted on borrow() and flashLoan() when debt needs to be opened
* @param reserve the address of the reserve * @param reserve The address of the underlying asset being borrowed
* @param user the address of the user * @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
* @param amount the amount to be deposited * initiator of the transaction on flashLoan()
* @param borrowRateMode the rate mode, can be either 1-stable or 2-variable * @param onBehalfOf The address that will be getting the debt
* @param borrowRate the rate at which the user has borrowed * @param amount The amount borrowed out
* @param referral the referral number of the action * @param borrowRateMode The rate mode: 1 for Stable, 2 for Variable
* @param borrowRate The numeric rate at which the user has borrowed
* @param referral The referral code used
**/ **/
event Borrow( event Borrow(
address indexed reserve, address indexed reserve,
@ -51,12 +53,13 @@ interface ILendingPool {
uint256 borrowRate, uint256 borrowRate,
uint16 indexed referral uint16 indexed referral
); );
/** /**
* @dev emitted on repay * @dev Emitted on repay()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user for which the repay has been executed * @param user The beneficiary of the repayment, getting his debt reduced
* @param repayer the address of the user that has performed the repay action * @param repayer The address of the user initiating the repay(), providing the funds
* @param amount the amount repaid * @param amount The amount repaid
**/ **/
event Repay( event Repay(
address indexed reserve, address indexed reserve,
@ -64,41 +67,44 @@ interface ILendingPool {
address indexed repayer, address indexed repayer,
uint256 amount uint256 amount
); );
/** /**
* @dev emitted when a user performs a rate swap * @dev Emitted on swapBorrowRateMode()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user executing the swap * @param user The address of the user swapping his rate mode
* @param rateMode The rate mode that the user wants to swap to
**/ **/
event Swap(address indexed reserve, address indexed user, uint256 rateMode); event Swap(address indexed reserve, address indexed user, uint256 rateMode);
/** /**
* @dev emitted when a user enables a reserve as collateral * @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user * @param user The address of the user enabling the usage as collateral
**/ **/
event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user); event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);
/** /**
* @dev emitted when a user disables a reserve as collateral * @dev Emitted on setUserUseReserveAsCollateral()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user * @param user The address of the user enabling the usage as collateral
**/ **/
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user); event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
/** /**
* @dev emitted when the stable rate of a user gets rebalanced * @dev Emitted on rebalanceStableBorrowRate()
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param user the address of the user for which the rebalance has been executed * @param user The address of the user for which the rebalance has been executed
**/ **/
event RebalanceStableBorrowRate(address indexed reserve, address indexed user); event RebalanceStableBorrowRate(address indexed reserve, address indexed user);
/** /**
* @dev emitted when a flashloan is executed * @dev Emitted on flashLoan()
* @param target the address of the flashLoanReceiver * @param target The address of the flash loan receiver contract
* @param initiator the address initiating the flash loan * @param initiator The address initiating the flash loan
* @param asset the address of the asset being flashborrowed * @param asset The address of the asset being flash borrowed
* @param amount the amount requested * @param amount The amount flash borrowed
* @param premium the total fee on the amount * @param premium The fee flash borrowed
* @param referralCode the referral code of the caller * @param referralCode The referral code used
**/ **/
event FlashLoan( event FlashLoan(
address indexed target, address indexed target,
@ -120,23 +126,23 @@ interface ILendingPool {
event Unpaused(); event Unpaused();
/** /**
* @dev emitted when a borrower is liquidated. Thos evemt is emitted directly by the LendingPool * @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via
* but it's declared here as the LendingPoolCollateralManager * LendingPoolCollateral manager using a DELEGATECALL
* is executed using a delegateCall().
* This allows to have the events in the generated ABI for LendingPool. * This allows to have the events in the generated ABI for LendingPool.
* @param collateral the address of the collateral being liquidated * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param principal the address of the reserve * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param user the address of the user being liquidated * @param user The address of the borrower getting liquidated
* @param purchaseAmount the total amount liquidated * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param liquidatedCollateralAmount the amount of collateral being liquidated * @param liquidatedCollateralAmount The amount of collateral received by the liiquidator
* @param liquidator the address of the liquidator * @param liquidator The address of the liquidator
* @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise * @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
**/ **/
event LiquidationCall( event LiquidationCall(
address indexed collateral, address indexed collateralAsset,
address indexed principal, address indexed debtAsset,
address indexed user, address indexed user,
uint256 purchaseAmount, uint256 debtToCover,
uint256 liquidatedCollateralAmount, uint256 liquidatedCollateralAmount,
address liquidator, address liquidator,
bool receiveAToken bool receiveAToken
@ -147,12 +153,12 @@ interface ILendingPool {
* in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal, * in the ReserveLogic library and emitted in the updateInterestRates() function. Since the function is internal,
* the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it * the event will actually be fired by the LendingPool contract. The event is therefore replicated here so it
* gets added to the LendingPool ABI * gets added to the LendingPool ABI
* @param reserve the address of the reserve * @param reserve The address of the underlying asset of the reserve
* @param liquidityRate the new liquidity rate * @param liquidityRate The new liquidity rate
* @param stableBorrowRate the new stable borrow rate * @param stableBorrowRate The new stable borrow rate
* @param variableBorrowRate the new variable borrow rate * @param variableBorrowRate The new variable borrow rate
* @param liquidityIndex the new liquidity index * @param liquidityIndex The new liquidity index
* @param variableBorrowIndex the new variable borrow index * @param variableBorrowIndex The new variable borrow index
**/ **/
event ReserveDataUpdated( event ReserveDataUpdated(
address indexed reserve, address indexed reserve,
@ -164,40 +170,56 @@ interface ILendingPool {
); );
/** /**
* @dev deposits The underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens) * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* is minted. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC
* @param reserve the address of the reserve * @param asset The address of the underlying asset to deposit
* @param amount the amount to be deposited * @param amount The amount to be deposited
* @param referralCode integrators are assigned a referral code and can potentially receive rewards. * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/ **/
function deposit( function deposit(
address reserve, address asset,
uint256 amount, uint256 amount,
address onBehalfOf, address onBehalfOf,
uint16 referralCode uint16 referralCode
) external; ) external;
/** /**
* @dev withdraws the assets of user. * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* @param reserve the address of the reserve * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param amount the underlying amount to be redeemed * @param asset The address of the underlying asset to withdraw
* @param to address that will receive the underlying * @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to Address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
**/ **/
function withdraw( function withdraw(
address reserve, address asset,
uint256 amount, uint256 amount,
address to address to
) external; ) external;
/** /**
* @dev Allows users to borrow a specific amount of the reserve currency, provided that the borrower * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already deposited enough collateral. * already deposited enough collateral, or he was given enough allowance by a credit delegator on the
* @param reserve the address of the reserve * corresponding debt token (StableDebtToken or VariableDebtToken)
* @param amount the amount to be borrowed * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* @param interestRateMode the interest rate mode at which the user wants to borrow. Can be 0 (STABLE) or 1 (VARIABLE) * and 100 stable/variable debt tokens, depending on the `interestRateMode`
* @param asset The address of the underlying asset to borrow
* @param amount The amount to be borrowed
* @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance
**/ **/
function borrow( function borrow(
address reserve, address asset,
uint256 amount, uint256 amount,
uint256 interestRateMode, uint256 interestRateMode,
uint16 referralCode, uint16 referralCode,
@ -205,73 +227,86 @@ interface ILendingPool {
) external; ) external;
/** /**
* @notice repays a borrow on the specific reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified). * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* @dev the target user is defined by onBehalfOf. If there is no repayment on behalf of another account, * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
* onBehalfOf must be equal to msg.sender. * @param asset The address of the borrowed underlying asset previously borrowed
* @param reserve the address of the reserve on which the user borrowed * @param amount The amount to repay
* @param amount the amount to repay, or uint256(-1) if the user wants to repay everything * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param onBehalfOf the address for which msg.sender is repaying. * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
**/ **/
function repay( function repay(
address reserve, address asset,
uint256 amount, uint256 amount,
uint256 rateMode, uint256 rateMode,
address onBehalfOf address onBehalfOf
) external; ) external;
/** /**
* @dev borrowers can user this function to swap between stable and variable borrow rate modes. * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
* @param reserve the address of the reserve on which the user borrowed * @param asset The address of the underlying asset borrowed
* @param rateMode the rate mode that the user wants to swap * @param rateMode The rate mode that the user wants to swap to
**/ **/
function swapBorrowRateMode(address reserve, uint256 rateMode) external; function swapBorrowRateMode(address asset, uint256 rateMode) external;
/** /**
* @dev rebalances the stable interest rate of a user if current liquidity rate > user stable rate. * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
* this is regulated by Aave to ensure that the protocol is not abused, and the user is paying a fair * - Users can be rebalanced if the following conditions are satisfied:
* rate. Anyone can call this function. * 1. Usage ratio is above 95%
* @param reserve the address of the reserve * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been
* @param user the address of the user to be rebalanced * borrowed at a stable rate and depositors are not earning enough
* @param asset The address of the underlying asset borrowed
* @param user The address of the user to be rebalanced
**/ **/
function rebalanceStableBorrowRate(address reserve, address user) external; function rebalanceStableBorrowRate(address asset, address user) external;
/** /**
* @dev allows depositors to enable or disable a specific deposit as collateral. * @dev Allows depositors to enable/disable a specific deposited asset as collateral
* @param reserve the address of the reserve * @param asset The address of the underlying asset deposited
* @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 reserve, bool useAsCollateral) external; function setUserUseReserveAsCollateral(address asset, bool useAsCollateral) external;
/** /**
* @dev users can invoke this function to liquidate an undercollateralized position. * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* @param reserve the address of the collateral to liquidated * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* @param reserve the address of the principal reserve * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param user the address of the borrower * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param purchaseAmount the amount of principal that the liquidator wants to repay * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if * @param user The address of the borrower getting liquidated
* he wants to receive the underlying asset directly * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
**/ **/
function liquidationCall( function liquidationCall(
address collateral, address collateralAsset,
address reserve, address debtAsset,
address user, address user,
uint256 purchaseAmount, uint256 debtToCover,
bool receiveAToken bool receiveAToken
) external; ) external;
/** /**
* @dev allows smartcontracts to access the liquidity of the pool within one transaction, * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts * as long as the amount taken plus a fee is returned.
* that must be kept into consideration. For further details please visit https://developers.aave.com * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.
* @param receiver The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface. * For further details please visit https://developers.aave.com
* @param assets the address of the principal reserve * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface
* @param amounts the amount requested for this flashloan * @param assets The addresses of the assets being flash-borrowed
* @param modes the flashloan borrow modes * @param amounts The amounts amounts being flash-borrowed
* @param params a bytes array to be sent to the flashloan executor * @param modes Types of the debt to open if the flash loan is not returned:
* @param referralCode the referral code of the caller * 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2
* @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/ **/
function flashLoan( function flashLoan(
address receiver, address receiverAddress,
address[] calldata assets, address[] calldata assets,
uint256[] calldata amounts, uint256[] calldata amounts,
uint256[] calldata modes, uint256[] calldata modes,
@ -280,24 +315,28 @@ interface ILendingPool {
uint16 referralCode uint16 referralCode
) external; ) external;
/**
* @dev Returns the user account data across all the reserves
* @param user The address of the user
* @return totalCollateralETH the total collateral in ETH of the user
* @return totalDebtETH the total debt in ETH of the user
* @return availableBorrowsETH the borrowing power left of the user
* @return currentLiquidationThreshold the liquidation threshold of the user
* @return ltv the loan to value of the user
* @return healthFactor the current health factor of the user
**/
function getUserAccountData(address user) function getUserAccountData(address user)
external external
view view
returns ( returns (
uint256 totalCollateralETH, uint256 totalCollateralETH,
uint256 totalBorrowsETH, uint256 totalDebtETH,
uint256 availableBorrowsETH, uint256 availableBorrowsETH,
uint256 currentLiquidationThreshold, uint256 currentLiquidationThreshold,
uint256 ltv, uint256 ltv,
uint256 healthFactor uint256 healthFactor
); );
/**
* @dev initializes a reserve
* @param reserve the address of the reserve
* @param aTokenAddress the address of the overlying aToken contract
* @param interestRateStrategyAddress the address of the interest rate strategy contract
**/
function initReserve( function initReserve(
address reserve, address reserve,
address aTokenAddress, address aTokenAddress,
@ -306,28 +345,44 @@ interface ILendingPool {
address interestRateStrategyAddress address interestRateStrategyAddress
) external; ) external;
/**
* @dev updates the address of the interest rate strategy contract
* @param reserve the address of the reserve
* @param rateStrategyAddress the address of the interest rate strategy contract
**/
function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress) function setReserveInterestRateStrategyAddress(address reserve, address rateStrategyAddress)
external; external;
function setConfiguration(address reserve, uint256 configuration) external; function setConfiguration(address reserve, uint256 configuration) external;
function getConfiguration(address reserve) /**
external * @dev Returns the configuration of the reserve
view * @param asset The address of the underlying asset of the reserve
returns (ReserveConfiguration.Map memory); * @return The configuration of the reserve
**/
function getConfiguration(address asset) external view returns (ReserveConfiguration.Map memory);
/**
* @dev Returns the configuration of the user across all the reserves
* @param user The user address
* @return The configuration of the user
**/
function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory); function getUserConfiguration(address user) external view returns (UserConfiguration.Map memory);
function getReserveNormalizedIncome(address reserve) external view returns (uint256); /**
* @dev Returns the normalized income normalized income of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The reserve's normalized income
*/
function getReserveNormalizedIncome(address asset) external view returns (uint256);
function getReserveNormalizedVariableDebt(address reserve) external view returns (uint256); /**
* @dev Returns the normalized variable debt per unit of asset
* @param asset The address of the underlying asset of the reserve
* @return The reserve normalized variable debt
*/
function getReserveNormalizedVariableDebt(address asset) external view returns (uint256);
/**
* @dev Returns the state and configuration of the reserve
* @param asset The address of the underlying asset of the reserve
* @return The state of the reserve
**/
function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory); function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
function finalizeTransfer( function finalizeTransfer(
@ -343,14 +398,7 @@ interface ILendingPool {
function getAddressesProvider() external view returns (ILendingPoolAddressesProvider); function getAddressesProvider() external view returns (ILendingPoolAddressesProvider);
/**
* @dev Set the _pause state
* @param val the boolean value to set the current pause state of LendingPool
*/
function setPause(bool val) external; function setPause(bool val) external;
/**
* @dev Returns if the LendingPool is paused
*/
function paused() external view returns (bool); function paused() external view returns (bool);
} }

View File

@ -14,7 +14,6 @@ interface ILendingPoolAddressesProvider {
event EmergencyAdminUpdated(address indexed newAddress); event EmergencyAdminUpdated(address indexed newAddress);
event LendingPoolConfiguratorUpdated(address indexed newAddress); event LendingPoolConfiguratorUpdated(address indexed newAddress);
event LendingPoolCollateralManagerUpdated(address indexed newAddress); event LendingPoolCollateralManagerUpdated(address indexed newAddress);
event EthereumAddressUpdated(address indexed newAddress);
event PriceOracleUpdated(address indexed newAddress); event PriceOracleUpdated(address indexed newAddress);
event LendingRateOracleUpdated(address indexed newAddress); event LendingRateOracleUpdated(address indexed newAddress);
event ProxyCreated(bytes32 id, address indexed newAddress); event ProxyCreated(bytes32 id, address indexed newAddress);

View File

@ -18,9 +18,8 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol'; import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol'; import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol'; import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol';
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol'; import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
import {LendingPoolCollateralManager} from './LendingPoolCollateralManager.sol'; import {LendingPoolCollateralManager} from './LendingPoolCollateralManager.sol'; // TODO change to interface
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol';
@ -29,7 +28,19 @@ import {Address} from '../dependencies/openzeppelin/contracts/Address.sol';
/** /**
* @title LendingPool contract * @title LendingPool contract
* @notice Implements the actions of the LendingPool, and exposes accessory methods to fetch the users and reserve data * @dev Main point of interaction with an Aave protocol's market
* - Users can:
* # Deposit
* # Withdraw
* # Borrow
* # Repay
* # Swap their loans between variable and stable rate
* # Enable/disable their deposits as collateral rebalance stable rate borrow positions
* # Liquidate positions
* # Execute Flash Loans
* - To be covered by a proxy contract, owned by the LendingPoolAddressesProvider of the specific Aave market
* - All admin functions are callable by the LendingPoolConfigurator contract defined also in the
* LendingPoolAddressesProvider
* @author Aave * @author Aave
**/ **/
contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage { contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage {
@ -44,25 +55,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
uint256 public constant MAX_NUMBER_RESERVES = 128; uint256 public constant MAX_NUMBER_RESERVES = 128;
uint256 public constant LENDINGPOOL_REVISION = 0x2; uint256 public constant LENDINGPOOL_REVISION = 0x2;
/**
* @dev functions marked by this modifier can only be called when the protocol is not paused
**/
modifier whenNotPaused() { modifier whenNotPaused() {
_whenNotPaused(); _whenNotPaused();
_; _;
} }
/**
* @dev functions marked by this modifier can only be called by the LendingPoolConfigurator
**/
modifier onlyLendingPoolConfigurator() { modifier onlyLendingPoolConfigurator() {
_onlyLendingPoolConfigurator(); _onlyLendingPoolConfigurator();
_; _;
} }
/** function _whenNotPaused() internal view {
* @dev only lending pools configurator can use functions affected by this modifier require(!_paused, Errors.LP_IS_PAUSED);
**/ }
function _onlyLendingPoolConfigurator() internal view { function _onlyLendingPoolConfigurator() internal view {
require( require(
_addressesProvider.getLendingPoolConfigurator() == msg.sender, _addressesProvider.getLendingPoolConfigurator() == msg.sender,
@ -70,36 +76,31 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
); );
} }
/**
* @dev Function to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _whenNotPaused() internal view {
require(!_paused, Errors.LP_IS_PAUSED);
}
function getRevision() internal override pure returns (uint256) { function getRevision() internal override pure returns (uint256) {
return LENDINGPOOL_REVISION; return LENDINGPOOL_REVISION;
} }
/** /**
* @dev this function is invoked by the proxy contract when the LendingPool contract is added to the * @dev Function is invoked by the proxy contract when the LendingPool contract is added to the
* AddressesProvider. * LendingPoolAddressesProvider of the market.
* @param provider the address of the LendingPoolAddressesProvider registry * - Caching the address of the LendingPoolAddressesProvider in order to reduce gas consumption
* on subsequent operations
* @param provider The address of the LendingPoolAddressesProvider
**/ **/
function initialize(ILendingPoolAddressesProvider provider) public initializer { function initialize(ILendingPoolAddressesProvider provider) public initializer {
_addressesProvider = provider; _addressesProvider = provider;
} }
/** /**
* @dev deposits The underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens) * @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
* is minted. * - E.g. User deposits 100 USDC and gets in return 100 aUSDC
* @param asset the address of the reserve * @param asset The address of the underlying asset to deposit
* @param amount the amount to be deposited * @param amount The amount to be deposited
* @param referralCode integrators are assigned a referral code and can potentially receive rewards. * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user
* wants to receive them on his own wallet, or a different address if the beneficiary of aTokens
* is a different wallet
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/ **/
function deposit( function deposit(
address asset, address asset,
@ -123,17 +124,20 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf); emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf);
} }
//transfer to the aToken contract
IERC20(asset).safeTransferFrom(msg.sender, aToken, amount); IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);
emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode); emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode);
} }
/** /**
* @dev withdraws the _reserves of user. * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
* @param asset the address of the reserve * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
* @param amount the underlying amount to be redeemed * @param asset The address of the underlying asset to withdraw
* @param to address that will receive the underlying * @param amount The underlying amount to be withdrawn
* - Send the value type(uint256).max in order to withdraw the whole aToken balance
* @param to Address that will receive the underlying, same as msg.sender if the user
* wants to receive it on his own wallet, or a different address if the beneficiary is a
* different wallet
**/ **/
function withdraw( function withdraw(
address asset, address asset,
@ -148,7 +152,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
uint256 amountToWithdraw = amount; uint256 amountToWithdraw = amount;
//if amount is equal to uint(-1), the user wants to redeem everything
if (amount == type(uint256).max) { if (amount == type(uint256).max) {
amountToWithdraw = userBalance; amountToWithdraw = userBalance;
} }
@ -179,16 +182,19 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev Allows users to borrow a specific amount of the reserve underlying asset, provided that the borrower * @dev Allows users to borrow a specific `amount` of the reserve underlying asset, provided that the borrower
* already deposited enough collateral, or he was given enough allowance by a credit delegator on the * already deposited enough collateral, or he was given enough allowance by a credit delegator on the
* corresponding debt token (StableDebtToken or VariableDebtToken) * corresponding debt token (StableDebtToken or VariableDebtToken)
* @param asset the address of the reserve * - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
* @param amount the amount to be borrowed * and 100 stable/variable debt tokens, depending on the `interestRateMode`
* @param interestRateMode the interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable * @param asset The address of the underlying asset to borrow
* @param referralCode a referral code for integrators * @param amount The amount to be borrowed
* @param onBehalfOf address of the user who will receive the debt. Should be the address of the borrower itself * @param interestRateMode The interest rate mode at which the user wants to borrow: 1 for Stable, 2 for Variable
* @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
* @param onBehalfOf Address of the user who will receive the debt. Should be the address of the borrower itself
* calling the function if he wants to borrow against his own collateral, or the address of the credit delegator * calling the function if he wants to borrow against his own collateral, or the address of the credit delegator
* if he has been given credit delegation allowance * if he has been given credit delegation allowance
**/ **/
function borrow( function borrow(
address asset, address asset,
@ -214,12 +220,15 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @notice repays a borrow on the specific reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified). * @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
* @dev the target user is defined by onBehalfOf. If there is no repayment on behalf of another account, * - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
* onBehalfOf must be equal to msg.sender. * @param asset The address of the borrowed underlying asset previously borrowed
* @param asset the address of the reserve on which the user borrowed * @param amount The amount to repay
* @param amount the amount to repay, or uint256(-1) if the user wants to repay everything * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
* @param onBehalfOf the address for which msg.sender is repaying. * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable
* @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the
* user calling the function if he wants to reduce/remove his own debt, or the address of any other
* other borrower whose debt should be removed
**/ **/
function repay( function repay(
address asset, address asset,
@ -242,7 +251,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
variableDebt variableDebt
); );
//default to max amount
uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
? stableDebt ? stableDebt
: variableDebt; : variableDebt;
@ -253,7 +261,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
reserve.updateState(); reserve.updateState();
//burns an equivalent amount of debt tokens
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount); IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
} else { } else {
@ -277,9 +284,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev borrowers can user this function to swap between stable and variable borrow rate modes. * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
* @param asset the address of the reserve on which the user borrowed * @param asset The address of the underlying asset borrowed
* @param rateMode the rate mode that the user wants to swap * @param rateMode The rate mode that the user wants to swap to
**/ **/
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused { function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
@ -299,7 +306,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
reserve.updateState(); reserve.updateState();
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) { if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
//burn stable rate tokens, mint variable rate tokens
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt); IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
IVariableDebtToken(reserve.variableDebtTokenAddress).mint( IVariableDebtToken(reserve.variableDebtTokenAddress).mint(
msg.sender, msg.sender,
@ -308,7 +314,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
reserve.variableBorrowIndex reserve.variableBorrowIndex
); );
} else { } else {
//do the opposite
IVariableDebtToken(reserve.variableDebtTokenAddress).burn( IVariableDebtToken(reserve.variableDebtTokenAddress).burn(
msg.sender, msg.sender,
variableDebt, variableDebt,
@ -328,12 +333,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev rebalances the stable interest rate of a user. Users can be rebalanced if the following conditions are satisfied: * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
* 1. Usage ratio is above 95% * - Users can be rebalanced if the following conditions are satisfied:
* 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been * 1. Usage ratio is above 95%
* borrowed at a stable rate and depositors are not earning enough. * 2. the current deposit APY is below REBALANCE_UP_THRESHOLD * maxVariableBorrowRate, which means that too much has been
* @param asset the address of the reserve * borrowed at a stable rate and depositors are not earning enough
* @param user the address of the user to be rebalanced * @param asset The address of the underlying asset borrowed
* @param user The address of the user to be rebalanced
**/ **/
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused { function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
ReserveLogic.ReserveData storage reserve = _reserves[asset]; ReserveLogic.ReserveData storage reserve = _reserves[asset];
@ -368,9 +374,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev allows depositors to enable or disable a specific deposit as collateral. * @dev Allows depositors to enable/disable a specific deposited asset as collateral
* @param asset the address of the reserve * @param asset The address of the underlying asset deposited
* @param useAsCollateral true if the user wants to use 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) function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
external external
@ -400,19 +406,21 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev users can invoke this function to liquidate an undercollateralized position. * @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
* @param asset the address of the collateral to liquidated * - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
* @param asset the address of the principal reserve * a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
* @param user the address of the borrower * @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
* @param purchaseAmount the amount of principal that the liquidator wants to repay * @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if * @param user The address of the borrower getting liquidated
* he wants to receive the underlying asset directly * @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
* @param receiveAToken `true` if the liquidators wants to receive the collateral aTokens, `false` if he wants
* to receive the underlying collateral asset directly
**/ **/
function liquidationCall( function liquidationCall(
address collateral, address collateralAsset,
address asset, address debtAsset,
address user, address user,
uint256 purchaseAmount, uint256 debtToCover,
bool receiveAToken bool receiveAToken
) external override whenNotPaused { ) external override whenNotPaused {
address collateralManager = _addressesProvider.getLendingPoolCollateralManager(); address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
@ -421,10 +429,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
(bool success, bytes memory result) = collateralManager.delegatecall( (bool success, bytes memory result) = collateralManager.delegatecall(
abi.encodeWithSignature( abi.encodeWithSignature(
'liquidationCall(address,address,address,uint256,bool)', 'liquidationCall(address,address,address,uint256,bool)',
collateral, collateralAsset,
asset, debtAsset,
user, user,
purchaseAmount, debtToCover,
receiveAToken receiveAToken
) )
); );
@ -448,16 +456,21 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev allows smartcontracts to access the liquidity of the pool within one transaction, * @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
* as long as the amount taken plus a fee is returned. NOTE There are security concerns for developers of flashloan receiver contracts * as long as the amount taken plus a fee is returned.
* that must be kept into consideration. For further details please visit https://developers.aave.com * IMPORTANT There are security concerns for developers of flashloan receiver contracts that must be kept into consideration.
* @param receiverAddress The address of the contract receiving the funds. The receiver should implement the IFlashLoanReceiver interface. * For further details please visit https://developers.aave.com
* @param assets The addresss of the assets being flashborrowed * @param receiverAddress The address of the contract receiving the funds, implementing the IFlashLoanReceiver interface
* @param amounts The amounts requested for this flashloan for each asset * @param assets The addresses of the assets being flash-borrowed
* @param modes Types 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 amounts The amounts amounts being flash-borrowed
* @param onBehalfOf If mode is not 0, then the address to take the debt onBehalfOf. The onBehalfOf address must already have approved `msg.sender` to incur the debt on their behalf. * @param modes Types of the debt to open if the flash loan is not returned:
* 0 -> Don't open any debt, just revert if funds can't be transferred from the receiver
* 1 -> Open debt at stable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* 2 -> Open debt at variable rate for the value of the amount flash-borrowed to the `onBehalfOf` address
* @param onBehalfOf The address that will receive the debt in the case of using on `modes` 1 or 2
* @param params Variadic packed params to pass to the receiver as extra information * @param params Variadic packed params to pass to the receiver as extra information
* @param referralCode Referral code of the flash loan * @param referralCode Code used to register the integrator originating the operation, for potential rewards.
* 0 if the action is executed directly by the user, without any middle-man
**/ **/
function flashLoan( function flashLoan(
address receiverAddress, address receiverAddress,
@ -482,11 +495,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
premiums[vars.i] = amounts[vars.i].mul(FLASHLOAN_PREMIUM_TOTAL).div(10000); 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]); IAToken(aTokenAddresses[vars.i]).transferUnderlyingTo(receiverAddress, amounts[vars.i]);
} }
//execute action of the receiver
require( require(
vars.receiver.executeOperation(assets, amounts, premiums, msg.sender, params), vars.receiver.executeOperation(assets, amounts, premiums, msg.sender, params),
Errors.LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN Errors.LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN
@ -518,8 +529,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
vars.currentAmountPlusPremium vars.currentAmountPlusPremium
); );
} else { } else {
//if the user didn't choose to return the funds, the system checks if there // If the user chose to not return the funds, the system checks if there is enough collateral and
//is enough collateral and eventually open a position // eventually opens a debt position
_executeBorrow( _executeBorrow(
ExecuteBorrowParams( ExecuteBorrowParams(
vars.currentAsset, vars.currentAsset,
@ -545,9 +556,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the state and configuration of the reserve * @dev Returns the state and configuration of the reserve
* @param asset the address of the reserve * @param asset The address of the underlying asset of the reserve
* @return the state of the reserve * @return The state of the reserve
**/ **/
function getReserveData(address asset) function getReserveData(address asset)
external external
@ -559,8 +570,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the user account data across all the reserves * @dev Returns the user account data across all the reserves
* @param user the address of the user * @param user The address of the user
* @return totalCollateralETH the total collateral in ETH of the user * @return totalCollateralETH the total collateral in ETH of the user
* @return totalDebtETH the total debt in ETH of the user * @return totalDebtETH the total debt in ETH of the user
* @return availableBorrowsETH the borrowing power left of the user * @return availableBorrowsETH the borrowing power left of the user
@ -604,9 +615,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the configuration of the reserve * @dev Returns the configuration of the reserve
* @param asset the address of the reserve * @param asset The address of the underlying asset of the reserve
* @return the configuration of the reserve * @return The configuration of the reserve
**/ **/
function getConfiguration(address asset) function getConfiguration(address asset)
external external
@ -618,9 +629,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the configuration of the user across all the reserves * @dev Returns the configuration of the user across all the reserves
* @param user the user * @param user The user address
* @return the configuration of the user * @return The configuration of the user
**/ **/
function getUserConfiguration(address user) function getUserConfiguration(address user)
external external
@ -632,9 +643,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the normalized income per unit of asset * @dev Returns the normalized income normalized income of the reserve
* @param asset the address of the reserve * @param asset The address of the underlying asset of the reserve
* @return the reserve normalized income * @return The reserve's normalized income
*/ */
function getReserveNormalizedIncome(address asset) function getReserveNormalizedIncome(address asset)
external external
@ -647,9 +658,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the normalized variable debt per unit of asset * @dev Returns the normalized variable debt per unit of asset
* @param asset the address of the reserve * @param asset The address of the underlying asset of the reserve
* @return the reserve normalized debt * @return The reserve normalized variable debt
*/ */
function getReserveNormalizedVariableDebt(address asset) function getReserveNormalizedVariableDebt(address asset)
external external
@ -668,7 +679,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the list of the initialized reserves * @dev Returns the list of the initialized reserves
**/ **/
function getReservesList() external override view returns (address[] memory) { function getReservesList() external override view returns (address[] memory) {
address[] memory _activeReserves = new address[](_reservesCount); address[] memory _activeReserves = new address[](_reservesCount);
@ -680,20 +691,21 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev returns the addresses provider * @dev Returns the cached LendingPoolAddressesProvider connected to this contract
**/ **/
function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) { function getAddressesProvider() external override view returns (ILendingPoolAddressesProvider) {
return _addressesProvider; return _addressesProvider;
} }
/** /**
* @dev validates and finalizes an aToken transfer * @dev Validates and finalizes an aToken transfer
* @param asset the address of the reserve * - Only callable by the overlying aToken of the `asset`
* @param from the user from which the aTokens are transferred * @param asset The address of the underlying asset of the aToken
* @param to the user receiving the aTokens * @param from The user from which the aTokens are transferred
* @param amount the amount being transferred/redeemed * @param to The user receiving the aTokens
* @param balanceFromBefore the balance of the from user before the transfer * @param amount The amount being transferred/withdrawn
* @param balanceToBefore the balance of the to user before the transfer * @param balanceFromBefore The aToken balance of the `from` user before the transfer
* @param balanceToBefore The aToken balance of the `to` user before the transfer
*/ */
function finalizeTransfer( function finalizeTransfer(
address asset, address asset,
@ -732,10 +744,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev initializes a reserve * @dev Initializes a reserve, activating it, assigning an aToken and debt tokens and an
* @param asset the address of the reserve * interest rate strategy
* @param aTokenAddress the address of the overlying aToken contract * - Only callable by the LendingPoolConfigurator contract
* @param interestRateStrategyAddress the address of the interest rate strategy contract * @param asset The address of the underlying asset of the reserve
* @param aTokenAddress The address of the aToken that will be assigned to the reserve
* @param stableDebtAddress The address of the StableDebtToken that will be assigned to the reserve
* @param aTokenAddress The address of the VariableDebtToken that will be assigned to the reserve
* @param interestRateStrategyAddress The address of the interest rate strategy contract
**/ **/
function initReserve( function initReserve(
address asset, address asset,
@ -755,9 +771,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev updates the address of the interest rate strategy contract * @dev Updates the address of the interest rate strategy contract
* @param asset the address of the reserve * - Only callable by the LendingPoolConfigurator contract
* @param rateStrategyAddress the address of the interest rate strategy contract * @param asset The address of the underlying asset of the reserve
* @param rateStrategyAddress The address of the interest rate strategy contract
**/ **/
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external external
@ -768,9 +785,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev sets the configuration map of the reserve * @dev Sets the configuration bitmap of the reserve as a whole
* @param asset the address of the reserve * - Only callable by the LendingPoolConfigurator contract
* @param configuration the configuration map * @param asset The address of the underlying asset of the reserve
* @param configuration The new configuration bitmap
**/ **/
function setConfiguration(address asset, uint256 configuration) function setConfiguration(address asset, uint256 configuration)
external external
@ -781,8 +799,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
/** /**
* @dev Set the _pause state * @dev Set the _pause state of a reserve
* @param val the boolean value to set the current pause state of LendingPool * - Only callable by the LendingPoolConfigurator contract
* @param val `true` to pause the reserve, `false` to un-pause it
*/ */
function setPause(bool val) external override onlyLendingPoolConfigurator { function setPause(bool val) external override onlyLendingPoolConfigurator {
_paused = val; _paused = val;
@ -793,7 +812,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
} }
} }
// internal functions
struct ExecuteBorrowParams { struct ExecuteBorrowParams {
address asset; address asset;
address user; address user;
@ -805,10 +823,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
bool releaseUnderlying; bool releaseUnderlying;
} }
/**
* @dev Internal function to execute a borrowing action, allowing to transfer or not the underlying
* @param vars Input struct for the borrowing action, in order to avoid STD errors
**/
function _executeBorrow(ExecuteBorrowParams memory vars) internal { function _executeBorrow(ExecuteBorrowParams memory vars) internal {
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset]; ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf]; UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf];
@ -836,7 +850,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
reserve.updateState(); reserve.updateState();
//caching the current stable borrow rate
uint256 currentStableRate = 0; uint256 currentStableRate = 0;
bool isFirstBorrowing = false; bool isFirstBorrowing = false;
@ -888,9 +901,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
); );
} }
/**
* @dev adds a reserve to the array of the _reserves address
**/
function _addReserveToList(address asset) internal { function _addReserveToList(address asset) internal {
uint256 reservesCount = _reservesCount; uint256 reservesCount = _reservesCount;

View File

@ -42,7 +42,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
* @param collateral the address of the collateral being liquidated * @param collateral the address of the collateral being liquidated
* @param principal the address of the reserve * @param principal the address of the reserve
* @param user the address of the user being liquidated * @param user the address of the user being liquidated
* @param purchaseAmount the total amount liquidated * @param debtToCover the total amount liquidated
* @param liquidatedCollateralAmount the amount of collateral being liquidated * @param liquidatedCollateralAmount the amount of collateral being liquidated
* @param liquidator the address of the liquidator * @param liquidator the address of the liquidator
* @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise * @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise
@ -51,7 +51,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
address indexed collateral, address indexed collateral,
address indexed principal, address indexed principal,
address indexed user, address indexed user,
uint256 purchaseAmount, uint256 debtToCover,
uint256 liquidatedCollateralAmount, uint256 liquidatedCollateralAmount,
address liquidator, address liquidator,
bool receiveAToken bool receiveAToken
@ -107,7 +107,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
* @param collateral the address of the collateral to liquidated * @param collateral the address of the collateral to liquidated
* @param principal the address of the principal reserve * @param principal the address of the principal reserve
* @param user the address of the borrower * @param user the address of the borrower
* @param purchaseAmount the amount of principal that the liquidator wants to repay * @param debtToCover the amount of principal that the liquidator wants to repay
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if * @param receiveAToken true if the liquidators wants to receive the aTokens, false if
* he wants to receive the underlying asset directly * he wants to receive the underlying asset directly
**/ **/
@ -115,7 +115,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
address collateral, address collateral,
address principal, address principal,
address user, address user,
uint256 purchaseAmount, uint256 debtToCover,
bool receiveAToken bool receiveAToken
) external returns (uint256, string memory) { ) external returns (uint256, string memory) {
ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral]; ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral];
@ -160,9 +160,9 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
LIQUIDATION_CLOSE_FACTOR_PERCENT LIQUIDATION_CLOSE_FACTOR_PERCENT
); );
vars.actualAmountToLiquidate = purchaseAmount > vars.maxPrincipalAmountToLiquidate vars.actualAmountToLiquidate = debtToCover > vars.maxPrincipalAmountToLiquidate
? vars.maxPrincipalAmountToLiquidate ? vars.maxPrincipalAmountToLiquidate
: purchaseAmount; : debtToCover;
( (
vars.maxCollateralToLiquidate, vars.maxCollateralToLiquidate,
@ -287,7 +287,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
* all the checks to validate the liquidation have been performed, otherwise it might fail. * all the checks to validate the liquidation have been performed, otherwise it might fail.
* @param collateralAddress the collateral to be liquidated * @param collateralAddress the collateral to be liquidated
* @param principalAddress the principal currency to be liquidated * @param principalAddress the principal currency to be liquidated
* @param purchaseAmount the amount of principal being liquidated * @param debtToCover the amount of principal being liquidated
* @param userCollateralBalance the collatera balance for the specific collateral asset of the user being liquidated * @param userCollateralBalance the collatera balance for the specific collateral asset of the user being liquidated
* @return collateralAmount the maximum amount that is possible to liquidated given all the liquidation constraints (user balance, close factor) * @return collateralAmount the maximum amount that is possible to liquidated given all the liquidation constraints (user balance, close factor)
* @return principalAmountNeeded the purchase amount * @return principalAmountNeeded the purchase amount
@ -297,7 +297,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
ReserveLogic.ReserveData storage principalReserve, ReserveLogic.ReserveData storage principalReserve,
address collateralAddress, address collateralAddress,
address principalAddress, address principalAddress,
uint256 purchaseAmount, uint256 debtToCover,
uint256 userCollateralBalance uint256 userCollateralBalance
) internal view returns (uint256, uint256) { ) internal view returns (uint256, uint256) {
uint256 collateralAmount = 0; uint256 collateralAmount = 0;
@ -318,7 +318,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
//max amount of principal currency that is available for liquidation. //max amount of principal currency that is available for liquidation.
vars.maxAmountCollateralToLiquidate = vars vars.maxAmountCollateralToLiquidate = vars
.principalCurrencyPrice .principalCurrencyPrice
.mul(purchaseAmount) .mul(debtToCover)
.mul(10**vars.collateralDecimals) .mul(10**vars.collateralDecimals)
.percentMul(vars.liquidationBonus) .percentMul(vars.liquidationBonus)
.div(vars.collateralPrice.mul(10**vars.principalDecimals)); .div(vars.collateralPrice.mul(10**vars.principalDecimals));
@ -333,7 +333,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor
.percentDiv(vars.liquidationBonus); .percentDiv(vars.liquidationBonus);
} else { } else {
collateralAmount = vars.maxAmountCollateralToLiquidate; collateralAmount = vars.maxAmountCollateralToLiquidate;
principalAmountNeeded = purchaseAmount; principalAmountNeeded = debtToCover;
} }
return (collateralAmount, principalAmountNeeded); return (collateralAmount, principalAmountNeeded);
} }

View File

@ -71,10 +71,10 @@ contract LendingPoolHarnessForVariableDebtToken is ILendingPool {
address collateral, address collateral,
address asset, address asset,
address user, address user,
uint256 purchaseAmount, uint256 debtToCover,
bool receiveAToken bool receiveAToken
) external override { ) external override {
originalPool.liquidationCall(collateral, asset, user, purchaseAmount, receiveAToken); originalPool.liquidationCall(collateral, asset, user, debtToCover, receiveAToken);
} }
function getReservesList() external override view returns (address[] memory) { function getReservesList() external override view returns (address[] memory) {