From 24a4980496b5ac5d3cf09b5660560fb320b4aeb2 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 15:51:48 +0200 Subject: [PATCH 1/2] Refactored reservesList to a mapping --- contracts/interfaces/ILendingPool.sol | 2 +- contracts/lendingpool/LendingPool.sol | 45 +++++++++++++------ .../LendingPoolCollateralManager.sol | 9 +++- contracts/lendingpool/LendingPoolStorage.sol | 18 ++------ contracts/libraries/logic/GenericLogic.sol | 10 +++-- contracts/libraries/logic/ValidationLogic.sol | 12 +++-- contracts/misc/AaveProtocolTestHelpers.sol | 4 +- contracts/misc/WalletBalanceProvider.sol | 2 +- deployed-contracts.json | 6 +-- 9 files changed, 65 insertions(+), 43 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 66d4542a..3fc461b6 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -428,7 +428,7 @@ interface ILendingPool { uint256 amount ) external view returns (bool); - function getReserves() external view returns (address[] memory); + function getReservesList() external view returns (address[] memory); /** * @dev Set the _pause state diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 6afb3eed..1a5b8152 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -144,6 +144,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -424,6 +425,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -753,6 +755,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -793,10 +796,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage usageAsCollateralEnabled = _usersConfig[user].isUsingAsCollateral(reserve.id); } - function getReserves() external override view returns (address[] memory) { - return _reservesList; - } - receive() external payable { revert(); } @@ -889,6 +888,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, userConfig, _reservesList, + _reservesCount, oracle ); @@ -948,16 +948,13 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @dev adds a reserve to the array of the _reserves address **/ function _addReserveToList(address asset) internal { - bool reserveAlreadyAdded = false; - require(_reservesList.length < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); - for (uint256 i = 0; i < _reservesList.length; i++) - if (_reservesList[i] == asset) { - reserveAlreadyAdded = true; - } - if (!reserveAlreadyAdded) { - _reserves[asset].id = uint8(_reservesList.length); - _reservesList.push(asset); - } + + require(_reservesCount < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); + + _reserves[asset].id = uint8(_reservesCount); + _reservesList[_reservesCount] = asset; + + _reservesCount++; } /** @@ -1004,6 +1001,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); } @@ -1029,4 +1027,23 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage function paused() external override view returns (bool) { return _paused; } + + /** + * @dev returns the list of the initialized reserves + **/ + function getReservesList() external override view returns (address[] memory) { + address[] memory _activeReserves = new address[](_reservesCount); + + for(uint256 i = 0; i < _reservesCount; i++){ + _activeReserves[i] = _reservesList[i]; + } + return _activeReserves; + } + + /** + * @dev returns the addresses provider + **/ + function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { + return _addressesProvider; + } } diff --git a/contracts/lendingpool/LendingPoolCollateralManager.sol b/contracts/lendingpool/LendingPoolCollateralManager.sol index 75f4f659..1e5488a4 100644 --- a/contracts/lendingpool/LendingPoolCollateralManager.sol +++ b/contracts/lendingpool/LendingPoolCollateralManager.sol @@ -154,6 +154,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -325,6 +326,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[user], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); @@ -412,7 +414,11 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor vars.actualAmountToLiquidate, 0 ); - IERC20(principal).safeTransferFrom(receiver, vars.principalAToken, vars.actualAmountToLiquidate); + IERC20(principal).safeTransferFrom( + receiver, + vars.principalAToken, + vars.actualAmountToLiquidate + ); if (vars.userVariableDebt >= vars.actualAmountToLiquidate) { IVariableDebtToken(debtReserve.variableDebtTokenAddress).burn( @@ -528,6 +534,7 @@ contract LendingPoolCollateralManager is VersionedInitializable, LendingPoolStor _reserves, _usersConfig[msg.sender], _reservesList, + _reservesCount, _addressesProvider.getPriceOracle() ); diff --git a/contracts/lendingpool/LendingPoolStorage.sol b/contracts/lendingpool/LendingPoolStorage.sol index 1f1e6d2e..c2fb6111 100644 --- a/contracts/lendingpool/LendingPoolStorage.sol +++ b/contracts/lendingpool/LendingPoolStorage.sol @@ -18,22 +18,12 @@ contract LendingPoolStorage { // debt token address => user who gives allowance => user who receives allowance => amount mapping(address => mapping(address => mapping(address => uint256))) internal _borrowAllowance; - address[] internal _reservesList; + // the list of the available reserves, structured as a mapping for gas savings reasons + mapping(uint256 => address) internal _reservesList; + + uint256 internal _reservesCount; bool internal _flashLiquidationLocked; bool internal _paused; - /** - * @dev returns the list of the initialized reserves - **/ - function getReservesList() external view returns (address[] memory) { - return _reservesList; - } - - /** - * @dev returns the addresses provider - **/ - function getAddressesProvider() external view returns (ILendingPoolAddressesProvider) { - return _addressesProvider; - } } diff --git a/contracts/libraries/logic/GenericLogic.sol b/contracts/libraries/logic/GenericLogic.sol index d1a7d6ce..5c7dc3dc 100644 --- a/contracts/libraries/logic/GenericLogic.sol +++ b/contracts/libraries/logic/GenericLogic.sol @@ -58,7 +58,8 @@ library GenericLogic { uint256 amount, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map calldata userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view returns (bool) { if (!userConfig.isBorrowingAny() || !userConfig.isUsingAsCollateral(reservesData[asset].id)) { @@ -79,7 +80,7 @@ library GenericLogic { , vars.avgLiquidationThreshold, - ) = calculateUserAccountData(user, reservesData, userConfig, reserves, oracle); + ) = calculateUserAccountData(user, reservesData, userConfig, reserves, reservesCount, oracle); if (vars.borrowBalanceETH == 0) { return true; //no borrows - no reasons to block the transfer @@ -149,7 +150,8 @@ library GenericLogic { address user, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map memory userConfig, - address[] memory reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) internal @@ -167,7 +169,7 @@ library GenericLogic { if (userConfig.isEmpty()) { return (0, 0, 0, 0, uint256(-1)); } - for (vars.i = 0; vars.i < reserves.length; vars.i++) { + for (vars.i = 0; vars.i < reservesCount; vars.i++) { if (!userConfig.isUsingAsCollateralOrBorrowing(vars.i)) { continue; } diff --git a/contracts/libraries/logic/ValidationLogic.sol b/contracts/libraries/logic/ValidationLogic.sol index 4ffa49f2..ee13232b 100644 --- a/contracts/libraries/logic/ValidationLogic.sol +++ b/contracts/libraries/logic/ValidationLogic.sol @@ -54,7 +54,8 @@ library ValidationLogic { uint256 userBalance, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { require(amount > 0, Errors.AMOUNT_NOT_GREATER_THAN_0); @@ -69,6 +70,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ), Errors.TRANSFER_NOT_ALLOWED @@ -119,7 +121,8 @@ library ValidationLogic { uint256 maxStableLoanPercent, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { ValidateBorrowLocalVars memory vars; @@ -154,6 +157,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ); @@ -298,7 +302,8 @@ library ValidationLogic { address reserveAddress, mapping(address => ReserveLogic.ReserveData) storage reservesData, UserConfiguration.Map storage userConfig, - address[] calldata reserves, + mapping(uint256 => address) storage reserves, + uint256 reservesCount, address oracle ) external view { uint256 underlyingBalance = IERC20(reserve.aTokenAddress).balanceOf(msg.sender); @@ -313,6 +318,7 @@ library ValidationLogic { reservesData, userConfig, reserves, + reservesCount, oracle ), Errors.DEPOSIT_ALREADY_IN_USE diff --git a/contracts/misc/AaveProtocolTestHelpers.sol b/contracts/misc/AaveProtocolTestHelpers.sol index 7b91bec2..75778f42 100644 --- a/contracts/misc/AaveProtocolTestHelpers.sol +++ b/contracts/misc/AaveProtocolTestHelpers.sol @@ -20,7 +20,7 @@ contract AaveProtocolTestHelpers { function getAllReservesTokens() external view returns (TokenData[] memory) { ILendingPool pool = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); TokenData[] memory reservesTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { reservesTokens[i] = TokenData({ @@ -35,7 +35,7 @@ contract AaveProtocolTestHelpers { function getAllATokens() external view returns (TokenData[] memory) { ILendingPool pool = ILendingPool(ADDRESSES_PROVIDER.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); TokenData[] memory aTokens = new TokenData[](reserves.length); for (uint256 i = 0; i < reserves.length; i++) { (address aTokenAddress, , ) = pool.getReserveTokensAddresses(reserves[i]); diff --git a/contracts/misc/WalletBalanceProvider.sol b/contracts/misc/WalletBalanceProvider.sol index c52b5f21..1c46922a 100644 --- a/contracts/misc/WalletBalanceProvider.sol +++ b/contracts/misc/WalletBalanceProvider.sol @@ -86,7 +86,7 @@ contract WalletBalanceProvider { { ILendingPool pool = ILendingPool(_provider.getLendingPool()); - address[] memory reserves = pool.getReserves(); + address[] memory reserves = pool.getReservesList(); uint256[] memory balances = new uint256[](reserves.length); diff --git a/deployed-contracts.json b/deployed-contracts.json index dd305039..ca9221df 100644 --- a/deployed-contracts.json +++ b/deployed-contracts.json @@ -608,7 +608,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xEcb928A3c079a1696Aa5244779eEc3dE1717fACd", + "address": "0xa89E20284Bd638F31b0011D0fC754Fc9d2fa73e3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -636,7 +636,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0xDFbeeed692AA81E7f86E72F7ACbEA2A1C4d63544", + "address": "0xaA935993065F2dDB1d13623B1941C7AEE3A60F23", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { @@ -650,7 +650,7 @@ "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "localhost": { - "address": "0x5191aA68c7dB195181Dd2441dBE23A48EA24b040", + "address": "0x35A2624888e207e4B3434E9a9E250bF6Ee68FeA3", "deployer": "0xc783df8a850f42e7F7e57013759C285caa701eB6" }, "coverage": { From 9fdfc8bf26e94ec230889502cc92477dbd37bde7 Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 6 Oct 2020 18:20:44 +0200 Subject: [PATCH 2/2] Added check if the reserve was already added --- contracts/lendingpool/LendingPool.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/lendingpool/LendingPool.sol b/contracts/lendingpool/LendingPool.sol index 1a5b8152..6016ee95 100644 --- a/contracts/lendingpool/LendingPool.sol +++ b/contracts/lendingpool/LendingPool.sol @@ -951,10 +951,14 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage require(_reservesCount < MAX_NUMBER_RESERVES, Errors.NO_MORE_RESERVES_ALLOWED); + bool reserveAlreadyAdded = _reserves[asset].id != 0 || _reservesList[0]==asset; + + if(!reserveAlreadyAdded){ _reserves[asset].id = uint8(_reservesCount); _reservesList[_reservesCount] = asset; _reservesCount++; + } } /**