mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
Merge branch 'fix/7' into 'master'
Resolve "Code cleanup" Closes #7 See merge request aave-tech/protocol-v2!17
This commit is contained in:
commit
440e5565ce
|
@ -3,7 +3,7 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import '../interfaces/IFeeProvider.sol';
|
||||
import '../libraries/WadRayMath.sol';
|
||||
import '../libraries/math/WadRayMath.sol';
|
||||
|
||||
/**
|
||||
* @title FeeProvider contract
|
||||
|
|
|
@ -9,7 +9,7 @@ import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
|||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import '../interfaces/IExchangeAdapter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||
import {PercentageMath} from '../libraries/math/PercentageMath.sol';
|
||||
|
||||
/// @title TokenDistributor
|
||||
/// @author Aave
|
||||
|
@ -128,9 +128,7 @@ contract TokenDistributor is ReentrancyGuard, VersionedInitializable {
|
|||
public
|
||||
{
|
||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||
uint256 _amountToDistribute = _tokens[i].balanceOf(address(this)).percentMul(
|
||||
_percentages[i]
|
||||
);
|
||||
uint256 _amountToDistribute = _tokens[i].balanceOf(address(this)).percentMul(_percentages[i]);
|
||||
|
||||
if (_amountToDistribute <= 0) {
|
||||
continue;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import '../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import '../libraries/WadRayMath.sol';
|
||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import '../interfaces/ILendingRateOracle.sol';
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IReserveInterestRateStrategy} from '../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {ILendingRateOracle} from '../interfaces/ILendingRateOracle.sol';
|
||||
|
||||
/**
|
||||
* @title DefaultReserveInterestRateStrategy contract
|
||||
|
|
|
@ -2,30 +2,29 @@
|
|||
pragma solidity ^0.6.8;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
|
||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import '../tokenization/AToken.sol';
|
||||
import '../libraries/WadRayMath.sol';
|
||||
import '../libraries/ReserveLogic.sol';
|
||||
import '../libraries/Helpers.sol';
|
||||
import '../libraries/GenericLogic.sol';
|
||||
import '../libraries/ValidationLogic.sol';
|
||||
import '../libraries/ReserveConfiguration.sol';
|
||||
import '../libraries/UserConfiguration.sol';
|
||||
import '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
|
||||
import '../interfaces/IFeeProvider.sol';
|
||||
import '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||
import './LendingPoolLiquidationManager.sol';
|
||||
import '../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {AToken} from '../tokenization/AToken.sol';
|
||||
import {Helpers} from '../libraries/helpers/Helpers.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {ReserveLogic} from '../libraries/logic/ReserveLogic.sol';
|
||||
import {GenericLogic} from '../libraries/logic/GenericLogic.sol';
|
||||
import {ValidationLogic} from '../libraries/logic/ValidationLogic.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 {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
import {IFlashLoanReceiver} from '../flashloan/interfaces/IFlashLoanReceiver.sol';
|
||||
import {LendingPoolLiquidationManager} from './LendingPoolLiquidationManager.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPool contract
|
||||
|
@ -400,15 +399,6 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
**/
|
||||
|
||||
struct RepayLocalVars {
|
||||
uint256 stableDebt;
|
||||
uint256 variableDebt;
|
||||
|
@ -417,6 +407,14 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
uint256 totalDebt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.
|
||||
**/
|
||||
function repay(
|
||||
address _reserve,
|
||||
uint256 _amount,
|
||||
|
@ -882,8 +880,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable {
|
|||
}
|
||||
|
||||
receive() external payable {
|
||||
//only contracts can send ETH to the core
|
||||
require(msg.sender.isContract(), '22');
|
||||
revert();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
pragma solidity ^0.6.8;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
|
||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import '../libraries/ReserveConfiguration.sol';
|
||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {
|
||||
InitializableAdminUpgradeabilityProxy
|
||||
} from '../libraries/openzeppelin-upgradeability/InitializableAdminUpgradeabilityProxy.sol';
|
||||
import {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {LendingPool} from './LendingPool.sol';
|
||||
import {IERC20Detailed} from '../interfaces/IERC20Detailed.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolConfigurator contract
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
|
||||
import '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
|
||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import '../tokenization/AToken.sol';
|
||||
import '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import '../tokenization/interfaces/IVariableDebtToken.sol';
|
||||
import '../libraries/WadRayMath.sol';
|
||||
import '../interfaces/IPriceOracleGetter.sol';
|
||||
import '../libraries/GenericLogic.sol';
|
||||
import '../libraries/Helpers.sol';
|
||||
import '../libraries/ReserveLogic.sol';
|
||||
import '../libraries/ReserveConfiguration.sol';
|
||||
import '../libraries/UserConfiguration.sol';
|
||||
import {PercentageMath} from '../libraries/PercentageMath.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {ReentrancyGuard} from '@openzeppelin/contracts/utils/ReentrancyGuard.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
import {LendingPoolAddressesProvider} from '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import {AToken} from '../tokenization/AToken.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 {ReserveConfiguration} from '../libraries/configuration/ReserveConfiguration.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 '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
|
||||
/**
|
||||
* @title LendingPoolLiquidationManager contract
|
||||
|
@ -87,9 +88,6 @@ contract LendingPoolLiquidationManager is ReentrancyGuard, VersionedInitializabl
|
|||
uint256 actualAmountToLiquidate;
|
||||
uint256 liquidationRatio;
|
||||
uint256 maxAmountCollateralToLiquidate;
|
||||
uint256 originationFee;
|
||||
uint256 feeLiquidated;
|
||||
uint256 liquidatedCollateralForFee;
|
||||
ReserveLogic.InterestRateMode borrowRateMode;
|
||||
uint256 userStableRate;
|
||||
uint256 maxCollateralToLiquidate;
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets if the user is borrowing the reserve identified by _reserveIndex
|
||||
* @param _self the configuration object
|
||||
* @param _reserveIndex the index of the reserve in the bitmap
|
||||
* @param _borrowing true if the user is borrowing the reserve, false otherwise
|
||||
**/
|
||||
function setBorrowing(
|
||||
UserConfiguration.Map storage _self,
|
||||
uint256 _reserveIndex,
|
||||
bool _borrowing
|
||||
) internal {
|
||||
_self.data = (_self.data & ~(1 << _reserveIndex*2)) | uint256(_borrowing ? 1 : 0) << (_reserveIndex * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets if the user is using as collateral the reserve identified by _reserveIndex
|
||||
* @param _self the configuration object
|
||||
* @param _reserveIndex the index of the reserve in the bitmap
|
||||
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
|
||||
**/
|
||||
function setUsingAsCollateral(
|
||||
UserConfiguration.Map storage _self,
|
||||
uint256 _reserveIndex,
|
||||
bool _usingAsCollateral
|
||||
) internal {
|
||||
_self.data = (_self.data & ~(1 << _reserveIndex*2+1)) | uint256(_usingAsCollateral ? 1 : 0) << (_reserveIndex * 2 + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve for borrowing or as collateral
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2)) & 3 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve for borrowing
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2)) & 1 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve as collateral
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2 + 1)) & 1 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been borrowing from any reserve
|
||||
* @param _self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isBorrowingAny(UserConfiguration.Map memory _self) internal view returns (bool) {
|
||||
return _self.data & BORROWING_MASK != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has not been using any reserve
|
||||
* @param _self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isEmpty(UserConfiguration.Map memory _self) internal view returns(bool) {
|
||||
return _self.data == 0;
|
||||
}
|
||||
}
|
|
@ -3,12 +3,10 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveConfiguration library
|
113
contracts/libraries/configuration/UserConfiguration.sol
Normal file
113
contracts/libraries/configuration/UserConfiguration.sol
Normal file
|
@ -0,0 +1,113 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../../interfaces/IFeeProvider.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets if the user is borrowing the reserve identified by _reserveIndex
|
||||
* @param _self the configuration object
|
||||
* @param _reserveIndex the index of the reserve in the bitmap
|
||||
* @param _borrowing true if the user is borrowing the reserve, false otherwise
|
||||
**/
|
||||
function setBorrowing(
|
||||
UserConfiguration.Map storage _self,
|
||||
uint256 _reserveIndex,
|
||||
bool _borrowing
|
||||
) internal {
|
||||
_self.data =
|
||||
(_self.data & ~(1 << (_reserveIndex * 2))) |
|
||||
(uint256(_borrowing ? 1 : 0) << (_reserveIndex * 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev sets if the user is using as collateral the reserve identified by _reserveIndex
|
||||
* @param _self the configuration object
|
||||
* @param _reserveIndex the index of the reserve in the bitmap
|
||||
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
|
||||
**/
|
||||
function setUsingAsCollateral(
|
||||
UserConfiguration.Map storage _self,
|
||||
uint256 _reserveIndex,
|
||||
bool _usingAsCollateral
|
||||
) internal {
|
||||
_self.data =
|
||||
(_self.data & ~(1 << (_reserveIndex * 2 + 1))) |
|
||||
(uint256(_usingAsCollateral ? 1 : 0) << (_reserveIndex * 2 + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve for borrowing or as collateral
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2)) & 3 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve for borrowing
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2)) & 1 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been using the reserve as collateral
|
||||
* @param _self the configuration object
|
||||
* @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)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return (_self.data >> (_reserveIndex * 2 + 1)) & 1 != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has been borrowing from any reserve
|
||||
* @param _self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isBorrowingAny(UserConfiguration.Map memory _self) internal view returns (bool) {
|
||||
return _self.data & BORROWING_MASK != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev used to validate if a user has not been using any reserve
|
||||
* @param _self the configuration object
|
||||
* @return true if the user has been borrowing any reserve, false otherwise
|
||||
**/
|
||||
function isEmpty(UserConfiguration.Map memory _self) internal view returns (bool) {
|
||||
return _self.data == 0;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '../tokenization/base/DebtTokenBase.sol';
|
||||
import './ReserveLogic.sol';
|
||||
|
||||
import {DebtTokenBase} from '../../tokenization/base/DebtTokenBase.sol';
|
||||
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
||||
|
||||
/**
|
||||
* @title Helpers library
|
||||
|
@ -12,7 +10,6 @@ import './ReserveLogic.sol';
|
|||
* @notice Implements calculation helpers.
|
||||
*/
|
||||
library Helpers {
|
||||
|
||||
/**
|
||||
* @dev fetches the user current stable and variable debt balances
|
||||
* @param _user the user
|
||||
|
@ -25,8 +22,8 @@ library Helpers {
|
|||
returns (uint256, uint256)
|
||||
{
|
||||
return (
|
||||
IERC20(_reserve.stableDebtTokenAddress).balanceOf(_user),
|
||||
IERC20(_reserve.variableDebtTokenAddress).balanceOf(_user)
|
||||
DebtTokenBase(_reserve.stableDebtTokenAddress).balanceOf(_user),
|
||||
DebtTokenBase(_reserve.variableDebtTokenAddress).balanceOf(_user)
|
||||
);
|
||||
}
|
||||
|
|
@ -4,15 +4,13 @@ pragma experimental ABIEncoderV2;
|
|||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from './UserConfiguration.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
import {PercentageMath} from './PercentageMath.sol';
|
||||
import '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
import '@nomiclabs/buidler/console.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 {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
|
||||
|
||||
/**
|
||||
* @title GenericLogic library
|
||||
|
@ -60,8 +58,10 @@ library GenericLogic {
|
|||
address[] calldata _reserves,
|
||||
address _oracle
|
||||
) external view returns (bool) {
|
||||
|
||||
if (!_userConfig.isBorrowingAny() || !_userConfig.isUsingAsCollateral(_reservesData[_reserve].index)) {
|
||||
if (
|
||||
!_userConfig.isBorrowingAny() ||
|
||||
!_userConfig.isUsingAsCollateral(_reservesData[_reserve].index)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3,18 +3,13 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {MathUtils} from './MathUtils.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {IStableDebtToken} from '../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||
|
||||
import '../configuration/LendingPoolAddressesProvider.sol';
|
||||
import '../interfaces/ILendingRateOracle.sol';
|
||||
import '../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import '../tokenization/AToken.sol';
|
||||
import './WadRayMath.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
import {MathUtils} from '../math/MathUtils.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {IStableDebtToken} from '../../tokenization/interfaces/IStableDebtToken.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {IReserveInterestRateStrategy} from '../../interfaces/IReserveInterestRateStrategy.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -25,16 +20,35 @@ library ReserveLogic {
|
|||
using SafeMath for uint256;
|
||||
using WadRayMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
using Address for address;
|
||||
|
||||
/**
|
||||
* @dev Emitted when the state of a reserve is updated
|
||||
* @dev NOTE: This event replaces the Deprecated ReserveUpdated() event, which didn't emit the average stable borrow rate
|
||||
* @param reserve the address of the reserve
|
||||
* @param liquidityRate the new liquidity rate
|
||||
* @param stableBorrowRate the new stable borrow rate
|
||||
* @param averageStableBorrowRate the new average 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,
|
||||
uint256 liquidityRate,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 averageStableBorrowRate,
|
||||
uint256 variableBorrowRate,
|
||||
uint256 liquidityIndex,
|
||||
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 {
|
||||
/**
|
||||
* @dev refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
|
||||
**/
|
||||
//the liquidity index. Expressed in ray
|
||||
uint256 lastLiquidityCumulativeIndex;
|
||||
//the current supply rate. Expressed in ray
|
||||
|
@ -45,27 +59,21 @@ library ReserveLogic {
|
|||
uint256 currentStableBorrowRate;
|
||||
//variable borrow index. Expressed in ray
|
||||
uint256 lastVariableBorrowCumulativeIndex;
|
||||
//stores the reserve configuration
|
||||
ReserveConfiguration.Map configuration;
|
||||
/**
|
||||
* @dev address of the aToken representing the asset
|
||||
**/
|
||||
address payable aTokenAddress;
|
||||
address stableDebtTokenAddress;
|
||||
address variableDebtTokenAddress;
|
||||
/**
|
||||
* @dev address of the interest rate strategy contract
|
||||
**/
|
||||
address interestRateStrategyAddress;
|
||||
uint40 lastUpdateTimestamp;
|
||||
// isStableBorrowRateEnabled = true means users can borrow at a stable rate
|
||||
bool isStableBorrowRateEnabled;
|
||||
//the index of the reserve in the list of the active reserves
|
||||
uint8 index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the ongoing normalized income for the reserve.
|
||||
* a value of 1e27 means there is no income. As time passes, the income is accrued.
|
||||
* A value of 2*1e27 means that the income of the reserve is double the initial amount.
|
||||
* A value of 2*1e27 means for each unit of assset two units of income have been accrued.
|
||||
* @param _reserve the reserve object
|
||||
* @return the normalized income. expressed in ray
|
||||
**/
|
||||
|
@ -114,10 +122,11 @@ library ReserveLogic {
|
|||
* @param _self the reserve object
|
||||
**/
|
||||
function updateCumulativeIndexesAndTimestamp(ReserveData storage _self) internal {
|
||||
uint256 totalBorrows = getTotalBorrows(_self);
|
||||
|
||||
if (totalBorrows > 0) {
|
||||
//only cumulating if there is any income being produced
|
||||
//only cumulating if there is any income being produced
|
||||
if (
|
||||
IERC20(_self.variableDebtTokenAddress).totalSupply() > 0 ||
|
||||
IERC20(_self.stableDebtTokenAddress).totalSupply() > 0
|
||||
) {
|
||||
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
|
||||
_self.currentLiquidityRate,
|
||||
_self.lastUpdateTimestamp
|
||||
|
@ -190,34 +199,6 @@ library ReserveLogic {
|
|||
_self.interestRateStrategyAddress = _interestRateStrategyAddress;
|
||||
}
|
||||
|
||||
function getTotalBorrows(ReserveData storage _self) internal view returns (uint256) {
|
||||
return
|
||||
IERC20(_self.stableDebtTokenAddress).totalSupply().add(
|
||||
IERC20(_self.variableDebtTokenAddress).totalSupply()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Emitted when the state of a reserve is updated
|
||||
* @dev NOTE: This event replaces the Deprecated ReserveUpdated() event, which didn't emit the average stable borrow rate
|
||||
* @param reserve the address of the reserve
|
||||
* @param liquidityRate the new liquidity rate
|
||||
* @param stableBorrowRate the new stable borrow rate
|
||||
* @param averageStableBorrowRate the new average 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,
|
||||
uint256 liquidityRate,
|
||||
uint256 stableBorrowRate,
|
||||
uint256 averageStableBorrowRate,
|
||||
uint256 variableBorrowRate,
|
||||
uint256 liquidityIndex,
|
||||
uint256 variableBorrowIndex
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev updates the state of the core as a result of a flashloan action
|
||||
* @param _reserve the address of the reserve in which the flashloan is happening
|
||||
|
@ -233,7 +214,9 @@ library ReserveLogic {
|
|||
//compounding the cumulated interest
|
||||
_reserve.updateCumulativeIndexesAndTimestamp();
|
||||
|
||||
uint256 totalLiquidityBefore = _availableLiquidityBefore.add(_reserve.getTotalBorrows());
|
||||
uint256 totalLiquidityBefore = _availableLiquidityBefore
|
||||
.add(IERC20(_reserve.variableDebtTokenAddress).totalSupply())
|
||||
.add(IERC20(_reserve.stableDebtTokenAddress).totalSupply());
|
||||
|
||||
//compounding the received fee into the reserve
|
||||
_reserve.cumulateToLiquidityIndex(totalLiquidityBefore, _income);
|
||||
|
@ -242,20 +225,6 @@ library ReserveLogic {
|
|||
updateInterestRates(_reserve, _reserveAddress, _income, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev gets the total liquidity in the reserve. The total liquidity is the balance of the core contract + total borrows
|
||||
* @param _reserve the reserve address
|
||||
* @return the total liquidity
|
||||
**/
|
||||
function getTotalLiquidity(ReserveData storage _reserve, address _reserveAddress)
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return
|
||||
IERC20(_reserveAddress).balanceOf(address(this)).add(_reserve.getTotalBorrows());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Updates the reserve current stable borrow rate Rf, the current variable borrow rate Rv and the current liquidity rate Rl.
|
||||
* Also updates the lastUpdateTimestamp value. Please refer to the whitepaper for further information.
|
||||
|
@ -300,56 +269,4 @@ library ReserveLogic {
|
|||
_reserve.lastVariableBorrowCumulativeIndex
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev gets the reserve current variable borrow rate. Is the base variable borrow rate if the reserve is empty
|
||||
* @param _reserve the reserve address
|
||||
* @return the reserve current variable borrow rate
|
||||
**/
|
||||
function getReserveCurrentVariableBorrowRate(ReserveData storage _reserve)
|
||||
external
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
if (_reserve.currentVariableBorrowRate == 0) {
|
||||
return
|
||||
IReserveInterestRateStrategy(_reserve.interestRateStrategyAddress)
|
||||
.getBaseVariableBorrowRate();
|
||||
}
|
||||
return _reserve.currentVariableBorrowRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev gets the reserve current stable borrow rate. Is the market rate if the reserve is empty
|
||||
* @param _reserve the reserve address
|
||||
* @return the reserve current stable borrow rate
|
||||
**/
|
||||
function getReserveCurrentStableBorrowRate(ReserveData storage _reserve, uint256 _baseRate)
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return _reserve.currentStableBorrowRate == 0 ? _baseRate : _reserve.currentStableBorrowRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev returns the utilization rate U of a specific reserve
|
||||
* @param _reserve the reserve for which the information is needed
|
||||
* @return the utilization rate in ray
|
||||
**/
|
||||
function getUtilizationRate(ReserveData storage _reserve, address _reserveAddress)
|
||||
public
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 totalBorrows = _reserve.getTotalBorrows();
|
||||
|
||||
if (totalBorrows == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 availableLiquidity = IERC20(_reserveAddress).balanceOf(address(this));
|
||||
|
||||
return totalBorrows.rayDiv(availableLiquidity.add(totalBorrows));
|
||||
}
|
||||
}
|
|
@ -4,17 +4,15 @@ pragma experimental ABIEncoderV2;
|
|||
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
|
||||
import {ReserveLogic} from './ReserveLogic.sol';
|
||||
import {GenericLogic} from './GenericLogic.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
import {PercentageMath} from './PercentageMath.sol';
|
||||
import {WadRayMath} from '../math/WadRayMath.sol';
|
||||
import {PercentageMath} from '../math/PercentageMath.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {ReserveConfiguration} from './ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from './UserConfiguration.sol';
|
||||
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../interfaces/IFeeProvider.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol';
|
||||
import {UserConfiguration} from '../configuration/UserConfiguration.sol';
|
||||
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
||||
import {IFeeProvider} from '../../interfaces/IFeeProvider.sol';
|
||||
|
||||
/**
|
||||
* @title ReserveLogic library
|
||||
|
@ -36,12 +34,14 @@ library ValidationLogic {
|
|||
* @param _amount the amount to be deposited
|
||||
*/
|
||||
function validateDeposit(ReserveLogic.ReserveData storage _reserve, uint256 _amount)
|
||||
external
|
||||
internal
|
||||
view
|
||||
{
|
||||
(bool isActive, bool isFreezed, , ) = _reserve.configuration.getFlags();
|
||||
|
||||
require(_amount > 0, 'Amount must be greater than 0');
|
||||
require(isActive, 'Action requires an active reserve');
|
||||
require(!isFreezed, 'Action requires an unfreezed reserve');
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import './WadRayMath.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {WadRayMath} from './WadRayMath.sol';
|
||||
|
||||
library MathUtils {
|
||||
using SafeMath for uint256;
|
||||
|
@ -34,7 +34,7 @@ library MathUtils {
|
|||
* @dev function to calculate the interest using a compounded interest rate formula.
|
||||
* To avoid expensive exponentiation, the calculation is performed using a binomial approximation:
|
||||
*
|
||||
* (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3...
|
||||
* (1+x)^n = 1+n*x+[n/2*(n-1)]*x^2+[n/6*(n-1)*(n-2)*x^3...
|
||||
*
|
||||
* The approximation slightly underpays liquidity providers, with the advantage of great gas cost reductions.
|
||||
* The whitepaper contains reference to the approximation and a table showing the margin of error per different time periods.
|
||||
|
@ -48,30 +48,25 @@ library MathUtils {
|
|||
view
|
||||
returns (uint256)
|
||||
{
|
||||
|
||||
//solium-disable-next-line
|
||||
uint256 exp = block.timestamp.sub(uint256(_lastUpdateTimestamp));
|
||||
|
||||
if(exp == 0){
|
||||
if (exp == 0) {
|
||||
return WadRayMath.ray();
|
||||
}
|
||||
|
||||
uint256 expMinusOne = exp.sub(1);
|
||||
uint256 expMinusOne = exp.sub(1);
|
||||
|
||||
uint256 expMinusTwo = exp > 2 ? exp.sub(2) : 0;
|
||||
uint256 expMinusTwo = exp > 2 ? exp.sub(2) : 0;
|
||||
|
||||
uint256 ratePerSecond = _rate.div(31536000);
|
||||
|
||||
uint basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
|
||||
uint basePowerThree = basePowerTwo.rayMul(ratePerSecond);
|
||||
|
||||
uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
|
||||
uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond);
|
||||
|
||||
|
||||
uint256 secondTerm = exp.mul(expMinusOne).mul(basePowerTwo).div(2);
|
||||
uint256 thirdTerm = exp.mul(expMinusOne).mul(expMinusTwo).mul(basePowerThree).div(6);
|
||||
|
||||
|
||||
return WadRayMath.ray().add(ratePerSecond.mul(exp)).add(secondTerm).add(thirdTerm);
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: agpl-3.0
|
||||
pragma solidity ^0.6.8;
|
||||
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
|
||||
/**
|
||||
* @title WadRayMath library
|
||||
|
@ -112,5 +112,4 @@ library WadRayMath {
|
|||
function wadToRay(uint256 a) internal pure returns (uint256) {
|
||||
return a.mul(WAD_RAY_RATIO);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,14 +3,12 @@ pragma solidity ^0.6.8;
|
|||
|
||||
import {ERC20} from './ERC20.sol';
|
||||
import {LendingPool} from '../lendingpool/LendingPool.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/SafeERC20.sol';
|
||||
import {
|
||||
VersionedInitializable
|
||||
} from '../libraries/openzeppelin-upgradeability/VersionedInitializable.sol';
|
||||
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
|
||||
/**
|
||||
* @title Aave ERC20 AToken
|
||||
*
|
||||
|
|
|
@ -5,8 +5,8 @@ import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
|||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {MathUtils} from '../libraries/MathUtils.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import {MathUtils} from '../libraries/math/MathUtils.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {IStableDebtToken} from './interfaces/IStableDebtToken.sol';
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
pragma solidity ^0.6.0;
|
||||
|
||||
import '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {Context} from '@openzeppelin/contracts/GSN/Context.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {SafeMath} from '@openzeppelin/contracts/math/SafeMath.sol';
|
||||
import {Address} from '@openzeppelin/contracts/utils/Address.sol';
|
||||
import {DebtTokenBase} from './base/DebtTokenBase.sol';
|
||||
import {WadRayMath} from '../libraries/WadRayMath.sol';
|
||||
import '@nomiclabs/buidler/console.sol';
|
||||
import {WadRayMath} from '../libraries/math/WadRayMath.sol';
|
||||
import {IVariableDebtToken} from './interfaces/IVariableDebtToken.sol';
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user