2020-07-21 07:53:38 +00:00
|
|
|
// 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';
|
2020-08-20 07:51:21 +00:00
|
|
|
import {ReserveLogic} from '../logic/ReserveLogic.sol';
|
|
|
|
import {WadRayMath} from '../math/WadRayMath.sol';
|
|
|
|
import {IPriceOracleGetter} from '../../interfaces/IPriceOracleGetter.sol';
|
2020-07-21 07:53:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @title ReserveConfiguration library
|
|
|
|
* @author Aave
|
2020-07-27 07:49:45 +00:00
|
|
|
* @notice Implements the bitmap logic to handle the reserve configuration
|
2020-07-21 07:53:38 +00:00
|
|
|
*/
|
|
|
|
library ReserveConfiguration {
|
2020-07-23 15:18:06 +00:00
|
|
|
uint256 constant LTV_MASK = 0xFFFFFFFFFFF0000;
|
|
|
|
uint256 constant LIQUIDATION_THRESHOLD_MASK = 0xFFFFFFF0000FFFF;
|
|
|
|
uint256 constant LIQUIDATION_BONUS_MASK = 0xFFF0000FFFFFFFF;
|
|
|
|
uint256 constant DECIMALS_MASK = 0xF00FFFFFFFFFFFF;
|
|
|
|
uint256 constant ACTIVE_MASK = 0xEFFFFFFFFFFFFFF;
|
2020-07-27 07:49:45 +00:00
|
|
|
uint256 constant FROZEN_MASK = 0xDFFFFFFFFFFFFFF;
|
2020-07-23 15:18:06 +00:00
|
|
|
uint256 constant BORROWING_MASK = 0xBFFFFFFFFFFFFFF;
|
|
|
|
uint256 constant STABLE_BORROWING_MASK = 0x7FFFFFFFFFFFFFF;
|
2020-07-21 07:53:38 +00:00
|
|
|
|
|
|
|
struct Map {
|
|
|
|
//bit 0-15: LTV
|
|
|
|
//bit 16-31: Liq. threshold
|
|
|
|
//bit 32-47: Liq. bonus
|
2020-07-23 15:18:06 +00:00
|
|
|
//bit 48-55: Decimals
|
|
|
|
//bit 56: Reserve is active
|
|
|
|
//bit 57: reserve is freezed
|
|
|
|
//bit 58: borrowing is enabled
|
|
|
|
//bit 59: stable rate borrowing enabled
|
2020-07-21 07:53:38 +00:00
|
|
|
uint256 data;
|
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the Loan to Value of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param ltv the new ltv
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setLtv(ReserveConfiguration.Map memory self, uint256 ltv) internal pure {
|
|
|
|
self.data = (self.data & LTV_MASK) | ltv;
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the Loan to Value of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the loan to value
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getLtv(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
|
|
|
return self.data & ~LTV_MASK;
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the liquidation threshold of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param threshold the new liquidation threshold
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setLiquidationThreshold(ReserveConfiguration.Map memory self, uint256 threshold)
|
2020-07-21 08:20:51 +00:00
|
|
|
internal
|
2020-08-21 12:50:28 +00:00
|
|
|
pure
|
2020-07-21 08:20:51 +00:00
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
self.data = (self.data & LIQUIDATION_THRESHOLD_MASK) | (threshold << 16);
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the Loan to Value of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the liquidation threshold
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getLiquidationThreshold(ReserveConfiguration.Map storage self)
|
2020-07-21 08:20:51 +00:00
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (uint256)
|
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
return (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> 16;
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the liquidation bonus of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param bonus the new liquidation bonus
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setLiquidationBonus(ReserveConfiguration.Map memory self, uint256 bonus) internal pure {
|
|
|
|
self.data = (self.data & LIQUIDATION_BONUS_MASK) | (bonus << 32);
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the liquidation bonus of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the liquidation bonus
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getLiquidationBonus(ReserveConfiguration.Map storage self)
|
2020-07-21 08:20:51 +00:00
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (uint256)
|
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
return (self.data & ~LIQUIDATION_BONUS_MASK) >> 32;
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the decimals of the underlying asset of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param decimals the decimals
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setDecimals(ReserveConfiguration.Map memory self, uint256 decimals) internal pure {
|
|
|
|
self.data = (self.data & DECIMALS_MASK) | (decimals << 48);
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the decimals of the underlying asset of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the decimals of the asset
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getDecimals(ReserveConfiguration.Map storage self) internal view returns (uint256) {
|
|
|
|
return (self.data & ~DECIMALS_MASK) >> 48;
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|
2020-07-23 15:18:06 +00:00
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the active state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param active the active state
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setActive(ReserveConfiguration.Map memory self, bool active) internal {
|
|
|
|
self.data = (self.data & ACTIVE_MASK) | (uint256(active ? 1 : 0) << 56);
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the active state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the active state
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getActive(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
|
|
|
return ((self.data & ~ACTIVE_MASK) >> 56) != 0;
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev sets the frozen state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param frozen the frozen state
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setFrozen(ReserveConfiguration.Map memory self, bool frozen) internal pure {
|
|
|
|
self.data = (self.data & FROZEN_MASK) | (uint256(frozen ? 1 : 0) << 57);
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the frozen state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the frozen state
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getFrozen(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
|
|
|
return ((self.data & ~FROZEN_MASK) >> 57) != 0;
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev enables or disables borrowing on the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param enabled true if the borrowing needs to be enabled, false otherwise
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled) internal pure {
|
|
|
|
self.data = (self.data & BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 58);
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the borrowing state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the borrowing state
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getBorrowingEnabled(ReserveConfiguration.Map storage self) internal view returns (bool) {
|
|
|
|
return ((self.data & ~BORROWING_MASK) >> 58) != 0;
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev enables or disables stable rate borrowing on the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
|
|
|
* @param enabled true if the stable rate borrowing needs to be enabled, false otherwise
|
2020-07-27 07:49:45 +00:00
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function setStableRateBorrowingEnabled(ReserveConfiguration.Map memory self, bool enabled)
|
|
|
|
internal pure
|
2020-07-23 15:18:06 +00:00
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
self.data = (self.data & STABLE_BORROWING_MASK) | (uint256(enabled ? 1 : 0) << 59);
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the stable rate borrowing state of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the stable rate borrowing state
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getStableRateBorrowingEnabled(ReserveConfiguration.Map storage self)
|
2020-07-23 15:18:06 +00:00
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (bool)
|
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
return ((self.data & ~STABLE_BORROWING_MASK) >> 59) != 0;
|
2020-07-23 15:18:06 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the configuration flags of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the state flags representing active, freezed, borrowing enabled, stableRateBorrowing enabled
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getFlags(ReserveConfiguration.Map storage self)
|
2020-07-23 15:18:06 +00:00
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (
|
|
|
|
bool,
|
|
|
|
bool,
|
|
|
|
bool,
|
|
|
|
bool
|
|
|
|
)
|
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
uint256 dataLocal = self.data;
|
2020-07-23 15:18:06 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
(dataLocal & ~ACTIVE_MASK) >> 56 != 0,
|
2020-07-27 07:49:45 +00:00
|
|
|
(dataLocal & ~FROZEN_MASK) >> 57 != 0,
|
2020-07-23 15:18:06 +00:00
|
|
|
(dataLocal & ~BORROWING_MASK) >> 58 != 0,
|
|
|
|
(dataLocal & ~STABLE_BORROWING_MASK) >> 59 != 0
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-27 07:49:45 +00:00
|
|
|
/**
|
|
|
|
* @dev gets the configuration paramters of the reserve
|
2020-08-21 12:50:28 +00:00
|
|
|
* @param self the reserve configuration
|
2020-07-27 07:49:45 +00:00
|
|
|
* @return the state params representing ltv, liquidation threshold, liquidation bonus, the reserve decimals
|
|
|
|
**/
|
2020-08-21 12:50:28 +00:00
|
|
|
function getParams(ReserveConfiguration.Map storage self)
|
2020-07-23 15:18:06 +00:00
|
|
|
internal
|
|
|
|
view
|
|
|
|
returns (
|
|
|
|
uint256,
|
|
|
|
uint256,
|
|
|
|
uint256,
|
|
|
|
uint256
|
|
|
|
)
|
|
|
|
{
|
2020-08-21 12:50:28 +00:00
|
|
|
uint256 dataLocal = self.data;
|
2020-07-23 15:18:06 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
dataLocal & ~LTV_MASK,
|
|
|
|
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> 16,
|
|
|
|
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> 32,
|
|
|
|
(dataLocal & ~DECIMALS_MASK) >> 48
|
|
|
|
);
|
|
|
|
}
|
2020-07-21 07:53:38 +00:00
|
|
|
}
|