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

View File

@ -134,6 +134,13 @@ interface ILendingPoolConfigurator {
**/ **/
event BorrowCapChanged(address indexed asset, uint256 borrowCap); 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 * @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

View File

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

View File

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

View File

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

View File

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

View File

@ -149,7 +149,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); 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( bytes memory encodedCall = abi.encodeWithSelector(
IInitializableAToken.initialize.selector, IInitializableAToken.initialize.selector,
@ -180,7 +180,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); 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( bytes memory encodedCall = abi.encodeWithSelector(
IInitializableDebtToken.initialize.selector, IInitializableDebtToken.initialize.selector,
@ -217,7 +217,7 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
DataTypes.ReserveData memory reserveData = cachedPool.getReserveData(input.asset); 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( bytes memory encodedCall = abi.encodeWithSelector(
IInitializableDebtToken.initialize.selector, IInitializableDebtToken.initialize.selector,
@ -446,6 +446,21 @@ contract LendingPoolConfigurator is VersionedInitializable, ILendingPoolConfigur
emit BorrowCapChanged(asset, borrowCap); 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 * @dev Sets the interest rate strategy of a reserve
* @param asset The address of the underlying asset of the 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 STABLE_BORROWING_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFF; // prettier-ignore
uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore uint256 constant RESERVE_FACTOR_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000FFFFFFFFFFFFFFFF; // prettier-ignore
uint256 constant BORROW_CAP_MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000FFFFFFFFFFFFFFFFFFFF; // 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 /// @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;
@ -31,6 +32,7 @@ library ReserveConfiguration {
uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59; uint256 constant STABLE_BORROWING_ENABLED_START_BIT_POSITION = 59;
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 = 128;
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;
@ -38,6 +40,7 @@ library ReserveConfiguration {
uint256 constant MAX_VALID_DECIMALS = 255; uint256 constant MAX_VALID_DECIMALS = 255;
uint256 constant MAX_VALID_RESERVE_FACTOR = 65535; uint256 constant MAX_VALID_RESERVE_FACTOR = 65535;
uint256 constant MAX_VALID_BORROW_CAP = 281474976710655; uint256 constant MAX_VALID_BORROW_CAP = 281474976710655;
uint256 constant MAX_VALID_SUPPLY_CAP = 281474976710655;
/** /**
* @dev Sets the Loan to Value of the reserve * @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; 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 * @dev Gets the configuration flags of the reserve
* @param self The reserve configuration * @param self The reserve configuration
@ -324,7 +356,7 @@ library ReserveConfiguration {
/** /**
* @dev Gets the configuration paramters of the reserve from storage * @dev Gets the configuration paramters of the reserve from storage
* @param self The reserve configuration * @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) function getParams(DataTypes.ReserveConfigurationMap storage self)
internal internal
@ -334,7 +366,6 @@ library ReserveConfiguration {
uint256, uint256,
uint256, uint256,
uint256, uint256,
uint256,
uint256 uint256
) )
{ {
@ -345,15 +376,35 @@ library ReserveConfiguration {
(dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, (dataLocal & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, (dataLocal & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, (dataLocal & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION, (dataLocal & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_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 * @dev Gets the configuration paramters of the reserve from a memory object
* @param self The reserve configuration * @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) function getParamsMemory(DataTypes.ReserveConfigurationMap memory self)
internal internal
@ -363,7 +414,6 @@ library ReserveConfiguration {
uint256, uint256,
uint256, uint256,
uint256, uint256,
uint256,
uint256 uint256
) )
{ {
@ -372,8 +422,26 @@ library ReserveConfiguration {
(self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION, (self.data & ~LIQUIDATION_THRESHOLD_MASK) >> LIQUIDATION_THRESHOLD_START_BIT_POSITION,
(self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION, (self.data & ~LIQUIDATION_BONUS_MASK) >> LIQUIDATION_BONUS_START_BIT_POSITION,
(self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION, (self.data & ~DECIMALS_MASK) >> RESERVE_DECIMALS_START_BIT_POSITION,
(self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION, (self.data & ~RESERVE_FACTOR_MASK) >> RESERVE_FACTOR_START_BIT_POSITION
(self.data & ~BORROW_CAP_MASK) >> BORROW_CAP_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 SDT_BURN_EXCEEDS_BALANCE = '80';
string public constant VL_BORROW_CAP_EXCEEDED = '81'; string public constant VL_BORROW_CAP_EXCEEDED = '81';
string public constant RC_INVALID_BORROW_CAP = '82'; 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 { enum CollateralManagerErrors {
NO_ERROR, NO_ERROR,

View File

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

View File

@ -178,7 +178,7 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral); expect(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus); 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(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
expect(variableBorrowIndex.toString()).to.be.equal(RAY); expect(variableBorrowIndex.toString()).to.be.equal(RAY);
@ -195,7 +195,9 @@ makeSuite('LendingPoolConfigurator', (testEnv: TestEnv) => {
it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => { it('Check the onlyAaveAdmin on enableBorrowingOnReserve ', async () => {
const { configurator, users, weth } = testEnv; const { configurator, users, weth } = testEnv;
await expect( 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 CALLER_NOT_POOL_ADMIN
).to.be.revertedWith(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(ltv).to.be.equal(strategyWETH.baseLTVAsCollateral);
expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold); expect(liquidationThreshold).to.be.equal(strategyWETH.liquidationThreshold);
expect(liquidationBonus).to.be.equal(strategyWETH.liquidationBonus); 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(reserveFactor).to.be.equal(strategyWETH.reserveFactor);
}); });