mirror of
https://github.com/Instadapp/aave-protocol-v2.git
synced 2024-07-29 21:47:30 +00:00
fix: Revert reserves cap change due breaking change at ILendingPool interface with current deployed markets
This commit is contained in:
parent
d998c2f4c7
commit
138446bb51
|
@ -87,7 +87,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage
|
||||||
_addressesProvider = provider;
|
_addressesProvider = provider;
|
||||||
_maxStableRateBorrowSizePercent = 2500;
|
_maxStableRateBorrowSizePercent = 2500;
|
||||||
_flashLoanPremiumTotal = 9;
|
_flashLoanPremiumTotal = 9;
|
||||||
_maxNumberOfReserves = UserConfiguration._maxReserves;
|
_maxNumberOfReserves = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,9 +13,6 @@ library UserConfiguration {
|
||||||
uint256 internal constant BORROWING_MASK =
|
uint256 internal constant BORROWING_MASK =
|
||||||
0x5555555555555555555555555555555555555555555555555555555555555555;
|
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
|
* @dev Sets if the user is borrowing the reserve identified by reserveIndex
|
||||||
* @param self The configuration object
|
* @param self The configuration object
|
||||||
|
@ -27,11 +24,9 @@ library UserConfiguration {
|
||||||
uint256 reserveIndex,
|
uint256 reserveIndex,
|
||||||
bool borrowing
|
bool borrowing
|
||||||
) internal {
|
) internal {
|
||||||
require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX);
|
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||||
uint256 index = reserveIndex / 128;
|
self.data =
|
||||||
reserveIndex = reserveIndex % 128;
|
(self.data & ~(1 << (reserveIndex * 2))) |
|
||||||
self.data[index] =
|
|
||||||
(self.data[index] & ~(1 << (reserveIndex * 2))) |
|
|
||||||
(uint256(borrowing ? 1 : 0) << (reserveIndex * 2));
|
(uint256(borrowing ? 1 : 0) << (reserveIndex * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +41,9 @@ library UserConfiguration {
|
||||||
uint256 reserveIndex,
|
uint256 reserveIndex,
|
||||||
bool usingAsCollateral
|
bool usingAsCollateral
|
||||||
) internal {
|
) internal {
|
||||||
require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX);
|
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||||
uint256 index = reserveIndex / 128;
|
self.data =
|
||||||
reserveIndex = reserveIndex % 128;
|
(self.data & ~(1 << (reserveIndex * 2 + 1))) |
|
||||||
self.data[index] =
|
|
||||||
(self.data[index] & ~(1 << (reserveIndex * 2 + 1))) |
|
|
||||||
(uint256(usingAsCollateral ? 1 : 0) << (reserveIndex * 2 + 1));
|
(uint256(usingAsCollateral ? 1 : 0) << (reserveIndex * 2 + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,10 +57,8 @@ library UserConfiguration {
|
||||||
DataTypes.UserConfigurationMap memory self,
|
DataTypes.UserConfigurationMap memory self,
|
||||||
uint256 reserveIndex
|
uint256 reserveIndex
|
||||||
) internal pure returns (bool) {
|
) internal pure returns (bool) {
|
||||||
require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX);
|
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||||
uint256 index = reserveIndex / 128;
|
return (self.data >> (reserveIndex * 2)) & 3 != 0;
|
||||||
reserveIndex = reserveIndex % 128;
|
|
||||||
return (self.data[index] >> (reserveIndex * 2)) & 3 != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,10 +72,8 @@ library UserConfiguration {
|
||||||
pure
|
pure
|
||||||
returns (bool)
|
returns (bool)
|
||||||
{
|
{
|
||||||
require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX);
|
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||||
uint256 index = reserveIndex / 128;
|
return (self.data >> (reserveIndex * 2)) & 1 != 0;
|
||||||
reserveIndex = reserveIndex % 128;
|
|
||||||
return (self.data[index] >> (reserveIndex * 2)) & 1 != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,10 +87,8 @@ library UserConfiguration {
|
||||||
pure
|
pure
|
||||||
returns (bool)
|
returns (bool)
|
||||||
{
|
{
|
||||||
require(reserveIndex < _maxReserves, Errors.UL_INVALID_INDEX);
|
require(reserveIndex < 128, Errors.UL_INVALID_INDEX);
|
||||||
uint256 index = reserveIndex / 128;
|
return (self.data >> (reserveIndex * 2 + 1)) & 1 != 0;
|
||||||
reserveIndex = reserveIndex % 128;
|
|
||||||
return (self.data[index] >> (reserveIndex * 2 + 1)) & 1 != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,12 +97,7 @@ library UserConfiguration {
|
||||||
* @return True if the user has been borrowing any reserve, false otherwise
|
* @return True if the user has been borrowing any reserve, false otherwise
|
||||||
**/
|
**/
|
||||||
function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
function isBorrowingAny(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||||
for (uint8 i = 0; i < _indexCount; i++) {
|
return self.data & BORROWING_MASK != 0;
|
||||||
if (self.data[i] & BORROWING_MASK != 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -124,11 +106,6 @@ library UserConfiguration {
|
||||||
* @return True if the user has been borrowing any reserve, false otherwise
|
* @return True if the user has been borrowing any reserve, false otherwise
|
||||||
**/
|
**/
|
||||||
function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
function isEmpty(DataTypes.UserConfigurationMap memory self) internal pure returns (bool) {
|
||||||
for (uint8 i = 0; i < _indexCount; i++) {
|
return self.data == 0;
|
||||||
if (self.data[i] != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ library DataTypes {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UserConfigurationMap {
|
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}
|
enum InterestRateMode {NONE, STABLE, VARIABLE}
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user