mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'master' into feat/uniswap-adapter-flashloan
# Conflicts: # test/__setup.spec.ts
This commit is contained in:
commit
71ea58f758
.gitignore.gitlab-ci.ymlDockerfilebuidler.config.tsdocker-compose.test.ymlhardhat.config.ts
contracts
dependencies/openzeppelin
contracts
upgradeability
deployments
flashloan
interfaces
IAaveIncentivesController.solIChainlinkAggregator.solIExchangeAdapter.solILendingPool.solILendingPoolAddressesProvider.solILendingPoolAddressesProviderRegistry.solILendingPoolCollateralManager.solILendingRateOracle.solIPriceOracle.solIPriceOracleGetter.solIReserveInterestRateStrategy.solIUniswapExchange.sol
lendingpool
libraries/helpers
misc
AaveOracle.solAaveProtocolDataProvider.solUiPoolDataProvider.solWETHGateway.solWalletBalanceProvider.sol
interfaces
mocks
attacks
dependencies/weth
flashloan
oracle
CLAggregators
ChainlinkUSDETHOracleI.solGenericOracleI.solIExtendedPriceAggregator.solLendingRateOracle.solPriceOracle.soltokens
upgradeability
protocol
configuration
lendingpool
DefaultReserveInterestRateStrategy.solLendingPool.solLendingPoolCollateralManager.solLendingPoolConfigurator.solLendingPoolStorage.sol
libraries
aave-upgradeability
BaseImmutableAdminUpgradeabilityProxy.solInitializableImmutableAdminUpgradeabilityProxy.solVersionedInitializable.sol
configuration
helpers
logic
math
types
tokenization
helpers
markets/aave
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -7,7 +7,7 @@ dist/
|
|||
build/
|
||||
.vscode
|
||||
.idea
|
||||
types
|
||||
/types
|
||||
|
||||
deployed-contracts.json
|
||||
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
stages:
|
||||
- test
|
||||
- checks
|
||||
|
||||
test:
|
||||
stage: test
|
||||
stage: checks
|
||||
tags:
|
||||
- aave-build-runner
|
||||
before_script:
|
||||
- docker-compose -f docker-compose.test.yml build
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build
|
||||
script:
|
||||
- docker-compose -f docker-compose.test.yml run contracts-env npm run ci:test
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:test
|
||||
after_script:
|
||||
- docker-compose -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -f docker-compose.test.yml down
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down
|
||||
|
||||
deploy-mainnet-fork:
|
||||
tags:
|
||||
- aave-build-runner
|
||||
stage: checks
|
||||
before_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml build
|
||||
script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run aave:fork:main
|
||||
after_script:
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml run contracts-env npm run ci:clean
|
||||
- docker-compose -p ${CI_JOB_ID} -f docker-compose.test.yml down
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM ethereum/solc:0.6.8 as build-deps
|
||||
FROM ethereum/solc:0.6.12 as build-deps
|
||||
|
||||
FROM node:14
|
||||
COPY --from=build-deps /usr/bin/solc /usr/bin/solc
|
||||
|
|
|
@ -49,7 +49,7 @@ const getCommonNetworkConfig = (networkName: eEthereumNetwork, networkId: number
|
|||
|
||||
const buidlerConfig: any = {
|
||||
solc: {
|
||||
version: '0.6.8',
|
||||
version: '0.6.12',
|
||||
optimizer: {enabled: true, runs: 200},
|
||||
evmVersion: 'istanbul',
|
||||
},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @dev Collection of functions related to the address type
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/*
|
||||
* @dev Provides information about the current execution context, including the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC20 standard as defined in the EIP.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IERC20} from './IERC20.sol';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IERC20} from './IERC20.sol';
|
||||
import {SafeMath} from './SafeMath.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './BaseAdminUpgradeabilityProxy.sol';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './UpgradeabilityProxy.sol';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './Proxy.sol';
|
||||
import '../contracts/Address.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './BaseAdminUpgradeabilityProxy.sol';
|
||||
import './InitializableUpgradeabilityProxy.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './BaseUpgradeabilityProxy.sol';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './BaseUpgradeabilityProxy.sol';
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {LendingPoolConfigurator} from '../lendingpool/LendingPoolConfigurator.sol';
|
||||
import {AToken} from '../tokenization/AToken.sol';
|
||||
import {LendingPool} from '../protocol/lendingpool/LendingPool.sol';
|
||||
import {
|
||||
LendingPoolAddressesProvider
|
||||
} from '../protocol/configuration/LendingPoolAddressesProvider.sol';
|
||||
import {LendingPoolConfigurator} from '../protocol/lendingpool/LendingPoolConfigurator.sol';
|
||||
import {AToken} from '../protocol/tokenization/AToken.sol';
|
||||
import {
|
||||
DefaultReserveInterestRateStrategy
|
||||
} from '../lendingpool/DefaultReserveInterestRateStrategy.sol';
|
||||
} from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol';
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {StringLib} from '../libraries/helpers/StringLib.sol';
|
||||
import {StringLib} from './StringLib.sol';
|
||||
|
||||
contract ATokensAndRatesHelper is Ownable {
|
||||
address payable private pool;
|
||||
|
@ -31,7 +33,7 @@ contract ATokensAndRatesHelper is Ownable {
|
|||
function initDeployment(
|
||||
address[] calldata tokens,
|
||||
string[] calldata symbols,
|
||||
uint256[5][] calldata rates,
|
||||
uint256[6][] calldata rates,
|
||||
address incentivesController
|
||||
) external onlyOwner {
|
||||
require(tokens.length == symbols.length, 't Arrays not same length');
|
||||
|
@ -55,7 +57,8 @@ contract ATokensAndRatesHelper is Ownable {
|
|||
rates[i][1],
|
||||
rates[i][2],
|
||||
rates[i][3],
|
||||
rates[i][4]
|
||||
rates[i][4],
|
||||
rates[i][5]
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -105,16 +108,16 @@ contract ATokensAndRatesHelper is Ownable {
|
|||
}
|
||||
}
|
||||
|
||||
function enableBorrowingOnReserves(address[] calldata tokens, bool[] calldata stableBorrows)
|
||||
function enableBorrowingOnReserves(address[] calldata tokens, bool[] calldata stableBorrowingEnabled)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
require(stableBorrows.length == tokens.length);
|
||||
require(stableBorrowingEnabled.length == tokens.length);
|
||||
|
||||
for (uint256 i = 0; i < tokens.length; i++) {
|
||||
LendingPoolConfigurator(poolConfigurator).enableBorrowingOnReserve(
|
||||
tokens[i],
|
||||
stableBorrows[i]
|
||||
stableBorrowingEnabled[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {StableDebtToken} from '../tokenization/StableDebtToken.sol';
|
||||
import {VariableDebtToken} from '../tokenization/VariableDebtToken.sol';
|
||||
import {StableDebtToken} from '../protocol/tokenization/StableDebtToken.sol';
|
||||
import {VariableDebtToken} from '../protocol/tokenization/VariableDebtToken.sol';
|
||||
import {LendingRateOracle} from '../mocks/oracle/LendingRateOracle.sol';
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {StringLib} from '../libraries/helpers/StringLib.sol';
|
||||
import {StringLib} from './StringLib.sol';
|
||||
|
||||
contract StableAndVariableTokensHelper is Ownable {
|
||||
address payable private pool;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
library StringLib {
|
||||
function concat(string memory a, string memory b) internal pure returns (string memory) {
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title IFlashLoanReceiver interface
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface IAaveIncentivesController {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IChainlinkAggregator {
|
||||
function latestAnswer() external view returns (int256);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
|
||||
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from './ILendingPoolAddressesProvider.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
|
||||
interface ILendingPool {
|
||||
/**
|
||||
* @dev emitted on deposit
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
* @param amount the amount to be deposited
|
||||
* @param referral the referral number of the action
|
||||
* @dev Emitted on deposit()
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @param user The address initiating the deposit
|
||||
* @param onBehalfOf The beneficiary of the deposit, receiving the aTokens
|
||||
* @param amount The amount deposited
|
||||
* @param referral The referral code used
|
||||
**/
|
||||
event Deposit(
|
||||
address indexed reserve,
|
||||
|
@ -25,22 +24,24 @@ interface ILendingPool {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev emitted during a withdraw action.
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
* @param to address that will receive the underlying
|
||||
* @param amount the amount to be withdrawn
|
||||
* @dev Emitted on withdraw()
|
||||
* @param reserve The address of the underlyng asset being withdrawn
|
||||
* @param user The address initiating the withdrawal, owner of aTokens
|
||||
* @param to Address that will receive the underlying
|
||||
* @param amount The amount to be withdrawn
|
||||
**/
|
||||
event Withdraw(address indexed reserve, address indexed user, address indexed to, uint256 amount);
|
||||
|
||||
/**
|
||||
* @dev emitted on borrow
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
* @param amount the amount to be deposited
|
||||
* @param borrowRateMode the rate mode, can be either 1-stable or 2-variable
|
||||
* @param borrowRate the rate at which the user has borrowed
|
||||
* @param referral the referral number of the action
|
||||
* @dev Emitted on borrow() and flashLoan() when debt needs to be opened
|
||||
* @param reserve The address of the underlying asset being borrowed
|
||||
* @param user The address of the user initiating the borrow(), receiving the funds on borrow() or just
|
||||
* initiator of the transaction on flashLoan()
|
||||
* @param onBehalfOf The address that will be getting the debt
|
||||
* @param amount The amount borrowed out
|
||||
* @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(
|
||||
address indexed reserve,
|
||||
|
@ -51,12 +52,13 @@ interface ILendingPool {
|
|||
uint256 borrowRate,
|
||||
uint16 indexed referral
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev emitted on repay
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user for which the repay has been executed
|
||||
* @param repayer the address of the user that has performed the repay action
|
||||
* @param amount the amount repaid
|
||||
* @dev Emitted on repay()
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @param user The beneficiary of the repayment, getting his debt reduced
|
||||
* @param repayer The address of the user initiating the repay(), providing the funds
|
||||
* @param amount The amount repaid
|
||||
**/
|
||||
event Repay(
|
||||
address indexed reserve,
|
||||
|
@ -64,41 +66,44 @@ interface ILendingPool {
|
|||
address indexed repayer,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when a user performs a rate swap
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user executing the swap
|
||||
* @dev Emitted on swapBorrowRateMode()
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @dev emitted when a user enables a reserve as collateral
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
* @dev Emitted on setUserUseReserveAsCollateral()
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @param user The address of the user enabling the usage as collateral
|
||||
**/
|
||||
event ReserveUsedAsCollateralEnabled(address indexed reserve, address indexed user);
|
||||
|
||||
/**
|
||||
* @dev emitted when a user disables a reserve as collateral
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
* @dev Emitted on setUserUseReserveAsCollateral()
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @param user The address of the user enabling the usage as collateral
|
||||
**/
|
||||
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
|
||||
|
||||
/**
|
||||
* @dev emitted when the stable rate of a user gets rebalanced
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user for which the rebalance has been executed
|
||||
* @dev Emitted on rebalanceStableBorrowRate()
|
||||
* @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
|
||||
**/
|
||||
event RebalanceStableBorrowRate(address indexed reserve, address indexed user);
|
||||
|
||||
/**
|
||||
* @dev emitted when a flashloan is executed
|
||||
* @param target the address of the flashLoanReceiver
|
||||
* @param initiator the address initiating the flash loan
|
||||
* @param asset the address of the asset being flashborrowed
|
||||
* @param amount the amount requested
|
||||
* @param premium the total fee on the amount
|
||||
* @param referralCode the referral code of the caller
|
||||
* @dev Emitted on flashLoan()
|
||||
* @param target The address of the flash loan receiver contract
|
||||
* @param initiator The address initiating the flash loan
|
||||
* @param asset The address of the asset being flash borrowed
|
||||
* @param amount The amount flash borrowed
|
||||
* @param premium The fee flash borrowed
|
||||
* @param referralCode The referral code used
|
||||
**/
|
||||
event FlashLoan(
|
||||
address indexed target,
|
||||
|
@ -120,23 +125,23 @@ interface ILendingPool {
|
|||
event Unpaused();
|
||||
|
||||
/**
|
||||
* @dev emitted when a borrower is liquidated. Thos evemt is emitted directly by the LendingPool
|
||||
* but it's declared here as the LendingPoolCollateralManager
|
||||
* is executed using a delegateCall().
|
||||
* @dev Emitted when a borrower is liquidated. This event is emitted by the LendingPool via
|
||||
* LendingPoolCollateral manager using a DELEGATECALL
|
||||
* This allows to have the events in the generated ABI for LendingPool.
|
||||
* @param collateral the address of the collateral being liquidated
|
||||
* @param principal the address of the reserve
|
||||
* @param user the address of the user being liquidated
|
||||
* @param purchaseAmount the total amount liquidated
|
||||
* @param liquidatedCollateralAmount the amount of collateral being liquidated
|
||||
* @param liquidator the address of the liquidator
|
||||
* @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param user The address of the borrower getting liquidated
|
||||
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
|
||||
* @param liquidatedCollateralAmount The amount of collateral received by the liiquidator
|
||||
* @param liquidator The address of the liquidator
|
||||
* @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(
|
||||
address indexed collateral,
|
||||
address indexed principal,
|
||||
address indexed collateralAsset,
|
||||
address indexed debtAsset,
|
||||
address indexed user,
|
||||
uint256 purchaseAmount,
|
||||
uint256 debtToCover,
|
||||
uint256 liquidatedCollateralAmount,
|
||||
address liquidator,
|
||||
bool receiveAToken
|
||||
|
@ -147,12 +152,12 @@ interface ILendingPool {
|
|||
* 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
|
||||
* gets added to the LendingPool ABI
|
||||
* @param reserve the address of the reserve
|
||||
* @param liquidityRate the new liquidity rate
|
||||
* @param stableBorrowRate the new stable borrow rate
|
||||
* @param variableBorrowRate the new variable borrow rate
|
||||
* @param liquidityIndex the new liquidity index
|
||||
* @param variableBorrowIndex the new variable borrow index
|
||||
* @param reserve The address of the underlying asset of the reserve
|
||||
* @param liquidityRate The new liquidity rate
|
||||
* @param stableBorrowRate The new stable borrow rate
|
||||
* @param variableBorrowRate The new variable borrow rate
|
||||
* @param liquidityIndex The new liquidity index
|
||||
* @param variableBorrowIndex The new variable borrow index
|
||||
**/
|
||||
event ReserveDataUpdated(
|
||||
address indexed reserve,
|
||||
|
@ -164,40 +169,56 @@ interface ILendingPool {
|
|||
);
|
||||
|
||||
/**
|
||||
* @dev deposits The underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens)
|
||||
* is minted.
|
||||
* @param reserve the address of the reserve
|
||||
* @param amount the amount to be deposited
|
||||
* @param referralCode integrators are assigned a referral code and can potentially receive rewards.
|
||||
* @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
|
||||
* - E.g. User deposits 100 USDC and gets in return 100 aUSDC
|
||||
* @param asset The address of the underlying asset to deposit
|
||||
* @param amount The amount to be deposited
|
||||
* @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(
|
||||
address reserve,
|
||||
address asset,
|
||||
uint256 amount,
|
||||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev withdraws the assets of user.
|
||||
* @param reserve the address of the reserve
|
||||
* @param amount the underlying amount to be redeemed
|
||||
* @param to address that will receive the underlying
|
||||
* @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
|
||||
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
|
||||
* @param asset The address of the underlying asset to withdraw
|
||||
* @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(
|
||||
address reserve,
|
||||
address asset,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev Allows users to borrow a specific amount of the reserve currency, provided that the borrower
|
||||
* already deposited enough collateral.
|
||||
* @param reserve the address of the reserve
|
||||
* @param amount the amount to be borrowed
|
||||
* @param interestRateMode the interest rate mode at which the user wants to borrow. Can be 0 (STABLE) or 1 (VARIABLE)
|
||||
* @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
|
||||
* corresponding debt token (StableDebtToken or VariableDebtToken)
|
||||
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
|
||||
* 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(
|
||||
address reserve,
|
||||
address asset,
|
||||
uint256 amount,
|
||||
uint256 interestRateMode,
|
||||
uint16 referralCode,
|
||||
|
@ -205,73 +226,86 @@ interface ILendingPool {
|
|||
) external;
|
||||
|
||||
/**
|
||||
* @notice repays a borrow on the specific reserve, for the specified amount (or for the whole amount, if uint256(-1) is specified).
|
||||
* @dev the target user is defined by onBehalfOf. If there is no repayment on behalf of another account,
|
||||
* onBehalfOf must be equal to msg.sender.
|
||||
* @param reserve the address of the reserve on which the user borrowed
|
||||
* @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
|
||||
* @param onBehalfOf the address for which msg.sender is repaying.
|
||||
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
|
||||
* - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
|
||||
* @param asset The address of the borrowed underlying asset previously borrowed
|
||||
* @param amount The amount to repay
|
||||
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
|
||||
* @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(
|
||||
address reserve,
|
||||
address asset,
|
||||
uint256 amount,
|
||||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @dev borrowers can user this function to swap between stable and variable borrow rate modes.
|
||||
* @param reserve the address of the reserve on which the user borrowed
|
||||
* @param rateMode the rate mode that the user wants to swap
|
||||
* @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
|
||||
* @param asset The address of the underlying asset borrowed
|
||||
* @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.
|
||||
* 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.
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user to be rebalanced
|
||||
* @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
|
||||
* - 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 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.
|
||||
* @param reserve the address of the reserve
|
||||
* @param useAsCollateral true if the user wants to user the deposit as collateral, false otherwise.
|
||||
* @dev Allows depositors to enable/disable a specific deposited asset as collateral
|
||||
* @param asset The address of the underlying asset deposited
|
||||
* @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.
|
||||
* @param reserve the address of the collateral to liquidated
|
||||
* @param reserve the address of the principal reserve
|
||||
* @param user the address of the borrower
|
||||
* @param purchaseAmount the amount of principal that the liquidator wants to repay
|
||||
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if
|
||||
* he wants to receive the underlying asset directly
|
||||
* @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
|
||||
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param user The address of the borrower getting liquidated
|
||||
* @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(
|
||||
address collateral,
|
||||
address reserve,
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
address user,
|
||||
uint256 purchaseAmount,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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 assets the address of the principal reserve
|
||||
* @param amounts the amount requested for this flashloan
|
||||
* @param modes the flashloan borrow modes
|
||||
* @param params a bytes array to be sent to the flashloan executor
|
||||
* @param referralCode the referral code of the caller
|
||||
* @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
|
||||
* as long as the amount taken plus a fee is returned.
|
||||
* IMPORTANT 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, implementing the IFlashLoanReceiver interface
|
||||
* @param assets The addresses of the assets being flash-borrowed
|
||||
* @param amounts The amounts amounts 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 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(
|
||||
address receiver,
|
||||
address receiverAddress,
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata modes,
|
||||
|
@ -280,24 +314,28 @@ interface ILendingPool {
|
|||
uint16 referralCode
|
||||
) 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)
|
||||
external
|
||||
view
|
||||
returns (
|
||||
uint256 totalCollateralETH,
|
||||
uint256 totalBorrowsETH,
|
||||
uint256 totalDebtETH,
|
||||
uint256 availableBorrowsETH,
|
||||
uint256 currentLiquidationThreshold,
|
||||
uint256 ltv,
|
||||
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(
|
||||
address reserve,
|
||||
address aTokenAddress,
|
||||
|
@ -306,29 +344,51 @@ interface ILendingPool {
|
|||
address interestRateStrategyAddress
|
||||
) 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)
|
||||
external;
|
||||
|
||||
function setConfiguration(address reserve, uint256 configuration) external;
|
||||
|
||||
function getConfiguration(address reserve)
|
||||
/**
|
||||
* @dev Returns the configuration of the reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @return The configuration of the reserve
|
||||
**/
|
||||
function getConfiguration(address asset)
|
||||
external
|
||||
view
|
||||
returns (ReserveConfiguration.Map memory);
|
||||
returns (DataTypes.ReserveConfigurationMap memory);
|
||||
|
||||
function getUserConfiguration(address user) external view returns (UserConfiguration.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 (DataTypes.UserConfigurationMap 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);
|
||||
|
||||
function getReserveData(address asset) external view returns (ReserveLogic.ReserveData memory);
|
||||
/**
|
||||
* @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 (DataTypes.ReserveData memory);
|
||||
|
||||
function finalizeTransfer(
|
||||
address asset,
|
||||
|
@ -343,14 +403,7 @@ interface ILendingPool {
|
|||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @dev Returns if the LendingPool is paused
|
||||
*/
|
||||
function paused() external view returns (bool);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,27 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
@title ILendingPoolAddressesProvider interface
|
||||
@notice provides the interface to fetch the Aave protocol address
|
||||
*/
|
||||
|
||||
* @title LendingPoolAddressesProvider contract
|
||||
* @dev Main registry of addresses part of or connected to the protocol, including permissioned roles
|
||||
* - Acting also as factory of proxies and admin of those, so with right to change its implementations
|
||||
* - Owned by the Aave Governance
|
||||
* @author Aave
|
||||
**/
|
||||
interface ILendingPoolAddressesProvider {
|
||||
event LendingPoolUpdated(address indexed newAddress);
|
||||
event ConfigurationAdminUpdated(address indexed newAddress);
|
||||
event EmergencyAdminUpdated(address indexed newAddress);
|
||||
event LendingPoolConfiguratorUpdated(address indexed newAddress);
|
||||
event LendingPoolCollateralManagerUpdated(address indexed newAddress);
|
||||
event EthereumAddressUpdated(address indexed newAddress);
|
||||
event PriceOracleUpdated(address indexed newAddress);
|
||||
event LendingRateOracleUpdated(address indexed newAddress);
|
||||
event ProxyCreated(bytes32 id, address indexed newAddress);
|
||||
event AddressSet(bytes32 id, address indexed newAddress, bool hasProxy);
|
||||
|
||||
function setAddress(
|
||||
bytes32 id,
|
||||
address newAddress
|
||||
) external;
|
||||
function setAddress(bytes32 id, address newAddress) external;
|
||||
|
||||
function setAddressAsProxy(
|
||||
bytes32 id,
|
||||
address impl
|
||||
) external;
|
||||
function setAddressAsProxy(bytes32 id, address impl) external;
|
||||
|
||||
function getAddress(bytes32 id) external view returns (address);
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title ILendingPoolAddressesProvider interface
|
||||
* @notice provides the interface to fetch the LendingPoolCore address
|
||||
* @title LendingPoolAddressesProviderRegistry contract
|
||||
* @dev Main registry of LendingPoolAddressesProvider of multiple Aave protocol's markets
|
||||
* - Used for indexing purposes of Aave protocol's markets
|
||||
* - The id assigned to a LendingPoolAddressesProvider refers to the market it is connected with,
|
||||
* for example with `0` for the Aave main market and `1` for the next created
|
||||
* @author Aave
|
||||
**/
|
||||
interface ILendingPoolAddressesProviderRegistry {
|
||||
event AddressesProviderRegistered(address indexed newAddress);
|
||||
|
@ -11,8 +15,6 @@ interface ILendingPoolAddressesProviderRegistry {
|
|||
|
||||
function getAddressesProvidersList() external view returns (address[] memory);
|
||||
|
||||
function isAddressesProviderRegistered(address provider) external view returns (uint256);
|
||||
|
||||
function getAddressesProviderIdByAddress(address addressesProvider)
|
||||
external
|
||||
view
|
||||
|
|
53
contracts/interfaces/ILendingPoolCollateralManager.sol
Normal file
53
contracts/interfaces/ILendingPoolCollateralManager.sol
Normal file
|
@ -0,0 +1,53 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title ILendingPoolCollateralManager interface
|
||||
* @author Aave
|
||||
* @notice Defines the actions involving management of collateral in the protocol.
|
||||
**/
|
||||
interface ILendingPoolCollateralManager {
|
||||
/**
|
||||
* @dev emitted when a borrower is liquidated
|
||||
* @param collateral the address of the collateral being liquidated
|
||||
* @param principal the address of the reserve
|
||||
* @param user the address of the user being liquidated
|
||||
* @param debtToCover the total amount liquidated
|
||||
* @param liquidatedCollateralAmount the amount of collateral being liquidated
|
||||
* @param liquidator the address of the liquidator
|
||||
* @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise
|
||||
**/
|
||||
event LiquidationCall(
|
||||
address indexed collateral,
|
||||
address indexed principal,
|
||||
address indexed user,
|
||||
uint256 debtToCover,
|
||||
uint256 liquidatedCollateralAmount,
|
||||
address liquidator,
|
||||
bool receiveAToken
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when a user disables a reserve as collateral
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
**/
|
||||
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
|
||||
|
||||
/**
|
||||
* @dev users can invoke this function to liquidate an undercollateralized position.
|
||||
* @param collateral the address of the collateral to liquidated
|
||||
* @param principal the address of the principal reserve
|
||||
* @param user the address of the borrower
|
||||
* @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
|
||||
* he wants to receive the underlying asset directly
|
||||
**/
|
||||
function liquidationCall(
|
||||
address collateral,
|
||||
address principal,
|
||||
address user,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external returns (uint256, string memory);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title ILendingRateOracle interface
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/************
|
||||
@title IPriceOracle interface
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title IPriceOracleGetter interface
|
||||
|
|
|
@ -1,27 +1,16 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
@title IReserveInterestRateStrategyInterface interface
|
||||
@notice Interface for the calculation of the interest rates.
|
||||
*/
|
||||
|
||||
* @title IReserveInterestRateStrategyInterface interface
|
||||
* @dev Interface for the calculation of the interest rates
|
||||
* @author Aave
|
||||
*/
|
||||
interface IReserveInterestRateStrategy {
|
||||
/**
|
||||
* @dev returns the base variable borrow rate, in rays
|
||||
*/
|
||||
function baseVariableBorrowRate() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev returns the maximum variable borrow rate
|
||||
*/
|
||||
function getMaxVariableBorrowRate() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @dev calculates the liquidity, stable, and variable rates depending on the current utilization rate
|
||||
* and the base parameters
|
||||
*
|
||||
*/
|
||||
function calculateInterestRates(
|
||||
address reserve,
|
||||
uint256 utilizationRate,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IUniswapExchange {
|
||||
event TokenPurchase(
|
||||
|
|
|
@ -1,340 +0,0 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {SafeMath} from '../dependencies/openzeppelin/contracts//SafeMath.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts//IERC20.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolCollateralManager contract
|
||||
* @author Aave
|
||||
* @notice Implements actions involving management of collateral in the protocol.
|
||||
* @notice this contract will be ran always through delegatecall
|
||||
* @dev LendingPoolCollateralManager inherits VersionedInitializable from OpenZeppelin to have the same storage layout as LendingPool
|
||||
**/
|
||||
contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStorage {
|
||||
using SafeERC20 for IERC20;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
|
||||
// IMPORTANT The storage layout of the LendingPool is reproduced here because this contract
|
||||
// is gonna be used through DELEGATECALL
|
||||
|
||||
uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;
|
||||
|
||||
/**
|
||||
* @dev emitted when a borrower is liquidated
|
||||
* @param collateral the address of the collateral being liquidated
|
||||
* @param principal the address of the reserve
|
||||
* @param user the address of the user being liquidated
|
||||
* @param purchaseAmount the total amount liquidated
|
||||
* @param liquidatedCollateralAmount the amount of collateral being liquidated
|
||||
* @param liquidator the address of the liquidator
|
||||
* @param receiveAToken true if the liquidator wants to receive aTokens, false otherwise
|
||||
**/
|
||||
event LiquidationCall(
|
||||
address indexed collateral,
|
||||
address indexed principal,
|
||||
address indexed user,
|
||||
uint256 purchaseAmount,
|
||||
uint256 liquidatedCollateralAmount,
|
||||
address liquidator,
|
||||
bool receiveAToken
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev emitted when a user disables a reserve as collateral
|
||||
* @param reserve the address of the reserve
|
||||
* @param user the address of the user
|
||||
**/
|
||||
event ReserveUsedAsCollateralDisabled(address indexed reserve, address indexed user);
|
||||
|
||||
struct LiquidationCallLocalVars {
|
||||
uint256 userCollateralBalance;
|
||||
uint256 userStableDebt;
|
||||
uint256 userVariableDebt;
|
||||
uint256 maxPrincipalAmountToLiquidate;
|
||||
uint256 actualAmountToLiquidate;
|
||||
uint256 liquidationRatio;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 userStableRate;
|
||||
uint256 maxCollateralToLiquidate;
|
||||
uint256 principalAmountNeeded;
|
||||
uint256 healthFactor;
|
||||
IAToken collateralAtoken;
|
||||
bool isCollateralEnabled;
|
||||
ReserveLogic.InterestRateMode borrowRateMode;
|
||||
address principalAToken;
|
||||
uint256 errorCode;
|
||||
string errorMsg;
|
||||
}
|
||||
|
||||
struct AvailableCollateralToLiquidateLocalVars {
|
||||
uint256 userCompoundedBorrowBalance;
|
||||
uint256 liquidationBonus;
|
||||
uint256 collateralPrice;
|
||||
uint256 principalCurrencyPrice;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 principalDecimals;
|
||||
uint256 collateralDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev as the contract extends the VersionedInitializable contract to match the state
|
||||
* of the LendingPool contract, the getRevision() function is needed.
|
||||
*/
|
||||
function getRevision() internal override pure returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev users can invoke this function to liquidate an undercollateralized position.
|
||||
* @param collateral the address of the collateral to liquidated
|
||||
* @param principal the address of the principal reserve
|
||||
* @param user the address of the borrower
|
||||
* @param purchaseAmount the amount of principal that the liquidator wants to repay
|
||||
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if
|
||||
* he wants to receive the underlying asset directly
|
||||
**/
|
||||
function liquidationCall(
|
||||
address collateral,
|
||||
address principal,
|
||||
address user,
|
||||
uint256 purchaseAmount,
|
||||
bool receiveAToken
|
||||
) external returns (uint256, string memory) {
|
||||
ReserveLogic.ReserveData storage collateralReserve = _reserves[collateral];
|
||||
ReserveLogic.ReserveData storage principalReserve = _reserves[principal];
|
||||
UserConfiguration.Map storage userConfig = _usersConfig[user];
|
||||
|
||||
LiquidationCallLocalVars memory vars;
|
||||
|
||||
(, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData(
|
||||
user,
|
||||
_reserves,
|
||||
userConfig,
|
||||
_reservesList,
|
||||
_reservesCount,
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
//if the user hasn't borrowed the specific currency defined by asset, it cannot be liquidated
|
||||
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(
|
||||
user,
|
||||
principalReserve
|
||||
);
|
||||
|
||||
(vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
|
||||
collateralReserve,
|
||||
principalReserve,
|
||||
userConfig,
|
||||
vars.healthFactor,
|
||||
vars.userStableDebt,
|
||||
vars.userVariableDebt
|
||||
);
|
||||
|
||||
if (Errors.CollateralManagerErrors(vars.errorCode) != Errors.CollateralManagerErrors.NO_ERROR) {
|
||||
return (vars.errorCode, vars.errorMsg);
|
||||
}
|
||||
|
||||
vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
|
||||
|
||||
vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
|
||||
|
||||
vars.maxPrincipalAmountToLiquidate = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
|
||||
LIQUIDATION_CLOSE_FACTOR_PERCENT
|
||||
);
|
||||
|
||||
vars.actualAmountToLiquidate = purchaseAmount > vars.maxPrincipalAmountToLiquidate
|
||||
? vars.maxPrincipalAmountToLiquidate
|
||||
: purchaseAmount;
|
||||
|
||||
(
|
||||
vars.maxCollateralToLiquidate,
|
||||
vars.principalAmountNeeded
|
||||
) = _calculateAvailableCollateralToLiquidate(
|
||||
collateralReserve,
|
||||
principalReserve,
|
||||
collateral,
|
||||
principal,
|
||||
vars.actualAmountToLiquidate,
|
||||
vars.userCollateralBalance
|
||||
);
|
||||
|
||||
//if principalAmountNeeded < vars.ActualAmountToLiquidate, there isn't enough
|
||||
//of collateral to cover the actual amount that is being liquidated, hence we liquidate
|
||||
//a smaller amount
|
||||
|
||||
if (vars.principalAmountNeeded < vars.actualAmountToLiquidate) {
|
||||
vars.actualAmountToLiquidate = vars.principalAmountNeeded;
|
||||
}
|
||||
|
||||
//if liquidator reclaims the underlying asset, we make sure there is enough available collateral in the reserve
|
||||
if (!receiveAToken) {
|
||||
uint256 currentAvailableCollateral = IERC20(collateral).balanceOf(
|
||||
address(vars.collateralAtoken)
|
||||
);
|
||||
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
||||
return (
|
||||
uint256(Errors.CollateralManagerErrors.NOT_ENOUGH_LIQUIDITY),
|
||||
Errors.LPCM_NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//update the principal reserve
|
||||
principalReserve.updateState();
|
||||
|
||||
if (vars.userVariableDebt >= vars.actualAmountToLiquidate) {
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate,
|
||||
principalReserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
//if the user does not have variable debt, no need to try to burn variable
|
||||
//debt tokens
|
||||
if (vars.userVariableDebt > 0) {
|
||||
IVariableDebtToken(principalReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.userVariableDebt,
|
||||
principalReserve.variableBorrowIndex
|
||||
);
|
||||
}
|
||||
IStableDebtToken(principalReserve.stableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualAmountToLiquidate.sub(vars.userVariableDebt)
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
//otherwise receives the underlying asset
|
||||
|
||||
//updating collateral reserve
|
||||
collateralReserve.updateState();
|
||||
collateralReserve.updateInterestRates(
|
||||
collateral,
|
||||
address(vars.collateralAtoken),
|
||||
0,
|
||||
vars.maxCollateralToLiquidate
|
||||
);
|
||||
|
||||
//burn the equivalent amount of atoken
|
||||
vars.collateralAtoken.burn(
|
||||
user,
|
||||
msg.sender,
|
||||
vars.maxCollateralToLiquidate,
|
||||
collateralReserve.liquidityIndex
|
||||
);
|
||||
}
|
||||
|
||||
//if the collateral being liquidated is equal to the user balance,
|
||||
//we set the currency as not being used as collateral anymore
|
||||
|
||||
if (vars.maxCollateralToLiquidate == vars.userCollateralBalance) {
|
||||
userConfig.setUsingAsCollateral(collateralReserve.id, false);
|
||||
emit ReserveUsedAsCollateralDisabled(collateral, user);
|
||||
}
|
||||
|
||||
//transfers the principal currency to the aToken
|
||||
IERC20(principal).safeTransferFrom(
|
||||
msg.sender,
|
||||
principalReserve.aTokenAddress,
|
||||
vars.actualAmountToLiquidate
|
||||
);
|
||||
|
||||
emit LiquidationCall(
|
||||
collateral,
|
||||
principal,
|
||||
user,
|
||||
vars.actualAmountToLiquidate,
|
||||
vars.maxCollateralToLiquidate,
|
||||
msg.sender,
|
||||
receiveAToken
|
||||
);
|
||||
|
||||
return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev calculates how much of a specific collateral can be liquidated, given
|
||||
* a certain amount of principal currency. This function needs to be called after
|
||||
* all the checks to validate the liquidation have been performed, otherwise it might fail.
|
||||
* @param collateralAddress the collateral to be liquidated
|
||||
* @param principalAddress the principal currency to be liquidated
|
||||
* @param purchaseAmount the amount of principal 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 principalAmountNeeded the purchase amount
|
||||
**/
|
||||
function _calculateAvailableCollateralToLiquidate(
|
||||
ReserveLogic.ReserveData storage collateralReserve,
|
||||
ReserveLogic.ReserveData storage principalReserve,
|
||||
address collateralAddress,
|
||||
address principalAddress,
|
||||
uint256 purchaseAmount,
|
||||
uint256 userCollateralBalance
|
||||
) internal view returns (uint256, uint256) {
|
||||
uint256 collateralAmount = 0;
|
||||
uint256 principalAmountNeeded = 0;
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle());
|
||||
|
||||
AvailableCollateralToLiquidateLocalVars memory vars;
|
||||
|
||||
vars.collateralPrice = oracle.getAssetPrice(collateralAddress);
|
||||
vars.principalCurrencyPrice = oracle.getAssetPrice(principalAddress);
|
||||
|
||||
(, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
|
||||
.configuration
|
||||
.getParams();
|
||||
vars.principalDecimals = principalReserve.configuration.getDecimals();
|
||||
|
||||
//this is the maximum possible amount of the selected collateral that can be liquidated, given the
|
||||
//max amount of principal currency that is available for liquidation.
|
||||
vars.maxAmountCollateralToLiquidate = vars
|
||||
.principalCurrencyPrice
|
||||
.mul(purchaseAmount)
|
||||
.mul(10**vars.collateralDecimals)
|
||||
.percentMul(vars.liquidationBonus)
|
||||
.div(vars.collateralPrice.mul(10**vars.principalDecimals));
|
||||
|
||||
if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) {
|
||||
collateralAmount = userCollateralBalance;
|
||||
principalAmountNeeded = vars
|
||||
.collateralPrice
|
||||
.mul(collateralAmount)
|
||||
.mul(10**vars.principalDecimals)
|
||||
.div(vars.principalCurrencyPrice.mul(10**vars.collateralDecimals))
|
||||
.percentDiv(vars.liquidationBonus);
|
||||
} else {
|
||||
collateralAmount = vars.maxAmountCollateralToLiquidate;
|
||||
principalAmountNeeded = purchaseAmount;
|
||||
}
|
||||
return (collateralAmount, principalAmountNeeded);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {DebtTokenBase} from '../../tokenization/base/DebtTokenBase.sol';
|
||||
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
||||
|
||||
/**
|
||||
* @title Helpers library
|
||||
* @author Aave
|
||||
* @notice Implements calculation helpers.
|
||||
*/
|
||||
library Helpers {
|
||||
/**
|
||||
* @dev fetches the user current stable and variable debt balances
|
||||
* @param user the user
|
||||
* @param reserve the reserve object
|
||||
* @return the stable and variable debt balance
|
||||
**/
|
||||
function getUserCurrentDebt(address user, ReserveLogic.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
|
||||
function getUserCurrentDebtMemory(address user, ReserveLogic.ReserveData memory reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import 'hardhat/console.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract AaveProtocolDataProvider {
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
address constant MKR = 0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2;
|
||||
address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
@ -56,7 +55,7 @@ contract AaveProtocolDataProvider {
|
|||
address[] memory reserves = pool.getReservesList();
|
||||
TokenData[] memory aTokens = new TokenData[](reserves.length);
|
||||
for (uint256 i = 0; i < reserves.length; i++) {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(reserves[i]);
|
||||
aTokens[i] = TokenData({
|
||||
symbol: IERC20Detailed(reserveData.aTokenAddress).symbol(),
|
||||
tokenAddress: reserveData.aTokenAddress
|
||||
|
@ -81,10 +80,8 @@ contract AaveProtocolDataProvider {
|
|||
bool isFrozen
|
||||
)
|
||||
{
|
||||
ReserveConfiguration.Map memory configuration = ILendingPool(
|
||||
ADDRESSES_PROVIDER.getLendingPool()
|
||||
)
|
||||
.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory configuration =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
|
||||
|
||||
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
|
||||
.getParamsMemory();
|
||||
|
@ -111,8 +108,8 @@ contract AaveProtocolDataProvider {
|
|||
uint40 lastUpdateTimestamp
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||
.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
return (
|
||||
IERC20Detailed(asset).balanceOf(reserve.aTokenAddress),
|
||||
|
@ -143,11 +140,11 @@ contract AaveProtocolDataProvider {
|
|||
bool usageAsCollateralEnabled
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||
.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
UserConfiguration.Map memory userConfig = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||
.getUserConfiguration(user);
|
||||
DataTypes.UserConfigurationMap memory userConfig =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getUserConfiguration(user);
|
||||
|
||||
currentATokenBalance = IERC20Detailed(reserve.aTokenAddress).balanceOf(user);
|
||||
currentVariableDebt = IERC20Detailed(reserve.variableDebtTokenAddress).balanceOf(user);
|
||||
|
@ -171,8 +168,8 @@ contract AaveProtocolDataProvider {
|
|||
address variableDebtTokenAddress
|
||||
)
|
||||
{
|
||||
ReserveLogic.ReserveData memory reserve = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
|
||||
.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserve =
|
||||
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getReserveData(asset);
|
||||
|
||||
return (
|
||||
reserve.aTokenAddress,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
|
@ -7,22 +7,22 @@ import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol';
|
|||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol';
|
||||
import {IVariableDebtToken} from '../protocol/tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {IStableDebtToken} from '../protocol/tokenization/interfaces/IStableDebtToken.sol';
|
||||
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {WadRayMath} from '../protocol/libraries/math/WadRayMath.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {
|
||||
DefaultReserveInterestRateStrategy
|
||||
} from '../lendingpool/DefaultReserveInterestRateStrategy.sol';
|
||||
} from '../protocol/lendingpool/DefaultReserveInterestRateStrategy.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract UiPoolDataProvider is IUiPoolDataProvider {
|
||||
using WadRayMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
|
||||
|
||||
|
@ -46,8 +46,8 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
|
||||
function getReservesData(ILendingPoolAddressesProvider provider, address user)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (
|
||||
AggregatedReserveData[] memory,
|
||||
UserReserveData[] memory,
|
||||
|
@ -57,21 +57,19 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
|
|||
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle());
|
||||
address[] memory reserves = lendingPool.getReservesList();
|
||||
UserConfiguration.Map memory userConfig = lendingPool.getUserConfiguration(user);
|
||||
DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user);
|
||||
|
||||
AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
|
||||
UserReserveData[] memory userReservesData = new UserReserveData[](
|
||||
user != address(0) ? reserves.length : 0
|
||||
);
|
||||
UserReserveData[] memory userReservesData =
|
||||
new UserReserveData[](user != address(0) ? reserves.length : 0);
|
||||
|
||||
for (uint256 i = 0; i < reserves.length; i++) {
|
||||
AggregatedReserveData memory reserveData = reservesData[i];
|
||||
reserveData.underlyingAsset = reserves[i];
|
||||
|
||||
// reserve current state
|
||||
ReserveLogic.ReserveData memory baseData = lendingPool.getReserveData(
|
||||
reserveData.underlyingAsset
|
||||
);
|
||||
DataTypes.ReserveData memory baseData =
|
||||
lendingPool.getReserveData(reserveData.underlyingAsset);
|
||||
reserveData.liquidityIndex = baseData.liquidityIndex;
|
||||
reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
|
||||
reserveData.liquidityRate = baseData.currentLiquidityRate;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {IWETH} from './interfaces/IWETH.sol';
|
||||
import {IWETHGateway} from './interfaces/IWETHGateway.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {IAToken} from '../protocol/tokenization/interfaces/IAToken.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../protocol/libraries/configuration/UserConfiguration.sol';
|
||||
import {Helpers} from '../protocol/libraries/helpers/Helpers.sol';
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
contract WETHGateway is IWETHGateway, Ownable {
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
IWETH internal immutable WETH;
|
||||
ILendingPool internal immutable POOL;
|
||||
|
@ -40,7 +40,7 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
* @param onBehalfOf address of the user who will receive the aTokens representing the deposit
|
||||
* @param referralCode integrators are assigned a referral code and can potentially receive rewards.
|
||||
**/
|
||||
function depositETH(address onBehalfOf, uint16 referralCode) external override payable {
|
||||
function depositETH(address onBehalfOf, uint16 referralCode) external payable override {
|
||||
WETH.deposit{value: msg.value}();
|
||||
POOL.deposit(address(WETH), msg.value, onBehalfOf, referralCode);
|
||||
}
|
||||
|
@ -74,16 +74,14 @@ contract WETHGateway is IWETHGateway, Ownable {
|
|||
uint256 amount,
|
||||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external override payable {
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebtMemory(
|
||||
onBehalfOf,
|
||||
POOL.getReserveData(address(WETH))
|
||||
);
|
||||
) external payable override {
|
||||
(uint256 stableDebt, uint256 variableDebt) =
|
||||
Helpers.getUserCurrentDebtMemory(onBehalfOf, POOL.getReserveData(address(WETH)));
|
||||
|
||||
uint256 paybackAmount = ReserveLogic.InterestRateMode(rateMode) ==
|
||||
ReserveLogic.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
uint256 paybackAmount =
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
if (amount < paybackAmount) {
|
||||
paybackAmount = amount;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
|
@ -9,7 +9,8 @@ import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
|||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {ReserveConfiguration} from '../protocol/libraries/configuration/ReserveConfiguration.sol';
|
||||
import {DataTypes} from '../protocol/libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title WalletBalanceProvider contract
|
||||
|
@ -22,15 +23,10 @@ contract WalletBalanceProvider {
|
|||
using Address for address payable;
|
||||
using Address for address;
|
||||
using SafeERC20 for IERC20;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
ILendingPoolAddressesProvider internal immutable _provider;
|
||||
address constant MOCK_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
|
||||
constructor(ILendingPoolAddressesProvider provider) public {
|
||||
_provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
@dev Fallback function, don't accept any ETH
|
||||
**/
|
||||
|
@ -80,12 +76,12 @@ contract WalletBalanceProvider {
|
|||
/**
|
||||
@dev provides balances of user wallet for all reserves available on the pool
|
||||
*/
|
||||
function getUserWalletBalances(address user)
|
||||
function getUserWalletBalances(address provider, address user)
|
||||
external
|
||||
view
|
||||
returns (address[] memory, uint256[] memory)
|
||||
{
|
||||
ILendingPool pool = ILendingPool(_provider.getLendingPool());
|
||||
ILendingPool pool = ILendingPool(ILendingPoolAddressesProvider(provider).getLendingPool());
|
||||
|
||||
address[] memory reserves = pool.getReservesList();
|
||||
address[] memory reservesWithEth = new address[](reserves.length + 1);
|
||||
|
@ -97,7 +93,7 @@ contract WalletBalanceProvider {
|
|||
uint256[] memory balances = new uint256[](reservesWithEth.length);
|
||||
|
||||
for (uint256 j = 0; j < reserves.length; j++) {
|
||||
ReserveConfiguration.Map memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(reservesWithEth[j]);
|
||||
|
||||
(bool isActive, , , ) = configuration.getFlagsMemory();
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
contract IERC20DetailedBytes {
|
||||
bytes32 public name;
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ReserveLogic} from '../../libraries/logic/ReserveLogic.sol';
|
||||
|
||||
interface IUiPoolDataProvider {
|
||||
struct AggregatedReserveData {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity >=0.6.2;
|
||||
|
||||
interface IUniswapV2Router01 {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity >=0.6.2;
|
||||
|
||||
import './IUniswapV2Router01.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IWETH {
|
||||
function deposit() external payable;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IWETHGateway {
|
||||
function depositETH(address onBehalfOf, uint16 referralCode) external payable;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
contract SelfdestructTransfer {
|
||||
function destroyAndTransfer(address payable to) external payable {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pragma solidity >=0.4.22 <=0.6.8;
|
||||
pragma solidity >=0.4.22 <=0.6.12;
|
||||
|
||||
contract WETH9 {
|
||||
string public name = 'Wrapped Ether';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
contract MockAggregator {
|
||||
int256 private _latestAnswer;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface ChainlinkUSDETHOracleI {
|
||||
event AnswerUpdated(int256 indexed current, uint256 indexed answerId);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface GenericOracleI {
|
||||
// ganache
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IExtendedPriceAggregator {
|
||||
event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 timestamp);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ILendingRateOracle} from '../../interfaces/ILendingRateOracle.sol';
|
||||
import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IPriceOracle} from '../../interfaces/IPriceOracle.sol';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol';
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol';
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pragma solidity >=0.4.22 <=0.6.8;
|
||||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity >=0.4.22 <=0.6.12;
|
||||
|
||||
import {WETH9} from '../dependencies/weth/WETH9.sol';
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {AToken} from '../../tokenization/AToken.sol';
|
||||
import {LendingPool} from '../../lendingpool/LendingPool.sol';
|
||||
import {AToken} from '../../protocol/tokenization/AToken.sol';
|
||||
import {LendingPool} from '../../protocol/lendingpool/LendingPool.sol';
|
||||
|
||||
contract MockAToken is AToken {
|
||||
constructor(
|
||||
|
@ -24,7 +24,7 @@ contract MockAToken is AToken {
|
|||
)
|
||||
{}
|
||||
|
||||
function getRevision() internal override pure returns (uint256) {
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {StableDebtToken} from '../../tokenization/StableDebtToken.sol';
|
||||
import {StableDebtToken} from '../../protocol/tokenization/StableDebtToken.sol';
|
||||
|
||||
contract MockStableDebtToken is StableDebtToken {
|
||||
constructor(
|
||||
|
@ -15,7 +15,7 @@ contract MockStableDebtToken is StableDebtToken {
|
|||
StableDebtToken(_pool, _underlyingAssetAddress, _tokenName, _tokenSymbol, incentivesController)
|
||||
{}
|
||||
|
||||
function getRevision() internal override pure returns (uint256) {
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {VariableDebtToken} from '../../tokenization/VariableDebtToken.sol';
|
||||
import {VariableDebtToken} from '../../protocol/tokenization/VariableDebtToken.sol';
|
||||
|
||||
contract MockVariableDebtToken is VariableDebtToken {
|
||||
constructor(
|
||||
|
@ -21,7 +21,7 @@ contract MockVariableDebtToken is VariableDebtToken {
|
|||
)
|
||||
{}
|
||||
|
||||
function getRevision() internal override pure returns (uint256) {
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0x2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
|
||||
// Prettier ignore to prevent buidler flatter bug
|
||||
// prettier-ignore
|
||||
import {InitializableImmutableAdminUpgradeabilityProxy} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
|
||||
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolAddressesProvider contract
|
||||
* @notice Is the main registry of the protocol. All the different components of the protocol are accessible
|
||||
* through the addresses provider.
|
||||
* @dev Main registry of addresses part of or connected to the protocol, including permissioned roles
|
||||
* - Acting also as factory of proxies and admin of those, so with right to change its implementations
|
||||
* - Owned by the Aave Governance
|
||||
* @author Aave
|
||||
**/
|
||||
|
||||
contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider {
|
||||
mapping(bytes32 => address) private _addresses;
|
||||
|
||||
|
@ -28,28 +28,30 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
bytes32 private constant LENDING_RATE_ORACLE = 'LENDING_RATE_ORACLE';
|
||||
|
||||
/**
|
||||
* @dev Sets an address for an id by updating a proxy implementation
|
||||
* @dev General function to update the implementation of a proxy registered with
|
||||
* certain `id`. If there is no proxy registered, it will instantiate one and
|
||||
* set as implementation the `implementationAddress`
|
||||
* IMPORTANT Use this function carefully, only for ids that don't have an explicit
|
||||
* setter function, in order to avoid unexpected consequences
|
||||
* @param id The id
|
||||
* @param implementationAddress The address of the implementation if we want it covered by a proxy
|
||||
* address(0) if we don't want a proxy covering
|
||||
* @param implementationAddress The address of the new implementation
|
||||
*/
|
||||
function setAddressAsProxy(
|
||||
bytes32 id,
|
||||
address implementationAddress
|
||||
) external override onlyOwner {
|
||||
function setAddressAsProxy(bytes32 id, address implementationAddress)
|
||||
external
|
||||
override
|
||||
onlyOwner
|
||||
{
|
||||
_updateImpl(id, implementationAddress);
|
||||
emit AddressSet(id, implementationAddress, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets an address for an id replacing the address saved in the addresses map
|
||||
* IMPORTANT Use this function carefully, as it will do a hard replacement
|
||||
* @param id The id
|
||||
* @param newAddress The address to set, pass address(0) if a proxy is needed
|
||||
* @param newAddress The address to set
|
||||
*/
|
||||
function setAddress(
|
||||
bytes32 id,
|
||||
address newAddress
|
||||
) external override onlyOwner {
|
||||
function setAddress(bytes32 id, address newAddress) external override onlyOwner {
|
||||
_addresses[id] = newAddress;
|
||||
emit AddressSet(id, newAddress, false);
|
||||
}
|
||||
|
@ -58,21 +60,22 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
* @dev Returns an address by id
|
||||
* @return The address
|
||||
*/
|
||||
function getAddress(bytes32 id) public override view returns (address) {
|
||||
function getAddress(bytes32 id) public view override returns (address) {
|
||||
return _addresses[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the address of the LendingPool proxy
|
||||
* @return the lending pool proxy address
|
||||
* @dev Returns the address of the LendingPool proxy
|
||||
* @return The LendingPool proxy address
|
||||
**/
|
||||
function getLendingPool() external override view returns (address) {
|
||||
function getLendingPool() external view override returns (address) {
|
||||
return getAddress(LENDING_POOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the implementation of the lending pool
|
||||
* @param pool the new lending pool implementation
|
||||
* @dev Updates the implementation of the LendingPool, or creates the proxy
|
||||
* setting the new `pool` implementation on the first time calling it
|
||||
* @param pool The new LendingPool implementation
|
||||
**/
|
||||
function setLendingPoolImpl(address pool) external override onlyOwner {
|
||||
_updateImpl(LENDING_POOL, pool);
|
||||
|
@ -80,16 +83,17 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev returns the address of the LendingPoolConfigurator proxy
|
||||
* @return the lending pool configurator proxy address
|
||||
* @dev Returns the address of the LendingPoolConfigurator proxy
|
||||
* @return The LendingPoolConfigurator proxy address
|
||||
**/
|
||||
function getLendingPoolConfigurator() external override view returns (address) {
|
||||
function getLendingPoolConfigurator() external view override returns (address) {
|
||||
return getAddress(LENDING_POOL_CONFIGURATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the implementation of the lending pool configurator
|
||||
* @param configurator the new lending pool configurator implementation
|
||||
* @dev Updates the implementation of the LendingPoolConfigurator, or creates the proxy
|
||||
* setting the new `configurator` implementation on the first time calling it
|
||||
* @param configurator The new LendingPoolConfigurator implementation
|
||||
**/
|
||||
function setLendingPoolConfiguratorImpl(address configurator) external override onlyOwner {
|
||||
_updateImpl(LENDING_POOL_CONFIGURATOR, configurator);
|
||||
|
@ -97,19 +101,19 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev returns the address of the LendingPoolCollateralManager. Since the manager is used
|
||||
* @dev Returns the address of the LendingPoolCollateralManager. Since the manager is used
|
||||
* through delegateCall within the LendingPool contract, the proxy contract pattern does not work properly hence
|
||||
* the addresses are changed directly.
|
||||
* @return the address of the Lending pool collateral manager
|
||||
* the addresses are changed directly
|
||||
* @return The address of the LendingPoolCollateralManager
|
||||
**/
|
||||
|
||||
function getLendingPoolCollateralManager() external override view returns (address) {
|
||||
function getLendingPoolCollateralManager() external view override returns (address) {
|
||||
return getAddress(LENDING_POOL_COLLATERAL_MANAGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev updates the address of the Lending pool collateral manager
|
||||
* @param manager the new lending pool collateral manager address
|
||||
* @dev Updates the address of the LendingPoolCollateralManager
|
||||
* @param manager The new LendingPoolCollateralManager address
|
||||
**/
|
||||
function setLendingPoolCollateralManager(address manager) external override onlyOwner {
|
||||
_addresses[LENDING_POOL_COLLATERAL_MANAGER] = manager;
|
||||
|
@ -117,11 +121,11 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev the functions below are storing specific addresses that are outside the context of the protocol
|
||||
* hence the upgradable proxy pattern is not used
|
||||
* @dev The functions below are getters/setters of addresses that are outside the context
|
||||
* of the protocol hence the upgradable proxy pattern is not used
|
||||
**/
|
||||
|
||||
function getPoolAdmin() external override view returns (address) {
|
||||
function getPoolAdmin() external view override returns (address) {
|
||||
return getAddress(POOL_ADMIN);
|
||||
}
|
||||
|
||||
|
@ -130,7 +134,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
emit ConfigurationAdminUpdated(admin);
|
||||
}
|
||||
|
||||
function getEmergencyAdmin() external override view returns (address) {
|
||||
function getEmergencyAdmin() external view override returns (address) {
|
||||
return getAddress(EMERGENCY_ADMIN);
|
||||
}
|
||||
|
||||
|
@ -139,7 +143,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
emit EmergencyAdminUpdated(emergencyAdmin);
|
||||
}
|
||||
|
||||
function getPriceOracle() external override view returns (address) {
|
||||
function getPriceOracle() external view override returns (address) {
|
||||
return getAddress(PRICE_ORACLE);
|
||||
}
|
||||
|
||||
|
@ -148,7 +152,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
emit PriceOracleUpdated(priceOracle);
|
||||
}
|
||||
|
||||
function getLendingRateOracle() external override view returns (address) {
|
||||
function getLendingRateOracle() external view override returns (address) {
|
||||
return getAddress(LENDING_RATE_ORACLE);
|
||||
}
|
||||
|
||||
|
@ -158,16 +162,19 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev internal function to update the implementation of a specific component of the protocol
|
||||
* @param id the id of the contract to be updated
|
||||
* @param newAddress the address of the new implementation
|
||||
* @dev Internal function to update the implementation of a specific proxied component of the protocol
|
||||
* - If there is no proxy registered in the given `id`, it creates the proxy setting `newAdress`
|
||||
* as implementation and calls the initialize() function on the proxy
|
||||
* - If there is already a proxy registered, it just updates the implementation to `newAddress` and
|
||||
* calls the initialize() function via upgradeToAndCall() in the proxy
|
||||
* @param id The id of the proxy to be updated
|
||||
* @param newAddress The address of the new implementation
|
||||
**/
|
||||
function _updateImpl(bytes32 id, address newAddress) internal {
|
||||
address payable proxyAddress = payable(_addresses[id]);
|
||||
|
||||
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy
|
||||
= InitializableImmutableAdminUpgradeabilityProxy(proxyAddress);
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
InitializableImmutableAdminUpgradeabilityProxy(proxyAddress);
|
||||
bytes memory params = abi.encodeWithSignature('initialize(address)', address(this));
|
||||
|
||||
if (proxyAddress == address(0)) {
|
|
@ -1,41 +1,29 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Ownable} from '../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {Ownable} from '../../dependencies/openzeppelin/contracts/Ownable.sol';
|
||||
import {
|
||||
ILendingPoolAddressesProviderRegistry
|
||||
} from '../interfaces/ILendingPoolAddressesProviderRegistry.sol';
|
||||
} from '../../interfaces/ILendingPoolAddressesProviderRegistry.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolAddressesProviderRegistry contract
|
||||
* @notice contains the list of active addresses providers
|
||||
* @dev Main registry of LendingPoolAddressesProvider of multiple Aave protocol's markets
|
||||
* - Used for indexing purposes of Aave protocol's markets
|
||||
* - The id assigned to a LendingPoolAddressesProvider refers to the market it is connected with,
|
||||
* for example with `0` for the Aave main market and `1` for the next created
|
||||
* @author Aave
|
||||
**/
|
||||
|
||||
contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesProviderRegistry {
|
||||
mapping(address => uint256) private _addressesProviders;
|
||||
address[] private _addressesProvidersList;
|
||||
|
||||
/**
|
||||
* @dev returns if an addressesProvider is registered or not
|
||||
* @param provider the addresses provider
|
||||
* @return The id of the addresses provider or 0 if the addresses provider not registered
|
||||
* @dev Returns the list of registered addresses provider
|
||||
* @return The list of addresses provider, potentially containing address(0) elements
|
||||
**/
|
||||
function isAddressesProviderRegistered(address provider)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _addressesProviders[provider];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the list of active addressesProviders
|
||||
* @return the list of addressesProviders, potentially containing address(0) elements
|
||||
**/
|
||||
function getAddressesProvidersList() external override view returns (address[] memory) {
|
||||
function getAddressesProvidersList() external view override returns (address[] memory) {
|
||||
address[] memory addressesProvidersList = _addressesProvidersList;
|
||||
|
||||
uint256 maxLength = addressesProvidersList.length;
|
||||
|
@ -52,8 +40,9 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev adds a lending pool to the list of registered lending pools
|
||||
* @param provider the pool address to be registered
|
||||
* @dev Registers an addresses provider
|
||||
* @param provider The address of the new LendingPoolAddressesProvider
|
||||
* @param id The id for the new LendingPoolAddressesProvider, referring to the market it belongs to
|
||||
**/
|
||||
function registerAddressesProvider(address provider, uint256 id) external override onlyOwner {
|
||||
require(id != 0, Errors.LPAPR_INVALID_ADDRESSES_PROVIDER_ID);
|
||||
|
@ -64,8 +53,8 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev removes a lending pool from the list of registered lending pools
|
||||
* @param provider the pool address to be unregistered
|
||||
* @dev Removes a LendingPoolAddressesProvider from the list of registered addresses provider
|
||||
* @param provider The LendingPoolAddressesProvider address
|
||||
**/
|
||||
function unregisterAddressesProvider(address provider) external override onlyOwner {
|
||||
require(_addressesProviders[provider] > 0, Errors.LPAPR_PROVIDER_NOT_REGISTERED);
|
||||
|
@ -74,9 +63,18 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev adds to the list of the addresses providers, if it wasn't already added before
|
||||
* @param provider the pool address to be added
|
||||
**/
|
||||
* @dev Returns the id on a registered LendingPoolAddressesProvider
|
||||
* @return The id or 0 if the LendingPoolAddressesProvider is not registered
|
||||
*/
|
||||
function getAddressesProviderIdByAddress(address addressesProvider)
|
||||
external
|
||||
view
|
||||
override
|
||||
returns (uint256)
|
||||
{
|
||||
return _addressesProviders[addressesProvider];
|
||||
}
|
||||
|
||||
function _addToAddressesProvidersList(address provider) internal {
|
||||
uint256 providersCount = _addressesProvidersList.length;
|
||||
|
||||
|
@ -88,17 +86,4 @@ contract LendingPoolAddressesProviderRegistry is Ownable, ILendingPoolAddressesP
|
|||
|
||||
_addressesProvidersList.push(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the id on an `addressesProvider` or address(0) if not registered
|
||||
* @return The id or 0 if the addresses provider is not registered
|
||||
*/
|
||||
function getAddressesProviderIdByAddress(address addressesProvider)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _addressesProviders[addressesProvider];
|
||||
}
|
||||
}
|
|
@ -1,63 +1,69 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {ILendingRateOracle} from '../interfaces/ILendingRateOracle.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingRateOracle} from '../../interfaces/ILendingRateOracle.sol';
|
||||
|
||||
/**
|
||||
* @title DefaultReserveInterestRateStrategy contract
|
||||
* @notice implements the calculation of the interest rates depending on the reserve parameters.
|
||||
* @dev if there is need to update the calculation of the interest rates for a specific reserve,
|
||||
* a new version of this contract will be deployed.
|
||||
* @notice Implements the calculation of the interest rates depending on the reserve state
|
||||
* @dev The model of interest rate is based on 2 slopes, one before the `OPTIMAL_UTILIZATION_RATE`
|
||||
* point of utilization and another from that one to 100%
|
||||
* - An instance of this same contract, can't be used across different Aave markets, due to the caching
|
||||
* of the LendingPoolAddressesProvider
|
||||
* @author Aave
|
||||
**/
|
||||
contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
||||
using WadRayMath for uint256;
|
||||
using SafeMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
/**
|
||||
* @dev this constant represents the utilization rate at which the pool aims to obtain most competitive borrow rates
|
||||
* expressed in ray
|
||||
**/
|
||||
uint256 public constant OPTIMAL_UTILIZATION_RATE = 0.8 * 1e27;
|
||||
|
||||
/**
|
||||
* @dev this constant represents the excess utilization rate above the optimal. It's always equal to
|
||||
* 1-optimal utilization rate. Added as a constant here for gas optimizations
|
||||
* expressed in ray
|
||||
* @dev this constant represents the utilization rate at which the pool aims to obtain most competitive borrow rates.
|
||||
* Expressed in ray
|
||||
**/
|
||||
uint256 public immutable OPTIMAL_UTILIZATION_RATE;
|
||||
|
||||
/**
|
||||
* @dev This constant represents the excess utilization rate above the optimal. It's always equal to
|
||||
* 1-optimal utilization rate. Added as a constant here for gas optimizations.
|
||||
* Expressed in ray
|
||||
**/
|
||||
|
||||
uint256 public constant EXCESS_UTILIZATION_RATE = 0.2 * 1e27;
|
||||
uint256 public immutable EXCESS_UTILIZATION_RATE;
|
||||
|
||||
LendingPoolAddressesProvider public immutable addressesProvider;
|
||||
ILendingPoolAddressesProvider public immutable addressesProvider;
|
||||
|
||||
//base variable borrow rate when Utilization rate = 0. Expressed in ray
|
||||
// Base variable borrow rate when Utilization rate = 0. Expressed in ray
|
||||
uint256 internal immutable _baseVariableBorrowRate;
|
||||
|
||||
//slope of the variable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
// Slope of the variable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
uint256 internal immutable _variableRateSlope1;
|
||||
|
||||
//slope of the variable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
// Slope of the variable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
uint256 internal immutable _variableRateSlope2;
|
||||
|
||||
//slope of the stable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
// Slope of the stable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
uint256 internal immutable _stableRateSlope1;
|
||||
|
||||
//slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
// Slope of the stable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray
|
||||
uint256 internal immutable _stableRateSlope2;
|
||||
|
||||
constructor(
|
||||
LendingPoolAddressesProvider provider,
|
||||
ILendingPoolAddressesProvider provider,
|
||||
uint256 optimalUtilizationRate,
|
||||
uint256 baseVariableBorrowRate,
|
||||
uint256 variableRateSlope1,
|
||||
uint256 variableRateSlope2,
|
||||
uint256 stableRateSlope1,
|
||||
uint256 stableRateSlope2
|
||||
) public {
|
||||
OPTIMAL_UTILIZATION_RATE = optimalUtilizationRate;
|
||||
EXCESS_UTILIZATION_RATE = WadRayMath.ray().sub(optimalUtilizationRate);
|
||||
addressesProvider = provider;
|
||||
_baseVariableBorrowRate = baseVariableBorrowRate;
|
||||
_variableRateSlope1 = variableRateSlope1;
|
||||
|
@ -66,10 +72,6 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
_stableRateSlope2 = stableRateSlope2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev accessors
|
||||
*/
|
||||
|
||||
function variableRateSlope1() external view returns (uint256) {
|
||||
return _variableRateSlope1;
|
||||
}
|
||||
|
@ -86,16 +88,16 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
return _stableRateSlope2;
|
||||
}
|
||||
|
||||
function baseVariableBorrowRate() external override view returns (uint256) {
|
||||
function baseVariableBorrowRate() external view override returns (uint256) {
|
||||
return _baseVariableBorrowRate;
|
||||
}
|
||||
|
||||
function getMaxVariableBorrowRate() external override view returns (uint256) {
|
||||
function getMaxVariableBorrowRate() external view override returns (uint256) {
|
||||
return _baseVariableBorrowRate.add(_variableRateSlope1).add(_variableRateSlope2);
|
||||
}
|
||||
|
||||
struct CalcInterestRatesLocalVars {
|
||||
uint256 totalBorrows;
|
||||
uint256 totalDebt;
|
||||
uint256 currentVariableBorrowRate;
|
||||
uint256 currentStableBorrowRate;
|
||||
uint256 currentLiquidityRate;
|
||||
|
@ -103,16 +105,14 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev calculates the interest rates depending on the available liquidity and the total borrowed.
|
||||
* @param reserve the address of the reserve
|
||||
* @param availableLiquidity the liquidity available in the reserve
|
||||
* @param totalStableDebt the total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt the total borrowed from the reserve at a variable rate
|
||||
* @param averageStableBorrowRate the weighted average of all the stable rate borrows
|
||||
* @param reserveFactor the reserve portion of the interest to redirect to the reserve treasury
|
||||
* @return currentLiquidityRate the liquidity rate
|
||||
* @return currentStableBorrowRate stable borrow rate
|
||||
* @return currentVariableBorrowRate variable borrow rate
|
||||
* @dev Calculates the interest rates depending on the reserve's state and configurations
|
||||
* @param reserve The address of the reserve
|
||||
* @param availableLiquidity The liquidity available in the reserve
|
||||
* @param totalStableDebt The total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt The total borrowed from the reserve at a variable rate
|
||||
* @param averageStableBorrowRate The weighted average of all the stable rate loans
|
||||
* @param reserveFactor The reserve portion of the interest that goes to the treasury of the market
|
||||
* @return The liquidity rate, the stable borrow rate and the variable borrow rate
|
||||
**/
|
||||
function calculateInterestRates(
|
||||
address reserve,
|
||||
|
@ -123,8 +123,8 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
uint256 reserveFactor
|
||||
)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
|
@ -133,22 +133,22 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
{
|
||||
CalcInterestRatesLocalVars memory vars;
|
||||
|
||||
vars.totalBorrows = totalStableDebt.add(totalVariableDebt);
|
||||
vars.totalDebt = totalStableDebt.add(totalVariableDebt);
|
||||
vars.currentVariableBorrowRate = 0;
|
||||
vars.currentStableBorrowRate = 0;
|
||||
vars.currentLiquidityRate = 0;
|
||||
|
||||
uint256 utilizationRate = vars.totalBorrows == 0
|
||||
? 0
|
||||
: vars.totalBorrows.rayDiv(availableLiquidity.add(vars.totalBorrows));
|
||||
uint256 utilizationRate =
|
||||
vars.totalDebt == 0
|
||||
? 0
|
||||
: vars.totalDebt.rayDiv(availableLiquidity.add(vars.totalDebt));
|
||||
|
||||
vars.currentStableBorrowRate = ILendingRateOracle(addressesProvider.getLendingRateOracle())
|
||||
.getMarketBorrowRate(reserve);
|
||||
|
||||
if (utilizationRate > OPTIMAL_UTILIZATION_RATE) {
|
||||
uint256 excessUtilizationRateRatio = utilizationRate.sub(OPTIMAL_UTILIZATION_RATE).rayDiv(
|
||||
EXCESS_UTILIZATION_RATE
|
||||
);
|
||||
uint256 excessUtilizationRateRatio =
|
||||
utilizationRate.sub(OPTIMAL_UTILIZATION_RATE).rayDiv(EXCESS_UTILIZATION_RATE);
|
||||
|
||||
vars.currentStableBorrowRate = vars.currentStableBorrowRate.add(_stableRateSlope1).add(
|
||||
_stableRateSlope2.rayMul(excessUtilizationRateRatio)
|
||||
|
@ -184,12 +184,12 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev calculates the overall borrow rate as the weighted average between the total variable borrows and total stable borrows.
|
||||
* @param totalStableDebt the total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt the total borrowed from the reserve at a variable rate
|
||||
* @param currentVariableBorrowRate the current variable borrow rate
|
||||
* @param currentAverageStableBorrowRate the weighted average of all the stable rate borrows
|
||||
* @return the weighted averaged borrow rate
|
||||
* @dev Calculates the overall borrow rate as the weighted average between the total variable debt and total stable debt
|
||||
* @param totalStableDebt The total borrowed from the reserve a stable rate
|
||||
* @param totalVariableDebt The total borrowed from the reserve at a variable rate
|
||||
* @param currentVariableBorrowRate The current variable borrow rate of the reserve
|
||||
* @param currentAverageStableBorrowRate The current weighted average of all the stable rate loans
|
||||
* @return The weighted averaged borrow rate
|
||||
**/
|
||||
function _getOverallBorrowRate(
|
||||
uint256 totalStableDebt,
|
||||
|
@ -197,17 +197,16 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
|
|||
uint256 currentVariableBorrowRate,
|
||||
uint256 currentAverageStableBorrowRate
|
||||
) internal pure returns (uint256) {
|
||||
uint256 totalBorrows = totalStableDebt.add(totalVariableDebt);
|
||||
uint256 totalDebt = totalStableDebt.add(totalVariableDebt);
|
||||
|
||||
if (totalBorrows == 0) return 0;
|
||||
if (totalDebt == 0) return 0;
|
||||
|
||||
uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);
|
||||
|
||||
uint256 weightedStableRate = totalStableDebt.wadToRay().rayMul(currentAverageStableBorrowRate);
|
||||
|
||||
uint256 overallBorrowRate = weightedVariableRate.add(weightedStableRate).rayDiv(
|
||||
totalBorrows.wadToRay()
|
||||
);
|
||||
uint256 overallBorrowRate =
|
||||
weightedVariableRate.add(weightedStableRate).rayDiv(totalDebt.wadToRay());
|
||||
|
||||
return overallBorrowRate;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
|
@ -18,18 +18,29 @@ import {ReserveConfiguration} from '../libraries/configuration/ReserveConfigurat
|
|||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {DebtTokenBase} from '../tokenization/base/DebtTokenBase.sol';
|
||||
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||
import {LendingPoolCollateralManager} from './LendingPoolCollateralManager.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {IFlashLoanReceiver} from '../../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
import {Address} from '../dependencies/openzeppelin/contracts/Address.sol';
|
||||
import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @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 market
|
||||
* - All admin functions are callable by the LendingPoolConfigurator contract defined also in the
|
||||
* LendingPoolAddressesProvider
|
||||
* @author Aave
|
||||
**/
|
||||
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 LENDINGPOOL_REVISION = 0x2;
|
||||
|
||||
/**
|
||||
* @dev functions marked by this modifier can only be called when the protocol is not paused
|
||||
**/
|
||||
modifier whenNotPaused() {
|
||||
_whenNotPaused();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev functions marked by this modifier can only be called by the LendingPoolConfigurator
|
||||
**/
|
||||
modifier onlyLendingPoolConfigurator() {
|
||||
_onlyLendingPoolConfigurator();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev only lending pools configurator can use functions affected by this modifier
|
||||
**/
|
||||
function _whenNotPaused() internal view {
|
||||
require(!_paused, Errors.LP_IS_PAUSED);
|
||||
}
|
||||
|
||||
function _onlyLendingPoolConfigurator() internal view {
|
||||
require(
|
||||
_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) {
|
||||
return LENDINGPOOL_REVISION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev this function is invoked by the proxy contract when the LendingPool contract is added to the
|
||||
* AddressesProvider.
|
||||
* @param provider the address of the LendingPoolAddressesProvider registry
|
||||
* @dev Function is invoked by the proxy contract when the LendingPool contract is added to the
|
||||
* LendingPoolAddressesProvider of the market.
|
||||
* - 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 {
|
||||
_addressesProvider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev deposits The underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens)
|
||||
* is minted.
|
||||
* @param asset the address of the reserve
|
||||
* @param amount the amount to be deposited
|
||||
* @param referralCode integrators are assigned a referral code and can potentially receive rewards.
|
||||
* @dev Deposits an `amount` of underlying asset into the reserve, receiving in return overlying aTokens.
|
||||
* - E.g. User deposits 100 USDC and gets in return 100 aUSDC
|
||||
* @param asset The address of the underlying asset to deposit
|
||||
* @param amount The amount to be deposited
|
||||
* @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(
|
||||
address asset,
|
||||
|
@ -107,7 +108,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
address onBehalfOf,
|
||||
uint16 referralCode
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateDeposit(reserve, amount);
|
||||
|
||||
|
@ -123,24 +124,27 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf);
|
||||
}
|
||||
|
||||
//transfer to the aToken contract
|
||||
IERC20(asset).safeTransferFrom(msg.sender, aToken, amount);
|
||||
|
||||
emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev withdraws the _reserves of user.
|
||||
* @param asset the address of the reserve
|
||||
* @param amount the underlying amount to be redeemed
|
||||
* @param to address that will receive the underlying
|
||||
* @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned
|
||||
* E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC
|
||||
* @param asset The address of the underlying asset to withdraw
|
||||
* @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(
|
||||
address asset,
|
||||
uint256 amount,
|
||||
address to
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
address aToken = reserve.aTokenAddress;
|
||||
|
||||
|
@ -148,7 +152,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
uint256 amountToWithdraw = amount;
|
||||
|
||||
//if amount is equal to uint(-1), the user wants to redeem everything
|
||||
if (amount == type(uint256).max) {
|
||||
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
|
||||
* corresponding debt token (StableDebtToken or VariableDebtToken)
|
||||
* @param asset the address of the reserve
|
||||
* @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 a referral code for integrators
|
||||
* @param onBehalfOf address of the user who will receive the debt. Should be the address of the borrower itself
|
||||
* - E.g. User borrows 100 USDC passing as `onBehalfOf` his own address, receiving the 100 USDC in his wallet
|
||||
* 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
|
||||
* if he has been given credit delegation allowance
|
||||
**/
|
||||
function borrow(
|
||||
address asset,
|
||||
|
@ -197,7 +203,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint16 referralCode,
|
||||
address onBehalfOf
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
_executeBorrow(
|
||||
ExecuteBorrowParams(
|
||||
|
@ -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).
|
||||
* @dev the target user is defined by onBehalfOf. If there is no repayment on behalf of another account,
|
||||
* onBehalfOf must be equal to msg.sender.
|
||||
* @param asset the address of the reserve on which the user borrowed
|
||||
* @param amount the amount to repay, or uint256(-1) if the user wants to repay everything
|
||||
* @param onBehalfOf the address for which msg.sender is repaying.
|
||||
* @notice Repays a borrowed `amount` on a specific reserve, burning the equivalent debt tokens owned
|
||||
* - E.g. User repays 100 USDC, burning 100 variable/stable debt tokens of the `onBehalfOf` address
|
||||
* @param asset The address of the borrowed underlying asset previously borrowed
|
||||
* @param amount The amount to repay
|
||||
* - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode`
|
||||
* @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(
|
||||
address asset,
|
||||
|
@ -227,11 +236,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
uint256 rateMode,
|
||||
address onBehalfOf
|
||||
) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(onBehalfOf, reserve);
|
||||
|
||||
ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
|
||||
DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
|
||||
|
||||
ValidationLogic.validateRepay(
|
||||
reserve,
|
||||
|
@ -242,8 +251,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
variableDebt
|
||||
);
|
||||
|
||||
//default to max amount
|
||||
uint256 paybackAmount = interestRateMode == ReserveLogic.InterestRateMode.STABLE
|
||||
uint256 paybackAmount = interestRateMode == DataTypes.InterestRateMode.STABLE
|
||||
? stableDebt
|
||||
: variableDebt;
|
||||
|
||||
|
@ -253,8 +261,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
reserve.updateState();
|
||||
|
||||
//burns an equivalent amount of debt tokens
|
||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(onBehalfOf, paybackAmount);
|
||||
} else {
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(
|
||||
|
@ -277,16 +284,16 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev borrowers can user this function to swap between stable and variable borrow rate modes.
|
||||
* @param asset the address of the reserve on which the user borrowed
|
||||
* @param rateMode the rate mode that the user wants to swap
|
||||
* @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa
|
||||
* @param asset The address of the underlying asset borrowed
|
||||
* @param rateMode The rate mode that the user wants to swap to
|
||||
**/
|
||||
function swapBorrowRateMode(address asset, uint256 rateMode) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(msg.sender, reserve);
|
||||
|
||||
ReserveLogic.InterestRateMode interestRateMode = ReserveLogic.InterestRateMode(rateMode);
|
||||
DataTypes.InterestRateMode interestRateMode = DataTypes.InterestRateMode(rateMode);
|
||||
|
||||
ValidationLogic.validateSwapRateMode(
|
||||
reserve,
|
||||
|
@ -298,8 +305,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
reserve.updateState();
|
||||
|
||||
if (interestRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
//burn stable rate tokens, mint variable rate tokens
|
||||
if (interestRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
IStableDebtToken(reserve.stableDebtTokenAddress).burn(msg.sender, stableDebt);
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).mint(
|
||||
msg.sender,
|
||||
|
@ -308,7 +314,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
reserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
//do the opposite
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).burn(
|
||||
msg.sender,
|
||||
variableDebt,
|
||||
|
@ -328,15 +333,16 @@ 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:
|
||||
* 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
|
||||
* @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve.
|
||||
* - 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 underlying asset borrowed
|
||||
* @param user The address of the user to be rebalanced
|
||||
**/
|
||||
function rebalanceStableBorrowRate(address asset, address user) external override whenNotPaused {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
IERC20 stableDebtToken = IERC20(reserve.stableDebtTokenAddress);
|
||||
IERC20 variableDebtToken = IERC20(reserve.variableDebtTokenAddress);
|
||||
|
@ -368,16 +374,16 @@ 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 use the deposit as collateral, false otherwise.
|
||||
* @dev Allows depositors to enable/disable a specific deposited asset as collateral
|
||||
* @param asset The address of the underlying asset deposited
|
||||
* @param useAsCollateral `true` if the user wants to use the deposit as collateral, `false` otherwise
|
||||
**/
|
||||
function setUserUseReserveAsCollateral(address asset, bool useAsCollateral)
|
||||
external
|
||||
override
|
||||
whenNotPaused
|
||||
{
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[asset];
|
||||
DataTypes.ReserveData storage reserve = _reserves[asset];
|
||||
|
||||
ValidationLogic.validateSetUseReserveAsCollateral(
|
||||
reserve,
|
||||
|
@ -400,19 +406,21 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev users can invoke this function to liquidate an undercollateralized position.
|
||||
* @param asset the address of the collateral to liquidated
|
||||
* @param asset the address of the principal reserve
|
||||
* @param user the address of the borrower
|
||||
* @param purchaseAmount the amount of principal that the liquidator wants to repay
|
||||
* @param receiveAToken true if the liquidators wants to receive the aTokens, false if
|
||||
* he wants to receive the underlying asset directly
|
||||
* @dev Function to liquidate a non-healthy position collateral-wise, with Health Factor below 1
|
||||
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param user The address of the borrower getting liquidated
|
||||
* @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(
|
||||
address collateral,
|
||||
address asset,
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
address user,
|
||||
uint256 purchaseAmount,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external override whenNotPaused {
|
||||
address collateralManager = _addressesProvider.getLendingPoolCollateralManager();
|
||||
|
@ -421,10 +429,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
(bool success, bytes memory result) = collateralManager.delegatecall(
|
||||
abi.encodeWithSignature(
|
||||
'liquidationCall(address,address,address,uint256,bool)',
|
||||
collateral,
|
||||
asset,
|
||||
collateralAsset,
|
||||
debtAsset,
|
||||
user,
|
||||
purchaseAmount,
|
||||
debtToCover,
|
||||
receiveAToken
|
||||
)
|
||||
);
|
||||
|
@ -448,16 +456,21 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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 assets The addresss of the assets being flashborrowed
|
||||
* @param amounts The amounts requested for this flashloan for each asset
|
||||
* @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 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.
|
||||
* @dev Allows smartcontracts to access the liquidity of the pool within one transaction,
|
||||
* as long as the amount taken plus a fee is returned.
|
||||
* IMPORTANT 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, implementing the IFlashLoanReceiver interface
|
||||
* @param assets The addresses of the assets being flash-borrowed
|
||||
* @param amounts The amounts amounts 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 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 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(
|
||||
address receiverAddress,
|
||||
|
@ -482,11 +495,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
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(assets, amounts, premiums, msg.sender, params),
|
||||
Errors.LP_INVALID_FLASH_LOAN_EXECUTOR_RETURN
|
||||
|
@ -499,7 +510,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.currentATokenAddress = aTokenAddresses[vars.i];
|
||||
vars.currentAmountPlusPremium = vars.currentAmount.add(vars.currentPremium);
|
||||
|
||||
if (ReserveLogic.InterestRateMode(modes[vars.i]) == ReserveLogic.InterestRateMode.NONE) {
|
||||
if (DataTypes.InterestRateMode(modes[vars.i]) == DataTypes.InterestRateMode.NONE) {
|
||||
_reserves[vars.currentAsset].updateState();
|
||||
_reserves[vars.currentAsset].cumulateToLiquidityIndex(
|
||||
IERC20(vars.currentATokenAddress).totalSupply(),
|
||||
|
@ -518,8 +529,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
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
|
||||
// If the user chose to not return the funds, the system checks if there is enough collateral and
|
||||
// eventually opens a debt position
|
||||
_executeBorrow(
|
||||
ExecuteBorrowParams(
|
||||
vars.currentAsset,
|
||||
|
@ -545,22 +556,22 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev returns the state and configuration of the reserve
|
||||
* @param asset the address of the reserve
|
||||
* @return the state of the reserve
|
||||
* @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
|
||||
override
|
||||
view
|
||||
returns (ReserveLogic.ReserveData memory)
|
||||
override
|
||||
returns (DataTypes.ReserveData memory)
|
||||
{
|
||||
return _reserves[asset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the user account data across all the reserves
|
||||
* @param user the address of the user
|
||||
* @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
|
||||
|
@ -570,8 +581,8 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
**/
|
||||
function getUserAccountData(address user)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (
|
||||
uint256 totalCollateralETH,
|
||||
uint256 totalDebtETH,
|
||||
|
@ -604,57 +615,57 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev returns the configuration of the reserve
|
||||
* @param asset the address of the reserve
|
||||
* @return the configuration of the reserve
|
||||
* @dev Returns the configuration of the reserve
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @return The configuration of the reserve
|
||||
**/
|
||||
function getConfiguration(address asset)
|
||||
external
|
||||
override
|
||||
view
|
||||
returns (ReserveConfiguration.Map memory)
|
||||
override
|
||||
returns (DataTypes.ReserveConfigurationMap memory)
|
||||
{
|
||||
return _reserves[asset].configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the configuration of the user across all the reserves
|
||||
* @param user the user
|
||||
* @return the configuration of the user
|
||||
* @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
|
||||
override
|
||||
view
|
||||
returns (UserConfiguration.Map memory)
|
||||
override
|
||||
returns (DataTypes.UserConfigurationMap memory)
|
||||
{
|
||||
return _usersConfig[user];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the normalized income per unit of asset
|
||||
* @param asset the address of the reserve
|
||||
* @return the reserve normalized income
|
||||
* @dev Returns the normalized income per unit of asset
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @return The reserve's normalized income
|
||||
*/
|
||||
function getReserveNormalizedIncome(address asset)
|
||||
external
|
||||
view
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _reserves[asset].getNormalizedIncome();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the normalized variable debt per unit of asset
|
||||
* @param asset the address of the reserve
|
||||
* @return the reserve normalized debt
|
||||
* @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
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (uint256)
|
||||
{
|
||||
return _reserves[asset].getNormalizedDebt();
|
||||
|
@ -663,14 +674,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
/**
|
||||
* @dev Returns if the LendingPool is paused
|
||||
*/
|
||||
function paused() external override view returns (bool) {
|
||||
function paused() external view override returns (bool) {
|
||||
return _paused;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 view override returns (address[] memory) {
|
||||
address[] memory _activeReserves = new address[](_reservesCount);
|
||||
|
||||
for (uint256 i = 0; i < _reservesCount; i++) {
|
||||
|
@ -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 view override returns (ILendingPoolAddressesProvider) {
|
||||
return _addressesProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev validates and finalizes an aToken transfer
|
||||
* @param asset the address of the reserve
|
||||
* @param from the user from which the aTokens are transferred
|
||||
* @param to the user receiving the aTokens
|
||||
* @param amount the amount being transferred/redeemed
|
||||
* @param balanceFromBefore the balance of the from user before the transfer
|
||||
* @param balanceToBefore the balance of the to user before the transfer
|
||||
* @dev Validates and finalizes an aToken transfer
|
||||
* - Only callable by the overlying aToken of the `asset`
|
||||
* @param asset The address of the underlying asset of the aToken
|
||||
* @param from The user from which the aTokens are transferred
|
||||
* @param to The user receiving the aTokens
|
||||
* @param amount The amount being transferred/withdrawn
|
||||
* @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(
|
||||
address asset,
|
||||
|
@ -718,13 +730,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
if (from != to) {
|
||||
if (balanceFromBefore.sub(amount) == 0) {
|
||||
UserConfiguration.Map storage fromConfig = _usersConfig[from];
|
||||
DataTypes.UserConfigurationMap storage fromConfig = _usersConfig[from];
|
||||
fromConfig.setUsingAsCollateral(reserveId, false);
|
||||
emit ReserveUsedAsCollateralDisabled(asset, from);
|
||||
}
|
||||
|
||||
if (balanceToBefore == 0 && amount != 0) {
|
||||
UserConfiguration.Map storage toConfig = _usersConfig[to];
|
||||
DataTypes.UserConfigurationMap storage toConfig = _usersConfig[to];
|
||||
toConfig.setUsingAsCollateral(reserveId, true);
|
||||
emit ReserveUsedAsCollateralEnabled(asset, to);
|
||||
}
|
||||
|
@ -732,10 +744,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev initializes a reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param aTokenAddress the address of the overlying aToken contract
|
||||
* @param interestRateStrategyAddress the address of the interest rate strategy contract
|
||||
* @dev Initializes a reserve, activating it, assigning an aToken and debt tokens and an
|
||||
* interest rate strategy
|
||||
* - Only callable by the LendingPoolConfigurator 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(
|
||||
address asset,
|
||||
|
@ -755,9 +771,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev updates the address of the interest rate strategy contract
|
||||
* @param asset the address of the reserve
|
||||
* @param rateStrategyAddress the address of the interest rate strategy contract
|
||||
* @dev Updates the address of the interest rate strategy contract
|
||||
* - Only callable by the LendingPoolConfigurator 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)
|
||||
external
|
||||
|
@ -768,9 +785,10 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev sets the configuration map of the reserve
|
||||
* @param asset the address of the reserve
|
||||
* @param configuration the configuration map
|
||||
* @dev Sets the configuration bitmap of the reserve as a whole
|
||||
* - Only callable by the LendingPoolConfigurator contract
|
||||
* @param asset The address of the underlying asset of the reserve
|
||||
* @param configuration The new configuration bitmap
|
||||
**/
|
||||
function setConfiguration(address asset, uint256 configuration)
|
||||
external
|
||||
|
@ -781,8 +799,9 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Set the _pause state
|
||||
* @param val the boolean value to set the current pause state of LendingPool
|
||||
* @dev Set the _pause state of a reserve
|
||||
* - 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 {
|
||||
_paused = val;
|
||||
|
@ -793,7 +812,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
}
|
||||
}
|
||||
|
||||
// internal functions
|
||||
struct ExecuteBorrowParams {
|
||||
address asset;
|
||||
address user;
|
||||
|
@ -805,19 +823,16 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
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 {
|
||||
ReserveLogic.ReserveData storage reserve = _reserves[vars.asset];
|
||||
UserConfiguration.Map storage userConfig = _usersConfig[vars.onBehalfOf];
|
||||
DataTypes.ReserveData storage reserve = _reserves[vars.asset];
|
||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[vars.onBehalfOf];
|
||||
|
||||
address oracle = _addressesProvider.getPriceOracle();
|
||||
|
||||
uint256 amountInETH = IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
|
||||
10**reserve.configuration.getDecimals()
|
||||
);
|
||||
uint256 amountInETH =
|
||||
IPriceOracleGetter(oracle).getAssetPrice(vars.asset).mul(vars.amount).div(
|
||||
10**reserve.configuration.getDecimals()
|
||||
);
|
||||
|
||||
ValidationLogic.validateBorrow(
|
||||
vars.asset,
|
||||
|
@ -836,12 +851,11 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
|
||||
reserve.updateState();
|
||||
|
||||
//caching the current stable borrow rate
|
||||
uint256 currentStableRate = 0;
|
||||
|
||||
bool isFirstBorrowing = false;
|
||||
if (
|
||||
ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
|
||||
DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
|
||||
) {
|
||||
currentStableRate = reserve.currentStableBorrowRate;
|
||||
|
||||
|
@ -881,16 +895,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
|||
vars.onBehalfOf,
|
||||
vars.amount,
|
||||
vars.interestRateMode,
|
||||
ReserveLogic.InterestRateMode(vars.interestRateMode) == ReserveLogic.InterestRateMode.STABLE
|
||||
DataTypes.InterestRateMode(vars.interestRateMode) == DataTypes.InterestRateMode.STABLE
|
||||
? currentStableRate
|
||||
: reserve.currentVariableBorrowRate,
|
||||
vars.referralCode
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev adds a reserve to the array of the _reserves address
|
||||
**/
|
||||
function _addReserveToList(address asset) internal {
|
||||
uint256 reservesCount = _reservesCount;
|
||||
|
309
contracts/protocol/lendingpool/LendingPoolCollateralManager.sol
Normal file
309
contracts/protocol/lendingpool/LendingPoolCollateralManager.sol
Normal file
|
@ -0,0 +1,309 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts//SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts//IERC20.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {IAToken} from '../tokenization/interfaces/IAToken.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {ILendingPoolCollateralManager} from '../../interfaces/ILendingPoolCollateralManager.sol';
|
||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.sol';
|
||||
import {LendingPoolStorage} from './LendingPoolStorage.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolCollateralManager contract
|
||||
* @author Aave
|
||||
* @dev Implements actions involving management of collateral in the protocol, the main one being the liquidations
|
||||
* IMPORTANT This contract will run always via DELEGATECALL, through the LendingPool, so the chain of inheritance
|
||||
* is the same as the LendingPool, to have compatible storage layouts
|
||||
**/
|
||||
contract LendingPoolCollateralManager is
|
||||
ILendingPoolCollateralManager,
|
||||
VersionedInitializable,
|
||||
LendingPoolStorage
|
||||
{
|
||||
using SafeERC20 for IERC20;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
|
||||
uint256 internal constant LIQUIDATION_CLOSE_FACTOR_PERCENT = 5000;
|
||||
|
||||
struct LiquidationCallLocalVars {
|
||||
uint256 userCollateralBalance;
|
||||
uint256 userStableDebt;
|
||||
uint256 userVariableDebt;
|
||||
uint256 maxLiquidatableDebt;
|
||||
uint256 actualDebtToLiquidate;
|
||||
uint256 liquidationRatio;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 userStableRate;
|
||||
uint256 maxCollateralToLiquidate;
|
||||
uint256 debtAmountNeeded;
|
||||
uint256 healthFactor;
|
||||
IAToken collateralAtoken;
|
||||
bool isCollateralEnabled;
|
||||
DataTypes.InterestRateMode borrowRateMode;
|
||||
uint256 errorCode;
|
||||
string errorMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev As thIS contract extends the VersionedInitializable contract to match the state
|
||||
* of the LendingPool contract, the getRevision() function is needed, but the value is not
|
||||
* important, as the initialize() function will never be called here
|
||||
*/
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to liquidate a position if its Health Factor drops below 1
|
||||
* - The caller (liquidator) covers `debtToCover` amount of debt of the user getting liquidated, and receives
|
||||
* a proportionally amount of the `collateralAsset` plus a bonus to cover market risk
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param user The address of the borrower getting liquidated
|
||||
* @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(
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
address user,
|
||||
uint256 debtToCover,
|
||||
bool receiveAToken
|
||||
) external override returns (uint256, string memory) {
|
||||
DataTypes.ReserveData storage collateralReserve = _reserves[collateralAsset];
|
||||
DataTypes.ReserveData storage debtReserve = _reserves[debtAsset];
|
||||
DataTypes.UserConfigurationMap storage userConfig = _usersConfig[user];
|
||||
|
||||
LiquidationCallLocalVars memory vars;
|
||||
|
||||
(, , , , vars.healthFactor) = GenericLogic.calculateUserAccountData(
|
||||
user,
|
||||
_reserves,
|
||||
userConfig,
|
||||
_reservesList,
|
||||
_reservesCount,
|
||||
_addressesProvider.getPriceOracle()
|
||||
);
|
||||
|
||||
(vars.userStableDebt, vars.userVariableDebt) = Helpers.getUserCurrentDebt(user, debtReserve);
|
||||
|
||||
(vars.errorCode, vars.errorMsg) = ValidationLogic.validateLiquidationCall(
|
||||
collateralReserve,
|
||||
debtReserve,
|
||||
userConfig,
|
||||
vars.healthFactor,
|
||||
vars.userStableDebt,
|
||||
vars.userVariableDebt
|
||||
);
|
||||
|
||||
if (Errors.CollateralManagerErrors(vars.errorCode) != Errors.CollateralManagerErrors.NO_ERROR) {
|
||||
return (vars.errorCode, vars.errorMsg);
|
||||
}
|
||||
|
||||
vars.collateralAtoken = IAToken(collateralReserve.aTokenAddress);
|
||||
|
||||
vars.userCollateralBalance = vars.collateralAtoken.balanceOf(user);
|
||||
|
||||
vars.maxLiquidatableDebt = vars.userStableDebt.add(vars.userVariableDebt).percentMul(
|
||||
LIQUIDATION_CLOSE_FACTOR_PERCENT
|
||||
);
|
||||
|
||||
vars.actualDebtToLiquidate = debtToCover > vars.maxLiquidatableDebt
|
||||
? vars.maxLiquidatableDebt
|
||||
: debtToCover;
|
||||
|
||||
(
|
||||
vars.maxCollateralToLiquidate,
|
||||
vars.debtAmountNeeded
|
||||
) = _calculateAvailableCollateralToLiquidate(
|
||||
collateralReserve,
|
||||
debtReserve,
|
||||
collateralAsset,
|
||||
debtAsset,
|
||||
vars.actualDebtToLiquidate,
|
||||
vars.userCollateralBalance
|
||||
);
|
||||
|
||||
// If debtAmountNeeded < actualDebtToLiquidate, there isn't enough
|
||||
// collateral to cover the actual amount that is being liquidated, hence we liquidate
|
||||
// a smaller amount
|
||||
|
||||
if (vars.debtAmountNeeded < vars.actualDebtToLiquidate) {
|
||||
vars.actualDebtToLiquidate = vars.debtAmountNeeded;
|
||||
}
|
||||
|
||||
// If the liquidator reclaims the underlying asset, we make sure there is enough available liquidity in the
|
||||
// collateral reserve
|
||||
if (!receiveAToken) {
|
||||
uint256 currentAvailableCollateral =
|
||||
IERC20(collateralAsset).balanceOf(address(vars.collateralAtoken));
|
||||
if (currentAvailableCollateral < vars.maxCollateralToLiquidate) {
|
||||
return (
|
||||
uint256(Errors.CollateralManagerErrors.NOT_ENOUGH_LIQUIDITY),
|
||||
Errors.LPCM_NOT_ENOUGH_LIQUIDITY_TO_LIQUIDATE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
debtReserve.updateState();
|
||||
|
||||
if (vars.userVariableDebt >= vars.actualDebtToLiquidate) {
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualDebtToLiquidate,
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
} else {
|
||||
// If the user doesn't have variable debt, no need to try to burn variable debt tokens
|
||||
if (vars.userVariableDebt > 0) {
|
||||
IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.userVariableDebt,
|
||||
debtReserve.variableBorrowIndex
|
||||
);
|
||||
}
|
||||
IStableDebtToken(debtReserve.stableDebtTokenAddress).burn(
|
||||
user,
|
||||
vars.actualDebtToLiquidate.sub(vars.userVariableDebt)
|
||||
);
|
||||
}
|
||||
|
||||
debtReserve.updateInterestRates(
|
||||
debtAsset,
|
||||
debtReserve.aTokenAddress,
|
||||
vars.actualDebtToLiquidate,
|
||||
0
|
||||
);
|
||||
|
||||
if (receiveAToken) {
|
||||
vars.collateralAtoken.transferOnLiquidation(user, msg.sender, vars.maxCollateralToLiquidate);
|
||||
} else {
|
||||
collateralReserve.updateState();
|
||||
collateralReserve.updateInterestRates(
|
||||
collateralAsset,
|
||||
address(vars.collateralAtoken),
|
||||
0,
|
||||
vars.maxCollateralToLiquidate
|
||||
);
|
||||
|
||||
// Burn the equivalent amount of aToken, sending the underlying to the liquidator
|
||||
vars.collateralAtoken.burn(
|
||||
user,
|
||||
msg.sender,
|
||||
vars.maxCollateralToLiquidate,
|
||||
collateralReserve.liquidityIndex
|
||||
);
|
||||
}
|
||||
|
||||
// If the collateral being liquidated is equal to the user balance,
|
||||
// we set the currency as not being used as collateral anymore
|
||||
if (vars.maxCollateralToLiquidate == vars.userCollateralBalance) {
|
||||
userConfig.setUsingAsCollateral(collateralReserve.id, false);
|
||||
emit ReserveUsedAsCollateralDisabled(collateralAsset, user);
|
||||
}
|
||||
|
||||
// Transfers the debt asset being repaid to the aToken, where the liquidity is kept
|
||||
IERC20(debtAsset).safeTransferFrom(
|
||||
msg.sender,
|
||||
debtReserve.aTokenAddress,
|
||||
vars.actualDebtToLiquidate
|
||||
);
|
||||
|
||||
emit LiquidationCall(
|
||||
collateralAsset,
|
||||
debtAsset,
|
||||
user,
|
||||
vars.actualDebtToLiquidate,
|
||||
vars.maxCollateralToLiquidate,
|
||||
msg.sender,
|
||||
receiveAToken
|
||||
);
|
||||
|
||||
return (uint256(Errors.CollateralManagerErrors.NO_ERROR), Errors.LPCM_NO_ERRORS);
|
||||
}
|
||||
|
||||
struct AvailableCollateralToLiquidateLocalVars {
|
||||
uint256 userCompoundedBorrowBalance;
|
||||
uint256 liquidationBonus;
|
||||
uint256 collateralPrice;
|
||||
uint256 debtAssetPrice;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 debtAssetDecimals;
|
||||
uint256 collateralDecimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates how much of a specific collateral can be liquidated, given
|
||||
* a certain amount of debt asset.
|
||||
* - This function needs to be called after all the checks to validate the liquidation have been performed,
|
||||
* otherwise it might fail.
|
||||
* @param collateralReserve The data of the collateral reserve
|
||||
* @param debtReserve The data of the debt reserve
|
||||
* @param collateralAsset The address of the underlying asset used as collateral, to receive as result of the liquidation
|
||||
* @param debtAsset The address of the underlying borrowed asset to be repaid with the liquidation
|
||||
* @param debtToCover The debt amount of borrowed `asset` the liquidator wants to cover
|
||||
* @param userCollateralBalance The collateral balance for the specific `collateralAsset` of the user being liquidated
|
||||
* @return collateralAmount: The maximum amount that is possible to liquidate given all the liquidation constraints
|
||||
* (user balance, close factor)
|
||||
* debtAmountNeeded: The amount to repay with the liquidation
|
||||
**/
|
||||
function _calculateAvailableCollateralToLiquidate(
|
||||
DataTypes.ReserveData storage collateralReserve,
|
||||
DataTypes.ReserveData storage debtReserve,
|
||||
address collateralAsset,
|
||||
address debtAsset,
|
||||
uint256 debtToCover,
|
||||
uint256 userCollateralBalance
|
||||
) internal view returns (uint256, uint256) {
|
||||
uint256 collateralAmount = 0;
|
||||
uint256 debtAmountNeeded = 0;
|
||||
IPriceOracleGetter oracle = IPriceOracleGetter(_addressesProvider.getPriceOracle());
|
||||
|
||||
AvailableCollateralToLiquidateLocalVars memory vars;
|
||||
|
||||
vars.collateralPrice = oracle.getAssetPrice(collateralAsset);
|
||||
vars.debtAssetPrice = oracle.getAssetPrice(debtAsset);
|
||||
|
||||
(, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
|
||||
.configuration
|
||||
.getParams();
|
||||
vars.debtAssetDecimals = debtReserve.configuration.getDecimals();
|
||||
|
||||
// This is the maximum possible amount of the selected collateral that can be liquidated, given the
|
||||
// max amount of liquidatable debt
|
||||
vars.maxAmountCollateralToLiquidate = vars
|
||||
.debtAssetPrice
|
||||
.mul(debtToCover)
|
||||
.mul(10**vars.collateralDecimals)
|
||||
.percentMul(vars.liquidationBonus)
|
||||
.div(vars.collateralPrice.mul(10**vars.debtAssetDecimals));
|
||||
|
||||
if (vars.maxAmountCollateralToLiquidate > userCollateralBalance) {
|
||||
collateralAmount = userCollateralBalance;
|
||||
debtAmountNeeded = vars
|
||||
.collateralPrice
|
||||
.mul(collateralAmount)
|
||||
.mul(10**vars.debtAssetDecimals)
|
||||
.div(vars.debtAssetPrice.mul(10**vars.collateralDecimals))
|
||||
.percentDiv(vars.liquidationBonus);
|
||||
} else {
|
||||
collateralAmount = vars.maxAmountCollateralToLiquidate;
|
||||
debtAmountNeeded = debtToCover;
|
||||
}
|
||||
return (collateralAmount, debtAmountNeeded);
|
||||
}
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {
|
||||
InitializableImmutableAdminUpgradeabilityProxy
|
||||
} from '../libraries/aave-upgradeability/InitializableImmutableAdminUpgradeabilityProxy.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {ITokenConfiguration} from '../tokenization/interfaces/ITokenConfiguration.sol';
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolConfigurator contract
|
||||
|
@ -25,7 +25,7 @@ import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
|||
|
||||
contract LendingPoolConfigurator is VersionedInitializable {
|
||||
using SafeMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve is initialized.
|
||||
|
@ -105,14 +105,14 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
event ReserveUnfrozen(address indexed asset);
|
||||
|
||||
|
||||
/**
|
||||
* @dev emitted when a reserve factor is updated
|
||||
* @param asset the address of the reserve
|
||||
* @param factor the new reserve factor
|
||||
**/
|
||||
event ReserveFactorChanged(address indexed asset, uint256 factor);
|
||||
|
||||
|
||||
/**
|
||||
* @dev emitted when the reserve decimals are updated
|
||||
* @param asset the address of the reserve
|
||||
|
@ -187,7 +187,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
|
||||
uint256 internal constant CONFIGURATOR_REVISION = 0x3;
|
||||
|
||||
function getRevision() internal override pure returns (uint256) {
|
||||
function getRevision() internal pure override returns (uint256) {
|
||||
return CONFIGURATOR_REVISION;
|
||||
}
|
||||
|
||||
|
@ -236,15 +236,11 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
|
||||
address aTokenProxyAddress = _initTokenWithProxy(aTokenImpl, underlyingAssetDecimals);
|
||||
|
||||
address stableDebtTokenProxyAddress = _initTokenWithProxy(
|
||||
stableDebtTokenImpl,
|
||||
underlyingAssetDecimals
|
||||
);
|
||||
address stableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(stableDebtTokenImpl, underlyingAssetDecimals);
|
||||
|
||||
address variableDebtTokenProxyAddress = _initTokenWithProxy(
|
||||
variableDebtTokenImpl,
|
||||
underlyingAssetDecimals
|
||||
);
|
||||
address variableDebtTokenProxyAddress =
|
||||
_initTokenWithProxy(variableDebtTokenImpl, underlyingAssetDecimals);
|
||||
|
||||
pool.initReserve(
|
||||
asset,
|
||||
|
@ -254,7 +250,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
interestRateStrategyAddress
|
||||
);
|
||||
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setDecimals(underlyingAssetDecimals);
|
||||
|
||||
|
@ -278,7 +274,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param implementation the address of the new aToken implementation
|
||||
**/
|
||||
function updateAToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.aTokenAddress, implementation);
|
||||
|
||||
|
@ -291,7 +287,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param implementation the address of the new aToken implementation
|
||||
**/
|
||||
function updateStableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.stableDebtTokenAddress, implementation);
|
||||
|
||||
|
@ -304,7 +300,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param implementation the address of the new aToken implementation
|
||||
**/
|
||||
function updateVariableDebtToken(address asset, address implementation) external onlyPoolAdmin {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
_upgradeTokenImplementation(asset, reserveData.variableDebtTokenAddress, implementation);
|
||||
|
||||
|
@ -320,7 +316,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
external
|
||||
onlyPoolAdmin
|
||||
{
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setBorrowingEnabled(true);
|
||||
currentConfig.setStableRateBorrowingEnabled(stableBorrowRateEnabled);
|
||||
|
@ -335,7 +331,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function disableBorrowingOnReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setBorrowingEnabled(false);
|
||||
|
||||
|
@ -358,7 +354,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
uint256 liquidationThreshold,
|
||||
uint256 liquidationBonus
|
||||
) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
//validation of the parameters: the LTV can
|
||||
//only be lower or equal than the liquidation threshold
|
||||
|
@ -368,13 +364,16 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
if (liquidationThreshold != 0) {
|
||||
//liquidation bonus must be bigger than 100.00%, otherwise the liquidator would receive less
|
||||
//collateral than needed to cover the debt.
|
||||
uint256 absoluteBonus = liquidationBonus.sub(PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION);
|
||||
uint256 absoluteBonus =
|
||||
liquidationBonus.sub(PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION);
|
||||
require(absoluteBonus > 0, Errors.LPC_INVALID_CONFIGURATION);
|
||||
|
||||
//we also need to require that the liq threshold is lower or equal than the liquidation bonus, to ensure that
|
||||
//there is always enough margin for liquidators to receive the bonus.
|
||||
require(liquidationThreshold.add(absoluteBonus) <= PercentageMath.PERCENTAGE_FACTOR, Errors.LPC_INVALID_CONFIGURATION);
|
||||
|
||||
require(
|
||||
liquidationThreshold.add(absoluteBonus) <= PercentageMath.PERCENTAGE_FACTOR,
|
||||
Errors.LPC_INVALID_CONFIGURATION
|
||||
);
|
||||
} else {
|
||||
require(liquidationBonus == 0, Errors.LPC_INVALID_CONFIGURATION);
|
||||
//if the liquidation threshold is being set to 0,
|
||||
|
@ -397,7 +396,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function enableReserveStableRate(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setStableRateBorrowingEnabled(true);
|
||||
|
||||
|
@ -411,7 +410,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function disableReserveStableRate(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setStableRateBorrowingEnabled(false);
|
||||
|
||||
|
@ -425,7 +424,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function activateReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setActive(true);
|
||||
|
||||
|
@ -441,7 +440,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
function deactivateReserve(address asset) external onlyPoolAdmin {
|
||||
_checkNoLiquidity(asset);
|
||||
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setActive(false);
|
||||
|
||||
|
@ -455,7 +454,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function freezeReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setFrozen(true);
|
||||
|
||||
|
@ -469,7 +468,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param asset the address of the reserve
|
||||
**/
|
||||
function unfreezeReserve(address asset) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setFrozen(false);
|
||||
|
||||
|
@ -484,7 +483,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param reserveFactor the new reserve factor of the reserve
|
||||
**/
|
||||
function setReserveFactor(address asset, uint256 reserveFactor) external onlyPoolAdmin {
|
||||
ReserveConfiguration.Map memory currentConfig = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
|
||||
|
||||
currentConfig.setReserveFactor(reserveFactor);
|
||||
|
||||
|
@ -512,16 +511,16 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
* @param decimals the decimals of the token
|
||||
**/
|
||||
function _initTokenWithProxy(address implementation, uint8 decimals) internal returns (address) {
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy
|
||||
= new InitializableImmutableAdminUpgradeabilityProxy(address(this));
|
||||
|
||||
bytes memory params = abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
decimals,
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
bytes memory params =
|
||||
abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
decimals,
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
|
||||
proxy.initialize(implementation, params);
|
||||
|
||||
|
@ -533,20 +532,20 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
address proxyAddress,
|
||||
address implementation
|
||||
) internal {
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy =
|
||||
InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
|
||||
|
||||
InitializableImmutableAdminUpgradeabilityProxy proxy
|
||||
= InitializableImmutableAdminUpgradeabilityProxy(payable(proxyAddress));
|
||||
|
||||
ReserveConfiguration.Map memory configuration = pool.getConfiguration(asset);
|
||||
DataTypes.ReserveConfigurationMap memory configuration = pool.getConfiguration(asset);
|
||||
|
||||
(, , , uint256 decimals, ) = configuration.getParamsMemory();
|
||||
|
||||
bytes memory params = abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
uint8(decimals),
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
bytes memory params =
|
||||
abi.encodeWithSignature(
|
||||
'initialize(uint8,string,string)',
|
||||
uint8(decimals),
|
||||
IERC20Detailed(implementation).name(),
|
||||
IERC20Detailed(implementation).symbol()
|
||||
);
|
||||
|
||||
proxy.upgradeToAndCall(implementation, params);
|
||||
}
|
||||
|
@ -560,7 +559,7 @@ contract LendingPoolConfigurator is VersionedInitializable {
|
|||
}
|
||||
|
||||
function _checkNoLiquidity(address asset) internal view {
|
||||
ReserveLogic.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
DataTypes.ReserveData memory reserveData = pool.getReserveData(asset);
|
||||
|
||||
uint256 availableLiquidity = IERC20Detailed(asset).balanceOf(reserveData.aTokenAddress);
|
||||
|
|
@ -1,20 +1,21 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {UserConfiguration} from '../libraries/configuration/UserConfiguration.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol';
|
||||
import {DataTypes} from '../libraries/types/DataTypes.sol';
|
||||
|
||||
contract LendingPoolStorage {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
ILendingPoolAddressesProvider internal _addressesProvider;
|
||||
|
||||
mapping(address => ReserveLogic.ReserveData) internal _reserves;
|
||||
mapping(address => UserConfiguration.Map) internal _usersConfig;
|
||||
mapping(address => DataTypes.ReserveData) internal _reserves;
|
||||
mapping(address => DataTypes.UserConfigurationMap) internal _usersConfig;
|
||||
|
||||
// the list of the available reserves, structured as a mapping for gas savings reasons
|
||||
mapping(uint256 => address) internal _reservesList;
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import '../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol';
|
||||
import '../../../dependencies/openzeppelin/upgradeability/BaseUpgradeabilityProxy.sol';
|
||||
|
||||
/**
|
||||
* @title BaseImmutableAdminUpgradeabilityProxy
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import './BaseImmutableAdminUpgradeabilityProxy.sol';
|
||||
import '../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol';
|
||||
import '../../../dependencies/openzeppelin/upgradeability/InitializableUpgradeabilityProxy.sol';
|
||||
|
||||
/**
|
||||
* @title InitializableAdminUpgradeabilityProxy
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title VersionedInitializable
|
||||
|
@ -51,7 +51,7 @@ abstract contract VersionedInitializable {
|
|||
|
||||
/// @dev returns the revision number of the contract.
|
||||
/// Needs to be defined in the inherited class as a constant.
|
||||
function getRevision() internal virtual pure returns (uint256);
|
||||
function getRevision() internal pure virtual returns (uint256);
|
||||
|
||||
/// @dev Returns true if and only if the function is running in the constructor
|
||||
function isConstructor() private view returns (bool) {
|
|
@ -1,7 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveConfiguration library
|
||||
|
@ -35,26 +36,12 @@ library ReserveConfiguration {
|
|||
uint256 constant MAX_VALID_DECIMALS = 255;
|
||||
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
|
||||
|
||||
struct Map {
|
||||
//bit 0-15: LTV
|
||||
//bit 16-31: Liq. threshold
|
||||
//bit 32-47: Liq. bonus
|
||||
//bit 48-55: Decimals
|
||||
//bit 56: Reserve is active
|
||||
//bit 57: reserve is frozen
|
||||
//bit 58: borrowing is enabled
|
||||
//bit 59: stable rate borrowing enabled
|
||||
//bit 60-63: reserved
|
||||
//bit 64-79: reserve factor
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets the Loan to Value of the reserve
|
||||
* @param self the reserve configuration
|
||||
* @param ltv the new ltv
|
||||
**/
|
||||
function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
|
||||
function setLtv(DataTypes.ReserveConfigurationMap memory self, uint256 ltv) internal pure {
|
||||
require(ltv <= MAX_VALID_LTV, Errors.RC_INVALID_LTV);
|
||||
|
||||
self.data = (self.data & LTV_MASK) | ltv;
|
||||
|
@ -65,7 +52,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the loan to value
|
||||
**/
|
||||
function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getLtv(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return self.data & ~LTV_MASK;
|
||||
}
|
||||
|
||||
|
@ -74,7 +61,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param threshold the new liquidation threshold
|
||||
**/
|
||||
function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold)
|
||||
function setLiquidationThreshold(DataTypes.ReserveConfigurationMap memory self, uint256 threshold)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -90,7 +77,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the liquidation threshold
|
||||
**/
|
||||
function getLiquidationThreshold(ReserveConfiguration.Map storage self)
|
||||
function getLiquidationThreshold(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
|
@ -103,7 +90,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param bonus the new liquidation bonus
|
||||
**/
|
||||
function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
|
||||
function setLiquidationBonus(DataTypes.ReserveConfigurationMap memory self, uint256 bonus) internal pure {
|
||||
require(bonus <= MAX_VALID_LIQUIDATION_BONUS, Errors.RC_INVALID_LIQ_BONUS);
|
||||
|
||||
self.data =
|
||||
|
@ -116,7 +103,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the liquidation bonus
|
||||
**/
|
||||
function getLiquidationBonus(ReserveConfiguration.Map storage self)
|
||||
function getLiquidationBonus(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
|
@ -129,7 +116,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param decimals the decimals
|
||||
**/
|
||||
function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
|
||||
function setDecimals(DataTypes.ReserveConfigurationMap memory self, uint256 decimals) internal pure {
|
||||
require(decimals <= MAX_VALID_DECIMALS, Errors.RC_INVALID_DECIMALS);
|
||||
|
||||
self.data = (self.data & DECIMALS_MASK) | (decimals << RESERVE_DECIMALS_START_BIT_POSITION);
|
||||
|
@ -140,7 +127,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the decimals of the asset
|
||||
**/
|
||||
function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getDecimals(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
@ -149,7 +136,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param active the active state
|
||||
**/
|
||||
function setActive(ReserveConfiguration.Map memory self, bool active) internal pure {
|
||||
function setActive(DataTypes.ReserveConfigurationMap memory self, bool active) internal pure {
|
||||
self.data =
|
||||
(self.data & ACTIVE_MASK) |
|
||||
(uint256(active ? 1 : 0) << IS_ACTIVE_START_BIT_POSITION);
|
||||
|
@ -160,7 +147,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the active state
|
||||
**/
|
||||
function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getActive(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~ACTIVE_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -169,7 +156,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param frozen the frozen state
|
||||
**/
|
||||
function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure {
|
||||
function setFrozen(DataTypes.ReserveConfigurationMap memory self, bool frozen) internal pure {
|
||||
self.data =
|
||||
(self.data & FROZEN_MASK) |
|
||||
(uint256(frozen ? 1 : 0) << IS_FROZEN_START_BIT_POSITION);
|
||||
|
@ -180,7 +167,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the frozen state
|
||||
**/
|
||||
function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getFrozen(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~FROZEN_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -189,7 +176,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param enabled true if the borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure {
|
||||
function setBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled) internal pure {
|
||||
self.data =
|
||||
(self.data & BORROWING_MASK) |
|
||||
(uint256(enabled ? 1 : 0) << BORROWING_ENABLED_START_BIT_POSITION);
|
||||
|
@ -200,7 +187,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the borrowing state
|
||||
**/
|
||||
function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
||||
function getBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self) internal view returns (bool) {
|
||||
return (self.data & ~BORROWING_MASK) != 0;
|
||||
}
|
||||
|
||||
|
@ -209,7 +196,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param enabled true if the stable rate borrowing needs to be enabled, false otherwise
|
||||
**/
|
||||
function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled)
|
||||
function setStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap memory self, bool enabled)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -223,7 +210,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the stable rate borrowing state
|
||||
**/
|
||||
function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self)
|
||||
function getStableRateBorrowingEnabled(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
|
@ -236,7 +223,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @param reserveFactor the reserve factor
|
||||
**/
|
||||
function setReserveFactor(ReserveConfiguration.Map memory self, uint256 reserveFactor)
|
||||
function setReserveFactor(DataTypes.ReserveConfigurationMap memory self, uint256 reserveFactor)
|
||||
internal
|
||||
pure
|
||||
{
|
||||
|
@ -252,7 +239,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the reserve factor
|
||||
**/
|
||||
function getReserveFactor(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
||||
function getReserveFactor(DataTypes.ReserveConfigurationMap storage self) internal view returns (uint256) {
|
||||
return (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION;
|
||||
}
|
||||
|
||||
|
@ -261,7 +248,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
|
||||
**/
|
||||
function getFlags(ReserveConfiguration.Map storage self)
|
||||
function getFlags(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
|
@ -286,7 +273,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
||||
**/
|
||||
function getParams(ReserveConfiguration.Map storage self)
|
||||
function getParams(DataTypes.ReserveConfigurationMap storage self)
|
||||
internal
|
||||
view
|
||||
returns (
|
||||
|
@ -313,7 +300,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
||||
**/
|
||||
function getParamsMemory(ReserveConfiguration.Map memory self)
|
||||
function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
|
||||
internal
|
||||
pure
|
||||
returns (
|
||||
|
@ -338,7 +325,7 @@ library ReserveConfiguration {
|
|||
* @param self the reserve configuration
|
||||
* @return the state flags representing active, frozen, borrowing enabled, stableRateBorrowing enabled
|
||||
**/
|
||||
function getFlagsMemory(ReserveConfiguration.Map memory self)
|
||||
function getFlagsMemory(DataTypes.ReserveConfigurationMap memory self)
|
||||
internal
|
||||
pure
|
||||
returns (
|
|
@ -1,18 +1,17 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title UserConfiguration library
|
||||
* @author Aave
|
||||
* @notice Implements the bitmap logic to handle the user configuration
|
||||
*/
|
||||
library UserConfiguration {
|
||||
uint256 internal constant BORROWING_MASK = 0x5555555555555555555555555555555555555555555555555555555555555555;
|
||||
|
||||
struct Map {
|
||||
uint256 data;
|
||||
}
|
||||
uint256 internal constant BORROWING_MASK =
|
||||
0x5555555555555555555555555555555555555555555555555555555555555555;
|
||||
|
||||
/**
|
||||
* @dev sets if the user is borrowing the reserve identified by reserveIndex
|
||||
|
@ -21,7 +20,7 @@ library UserConfiguration {
|
|||
* @param borrowing true if the user is borrowing the reserve, false otherwise
|
||||
**/
|
||||
function setBorrowing(
|
||||
UserConfiguration.Map storage self,
|
||||
DataTypes.UserConfigurationMap storage self,
|
||||
uint256 reserveIndex,
|
||||
bool borrowing
|
||||
) internal {
|
||||
|
@ -38,7 +37,7 @@ library UserConfiguration {
|
|||
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
|
||||
**/
|
||||
function setUsingAsCollateral(
|
||||
UserConfiguration.Map storage self,
|
||||
DataTypes.UserConfigurationMap storage self,
|
||||
uint256 reserveIndex,
|
||||
bool _usingAsCollateral
|
||||
) internal {
|
||||
|
@ -54,7 +53,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve for borrowing or as collateral, false otherwise
|
||||
**/
|
||||
function isUsingAsCollateralOrBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isUsingAsCollateralOrBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -69,7 +68,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve for borrowing, false otherwise
|
||||
**/
|
||||
function isBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isBorrowing(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -84,7 +83,7 @@ library UserConfiguration {
|
|||
* @param reserveIndex the index of the reserve in the bitmap
|
||||
* @return true if the user has been using a reserve as collateral, false otherwise
|
||||
**/
|
||||
function isUsingAsCollateral(UserConfiguration.Map memory self, uint256 reserveIndex)
|
||||
function isUsingAsCollateral(DataTypes.UserConfigurationMap memory self, uint256 reserveIndex)
|
||||
internal
|
||||
pure
|
||||
returns (bool)
|
||||
|
@ -98,7 +97,7 @@ library UserConfiguration {
|
|||
* @param self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isBorrowingAny(UserConfiguration.Map memory self) internal pure returns (bool) {
|
||||
function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||
return self.data & BORROWING_MASK != 0;
|
||||
}
|
||||
|
||||
|
@ -107,7 +106,7 @@ library UserConfiguration {
|
|||
* @param self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isEmpty(UserConfiguration.Map memory self) internal pure returns (bool) {
|
||||
function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||
return self.data == 0;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title Errors library
|
40
contracts/protocol/libraries/helpers/Helpers.sol
Normal file
40
contracts/protocol/libraries/helpers/Helpers.sol
Normal file
|
@ -0,0 +1,40 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title Helpers library
|
||||
* @author Aave
|
||||
* @notice Implements calculation helpers.
|
||||
*/
|
||||
library Helpers {
|
||||
/**
|
||||
* @dev fetches the user current stable and variable debt balances
|
||||
* @param user the user
|
||||
* @param reserve the reserve object
|
||||
* @return the stable and variable debt balance
|
||||
**/
|
||||
function getUserCurrentDebt(address user, DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
|
||||
function getUserCurrentDebtMemory(address user, DataTypes.ReserveData memory reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
IERC20(reserve.stableDebtTokenAddress).balanceOf(user),
|
||||
IERC20(reserve.variableDebtTokenAddress).balanceOf(user)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {IPriceOracleGetter} from '../../../interfaces/IPriceOracleGetter.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title GenericLogic library
|
||||
|
@ -17,12 +18,12 @@ import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
|||
* @title Implements protocol-level logic to check the status of the user across all the reserves
|
||||
*/
|
||||
library GenericLogic {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
uint256 public constant HEALTH_FACTOR_LIQUIDATION_THRESHOLD = 1 ether;
|
||||
|
||||
|
@ -55,8 +56,8 @@ library GenericLogic {
|
|||
address asset,
|
||||
address user,
|
||||
uint256 amount,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map calldata userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap calldata userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -104,11 +105,12 @@ library GenericLogic {
|
|||
.sub(vars.amountToDecreaseETH.mul(vars.liquidationThreshold))
|
||||
.div(vars.collateralBalanceAfterDecrease);
|
||||
|
||||
uint256 healthFactorAfterDecrease = calculateHealthFactorFromBalances(
|
||||
vars.collateralBalanceAfterDecrease,
|
||||
vars.borrowBalanceETH,
|
||||
vars.liquidationThresholdAfterDecrease
|
||||
);
|
||||
uint256 healthFactorAfterDecrease =
|
||||
calculateHealthFactorFromBalances(
|
||||
vars.collateralBalanceAfterDecrease,
|
||||
vars.borrowBalanceETH,
|
||||
vars.liquidationThresholdAfterDecrease
|
||||
);
|
||||
|
||||
return healthFactorAfterDecrease >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD;
|
||||
}
|
||||
|
@ -149,8 +151,8 @@ library GenericLogic {
|
|||
**/
|
||||
function calculateUserAccountData(
|
||||
address user,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map memory userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap memory userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -176,7 +178,7 @@ library GenericLogic {
|
|||
}
|
||||
|
||||
vars.currentReserveAddress = reserves[vars.i];
|
||||
ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
||||
DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
|
||||
|
||||
(vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve
|
||||
.configuration
|
||||
|
@ -188,10 +190,8 @@ library GenericLogic {
|
|||
if (vars.liquidationThreshold != 0 && userConfig.isUsingAsCollateral(vars.i)) {
|
||||
vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(user);
|
||||
|
||||
uint256 liquidityBalanceETH = vars
|
||||
.reserveUnitPrice
|
||||
.mul(vars.compoundedLiquidityBalance)
|
||||
.div(vars.tokenUnit);
|
||||
uint256 liquidityBalanceETH =
|
||||
vars.reserveUnitPrice.mul(vars.compoundedLiquidityBalance).div(vars.tokenUnit);
|
||||
|
||||
vars.totalCollateralBalanceETH = vars.totalCollateralBalanceETH.add(liquidityBalanceETH);
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {MathUtils} from '../math/MathUtils.sol';
|
||||
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {IAToken} from '../../tokenization/interfaces/IAToken.sol';
|
||||
import {IStableDebtToken} from '../../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {IVariableDebtToken} from '../../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -43,35 +44,8 @@ library ReserveLogic {
|
|||
uint256 variableBorrowIndex
|
||||
);
|
||||
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
|
||||
// refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
struct ReserveData {
|
||||
//stores the reserve configuration
|
||||
ReserveConfiguration.Map configuration;
|
||||
//the liquidity index. Expressed in ray
|
||||
uint128 liquidityIndex;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint128 variableBorrowIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint128 currentLiquidityRate;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint128 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint128 currentStableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
//tokens addresses
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
//address of the interest rate strategy
|
||||
address interestRateStrategyAddress;
|
||||
//the id of the reserve. Represents the position in the list of the active reserves
|
||||
uint8 id;
|
||||
}
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
|
||||
/**
|
||||
* @dev returns the ongoing normalized income for the reserve.
|
||||
|
@ -80,7 +54,11 @@ library ReserveLogic {
|
|||
* @param reserve the reserve object
|
||||
* @return the normalized income. expressed in ray
|
||||
**/
|
||||
function getNormalizedIncome(ReserveData storage reserve) internal view returns (uint256) {
|
||||
function getNormalizedIncome(DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -89,9 +67,10 @@ library ReserveLogic {
|
|||
return reserve.liquidityIndex;
|
||||
}
|
||||
|
||||
uint256 cumulated = MathUtils
|
||||
.calculateLinearInterest(reserve.currentLiquidityRate, timestamp)
|
||||
.rayMul(reserve.liquidityIndex);
|
||||
uint256 cumulated =
|
||||
MathUtils.calculateLinearInterest(reserve.currentLiquidityRate, timestamp).rayMul(
|
||||
reserve.liquidityIndex
|
||||
);
|
||||
|
||||
return cumulated;
|
||||
}
|
||||
|
@ -103,7 +82,11 @@ library ReserveLogic {
|
|||
* @param reserve the reserve object
|
||||
* @return the normalized variable debt. expressed in ray
|
||||
**/
|
||||
function getNormalizedDebt(ReserveData storage reserve) internal view returns (uint256) {
|
||||
function getNormalizedDebt(DataTypes.ReserveData storage reserve)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint40 timestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
//solium-disable-next-line
|
||||
|
@ -112,9 +95,10 @@ library ReserveLogic {
|
|||
return reserve.variableBorrowIndex;
|
||||
}
|
||||
|
||||
uint256 cumulated = MathUtils
|
||||
.calculateCompoundedInterest(reserve.currentVariableBorrowRate, timestamp)
|
||||
.rayMul(reserve.variableBorrowIndex);
|
||||
uint256 cumulated =
|
||||
MathUtils.calculateCompoundedInterest(reserve.currentVariableBorrowRate, timestamp).rayMul(
|
||||
reserve.variableBorrowIndex
|
||||
);
|
||||
|
||||
return cumulated;
|
||||
}
|
||||
|
@ -124,20 +108,21 @@ library ReserveLogic {
|
|||
* a formal specification.
|
||||
* @param reserve the reserve object
|
||||
**/
|
||||
function updateState(ReserveData storage reserve) internal {
|
||||
uint256 scaledVariableDebt = IVariableDebtToken(reserve.variableDebtTokenAddress)
|
||||
.scaledTotalSupply();
|
||||
function updateState(DataTypes.ReserveData storage reserve) internal {
|
||||
uint256 scaledVariableDebt =
|
||||
IVariableDebtToken(reserve.variableDebtTokenAddress).scaledTotalSupply();
|
||||
uint256 previousVariableBorrowIndex = reserve.variableBorrowIndex;
|
||||
uint256 previousLiquidityIndex = reserve.liquidityIndex;
|
||||
uint40 lastUpdatedTimestamp = reserve.lastUpdateTimestamp;
|
||||
|
||||
(uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) = _updateIndexes(
|
||||
reserve,
|
||||
scaledVariableDebt,
|
||||
previousLiquidityIndex,
|
||||
previousVariableBorrowIndex,
|
||||
lastUpdatedTimestamp
|
||||
);
|
||||
(uint256 newLiquidityIndex, uint256 newVariableBorrowIndex) =
|
||||
_updateIndexes(
|
||||
reserve,
|
||||
scaledVariableDebt,
|
||||
previousLiquidityIndex,
|
||||
previousVariableBorrowIndex,
|
||||
lastUpdatedTimestamp
|
||||
);
|
||||
|
||||
_mintToTreasury(
|
||||
reserve,
|
||||
|
@ -157,7 +142,7 @@ library ReserveLogic {
|
|||
* @param amount the amount to accomulate
|
||||
**/
|
||||
function cumulateToLiquidityIndex(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 totalLiquidity,
|
||||
uint256 amount
|
||||
) internal {
|
||||
|
@ -178,14 +163,14 @@ library ReserveLogic {
|
|||
* @param interestRateStrategyAddress the address of the interest rate strategy contract
|
||||
**/
|
||||
function init(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address aTokenAddress,
|
||||
address stableDebtTokenAddress,
|
||||
address variableDebtTokenAddress,
|
||||
address interestRateStrategyAddress
|
||||
) external {
|
||||
require(reserve.aTokenAddress == address(0), Errors.RL_RESERVE_ALREADY_INITIALIZED);
|
||||
|
||||
|
||||
reserve.liquidityIndex = uint128(WadRayMath.ray());
|
||||
reserve.variableBorrowIndex = uint128(WadRayMath.ray());
|
||||
reserve.aTokenAddress = aTokenAddress;
|
||||
|
@ -213,7 +198,7 @@ library ReserveLogic {
|
|||
* @param liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow)
|
||||
**/
|
||||
function updateInterestRates(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
address aTokenAddress,
|
||||
uint256 liquidityAdded,
|
||||
|
@ -289,7 +274,7 @@ library ReserveLogic {
|
|||
* @param newVariableBorrowIndex the variable borrow index after the last accumulation of the interest
|
||||
**/
|
||||
function _mintToTreasury(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 previousVariableBorrowIndex,
|
||||
uint256 newLiquidityIndex,
|
||||
|
@ -349,7 +334,7 @@ library ReserveLogic {
|
|||
* @param variableBorrowIndex the last stored variable borrow index
|
||||
**/
|
||||
function _updateIndexes(
|
||||
ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 scaledVariableDebt,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex,
|
||||
|
@ -362,10 +347,8 @@ library ReserveLogic {
|
|||
|
||||
//only cumulating if there is any income being produced
|
||||
if (currentLiquidityRate > 0) {
|
||||
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
|
||||
currentLiquidityRate,
|
||||
timestamp
|
||||
);
|
||||
uint256 cumulatedLiquidityInterest =
|
||||
MathUtils.calculateLinearInterest(currentLiquidityRate, timestamp);
|
||||
newLiquidityIndex = cumulatedLiquidityInterest.rayMul(liquidityIndex);
|
||||
require(newLiquidityIndex < type(uint128).max, Errors.RL_LIQUIDITY_INDEX_OVERFLOW);
|
||||
|
||||
|
@ -374,12 +357,13 @@ library ReserveLogic {
|
|||
//as the liquidity rate might come only from stable rate loans, we need to ensure
|
||||
//that there is actual variable debt before accumulating
|
||||
if (scaledVariableDebt != 0) {
|
||||
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
|
||||
reserve.currentVariableBorrowRate,
|
||||
timestamp
|
||||
);
|
||||
uint256 cumulatedVariableBorrowInterest =
|
||||
MathUtils.calculateCompoundedInterest(reserve.currentVariableBorrowRate, timestamp);
|
||||
newVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(variableBorrowIndex);
|
||||
require(newVariableBorrowIndex < type(uint128).max, Errors.RL_VARIABLE_BORROW_INDEX_OVERFLOW);
|
||||
require(
|
||||
newVariableBorrowIndex < type(uint128).max,
|
||||
Errors.RL_VARIABLE_BORROW_INDEX_OVERFLOW
|
||||
);
|
||||
reserve.variableBorrowIndex = uint128(newVariableBorrowIndex);
|
||||
}
|
||||
}
|
|
@ -1,19 +1,20 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {GenericLogic} from './GenericLogic.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {SafeERC20} from '../../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
import {Helpers} from '../helpers/Helpers.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {DataTypes} from '../types/DataTypes.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -21,13 +22,13 @@ import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRat
|
|||
* @notice Implements functions to validate specific action on the protocol.
|
||||
*/
|
||||
library ValidationLogic {
|
||||
using ReserveLogic for ReserveLogic.ReserveData;
|
||||
using ReserveLogic for DataTypes.ReserveData;
|
||||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using PercentageMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
using ReserveConfiguration for ReserveConfiguration.Map;
|
||||
using UserConfiguration for UserConfiguration.Map;
|
||||
using ReserveConfiguration for DataTypes.ReserveConfigurationMap;
|
||||
using UserConfiguration for DataTypes.UserConfigurationMap;
|
||||
|
||||
uint256 public constant REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD = 4000;
|
||||
uint256 public constant REBALANCE_UP_USAGE_RATIO_THRESHOLD = 0.95 * 1e27; //usage ratio of 95%
|
||||
|
@ -37,7 +38,7 @@ library ValidationLogic {
|
|||
* @param reserve the reserve state on which the user is depositing
|
||||
* @param amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount) external view {
|
||||
function validateDeposit(DataTypes.ReserveData storage reserve, uint256 amount) external view {
|
||||
(bool isActive, bool isFrozen, , ) = reserve.configuration.getFlags();
|
||||
|
||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||
|
@ -60,17 +61,16 @@ library ValidationLogic {
|
|||
address reserveAddress,
|
||||
uint256 amount,
|
||||
uint256 userBalance,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
) external view {
|
||||
|
||||
require(amount != 0, Errors.VL_INVALID_AMOUNT);
|
||||
require(amount <= userBalance, Errors.VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE);
|
||||
|
||||
(bool isActive,, , ) = reservesData[reserveAddress].configuration.getFlags();
|
||||
(bool isActive, , , ) = reservesData[reserveAddress].configuration.getFlags();
|
||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||
|
||||
require(
|
||||
|
@ -101,7 +101,7 @@ library ValidationLogic {
|
|||
uint256 availableLiquidity;
|
||||
uint256 finalUserBorrowRate;
|
||||
uint256 healthFactor;
|
||||
ReserveLogic.InterestRateMode rateMode;
|
||||
DataTypes.InterestRateMode rateMode;
|
||||
bool healthFactorBelowThreshold;
|
||||
bool isActive;
|
||||
bool isFrozen;
|
||||
|
@ -126,14 +126,14 @@ library ValidationLogic {
|
|||
|
||||
function validateBorrow(
|
||||
address asset,
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address userAddress,
|
||||
uint256 amount,
|
||||
uint256 amountInETH,
|
||||
uint256 interestRateMode,
|
||||
uint256 maxStableLoanPercent,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -152,8 +152,8 @@ library ValidationLogic {
|
|||
|
||||
//validate interest rate mode
|
||||
require(
|
||||
uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode ||
|
||||
uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode,
|
||||
uint256(DataTypes.InterestRateMode.VARIABLE) == interestRateMode ||
|
||||
uint256(DataTypes.InterestRateMode.STABLE) == interestRateMode,
|
||||
Errors.VL_INVALID_INTEREST_RATE_MODE_SELECTED
|
||||
);
|
||||
|
||||
|
@ -198,7 +198,7 @@ library ValidationLogic {
|
|||
* liquidity
|
||||
**/
|
||||
|
||||
if (vars.rateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (vars.rateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
//check if the borrow mode is stable and if stable rate borrowing is enabled on this reserve
|
||||
|
||||
require(vars.stableRateBorrowingEnabled, Errors.VL_STABLE_BORROWING_NOT_ENABLED);
|
||||
|
@ -229,9 +229,9 @@ library ValidationLogic {
|
|||
* @param variableDebt the borrow balance of the user
|
||||
*/
|
||||
function validateRepay(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
uint256 amountSent,
|
||||
ReserveLogic.InterestRateMode rateMode,
|
||||
DataTypes.InterestRateMode rateMode,
|
||||
address onBehalfOf,
|
||||
uint256 stableDebt,
|
||||
uint256 variableDebt
|
||||
|
@ -244,9 +244,9 @@ library ValidationLogic {
|
|||
|
||||
require(
|
||||
(stableDebt > 0 &&
|
||||
ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) ||
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.STABLE) ||
|
||||
(variableDebt > 0 &&
|
||||
ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE),
|
||||
DataTypes.InterestRateMode(rateMode) == DataTypes.InterestRateMode.VARIABLE),
|
||||
Errors.VL_NO_DEBT_OF_SELECTED_TYPE
|
||||
);
|
||||
|
||||
|
@ -265,20 +265,20 @@ library ValidationLogic {
|
|||
* @param currentRateMode the rate mode of the borrow
|
||||
*/
|
||||
function validateSwapRateMode(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
uint256 stableDebt,
|
||||
uint256 variableDebt,
|
||||
ReserveLogic.InterestRateMode currentRateMode
|
||||
DataTypes.InterestRateMode currentRateMode
|
||||
) external view {
|
||||
(bool isActive, bool isFrozen, , bool stableRateEnabled) = reserve.configuration.getFlags();
|
||||
|
||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||
require(!isFrozen, Errors.VL_RESERVE_FROZEN);
|
||||
|
||||
if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) {
|
||||
if (currentRateMode == DataTypes.InterestRateMode.STABLE) {
|
||||
require(stableDebt > 0, Errors.VL_NO_STABLE_RATE_LOAN_IN_RESERVE);
|
||||
} else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) {
|
||||
} else if (currentRateMode == DataTypes.InterestRateMode.VARIABLE) {
|
||||
require(variableDebt > 0, Errors.VL_NO_VARIABLE_RATE_LOAN_IN_RESERVE);
|
||||
/**
|
||||
* user wants to swap to stable, before swapping we need to ensure that
|
||||
|
@ -309,35 +309,28 @@ library ValidationLogic {
|
|||
* @param aTokenAddress the address of the aToken contract
|
||||
*/
|
||||
function validateRebalanceStableBorrowRate(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
IERC20 stableDebtToken,
|
||||
IERC20 variableDebtToken,
|
||||
address aTokenAddress) external view {
|
||||
|
||||
(bool isActive,,, ) = reserve.configuration.getFlags();
|
||||
address aTokenAddress
|
||||
) external view {
|
||||
(bool isActive, , , ) = reserve.configuration.getFlags();
|
||||
|
||||
require(isActive, Errors.VL_NO_ACTIVE_RESERVE);
|
||||
|
||||
//if the usage ratio is below 95%, no rebalances are needed
|
||||
uint256 totalDebt = stableDebtToken
|
||||
.totalSupply()
|
||||
.add(variableDebtToken.totalSupply())
|
||||
.wadToRay();
|
||||
uint256 totalDebt =
|
||||
stableDebtToken.totalSupply().add(variableDebtToken.totalSupply()).wadToRay();
|
||||
uint256 availableLiquidity = IERC20(reserveAddress).balanceOf(aTokenAddress).wadToRay();
|
||||
uint256 usageRatio = totalDebt == 0
|
||||
? 0
|
||||
: totalDebt.rayDiv(availableLiquidity.add(totalDebt));
|
||||
uint256 usageRatio = totalDebt == 0 ? 0 : totalDebt.rayDiv(availableLiquidity.add(totalDebt));
|
||||
|
||||
//if the liquidity rate is below REBALANCE_UP_THRESHOLD of the max variable APR at 95% usage,
|
||||
//then we allow rebalancing of the stable rate positions.
|
||||
|
||||
uint256 currentLiquidityRate = reserve.currentLiquidityRate;
|
||||
uint256 maxVariableBorrowRate = IReserveInterestRateStrategy(
|
||||
reserve
|
||||
.interestRateStrategyAddress
|
||||
)
|
||||
.getMaxVariableBorrowRate();
|
||||
uint256 maxVariableBorrowRate =
|
||||
IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).getMaxVariableBorrowRate();
|
||||
|
||||
require(
|
||||
usageRatio >= REBALANCE_UP_USAGE_RATIO_THRESHOLD &&
|
||||
|
@ -345,7 +338,6 @@ library ValidationLogic {
|
|||
maxVariableBorrowRate.percentMul(REBALANCE_UP_LIQUIDITY_RATE_THRESHOLD),
|
||||
Errors.LP_INTEREST_RATE_REBALANCE_CONDITIONS_NOT_MET
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,11 +350,11 @@ library ValidationLogic {
|
|||
* @param oracle the price oracle
|
||||
*/
|
||||
function validateSetUseReserveAsCollateral(
|
||||
ReserveLogic.ReserveData storage reserve,
|
||||
DataTypes.ReserveData storage reserve,
|
||||
address reserveAddress,
|
||||
bool useAsCollateral,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
|
@ -373,16 +365,16 @@ library ValidationLogic {
|
|||
|
||||
require(
|
||||
useAsCollateral ||
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
reserveAddress,
|
||||
msg.sender,
|
||||
underlyingBalance,
|
||||
reservesData,
|
||||
userConfig,
|
||||
reserves,
|
||||
reservesCount,
|
||||
oracle
|
||||
),
|
||||
GenericLogic.balanceDecreaseAllowed(
|
||||
reserveAddress,
|
||||
msg.sender,
|
||||
underlyingBalance,
|
||||
reservesData,
|
||||
userConfig,
|
||||
reserves,
|
||||
reservesCount,
|
||||
oracle
|
||||
),
|
||||
Errors.VL_DEPOSIT_ALREADY_IN_USE
|
||||
);
|
||||
}
|
||||
|
@ -406,9 +398,9 @@ library ValidationLogic {
|
|||
* @param userVariableDebt Total variable debt balance of the user
|
||||
**/
|
||||
function validateLiquidationCall(
|
||||
ReserveLogic.ReserveData storage collateralReserve,
|
||||
ReserveLogic.ReserveData storage principalReserve,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
DataTypes.ReserveData storage collateralReserve,
|
||||
DataTypes.ReserveData storage principalReserve,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
uint256 userHealthFactor,
|
||||
uint256 userStableDebt,
|
||||
uint256 userVariableDebt
|
||||
|
@ -429,8 +421,9 @@ library ValidationLogic {
|
|||
);
|
||||
}
|
||||
|
||||
bool isCollateralEnabled = collateralReserve.configuration.getLiquidationThreshold() > 0 &&
|
||||
userConfig.isUsingAsCollateral(collateralReserve.id);
|
||||
bool isCollateralEnabled =
|
||||
collateralReserve.configuration.getLiquidationThreshold() > 0 &&
|
||||
userConfig.isUsingAsCollateral(collateralReserve.id);
|
||||
|
||||
//if collateral isn't enabled as collateral by user, it cannot be liquidated
|
||||
if (!isCollateralEnabled) {
|
||||
|
@ -460,20 +453,21 @@ library ValidationLogic {
|
|||
*/
|
||||
function validateTransfer(
|
||||
address from,
|
||||
mapping(address => ReserveLogic.ReserveData) storage reservesData,
|
||||
UserConfiguration.Map storage userConfig,
|
||||
mapping(address => DataTypes.ReserveData) storage reservesData,
|
||||
DataTypes.UserConfigurationMap storage userConfig,
|
||||
mapping(uint256 => address) storage reserves,
|
||||
uint256 reservesCount,
|
||||
address oracle
|
||||
) internal view {
|
||||
(, , , , uint256 healthFactor) = GenericLogic.calculateUserAccountData(
|
||||
from,
|
||||
reservesData,
|
||||
userConfig,
|
||||
reserves,
|
||||
reservesCount,
|
||||
oracle
|
||||
);
|
||||
(, , , , uint256 healthFactor) =
|
||||
GenericLogic.calculateUserAccountData(
|
||||
from,
|
||||
reservesData,
|
||||
userConfig,
|
||||
reserves,
|
||||
reservesCount,
|
||||
oracle
|
||||
);
|
||||
|
||||
require(
|
||||
healthFactor >= GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD,
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
|
||||
library MathUtils {
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Errors} from '../helpers/Errors.sol';
|
||||
|
49
contracts/protocol/libraries/types/DataTypes.sol
Normal file
49
contracts/protocol/libraries/types/DataTypes.sol
Normal file
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
library DataTypes {
|
||||
// refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
struct ReserveData {
|
||||
//stores the reserve configuration
|
||||
ReserveConfigurationMap configuration;
|
||||
//the liquidity index. Expressed in ray
|
||||
uint128 liquidityIndex;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint128 variableBorrowIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
uint128 currentLiquidityRate;
|
||||
//the current variable borrow rate. Expressed in ray
|
||||
uint128 currentVariableBorrowRate;
|
||||
//the current stable borrow rate. Expressed in ray
|
||||
uint128 currentStableBorrowRate;
|
||||
uint40 lastUpdateTimestamp;
|
||||
//tokens addresses
|
||||
address aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
//address of the interest rate strategy
|
||||
address interestRateStrategyAddress;
|
||||
//the id of the reserve. Represents the position in the list of the active reserves
|
||||
uint8 id;
|
||||
}
|
||||
|
||||
struct ReserveConfigurationMap {
|
||||
//bit 0-15: LTV
|
||||
//bit 16-31: Liq. threshold
|
||||
//bit 32-47: Liq. bonus
|
||||
//bit 48-55: Decimals
|
||||
//bit 56: Reserve is active
|
||||
//bit 57: reserve is frozen
|
||||
//bit 58: borrowing is enabled
|
||||
//bit 59: stable rate borrowing enabled
|
||||
//bit 60-63: reserved
|
||||
//bit 64-79: reserve factor
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
struct UserConfigurationMap {
|
||||
uint256 data;
|
||||
}
|
||||
|
||||
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IncentivizedERC20} from './IncentivizedERC20.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
import {VersionedInitializable} from '../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
import {IAToken} from './interfaces/IAToken.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol';
|
||||
|
||||
/**
|
||||
* @title Aave ERC20 AToken
|
||||
|
@ -21,12 +21,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
using SafeERC20 for IERC20;
|
||||
|
||||
bytes public constant EIP712_REVISION = bytes('1');
|
||||
bytes32 internal constant EIP712_DOMAIN = keccak256(
|
||||
'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
|
||||
);
|
||||
bytes32 public constant PERMIT_TYPEHASH = keccak256(
|
||||
'Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'
|
||||
);
|
||||
bytes32 internal constant EIP712_DOMAIN =
|
||||
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)');
|
||||
bytes32 public constant PERMIT_TYPEHASH =
|
||||
keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)');
|
||||
|
||||
uint256 public constant UINT_MAX_VALUE = uint256(-1);
|
||||
uint256 public constant ATOKEN_REVISION = 0x1;
|
||||
|
@ -57,7 +55,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
RESERVE_TREASURY_ADDRESS = reserveTreasuryAddress;
|
||||
}
|
||||
|
||||
function getRevision() internal virtual override pure returns (uint256) {
|
||||
function getRevision() internal pure virtual override returns (uint256) {
|
||||
return ATOKEN_REVISION;
|
||||
}
|
||||
|
||||
|
@ -187,8 +185,8 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
**/
|
||||
function balanceOf(address user)
|
||||
public
|
||||
override(IncentivizedERC20, IERC20)
|
||||
view
|
||||
override(IncentivizedERC20, IERC20)
|
||||
returns (uint256)
|
||||
{
|
||||
return super.balanceOf(user).rayMul(POOL.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS));
|
||||
|
@ -200,7 +198,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
* @param user the address of the user
|
||||
* @return the scaled balance of the user
|
||||
**/
|
||||
function scaledBalanceOf(address user) external override view returns (uint256) {
|
||||
function scaledBalanceOf(address user) external view override returns (uint256) {
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
|
@ -212,8 +210,8 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
**/
|
||||
function getScaledUserBalanceAndSupply(address user)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (super.balanceOf(user), super.totalSupply());
|
||||
|
@ -225,7 +223,7 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
* does that too.
|
||||
* @return the current total supply
|
||||
**/
|
||||
function totalSupply() public override(IncentivizedERC20, IERC20) view returns (uint256) {
|
||||
function totalSupply() public view override(IncentivizedERC20, IERC20) returns (uint256) {
|
||||
uint256 currentSupplyScaled = super.totalSupply();
|
||||
|
||||
if (currentSupplyScaled == 0) {
|
||||
|
@ -236,10 +234,10 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index)
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)
|
||||
* @return the scaled total supply
|
||||
**/
|
||||
function scaledTotalSupply() public virtual override view returns (uint256) {
|
||||
function scaledTotalSupply() public view virtual override returns (uint256) {
|
||||
return super.totalSupply();
|
||||
}
|
||||
|
||||
|
@ -283,13 +281,14 @@ contract AToken is VersionedInitializable, IncentivizedERC20, IAToken {
|
|||
//solium-disable-next-line
|
||||
require(block.timestamp <= deadline, 'INVALID_EXPIRATION');
|
||||
uint256 currentValidNonce = _nonces[owner];
|
||||
bytes32 digest = keccak256(
|
||||
abi.encodePacked(
|
||||
'\x19\x01',
|
||||
DOMAIN_SEPARATOR,
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
|
||||
)
|
||||
);
|
||||
bytes32 digest =
|
||||
keccak256(
|
||||
abi.encodePacked(
|
||||
'\x19\x01',
|
||||
DOMAIN_SEPARATOR,
|
||||
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline))
|
||||
)
|
||||
);
|
||||
require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE');
|
||||
_nonces[owner] = currentValidNonce.add(1);
|
||||
_approve(owner, spender, value);
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {AToken} from './AToken.sol';
|
||||
import {ILendingPool} from '../interfaces/ILendingPool.sol';
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {Errors} from '../libraries/helpers/Errors.sol';
|
||||
|
||||
/**
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity 0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {Context} from '../dependencies/openzeppelin/contracts/Context.sol';
|
||||
import {IERC20} from '../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {SafeMath} from '../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol';
|
||||
import {Context} from '../../dependencies/openzeppelin/contracts/Context.sol';
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {IERC20Detailed} from '../../dependencies/openzeppelin/contracts/IERC20Detailed.sol';
|
||||
import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol';
|
||||
import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol';
|
||||
|
||||
/**
|
||||
* @title ERC20
|
||||
|
@ -40,35 +40,35 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
/**
|
||||
* @return the name of the token
|
||||
**/
|
||||
function name() public override view returns (string memory) {
|
||||
function name() public view override returns (string memory) {
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the symbol of the token
|
||||
**/
|
||||
function symbol() public override view returns (string memory) {
|
||||
function symbol() public view override returns (string memory) {
|
||||
return _symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the decimals of the token
|
||||
**/
|
||||
function decimals() public override view returns (uint8) {
|
||||
function decimals() public view override returns (uint8) {
|
||||
return _decimals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total supply of the token
|
||||
**/
|
||||
function totalSupply() public virtual override view returns (uint256) {
|
||||
function totalSupply() public view virtual override returns (uint256) {
|
||||
return _totalSupply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the balance of the token
|
||||
**/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
function balanceOf(address account) public view virtual override returns (uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
|
@ -92,9 +92,9 @@ contract IncentivizedERC20 is Context, IERC20, IERC20Detailed {
|
|||
**/
|
||||
function allowance(address owner, address spender)
|
||||
public
|
||||
view
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _allowances[owner][spender];
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {MathUtils} from '../libraries/math/MathUtils.sol';
|
||||
|
@ -34,7 +34,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @dev gets the revision of the stable debt token implementation
|
||||
* @return the debt token implementation revision
|
||||
**/
|
||||
function getRevision() internal virtual override pure returns (uint256) {
|
||||
function getRevision() internal pure virtual override returns (uint256) {
|
||||
return DEBT_TOKEN_REVISION;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @dev returns the average stable rate across all the stable rate debt
|
||||
* @return the average stable rate
|
||||
**/
|
||||
function getAverageStableRate() external virtual override view returns (uint256) {
|
||||
function getAverageStableRate() external view virtual override returns (uint256) {
|
||||
return _avgStableRate;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @dev returns the timestamp of the last user action
|
||||
* @return the last update timestamp
|
||||
**/
|
||||
function getUserLastUpdated(address user) external virtual override view returns (uint40) {
|
||||
function getUserLastUpdated(address user) external view virtual override returns (uint40) {
|
||||
return _timestamps[user];
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @param user the address of the user
|
||||
* @return the stable rate of user
|
||||
**/
|
||||
function getUserStableRate(address user) external virtual override view returns (uint256) {
|
||||
function getUserStableRate(address user) external view virtual override returns (uint256) {
|
||||
return _usersStableRate[user];
|
||||
}
|
||||
|
||||
|
@ -67,16 +67,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @dev calculates the current user debt balance
|
||||
* @return the accumulated debt of the user
|
||||
**/
|
||||
function balanceOf(address account) public virtual override view returns (uint256) {
|
||||
function balanceOf(address account) public view virtual override returns (uint256) {
|
||||
uint256 accountBalance = super.balanceOf(account);
|
||||
uint256 stableRate = _usersStableRate[account];
|
||||
if (accountBalance == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(
|
||||
stableRate,
|
||||
_timestamps[account]
|
||||
);
|
||||
uint256 cumulatedInterest =
|
||||
MathUtils.calculateCompoundedInterest(stableRate, _timestamps[account]);
|
||||
return accountBalance.rayMul(cumulatedInterest);
|
||||
}
|
||||
|
||||
|
@ -248,8 +246,8 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
**/
|
||||
function getSupplyData()
|
||||
public
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (
|
||||
uint256,
|
||||
uint256,
|
||||
|
@ -264,7 +262,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
/**
|
||||
* @dev returns the the total supply and the average stable rate
|
||||
**/
|
||||
function getTotalSupplyAndAvgRate() public override view returns (uint256, uint256) {
|
||||
function getTotalSupplyAndAvgRate() public view override returns (uint256, uint256) {
|
||||
uint256 avgRate = _avgStableRate;
|
||||
return (_calcTotalSupply(avgRate), avgRate);
|
||||
}
|
||||
|
@ -272,14 +270,14 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
/**
|
||||
* @dev returns the total supply
|
||||
**/
|
||||
function totalSupply() public override view returns (uint256) {
|
||||
function totalSupply() public view override returns (uint256) {
|
||||
return _calcTotalSupply(_avgStableRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the timestamp at which the total supply was updated
|
||||
**/
|
||||
function getTotalSupplyLastUpdated() public override view returns (uint40) {
|
||||
function getTotalSupplyLastUpdated() public view override returns (uint40) {
|
||||
return _totalSupplyTimestamp;
|
||||
}
|
||||
|
||||
|
@ -288,7 +286,7 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @param user the user
|
||||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function principalBalanceOf(address user) external virtual override view returns (uint256) {
|
||||
function principalBalanceOf(address user) external view virtual override returns (uint256) {
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
|
@ -297,17 +295,15 @@ contract StableDebtToken is IStableDebtToken, DebtTokenBase {
|
|||
* @param avgRate the average rate at which calculate the total supply
|
||||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function _calcTotalSupply(uint256 avgRate) internal virtual view returns (uint256) {
|
||||
function _calcTotalSupply(uint256 avgRate) internal view virtual returns (uint256) {
|
||||
uint256 principalSupply = super.totalSupply();
|
||||
|
||||
if (principalSupply == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 cumulatedInterest = MathUtils.calculateCompoundedInterest(
|
||||
avgRate,
|
||||
_totalSupplyTimestamp
|
||||
);
|
||||
uint256 cumulatedInterest =
|
||||
MathUtils.calculateCompoundedInterest(avgRate, _totalSupplyTimestamp);
|
||||
|
||||
return principalSupply.rayMul(cumulatedInterest);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
|
@ -28,7 +28,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @dev gets the revision of the stable debt token implementation
|
||||
* @return the debt token implementation revision
|
||||
**/
|
||||
function getRevision() internal virtual override pure returns (uint256) {
|
||||
function getRevision() internal pure virtual override returns (uint256) {
|
||||
return DEBT_TOKEN_REVISION;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @dev calculates the accumulated debt balance of the user
|
||||
* @return the debt balance of the user
|
||||
**/
|
||||
function balanceOf(address user) public virtual override view returns (uint256) {
|
||||
function balanceOf(address user) public view virtual override returns (uint256) {
|
||||
uint256 scaledBalance = super.balanceOf(user);
|
||||
|
||||
if (scaledBalance == 0) {
|
||||
|
@ -98,7 +98,7 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @dev Returns the principal debt balance of the user from
|
||||
* @return The debt balance of the user since the last burn/mint action
|
||||
**/
|
||||
function scaledBalanceOf(address user) public virtual override view returns (uint256) {
|
||||
function scaledBalanceOf(address user) public view virtual override returns (uint256) {
|
||||
return super.balanceOf(user);
|
||||
}
|
||||
|
||||
|
@ -106,16 +106,16 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
* @dev Returns the total supply of the variable debt token. Represents the total debt accrued by the users
|
||||
* @return the total supply
|
||||
**/
|
||||
function totalSupply() public virtual override view returns (uint256) {
|
||||
function totalSupply() public view virtual override returns (uint256) {
|
||||
return
|
||||
super.totalSupply().rayMul(POOL.getReserveNormalizedVariableDebt(UNDERLYING_ASSET_ADDRESS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index)
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)
|
||||
* @return the scaled total supply
|
||||
**/
|
||||
function scaledTotalSupply() public virtual override view returns (uint256) {
|
||||
function scaledTotalSupply() public view virtual override returns (uint256) {
|
||||
return super.totalSupply();
|
||||
}
|
||||
|
||||
|
@ -127,8 +127,8 @@ contract VariableDebtToken is DebtTokenBase, IVariableDebtToken {
|
|||
**/
|
||||
function getScaledUserBalanceAndSupply(address user)
|
||||
external
|
||||
override
|
||||
view
|
||||
override
|
||||
returns (uint256, uint256)
|
||||
{
|
||||
return (super.balanceOf(user), super.totalSupply());
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {ILendingPool} from '../../interfaces/ILendingPool.sol';
|
||||
import {ILendingPool} from '../../../interfaces/ILendingPool.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../../libraries/aave-upgradeability/VersionedInitializable.sol';
|
||||
|
@ -100,9 +100,9 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
|
|||
|
||||
function allowance(address owner, address spender)
|
||||
public
|
||||
view
|
||||
virtual
|
||||
override
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
owner;
|
||||
|
@ -154,10 +154,8 @@ abstract contract DebtTokenBase is IncentivizedERC20, VersionedInitializable {
|
|||
address delegatee,
|
||||
uint256 amount
|
||||
) internal {
|
||||
uint256 newAllowance = _borrowAllowances[delegator][delegatee].sub(
|
||||
amount,
|
||||
Errors.BORROW_ALLOWANCE_NOT_ENOUGH
|
||||
);
|
||||
uint256 newAllowance =
|
||||
_borrowAllowances[delegator][delegatee].sub(amount, Errors.BORROW_ALLOWANCE_NOT_ENOUGH);
|
||||
|
||||
_borrowAllowances[delegator][delegatee] = newAllowance;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol';
|
||||
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
|
||||
|
||||
interface IAToken is IERC20, IScaledBalanceToken {
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
interface IScaledBalanceToken {
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@ interface IScaledBalanceToken {
|
|||
function getScaledUserBalanceAndSupply(address user) external view returns (uint256, uint256);
|
||||
|
||||
/**
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(borrows/index)
|
||||
* @dev Returns the scaled total supply of the variable debt token. Represents sum(debt/index)
|
||||
* @return the scaled total supply
|
||||
**/
|
||||
function scaledTotalSupply() external view returns (uint256);
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
/**
|
||||
* @title interface IStableDebtToken
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6;
|
||||
|
||||
/**
|
|
@ -1,5 +1,5 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
pragma solidity 0.6.12;
|
||||
|
||||
import {IScaledBalanceToken} from './IScaledBalanceToken.sol';
|
||||
|
|
@ -4,4 +4,6 @@ services:
|
|||
build:
|
||||
context: ./
|
||||
dockerfile: ./Dockerfile_test
|
||||
command: npm run test
|
||||
environment:
|
||||
- MNEMONIC
|
||||
- ALCHEMY_KEY
|
||||
|
|
|
@ -71,7 +71,7 @@ const mainnetFork = MAINNET_FORK
|
|||
|
||||
const buidlerConfig: HardhatUserConfig = {
|
||||
solidity: {
|
||||
version: '0.6.8',
|
||||
version: '0.6.12',
|
||||
settings: {
|
||||
optimizer: {enabled: true, runs: 200},
|
||||
evmVersion: 'istanbul',
|
||||
|
|
|
@ -16,7 +16,6 @@ export const MAX_UINT_AMOUNT =
|
|||
export const ONE_YEAR = '31536000';
|
||||
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
||||
export const ONE_ADDRESS = '0x0000000000000000000000000000000000000001';
|
||||
|
||||
// ----------------
|
||||
// PROTOCOL GLOBAL PARAMS
|
||||
// ----------------
|
||||
|
|
|
@ -165,8 +165,8 @@ export const deployAaveLibraries = async (
|
|||
// libPath example: contracts/libraries/logic/GenericLogic.sol
|
||||
// libName example: GenericLogic
|
||||
return {
|
||||
['__$5201a97c05ba6aa659e2f36a933dd51801$__']: validationLogic.address,
|
||||
['__$d3b4366daeb9cadc7528af6145b50b2183$__']: reserveLogic.address,
|
||||
['__$de8c0cf1a7d7c36c802af9a64fb9d86036$__']: validationLogic.address,
|
||||
['__$22cd43a9dda9ce44e9b92ba393b88fb9ac$__']: reserveLogic.address,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -247,14 +247,11 @@ export const deployMockFlashLoanReceiver = async (
|
|||
verify
|
||||
);
|
||||
|
||||
export const deployWalletBalancerProvider = async (
|
||||
addressesProvider: tEthereumAddress,
|
||||
verify?: boolean
|
||||
) =>
|
||||
export const deployWalletBalancerProvider = async (verify?: boolean) =>
|
||||
withSaveAndVerify(
|
||||
await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(addressesProvider),
|
||||
await new WalletBalanceProviderFactory(await getFirstSigner()).deploy(),
|
||||
eContractid.WalletBalanceProvider,
|
||||
[addressesProvider],
|
||||
[],
|
||||
verify
|
||||
);
|
||||
|
||||
|
@ -291,7 +288,7 @@ export const deployMintableDelegationERC20 = async (
|
|||
verify
|
||||
);
|
||||
export const deployDefaultReserveInterestRateStrategy = async (
|
||||
args: [tEthereumAddress, string, string, string, string, string],
|
||||
args: [tEthereumAddress, string, string, string, string, string, string],
|
||||
verify: boolean
|
||||
) =>
|
||||
withSaveAndVerify(
|
||||
|
@ -369,7 +366,7 @@ export const deployDelegationAwareAToken = async (
|
|||
] = [poolAddress, underlyingAssetAddress, ZERO_ADDRESS, name, symbol, incentivesController];
|
||||
return withSaveAndVerify(
|
||||
await new DelegationAwareATokenFactory(await getFirstSigner()).deploy(...args),
|
||||
eContractid.AToken,
|
||||
eContractid.DelegationAwareAToken,
|
||||
args,
|
||||
verify
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { iMultiPoolsAssets, IReserveParams, tEthereumAddress } from './types';
|
||||
import { eContractid, iMultiPoolsAssets, IReserveParams, tEthereumAddress } from './types';
|
||||
import { AaveProtocolDataProvider } from '../types/AaveProtocolDataProvider';
|
||||
import { chunk, waitForTx } from './misc-utils';
|
||||
import {
|
||||
|
@ -8,17 +8,38 @@ import {
|
|||
} from './contracts-getters';
|
||||
import { rawInsertContractAddressInDb } from './contracts-helpers';
|
||||
import { BigNumberish } from 'ethers';
|
||||
import {
|
||||
deployDefaultReserveInterestRateStrategy,
|
||||
deployDelegationAwareAToken,
|
||||
deployGenericAToken,
|
||||
deployStableDebtToken,
|
||||
deployVariableDebtToken,
|
||||
} from './contracts-deployments';
|
||||
import { ZERO_ADDRESS } from './constants';
|
||||
|
||||
const chooseATokenDeployment = (id: eContractid) => {
|
||||
switch (id) {
|
||||
case eContractid.AToken:
|
||||
return deployGenericAToken;
|
||||
case eContractid.DelegationAwareAToken:
|
||||
return deployDelegationAwareAToken;
|
||||
default:
|
||||
throw Error(`Missing aToken deployment script for: ${id}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const initReservesByHelper = async (
|
||||
reservesParams: iMultiPoolsAssets<IReserveParams>,
|
||||
tokenAddresses: { [symbol: string]: tEthereumAddress },
|
||||
admin: tEthereumAddress,
|
||||
incentivesController: tEthereumAddress
|
||||
incentivesController: tEthereumAddress,
|
||||
verify: boolean
|
||||
) => {
|
||||
const stableAndVariableDeployer = await getStableAndVariableTokensHelper();
|
||||
const atokenAndRatesDeployer = await getATokensAndRatesHelper();
|
||||
|
||||
const addressProvider = await getLendingPoolAddressesProvider();
|
||||
const poolAddress = await addressProvider.getLendingPool();
|
||||
|
||||
// Set aTokenAndRatesDeployer as temporal admin
|
||||
await waitForTx(await addressProvider.setPoolAdmin(atokenAndRatesDeployer.address));
|
||||
|
@ -27,9 +48,11 @@ export const initReservesByHelper = async (
|
|||
const tokensChunks = 4;
|
||||
const initChunks = 6;
|
||||
|
||||
// Deploy tokens and rates in chunks
|
||||
// Deploy tokens and rates that uses common aToken in chunks
|
||||
const reservesChunks = chunk(
|
||||
Object.entries(reservesParams) as [string, IReserveParams][],
|
||||
Object.entries(reservesParams).filter(
|
||||
([_, { aTokenImpl }]) => aTokenImpl === eContractid.AToken
|
||||
) as [string, IReserveParams][],
|
||||
tokensChunks
|
||||
);
|
||||
// Initialize variables for future reserves initialization
|
||||
|
@ -39,6 +62,7 @@ export const initReservesByHelper = async (
|
|||
let deployedRates: string[] = [];
|
||||
let reserveTokens: string[] = [];
|
||||
let reserveInitDecimals: string[] = [];
|
||||
let reserveSymbols: string[] = [];
|
||||
|
||||
console.log(
|
||||
`- Token deployments in ${reservesChunks.length * 2} txs instead of ${
|
||||
|
@ -54,6 +78,7 @@ export const initReservesByHelper = async (
|
|||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish
|
||||
][] = [];
|
||||
const reservesDecimals: string[] = [];
|
||||
|
@ -72,6 +97,7 @@ export const initReservesByHelper = async (
|
|||
const [
|
||||
,
|
||||
{
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
|
@ -83,6 +109,7 @@ export const initReservesByHelper = async (
|
|||
tokens.push(tokenAddress);
|
||||
symbols.push(assetSymbol);
|
||||
strategyRates.push([
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
|
@ -126,6 +153,75 @@ export const initReservesByHelper = async (
|
|||
deployedRates = [...deployedRates, ...strategies];
|
||||
reserveInitDecimals = [...reserveInitDecimals, ...reservesDecimals];
|
||||
reserveTokens = [...reserveTokens, ...tokens];
|
||||
reserveSymbols = [...reserveSymbols, ...symbols];
|
||||
}
|
||||
|
||||
// Deploy delegated aware reserves tokens
|
||||
const delegatedAwareReserves = Object.entries(reservesParams).filter(
|
||||
([_, { aTokenImpl }]) => aTokenImpl === eContractid.DelegationAwareAToken
|
||||
) as [string, IReserveParams][];
|
||||
|
||||
for (let [symbol, params] of delegatedAwareReserves) {
|
||||
console.log(` - Deploy ${symbol} delegation await aToken, debts tokens, and strategy`);
|
||||
const {
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
} = params;
|
||||
const deployCustomAToken = chooseATokenDeployment(params.aTokenImpl);
|
||||
const aToken = await deployCustomAToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
`Aave interest bearing ${symbol}`,
|
||||
`a${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const stableDebt = await deployStableDebtToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
`Aave stable debt bearing ${symbol}`,
|
||||
`stableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const variableDebt = await deployVariableDebtToken(
|
||||
[
|
||||
poolAddress,
|
||||
tokenAddresses[symbol],
|
||||
`Aave variable debt bearing ${symbol}`,
|
||||
`variableDebt${symbol}`,
|
||||
ZERO_ADDRESS,
|
||||
],
|
||||
verify
|
||||
);
|
||||
const rates = await deployDefaultReserveInterestRateStrategy(
|
||||
[
|
||||
tokenAddresses[symbol],
|
||||
optimalUtilizationRate,
|
||||
baseVariableBorrowRate,
|
||||
variableRateSlope1,
|
||||
variableRateSlope2,
|
||||
stableRateSlope1,
|
||||
stableRateSlope2,
|
||||
],
|
||||
verify
|
||||
);
|
||||
|
||||
deployedStableTokens.push(stableDebt.address);
|
||||
deployedVariableTokens.push(variableDebt.address);
|
||||
deployedATokens.push(aToken.address);
|
||||
deployedRates.push(rates.address);
|
||||
reserveInitDecimals.push(params.reserveDecimals);
|
||||
reserveTokens.push(tokenAddresses[symbol]);
|
||||
reserveSymbols.push(symbol);
|
||||
}
|
||||
|
||||
// Deploy init reserves per chunks
|
||||
|
@ -134,7 +230,7 @@ export const initReservesByHelper = async (
|
|||
const chunkedAtokens = chunk(deployedATokens, initChunks);
|
||||
const chunkedRates = chunk(deployedRates, initChunks);
|
||||
const chunkedDecimals = chunk(reserveInitDecimals, initChunks);
|
||||
const chunkedSymbols = chunk(Object.keys(tokenAddresses), initChunks);
|
||||
const chunkedSymbols = chunk(reserveSymbols, initChunks);
|
||||
|
||||
console.log(`- Reserves initialization in ${chunkedStableTokens.length} txs`);
|
||||
for (let chunkIndex = 0; chunkIndex < chunkedDecimals.length; chunkIndex++) {
|
||||
|
|
|
@ -263,9 +263,12 @@ export enum TokenContractId {
|
|||
ENJ = 'ENJ',
|
||||
}
|
||||
|
||||
export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {}
|
||||
export interface IReserveParams extends IReserveBorrowParams, IReserveCollateralParams {
|
||||
aTokenImpl: eContractid;
|
||||
}
|
||||
|
||||
export interface IReserveBorrowParams {
|
||||
optimalUtilizationRate: string;
|
||||
baseVariableBorrowRate: string;
|
||||
variableRateSlope1: string;
|
||||
variableRateSlope2: string;
|
||||
|
@ -324,12 +327,8 @@ export enum EthereumNetwork {
|
|||
}
|
||||
|
||||
export interface IProtocolGlobalConfig {
|
||||
OptimalUtilizationRate: BigNumber;
|
||||
ExcessUtilizationRate: BigNumber;
|
||||
ApprovalAmountLendingPoolCore: string;
|
||||
TokenDistributorPercentageBase: string;
|
||||
MockUsdPriceInWei: string;
|
||||
EthereumAddress: tEthereumAddress;
|
||||
UsdAddress: tEthereumAddress;
|
||||
NilAddress: tEthereumAddress;
|
||||
OneAddress: tEthereumAddress;
|
||||
|
|
|
@ -33,12 +33,8 @@ export const CommonsConfig: ICommonConfiguration = {
|
|||
ConfigName: 'Commons',
|
||||
ProviderId: 0,
|
||||
ProtocolGlobalParams: {
|
||||
OptimalUtilizationRate: new BigNumber(0.8).times(RAY),
|
||||
ExcessUtilizationRate: new BigNumber(0.2).times(RAY),
|
||||
ApprovalAmountLendingPoolCore: '1000000000000000000000000000',
|
||||
TokenDistributorPercentageBase: '10000',
|
||||
MockUsdPriceInWei: '5848466240000000',
|
||||
EthereumAddress: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
|
||||
UsdAddress: '0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96',
|
||||
NilAddress: '0x0000000000000000000000000000000000000000',
|
||||
OneAddress: '0x0000000000000000000000000000000000000001',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user