feat-refactor: added supplyCap and refactored borrowCap

This commit is contained in:
Hadrien Charlanes 2021-04-30 16:14:59 +02:00
parent cd2eb0af58
commit f624783a36
11 changed files with 125 additions and 24 deletions

View File

@ -32,6 +32,7 @@ contract ATokensAndRatesHelper is Ownable {
uint256 liquidationBonus;
uint256 reserveFactor;
uint256 borrowCap;
uint256 supplyCap;
bool stableBorrowingEnabled;
}
@ -79,6 +80,7 @@ contract ATokensAndRatesHelper is Ownable {
inputParams[i].borrowCap,
inputParams[i].stableBorrowingEnabled
);
configurator.setSupplyCap(inputParams[i].asset, inputParams[i].supplyCap);
configurator.setReserveFactor(inputParams[i].asset, inputParams[i].reserveFactor);
}
}

View File

@ -134,6 +134,13 @@ interface ILendingPoolConfigurator {
**/
event BorrowCapChanged(address indexed asset, uint256 borrowCap);
/**
* @dev Emitted when the supply cap of a reserve is updated
* @param asset The address of the underlying asset of the reserve
* @param supplyCap The new supply cap
**/
event SupplyCapChanged(address indexed asset, uint256 supplyCap);
/**
* @dev Emitted when the reserve decimals are updated
* @param asset The address of the underlying asset of the reserve

View File

@ -64,6 +64,7 @@ contract AaveProtocolDataProvider {
return aTokens;
}
// not returning borrow and supply caps for compatibility
function getReserveConfigurationData(address asset)
external
view
@ -83,7 +84,7 @@ contract AaveProtocolDataProvider {
DataTypes.ReserveConfigurationMap memory configuration =
ILendingPool(ADDRESSES_PROVIDER.getLendingPool()).getConfiguration(asset);
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor, ) =
(ltv, liquidationThreshold, liquidationBonus, decimals, reserveFactor) =
configuration.getParamsMemory();
(isActive, isFrozen, borrowingEnabled, stableBorrowRateEnabled) =
@ -92,14 +93,14 @@ contract AaveProtocolDataProvider {
usageAsCollateralEnabled = liquidationThreshold > 0;
}
function getReserveBorrowCap(address asset)
function getReserveCaps(address asset)
external
view
returns (uint256 borrowCap) {
returns (uint256 borrowCap, uint256 supplyCap) {
(, , , , , borrowCap) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
(borrowCap, supplyCap) = ILendingPool(ADDRESSES_PROVIDER.getLendingPool())
.getConfiguration(asset)
.getParamsMemory();
.getCapsMemory();
}
function getReserveData(address asset)

View File

@ -104,9 +104,12 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
reserveData.reserveLiquidationThreshold,
reserveData.reserveLiquidationBonus,
reserveData.decimals,
reserveData.reserveFactor,
reserveData.borrowCap
reserveData.reserveFactor
) = baseData.configuration.getParamsMemory();
(
reserveData.borrowCap,
reserveData.supplyCap
) = baseData.configuration.getCapsMemory();
(
reserveData.isActive,
reserveData.isFrozen,

View File

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

View File

@ -286,7 +286,7 @@ contract LendingPoolCollateralManager is
vars.collateralPrice = oracle.getAssetPrice(collateralAsset);
vars.debtAssetPrice = oracle.getAssetPrice(debtAsset);
(, , vars.liquidationBonus, vars.collateralDecimals, , ) = collateralReserve
(, , vars.liquidationBonus, vars.collateralDecimals, ) = collateralReserve
.configuration
.getParams();
vars.debtAssetDecimals = debtReserve.configuration.getDecimals();

View File

@ -149,7 +149,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
(, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
bytes memory encodedCall = abi.encodeWithSelector(
IInitializableAToken.initialize.selector,
@ -180,7 +180,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
(, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
bytes memory encodedCall = abi.encodeWithSelector(
IInitializableDebtToken.initialize.selector,
@ -217,7 +217,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset);
(, , , uint256 decimals, , ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
(, , , uint256 decimals, ) = cachedPool.getConfiguration(input.asset).getParamsMemory();
bytes memory encodedCall = abi.encodeWithSelector(
IInitializableDebtToken.initialize.selector,
@ -446,6 +446,21 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit BorrowCapChanged(asset, borrowCap);
}
/**
* @dev Updates the supply cap of a reserve
* @param asset The address of the underlying asset of the reserve
* @param supplyCap The new supply of the reserve
**/
function setSupplyCap(address asset, uint256 supplyCap) external onlyPoolAdmin {
DataTypes.ReserveConfigurationMap memory currentConfig = pool.getConfiguration(asset);
currentConfig.setSupplyCap(supplyCap);
pool.setConfiguration(asset, currentConfig.data);
emit SupplyCapChanged(asset, supplyCap);
}
/**
* @dev Sets the interest rate strategy of a reserve
* @param asset The address of the underlying asset of the reserve

View File

@ -20,6 +20,7 @@ library ReserveConfiguration {
uint256 constant STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant SUPPLY_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFF; // prettier-ignore
/// @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;
@ -31,6 +32,7 @@ library ReserveConfiguration {
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
uint256 constant RESERVE_FACTOR_START_BIT_POSITION = 64;
uint256 constant BORROW_CAP_START_BIT_POSITION = 80;
uint256 constant SUPPLY_CAP_START_BIT_POSITION = 128;
uint256 constant MAX_VALID_LTV = 65535;
uint256 constant MAX_VALID_LIQUIDATION_THRESHOLD = 65535;
@ -38,6 +40,7 @@ library ReserveConfiguration {
uint256 constant MAX_VALID_DECIMALS = 255;
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 constant MAX_VALID_BORROW_CAP = 281474976710655;
uint256 constant MAX_VALID_SUPPLY_CAP = 281474976710655;
/**
* @dev Sets the Loan to Value of the reserve
@ -296,6 +299,35 @@ library ReserveConfiguration {
return (self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION;
}
/**
* @dev Sets the supply cap of the reserve
* @param self The reserve configuration
* @param supplyCap The supply cap
**/
function setSupplyCap(DataTypes.ReserveConfigurationMap memory self, uint256 supplyCap)
internal
pure
{
require(supplyCap <= MAX_VALID_SUPPLY_CAP, Errors.RC_INVALID_SUPPLY_CAP);
self.data =
(self.data & SUPPLY_CAP_MASK) |
(supplyCap << SUPPLY_CAP_START_BIT_POSITION);
}
/**
* @dev Gets the supply cap of the reserve
* @param self The reserve configuration
* @return The supply cap
**/
function getSupplyCap(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (uint256)
{
return (self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION;
}
/**
* @dev Gets the configuration flags of the reserve
* @param self The reserve configuration
@ -324,7 +356,7 @@ library ReserveConfiguration {
/**
* @dev Gets the configuration paramters of the reserve from storage
* @param self The reserve configuration
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor and borrow cap.
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor
**/
function getParams(DataTypes.ReserveConfigurationMap storage self)
internal
@ -334,7 +366,6 @@ library ReserveConfiguration {
uint256,
uint256,
uint256,
uint256,
uint256
)
{
@ -345,15 +376,35 @@ library ReserveConfiguration {
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION,
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
);
}
/**
* @dev Gets the caps paramters of the reserve from storage
* @param self The reserve configuration
* @return The state params representing borrow cap and supply cap.
**/
function getCaps(DataTypes.ReserveConfigurationMap storage self)
internal
view
returns (
uint256,
uint256
)
{
uint256 dataLocal = self.data;
return (
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}
/**
* @dev Gets the configuration paramters of the reserve from a memory object
* @param self The reserve configuration
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor, borrow cap
* @return The state params representing ltv, liquidation threshold, liquidation bonus, reserve decimals, reserve factor
**/
function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
internal
@ -363,7 +414,6 @@ library ReserveConfiguration {
uint256,
uint256,
uint256,
uint256,
uint256
)
{
@ -372,8 +422,26 @@ library ReserveConfiguration {
(self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION,
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION
(self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
);
}
/**
* @dev Gets the caps paramters of the reserve from a memory object
* @param self The reserve configuration
* @return The state params borrow cap and supply cap
**/
function getCapsMemory(DataTypes.ReserveConfigurationMap memory self)
internal
pure
returns (
uint256,
uint256
)
{
return (
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_START_BIT_POSITION,
(self.data & ~SUPPLY_CAP_MASK) >> SUPPLY_CAP_START_BIT_POSITION
);
}

View File

@ -105,6 +105,8 @@ library Errors {
string public constant SDT_BURN_EXCEEDS_BALANCE = '80';
string public constant VL_BORROW_CAP_EXCEEDED = '81';
string public constant RC_INVALID_BORROW_CAP = '82';
string public constant VL_SUPPLY_CAP_EXCEEDED = '83';
string public constant RC_INVALID_SUPPLY_CAP = '84';
enum CollateralManagerErrors {
NO_ERROR,

View File

@ -68,7 +68,7 @@ library GenericLogic {
balanceDecreaseAllowedLocalVars memory vars;
(, vars.liquidationThreshold, , vars.decimals, , ) = reservesData[asset]
(, vars.liquidationThreshold, , vars.decimals, ) = reservesData[asset]
.configuration
.getParams();
@ -178,7 +178,7 @@ library GenericLogic {
vars.currentReserveAddress = reserves[vars.i];
DataTypes.ReserveData storage currentReserve = reservesData[vars.currentReserveAddress];
(vars.ltv, vars.liquidationThreshold, , vars.decimals, , ) = currentReserve
(vars.ltv, vars.liquidationThreshold, , vars.decimals, ) = currentReserve
.configuration
.getParams();

View File

@ -178,7 +178,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true/*strategyWETH.stableBorrowRateEnabled*/);
expect(stableBorrowRateEnabled).to.be.equal(true /*strategyWETH.stableBorrowRateEnabled*/);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(variableBorrowIndex.toString()).to.be.equal(RAY);
@ -195,7 +195,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv;
await expect(
configurator.connect(users[2].signer).enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true),
configurator
.connect(users[2].signer)
.enableBorrowingOnReserve(weth.address, MAX_BORROW_CAP, true),
CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(CALLER_NOT_POOL_ADMIN);
});
@ -250,7 +252,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus);
expect(stableBorrowRateEnabled).to.be.equal(true/*strategyWETH.stableBorrowRateEnabled*/);
expect(stableBorrowRateEnabled).to.be.equal(true /*strategyWETH.stableBorrowRateEnabled*/);
expect(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
});