From 138446bb5139174f6c1a84c0c8346daacee91c36 Mon Sep 17 00:00:00 2001 From: kartojal Date: Mon, 10 Jan 2022 17:30:44 +0100 Subject: [PATCH] fix: Revert reserves cap change due breaking change at ILendingPool interface with current deployed markets --- .../protocol/lendingpool/LendingPool.sol | 4 +- .../configuration/UserConfiguration.sol | 51 ++---- .../protocol/libraries/types/DataTypes.sol | 2 +- test-suites/test-aave/many-asset.spec.ts | 164 ------------------ 4 files changed, 17 insertions(+), 204 deletions(-) delete mode 100644 test-suites/test-aave/many-asset.spec.ts diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 304fa3a6..8e38650c 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -87,7 +87,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _addressesProvider = provider; _maxStableRateBorrowSizePercent = 2500; _flashLoanPremiumTotal = 9; - _maxNumberOfReserves = UserConfiguration._maxReserves; + _maxNumberOfReserves = 128; } /** @@ -713,7 +713,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage } /** - * @dev Returns the fee on flash loans + * @dev Returns the fee on flash loans */ function FLASHLOAN_PREMIUM_TOTAL() public view returns (uint256) { return _flashLoanPremiumTotal; diff --git a/contracts/protocol/libraries/configuration/UserConfiguration.sol b/contracts/protocol/libraries/configuration/UserConfiguration.sol index fed8ffda..2994f05d 100644 --- a/contracts/protocol/libraries/configuration/UserConfiguration.sol +++ b/contracts/protocol/libraries/configuration/UserConfiguration.sol @@ -13,9 +13,6 @@ library UserConfiguration { uint256 internal constant BORROWING_MASK = 0x5555555555555555555555555555555555555555555555555555555555555555; - uint256 internal constant _maxReserves = 256; - uint256 internal constant _indexCount = _maxReserves / 128 + ((_maxReserves % 128 > 0) ? 1 : 0); - /** * @dev Sets if the user is borrowing the reserve identified by reserveIndex * @param self The configuration object @@ -27,11 +24,9 @@ library UserConfiguration { uint256 reserveIndex, bool borrowing ) internal { - require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX); - uint256 index = reserveIndex / 128; - reserveIndex = reserveIndex % 128; - self.data[index] = - (self.data[index] & ~(1 << (reserveIndex * 2))) | + require(reserveIndex < 128, Errors.UL_INVALID_INDEX); + self.data = + (self.data & ~(1 << (reserveIndex * 2))) | (uint256(borrowing ? 1 : 0) << (reserveIndex * 2)); } @@ -46,11 +41,9 @@ library UserConfiguration { uint256 reserveIndex, bool usingAsCollateral ) internal { - require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX); - uint256 index = reserveIndex / 128; - reserveIndex = reserveIndex % 128; - self.data[index] = - (self.data[index] & ~(1 << (reserveIndex * 2 + 1))) | + require(reserveIndex < 128, Errors.UL_INVALID_INDEX); + self.data = + (self.data & ~(1 << (reserveIndex * 2 + 1))) | (uint256(usingAsCollateral ? 1 : 0) << (reserveIndex * 2 + 1)); } @@ -64,10 +57,8 @@ library UserConfiguration { DataTypes.UserConfigurationMap memory self, uint256 reserveIndex ) internal pure returns (bool) { - require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX); - uint256 index = reserveIndex / 128; - reserveIndex = reserveIndex % 128; - return (self.data[index] >> (reserveIndex * 2)) & 3 != 0; + require(reserveIndex < 128, Errors.UL_INVALID_INDEX); + return (self.data >> (reserveIndex * 2)) & 3 != 0; } /** @@ -81,10 +72,8 @@ library UserConfiguration { pure returns (bool) { - require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX); - uint256 index = reserveIndex / 128; - reserveIndex = reserveIndex % 128; - return (self.data[index] >> (reserveIndex * 2)) & 1 != 0; + require(reserveIndex < 128, Errors.UL_INVALID_INDEX); + return (self.data >> (reserveIndex * 2)) & 1 != 0; } /** @@ -98,10 +87,8 @@ library UserConfiguration { pure returns (bool) { - require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX); - uint256 index = reserveIndex / 128; - reserveIndex = reserveIndex % 128; - return (self.data[index] >> (reserveIndex * 2 + 1)) & 1 != 0; + require(reserveIndex < 128, Errors.UL_INVALID_INDEX); + return (self.data >> (reserveIndex * 2 + 1)) & 1 != 0; } /** @@ -110,12 +97,7 @@ library UserConfiguration { * @return True if the user has been borrowing any reserve, false otherwise **/ function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { - for (uint8 i = 0; i < _indexCount; i++) { - if (self.data[i] & BORROWING_MASK != 0) { - return true; - } - } - return false; + return self.data & BORROWING_MASK != 0; } /** @@ -124,11 +106,6 @@ library UserConfiguration { * @return True if the user has been borrowing any reserve, false otherwise **/ function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) { - for (uint8 i = 0; i < _indexCount; i++) { - if (self.data[i] != 0) { - return false; - } - } - return true; + return self.data == 0; } } diff --git a/contracts/protocol/libraries/types/DataTypes.sol b/contracts/protocol/libraries/types/DataTypes.sol index b3b76b15..a19e5efc 100644 --- a/contracts/protocol/libraries/types/DataTypes.sol +++ b/contracts/protocol/libraries/types/DataTypes.sol @@ -42,7 +42,7 @@ library DataTypes { } struct UserConfigurationMap { - uint256[2] data; // size is _maxReserves / 128 + ((_maxReserves % 128 > 0) ? 1 : 0), but need to be literal + uint256 data; } enum InterestRateMode {NONE, STABLE, VARIABLE} diff --git a/test-suites/test-aave/many-asset.spec.ts b/test-suites/test-aave/many-asset.spec.ts deleted file mode 100644 index 3408e549..00000000 --- a/test-suites/test-aave/many-asset.spec.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { TestEnv, makeSuite } from './helpers/make-suite'; -import { - APPROVAL_AMOUNT_LENDING_POOL, - MAX_UINT_AMOUNT, - RAY, - ZERO_ADDRESS, -} from '../../helpers/constants'; -import { - convertToCurrencyDecimals, - getContractAddressWithJsonFallback, -} from '../../helpers/contracts-helpers'; -import { eContractid, ProtocolErrors, RateMode } from '../../helpers/types'; -import { strategyWETH } from '../../markets/aave/reservesConfigs'; -import { - deployATokenImplementations, - deployMintableERC20, - deployValidationLogic, -} from '../../helpers/contracts-deployments'; -import { getATokenExtraParams } from '../../helpers/init-helpers'; -import { ConfigNames } from '../../helpers/configuration'; -import { zeroAddress } from 'hardhat/node_modules/ethereumjs-util'; -import AaveConfig from '../../markets/aave'; -import { getATokensAndRatesHelper } from '../../helpers/contracts-getters'; -import { config } from 'process'; -import { parseEther } from '@ethersproject/units'; -import exp from 'constants'; - -const { expect } = require('chai'); - -makeSuite('Adding > 128 asset to many-asset configured pool', (testEnv: TestEnv) => { - const tokens = {}; - - before('setup', async () => { - const { pool, dai, configurator, deployer, oracle } = testEnv; - const atokenAndRatesDeployer = await getATokensAndRatesHelper(); - - const reservesCount = await pool.getReservesList(); - - const daiData = await pool.getReserveData(dai.address); - const poolName = ConfigNames.Aave; - - const { - ATokenNamePrefix, - StableDebtTokenNamePrefix, - VariableDebtTokenNamePrefix, - SymbolPrefix, - } = AaveConfig; - - // Create tokens - let tokenInitParams = []; - let reserveInitParams = []; - - const aTokenImplAddress = await getContractAddressWithJsonFallback( - eContractid.AToken, - poolName - ); - const stableDebtImplAddress = await getContractAddressWithJsonFallback( - eContractid.StableDebtToken, - poolName - ); - const variableDebtImplAddress = await getContractAddressWithJsonFallback( - eContractid.VariableDebtToken, - poolName - ); - - const daiPrice = await oracle.getAssetPrice(dai.address); - - // All assets will be initialized with the same price as Dai. - for (let i = reservesCount.length; i < 140; i++) { - const tokenName = `RealT-${i}`; - const token = await deployMintableERC20([tokenName, tokenName, '18']); - tokens[tokenName] = token; - - tokenInitParams.push({ - aTokenImpl: aTokenImplAddress, - stableDebtTokenImpl: stableDebtImplAddress, - variableDebtTokenImpl: variableDebtImplAddress, - underlyingAssetDecimals: 18, - interestRateStrategyAddress: daiData.interestRateStrategyAddress, - underlyingAsset: token.address, - treasury: ZERO_ADDRESS, - incentivesController: ZERO_ADDRESS, - underlyingAssetName: tokenName, - aTokenName: `${ATokenNamePrefix} ${tokenName}`, - aTokenSymbol: `a${SymbolPrefix}${tokenName}`, - variableDebtTokenName: `${VariableDebtTokenNamePrefix} ${SymbolPrefix}${tokenName}`, - variableDebtTokenSymbol: `variableDebt${SymbolPrefix}${tokenName}`, - stableDebtTokenName: `${StableDebtTokenNamePrefix} ${tokenName}`, - stableDebtTokenSymbol: `stableDebt${SymbolPrefix}${tokenName}`, - params: '0x10', - }); - - reserveInitParams.push({ - asset: token.address, - baseLTV: 5000, - liquidationThreshold: 8000, - liquidationBonus: 10500, - reserveFactor: 1000, - stableBorrowingEnabled: false, - borrowingEnabled: true, - }); - - if (tokenInitParams.length == 2 || i == 139) { - await configurator.batchInitReserve(tokenInitParams); - - for (let j = 0; j < reserveInitParams.length; j++) { - let params = reserveInitParams[j]; - await configurator - .connect(deployer.signer) - .configureReserveAsCollateral( - params.asset, - params.baseLTV, - params.liquidationThreshold, - params.liquidationBonus - ); - await configurator.enableBorrowingOnReserve(params.asset, false); - await oracle.setAssetPrice(params.asset, daiPrice); - } - tokenInitParams = []; - reserveInitParams = []; - } - } - }); - - it('Check that pool contains >128 assets', async () => { - const { pool } = testEnv; - const reservesCount = await pool.getReservesList(); - expect(reservesCount.length).to.be.gt(128); - }); - - it('Add collateral and borrow asset 130', async () => { - const { - users: [, user, funder], - weth, - pool, - } = testEnv; - - const realT130 = tokens[`RealT-${130}`]; - - const assetdata = await pool.getReserveData(realT130.address); - expect(assetdata.id).to.be.gt(128); - - await realT130.connect(funder.signer).mint(parseEther('100')); - await realT130.connect(funder.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool - .connect(funder.signer) - .deposit(realT130.address, parseEther('100'), funder.address, 0); - - await weth.connect(user.signer).mint(parseEther('1')); - await weth.connect(user.signer).approve(pool.address, MAX_UINT_AMOUNT); - await pool.connect(user.signer).deposit(weth.address, parseEther('1'), user.address, 0); - - const userDataBefore = await pool.getUserAccountData(user.address); - await pool - .connect(user.signer) - .borrow(realT130.address, parseEther('1'), RateMode.Variable, 0, user.address); - const userDataAfter = await pool.getUserAccountData(user.address); - - expect(userDataAfter.totalCollateralETH).to.be.eq(userDataBefore.totalCollateralETH); - expect(userDataBefore.totalDebtETH).to.be.eq(0); - expect(userDataAfter.totalDebtETH).to.be.gt(userDataBefore.totalDebtETH); - expect(userDataAfter.healthFactor).to.be.lt(userDataBefore.healthFactor); - }); -});