Merge branch 'fix/22' into 'master'

Resolve "FIx the libraries folder to follow our internal guidelines"

Closes #22

See merge request aave-tech/protocol-v2!27
This commit is contained in:
Andrey Ko 2020-08-21 20:34:28 +00:00
commit 45cb9ab680
17 changed files with 426 additions and 3084 deletions

View File

@ -43,7 +43,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
* @param pool the new lending pool implementation * @param pool the new lending pool implementation
**/ **/
function setLendingPoolImpl(address pool) external override onlyOwner { function setLendingPoolImpl(address pool) external override onlyOwner {
_updateImplementation(LENDING_POOL, pool); _updateImpl(LENDING_POOL, pool);
emit LendingPoolUpdated(pool); emit LendingPoolUpdated(pool);
} }
@ -60,7 +60,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
* @param configurator the new lending pool configurator implementation * @param configurator the new lending pool configurator implementation
**/ **/
function setLendingPoolConfiguratorImpl(address configurator) external override onlyOwner { function setLendingPoolConfiguratorImpl(address configurator) external override onlyOwner {
_updateImplementation(LENDING_POOL_CONFIGURATOR, configurator); _updateImpl(LENDING_POOL_CONFIGURATOR, configurator);
emit LendingPoolConfiguratorUpdated(configurator); emit LendingPoolConfiguratorUpdated(configurator);
} }
@ -121,7 +121,7 @@ contract LendingPoolAddressesProvider is Ownable, ILendingPoolAddressesProvider
* @param id the id of the contract to be updated * @param id the id of the contract to be updated
* @param newAddress the address of the new implementation * @param newAddress the address of the new implementation
**/ **/
function _updateImplementation(bytes32 id, address newAddress) internal { function _updateImpl(bytes32 id, address newAddress) internal {
address payable proxyAddress = payable(_addresses[id]); address payable proxyAddress = payable(_addresses[id]);
InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy( InitializableAdminUpgradeabilityProxy proxy = InitializableAdminUpgradeabilityProxy(

View File

@ -20,7 +20,7 @@ abstract contract FlashLoanReceiverBase is IFlashLoanReceiver {
receive() external payable {} receive() external payable {}
function transferFundsBackInternal( function _transferFundsBack(
address reserve, address reserve,
address destination, address destination,
uint256 amount uint256 amount

View File

@ -149,7 +149,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
); );
} }
currentLiquidityRate = getOverallBorrowRateInternal( currentLiquidityRate = _getOverallBorrowRate(
totalBorrowsStable, totalBorrowsStable,
totalBorrowsVariable, totalBorrowsVariable,
currentVariableBorrowRate, currentVariableBorrowRate,
@ -170,7 +170,7 @@ contract DefaultReserveInterestRateStrategy is IReserveInterestRateStrategy {
* @param currentAverageStableBorrowRate the weighted average of all the stable rate borrows * @param currentAverageStableBorrowRate the weighted average of all the stable rate borrows
* @return the weighted averaged borrow rate * @return the weighted averaged borrow rate
**/ **/
function getOverallBorrowRateInternal( function _getOverallBorrowRate(
uint256 totalBorrowsStable, uint256 totalBorrowsStable,
uint256 totalBorrowsVariable, uint256 totalBorrowsVariable,
uint256 currentVariableBorrowRate, uint256 currentVariableBorrowRate,

View File

@ -242,7 +242,7 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
(uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve); (uint256 stableDebt, uint256 variableDebt) = Helpers.getUserCurrentDebt(_onBehalfOf, reserve);
ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode); ReserveLogic.InterestRateMode rateMode = ReserveLogic.InterestRateMode(_rateMode);
//default to max amount //default to max amount
uint256 paybackAmount = rateMode == ReserveLogic.InterestRateMode.STABLE uint256 paybackAmount = rateMode == ReserveLogic.InterestRateMode.STABLE
? stableDebt ? stableDebt
@ -254,13 +254,11 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
ValidationLogic.validateRepay( ValidationLogic.validateRepay(
reserve, reserve,
asset,
amount, amount,
rateMode, rateMode,
_onBehalfOf, _onBehalfOf,
stableDebt, stableDebt,
variableDebt, variableDebt
paybackAmount
); );
reserve.updateCumulativeIndexesAndTimestamp(); reserve.updateCumulativeIndexesAndTimestamp();
@ -492,7 +490,18 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
'The actual balance of the protocol is inconsistent' 'The actual balance of the protocol is inconsistent'
); );
reserve.updateStateOnFlashLoan(asset, availableLiquidityBefore, amountFee); //compounding the cumulated interest
reserve.updateCumulativeIndexesAndTimestamp();
uint256 totalLiquidityBefore = availableLiquidityBefore
.add(IERC20(reserve.variableDebtTokenAddress).totalSupply())
.add(IERC20(reserve.stableDebtTokenAddress).totalSupply());
//compounding the received fee into the reserve
reserve.cumulateToLiquidityIndex(totalLiquidityBefore, amountFee);
//refresh interest rates
reserve.updateInterestRates(asset, amountFee, 0);
//solium-disable-next-line //solium-disable-next-line
emit FlashLoan(receiverAddress, asset, amount, amountFee); emit FlashLoan(receiverAddress, asset, amount, amountFee);
@ -580,8 +589,8 @@ contract LendingPool is ReentrancyGuard, VersionedInitializable, ILendingPool {
reserve.currentVariableBorrowRate, reserve.currentVariableBorrowRate,
reserve.currentStableBorrowRate, reserve.currentStableBorrowRate,
IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(), IStableDebtToken(reserve.stableDebtTokenAddress).getAverageStableRate(),
reserve.lastLiquidityCumulativeIndex, reserve.lastLiquidityIndex,
reserve.lastVariableBorrowCumulativeIndex, reserve.lastVariableBorrowIndex,
reserve.lastUpdateTimestamp reserve.lastUpdateTimestamp
); );
} }

View File

@ -36,174 +36,171 @@ library ReserveConfiguration {
/** /**
* @dev sets the Loan to Value of the reserve * @dev sets the Loan to Value of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _ltv the new ltv * @param ltv the new ltv
**/ **/
function setLtv(ReserveConfiguration.Map memory _self, uint256 _ltv) internal { function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
_self.data = (_self.data & LTV_MASK) | _ltv; self.data = (self.data & LTV_MASK) | ltv;
} }
/** /**
* @dev gets the Loan to Value of the reserve * @dev gets the Loan to Value of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the loan to value * @return the loan to value
**/ **/
function getLtv(ReserveConfiguration.Map storage _self) internal view returns (uint256) { function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) {
return _self.data & ~LTV_MASK; return self.data & ~LTV_MASK;
} }
/** /**
* @dev sets the liquidation threshold of the reserve * @dev sets the liquidation threshold of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _threshold the new liquidation threshold * @param threshold the new liquidation threshold
**/ **/
function setLiquidationThreshold(ReserveConfiguration.Map memory _self, uint256 _threshold) function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold)
internal internal
pure
{ {
_self.data = (_self.data & LIQUIDATION_THRESHOLD_MASK) | (_threshold << 16); self.data = (self.data & LIQUIDATION_THRESHOLD_MASK) | (threshold << 16);
} }
/** /**
* @dev gets the Loan to Value of the reserve * @dev gets the Loan to Value of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the liquidation threshold * @return the liquidation threshold
**/ **/
function getLiquidationThreshold(ReserveConfiguration.Map storage _self) function getLiquidationThreshold(ReserveConfiguration.Map storage self)
internal internal
view view
returns (uint256) returns (uint256)
{ {
return (_self.data & ~LIQUIDATION_THRESHOLD_MASK) >> 16; return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> 16;
} }
/** /**
* @dev sets the liquidation bonus of the reserve * @dev sets the liquidation bonus of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _bonus the new liquidation bonus * @param bonus the new liquidation bonus
**/ **/
function setLiquidationBonus(ReserveConfiguration.Map memory _self, uint256 _bonus) internal { function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
_self.data = (_self.data & LIQUIDATION_BONUS_MASK) | (_bonus << 32); self.data = (self.data & LIQUIDATION_BONUS_MASK) | (bonus << 32);
} }
/** /**
* @dev gets the liquidation bonus of the reserve * @dev gets the liquidation bonus of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the liquidation bonus * @return the liquidation bonus
**/ **/
function getLiquidationBonus(ReserveConfiguration.Map storage _self) function getLiquidationBonus(ReserveConfiguration.Map storage self)
internal internal
view view
returns (uint256) returns (uint256)
{ {
return (_self.data & ~LIQUIDATION_BONUS_MASK) >> 32; return (self.data & ~LIQUIDATION_BONUS_MASK) >> 32;
} }
/** /**
* @dev sets the decimals of the underlying asset of the reserve * @dev sets the decimals of the underlying asset of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _decimals the decimals * @param decimals the decimals
**/ **/
function setDecimals(ReserveConfiguration.Map memory _self, uint256 _decimals) internal { function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
_self.data = (_self.data & DECIMALS_MASK) | (_decimals << 48); self.data = (self.data & DECIMALS_MASK) | (decimals << 48);
} }
/** /**
* @dev gets the decimals of the underlying asset of the reserve * @dev gets the decimals of the underlying asset of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the decimals of the asset * @return the decimals of the asset
**/ **/
function getDecimals(ReserveConfiguration.Map storage _self) internal view returns (uint256) { function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) {
return (_self.data & ~DECIMALS_MASK) >> 48; return (self.data & ~DECIMALS_MASK) >> 48;
} }
/** /**
* @dev sets the active state of the reserve * @dev sets the active state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _active the active state * @param active the active state
**/ **/
function setActive(ReserveConfiguration.Map memory _self, bool _active) internal { function setActive(ReserveConfiguration.Map memory self, bool active) internal {
_self.data = (_self.data & ACTIVE_MASK) | (uint256(_active ? 1 : 0) << 56); self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << 56);
} }
/** /**
* @dev gets the active state of the reserve * @dev gets the active state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the active state * @return the active state
**/ **/
function getActive(ReserveConfiguration.Map storage _self) internal view returns (bool) { function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
return ((_self.data & ~ACTIVE_MASK) >> 56) != 0; return ((self.data & ~ACTIVE_MASK) >> 56) != 0;
} }
/** /**
* @dev sets the frozen state of the reserve * @dev sets the frozen state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _frozen the frozen state * @param frozen the frozen state
**/ **/
function setFrozen(ReserveConfiguration.Map memory _self, bool _frozen) internal { function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure {
_self.data = (_self.data & FROZEN_MASK) | (uint256(_frozen ? 1 : 0) << 57); self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << 57);
} }
/** /**
* @dev gets the frozen state of the reserve * @dev gets the frozen state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the frozen state * @return the frozen state
**/ **/
function getFrozen(ReserveConfiguration.Map storage _self) internal view returns (bool) { function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
return ((_self.data & ~FROZEN_MASK) >> 57) != 0; return ((self.data & ~FROZEN_MASK) >> 57) != 0;
} }
/** /**
* @dev enables or disables borrowing on the reserve * @dev enables or disables borrowing on the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _enabled true if the borrowing needs to be enabled, false otherwise * @param enabled true if the borrowing needs to be enabled, false otherwise
**/ **/
function setBorrowingEnabled(ReserveConfiguration.Map memory _self, bool _enabled) internal { function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure {
_self.data = (_self.data & BORROWING_MASK) | (uint256(_enabled ? 1 : 0) << 58); self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 58);
} }
/** /**
* @dev gets the borrowing state of the reserve * @dev gets the borrowing state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the borrowing state * @return the borrowing state
**/ **/
function getBorrowingEnabled(ReserveConfiguration.Map storage _self) function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
internal return ((self.data & ~BORROWING_MASK) >> 58) != 0;
view
returns (bool)
{
return ((_self.data & ~BORROWING_MASK) >> 58) != 0;
} }
/** /**
* @dev enables or disables stable rate borrowing on the reserve * @dev enables or disables stable rate borrowing on the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @param _enabled true if the stable rate borrowing needs to be enabled, false otherwise * @param enabled true if the stable rate borrowing needs to be enabled, false otherwise
**/ **/
function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory _self, bool _enabled) function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled)
internal internal pure
{ {
_self.data = (_self.data & STABLE_BORROWING_MASK) | (uint256(_enabled ? 1 : 0) << 59); self.data = (self.data & STABLE_BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 59);
} }
/** /**
* @dev gets the stable rate borrowing state of the reserve * @dev gets the stable rate borrowing state of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the stable rate borrowing state * @return the stable rate borrowing state
**/ **/
function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage _self) function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self)
internal internal
view view
returns (bool) returns (bool)
{ {
return ((_self.data & ~STABLE_BORROWING_MASK) >> 59) != 0; return ((self.data & ~STABLE_BORROWING_MASK) >> 59) != 0;
} }
/** /**
* @dev gets the configuration flags of the reserve * @dev gets the configuration flags of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled * @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled
**/ **/
function getFlags(ReserveConfiguration.Map storage _self) function getFlags(ReserveConfiguration.Map storage self)
internal internal
view view
returns ( returns (
@ -213,7 +210,7 @@ library ReserveConfiguration {
bool bool
) )
{ {
uint256 dataLocal = _self.data; uint256 dataLocal = self.data;
return ( return (
(dataLocal & ~ACTIVE_MASK) >> 56 != 0, (dataLocal & ~ACTIVE_MASK) >> 56 != 0,
@ -225,10 +222,10 @@ library ReserveConfiguration {
/** /**
* @dev gets the configuration paramters of the reserve * @dev gets the configuration paramters of the reserve
* @param _self the reserve configuration * @param self the reserve configuration
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals * @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
**/ **/
function getParams(ReserveConfiguration.Map storage _self) function getParams(ReserveConfiguration.Map storage self)
internal internal
view view
returns ( returns (
@ -238,7 +235,7 @@ library ReserveConfiguration {
uint256 uint256
) )
{ {
uint256 dataLocal = _self.data; uint256 dataLocal = self.data;
return ( return (
dataLocal & ~LTV_MASK, dataLocal & ~LTV_MASK,

View File

@ -18,94 +18,94 @@ library UserConfiguration {
} }
/** /**
* @dev sets if the user is borrowing the reserve identified by _reserveIndex * @dev sets if the user is borrowing the reserve identified by reserveIndex
* @param _self the configuration object * @param self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap * @param reserveIndex the index of the reserve in the bitmap
* @param _borrowing true if the user is borrowing the reserve, false otherwise * @param borrowing true if the user is borrowing the reserve, false otherwise
**/ **/
function setBorrowing( function setBorrowing(
UserConfiguration.Map storage _self, UserConfiguration.Map storage self,
uint256 _reserveIndex, uint256 reserveIndex,
bool _borrowing bool borrowing
) internal { ) internal {
_self.data = self.data =
(_self.data & ~(1 << (_reserveIndex * 2))) | (self.data & ~(1 << (reserveIndex * 2))) |
(uint256(_borrowing ? 1 : 0) << (_reserveIndex * 2)); (uint256(borrowing ? 1 : 0) << (reserveIndex * 2));
} }
/** /**
* @dev sets if the user is using as collateral the reserve identified by _reserveIndex * @dev sets if the user is using as collateral the reserve identified by reserveIndex
* @param _self the configuration object * @param self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap * @param reserveIndex the index of the reserve in the bitmap
* @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise * @param _usingAsCollateral true if the user is usin the reserve as collateral, false otherwise
**/ **/
function setUsingAsCollateral( function setUsingAsCollateral(
UserConfiguration.Map storage _self, UserConfiguration.Map storage self,
uint256 _reserveIndex, uint256 reserveIndex,
bool _usingAsCollateral bool _usingAsCollateral
) internal { ) internal {
_self.data = self.data =
(_self.data & ~(1 << (_reserveIndex * 2 + 1))) | (self.data & ~(1 << (reserveIndex * 2 + 1))) |
(uint256(_usingAsCollateral ? 1 : 0) << (_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 * @dev used to validate if a user has been using the reserve for borrowing or as collateral
* @param _self the configuration object * @param self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap * @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 * @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(UserConfiguration.Map memory self, uint256 reserveIndex)
internal internal
view pure
returns (bool) returns (bool)
{ {
return (_self.data >> (_reserveIndex * 2)) & 3 != 0; return (self.data >> (reserveIndex * 2)) & 3 != 0;
} }
/** /**
* @dev used to validate if a user has been using the reserve for borrowing * @dev used to validate if a user has been using the reserve for borrowing
* @param _self the configuration object * @param self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap * @param reserveIndex the index of the reserve in the bitmap
* @return true if the user has been using a reserve for borrowing, false otherwise * @return true if the user has been using a reserve for borrowing, false otherwise
**/ **/
function isBorrowing(UserConfiguration.Map memory _self, uint256 _reserveIndex) function isBorrowing(UserConfiguration.Map memory self, uint256 reserveIndex)
internal internal
view pure
returns (bool) returns (bool)
{ {
return (_self.data >> (_reserveIndex * 2)) & 1 != 0; return (self.data >> (reserveIndex * 2)) & 1 != 0;
} }
/** /**
* @dev used to validate if a user has been using the reserve as collateral * @dev used to validate if a user has been using the reserve as collateral
* @param _self the configuration object * @param self the configuration object
* @param _reserveIndex the index of the reserve in the bitmap * @param reserveIndex the index of the reserve in the bitmap
* @return true if the user has been using a reserve as collateral, false otherwise * @return true if the user has been using a reserve as collateral, false otherwise
**/ **/
function isUsingAsCollateral(UserConfiguration.Map memory _self, uint256 _reserveIndex) function isUsingAsCollateral(UserConfiguration.Map memory self, uint256 reserveIndex)
internal internal
view pure
returns (bool) returns (bool)
{ {
return (_self.data >> (_reserveIndex * 2 + 1)) & 1 != 0; return (self.data >> (reserveIndex * 2 + 1)) & 1 != 0;
} }
/** /**
* @dev used to validate if a user has been borrowing from any reserve * @dev used to validate if a user has been borrowing from any reserve
* @param _self the configuration object * @param self the configuration object
* @return true if the user has been borrowing any reserve, false otherwise * @return true if the user has been borrowing any reserve, false otherwise
**/ **/
function isBorrowingAny(UserConfiguration.Map memory _self) internal view returns (bool) { function isBorrowingAny(UserConfiguration.Map memory self) internal pure returns (bool) {
return _self.data & BORROWING_MASK != 0; return self.data & BORROWING_MASK != 0;
} }
/** /**
* @dev used to validate if a user has not been using any reserve * @dev used to validate if a user has not been using any reserve
* @param _self the configuration object * @param self the configuration object
* @return true if the user has been borrowing any reserve, false otherwise * @return true if the user has been borrowing any reserve, false otherwise
**/ **/
function isEmpty(UserConfiguration.Map memory _self) internal view returns (bool) { function isEmpty(UserConfiguration.Map memory self) internal pure returns (bool) {
return _self.data == 0; return self.data == 0;
} }
} }

View File

@ -12,35 +12,35 @@ import {ReserveLogic} from '../logic/ReserveLogic.sol';
library Helpers { library Helpers {
/** /**
* @dev fetches the user current stable and variable debt balances * @dev fetches the user current stable and variable debt balances
* @param _user the user * @param user the user
* @param _reserve the reserve object * @param reserve the reserve object
* @return the stable and variable debt balance * @return the stable and variable debt balance
**/ **/
function getUserCurrentDebt(address _user, ReserveLogic.ReserveData storage _reserve) function getUserCurrentDebt(address user, ReserveLogic.ReserveData storage reserve)
internal internal
view view
returns (uint256, uint256) returns (uint256, uint256)
{ {
return ( return (
DebtTokenBase(_reserve.stableDebtTokenAddress).balanceOf(_user), DebtTokenBase(reserve.stableDebtTokenAddress).balanceOf(user),
DebtTokenBase(_reserve.variableDebtTokenAddress).balanceOf(_user) DebtTokenBase(reserve.variableDebtTokenAddress).balanceOf(user)
); );
} }
/** /**
* @dev fetches the user principal stable and variable debt balances * @dev fetches the user principal stable and variable debt balances
* @param _user the user * @param user the user
* @param _reserve the reserve object * @param reserve the reserve object
* @return the stable and variable debt balance * @return the stable and variable debt balance
**/ **/
function getUserPrincipalDebt(address _user, ReserveLogic.ReserveData storage _reserve) function getUserPrincipalDebt(address user, ReserveLogic.ReserveData storage reserve)
internal internal
view view
returns (uint256, uint256) returns (uint256, uint256)
{ {
return ( return (
DebtTokenBase(_reserve.stableDebtTokenAddress).principalBalanceOf(_user), DebtTokenBase(reserve.stableDebtTokenAddress).principalBalanceOf(user),
DebtTokenBase(_reserve.variableDebtTokenAddress).principalBalanceOf(_user) DebtTokenBase(reserve.variableDebtTokenAddress).principalBalanceOf(user)
); );
} }
} }

View File

@ -43,23 +43,27 @@ library GenericLogic {
/** /**
* @dev check if a specific balance decrease is allowed * @dev check if a specific balance decrease is allowed
* (i.e. doesn't bring the user borrow position health factor under HEALTH_FACTOR_LIQUIDATION_THRESHOLD) * (i.e. doesn't bring the user borrow position health factor under HEALTH_FACTOR_LIQUIDATION_THRESHOLD)
* @param _reserve the address of the reserve * @param asset the address of the reserve
* @param _user the address of the user * @param user the address of the user
* @param _amount the amount to decrease * @param amount the amount to decrease
* @param reservesData the data of all the reserves
* @param userConfig the user configuration
* @param reserves the list of all the active reserves
* @param oracle the address of the oracle contract
* @return true if the decrease of the balance is allowed * @return true if the decrease of the balance is allowed
**/ **/
function balanceDecreaseAllowed( function balanceDecreaseAllowed(
address _reserve, address asset,
address _user, address user,
uint256 _amount, uint256 amount,
mapping(address => ReserveLogic.ReserveData) storage _reservesData, mapping(address => ReserveLogic.ReserveData) storage reservesData,
UserConfiguration.Map calldata _userConfig, UserConfiguration.Map calldata userConfig,
address[] calldata _reserves, address[] calldata reserves,
address _oracle address oracle
) external view returns (bool) { ) external view returns (bool) {
if ( if (
!_userConfig.isBorrowingAny() || !userConfig.isBorrowingAny() ||
!_userConfig.isUsingAsCollateral(_reservesData[_reserve].index) !userConfig.isUsingAsCollateral(reservesData[asset].index)
) { ) {
return true; return true;
} }
@ -67,7 +71,7 @@ library GenericLogic {
// Usage of a memory struct of vars to avoid "Stack too deep" errors due to local variables // Usage of a memory struct of vars to avoid "Stack too deep" errors due to local variables
balanceDecreaseAllowedLocalVars memory vars; balanceDecreaseAllowedLocalVars memory vars;
(vars.ltv, , , vars.decimals) = _reservesData[_reserve].configuration.getParams(); (vars.ltv, , , vars.decimals) = reservesData[asset].configuration.getParams();
if (vars.ltv == 0) { if (vars.ltv == 0) {
return true; //if reserve is not used as collateral, no reasons to block the transfer return true; //if reserve is not used as collateral, no reasons to block the transfer
@ -79,13 +83,13 @@ library GenericLogic {
, ,
vars.currentLiquidationThreshold, vars.currentLiquidationThreshold,
) = calculateUserAccountData(_user, _reservesData, _userConfig, _reserves, _oracle); ) = calculateUserAccountData(user, reservesData, userConfig, reserves, oracle);
if (vars.borrowBalanceETH == 0) { if (vars.borrowBalanceETH == 0) {
return true; //no borrows - no reasons to block the transfer return true; //no borrows - no reasons to block the transfer
} }
vars.amountToDecreaseETH = IPriceOracleGetter(_oracle).getAssetPrice(_reserve).mul(_amount).div( vars.amountToDecreaseETH = IPriceOracleGetter(oracle).getAssetPrice(asset).mul(amount).div(
10**vars.decimals 10**vars.decimals
); );
@ -137,20 +141,20 @@ library GenericLogic {
* @dev calculates the user data across the reserves. * @dev calculates the user data across the reserves.
* this includes the total liquidity/collateral/borrow balances in ETH, * this includes the total liquidity/collateral/borrow balances in ETH,
* the average Loan To Value, the average Liquidation Ratio, and the Health factor. * the average Loan To Value, the average Liquidation Ratio, and the Health factor.
* @param _user the address of the user * @param user the address of the user
* @param _reservesData data of all the reserves * @param reservesData data of all the reserves
* @param _userConfig the configuration of the user * @param userConfig the configuration of the user
* @param _reserves the list of the available reserves * @param reserves the list of the available reserves
* @param _oracle the price oracle address * @param oracle the price oracle address
* @return the total collateral and total borrow balance of the user in ETH, the avg ltv and liquidation threshold and the HF * @return the total collateral and total borrow balance of the user in ETH, the avg ltv and liquidation threshold and the HF
* also the average Ltv, liquidation threshold, and the health factor * also the average Ltv, liquidation threshold, and the health factor
**/ **/
function calculateUserAccountData( function calculateUserAccountData(
address _user, address user,
mapping(address => ReserveLogic.ReserveData) storage _reservesData, mapping(address => ReserveLogic.ReserveData) storage reservesData,
UserConfiguration.Map memory _userConfig, UserConfiguration.Map memory userConfig,
address[] memory _reserves, address[] memory reserves,
address _oracle address oracle
) )
internal internal
view view
@ -164,26 +168,26 @@ library GenericLogic {
{ {
CalculateUserAccountDataVars memory vars; CalculateUserAccountDataVars memory vars;
if (_userConfig.isEmpty()) { if (userConfig.isEmpty()) {
return (0, 0, 0, 0, uint256(-1)); return (0, 0, 0, 0, uint256(-1));
} }
for (vars.i = 0; vars.i < _reserves.length; vars.i++) { for (vars.i = 0; vars.i < reserves.length; vars.i++) {
if (!_userConfig.isUsingAsCollateralOrBorrowing(vars.i)) { if (!userConfig.isUsingAsCollateralOrBorrowing(vars.i)) {
continue; continue;
} }
vars.currentReserveAddress = _reserves[vars.i]; vars.currentReserveAddress = reserves[vars.i];
ReserveLogic.ReserveData storage currentReserve = _reservesData[vars.currentReserveAddress]; ReserveLogic.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
(vars.ltv, vars.liquidationThreshold, , vars.decimals) = currentReserve (vars.ltv, vars.liquidationThreshold, , vars.decimals) = currentReserve
.configuration .configuration
.getParams(); .getParams();
vars.tokenUnit = 10**vars.decimals; vars.tokenUnit = 10**vars.decimals;
vars.reserveUnitPrice = IPriceOracleGetter(_oracle).getAssetPrice(vars.currentReserveAddress); vars.reserveUnitPrice = IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress);
if (vars.ltv != 0 && _userConfig.isUsingAsCollateral(vars.i)) { if (vars.ltv != 0 && userConfig.isUsingAsCollateral(vars.i)) {
vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(_user); vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(user);
uint256 liquidityBalanceETH = vars uint256 liquidityBalanceETH = vars
.reserveUnitPrice .reserveUnitPrice
@ -198,12 +202,12 @@ library GenericLogic {
); );
} }
if (_userConfig.isBorrowing(vars.i)) { if (userConfig.isBorrowing(vars.i)) {
vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf( vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf(
_user user
); );
vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add( vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(
IERC20(currentReserve.variableDebtTokenAddress).balanceOf(_user) IERC20(currentReserve.variableDebtTokenAddress).balanceOf(user)
); );
vars.totalBorrowBalanceETH = vars.totalBorrowBalanceETH.add( vars.totalBorrowBalanceETH = vars.totalBorrowBalanceETH.add(
@ -244,7 +248,7 @@ library GenericLogic {
uint256 collateralBalanceETH, uint256 collateralBalanceETH,
uint256 borrowBalanceETH, uint256 borrowBalanceETH,
uint256 liquidationThreshold uint256 liquidationThreshold
) internal view returns (uint256) { ) internal pure returns (uint256) {
if (borrowBalanceETH == 0) return uint256(-1); if (borrowBalanceETH == 0) return uint256(-1);
return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH); return (collateralBalanceETH.percentMul(liquidationThreshold)).wadDiv(borrowBalanceETH);
@ -263,7 +267,7 @@ library GenericLogic {
uint256 collateralBalanceETH, uint256 collateralBalanceETH,
uint256 borrowBalanceETH, uint256 borrowBalanceETH,
uint256 ltv uint256 ltv
) external view returns (uint256) { ) internal pure returns (uint256) {
uint256 availableBorrowsETH = collateralBalanceETH.percentMul(ltv); //ltv is in percentage uint256 availableBorrowsETH = collateralBalanceETH.percentMul(ltv); //ltv is in percentage
if (availableBorrowsETH < borrowBalanceETH) { if (availableBorrowsETH < borrowBalanceETH) {

View File

@ -23,7 +23,6 @@ library ReserveLogic {
/** /**
* @dev Emitted when the state of a reserve is updated * @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 reserve the address of the reserve
* @param liquidityRate the new liquidity rate * @param liquidityRate the new liquidity rate
* @param stableBorrowRate the new stable borrow rate * @param stableBorrowRate the new stable borrow rate
@ -50,7 +49,7 @@ library ReserveLogic {
// refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties. // refer to the whitepaper, section 1.1 basic concepts for a formal description of these properties.
struct ReserveData { struct ReserveData {
//the liquidity index. Expressed in ray //the liquidity index. Expressed in ray
uint256 lastLiquidityCumulativeIndex; uint256 lastLiquidityIndex;
//the current supply rate. Expressed in ray //the current supply rate. Expressed in ray
uint256 currentLiquidityRate; uint256 currentLiquidityRate;
//the current variable borrow rate. Expressed in ray //the current variable borrow rate. Expressed in ray
@ -58,7 +57,7 @@ library ReserveLogic {
//the current stable borrow rate. Expressed in ray //the current stable borrow rate. Expressed in ray
uint256 currentStableBorrowRate; uint256 currentStableBorrowRate;
//variable borrow index. Expressed in ray //variable borrow index. Expressed in ray
uint256 lastVariableBorrowCumulativeIndex; uint256 lastVariableBorrowIndex;
//stores the reserve configuration //stores the reserve configuration
ReserveConfiguration.Map configuration; ReserveConfiguration.Map configuration;
address aTokenAddress; address aTokenAddress;
@ -74,21 +73,21 @@ library ReserveLogic {
* @dev returns the ongoing normalized income for the reserve. * @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 1e27 means there is no income. As time passes, the income is accrued.
* A value of 2*1e27 means for each unit of assset two units of income have been accrued. * A value of 2*1e27 means for each unit of assset two units of income have been accrued.
* @param _reserve the reserve object * @param reserve the reserve object
* @return the normalized income. expressed in ray * @return the normalized income. expressed in ray
**/ **/
function getNormalizedIncome(ReserveData storage _reserve) internal view returns (uint256) { function getNormalizedIncome(ReserveData storage reserve) internal view returns (uint256) {
uint40 timestamp = _reserve.lastUpdateTimestamp; uint40 timestamp = reserve.lastUpdateTimestamp;
//solium-disable-next-line //solium-disable-next-line
if (timestamp == uint40(block.timestamp)) { if (timestamp == uint40(block.timestamp)) {
//if the index was updated in the same block, no need to perform any calculation //if the index was updated in the same block, no need to perform any calculation
return _reserve.lastLiquidityCumulativeIndex; return reserve.lastLiquidityIndex;
} }
uint256 cumulated = MathUtils uint256 cumulated = MathUtils
.calculateLinearInterest(_reserve.currentLiquidityRate, timestamp) .calculateLinearInterest(reserve.currentLiquidityRate, timestamp)
.rayMul(_reserve.lastLiquidityCumulativeIndex); .rayMul(reserve.lastLiquidityIndex);
return cumulated; return cumulated;
} }
@ -97,21 +96,21 @@ library ReserveLogic {
* @dev returns the ongoing normalized variable debt for the reserve. * @dev returns the ongoing normalized variable debt for the reserve.
* a value of 1e27 means there is no debt. As time passes, the income is accrued. * a value of 1e27 means there is no debt. As time passes, the income is accrued.
* A value of 2*1e27 means that the debt of the reserve is double the initial amount. * A value of 2*1e27 means that the debt of the reserve is double the initial amount.
* @param _reserve the reserve object * @param reserve the reserve object
* @return the normalized variable debt. expressed in ray * @return the normalized variable debt. expressed in ray
**/ **/
function getNormalizedDebt(ReserveData storage _reserve) internal view returns (uint256) { function getNormalizedDebt(ReserveData storage reserve) internal view returns (uint256) {
uint40 timestamp = _reserve.lastUpdateTimestamp; uint40 timestamp = reserve.lastUpdateTimestamp;
//solium-disable-next-line //solium-disable-next-line
if (timestamp == uint40(block.timestamp)) { if (timestamp == uint40(block.timestamp)) {
//if the index was updated in the same block, no need to perform any calculation //if the index was updated in the same block, no need to perform any calculation
return _reserve.lastVariableBorrowCumulativeIndex; return reserve.lastVariableBorrowIndex;
} }
uint256 cumulated = MathUtils uint256 cumulated = MathUtils
.calculateCompoundedInterest(_reserve.currentVariableBorrowRate, timestamp) .calculateCompoundedInterest(reserve.currentVariableBorrowRate, timestamp)
.rayMul(_reserve.lastVariableBorrowCumulativeIndex); .rayMul(reserve.lastVariableBorrowIndex);
return cumulated; return cumulated;
} }
@ -119,153 +118,128 @@ library ReserveLogic {
/** /**
* @dev Updates the liquidity cumulative index Ci and variable borrow cumulative index Bvc. Refer to the whitepaper for * @dev Updates the liquidity cumulative index Ci and variable borrow cumulative index Bvc. Refer to the whitepaper for
* a formal specification. * a formal specification.
* @param _self the reserve object * @param reserve the reserve object
**/ **/
function updateCumulativeIndexesAndTimestamp(ReserveData storage _self) internal { function updateCumulativeIndexesAndTimestamp(ReserveData storage reserve) internal {
//only cumulating if there is any income being produced //only cumulating if there is any income being produced
if ( if (
IERC20(_self.variableDebtTokenAddress).totalSupply() > 0 || IERC20(reserve.variableDebtTokenAddress).totalSupply() > 0 ||
IERC20(_self.stableDebtTokenAddress).totalSupply() > 0 IERC20(reserve.stableDebtTokenAddress).totalSupply() > 0
) { ) {
uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest( uint256 cumulatedLiquidityInterest = MathUtils.calculateLinearInterest(
_self.currentLiquidityRate, reserve.currentLiquidityRate,
_self.lastUpdateTimestamp reserve.lastUpdateTimestamp
); );
_self.lastLiquidityCumulativeIndex = cumulatedLiquidityInterest.rayMul( reserve.lastLiquidityIndex = cumulatedLiquidityInterest.rayMul(
_self.lastLiquidityCumulativeIndex reserve.lastLiquidityIndex
); );
uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest( uint256 cumulatedVariableBorrowInterest = MathUtils.calculateCompoundedInterest(
_self.currentVariableBorrowRate, reserve.currentVariableBorrowRate,
_self.lastUpdateTimestamp reserve.lastUpdateTimestamp
); );
_self.lastVariableBorrowCumulativeIndex = cumulatedVariableBorrowInterest.rayMul( reserve.lastVariableBorrowIndex = cumulatedVariableBorrowInterest.rayMul(
_self.lastVariableBorrowCumulativeIndex reserve.lastVariableBorrowIndex
); );
} }
//solium-disable-next-line //solium-disable-next-line
_self.lastUpdateTimestamp = uint40(block.timestamp); reserve.lastUpdateTimestamp = uint40(block.timestamp);
} }
/** /**
* @dev accumulates a predefined amount of asset to the reserve as a fixed, one time income. Used for example to accumulate * @dev accumulates a predefined amount of asset to the reserve as a fixed, one time income. Used for example to accumulate
* the flashloan fee to the reserve, and spread it through the depositors. * the flashloan fee to the reserve, and spread it through the depositors.
* @param _self the reserve object * @param reserve the reserve object
* @param _totalLiquidity the total liquidity available in the reserve * @param totalLiquidity the total liquidity available in the reserve
* @param _amount the amount to accomulate * @param amount the amount to accomulate
**/ **/
function cumulateToLiquidityIndex( function cumulateToLiquidityIndex(
ReserveData storage _self, ReserveData storage reserve,
uint256 _totalLiquidity, uint256 totalLiquidity,
uint256 _amount uint256 amount
) internal { ) internal {
uint256 amountToLiquidityRatio = _amount.wadToRay().rayDiv(_totalLiquidity.wadToRay()); uint256 amountToLiquidityRatio = amount.wadToRay().rayDiv(totalLiquidity.wadToRay());
uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray()); uint256 cumulatedLiquidity = amountToLiquidityRatio.add(WadRayMath.ray());
_self.lastLiquidityCumulativeIndex = cumulatedLiquidity.rayMul( reserve.lastLiquidityIndex = cumulatedLiquidity.rayMul(
_self.lastLiquidityCumulativeIndex reserve.lastLiquidityIndex
); );
} }
/** /**
* @dev initializes a reserve * @dev initializes a reserve
* @param _self the reserve object * @param reserve the reserve object
* @param _aTokenAddress the address of the overlying atoken contract * @param aTokenAddress the address of the overlying atoken contract
* @param _interestRateStrategyAddress the address of the interest rate strategy contract * @param interestRateStrategyAddress the address of the interest rate strategy contract
**/ **/
function init( function init(
ReserveData storage _self, ReserveData storage reserve,
address _aTokenAddress, address aTokenAddress,
address _stableDebtAddress, address stableDebtTokenAddress,
address _variableDebtAddress, address variableDebtTokenAddress,
address _interestRateStrategyAddress address interestRateStrategyAddress
) external { ) external {
require(_self.aTokenAddress == address(0), 'Reserve has already been initialized'); require(reserve.aTokenAddress == address(0), 'Reserve has already been initialized');
if (_self.lastLiquidityCumulativeIndex == 0) { if (reserve.lastLiquidityIndex == 0) {
//if the reserve has not been initialized yet //if the reserve has not been initialized yet
_self.lastLiquidityCumulativeIndex = WadRayMath.ray(); reserve.lastLiquidityIndex = WadRayMath.ray();
} }
if (_self.lastVariableBorrowCumulativeIndex == 0) { if (reserve.lastVariableBorrowIndex == 0) {
_self.lastVariableBorrowCumulativeIndex = WadRayMath.ray(); reserve.lastVariableBorrowIndex = WadRayMath.ray();
} }
_self.aTokenAddress = _aTokenAddress; reserve.aTokenAddress = aTokenAddress;
_self.stableDebtTokenAddress = _stableDebtAddress; reserve.stableDebtTokenAddress = stableDebtTokenAddress;
_self.variableDebtTokenAddress = _variableDebtAddress; reserve.variableDebtTokenAddress = variableDebtTokenAddress;
_self.interestRateStrategyAddress = _interestRateStrategyAddress; reserve.interestRateStrategyAddress = interestRateStrategyAddress;
}
/**
* @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
* @param _income the income of the protocol as a result of the action
**/
function updateStateOnFlashLoan(
ReserveData storage _reserve,
address _reserveAddress,
uint256 _availableLiquidityBefore,
uint256 _income
) external {
//compounding the cumulated interest
_reserve.updateCumulativeIndexesAndTimestamp();
uint256 totalLiquidityBefore = _availableLiquidityBefore
.add(IERC20(_reserve.variableDebtTokenAddress).totalSupply())
.add(IERC20(_reserve.stableDebtTokenAddress).totalSupply());
//compounding the received fee into the reserve
_reserve.cumulateToLiquidityIndex(totalLiquidityBefore, _income);
//refresh interest rates
updateInterestRates(_reserve, _reserveAddress, _income, 0);
} }
/** /**
* @dev Updates the reserve current stable borrow rate Rf, the current variable borrow rate Rv and the current liquidity rate Rl. * @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. * Also updates the lastUpdateTimestamp value. Please refer to the whitepaper for further information.
* @param _reserve the address of the reserve to be updated * @param reserve the address of the reserve to be updated
* @param _liquidityAdded the amount of liquidity added to the protocol (deposit or repay) in the previous action * @param liquidityAdded the amount of liquidity added to the protocol (deposit or repay) in the previous action
* @param _liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow) * @param liquidityTaken the amount of liquidity taken from the protocol (redeem or borrow)
**/ **/
function updateInterestRates( function updateInterestRates(
ReserveData storage _reserve, ReserveData storage reserve,
address _reserveAddress, address reserveAddress,
uint256 _liquidityAdded, uint256 liquidityAdded,
uint256 _liquidityTaken uint256 liquidityTaken
) internal { ) internal {
uint256 currentAvgStableRate = IStableDebtToken(_reserve.stableDebtTokenAddress) uint256 currentAvgStableRate = IStableDebtToken(reserve.stableDebtTokenAddress)
.getAverageStableRate(); .getAverageStableRate();
uint256 balance = IERC20(_reserveAddress).balanceOf(_reserve.aTokenAddress); uint256 balance = IERC20(reserveAddress).balanceOf(reserve.aTokenAddress);
( (
uint256 newLiquidityRate, uint256 newLiquidityRate,
uint256 newStableRate, uint256 newStableRate,
uint256 newVariableRate uint256 newVariableRate
) = IReserveInterestRateStrategy(_reserve.interestRateStrategyAddress).calculateInterestRates( ) = IReserveInterestRateStrategy(reserve.interestRateStrategyAddress).calculateInterestRates(
_reserveAddress, reserveAddress,
balance.add(_liquidityAdded).sub(_liquidityTaken), balance.add(liquidityAdded).sub(liquidityTaken),
IERC20(_reserve.stableDebtTokenAddress).totalSupply(), IERC20(reserve.stableDebtTokenAddress).totalSupply(),
IERC20(_reserve.variableDebtTokenAddress).totalSupply(), IERC20(reserve.variableDebtTokenAddress).totalSupply(),
currentAvgStableRate currentAvgStableRate
); );
_reserve.currentLiquidityRate = newLiquidityRate; reserve.currentLiquidityRate = newLiquidityRate;
_reserve.currentStableBorrowRate = newStableRate; reserve.currentStableBorrowRate = newStableRate;
_reserve.currentVariableBorrowRate = newVariableRate; reserve.currentVariableBorrowRate = newVariableRate;
emit ReserveDataUpdated( emit ReserveDataUpdated(
_reserveAddress, reserveAddress,
newLiquidityRate, newLiquidityRate,
newStableRate, newStableRate,
currentAvgStableRate, currentAvgStableRate,
newVariableRate, newVariableRate,
_reserve.lastLiquidityCumulativeIndex, reserve.lastLiquidityIndex,
_reserve.lastVariableBorrowCumulativeIndex reserve.lastVariableBorrowIndex
); );
} }
} }

View File

@ -29,54 +29,54 @@ library ValidationLogic {
/** /**
* @dev validates a deposit. * @dev validates a deposit.
* @param _reserve the reserve state on which the user is depositing * @param reserve the reserve state on which the user is depositing
* @param _amount the amount to be deposited * @param amount the amount to be deposited
*/ */
function validateDeposit(ReserveLogic.ReserveData storage _reserve, uint256 _amount) function validateDeposit(ReserveLogic.ReserveData storage reserve, uint256 amount)
internal internal
view view
{ {
(bool isActive, bool isFreezed, , ) = _reserve.configuration.getFlags(); (bool isActive, bool isFreezed, , ) = reserve.configuration.getFlags();
require(_amount > 0, 'Amount must be greater than 0'); require(amount > 0, 'Amount must be greater than 0');
require(isActive, 'Action requires an active reserve'); require(isActive, 'Action requires an active reserve');
require(!isFreezed, 'Action requires an unfreezed reserve'); require(!isFreezed, 'Action requires an unfreezed reserve');
} }
/** /**
* @dev validates a withdraw action. * @dev validates a withdraw action.
* @param _reserveAddress the address of the reserve * @param reserveAddress the address of the reserve
* @param _aTokenAddress the address of the aToken for the reserve * @param aTokenAddress the address of the aToken for the reserve
* @param _amount the amount to be withdrawn * @param amount the amount to be withdrawn
* @param _userBalance the balance of the user * @param userBalance the balance of the user
*/ */
function validateWithdraw( function validateWithdraw(
address _reserveAddress, address reserveAddress,
address _aTokenAddress, address aTokenAddress,
uint256 _amount, uint256 amount,
uint256 _userBalance, uint256 userBalance,
mapping(address => ReserveLogic.ReserveData) storage _reservesData, mapping(address => ReserveLogic.ReserveData) storage reservesData,
UserConfiguration.Map storage _userConfig, UserConfiguration.Map storage userConfig,
address[] calldata _reserves, address[] calldata reserves,
address _oracle address oracle
) external view { ) external view {
require(_amount > 0, 'Amount must be greater than 0'); require(amount > 0, 'Amount must be greater than 0');
uint256 currentAvailableLiquidity = IERC20(_reserveAddress).balanceOf(address(_aTokenAddress)); uint256 currentAvailableLiquidity = IERC20(reserveAddress).balanceOf(address(aTokenAddress));
require(currentAvailableLiquidity >= _amount, '4'); require(currentAvailableLiquidity >= amount, '4');
require(_amount <= _userBalance, 'User cannot withdraw more than the available balance'); require(amount <= userBalance, 'User cannot withdraw more than the available balance');
require( require(
GenericLogic.balanceDecreaseAllowed( GenericLogic.balanceDecreaseAllowed(
_reserveAddress, reserveAddress,
msg.sender, msg.sender,
_userBalance, userBalance,
_reservesData, reservesData,
_userConfig, userConfig,
_reserves, reserves,
_oracle oracle
), ),
'Transfer cannot be allowed.' 'Transfer cannot be allowed.'
); );
@ -105,29 +105,29 @@ library ValidationLogic {
/** /**
* @dev validates a borrow. * @dev validates a borrow.
* @param _reserve the reserve state from which the user is borrowing * @param reserve the reserve state from which the user is borrowing
* @param _reserveAddress the address of the reserve * @param reserveAddress the address of the reserve
* @param _amount the amount to be borrowed * @param amount the amount to be borrowed
* @param _amountInETH the amount to be borrowed, in ETH * @param amountInETH the amount to be borrowed, in ETH
* @param _interestRateMode the interest rate mode at which the user is borrowing * @param interestRateMode the interest rate mode at which the user is borrowing
* @param _maxStableLoanPercent the max amount of the liquidity that can be borrowed at stable rate, in percentage * @param maxStableLoanPercent the max amount of the liquidity that can be borrowed at stable rate, in percentage
* @param _reservesData the state of all the reserves * @param reservesData the state of all the reserves
* @param _userConfig the state of the user for the specific reserve * @param userConfig the state of the user for the specific reserve
* @param _reserves the addresses of all the active reserves * @param reserves the addresses of all the active reserves
* @param _oracle the price oracle * @param oracle the price oracle
*/ */
function validateBorrow( function validateBorrow(
ReserveLogic.ReserveData storage _reserve, ReserveLogic.ReserveData storage reserve,
address _reserveAddress, address reserveAddress,
uint256 _amount, uint256 amount,
uint256 _amountInETH, uint256 amountInETH,
uint256 _interestRateMode, uint256 interestRateMode,
uint256 _maxStableLoanPercent, uint256 maxStableLoanPercent,
mapping(address => ReserveLogic.ReserveData) storage _reservesData, mapping(address => ReserveLogic.ReserveData) storage reservesData,
UserConfiguration.Map storage _userConfig, UserConfiguration.Map storage userConfig,
address[] calldata _reserves, address[] calldata reserves,
address _oracle address oracle
) external view { ) external view {
ValidateBorrowLocalVars memory vars; ValidateBorrowLocalVars memory vars;
@ -136,7 +136,7 @@ library ValidationLogic {
vars.isFreezed, vars.isFreezed,
vars.borrowingEnabled, vars.borrowingEnabled,
vars.stableRateBorrowingEnabled vars.stableRateBorrowingEnabled
) = _reserve.configuration.getFlags(); ) = reserve.configuration.getFlags();
require(vars.isActive, 'Action requires an active reserve'); require(vars.isActive, 'Action requires an active reserve');
require(!vars.isFreezed, 'Action requires an unfreezed reserve'); require(!vars.isFreezed, 'Action requires an unfreezed reserve');
@ -145,15 +145,15 @@ library ValidationLogic {
//validate interest rate mode //validate interest rate mode
require( require(
uint256(ReserveLogic.InterestRateMode.VARIABLE) == _interestRateMode || uint256(ReserveLogic.InterestRateMode.VARIABLE) == interestRateMode ||
uint256(ReserveLogic.InterestRateMode.STABLE) == _interestRateMode, uint256(ReserveLogic.InterestRateMode.STABLE) == interestRateMode,
'Invalid interest rate mode selected' 'Invalid interest rate mode selected'
); );
//check that the amount is available in the reserve //check that the amount is available in the reserve
vars.availableLiquidity = IERC20(_reserveAddress).balanceOf(address(_reserve.aTokenAddress)); vars.availableLiquidity = IERC20(reserveAddress).balanceOf(address(reserve.aTokenAddress));
require(vars.availableLiquidity >= _amount, '7'); require(vars.availableLiquidity >= amount, '7');
( (
vars.userCollateralBalanceETH, vars.userCollateralBalanceETH,
@ -163,10 +163,10 @@ library ValidationLogic {
vars.healthFactor vars.healthFactor
) = GenericLogic.calculateUserAccountData( ) = GenericLogic.calculateUserAccountData(
msg.sender, msg.sender,
_reservesData, reservesData,
_userConfig, userConfig,
_reserves, reserves,
_oracle oracle
); );
require(vars.userCollateralBalanceETH > 0, 'The collateral balance is 0'); require(vars.userCollateralBalanceETH > 0, 'The collateral balance is 0');
@ -174,7 +174,7 @@ library ValidationLogic {
require(vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, '8'); require(vars.healthFactor > GenericLogic.HEALTH_FACTOR_LIQUIDATION_THRESHOLD, '8');
//add the current already borrowed amount to the amount requested to calculate the total collateral needed. //add the current already borrowed amount to the amount requested to calculate the total collateral needed.
vars.amountOfCollateralNeededETH = vars.userBorrowBalanceETH.add(_amountInETH).percentDiv( vars.amountOfCollateralNeededETH = vars.userBorrowBalanceETH.add(amountInETH).percentDiv(
vars.currentLtv vars.currentLtv
); //LTV is calculated in percentage ); //LTV is calculated in percentage
@ -198,88 +198,84 @@ library ValidationLogic {
require(vars.stableRateBorrowingEnabled, '11'); require(vars.stableRateBorrowingEnabled, '11');
require( require(
!_userConfig.isUsingAsCollateral(_reserve.index) || !userConfig.isUsingAsCollateral(reserve.index) ||
_reserve.configuration.getLtv() == 0 || reserve.configuration.getLtv() == 0 ||
_amount > IERC20(_reserve.aTokenAddress).balanceOf(msg.sender), amount > IERC20(reserve.aTokenAddress).balanceOf(msg.sender),
'12' '12'
); );
//calculate the max available loan size in stable rate mode as a percentage of the //calculate the max available loan size in stable rate mode as a percentage of the
//available liquidity //available liquidity
uint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(_maxStableLoanPercent); uint256 maxLoanSizeStable = vars.availableLiquidity.percentMul(maxStableLoanPercent);
require(_amount <= maxLoanSizeStable, '13'); require(amount <= maxLoanSizeStable, '13');
} }
} }
/** /**
* @dev validates a repay. * @dev validates a repay.
* @param _reserve the reserve state from which the user is repaying * @param reserve the reserve state from which the user is repaying
* @param _reserveAddress the address of the reserve * @param amountSent the amount sent for the repayment. Can be an actual value or uint(-1)
* @param _amountSent the amount sent for the repayment. Can be an actual value or uint(-1) * @param onBehalfOf the address of the user msg.sender is repaying for
* @param _onBehalfOf the address of the user msg.sender is repaying for * @param stableDebt the borrow balance of the user
* @param _stableBorrowBalance the borrow balance of the user * @param variableDebt the borrow balance of the user
* @param _variableBorrowBalance the borrow balance of the user
* @param _actualPaybackAmount the actual amount being repaid
*/ */
function validateRepay( function validateRepay(
ReserveLogic.ReserveData storage _reserve, ReserveLogic.ReserveData storage reserve,
address _reserveAddress, uint256 amountSent,
uint256 _amountSent, ReserveLogic.InterestRateMode rateMode,
ReserveLogic.InterestRateMode _rateMode, address onBehalfOf,
address _onBehalfOf, uint256 stableDebt,
uint256 _stableBorrowBalance, uint256 variableDebt
uint256 _variableBorrowBalance,
uint256 _actualPaybackAmount
) external view { ) external view {
bool isActive = _reserve.configuration.getActive(); bool isActive = reserve.configuration.getActive();
require(isActive, 'Action requires an active reserve'); require(isActive, 'Action requires an active reserve');
require(_amountSent > 0, 'Amount must be greater than 0'); require(amountSent > 0, 'Amount must be greater than 0');
require( require(
(_stableBorrowBalance > 0 && (stableDebt > 0 &&
ReserveLogic.InterestRateMode(_rateMode) == ReserveLogic.InterestRateMode.STABLE) || ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.STABLE) ||
(_variableBorrowBalance > 0 && (variableDebt > 0 &&
ReserveLogic.InterestRateMode(_rateMode) == ReserveLogic.InterestRateMode.VARIABLE), ReserveLogic.InterestRateMode(rateMode) == ReserveLogic.InterestRateMode.VARIABLE),
'16' '16'
); );
require( require(
_amountSent != uint256(-1) || msg.sender == _onBehalfOf, amountSent != uint256(-1) || msg.sender == onBehalfOf,
'To repay on behalf of an user an explicit amount to repay is needed' 'To repay on behalf of an user an explicit amount to repay is needed'
); );
} }
/** /**
* @dev validates a swap of borrow rate mode. * @dev validates a swap of borrow rate mode.
* @param _reserve the reserve state on which the user is swapping the rate * @param reserve the reserve state on which the user is swapping the rate
* @param _userConfig the user reserves configuration * @param userConfig the user reserves configuration
* @param _stableBorrowBalance the stable borrow balance of the user * @param stableBorrowBalance the stable borrow balance of the user
* @param _variableBorrowBalance the stable borrow balance of the user * @param variableBorrowBalance the stable borrow balance of the user
* @param _currentRateMode the rate mode of the borrow * @param currentRateMode the rate mode of the borrow
*/ */
function validateSwapRateMode( function validateSwapRateMode(
ReserveLogic.ReserveData storage _reserve, ReserveLogic.ReserveData storage reserve,
UserConfiguration.Map storage _userConfig, UserConfiguration.Map storage userConfig,
uint256 _stableBorrowBalance, uint256 stableBorrowBalance,
uint256 _variableBorrowBalance, uint256 variableBorrowBalance,
ReserveLogic.InterestRateMode _currentRateMode ReserveLogic.InterestRateMode currentRateMode
) external view { ) external view {
(bool isActive, bool isFreezed, , bool stableRateEnabled) = _reserve.configuration.getFlags(); (bool isActive, bool isFreezed, , bool stableRateEnabled) = reserve.configuration.getFlags();
require(isActive, 'Action requires an active reserve'); require(isActive, 'Action requires an active reserve');
require(!isFreezed, 'Action requires an unfreezed reserve'); require(!isFreezed, 'Action requires an unfreezed reserve');
if (_currentRateMode == ReserveLogic.InterestRateMode.STABLE) { if (currentRateMode == ReserveLogic.InterestRateMode.STABLE) {
require( require(
_stableBorrowBalance > 0, stableBorrowBalance > 0,
'User does not have a stable rate loan in progress on this reserve' 'User does not have a stable rate loan in progress on this reserve'
); );
} else if (_currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) { } else if (currentRateMode == ReserveLogic.InterestRateMode.VARIABLE) {
require( require(
_variableBorrowBalance > 0, variableBorrowBalance > 0,
'User does not have a variable rate loan in progress on this reserve' 'User does not have a variable rate loan in progress on this reserve'
); );
/** /**
@ -292,10 +288,10 @@ library ValidationLogic {
require(stableRateEnabled, '11'); require(stableRateEnabled, '11');
require( require(
!_userConfig.isUsingAsCollateral(_reserve.index) || !userConfig.isUsingAsCollateral(reserve.index) ||
_reserve.configuration.getLtv() == 0 || reserve.configuration.getLtv() == 0 ||
_stableBorrowBalance.add(_variableBorrowBalance) > stableBorrowBalance.add(variableBorrowBalance) >
IERC20(_reserve.aTokenAddress).balanceOf(msg.sender), IERC20(reserve.aTokenAddress).balanceOf(msg.sender),
'12' '12'
); );
} else { } else {
@ -305,34 +301,34 @@ library ValidationLogic {
/** /**
* @dev validates the choice of a user of setting (or not) an asset as collateral * @dev validates the choice of a user of setting (or not) an asset as collateral
* @param _reserve the state of the reserve that the user is enabling or disabling as collateral * @param reserve the state of the reserve that the user is enabling or disabling as collateral
* @param _reserveAddress the address of the reserve * @param reserveAddress the address of the reserve
* @param _reservesData the data of all the reserves * @param reservesData the data of all the reserves
* @param _userConfig the state of the user for the specific reserve * @param userConfig the state of the user for the specific reserve
* @param _reserves the addresses of all the active reserves * @param reserves the addresses of all the active reserves
* @param _oracle the price oracle * @param oracle the price oracle
*/ */
function validateSetUseReserveAsCollateral( function validateSetUseReserveAsCollateral(
ReserveLogic.ReserveData storage _reserve, ReserveLogic.ReserveData storage reserve,
address _reserveAddress, address reserveAddress,
mapping(address => ReserveLogic.ReserveData) storage _reservesData, mapping(address => ReserveLogic.ReserveData) storage reservesData,
UserConfiguration.Map storage _userConfig, UserConfiguration.Map storage userConfig,
address[] calldata _reserves, address[] calldata reserves,
address _oracle address oracle
) external view { ) external view {
uint256 underlyingBalance = IERC20(_reserve.aTokenAddress).balanceOf(msg.sender); uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender);
require(underlyingBalance > 0, '22'); require(underlyingBalance > 0, '22');
require( require(
GenericLogic.balanceDecreaseAllowed( GenericLogic.balanceDecreaseAllowed(
_reserveAddress, reserveAddress,
msg.sender, msg.sender,
underlyingBalance, underlyingBalance,
_reservesData, reservesData,
_userConfig, userConfig,
_reserves, reserves,
_oracle oracle
), ),
'User deposit is already being used as collateral' 'User deposit is already being used as collateral'
); );

View File

@ -12,22 +12,22 @@ library MathUtils {
/** /**
* @dev function to calculate the interest using a linear interest rate formula * @dev function to calculate the interest using a linear interest rate formula
* @param _rate the interest rate, in ray * @param rate the interest rate, in ray
* @param _lastUpdateTimestamp the timestamp of the last update of the interest * @param lastUpdateTimestamp the timestamp of the last update of the interest
* @return the interest rate linearly accumulated during the timeDelta, in ray * @return the interest rate linearly accumulated during the timeDelta, in ray
**/ **/
function calculateLinearInterest(uint256 _rate, uint40 _lastUpdateTimestamp) function calculateLinearInterest(uint256 rate, uint40 lastUpdateTimestamp)
internal internal
view view
returns (uint256) returns (uint256)
{ {
//solium-disable-next-line //solium-disable-next-line
uint256 timeDifference = block.timestamp.sub(uint256(_lastUpdateTimestamp)); uint256 timeDifference = block.timestamp.sub(uint256(lastUpdateTimestamp));
uint256 timeDelta = timeDifference.wadToRay().rayDiv(SECONDS_PER_YEAR.wadToRay()); uint256 timeDelta = timeDifference.wadToRay().rayDiv(SECONDS_PER_YEAR.wadToRay());
return _rate.rayMul(timeDelta).add(WadRayMath.ray()); return rate.rayMul(timeDelta).add(WadRayMath.ray());
} }
/** /**
@ -39,17 +39,17 @@ library MathUtils {
* The approximation slightly underpays liquidity providers, with the advantage of great gas cost reductions. * 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. * The whitepaper contains reference to the approximation and a table showing the margin of error per different time periods.
* *
* @param _rate the interest rate, in ray * @param rate the interest rate, in ray
* @param _lastUpdateTimestamp the timestamp of the last update of the interest * @param lastUpdateTimestamp the timestamp of the last update of the interest
* @return the interest rate compounded during the timeDelta, in ray * @return the interest rate compounded during the timeDelta, in ray
**/ **/
function calculateCompoundedInterest(uint256 _rate, uint40 _lastUpdateTimestamp) function calculateCompoundedInterest(uint256 rate, uint40 lastUpdateTimestamp)
internal internal
view view
returns (uint256) returns (uint256)
{ {
//solium-disable-next-line //solium-disable-next-line
uint256 exp = block.timestamp.sub(uint256(_lastUpdateTimestamp)); uint256 exp = block.timestamp.sub(uint256(lastUpdateTimestamp));
if (exp == 0) { if (exp == 0) {
return WadRayMath.ray(); return WadRayMath.ray();
@ -59,7 +59,7 @@ library MathUtils {
uint256 expMinusTwo = exp > 2 ? exp.sub(2) : 0; uint256 expMinusTwo = exp > 2 ? exp.sub(2) : 0;
uint256 ratePerSecond = _rate.div(31536000); uint256 ratePerSecond = rate.div(31536000);
uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond); uint256 basePowerTwo = ratePerSecond.rayMul(ratePerSecond);
uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond); uint256 basePowerThree = basePowerTwo.rayMul(ratePerSecond);

View File

@ -19,23 +19,23 @@ library PercentageMath {
/** /**
* @dev executes a percentage multiplication * @dev executes a percentage multiplication
* @param _value the value of which the percentage needs to be calculated * @param value the value of which the percentage needs to be calculated
* @param _percentage the percentage of the value to be calculated * @param percentage the percentage of the value to be calculated
* @return the _percentage of _value * @return the percentage of value
**/ **/
function percentMul(uint256 _value, uint256 _percentage) internal pure returns (uint256) { function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256) {
return HALF_PERCENT.add(_value.mul(_percentage)).div(PERCENTAGE_FACTOR); return HALF_PERCENT.add(value.mul(percentage)).div(PERCENTAGE_FACTOR);
} }
/** /**
* @dev executes a percentage division * @dev executes a percentage division
* @param _value the value of which the percentage needs to be calculated * @param value the value of which the percentage needs to be calculated
* @param _percentage the percentage of the value to be calculated * @param percentage the percentage of the value to be calculated
* @return the _value divided the _percentage * @return the value divided the percentage
**/ **/
function percentDiv(uint256 _value, uint256 _percentage) internal pure returns (uint256) { function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256) {
uint256 halfPercentage = _percentage / 2; uint256 halfPercentage = percentage / 2;
return halfPercentage.add(_value.mul(PERCENTAGE_FACTOR)).div(_percentage); return halfPercentage.add(value.mul(PERCENTAGE_FACTOR)).div(percentage);
} }
} }

View File

@ -15,22 +15,22 @@ contract InitializableAdminUpgradeabilityProxy is
{ {
/** /**
* Contract initializer. * Contract initializer.
* @param _logic address of the initial implementation. * @param logic address of the initial implementation.
* @param _admin Address of the proxy administrator. * @param admin Address of the proxy administrator.
* @param _data Data to send as msg.data to the implementation to initialize the proxied contract. * @param data Data to send as msg.data to the implementation to initialize the proxied contract.
* It should include the signature and the parameters of the function to be called, as described in * It should include the signature and the parameters of the function to be called, as described in
* https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding. * https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#function-selector-and-argument-encoding.
* This parameter is optional, if no data is given the initialization call to proxied contract will be skipped. * This parameter is optional, if no data is given the initialization call to proxied contract will be skipped.
*/ */
function initialize( function initialize(
address _logic, address logic,
address _admin, address admin,
bytes memory _data bytes memory data
) public payable { ) public payable {
require(_implementation() == address(0)); require(_implementation() == address(0));
InitializableUpgradeabilityProxy.initialize(_logic, _data); InitializableUpgradeabilityProxy.initialize(logic, data);
assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1));
_setAdmin(_admin); _setAdmin(admin);
} }
/** /**

View File

@ -51,7 +51,7 @@ contract MockFlashLoanReceiver is FlashLoanReceiverBase {
token.mint(_fee); token.mint(_fee);
//returning amount + fee to the destination //returning amount + fee to the destination
transferFundsBackInternal(_reserve, _destination, _amount.add(_fee)); _transferFundsBack(_reserve, _destination, _amount.add(_fee));
emit ExecutedWithSuccess(_reserve, _amount, _fee); emit ExecutedWithSuccess(_reserve, _amount, _fee);
} }

View File

@ -76,7 +76,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
address to, address to,
uint256 amount uint256 amount
) internal override whenTransferAllowed(from, amount) { ) internal override whenTransferAllowed(from, amount) {
executeTransferInternal(from, to, amount); _executeTransfer(from, to, amount);
} }
/** /**
@ -86,7 +86,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param to the address to which the interest will be redirected * @param to the address to which the interest will be redirected
**/ **/
function redirectInterestStream(address to) external override { function redirectInterestStream(address to) external override {
redirectInterestStreamInternal(msg.sender, to); _redirectInterestStream(msg.sender, to);
} }
/** /**
@ -102,7 +102,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
msg.sender == _interestRedirectionAllowances[from], msg.sender == _interestRedirectionAllowances[from],
'Caller is not allowed to redirect the interest of the user' 'Caller is not allowed to redirect the interest of the user'
); );
redirectInterestStreamInternal(from, to); _redirectInterestStream(from, to);
} }
/** /**
@ -128,12 +128,12 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
uint256 amount uint256 amount
) external override onlyLendingPool { ) external override onlyLendingPool {
//cumulates the balance of the user //cumulates the balance of the user
(, uint256 currentBalance, uint256 balanceIncrease) = calculateBalanceIncreaseInternal(user); (, uint256 currentBalance, uint256 balanceIncrease) = _calculateBalanceIncrease(user);
//if the user is redirecting his interest towards someone else, //if the user is redirecting his interest towards someone else,
//we update the redirected balance of the redirection address by adding the accrued interest, //we update the redirected balance of the redirection address by adding the accrued interest,
//and removing the amount to redeem //and removing the amount to redeem
updateRedirectedBalanceOfRedirectionAddressInternal(user, balanceIncrease, amount); _updateRedirectedBalanceOfRedirectionAddress(user, balanceIncrease, amount);
if (balanceIncrease > amount) { if (balanceIncrease > amount) {
_mint(user, balanceIncrease.sub(amount)); _mint(user, balanceIncrease.sub(amount));
@ -145,7 +145,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
//reset the user data if the remaining balance is 0 //reset the user data if the remaining balance is 0
if (currentBalance.sub(amount) == 0) { if (currentBalance.sub(amount) == 0) {
resetDataOnZeroBalanceInternal(user); _resetDataOnZeroBalance(user);
} else { } else {
//updates the user index //updates the user index
userIndex = _userIndexes[user] = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS); userIndex = _userIndexes[user] = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
@ -165,7 +165,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
*/ */
function mint(address user, uint256 amount) external override onlyLendingPool { function mint(address user, uint256 amount) external override onlyLendingPool {
//cumulates the balance of the user //cumulates the balance of the user
(, , uint256 balanceIncrease) = calculateBalanceIncreaseInternal(user); (, , uint256 balanceIncrease) = _calculateBalanceIncrease(user);
//updates the user index //updates the user index
uint256 index = _userIndexes[user] = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS); uint256 index = _userIndexes[user] = _pool.getReserveNormalizedIncome(UNDERLYING_ASSET_ADDRESS);
@ -173,7 +173,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
//if the user is redirecting his interest towards someone else, //if the user is redirecting his interest towards someone else,
//we update the redirected balance of the redirection address by adding the accrued interest //we update the redirected balance of the redirection address by adding the accrued interest
//and the amount deposited //and the amount deposited
updateRedirectedBalanceOfRedirectionAddressInternal(user, balanceIncrease.add(amount), 0); _updateRedirectedBalanceOfRedirectionAddress(user, balanceIncrease.add(amount), 0);
//mint an equivalent amount of tokens to cover the new deposit //mint an equivalent amount of tokens to cover the new deposit
_mint(user, amount.add(balanceIncrease)); _mint(user, amount.add(balanceIncrease));
@ -195,7 +195,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
) external override onlyLendingPool { ) external override onlyLendingPool {
//being a normal transfer, the Transfer() and BalanceTransfer() are emitted //being a normal transfer, the Transfer() and BalanceTransfer() are emitted
//so no need to emit a specific event here //so no need to emit a specific event here
executeTransferInternal(from, to, value); _executeTransfer(from, to, value);
} }
/** /**
@ -220,7 +220,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
//accruing for himself means that both the principal balance and //accruing for himself means that both the principal balance and
//the redirected balance partecipate in the interest //the redirected balance partecipate in the interest
return return
calculateCumulatedBalanceInternal(user, currentPrincipalBalance.add(redirectedBalance)).sub( _calculateCumulatedBalance(user, currentPrincipalBalance.add(redirectedBalance)).sub(
redirectedBalance redirectedBalance
); );
} else { } else {
@ -229,7 +229,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
//by the redirected balance is added to the current principal balance. //by the redirected balance is added to the current principal balance.
return return
currentPrincipalBalance.add( currentPrincipalBalance.add(
calculateCumulatedBalanceInternal(user, redirectedBalance).sub(redirectedBalance) _calculateCumulatedBalance(user, redirectedBalance).sub(redirectedBalance)
); );
} }
} }
@ -307,7 +307,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param user the address of the user * @param user the address of the user
* @return the last user principal balance, the current balance and the balance increase * @return the last user principal balance, the current balance and the balance increase
**/ **/
function calculateBalanceIncreaseInternal(address user) function _calculateBalanceIncrease(address user)
internal internal
view view
returns ( returns (
@ -335,7 +335,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @return the previous principal balance, the new principal balance, the balance increase * @return the previous principal balance, the new principal balance, the balance increase
* and the new user index * and the new user index
**/ **/
function cumulateBalanceInternal(address user) function _cumulateBalance(address user)
internal internal
returns ( returns (
uint256, uint256,
@ -348,7 +348,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
uint256 previousBalance, uint256 previousBalance,
uint256 currentBalance, uint256 currentBalance,
uint256 balanceIncrease uint256 balanceIncrease
) = calculateBalanceIncreaseInternal(user); ) = _calculateBalanceIncrease(user);
_mint(user, balanceIncrease); _mint(user, balanceIncrease);
@ -365,7 +365,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param balanceToAdd the amount to add to the redirected balance * @param balanceToAdd the amount to add to the redirected balance
* @param balanceToRemove the amount to remove from the redirected balance * @param balanceToRemove the amount to remove from the redirected balance
**/ **/
function updateRedirectedBalanceOfRedirectionAddressInternal( function _updateRedirectedBalanceOfRedirectionAddress(
address user, address user,
uint256 balanceToAdd, uint256 balanceToAdd,
uint256 balanceToRemove uint256 balanceToRemove
@ -377,7 +377,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
} }
//compound balances of the redirected address //compound balances of the redirected address
(, , uint256 balanceIncrease, uint256 index) = cumulateBalanceInternal(redirectionAddress); (, , uint256 balanceIncrease, uint256 index) = _cumulateBalance(redirectionAddress);
//updating the redirected balance //updating the redirected balance
_redirectedBalances[redirectionAddress] = _redirectedBalances[redirectionAddress] _redirectedBalances[redirectionAddress] = _redirectedBalances[redirectionAddress]
@ -391,7 +391,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
// if the redirection address is also redirecting the interest, we accumulate his balance // if the redirection address is also redirecting the interest, we accumulate his balance
// and update his chain of redirection // and update his chain of redirection
if (targetOfRedirectionAddress != address(0)) { if (targetOfRedirectionAddress != address(0)) {
updateRedirectedBalanceOfRedirectionAddressInternal(redirectionAddress, balanceIncrease, 0); _updateRedirectedBalanceOfRedirectionAddress(redirectionAddress, balanceIncrease, 0);
} }
emit RedirectedBalanceUpdated( emit RedirectedBalanceUpdated(
@ -409,7 +409,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param balance the balance on which the interest is calculated * @param balance the balance on which the interest is calculated
* @return the interest rate accrued * @return the interest rate accrued
**/ **/
function calculateCumulatedBalanceInternal(address user, uint256 balance) function _calculateCumulatedBalance(address user, uint256 balance)
internal internal
view view
returns (uint256) returns (uint256)
@ -429,7 +429,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param to the destination address * @param to the destination address
* @param value the amount to transfer * @param value the amount to transfer
**/ **/
function executeTransferInternal( function _executeTransfer(
address from, address from,
address to, address to,
uint256 value uint256 value
@ -442,20 +442,20 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
uint256 fromBalance, uint256 fromBalance,
uint256 fromBalanceIncrease, uint256 fromBalanceIncrease,
uint256 fromIndex uint256 fromIndex
) = cumulateBalanceInternal(from); ) = _cumulateBalance(from);
//cumulate the balance of the receiver //cumulate the balance of the receiver
(, , uint256 toBalanceIncrease, uint256 toIndex) = cumulateBalanceInternal(to); (, , uint256 toBalanceIncrease, uint256 toIndex) = _cumulateBalance(to);
//if the sender is redirecting his interest towards someone else, //if the sender is redirecting his interest towards someone else,
//adds to the redirected balance the accrued interest and removes the amount //adds to the redirected balance the accrued interest and removes the amount
//being transferred //being transferred
updateRedirectedBalanceOfRedirectionAddressInternal(from, fromBalanceIncrease, value); _updateRedirectedBalanceOfRedirectionAddress(from, fromBalanceIncrease, value);
//if the receiver is redirecting his interest towards someone else, //if the receiver is redirecting his interest towards someone else,
//adds to the redirected balance the accrued interest and the amount //adds to the redirected balance the accrued interest and the amount
//being transferred //being transferred
updateRedirectedBalanceOfRedirectionAddressInternal(to, toBalanceIncrease.add(value), 0); _updateRedirectedBalanceOfRedirectionAddress(to, toBalanceIncrease.add(value), 0);
//performs the transfer //performs the transfer
super._transfer(from, to, value); super._transfer(from, to, value);
@ -463,7 +463,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
bool fromIndexReset = false; bool fromIndexReset = false;
//reset the user data if the remaining balance is 0 //reset the user data if the remaining balance is 0
if (fromBalance.sub(value) == 0 && from != to) { if (fromBalance.sub(value) == 0 && from != to) {
fromIndexReset = resetDataOnZeroBalanceInternal(from); fromIndexReset = _resetDataOnZeroBalance(from);
} }
emit BalanceTransfer( emit BalanceTransfer(
@ -483,7 +483,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param from the address from which transfer the aTokens * @param from the address from which transfer the aTokens
* @param to the destination address * @param to the destination address
**/ **/
function redirectInterestStreamInternal(address from, address to) internal { function _redirectInterestStream(address from, address to) internal {
address currentRedirectionAddress = _interestRedirectionAddresses[from]; address currentRedirectionAddress = _interestRedirectionAddresses[from];
require(to != currentRedirectionAddress, 'Interest is already redirected to the user'); require(to != currentRedirectionAddress, 'Interest is already redirected to the user');
@ -494,7 +494,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
uint256 fromBalance, uint256 fromBalance,
uint256 balanceIncrease, uint256 balanceIncrease,
uint256 fromIndex uint256 fromIndex
) = cumulateBalanceInternal(from); ) = _cumulateBalance(from);
require(fromBalance > 0, 'Interest stream can only be redirected if there is a valid balance'); require(fromBalance > 0, 'Interest stream can only be redirected if there is a valid balance');
@ -502,7 +502,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
//the redirection address we substract the redirected balance of the previous //the redirection address we substract the redirected balance of the previous
//recipient //recipient
if (currentRedirectionAddress != address(0)) { if (currentRedirectionAddress != address(0)) {
updateRedirectedBalanceOfRedirectionAddressInternal(from, 0, previousPrincipalBalance); _updateRedirectedBalanceOfRedirectionAddress(from, 0, previousPrincipalBalance);
} }
//if the user is redirecting the interest back to himself, //if the user is redirecting the interest back to himself,
@ -517,7 +517,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
_interestRedirectionAddresses[from] = to; _interestRedirectionAddresses[from] = to;
//adds the user balance to the redirected balance of the destination //adds the user balance to the redirected balance of the destination
updateRedirectedBalanceOfRedirectionAddressInternal(from, fromBalance, 0); _updateRedirectedBalanceOfRedirectionAddress(from, fromBalance, 0);
emit InterestStreamRedirected(from, to, fromBalance, balanceIncrease, fromIndex); emit InterestStreamRedirected(from, to, fromBalance, balanceIncrease, fromIndex);
} }
@ -528,7 +528,7 @@ contract AToken is VersionedInitializable, ERC20, IAToken {
* @param user the address of the user * @param user the address of the user
* @return true if the user index has also been reset, false otherwise. useful to emit the proper user index value * @return true if the user index has also been reset, false otherwise. useful to emit the proper user index value
**/ **/
function resetDataOnZeroBalanceInternal(address user) internal returns (bool) { function _resetDataOnZeroBalance(address user) internal returns (bool) {
//if the user has 0 principal balance, the interest stream redirection gets reset //if the user has 0 principal balance, the interest stream redirection gets reset
_interestRedirectionAddresses[user] = address(0); _interestRedirectionAddresses[user] = address(0);

View File

2638
tsts.log

File diff suppressed because it is too large Load Diff