feat: addind exposure caps to reserve config, condigurator and helpers

This commit is contained in:
Hadrien Charlanes 2021-06-02 16:44:03 +02:00
parent 0214b34d37
commit 31f78a1537
9 changed files with 121 additions and 28 deletions

View File

@ -33,6 +33,7 @@ contract ATokensAndRatesHelper is Ownable {
uint256 reserveFactor; uint256 reserveFactor;
uint256 borrowCap; uint256 borrowCap;
uint256 supplyCap; uint256 supplyCap;
uint256 exposureCap;
bool stableBorrowingEnabled; bool stableBorrowingEnabled;
bool borrowingEnabled; bool borrowingEnabled;
} }
@ -73,7 +74,8 @@ contract ATokensAndRatesHelper is Ownable {
inputParams[i].asset, inputParams[i].asset,
inputParams[i].baseLTV, inputParams[i].baseLTV,
inputParams[i].liquidationThreshold, inputParams[i].liquidationThreshold,
inputParams[i].liquidationBonus inputParams[i].liquidationBonus,
inputParams[i].exposureCap
); );
if (inputParams[i].borrowingEnabled) { if (inputParams[i].borrowingEnabled) {

View File

@ -153,6 +153,13 @@ interface ILendingPoolConfigurator {
**/ **/
event SupplyCapChanged(address indexed asset, uint256 supplyCap); event SupplyCapChanged(address indexed asset, uint256 supplyCap);
/**
* @dev Emitted when the exposure cap of a reserve is updated
* @param asset The address of the underlying asset of the reserve
* @param exposureCap The new exposure cap
**/
event ExposureCapChanged(address indexed asset, uint256 exposureCap);
/** /**
* @dev Emitted when the reserve decimals are updated * @dev Emitted when the reserve decimals are updated
* @param asset The address of the underlying asset of the reserve * @param asset The address of the underlying asset of the reserve
@ -264,13 +271,15 @@ interface ILendingPoolConfigurator {
* @param ltv The loan to value of the asset when used as collateral * @param ltv The loan to value of the asset when used as collateral
* @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized * @param liquidationThreshold The threshold at which loans using this asset as collateral will be considered undercollateralized
* @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105% * @param liquidationBonus The bonus liquidators receive to liquidate this asset. The values is always above 100%. A value of 105%
* @param exposureCap The exposure cap for the collateral reserve. If cap is reached, effective LTV = 0
* means the liquidator will receive a 5% bonus * means the liquidator will receive a 5% bonus
**/ **/
function configureReserveAsCollateral( function configureReserveAsCollateral(
address asset, address asset,
uint256 ltv, uint256 ltv,
uint256 liquidationThreshold, uint256 liquidationThreshold,
uint256 liquidationBonus uint256 liquidationBonus,
uint256 exposureCap
) external; ) external;
/** /**
@ -357,6 +366,13 @@ interface ILendingPoolConfigurator {
**/ **/
function setSupplyCap(address asset, uint256 supplyCap) external; function setSupplyCap(address asset, uint256 supplyCap) external;
/**
* @dev Updates the exposure cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param exposureCap The new exposure of the reserve
**/
function setExposureCap(address asset, uint256 exposureCap) external;
/** /**
* @dev Registers a new admin with rights on risk related configurations * @dev Registers a new admin with rights on risk related configurations
* @param admin The address of the admin to register * @param admin The address of the admin to register

View File

@ -81,14 +81,14 @@ contract AaveProtocolDataProvider {
bool isFrozen bool isFrozen
) )
{ {
DataTypes.ReserveConfigurationMap memory configuration = DataTypes.ReserveConfigurationMap memory configuration =
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset); ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = (ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) = configuration
configuration.getParamsMemory(); .getParamsMemory();
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled, ) = (isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled, ) = configuration
configuration.getFlagsMemory(); .getFlagsMemory();
usageAsCollateralEnabled = liquidationThreshold > 0; usageAsCollateralEnabled = liquidationThreshold > 0;
} }
@ -96,18 +96,21 @@ contract AaveProtocolDataProvider {
function getReserveCaps(address asset) function getReserveCaps(address asset)
external external
view view
returns (uint256 borrowCap, uint256 supplyCap) { returns (
uint256 borrowCap,
(borrowCap, supplyCap) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) uint256 supplyCap,
.getConfiguration(asset) uint256 exposureCap
.getCapsMemory(); )
} {
(borrowCap, supplyCap, exposureCap) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
.getConfiguration(asset)
.getCapsMemory();
}
function getPaused(address asset) external view returns (bool isPaused) { function getPaused(address asset) external view returns (bool isPaused) {
(, , , , isPaused) = (, , , , isPaused) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()) .getConfiguration(asset)
.getConfiguration(asset) .getFlagsMemory();
.getFlagsMemory();
} }
function getReserveData(address asset) function getReserveData(address asset)

View File

@ -114,10 +114,9 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
reserveData.decimals, reserveData.decimals,
reserveData.reserveFactor reserveData.reserveFactor
) = baseData.configuration.getParamsMemory(); ) = baseData.configuration.getParamsMemory();
( (reserveData.borrowCap, reserveData.supplyCap, reserveData.exposureCap) = baseData
reserveData.borrowCap, .configuration
reserveData.supplyCap .getCapsMemory();
) = baseData.configuration.getCapsMemory();
( (
reserveData.isActive, reserveData.isActive,
reserveData.isFrozen, reserveData.isFrozen,

View File

@ -17,6 +17,7 @@ interface IUiPoolDataProvider {
uint256 reserveFactor; uint256 reserveFactor;
uint256 borrowCap; uint256 borrowCap;
uint256 supplyCap; uint256 supplyCap;
uint256 exposureCap;
bool usageAsCollateralEnabled; bool usageAsCollateralEnabled;
bool borrowingEnabled; bool borrowingEnabled;
bool stableBorrowRateEnabled; bool stableBorrowRateEnabled;

View File

@ -292,7 +292,8 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
address asset, address asset,
uint256 ltv, uint256 ltv,
uint256 liquidationThreshold, uint256 liquidationThreshold,
uint256 liquidationBonus uint256 liquidationBonus,
uint256 exposureCap
) external override onlyRiskOrPoolAdmins { ) external override onlyRiskOrPoolAdmins {
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset); DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
@ -326,6 +327,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
currentConfig.setLtv(ltv); currentConfig.setLtv(ltv);
currentConfig.setLiquidationThreshold(liquidationThreshold); currentConfig.setLiquidationThreshold(liquidationThreshold);
currentConfig.setLiquidationBonus(liquidationBonus); currentConfig.setLiquidationBonus(liquidationBonus);
currentConfig.setExposureCap(exposureCap);
_pool.setConfiguration(asset, currentConfig.data); _pool.setConfiguration(asset, currentConfig.data);
@ -459,6 +461,21 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit SupplyCapChanged(asset, supplyCap); emit SupplyCapChanged(asset, supplyCap);
} }
///@inheritdoc ILendingPoolConfigurator
function setExposureCap(address asset, uint256 exposureCap)
external
override
onlyRiskOrPoolAdmins
{
DataTypes.ReserveConfigurationMap memory currentConfig = _pool.getConfiguration(asset);
currentConfig.setExposureCap(exposureCap);
_pool.setConfiguration(asset, currentConfig.data);
emit ExposureCapChanged(asset, exposureCap);
}
///@inheritdoc ILendingPoolConfigurator ///@inheritdoc ILendingPoolConfigurator
function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress) function setReserveInterestRateStrategyAddress(address asset, address rateStrategyAddress)
external external

View File

@ -22,6 +22,7 @@ library ReserveConfiguration {
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant EXPOSURE_CAP_MASK = 0xFFFFFFFFFFFFFFFFF000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // prettier-ignore
/// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed /// @dev For the LTV, the start bit is 0 (up to 15), hence no bitshifting is needed
uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16; uint256 constant LIQUIDATION_THRESHOLD_START_BIT_POSITION = 16;
@ -36,6 +37,7 @@ library ReserveConfiguration {
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64; uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 constant BORROW_CAP_START_BIT_POSITION = 80; uint256 constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 116; uint256 constant SUPPLY_CAP_START_BIT_POSITION = 116;
uint256 constant EXPOSURE_CAP_START_BIT_POSITION = 152;
uint256 constant MAX_VALID_LTV = 65535; uint256 constant MAX_VALID_LTV = 65535;
uint256 constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535; uint256 constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
@ -44,6 +46,7 @@ library ReserveConfiguration {
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535; uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 constant MAX_VALID_BORROW_CAP = 68719476735; uint256 constant MAX_VALID_BORROW_CAP = 68719476735;
uint256 constant MAX_VALID_SUPPLY_CAP = 68719476735; uint256 constant MAX_VALID_SUPPLY_CAP = 68719476735;
uint256 constant MAX_VALID_EXPOSURE_CAP = 68719476735;
/** /**
* @dev Sets the Loan to Value of the reserve * @dev Sets the Loan to Value of the reserve
@ -190,7 +193,7 @@ library ReserveConfiguration {
return (self.data & ~FROZEN_MASK) != 0; return (self.data & ~FROZEN_MASK) != 0;
} }
/** /**
* @dev Sets the paused state of the reserve * @dev Sets the paused state of the reserve
* @param self The reserve configuration * @param self The reserve configuration
* @param paused The paused state * @param paused The paused state
@ -347,6 +350,33 @@ library ReserveConfiguration {
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION; return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
} }
/**
* @dev Sets the exposure cap of the reserve
* @param self The reserve configuration
* @param exposureCap The exposure cap
**/
function setExposureCap(DataTypes.ReserveConfigurationMap memory self, uint256 exposureCap)
internal
pure
{
require(exposureCap <= MAX_VALID_EXPOSURE_CAP, Errors.RC_INVALID_EXPOSURE_CAP);
self.data = (self.data & EXPOSURE_CAP_MASK) | (exposureCap << EXPOSURE_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the exposure cap of the reserve
* @param self The reserve configuration
* @return The exposure cap
**/
function getExposureCap(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (uint256)
{
return (self.data & ~EXPOSURE_CAP_MASK) >> EXPOSURE_CAP_START_BIT_POSITION;
}
/** /**
* @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
@ -409,13 +439,18 @@ library ReserveConfiguration {
function getCaps(DataTypes.ReserveConfigurationMap storage self) function getCaps(DataTypes.ReserveConfigurationMap storage self)
internal internal
view view
returns (uint256, uint256) returns (
uint256,
uint256,
uint256
)
{ {
uint256 dataLocal = self.data; uint256 dataLocal = self.data;
return ( return (
(dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION, (dataLocal & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION (dataLocal & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION,
(dataLocal & ~EXPOSURE_CAP_MASK) >> EXPOSURE_CAP_START_BIT_POSITION
); );
} }
@ -452,11 +487,16 @@ library ReserveConfiguration {
function getCapsMemory(DataTypes.ReserveConfigurationMap memory self) function getCapsMemory(DataTypes.ReserveConfigurationMap memory self)
internal internal
pure pure
returns (uint256, uint256) returns (
uint256,
uint256,
uint256
)
{ {
return ( return (
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION, (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION,
(self.data & ~EXPOSURE_CAP_MASK) >> EXPOSURE_CAP_START_BIT_POSITION
); );
} }
@ -510,4 +550,17 @@ library ReserveConfiguration {
{ {
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION; return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
} }
/**
* @dev Gets the exposure cap of the reserve from a memory object
* @param self The reserve configuration
* @return The exposure cap
**/
function getExposureCapMemory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (uint256)
{
return (self.data & ~EXPOSURE_CAP_MASK) >> EXPOSURE_CAP_START_BIT_POSITION;
}
} }

View File

@ -109,6 +109,7 @@ library Errors {
string public constant LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85'; string public constant LPC_CALLER_NOT_EMERGENCY_OR_POOL_ADMIN = '85';
string public constant VL_RESERVE_PAUSED = '86'; string public constant VL_RESERVE_PAUSED = '86';
string public constant LPC_CALLER_NOT_RISK_OR_POOL_ADMIN = '87'; string public constant LPC_CALLER_NOT_RISK_OR_POOL_ADMIN = '87';
string public constant RC_INVALID_EXPOSURE_CAP = '88';
enum CollateralManagerErrors { enum CollateralManagerErrors {
NO_ERROR, NO_ERROR,

View File

@ -40,7 +40,8 @@ library DataTypes {
//bit 61-63: reserved //bit 61-63: reserved
//bit 64-79: reserve factor //bit 64-79: reserve factor
//bit 80-115 borrow cap, borrowCap == 0 => disabled //bit 80-115 borrow cap, borrowCap == 0 => disabled
//bit 116-152 supply cap, supplyCap == 0 => disabled //bit 116-151 supply cap, supplyCap == 0 => disabled
//bit 152-185 exposure cap, exposureCap == 0 => disabled
uint256 data; uint256 data;
} }