From 94293a42db08bf7c9199f93e4097321145a1ef41 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Sat, 19 Dec 2020 19:36:40 +0100 Subject: [PATCH 01/45] Register mock tokens in json database Allows all steps of the aave:dev task to run successfully --- helpers/contracts-deployments.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 322e4f18..739ade34 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -387,6 +387,7 @@ export const deployAllMockTokens = async (verify?: boolean) => { [tokenSymbol, tokenSymbol, configData ? configData.reserveDecimals : decimals], verify ); + await registerContractInJsonDb(tokenSymbol.toUpperCase(), tokens[tokenSymbol]); } return tokens; }; From f9cf541be1932db72fa2a81263d31cbb4890f7e4 Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 23 Mar 2021 18:52:51 +0100 Subject: [PATCH 02/45] Added incentives data to ui helper --- .../interfaces/IAaveIncentivesController.sol | 15 ++++++ contracts/misc/UiPoolDataProvider.sol | 51 ++++++++++++++++++- .../misc/interfaces/IUiPoolDataProvider.sol | 24 ++++++++- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index c049bd77..5125ac7b 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -3,9 +3,24 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IAaveIncentivesController { + struct AssetData { + uint128 emissionPerSecond; + uint128 lastUpdateTimestamp; + uint256 index; + } + + function REWARD_TOKEN() external view returns (address rewardToken); + + function assets(address underlying) external view returns (AssetData memory assets); + function handleAction( address user, uint256 userBalance, uint256 totalSupply ) external; + + function getRewardsBalance(address[] calldata assets, address user) + external + view + returns (uint256); } diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 65fdc4dd..4d61ee8d 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2; import {IERC20Detailed} from '../dependencies/openzeppelin/contracts/IERC20Detailed.sol'; import {ILendingPoolAddressesProvider} from '../interfaces/ILendingPoolAddressesProvider.sol'; +import {IAaveIncentivesController} from '../interfaces/IAaveIncentivesController.sol'; import {IUiPoolDataProvider} from './interfaces/IUiPoolDataProvider.sol'; import {ILendingPool} from '../interfaces/ILendingPool.sol'; import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol'; @@ -43,7 +44,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); } - function getReservesData(ILendingPoolAddressesProvider provider, address user) + function getReservesData( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentivesControllerAddr, + address user + ) external view override @@ -53,6 +58,8 @@ contract UiPoolDataProvider is IUiPoolDataProvider { uint256 ) { + IAaveIncentivesController incentivesController = + IAaveIncentivesController(incentivesControllerAddr); ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); @@ -122,6 +129,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress) ); + // incentives + reserveData.emissionPerSecond = incentivesController + .assets(reserveData.underlyingAsset) + .emissionPerSecond; + if (user != address(0)) { // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -155,6 +167,43 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } } + return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS)); } + + function getUserIncentivesBalance( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentivesControllerAddr, + address user + ) external view override returns (IncentivesDataUser memory) { + IAaveIncentivesController incentivesController = + IAaveIncentivesController(incentivesControllerAddr); + ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); + IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); + address[] memory reserves = lendingPool.getReservesList(); + + // array of atokens that have incentives + address[] memory incentivesATokens = new address[](user != address(0) ? reserves.length : 0); + + for (uint256 i = 0; i < reserves.length; i++) { + DataTypes.ReserveData memory baseData = lendingPool.getReserveData(reserves[i]); + if (user != address(0)) { + incentivesATokens[i] = baseData.aTokenAddress; + } + } + + IncentivesDataUser memory userRewardsBalance; + if (user != address(0)) { + userRewardsBalance.rewardToken = incentivesController.REWARD_TOKEN(); + userRewardsBalance.claimableRewards = incentivesController.getRewardsBalance( + incentivesATokens, + user + ); + userRewardsBalance.rewardTokenDecimals = IERC20Detailed(userRewardsBalance.rewardToken) + .decimals(); + userRewardsBalance.rewardTokenPriceEth = oracle.getAssetPrice(userRewardsBalance.rewardToken); + } + + return (userRewardsBalance); + } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 81a553e8..a1fb7572 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -3,6 +3,7 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; +import {IAaveIncentivesController} from '../../interfaces/IAaveIncentivesController.sol'; interface IUiPoolDataProvider { struct AggregatedReserveData { @@ -41,7 +42,18 @@ interface IUiPoolDataProvider { uint256 variableRateSlope2; uint256 stableRateSlope1; uint256 stableRateSlope2; + // incentives + uint128 emissionPerSecond; } + + struct IncentivesDataUser { + address rewardToken; + uint256 claimableRewards; + uint256 rewardTokenDecimals; + uint256 rewardTokenPriceEth; + uint128 emissionPerSecond; + } + // // struct ReserveData { // uint256 averageStableBorrowRate; @@ -67,7 +79,11 @@ interface IUiPoolDataProvider { // address aTokenAddress; // } - function getReservesData(ILendingPoolAddressesProvider provider, address user) + function getReservesData( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentives, + address user + ) external view returns ( @@ -76,6 +92,12 @@ interface IUiPoolDataProvider { uint256 ); + function getUserIncentivesBalance( + ILendingPoolAddressesProvider provider, + IAaveIncentivesController incentives, + address user + ) external view returns (IncentivesDataUser memory); + // function getUserReservesData(ILendingPoolAddressesProvider provider, address user) // external // view From 83a499f2994a4127d706c0cb5dfa39636ab042b8 Mon Sep 17 00:00:00 2001 From: sendra Date: Fri, 26 Mar 2021 11:08:07 +0100 Subject: [PATCH 03/45] added incentives emission for a / v /s tokens --- contracts/misc/UiPoolDataProvider.sol | 12 ++++++++++-- contracts/misc/interfaces/IUiPoolDataProvider.sol | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 4d61ee8d..15c0e91c 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -130,8 +130,16 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives - reserveData.emissionPerSecond = incentivesController - .assets(reserveData.underlyingAsset) + reserveData.aEmissionPerSecond = incentivesController + .assets(reserveData.aTokenAddress) + .emissionPerSecond; + + reserveData.vEmissionPerSecond = incentivesController + .assets(reserveData.variableDebtTokenAddress) + .emissionPerSecond; + + reserveData.sEmissionPerSecond = incentivesController + .assets(reserveData.stableDebtTokenAddress) .emissionPerSecond; if (user != address(0)) { diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index a1fb7572..41519611 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -43,7 +43,9 @@ interface IUiPoolDataProvider { uint256 stableRateSlope1; uint256 stableRateSlope2; // incentives - uint128 emissionPerSecond; + uint128 aEmissionPerSecond; + uint128 vEmissionPerSecond; + uint128 sEmissionPerSecond; } struct IncentivesDataUser { From 2028631ad74e89fbdd571a26b38cd6bb25ef2570 Mon Sep 17 00:00:00 2001 From: sendra Date: Fri, 26 Mar 2021 13:59:49 +0100 Subject: [PATCH 04/45] fixed not needed casting --- contracts/misc/UiPoolDataProvider.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 15c0e91c..aff0c92d 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -58,8 +58,6 @@ contract UiPoolDataProvider is IUiPoolDataProvider { uint256 ) { - IAaveIncentivesController incentivesController = - IAaveIncentivesController(incentivesControllerAddr); ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); @@ -184,8 +182,6 @@ contract UiPoolDataProvider is IUiPoolDataProvider { IAaveIncentivesController incentivesControllerAddr, address user ) external view override returns (IncentivesDataUser memory) { - IAaveIncentivesController incentivesController = - IAaveIncentivesController(incentivesControllerAddr); ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); From ab8c9a22a912399df402acd8019f028c8cf74f65 Mon Sep 17 00:00:00 2001 From: andyk Date: Fri, 26 Mar 2021 15:06:49 +0200 Subject: [PATCH 05/45] fix typo in incentives controller env --- contracts/misc/UiPoolDataProvider.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index aff0c92d..d9350e6a 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -46,7 +46,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { function getReservesData( ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentivesControllerAddr, + IAaveIncentivesController incentivesController, address user ) external @@ -179,7 +179,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { function getUserIncentivesBalance( ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentivesControllerAddr, + IAaveIncentivesController incentivesController, address user ) external view override returns (IncentivesDataUser memory) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); From e81ddb4e2f66039a819183027dafd36bd609965f Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 29 Mar 2021 17:10:35 +0200 Subject: [PATCH 06/45] Added incentives information to UI data provider contract --- .../interfaces/IAaveIncentivesController.sol | 6 ++ contracts/misc/UiPoolDataProvider.sol | 91 +++++++++++-------- .../misc/interfaces/IUiPoolDataProvider.sol | 33 +++++-- 3 files changed, 85 insertions(+), 45 deletions(-) diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index 5125ac7b..8e9c74a7 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -11,6 +11,8 @@ interface IAaveIncentivesController { function REWARD_TOKEN() external view returns (address rewardToken); + function PRECISION() external view returns (uint8); + function assets(address underlying) external view returns (AssetData memory assets); function handleAction( @@ -23,4 +25,8 @@ interface IAaveIncentivesController { external view returns (uint256); + + function getUserUnclaimedRewards(address _user) external view returns (uint256); + + function getUserAssetData(address user, address asset) external view returns (uint256); } diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index aff0c92d..28b0da0b 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -46,7 +46,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { function getReservesData( ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentivesControllerAddr, + IAaveIncentivesController incentivesController, address user ) external @@ -55,7 +55,8 @@ contract UiPoolDataProvider is IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, - uint256 + uint256, + IncentivesDataUser memory ) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); @@ -128,19 +129,54 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives + // IncentivesAssetData memory aTokenIncentives = incentivesController.assets(reserveData.aTokenAddress); reserveData.aEmissionPerSecond = incentivesController .assets(reserveData.aTokenAddress) .emissionPerSecond; + reserveData.aIncentivesLastUpdateTimestamp = incentivesController + .assets(reserveData.aTokenAddress) + .lastUpdateTimestamp; + reserveData.aTokenIncentivesIndex = incentivesController + .assets(reserveData.aTokenAddress) + .index; - reserveData.vEmissionPerSecond = incentivesController - .assets(reserveData.variableDebtTokenAddress) - .emissionPerSecond; - + // IncentivesAssetData memory sTokenIncentives = incentivesController.assets(reserveData.stableDebtTokenAddress); reserveData.sEmissionPerSecond = incentivesController .assets(reserveData.stableDebtTokenAddress) .emissionPerSecond; + reserveData.sIncentivesLastUpdateTimestamp = incentivesController + .assets(reserveData.stableDebtTokenAddress) + .lastUpdateTimestamp; + reserveData.sTokenIncentivesIndex = incentivesController + .assets(reserveData.stableDebtTokenAddress) + .index; + + // IncentivesAssetData memory vTokenIncentives = incentivesController.assets(reserveData.variableDebtTokenAddress); + reserveData.vEmissionPerSecond = incentivesController + .assets(reserveData.variableDebtTokenAddress) + .emissionPerSecond; + reserveData.vIncentivesLastUpdateTimestamp = incentivesController + .assets(reserveData.variableDebtTokenAddress) + .lastUpdateTimestamp; + reserveData.vTokenIncentivesIndex = incentivesController + .assets(reserveData.variableDebtTokenAddress) + .index; if (user != address(0)) { + // incentives + // userIncentives.incentivesLastUpdated = + userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.aTokenAddress + ); + userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.stableDebtTokenAddress + ); + userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.variableDebtTokenAddress + ); // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; userReservesData[i].scaledATokenBalance = IAToken(reserveData.aTokenAddress) @@ -174,40 +210,21 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } - return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS)); - } - - function getUserIncentivesBalance( - ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentivesControllerAddr, - address user - ) external view override returns (IncentivesDataUser memory) { - ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); - IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); - address[] memory reserves = lendingPool.getReservesList(); - - // array of atokens that have incentives - address[] memory incentivesATokens = new address[](user != address(0) ? reserves.length : 0); - - for (uint256 i = 0; i < reserves.length; i++) { - DataTypes.ReserveData memory baseData = lendingPool.getReserveData(reserves[i]); - if (user != address(0)) { - incentivesATokens[i] = baseData.aTokenAddress; - } - } - - IncentivesDataUser memory userRewardsBalance; + IncentivesDataUser memory incentivesDataUser; if (user != address(0)) { - userRewardsBalance.rewardToken = incentivesController.REWARD_TOKEN(); - userRewardsBalance.claimableRewards = incentivesController.getRewardsBalance( - incentivesATokens, - user - ); - userRewardsBalance.rewardTokenDecimals = IERC20Detailed(userRewardsBalance.rewardToken) + incentivesDataUser.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user); + incentivesDataUser.rewardToken = incentivesController.REWARD_TOKEN(); + incentivesDataUser.precision = incentivesController.PRECISION(); + incentivesDataUser.rewardTokenDecimals = IERC20Detailed(incentivesDataUser.rewardToken) .decimals(); - userRewardsBalance.rewardTokenPriceEth = oracle.getAssetPrice(userRewardsBalance.rewardToken); + incentivesDataUser.rewardTokenPriceEth = oracle.getAssetPrice(incentivesDataUser.rewardToken); } - return (userRewardsBalance); + return ( + reservesData, + userReservesData, + oracle.getAssetPrice(MOCK_USD_ADDRESS), + incentivesDataUser + ); } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 41519611..9ad0c8c4 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -46,14 +46,20 @@ interface IUiPoolDataProvider { uint128 aEmissionPerSecond; uint128 vEmissionPerSecond; uint128 sEmissionPerSecond; + uint256 aIncentivesLastUpdateTimestamp; + uint256 vIncentivesLastUpdateTimestamp; + uint256 sIncentivesLastUpdateTimestamp; + uint256 aTokenIncentivesIndex; + uint256 vTokenIncentivesIndex; + uint256 sTokenIncentivesIndex; } struct IncentivesDataUser { address rewardToken; - uint256 claimableRewards; + uint256 userUnclaimedRewards; uint256 rewardTokenDecimals; uint256 rewardTokenPriceEth; - uint128 emissionPerSecond; + uint8 precision; } // @@ -70,6 +76,16 @@ interface IUiPoolDataProvider { uint256 scaledVariableDebt; uint256 principalStableDebt; uint256 stableBorrowLastUpdateTimestamp; + // incentives + uint256 aTokenincentivesUserIndex; + uint256 vTokenincentivesUserIndex; + uint256 sTokenincentivesUserIndex; + } + + struct IncentivesAssetData { + uint128 emissionPerSecond; + uint128 lastUpdateTimestamp; + uint256 index; } // @@ -91,14 +107,15 @@ interface IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, - uint256 + uint256, + IncentivesDataUser memory ); - function getUserIncentivesBalance( - ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentives, - address user - ) external view returns (IncentivesDataUser memory); + // function getUserIncentivesBalance( + // ILendingPoolAddressesProvider provider, + // IAaveIncentivesController incentives, + // address user + // ) external view returns (IncentivesDataUser memory); // function getUserReservesData(ILendingPoolAddressesProvider provider, address user) // external From 99a0d17de4508abeeb67cca681180b6c9f695e42 Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 30 Mar 2021 12:39:00 +0200 Subject: [PATCH 07/45] reused local vars to not fill stack --- contracts/misc/UiPoolDataProvider.sol | 66 ++++++++----------- .../misc/interfaces/IUiPoolDataProvider.sol | 48 +------------- 2 files changed, 32 insertions(+), 82 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 28b0da0b..d585593c 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -25,6 +25,21 @@ contract UiPoolDataProvider is IUiPoolDataProvider { using UserConfiguration for DataTypes.UserConfigurationMap; address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; + IAaveIncentivesController immutable incentivesController; + IPriceOracleGetter immutable oracle; + + constructor(IAaveIncentivesController _incentivesController, IPriceOracleGetter _oracle) public { + incentivesController = _incentivesController; + oracle = _oracle; + } + + function getPriceOracle() public view override returns (address) { + return address(oracle); + } + + function getIncentivesController() public view override returns (address) { + return address(incentivesController); + } function getInterestRateStrategySlopes(DefaultReserveInterestRateStrategy interestRateStrategy) internal @@ -44,11 +59,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); } - function getReservesData( - ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentivesController, - address user - ) + function getReservesData(ILendingPoolAddressesProvider provider, address user) external view override @@ -60,7 +71,6 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); - IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user); @@ -129,42 +139,24 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives - // IncentivesAssetData memory aTokenIncentives = incentivesController.assets(reserveData.aTokenAddress); - reserveData.aEmissionPerSecond = incentivesController - .assets(reserveData.aTokenAddress) - .emissionPerSecond; - reserveData.aIncentivesLastUpdateTimestamp = incentivesController - .assets(reserveData.aTokenAddress) - .lastUpdateTimestamp; - reserveData.aTokenIncentivesIndex = incentivesController - .assets(reserveData.aTokenAddress) - .index; + IAaveIncentivesController.AssetData memory tokenIncentivesInfo = + incentivesController.assets(reserveData.aTokenAddress); + reserveData.aEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; + reserveData.aIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; + reserveData.aTokenIncentivesIndex = tokenIncentivesInfo.index; - // IncentivesAssetData memory sTokenIncentives = incentivesController.assets(reserveData.stableDebtTokenAddress); - reserveData.sEmissionPerSecond = incentivesController - .assets(reserveData.stableDebtTokenAddress) - .emissionPerSecond; - reserveData.sIncentivesLastUpdateTimestamp = incentivesController - .assets(reserveData.stableDebtTokenAddress) - .lastUpdateTimestamp; - reserveData.sTokenIncentivesIndex = incentivesController - .assets(reserveData.stableDebtTokenAddress) - .index; + tokenIncentivesInfo = incentivesController.assets(reserveData.stableDebtTokenAddress); + reserveData.sEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; + reserveData.sIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; + reserveData.sTokenIncentivesIndex = tokenIncentivesInfo.index; - // IncentivesAssetData memory vTokenIncentives = incentivesController.assets(reserveData.variableDebtTokenAddress); - reserveData.vEmissionPerSecond = incentivesController - .assets(reserveData.variableDebtTokenAddress) - .emissionPerSecond; - reserveData.vIncentivesLastUpdateTimestamp = incentivesController - .assets(reserveData.variableDebtTokenAddress) - .lastUpdateTimestamp; - reserveData.vTokenIncentivesIndex = incentivesController - .assets(reserveData.variableDebtTokenAddress) - .index; + tokenIncentivesInfo = incentivesController.assets(reserveData.variableDebtTokenAddress); + reserveData.vEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; + reserveData.vIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; + reserveData.vTokenIncentivesIndex = tokenIncentivesInfo.index; if (user != address(0)) { // incentives - // userIncentives.incentivesLastUpdated = userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( user, reserveData.aTokenAddress diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 9ad0c8c4..3bdad9f6 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -62,12 +62,6 @@ interface IUiPoolDataProvider { uint8 precision; } - // - // struct ReserveData { - // uint256 averageStableBorrowRate; - // uint256 totalLiquidity; - // } - struct UserReserveData { address underlyingAsset; uint256 scaledATokenBalance; @@ -82,26 +76,7 @@ interface IUiPoolDataProvider { uint256 sTokenincentivesUserIndex; } - struct IncentivesAssetData { - uint128 emissionPerSecond; - uint128 lastUpdateTimestamp; - uint256 index; - } - - // - // struct ATokenSupplyData { - // string name; - // string symbol; - // uint8 decimals; - // uint256 totalSupply; - // address aTokenAddress; - // } - - function getReservesData( - ILendingPoolAddressesProvider provider, - IAaveIncentivesController incentives, - address user - ) + function getReservesData(ILendingPoolAddressesProvider provider, address user) external view returns ( @@ -111,24 +86,7 @@ interface IUiPoolDataProvider { IncentivesDataUser memory ); - // function getUserIncentivesBalance( - // ILendingPoolAddressesProvider provider, - // IAaveIncentivesController incentives, - // address user - // ) external view returns (IncentivesDataUser memory); + function getPriceOracle() external view returns (address); - // function getUserReservesData(ILendingPoolAddressesProvider provider, address user) - // external - // view - // returns (UserReserveData[] memory); - // - // function getAllATokenSupply(ILendingPoolAddressesProvider provider) - // external - // view - // returns (ATokenSupplyData[] memory); - // - // function getATokenSupply(address[] calldata aTokens) - // external - // view - // returns (ATokenSupplyData[] memory); + function getIncentivesController() external view returns (address); } From 9ed357662bdecb7989da044c52846543786e9090 Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 30 Mar 2021 12:42:20 +0200 Subject: [PATCH 08/45] added public to incentives controller and price oracle so we can remove getters --- contracts/misc/UiPoolDataProvider.sol | 12 ++---------- contracts/misc/interfaces/IUiPoolDataProvider.sol | 4 ---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index d585593c..d0b71a17 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -25,22 +25,14 @@ contract UiPoolDataProvider is IUiPoolDataProvider { using UserConfiguration for DataTypes.UserConfigurationMap; address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; - IAaveIncentivesController immutable incentivesController; - IPriceOracleGetter immutable oracle; + IAaveIncentivesController public immutable incentivesController; + IPriceOracleGetter public immutable oracle; constructor(IAaveIncentivesController _incentivesController, IPriceOracleGetter _oracle) public { incentivesController = _incentivesController; oracle = _oracle; } - function getPriceOracle() public view override returns (address) { - return address(oracle); - } - - function getIncentivesController() public view override returns (address) { - return address(incentivesController); - } - function getInterestRateStrategySlopes(DefaultReserveInterestRateStrategy interestRateStrategy) internal view diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 3bdad9f6..240f9fd4 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -85,8 +85,4 @@ interface IUiPoolDataProvider { uint256, IncentivesDataUser memory ); - - function getPriceOracle() external view returns (address); - - function getIncentivesController() external view returns (address); } From 516cbc7349065bcea1f9d9e68810b12428ed3b36 Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 30 Mar 2021 13:17:08 +0200 Subject: [PATCH 09/45] updated deployment scripts --- helpers/contracts-deployments.ts | 26 +++++++++++++- package.json | 4 ++- .../deployments/deploy-UiPoolDataProvider.ts | 36 +++++++++++++------ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/helpers/contracts-deployments.ts b/helpers/contracts-deployments.ts index 07f34a91..68024d2a 100644 --- a/helpers/contracts-deployments.ts +++ b/helpers/contracts-deployments.ts @@ -55,12 +55,28 @@ import { registerContractInJsonDb, linkBytecode, insertContractAddressInDb, + deployContract, } from './contracts-helpers'; import { StableAndVariableTokensHelperFactory } from '../types/StableAndVariableTokensHelperFactory'; import { MintableDelegationERC20 } from '../types/MintableDelegationERC20'; import { readArtifact as buidlerReadArtifact } from '@nomiclabs/buidler/plugins'; import { HardhatRuntimeEnvironment } from 'hardhat/types'; import { LendingPoolLibraryAddresses } from '../types/LendingPoolFactory'; +import { UiPoolDataProvider } from '../types'; +import { verifyContract } from './etherscan-verification'; + +export const deployUiPoolDataProvider = async ( + [incentivesController, aaveOracle]: [tEthereumAddress, tEthereumAddress], + verify?: boolean +) => { + const id = eContractid.UiPoolDataProvider; + const args: string[] = [incentivesController, aaveOracle]; + const instance = await deployContract(id, args); + if (verify) { + await verifyContract(instance.address, args); + } + return instance; +}; const readArtifact = async (id: string) => { if (DRE.network.name === eEthereumNetwork.buidlerevm) { @@ -546,7 +562,15 @@ export const deployMockVariableDebtToken = async ( }; export const deployMockAToken = async ( - args: [tEthereumAddress, tEthereumAddress, tEthereumAddress, tEthereumAddress, string, string, string], + args: [ + tEthereumAddress, + tEthereumAddress, + tEthereumAddress, + tEthereumAddress, + string, + string, + string + ], verify?: boolean ) => { const instance = await withSaveAndVerify( diff --git a/package.json b/package.json index 4532f6fa..dce53f5d 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,9 @@ "print-contracts:kovan": "npm run hardhat:kovan -- print-contracts", "print-contracts:main": "npm run hardhat:main -- print-contracts", "print-contracts:ropsten": "npm run hardhat:main -- print-contracts", - "dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider", + "dev:deployUIProvider": "hardhat --network kovan deploy-UiPoolDataProvider", + "main:deployUIProvider": "hardhat --network main deploy-UiPoolDataProvider", + "matic:deployUIProvider": "hardhat --network matic deploy-UiPoolDataProvider", "dev:deployUniswapRepayAdapter": "hardhat --network kovan deploy-UniswapRepayAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", "dev:UniswapLiquiditySwapAdapter": "hardhat --network kovan deploy-UniswapLiquiditySwapAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", "main:deployUniswapRepayAdapter": "hardhat --network main deploy-UniswapRepayAdapter --provider 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5 --router 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D --weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 2d696702..64a6dae4 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -1,8 +1,6 @@ import { task } from 'hardhat/config'; - -import { UiPoolDataProviderFactory } from '../../types'; -import { verifyContract } from '../../helpers/etherscan-verification'; -import { eContractid } from '../../helpers/types'; +import { eContractid, eEthereumNetwork, ePolygonNetwork } from '../../helpers/types'; +import { deployUiPoolDataProvider } from '../../helpers/contracts-deployments'; task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider contract`) .addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.') @@ -13,15 +11,31 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider throw new Error('INVALID_CHAIN_ID'); } + const addressesByNetwork = { + // [eEthereumNetwork.kovan]: { + // incentivesController: '', + // aaveOracle: '', + // }, + // [eEthereumNetwork.main]: { + // incentivesController: '', + // aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', + // }, + [ePolygonNetwork.matic]: { + incentivesController: '0x357D51124f59836DeD84c8a1730D72B749d8BC23', + aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', + }, + }; + console.log(`\n- UiPoolDataProvider deployment`); console.log(`\tDeploying UiPoolDataProvider implementation ...`); - const uiPoolDataProvider = await new UiPoolDataProviderFactory( - await localBRE.ethers.provider.getSigner() - ).deploy(); - await uiPoolDataProvider.deployTransaction.wait(); - console.log('uiPoolDataProvider.address', uiPoolDataProvider.address); - await verifyContract(uiPoolDataProvider.address, []); + const UiPoolDataProvider = await deployUiPoolDataProvider( + [ + addressesByNetwork[localBRE.network.name].incentivesController, + addressesByNetwork[localBRE.network.name].aaveOracle, + ], + verify + ); - console.log(`\tFinished UiPoolDataProvider proxy and implementation deployment`); + console.log(`\tFinished UiPoolDataProvider deployment: ${UiPoolDataProvider.address}`); }); From 5ba17aa1c1745d48379a48a072a0c613386195ea Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 30 Mar 2021 13:19:47 +0200 Subject: [PATCH 10/45] naming changed to IncentivesUserData --- contracts/misc/UiPoolDataProvider.sol | 16 ++++++++-------- .../misc/interfaces/IUiPoolDataProvider.sol | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index d0b71a17..49bbf63f 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -59,7 +59,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { AggregatedReserveData[] memory, UserReserveData[] memory, uint256, - IncentivesDataUser memory + IncentivesUserData memory ) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); @@ -194,21 +194,21 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } - IncentivesDataUser memory incentivesDataUser; + IncentivesUserData memory incentivesUserData; if (user != address(0)) { - incentivesDataUser.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user); - incentivesDataUser.rewardToken = incentivesController.REWARD_TOKEN(); - incentivesDataUser.precision = incentivesController.PRECISION(); - incentivesDataUser.rewardTokenDecimals = IERC20Detailed(incentivesDataUser.rewardToken) + incentivesUserData.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user); + incentivesUserData.rewardToken = incentivesController.REWARD_TOKEN(); + incentivesUserData.precision = incentivesController.PRECISION(); + incentivesUserData.rewardTokenDecimals = IERC20Detailed(incentivesUserData.rewardToken) .decimals(); - incentivesDataUser.rewardTokenPriceEth = oracle.getAssetPrice(incentivesDataUser.rewardToken); + incentivesUserData.rewardTokenPriceEth = oracle.getAssetPrice(incentivesUserData.rewardToken); } return ( reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS), - incentivesDataUser + incentivesUserData ); } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 240f9fd4..efee35bc 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -54,7 +54,7 @@ interface IUiPoolDataProvider { uint256 sTokenIncentivesIndex; } - struct IncentivesDataUser { + struct IncentivesUserData { address rewardToken; uint256 userUnclaimedRewards; uint256 rewardTokenDecimals; @@ -83,6 +83,6 @@ interface IUiPoolDataProvider { AggregatedReserveData[] memory, UserReserveData[] memory, uint256, - IncentivesDataUser memory + IncentivesUserData memory ); } From 566f9b1a5d8b0f8f76230d4aec07189c55a6898c Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Thu, 1 Apr 2021 14:23:31 +0200 Subject: [PATCH 11/45] Updated ILendingPool Interface --- contracts/interfaces/ILendingPool.sol | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index 64f726c0..efcdebf4 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -244,6 +244,55 @@ interface ILendingPool { address onBehalfOf ) external returns (uint256); + /** + * @notice Deposit with transfer approval of asset to be deposited done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the underlying asset to deposit + * @param amount The amount to be deposited + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + **/ + function depositWithPermit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external; + + /** + * @notice Repay with transfer approval of asset to be repaid done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the + * user calling the function if he wants to reduce/remove his own debt, or the address of any other + * other borrower whose debt should be removed + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + * @return The final amount repaid + **/ + function repayWithPermit( + address asset, + uint256 amount, + uint256 rateMode, + address onBehalfOf, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external returns (uint256); + /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed From 6810940c9f07025559825ab95e69e0cabef29380 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Fri, 2 Apr 2021 09:49:13 +0200 Subject: [PATCH 12/45] Added deadline, implemented deposit and repay withPermit functions --- contracts/interfaces/ILendingPool.sol | 2 + .../protocol/lendingpool/LendingPool.sol | 105 ++++++++++++++---- 2 files changed, 88 insertions(+), 19 deletions(-) diff --git a/contracts/interfaces/ILendingPool.sol b/contracts/interfaces/ILendingPool.sol index efcdebf4..ab012fb8 100644 --- a/contracts/interfaces/ILendingPool.sol +++ b/contracts/interfaces/ILendingPool.sol @@ -263,6 +263,7 @@ interface ILendingPool { uint256 amount, address onBehalfOf, uint16 referralCode, + uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS @@ -288,6 +289,7 @@ interface ILendingPool { uint256 amount, uint256 rateMode, address onBehalfOf, + uint256 deadline, uint8 permitV, bytes32 permitR, bytes32 permitS diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 531f007b..a86dc4aa 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2; import {SafeMath} from '../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {IERC20} from '../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {IERC20WithPermit} from '../../interfaces/IERC20WithPermit.sol'; import {SafeERC20} from '../../dependencies/openzeppelin/contracts/SafeERC20.sol'; import {Address} from '../../dependencies/openzeppelin/contracts/Address.sol'; import {ILendingPoolAddressesProvider} from '../../interfaces/ILendingPoolAddressesProvider.sol'; @@ -107,25 +108,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage address onBehalfOf, uint16 referralCode ) external override whenNotPaused { - DataTypes.ReserveData storage reserve = _reserves[asset]; - - ValidationLogic.validateDeposit(reserve, amount); - - address aToken = reserve.aTokenAddress; - - reserve.updateState(); - reserve.updateInterestRates(asset, aToken, amount, 0); - - IERC20(asset).safeTransferFrom(msg.sender, aToken, amount); - - bool isFirstDeposit = IAToken(aToken).mint(onBehalfOf, amount, reserve.liquidityIndex); - - if (isFirstDeposit) { - _usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true); - emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf); - } - - emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode); + _executeDeposit(asset, amount, onBehalfOf, referralCode); } /** @@ -254,6 +237,63 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage emit Swap(asset, msg.sender, rateMode); } + /** + * @notice Deposit with transfer approval of asset to be deposited done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the underlying asset to deposit + * @param amount The amount to be deposited + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + **/ + function depositWithPermit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external override { + IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); + _executeDeposit(asset, amount, onBehalfOf, referralCode); + } + + /** + * @notice Repay with transfer approval of asset to be repaid done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the + * user calling the function if he wants to reduce/remove his own debt, or the address of any other + * other borrower whose debt should be removed + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + * @return The final amount repaid + **/ + function repayWithPermit( + address asset, + uint256 amount, + uint256 rateMode, + address onBehalfOf, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external override returns (uint256) { + IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); + return _executeRepay(asset, amount, rateMode, onBehalfOf); + } + /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: @@ -845,6 +885,33 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage ); } + function _executeDeposit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode + ) internal { + DataTypes.ReserveData storage reserve = _reserves[asset]; + + ValidationLogic.validateDeposit(reserve, amount); + + address aToken = reserve.aTokenAddress; + + reserve.updateState(); + reserve.updateInterestRates(asset, aToken, amount, 0); + + IERC20(asset).safeTransferFrom(msg.sender, aToken, amount); + + bool isFirstDeposit = IAToken(aToken).mint(onBehalfOf, amount, reserve.liquidityIndex); + + if (isFirstDeposit) { + _usersConfig[onBehalfOf].setUsingAsCollateral(reserve.id, true); + emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf); + } + + emit Deposit(asset, msg.sender, onBehalfOf, amount, referralCode); + } + function _executeWithdraw( address asset, uint256 amount, From 3a6948ce2c1edd6e395681f57f4f58f159e78294 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 6 Apr 2021 14:55:28 +0200 Subject: [PATCH 13/45] Added depositWithPermit, repayWithPermit test scenarios --- contracts/mocks/tokens/MintableERC20.sol | 53 ++++ helpers/contracts-getters.ts | 2 + package.json | 2 +- test-suites/test-aave/helpers/actions.ts | 258 +++++++++++++++++- .../test-aave/helpers/scenario-engine.ts | 67 +++++ .../borrow-repayWithPermit-variable.json | 191 +++++++++++++ test-suites/test-aave/scenario.spec.ts | 2 +- 7 files changed, 571 insertions(+), 4 deletions(-) create mode 100644 test-suites/test-aave/helpers/scenarios/borrow-repayWithPermit-variable.json diff --git a/contracts/mocks/tokens/MintableERC20.sol b/contracts/mocks/tokens/MintableERC20.sol index 56da583e..82e40b99 100644 --- a/contracts/mocks/tokens/MintableERC20.sol +++ b/contracts/mocks/tokens/MintableERC20.sol @@ -8,14 +8,67 @@ import {ERC20} from '../../dependencies/openzeppelin/contracts/ERC20.sol'; * @dev ERC20 minting logic */ contract MintableERC20 is ERC20 { + + bytes public constant EIP712_REVISION = bytes('1'); + bytes32 internal constant EIP712_DOMAIN = + keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'); + bytes32 public constant PERMIT_TYPEHASH = + keccak256('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)'); + + mapping(address => uint256) public _nonces; + + bytes32 public DOMAIN_SEPARATOR; + constructor( string memory name, string memory symbol, uint8 decimals ) public ERC20(name, symbol) { + + uint256 chainId; + + assembly { + chainId := chainid() + } + + DOMAIN_SEPARATOR = keccak256( + abi.encode( + EIP712_DOMAIN, + keccak256(bytes(name)), + keccak256(EIP712_REVISION), + chainId, + address(this) + ) + ); _setupDecimals(decimals); } + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external { + require(owner != address(0), 'INVALID_OWNER'); + //solium-disable-next-line + require(block.timestamp <= deadline, 'INVALID_EXPIRATION'); + uint256 currentValidNonce = _nonces[owner]; + bytes32 digest = + keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR, + keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, currentValidNonce, deadline)) + ) + ); + require(owner == ecrecover(digest, v, r, s), 'INVALID_SIGNATURE'); + _nonces[owner] = currentValidNonce.add(1); + _approve(owner, spender, value); + } + /** * @dev Function to mint tokens * @param value The amount of tokens to mint. diff --git a/helpers/contracts-getters.ts b/helpers/contracts-getters.ts index 0f70c48b..33da4054 100644 --- a/helpers/contracts-getters.ts +++ b/helpers/contracts-getters.ts @@ -363,3 +363,5 @@ export const getFlashLiquidationAdapter = async (address?: tEthereumAddress) => .address, await getFirstSigner() ); + +export const getChainId = async () => (await DRE.ethers.provider.getNetwork()).chainId; diff --git a/package.json b/package.json index 4532f6fa..defa7412 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-aave/*.spec.ts", "test-amm": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/*.spec.ts", "test-amm-scenarios": "TS_NODE_TRANSPILE_ONLY=1 hardhat test ./test-suites/test-amm/__setup.spec.ts test-suites/test-amm/scenario.spec.ts", - "test-scenarios": "npx hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts", + "test-scenarios": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/scenario.spec.ts", "test-repay-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/repay-with-collateral.spec.ts", "test-liquidate-with-collateral": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/flash-liquidation-with-collateral.spec.ts", "test-liquidate-underlying": "hardhat test test-suites/test-aave/__setup.spec.ts test-suites/test-aave/liquidation-underlying.spec.ts", diff --git a/test-suites/test-aave/helpers/actions.ts b/test-suites/test-aave/helpers/actions.ts index 3000576a..fac619f4 100644 --- a/test-suites/test-aave/helpers/actions.ts +++ b/test-suites/test-aave/helpers/actions.ts @@ -16,6 +16,7 @@ import { calcExpectedUserDataAfterWithdraw, } from './utils/calculations'; import { getReserveAddressFromSymbol, getReserveData, getUserData } from './utils/helpers'; +import { buildPermitParams, getSignatureFromTypedData } from '../../../helpers/contracts-helpers'; import { convertToCurrencyDecimals } from '../../../helpers/contracts-helpers'; import { @@ -23,6 +24,7 @@ import { getMintableERC20, getStableDebtToken, getVariableDebtToken, + getChainId, } from '../../../helpers/contracts-getters'; import { MAX_UINT_AMOUNT, ONE_YEAR } from '../../../helpers/constants'; import { SignerWithAddress, TestEnv } from './make-suite'; @@ -30,9 +32,10 @@ import { advanceTimeAndBlock, DRE, timeLatest, waitForTx } from '../../../helper import chai from 'chai'; import { ReserveData, UserReserveData } from './utils/interfaces'; -import { ContractReceipt } from 'ethers'; +import { ContractReceipt, Wallet } from 'ethers'; import { AToken } from '../../../types/AToken'; import { RateMode, tEthereumAddress } from '../../../helpers/types'; +import { MintableERC20Factory } from '../../../types'; const { expect } = chai; @@ -349,7 +352,7 @@ export const borrow = async ( ); const amountToBorrow = await convertToCurrencyDecimals(reserve, amount); - + if (expectedResult === 'success') { const txResult = await waitForTx( await pool @@ -515,6 +518,257 @@ export const repay = async ( } }; +export const depositWithPermit = async ( + reserveSymbol: string, + amount: string, + sender: SignerWithAddress, + senderPk: string, + onBehalfOf: tEthereumAddress, + sendValue: string, + expectedResult: string, + testEnv: TestEnv, + revertMessage?: string +) => { + const { pool } = testEnv; + + const reserve = await getReserveAddressFromSymbol(reserveSymbol); + const amountToDeposit = await convertToCurrencyDecimals(reserve, amount); + + const chainId = await getChainId(); + const token = new MintableERC20Factory(sender.signer).attach(reserve); + const highDeadline = '100000000000000000000000000'; + const nonce = await token._nonces(sender.address); + + const msgParams = buildPermitParams( + chainId, + reserve, + '1', + reserveSymbol, + sender.address, + pool.address, + nonce.toNumber(), + highDeadline, + amountToDeposit.toString() + ); + const { v, r, s } = getSignatureFromTypedData(senderPk, msgParams); + + const txOptions: any = {}; + + const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( + reserve, + onBehalfOf, + testEnv, + sender.address + ); + + if (sendValue) { + txOptions.value = await convertToCurrencyDecimals(reserve, sendValue); + } + + if (expectedResult === 'success') { + const txResult = await waitForTx( + await pool + .connect(sender.signer) + .depositWithPermit( + reserve, + amountToDeposit, + onBehalfOf, + '0', + highDeadline, + v, + r, + s, + txOptions + ) + ); + + const { + reserveData: reserveDataAfter, + userData: userDataAfter, + timestamp, + } = await getContractsData(reserve, onBehalfOf, testEnv, sender.address); + + const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); + + const expectedReserveData = calcExpectedReserveDataAfterDeposit( + amountToDeposit.toString(), + reserveDataBefore, + txTimestamp + ); + + const expectedUserReserveData = calcExpectedUserDataAfterDeposit( + amountToDeposit.toString(), + reserveDataBefore, + expectedReserveData, + userDataBefore, + txTimestamp, + timestamp, + txCost + ); + + expectEqual(reserveDataAfter, expectedReserveData); + expectEqual(userDataAfter, expectedUserReserveData); + + // truffleAssert.eventEmitted(txResult, "Deposit", (ev: any) => { + // const {_reserve, _user, _amount} = ev; + // return ( + // _reserve === reserve && + // _user === user && + // new BigNumber(_amount).isEqualTo(new BigNumber(amountToDeposit)) + // ); + // }); + } else if (expectedResult === 'revert') { + await expect( + pool + .connect(sender.signer) + .depositWithPermit( + reserve, + amountToDeposit, + onBehalfOf, + '0', + highDeadline, + v, + r, + s, + txOptions + ), + revertMessage + ).to.be.reverted; + } +}; + +export const repayWithPermit = async ( + reserveSymbol: string, + amount: string, + rateMode: string, + user: SignerWithAddress, + userPk: string, + onBehalfOf: SignerWithAddress, + sendValue: string, + expectedResult: string, + testEnv: TestEnv, + revertMessage?: string +) => { + const { pool } = testEnv; + const reserve = await getReserveAddressFromSymbol(reserveSymbol); + const highDeadline = '100000000000000000000000000'; + + const { reserveData: reserveDataBefore, userData: userDataBefore } = await getContractsData( + reserve, + onBehalfOf.address, + testEnv + ); + + let amountToRepay = '0'; + + if (amount !== '-1') { + amountToRepay = (await convertToCurrencyDecimals(reserve, amount)).toString(); + } else { + amountToRepay = MAX_UINT_AMOUNT; + } + amountToRepay = '0x' + new BigNumber(amountToRepay).toString(16); + + const chainId = await getChainId(); + const token = new MintableERC20Factory(user.signer).attach(reserve); + const nonce = await token._nonces(user.address); + + const msgParams = buildPermitParams( + chainId, + reserve, + '1', + reserveSymbol, + user.address, + pool.address, + nonce.toNumber(), + highDeadline, + amountToRepay + ); + const { v, r, s } = getSignatureFromTypedData(userPk, msgParams); + const txOptions: any = {}; + + if (sendValue) { + const valueToSend = await convertToCurrencyDecimals(reserve, sendValue); + txOptions.value = '0x' + new BigNumber(valueToSend.toString()).toString(16); + } + + if (expectedResult === 'success') { + const txResult = await waitForTx( + await pool + .connect(user.signer) + .repayWithPermit( + reserve, + amountToRepay, + rateMode, + onBehalfOf.address, + highDeadline, + v, + r, + s, + txOptions + ) + ); + + const { txCost, txTimestamp } = await getTxCostAndTimestamp(txResult); + + const { + reserveData: reserveDataAfter, + userData: userDataAfter, + timestamp, + } = await getContractsData(reserve, onBehalfOf.address, testEnv); + + const expectedReserveData = calcExpectedReserveDataAfterRepay( + amountToRepay, + rateMode, + reserveDataBefore, + userDataBefore, + txTimestamp, + timestamp + ); + + const expectedUserData = calcExpectedUserDataAfterRepay( + amountToRepay, + rateMode, + reserveDataBefore, + expectedReserveData, + userDataBefore, + user.address, + onBehalfOf.address, + txTimestamp, + timestamp + ); + + expectEqual(reserveDataAfter, expectedReserveData); + expectEqual(userDataAfter, expectedUserData); + + // truffleAssert.eventEmitted(txResult, "Repay", (ev: any) => { + // const {_reserve, _user, _repayer} = ev; + + // return ( + // _reserve.toLowerCase() === reserve.toLowerCase() && + // _user.toLowerCase() === onBehalfOf.toLowerCase() && + // _repayer.toLowerCase() === user.toLowerCase() + // ); + // }); + } else if (expectedResult === 'revert') { + await expect( + pool + .connect(user.signer) + .repayWithPermit( + reserve, + amountToRepay, + rateMode, + onBehalfOf.address, + highDeadline, + v, + r, + s, + txOptions + ), + revertMessage + ).to.be.reverted; + } +}; + export const setUseAsCollateral = async ( reserveSymbol: string, user: SignerWithAddress, diff --git a/test-suites/test-aave/helpers/scenario-engine.ts b/test-suites/test-aave/helpers/scenario-engine.ts index 492fa8b2..7ec22bd5 100644 --- a/test-suites/test-aave/helpers/scenario-engine.ts +++ b/test-suites/test-aave/helpers/scenario-engine.ts @@ -10,8 +10,11 @@ import { swapBorrowRateMode, rebalanceStableBorrowRate, delegateBorrowAllowance, + repayWithPermit, + depositWithPermit, } from './actions'; import { RateMode } from '../../../helpers/types'; +import { Wallet } from '@ethersproject/wallet'; export interface Action { name: string; @@ -73,6 +76,12 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv const user = users[parseInt(userIndex)]; + const userPrivateKey = require('../../../test-wallets.js').accounts[parseInt(userIndex) + 1] + .secretKey; + if (!userPrivateKey) { + throw new Error('INVALID_OWNER_PK'); + } + switch (name) { case 'mint': const { amount } = action.args; @@ -111,6 +120,30 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv ); } break; + case 'depositWithPermit': + { + const { amount, sendValue, onBehalfOf: onBehalfOfIndex } = action.args; + const onBehalfOf = onBehalfOfIndex + ? users[parseInt(onBehalfOfIndex)].address + : user.address; + + if (!amount || amount === '') { + throw `Invalid amount to deposit into the ${reserve} reserve`; + } + + await depositWithPermit( + reserve, + amount, + user, + userPrivateKey, + onBehalfOf, + sendValue, + expected, + testEnv, + revertMessage + ); + } + break; case 'delegateBorrowAllowance': { @@ -203,6 +236,40 @@ const executeAction = async (action: Action, users: SignerWithAddress[], testEnv } break; + case 'repayWithPermit': + { + const { amount, borrowRateMode, sendValue, deadline } = action.args; + let { onBehalfOf: onBehalfOfIndex } = action.args; + + if (!amount || amount === '') { + throw `Invalid amount to repay into the ${reserve} reserve`; + } + + let userToRepayOnBehalf: SignerWithAddress; + if (!onBehalfOfIndex || onBehalfOfIndex === '') { + console.log( + 'WARNING: No onBehalfOf specified for a repay action. Defaulting to the repayer address' + ); + userToRepayOnBehalf = user; + } else { + userToRepayOnBehalf = users[parseInt(onBehalfOfIndex)]; + } + + await repayWithPermit( + reserve, + amount, + rateMode, + user, + userPrivateKey, + userToRepayOnBehalf, + sendValue, + expected, + testEnv, + revertMessage + ); + } + break; + case 'setUseAsCollateral': { const { useAsCollateral } = action.args; diff --git a/test-suites/test-aave/helpers/scenarios/borrow-repayWithPermit-variable.json b/test-suites/test-aave/helpers/scenarios/borrow-repayWithPermit-variable.json new file mode 100644 index 00000000..85f5c723 --- /dev/null +++ b/test-suites/test-aave/helpers/scenarios/borrow-repayWithPermit-variable.json @@ -0,0 +1,191 @@ +{ + "title": "LendingPool: Borrow/repay with permit with Permit (variable rate)", + "description": "Test cases for the borrow function, variable mode.", + "stories": [ + { + "description": "User 2 deposits with permit 1 DAI to account for rounding errors", + "actions": [ + { + "name": "mint", + "args": { + "reserve": "DAI", + "amount": "1", + "user": "2" + }, + "expected": "success" + }, + { + "name": "depositWithPermit", + "args": { + "reserve": "DAI", + "amount": "1", + "user": "2" + }, + "expected": "success" + } + ] + }, + { + "description": "User 0 deposits with permit 1000 DAI, user 1 deposits 1 WETH as collateral and borrows 100 DAI at variable rate", + "actions": [ + { + "name": "mint", + "args": { + "reserve": "DAI", + "amount": "1000", + "user": "0" + }, + "expected": "success" + }, + { + "name": "depositWithPermit", + "args": { + "reserve": "DAI", + "amount": "1000", + "user": "0" + }, + "expected": "success" + }, + { + "name": "mint", + "args": { + "reserve": "WETH", + "amount": "1", + "user": "1" + }, + "expected": "success" + }, + { + "name": "approve", + "args": { + "reserve": "WETH", + "user": "1" + }, + "expected": "success" + }, + { + "name": "deposit", + "args": { + "reserve": "WETH", + "amount": "1", + "user": "1" + }, + "expected": "success" + }, + { + "name": "borrow", + "args": { + "reserve": "DAI", + "amount": "100", + "borrowRateMode": "variable", + "user": "1", + "timeTravel": "365" + }, + "expected": "success" + } + ] + }, + { + "description": "User 1 tries to borrow the rest of the DAI liquidity (revert expected)", + "actions": [ + { + "name": "borrow", + "args": { + "reserve": "DAI", + "amount": "900", + "borrowRateMode": "variable", + "user": "1" + }, + "expected": "revert", + "revertMessage": "There is not enough collateral to cover a new borrow" + } + ] + }, + { + "description": "User 1 tries to repay with permit 0 DAI (revert expected)", + "actions": [ + { + "name": "repayWithPermit", + "args": { + "reserve": "DAI", + "amount": "0", + "user": "1", + "onBehalfOf": "1" + }, + "expected": "revert", + "revertMessage": "Amount must be greater than 0" + } + ] + }, + { + "description": "User 1 repays with permit a small amount of DAI, enough to cover a small part of the interest", + "actions": [ + { + "name": "repayWithPermit", + "args": { + "reserve": "DAI", + "amount": "1.25", + "user": "1", + "onBehalfOf": "1", + "borrowRateMode": "variable" + }, + "expected": "success" + } + ] + }, + { + "description": "User 1 repays with permit the DAI borrow after one year", + "actions": [ + { + "name": "mint", + "description": "Mint 10 DAI to cover the interest", + "args": { + "reserve": "DAI", + "amount": "10", + "user": "1" + }, + "expected": "success" + }, + { + "name": "repayWithPermit", + "args": { + "reserve": "DAI", + "amount": "-1", + "user": "1", + "onBehalfOf": "1", + "borrowRateMode": "variable" + }, + "expected": "success" + } + ] + }, + { + "description": "User 0 withdraws the deposited DAI plus interest", + "actions": [ + { + "name": "withdraw", + "args": { + "reserve": "DAI", + "amount": "-1", + "user": "0" + }, + "expected": "success" + } + ] + }, + { + "description": "User 1 withdraws the collateral", + "actions": [ + { + "name": "withdraw", + "args": { + "reserve": "WETH", + "amount": "-1", + "user": "1" + }, + "expected": "success" + } + ] + } + ] +} diff --git a/test-suites/test-aave/scenario.spec.ts b/test-suites/test-aave/scenario.spec.ts index 68b792d5..e658948a 100644 --- a/test-suites/test-aave/scenario.spec.ts +++ b/test-suites/test-aave/scenario.spec.ts @@ -35,7 +35,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => { for (const story of scenario.stories) { it(story.description, async function () { - // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors + // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors this.retries(4); await executeStory(story, testEnv); }); From 1316cf48e4b605cda20caae6846564906bf0664c Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 6 Apr 2021 15:08:19 +0200 Subject: [PATCH 14/45] Updated WETHGateway for withdrawETHWithPermit --- contracts/misc/WETHGateway.sol | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol index 336e8de2..1ddceaa0 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -131,6 +131,37 @@ contract WETHGateway is IWETHGateway, Ownable { _safeTransferETH(msg.sender, amount); } + /** + * @dev withdraws the WETH _reserves of msg.sender. + * @param lendingPool address of the targeted underlying lending pool + * @param amount amount of aWETH to withdraw and receive native ETH + * @param to address of the user who will receive native ETH + */ + function withdrawETHWithPermit( + address lendingPool, + uint256 amount, + address to, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external override { + IAToken aWETH = IAToken(ILendingPool(lendingPool).getReserveData(address(WETH)).aTokenAddress); + uint256 userBalance = aWETH.balanceOf(msg.sender); + uint256 amountToWithdraw = amount; + + // if amount is equal to uint(-1), the user wants to redeem everything + if (amount == type(uint256).max) { + amountToWithdraw = userBalance; + } + // chosing to permit `amount`and not `amountToWithdraw`, easier for frontends, intregrators. + aWETH.permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); + aWETH.transferFrom(msg.sender, address(this), amountToWithdraw); + ILendingPool(lendingPool).withdraw(address(WETH), amountToWithdraw, address(this)); + WETH.withdraw(amountToWithdraw); + _safeTransferETH(to, amountToWithdraw); + } + /** * @dev transfer ETH to an address, revert if it fails. * @param to recipient of the transfer From 5facb2a14d1c9413893ae7a7a2ec6466f587e5b0 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 6 Apr 2021 15:18:31 +0200 Subject: [PATCH 15/45] Added new IWETHGateway interface --- contracts/misc/interfaces/IWETHGateway.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contracts/misc/interfaces/IWETHGateway.sol b/contracts/misc/interfaces/IWETHGateway.sol index 78d913cd..326ece57 100644 --- a/contracts/misc/interfaces/IWETHGateway.sol +++ b/contracts/misc/interfaces/IWETHGateway.sol @@ -27,4 +27,14 @@ interface IWETHGateway { uint256 interesRateMode, uint16 referralCode ) external; + + function withdrawETHWithPermit( + address lendingPool, + uint256 amount, + address to, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external; } From b84a486d106fe67c9d1019a71132c26527fd789c Mon Sep 17 00:00:00 2001 From: sendra Date: Tue, 6 Apr 2021 16:17:04 +0200 Subject: [PATCH 16/45] removed extra external calls that are not needed --- contracts/misc/UiPoolDataProvider.sol | 3 --- contracts/misc/interfaces/IUiPoolDataProvider.sol | 2 -- 2 files changed, 5 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 49bbf63f..1672ab1a 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -198,9 +198,6 @@ contract UiPoolDataProvider is IUiPoolDataProvider { if (user != address(0)) { incentivesUserData.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user); incentivesUserData.rewardToken = incentivesController.REWARD_TOKEN(); - incentivesUserData.precision = incentivesController.PRECISION(); - incentivesUserData.rewardTokenDecimals = IERC20Detailed(incentivesUserData.rewardToken) - .decimals(); incentivesUserData.rewardTokenPriceEth = oracle.getAssetPrice(incentivesUserData.rewardToken); } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index efee35bc..7757a4f1 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -57,9 +57,7 @@ interface IUiPoolDataProvider { struct IncentivesUserData { address rewardToken; uint256 userUnclaimedRewards; - uint256 rewardTokenDecimals; uint256 rewardTokenPriceEth; - uint8 precision; } struct UserReserveData { From dc2943f2ec243ae93178913fc130c7570d5c5936 Mon Sep 17 00:00:00 2001 From: sendra Date: Wed, 7 Apr 2021 17:44:29 +0200 Subject: [PATCH 17/45] removed incentives data, as it is hardcoded on client side --- contracts/misc/UiPoolDataProvider.sol | 17 ++--------------- .../misc/interfaces/IUiPoolDataProvider.sol | 9 +-------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 1672ab1a..026d67d9 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -58,8 +58,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, - uint256, - IncentivesUserData memory + uint256 ) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); @@ -194,18 +193,6 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } - IncentivesUserData memory incentivesUserData; - if (user != address(0)) { - incentivesUserData.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user); - incentivesUserData.rewardToken = incentivesController.REWARD_TOKEN(); - incentivesUserData.rewardTokenPriceEth = oracle.getAssetPrice(incentivesUserData.rewardToken); - } - - return ( - reservesData, - userReservesData, - oracle.getAssetPrice(MOCK_USD_ADDRESS), - incentivesUserData - ); + return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS)); } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 7757a4f1..283c3500 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -54,12 +54,6 @@ interface IUiPoolDataProvider { uint256 sTokenIncentivesIndex; } - struct IncentivesUserData { - address rewardToken; - uint256 userUnclaimedRewards; - uint256 rewardTokenPriceEth; - } - struct UserReserveData { address underlyingAsset; uint256 scaledATokenBalance; @@ -80,7 +74,6 @@ interface IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, - uint256, - IncentivesUserData memory + uint256 ); } From 717bb133e100236d728fd463704fd0cb4e710815 Mon Sep 17 00:00:00 2001 From: sendra Date: Thu, 8 Apr 2021 13:55:01 +0200 Subject: [PATCH 18/45] added unclaimed user rewards --- contracts/misc/UiPoolDataProvider.sol | 8 +++++++- contracts/misc/interfaces/IUiPoolDataProvider.sol | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 026d67d9..7d2aef55 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -58,6 +58,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, + uint256, uint256 ) { @@ -193,6 +194,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } - return (reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS)); + return ( + reservesData, + userReservesData, + oracle.getAssetPrice(MOCK_USD_ADDRESS), + incentivesController.getUserUnclaimedRewards(user) + ); } } diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 283c3500..43e4e997 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -74,6 +74,7 @@ interface IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, + uint256, uint256 ); } From a5ab0a6e3b3b4715ff692740ae9b68fe2d407ab5 Mon Sep 17 00:00:00 2001 From: sendra Date: Fri, 9 Apr 2021 10:57:01 +0200 Subject: [PATCH 19/45] added mumbai addresses --- package-lock.json | 313 +++++++++--------- package.json | 1 + .../deployments/deploy-UiPoolDataProvider.ts | 6 +- 3 files changed, 171 insertions(+), 149 deletions(-) diff --git a/package-lock.json b/package-lock.json index b05b76cb..cf9af765 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2803,7 +2803,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5151,8 +5150,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -5889,36 +5887,6 @@ "@ethersproject/strings": ">=5.0.0-beta.130" } }, - "@ethersproject/abstract-provider": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.8.tgz", - "integrity": "sha512-fqJXkewcGdi8LogKMgRyzc/Ls2js07yor7+g9KfPs09uPOcQLg7cc34JN+lk34HH9gg2HU0DIA5797ZR8znkfw==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.10.tgz", - "integrity": "sha512-irx7kH7FDAeW7QChDPW19WsxqeB1d3XLyOLSXm0bfPqL1SS07LXWltBJUBUxqC03ORpAOcM3JQj57DU8JnVY2g==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, "@ethersproject/address": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.9.tgz", @@ -5933,16 +5901,6 @@ "@ethersproject/rlp": "^5.0.7" } }, - "@ethersproject/base64": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.7.tgz", - "integrity": "sha512-S5oh5DVfCo06xwJXT8fQC68mvJfgScTl2AXvbYMsHNfIBTDb084Wx4iA9MNlEReOv6HulkS+gyrUM/j3514rSw==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9" - } - }, "@ethersproject/bignumber": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.13.tgz", @@ -6010,16 +5968,6 @@ "dev": true, "optional": true }, - "@ethersproject/networks": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.7.tgz", - "integrity": "sha512-dI14QATndIcUgcCBL1c5vUr/YsI5cCHLN81rF7PU+yS7Xgp2/Rzbr9+YqpC6NBXHFUASjh6GpKqsVMpufAL0BQ==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, "@ethersproject/properties": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.7.tgz", @@ -6084,20 +6032,6 @@ "@ethersproject/signing-key": "^5.0.8" } }, - "@ethersproject/web": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.12.tgz", - "integrity": "sha512-gVxS5iW0bgidZ76kr7LsTxj4uzN5XpCLzvZrLp8TP+4YgxHfCeetFyQkRPgBEAJdNrexdSBayvyJvzGvOq0O8g==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -7294,15 +7228,6 @@ "requires": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", - "dev": true, - "optional": true - } } }, "browserify-sign": { @@ -7410,6 +7335,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } } }, "bytes": { @@ -7510,16 +7443,6 @@ } } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "caniuse-lite": { "version": "1.0.30001174", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz", @@ -8038,7 +7961,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -8264,7 +8186,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -10434,8 +10355,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -10443,17 +10363,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -10501,6 +10410,14 @@ "requires": { "min-document": "^2.19.0", "process": "^0.11.10" + }, + "dependencies": { + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "dev": true + } } }, "got": { @@ -10561,7 +10478,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -10599,8 +10515,7 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-to-string-tag-x": { "version": "1.4.1", @@ -10873,8 +10788,7 @@ "is-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", - "dev": true + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" }, "is-ci": { "version": "2.0.0", @@ -10897,8 +10811,7 @@ "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" }, "is-descriptor": { "version": "1.0.2", @@ -10947,8 +10860,7 @@ "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" }, "is-object": { "version": "1.0.2", @@ -10977,7 +10889,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, "requires": { "has-symbols": "^1.0.1" } @@ -10993,7 +10904,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, "requires": { "has-symbols": "^1.0.1" } @@ -11836,8 +11746,7 @@ "object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" }, "object-is": { "version": "1.1.4", @@ -11847,13 +11756,33 @@ "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -11868,12 +11797,32 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object.getownpropertydescriptors": { @@ -12145,12 +12094,6 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -12411,22 +12354,71 @@ }, "dependencies": { "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } } } } @@ -12514,6 +12506,15 @@ "uuid": "^3.3.2" } }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -13172,13 +13173,34 @@ "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string.prototype.trimend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -13188,7 +13210,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -13375,15 +13396,6 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, @@ -13745,6 +13757,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } } }, "utf8": { @@ -14723,7 +14743,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -15087,7 +15106,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -15113,8 +15131,7 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-to-string-tag-x": { "version": "1.4.1", diff --git a/package.json b/package.json index dce53f5d..cfb6ee28 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "dev:deployUIProvider": "hardhat --network kovan deploy-UiPoolDataProvider", "main:deployUIProvider": "hardhat --network main deploy-UiPoolDataProvider", "matic:deployUIProvider": "hardhat --network matic deploy-UiPoolDataProvider", + "mumbai:deployUIProvider": "hardhat --network mumbai deploy-UiPoolDataProvider", "dev:deployUniswapRepayAdapter": "hardhat --network kovan deploy-UniswapRepayAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", "dev:UniswapLiquiditySwapAdapter": "hardhat --network kovan deploy-UniswapLiquiditySwapAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", "main:deployUniswapRepayAdapter": "hardhat --network main deploy-UniswapRepayAdapter --provider 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5 --router 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D --weth 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 64a6dae4..79d75a49 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -6,7 +6,7 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider .addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.') .setAction(async ({ verify }, localBRE) => { await localBRE.run('set-DRE'); - + console.log('founds: ', await localBRE.ethers.getSigners()); if (!localBRE.network.config.chainId) { throw new Error('INVALID_CHAIN_ID'); } @@ -24,6 +24,10 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider incentivesController: '0x357D51124f59836DeD84c8a1730D72B749d8BC23', aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', }, + [ePolygonNetwork.mumbai]: { + incentivesController: '0xc31c45a46e55f714f9CB2b43Ae688487C16616e2', + aaveOracle: '0x584c84AA7aE807e18957f8E3693BccBD482357E2', + }, }; console.log(`\n- UiPoolDataProvider deployment`); From f7fde949a75bb0e890d67d9619883c74e4decd3a Mon Sep 17 00:00:00 2001 From: sendra Date: Fri, 9 Apr 2021 15:06:57 +0200 Subject: [PATCH 20/45] updated with latest addresses --- tasks/deployments/deploy-UiPoolDataProvider.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 79d75a49..21bf08ed 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -6,7 +6,6 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider .addFlag('verify', 'Verify UiPoolDataProvider contract via Etherscan API.') .setAction(async ({ verify }, localBRE) => { await localBRE.run('set-DRE'); - console.log('founds: ', await localBRE.ethers.getSigners()); if (!localBRE.network.config.chainId) { throw new Error('INVALID_CHAIN_ID'); } @@ -25,8 +24,8 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', }, [ePolygonNetwork.mumbai]: { - incentivesController: '0xc31c45a46e55f714f9CB2b43Ae688487C16616e2', - aaveOracle: '0x584c84AA7aE807e18957f8E3693BccBD482357E2', + incentivesController: '0xa20493558dB697369ffB1b4A4Dc6455ee26aEeff', + aaveOracle: '0xE6d947B89c837B761bf3B7D48bB406a7a2EEc3e0', }, }; From 1849484cbf8c040c09f8faa6edaae06db6c980e0 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 12 Apr 2021 09:37:55 +0200 Subject: [PATCH 21/45] updated with new mumbai addresses --- tasks/deployments/deploy-UiPoolDataProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 21bf08ed..881e71eb 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -24,8 +24,8 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', }, [ePolygonNetwork.mumbai]: { - incentivesController: '0xa20493558dB697369ffB1b4A4Dc6455ee26aEeff', - aaveOracle: '0xE6d947B89c837B761bf3B7D48bB406a7a2EEc3e0', + incentivesController: '0xCA8f76C244271A857CE76263e60d294EB24186A8', + aaveOracle: '0x3cC6db8dBBa233Fe342c2c8379993aCa231674bd', }, }; From 47b3d8ff65c2280a183edee8b626123152090676 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 12 Apr 2021 10:56:33 +0200 Subject: [PATCH 22/45] new mumbai addresses --- tasks/deployments/deploy-UiPoolDataProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 881e71eb..31290c2d 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -24,8 +24,8 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', }, [ePolygonNetwork.mumbai]: { - incentivesController: '0xCA8f76C244271A857CE76263e60d294EB24186A8', - aaveOracle: '0x3cC6db8dBBa233Fe342c2c8379993aCa231674bd', + incentivesController: '0xd3aC1EBa90c21D70464dDafd30E3Ff8941002929', + aaveOracle: '0x48beE000e8f86d0ED8c0fB22D63e789b0cE9Aed1', }, }; From b0caaee52e7483ca50809a29765afcd84ae6e928 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 12 Apr 2021 21:36:34 +0200 Subject: [PATCH 23/45] updated for latest mumbai addresses --- tasks/deployments/deploy-UiPoolDataProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 31290c2d..c2646923 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -24,8 +24,8 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', }, [ePolygonNetwork.mumbai]: { - incentivesController: '0xd3aC1EBa90c21D70464dDafd30E3Ff8941002929', - aaveOracle: '0x48beE000e8f86d0ED8c0fB22D63e789b0cE9Aed1', + incentivesController: '0xd41aE58e803Edf4304334acCE4DC4Ec34a63C644', + aaveOracle: '0xC365C653f7229894F93994CD0b30947Ab69Ff1D5', }, }; From 21fc210901c7d50fbd1acfe1a6b8cc97b59ed3c3 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 19 Apr 2021 17:17:30 +0200 Subject: [PATCH 24/45] fix: updated interface to last version --- .../interfaces/IAaveIncentivesController.sol | 103 +++++++++++++++++- 1 file changed, 99 insertions(+), 4 deletions(-) diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index 8e9c74a7..4b49eb23 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -9,24 +9,119 @@ interface IAaveIncentivesController { uint256 index; } - function REWARD_TOKEN() external view returns (address rewardToken); + event RewardsAccrued(address indexed user, uint256 amount); - function PRECISION() external view returns (uint8); + event RewardsClaimed( + address indexed user, + address indexed to, + uint256 amount + ); + + event RewardsClaimed( + address indexed user, + address indexed to, + address indexed claimer, + uint256 amount + ); + + event ClaimerSet(address indexed user, address indexed claimer); function assets(address underlying) external view returns (AssetData memory assets); + /** + * @dev Whitelists an address to claim the rewards on behalf of another address + * @param user The address of the user + * @param claimer The address of the claimer + */ + function setClaimer(address user, address claimer) external; + + /** + * @dev Returns the whitelisted claimer for a certain address (0x0 if not set) + * @param user The address of the user + * @return The claimer address + */ + function getClaimer(address user) external view returns (address); + + /** + * @dev Configure assets for a certain rewards emission + * @param assets The assets to incentivize + * @param emissionsPerSecond The emission for each asset + */ + function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) + external; + + + /** + * @dev Called by the corresponding asset on any update that affects the rewards distribution + * @param asset The address of the user + * @param userBalance The balance of the user of the asset in the lending pool + * @param totalSupply The total supply of the asset in the lending pool + **/ function handleAction( - address user, + address asset, uint256 userBalance, uint256 totalSupply ) external; + /** + * @dev Returns the total of rewards of an user, already accrued + not yet accrued + * @param user The address of the user + * @return The rewards + **/ function getRewardsBalance(address[] calldata assets, address user) external view returns (uint256); - function getUserUnclaimedRewards(address _user) external view returns (uint256); + /** + * @dev Claims reward for an user, on all the assets of the lending pool, accumulating the pending rewards + * @param amount Amount of rewards to claim + * @param to Address that will be receiving the rewards + * @return Rewards claimed + **/ + function claimRewards( + address[] calldata assets, + uint256 amount, + address to + ) external returns (uint256); + /** + * @dev Claims reward for an user on behalf, on all the assets of the lending pool, accumulating the pending rewards. The caller must + * be whitelisted via "allowClaimOnBehalf" function by the RewardsAdmin role manager + * @param amount Amount of rewards to claim + * @param user Address to check and claim rewards + * @param to Address that will be receiving the rewards + * @return Rewards claimed + **/ + function claimRewardsOnBehalf( + address[] calldata assets, + uint256 amount, + address user, + address to + ) external returns (uint256); + + /** + * @dev returns the unclaimed rewards of the user + * @param user the address of the user + * @return the unclaimed user rewards + */ + function getUserUnclaimedRewards(address user) external view returns (uint256); + + /** + * @dev returns the unclaimed rewards of the user + * @param user the address of the user + * @param asset The asset to incentivize + * @return the user index for the asset + */ function getUserAssetData(address user, address asset) external view returns (uint256); + + /** + * @dev for backward compatibility with previous implementation of the Incentives controller + */ + function REWARD_TOKEN() external view returns (address); + + /** + * @dev for backward compatibility with previous implementation of the Incentives controller + */ + function PRECISION() external view returns (uint8); } From 360d37f9f87bcb7198202fb2d50ab49376f87d7a Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 19 Apr 2021 17:23:45 +0200 Subject: [PATCH 25/45] fix: updated mainnet task to deploy ui helper --- package.json | 4 ++-- tasks/deployments/deploy-UiPoolDataProvider.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index cfb6ee28..c3a97f23 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "print-contracts:kovan": "npm run hardhat:kovan -- print-contracts", "print-contracts:main": "npm run hardhat:main -- print-contracts", "print-contracts:ropsten": "npm run hardhat:main -- print-contracts", - "dev:deployUIProvider": "hardhat --network kovan deploy-UiPoolDataProvider", - "main:deployUIProvider": "hardhat --network main deploy-UiPoolDataProvider", + "dev:deployUIProvider": "hardhat --network kovan deploy-UiPoolDataProvider --verify", + "main:deployUIProvider": "hardhat --network main deploy-UiPoolDataProvider --verify", "matic:deployUIProvider": "hardhat --network matic deploy-UiPoolDataProvider", "mumbai:deployUIProvider": "hardhat --network mumbai deploy-UiPoolDataProvider", "dev:deployUniswapRepayAdapter": "hardhat --network kovan deploy-UniswapRepayAdapter --provider 0x88757f2f99175387aB4C6a4b3067c77A695b0349 --router 0xfcd87315f0e4067070ade8682fcdbc3006631441 --weth 0xd0a1e359811322d97991e03f863a0c30c2cf029c", diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index c2646923..1158fe90 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -15,10 +15,10 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider // incentivesController: '', // aaveOracle: '', // }, - // [eEthereumNetwork.main]: { - // incentivesController: '', - // aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', - // }, + [eEthereumNetwork.main]: { + incentivesController: '0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5', + aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', + }, [ePolygonNetwork.matic]: { incentivesController: '0x357D51124f59836DeD84c8a1730D72B749d8BC23', aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', From 8000d838a36c666b307f7b30bdefd1269410ecbf Mon Sep 17 00:00:00 2001 From: sendra Date: Wed, 21 Apr 2021 17:45:19 +0200 Subject: [PATCH 26/45] Updated to new asset struct interface --- contracts/interfaces/IAaveIncentivesController.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index 4b49eb23..55f0db7d 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -4,9 +4,9 @@ pragma experimental ABIEncoderV2; interface IAaveIncentivesController { struct AssetData { - uint128 emissionPerSecond; - uint128 lastUpdateTimestamp; - uint256 index; + uint104 emissionPerSecond; + uint104 index; + uint40 lastUpdateTimestamp; } event RewardsAccrued(address indexed user, uint256 amount); From 2a19131b7af38bf5233e0d34f83b450635e03676 Mon Sep 17 00:00:00 2001 From: David Racero Date: Wed, 21 Apr 2021 18:00:00 +0200 Subject: [PATCH 27/45] feat: Updated to new interface of Incentives Controller --- .../interfaces/IAaveIncentivesController.sol | 35 ++++++++++--------- contracts/misc/UiPoolDataProvider.sol | 28 ++++++++------- .../misc/interfaces/IUiPoolDataProvider.sol | 6 ++-- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index 55f0db7d..efa132b2 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -3,19 +3,9 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IAaveIncentivesController { - struct AssetData { - uint104 emissionPerSecond; - uint104 index; - uint40 lastUpdateTimestamp; - } - event RewardsAccrued(address indexed user, uint256 amount); - event RewardsClaimed( - address indexed user, - address indexed to, - uint256 amount - ); + event RewardsClaimed(address indexed user, address indexed to, uint256 amount); event RewardsClaimed( address indexed user, @@ -26,7 +16,19 @@ interface IAaveIncentivesController { event ClaimerSet(address indexed user, address indexed claimer); - function assets(address underlying) external view returns (AssetData memory assets); + /* + * @dev Returns the configuration of the distribution for a certain asset + * @param asset The address of the reference asset of the distribution + * @return The asset index, the emission per second and the last updated timestamp + **/ + function getAssetData(address asset) + external + view + returns ( + uint256, + uint256, + uint256 + ); /** * @dev Whitelists an address to claim the rewards on behalf of another address @@ -50,7 +52,6 @@ interface IAaveIncentivesController { function configureAssets(address[] calldata assets, uint256[] calldata emissionsPerSecond) external; - /** * @dev Called by the corresponding asset on any update that affects the rewards distribution * @param asset The address of the user @@ -116,12 +117,12 @@ interface IAaveIncentivesController { function getUserAssetData(address user, address asset) external view returns (uint256); /** - * @dev for backward compatibility with previous implementation of the Incentives controller - */ + * @dev for backward compatibility with previous implementation of the Incentives controller + */ function REWARD_TOKEN() external view returns (address); /** - * @dev for backward compatibility with previous implementation of the Incentives controller - */ + * @dev for backward compatibility with previous implementation of the Incentives controller + */ function PRECISION() external view returns (uint8); } diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 7d2aef55..a3f25c05 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -131,21 +131,23 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives - IAaveIncentivesController.AssetData memory tokenIncentivesInfo = - incentivesController.assets(reserveData.aTokenAddress); - reserveData.aEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; - reserveData.aIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; - reserveData.aTokenIncentivesIndex = tokenIncentivesInfo.index; + ( + reserveData.aEmissionPerSecond, + reserveData.aIncentivesLastUpdateTimestamp, + reserveData.aTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.aTokenAddress); - tokenIncentivesInfo = incentivesController.assets(reserveData.stableDebtTokenAddress); - reserveData.sEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; - reserveData.sIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; - reserveData.sTokenIncentivesIndex = tokenIncentivesInfo.index; + ( + reserveData.sEmissionPerSecond, + reserveData.sIncentivesLastUpdateTimestamp, + reserveData.sTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); - tokenIncentivesInfo = incentivesController.assets(reserveData.variableDebtTokenAddress); - reserveData.vEmissionPerSecond = tokenIncentivesInfo.emissionPerSecond; - reserveData.vIncentivesLastUpdateTimestamp = tokenIncentivesInfo.lastUpdateTimestamp; - reserveData.vTokenIncentivesIndex = tokenIncentivesInfo.index; + ( + reserveData.vEmissionPerSecond, + reserveData.vIncentivesLastUpdateTimestamp, + reserveData.vTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); if (user != address(0)) { // incentives diff --git a/contracts/misc/interfaces/IUiPoolDataProvider.sol b/contracts/misc/interfaces/IUiPoolDataProvider.sol index 43e4e997..34f06d1c 100644 --- a/contracts/misc/interfaces/IUiPoolDataProvider.sol +++ b/contracts/misc/interfaces/IUiPoolDataProvider.sol @@ -43,9 +43,9 @@ interface IUiPoolDataProvider { uint256 stableRateSlope1; uint256 stableRateSlope2; // incentives - uint128 aEmissionPerSecond; - uint128 vEmissionPerSecond; - uint128 sEmissionPerSecond; + uint256 aEmissionPerSecond; + uint256 vEmissionPerSecond; + uint256 sEmissionPerSecond; uint256 aIncentivesLastUpdateTimestamp; uint256 vIncentivesLastUpdateTimestamp; uint256 sIncentivesLastUpdateTimestamp; From 9df1502f2262d0783cf2c8c0001066fe8b82f0af Mon Sep 17 00:00:00 2001 From: sendra Date: Wed, 21 Apr 2021 19:16:11 +0200 Subject: [PATCH 28/45] correct mainnet incentives controller --- tasks/deployments/deploy-UiPoolDataProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 1158fe90..984d5a13 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -16,7 +16,7 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider // aaveOracle: '', // }, [eEthereumNetwork.main]: { - incentivesController: '0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5', + incentivesController: '0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5', aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', }, [ePolygonNetwork.matic]: { From 7ffb0e573fbf48160d93b974bd530ff06d3aea0d Mon Sep 17 00:00:00 2001 From: David Racero Date: Thu, 22 Apr 2021 10:17:45 +0200 Subject: [PATCH 29/45] fix: Change the order of return variables of incentives getAssetData --- contracts/misc/UiPoolDataProvider.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index a3f25c05..bbd78f29 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -132,21 +132,21 @@ contract UiPoolDataProvider is IUiPoolDataProvider { // incentives ( + reserveData.aTokenIncentivesIndex, reserveData.aEmissionPerSecond, - reserveData.aIncentivesLastUpdateTimestamp, - reserveData.aTokenIncentivesIndex + reserveData.aIncentivesLastUpdateTimestamp ) = incentivesController.getAssetData(reserveData.aTokenAddress); ( + reserveData.sTokenIncentivesIndex, reserveData.sEmissionPerSecond, - reserveData.sIncentivesLastUpdateTimestamp, - reserveData.sTokenIncentivesIndex + reserveData.sIncentivesLastUpdateTimestamp ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); ( + reserveData.vTokenIncentivesIndex, reserveData.vEmissionPerSecond, - reserveData.vIncentivesLastUpdateTimestamp, - reserveData.vTokenIncentivesIndex + reserveData.vIncentivesLastUpdateTimestamp ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); if (user != address(0)) { From 50b1a5ff37dd669163a121b29ee068d1b9680307 Mon Sep 17 00:00:00 2001 From: David Racero Date: Fri, 23 Apr 2021 23:31:59 +0200 Subject: [PATCH 30/45] Added "build" badge from Github Actions --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1609baf9..658c7a91 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) +![Build pass](https://github.com/AAVE/protocol-v2/actions/workflows/node.js.yml/badge.svg) ``` .///. .///. //. .// `/////////////- `++:++` .++:++` :++` `++: `++:......---.` From ba51b6a048e3d26eb068bd7eebf8fd77908a0f35 Mon Sep 17 00:00:00 2001 From: David Racero Date: Fri, 23 Apr 2021 23:34:55 +0200 Subject: [PATCH 31/45] rename: Workflow name set to "Build" for better badge naming --- .github/workflows/node.js.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 094c2263..7e24fc10 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -1,4 +1,4 @@ -name: Aave Actions +name: Build on: push: From aeae16b22f5b83278aff3b623fde1df97b6a5d9c Mon Sep 17 00:00:00 2001 From: David Racero Date: Fri, 23 Apr 2021 23:44:09 +0200 Subject: [PATCH 32/45] readme: link Build badge to Github Actions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 658c7a91..d59473e7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) -![Build pass](https://github.com/AAVE/protocol-v2/actions/workflows/node.js.yml/badge.svg) +[![Build pass](https://github.com/AAVE/protocol-v2/actions/workflows/node.js.yml/badge.svg)](https://github.com/aave/protocol-v2/actions/workflows/node.js.yml) ``` .///. .///. //. .// `/////////////- `++:++` .++:++` :++` `++: `++:......---.` From 60dc2346c822e7faa6d7a31cb38b3d5d22c30cdc Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 12:26:30 +0200 Subject: [PATCH 33/45] fix: added try catch for incentives controller interactions --- contracts/misc/UiPoolDataProvider.sol | 78 ++++++++++++++++++--------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index a3f25c05..6a051f23 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -131,38 +131,61 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives - ( - reserveData.aEmissionPerSecond, - reserveData.aIncentivesLastUpdateTimestamp, - reserveData.aTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.aTokenAddress); + try incentivesController.getAssetData(reserveData.aTokenAddress) returns ( + uint256 aEmissionPerSecond, uint256 aIncentivesLastUpdateTimestamp, uint256 aTokenIncentivesIndex) { + + reserveData.aEmissionPerSecond = aEmissionPerSecond; + reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; + reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; + } catch Error(string memory /*reason*/) { + } + + try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( + uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { + + reserveData.vEmissionPerSecond = vEmissionPerSecond; + reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; + reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; + } catch Error(string memory /*reason*/) { + } - ( - reserveData.sEmissionPerSecond, - reserveData.sIncentivesLastUpdateTimestamp, - reserveData.sTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); - - ( - reserveData.vEmissionPerSecond, - reserveData.vIncentivesLastUpdateTimestamp, - reserveData.vTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); + try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( + uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { + + reserveData.sEmissionPerSecond = sEmissionPerSecond; + reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; + reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; + } catch Error(string memory /*reason*/) { + } if (user != address(0)) { // incentives - userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( + try incentivesController.getUserAssetData( user, reserveData.aTokenAddress - ); - userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( - user, - reserveData.stableDebtTokenAddress - ); - userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( + ) returns ( + uint256 aTokenincentivesUserIndex) { + userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) { + } + + try incentivesController.getUserAssetData( user, reserveData.variableDebtTokenAddress - ); + ) returns ( + uint256 vTokenincentivesUserIndex) { + userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) { + } + + try incentivesController.getUserAssetData( + user, + reserveData.stableDebtTokenAddress + ) returns ( + uint256 sTokenincentivesUserIndex) { + userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) { + } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; userReservesData[i].scaledATokenBalance = IAToken(reserveData.aTokenAddress) @@ -196,11 +219,16 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } + uint256 unclaimedRewards; + try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { + unclaimedRewards = rewards; + } catch Error (string memory) {} + return ( reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS), - incentivesController.getUserUnclaimedRewards(user) + unclaimedRewards ); } } From 60ee0c54eb8e880b1392cc9f69f4381015b2b20b Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 12:39:37 +0200 Subject: [PATCH 34/45] fix: added check if incentives contract is 0 --- contracts/misc/UiPoolDataProvider.sol | 85 +++++++++++---------------- 1 file changed, 33 insertions(+), 52 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 6a051f23..c24e8939 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -131,60 +131,41 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ); // incentives - try incentivesController.getAssetData(reserveData.aTokenAddress) returns ( - uint256 aEmissionPerSecond, uint256 aIncentivesLastUpdateTimestamp, uint256 aTokenIncentivesIndex) { - - reserveData.aEmissionPerSecond = aEmissionPerSecond; - reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; - reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; - } catch Error(string memory /*reason*/) { - } - - try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( - uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { - - reserveData.vEmissionPerSecond = vEmissionPerSecond; - reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; - reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; - } catch Error(string memory /*reason*/) { - } + if (address(0) != address(incentivesController)) { + ( + reserveData.aEmissionPerSecond, + reserveData.aIncentivesLastUpdateTimestamp, + reserveData.aTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.aTokenAddress); - try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( - uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { - - reserveData.sEmissionPerSecond = sEmissionPerSecond; - reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; - reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; - } catch Error(string memory /*reason*/) { + ( + reserveData.sEmissionPerSecond, + reserveData.sIncentivesLastUpdateTimestamp, + reserveData.sTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); + + ( + reserveData.vEmissionPerSecond, + reserveData.vIncentivesLastUpdateTimestamp, + reserveData.vTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); } if (user != address(0)) { // incentives - try incentivesController.getUserAssetData( - user, - reserveData.aTokenAddress - ) returns ( - uint256 aTokenincentivesUserIndex) { - userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) { - } - - try incentivesController.getUserAssetData( - user, - reserveData.variableDebtTokenAddress - ) returns ( - uint256 vTokenincentivesUserIndex) { - userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) { - } - - try incentivesController.getUserAssetData( - user, - reserveData.stableDebtTokenAddress - ) returns ( - uint256 sTokenincentivesUserIndex) { - userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) { + if (address(0) != address(incentivesController)) { + userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.aTokenAddress + ); + userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.stableDebtTokenAddress + ); + userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.variableDebtTokenAddress + ); } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -220,9 +201,9 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } uint256 unclaimedRewards; - try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { - unclaimedRewards = rewards; - } catch Error (string memory) {} + if (address(0) != address(incentivesController)) { + unclaimedRewards = incentivesController.getUserUnclaimedRewards(user); + } return ( reservesData, From 8b8736dc5a4956ae470990b3f4b05556b6cd5ab8 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 15:26:36 +0200 Subject: [PATCH 35/45] Back to try catch, but with also 0 address catching --- contracts/misc/UiPoolDataProvider.sol | 67 +++++++++++++++++---------- package-lock.json | 35 ++++++++------ 2 files changed, 64 insertions(+), 38 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index c24e8939..70aef7b9 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -132,40 +132,57 @@ contract UiPoolDataProvider is IUiPoolDataProvider { // incentives if (address(0) != address(incentivesController)) { - ( - reserveData.aEmissionPerSecond, - reserveData.aIncentivesLastUpdateTimestamp, - reserveData.aTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.aTokenAddress); + try incentivesController.getAssetData(reserveData.aTokenAddress) returns ( + uint256 aEmissionPerSecond, uint256 aIncentivesLastUpdateTimestamp, uint256 aTokenIncentivesIndex) { - ( - reserveData.sEmissionPerSecond, - reserveData.sIncentivesLastUpdateTimestamp, - reserveData.sTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); + reserveData.aEmissionPerSecond = aEmissionPerSecond; + reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; + reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; + } catch Error(string memory /*reason*/) {} - ( - reserveData.vEmissionPerSecond, - reserveData.vIncentivesLastUpdateTimestamp, - reserveData.vTokenIncentivesIndex - ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); + try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( + uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { + + reserveData.vEmissionPerSecond = vEmissionPerSecond; + reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; + reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; + } catch Error(string memory /*reason*/) {} + + try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( + uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { + + reserveData.sEmissionPerSecond = sEmissionPerSecond; + reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; + reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; + } catch Error(string memory /*reason*/) {} } if (user != address(0)) { // incentives if (address(0) != address(incentivesController)) { - userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( + try incentivesController.getUserAssetData( user, reserveData.aTokenAddress - ); - userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( - user, - reserveData.stableDebtTokenAddress - ); - userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( + ) returns ( + uint256 aTokenincentivesUserIndex) { + userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) {} + + try incentivesController.getUserAssetData( user, reserveData.variableDebtTokenAddress - ); + ) returns ( + uint256 vTokenincentivesUserIndex) { + userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) {} + + try incentivesController.getUserAssetData( + user, + reserveData.stableDebtTokenAddress + ) returns ( + uint256 sTokenincentivesUserIndex) { + userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; + } catch Error(string memory /*reason*/) {} } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -202,7 +219,9 @@ contract UiPoolDataProvider is IUiPoolDataProvider { uint256 unclaimedRewards; if (address(0) != address(incentivesController)) { - unclaimedRewards = incentivesController.getUserUnclaimedRewards(user); + // try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { + // unclaimedRewards = rewards; + // } catch Error (string memory) {} } return ( diff --git a/package-lock.json b/package-lock.json index 6cd1ef03..c5cc43eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7709,6 +7709,15 @@ "requires": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true, + "optional": true + } } }, "browserify-sign": { @@ -7819,9 +7828,9 @@ }, "dependencies": { "node-gyp-build": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", - "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "dev": true } } @@ -10891,14 +10900,6 @@ "requires": { "min-document": "^2.19.0", "process": "^0.11.10" - }, - "dependencies": { - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", - "dev": true - } } }, "got": { @@ -12575,6 +12576,12 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -14241,9 +14248,9 @@ }, "dependencies": { "node-gyp-build": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", - "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==", "dev": true } } From acc2207d81d136781735360f89bd513c33d6d245 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 15:57:26 +0200 Subject: [PATCH 36/45] added kovan config --- tasks/deployments/deploy-UiPoolDataProvider.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tasks/deployments/deploy-UiPoolDataProvider.ts b/tasks/deployments/deploy-UiPoolDataProvider.ts index 984d5a13..6cc07449 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -11,10 +11,10 @@ task(`deploy-${eContractid.UiPoolDataProvider}`, `Deploys the UiPoolDataProvider } const addressesByNetwork = { - // [eEthereumNetwork.kovan]: { - // incentivesController: '', - // aaveOracle: '', - // }, + [eEthereumNetwork.kovan]: { + incentivesController: '0x0000000000000000000000000000000000000000', + aaveOracle: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', + }, [eEthereumNetwork.main]: { incentivesController: '0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5', aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', From f5f3adeb0f83f229ddf879346dbb5707bcb16e45 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 16:29:30 +0200 Subject: [PATCH 37/45] removed error from catch so it catches everything --- contracts/misc/UiPoolDataProvider.sol | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 70aef7b9..7a77c43a 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -138,7 +138,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.aEmissionPerSecond = aEmissionPerSecond; reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; - } catch Error(string memory /*reason*/) {} + } catch {} try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { @@ -146,7 +146,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.vEmissionPerSecond = vEmissionPerSecond; reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; - } catch Error(string memory /*reason*/) {} + } catch {} try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { @@ -154,7 +154,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.sEmissionPerSecond = sEmissionPerSecond; reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; - } catch Error(string memory /*reason*/) {} + } catch {} } if (user != address(0)) { @@ -166,7 +166,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 aTokenincentivesUserIndex) { userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) {} + } catch {} try incentivesController.getUserAssetData( user, @@ -174,7 +174,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 vTokenincentivesUserIndex) { userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) {} + } catch {} try incentivesController.getUserAssetData( user, @@ -182,7 +182,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 sTokenincentivesUserIndex) { userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; - } catch Error(string memory /*reason*/) {} + } catch {} } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -219,9 +219,9 @@ contract UiPoolDataProvider is IUiPoolDataProvider { uint256 unclaimedRewards; if (address(0) != address(incentivesController)) { - // try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { - // unclaimedRewards = rewards; - // } catch Error (string memory) {} + try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { + unclaimedRewards = rewards; + } catch {} } return ( From d36b9fd14c0cf96dc927531d814713785f486f0a Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 16:43:21 +0200 Subject: [PATCH 38/45] added other catch --- contracts/misc/UiPoolDataProvider.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 7a77c43a..bbb8290d 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -138,7 +138,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.aEmissionPerSecond = aEmissionPerSecond; reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { @@ -146,7 +146,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.vEmissionPerSecond = vEmissionPerSecond; reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { @@ -154,7 +154,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { reserveData.sEmissionPerSecond = sEmissionPerSecond; reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} } if (user != address(0)) { @@ -166,7 +166,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 aTokenincentivesUserIndex) { userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} try incentivesController.getUserAssetData( user, @@ -174,7 +174,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 vTokenincentivesUserIndex) { userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} try incentivesController.getUserAssetData( user, @@ -182,7 +182,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider { ) returns ( uint256 sTokenincentivesUserIndex) { userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; - } catch {} + } catch Error(string memory) {} catch (bytes memory) {} } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; From c1c2cffd2671678c02381c862233429d76145cf1 Mon Sep 17 00:00:00 2001 From: sendra Date: Mon, 26 Apr 2021 17:51:39 +0200 Subject: [PATCH 39/45] remove try catch as it doesnt catch the implementation exeption --- contracts/misc/UiPoolDataProvider.sol | 68 +++++++++------------------ 1 file changed, 22 insertions(+), 46 deletions(-) diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index bbb8290d..63dd7a1c 100644 --- a/contracts/misc/UiPoolDataProvider.sol +++ b/contracts/misc/UiPoolDataProvider.sol @@ -132,57 +132,40 @@ contract UiPoolDataProvider is IUiPoolDataProvider { // incentives if (address(0) != address(incentivesController)) { - try incentivesController.getAssetData(reserveData.aTokenAddress) returns ( - uint256 aEmissionPerSecond, uint256 aIncentivesLastUpdateTimestamp, uint256 aTokenIncentivesIndex) { + ( + reserveData.aEmissionPerSecond, + reserveData.aIncentivesLastUpdateTimestamp, + reserveData.aTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.aTokenAddress); - reserveData.aEmissionPerSecond = aEmissionPerSecond; - reserveData.aIncentivesLastUpdateTimestamp = aIncentivesLastUpdateTimestamp; - reserveData.aTokenIncentivesIndex = aTokenIncentivesIndex; - } catch Error(string memory) {} catch (bytes memory) {} + ( + reserveData.sEmissionPerSecond, + reserveData.sIncentivesLastUpdateTimestamp, + reserveData.sTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress); - try incentivesController.getAssetData(reserveData.variableDebtTokenAddress) returns ( - uint256 vEmissionPerSecond, uint256 vIncentivesLastUpdateTimestamp, uint256 vTokenIncentivesIndex) { - - reserveData.vEmissionPerSecond = vEmissionPerSecond; - reserveData.vIncentivesLastUpdateTimestamp = vIncentivesLastUpdateTimestamp; - reserveData.vTokenIncentivesIndex = vTokenIncentivesIndex; - } catch Error(string memory) {} catch (bytes memory) {} - - try incentivesController.getAssetData(reserveData.stableDebtTokenAddress) returns ( - uint256 sEmissionPerSecond, uint256 sIncentivesLastUpdateTimestamp, uint256 sTokenIncentivesIndex) { - - reserveData.sEmissionPerSecond = sEmissionPerSecond; - reserveData.sIncentivesLastUpdateTimestamp = sIncentivesLastUpdateTimestamp; - reserveData.sTokenIncentivesIndex = sTokenIncentivesIndex; - } catch Error(string memory) {} catch (bytes memory) {} + ( + reserveData.vEmissionPerSecond, + reserveData.vIncentivesLastUpdateTimestamp, + reserveData.vTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress); } if (user != address(0)) { // incentives if (address(0) != address(incentivesController)) { - try incentivesController.getUserAssetData( + userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( user, reserveData.aTokenAddress - ) returns ( - uint256 aTokenincentivesUserIndex) { - userReservesData[i].aTokenincentivesUserIndex = aTokenincentivesUserIndex; - } catch Error(string memory) {} catch (bytes memory) {} - - try incentivesController.getUserAssetData( + ); + userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( user, reserveData.variableDebtTokenAddress - ) returns ( - uint256 vTokenincentivesUserIndex) { - userReservesData[i].vTokenincentivesUserIndex = vTokenincentivesUserIndex; - } catch Error(string memory) {} catch (bytes memory) {} - - try incentivesController.getUserAssetData( + ); + userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( user, reserveData.stableDebtTokenAddress - ) returns ( - uint256 sTokenincentivesUserIndex) { - userReservesData[i].sTokenincentivesUserIndex = sTokenincentivesUserIndex; - } catch Error(string memory) {} catch (bytes memory) {} + ); } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; @@ -217,18 +200,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { } } - uint256 unclaimedRewards; - if (address(0) != address(incentivesController)) { - try incentivesController.getUserUnclaimedRewards(user) returns (uint256 rewards) { - unclaimedRewards = rewards; - } catch {} - } - return ( reservesData, userReservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS), - unclaimedRewards + incentivesController.getUserUnclaimedRewards(user) ); } } From 0b8952887168fb40629fcec3a7d59f087706b3d4 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 27 Apr 2021 09:44:18 +0200 Subject: [PATCH 40/45] doc: added signature paramters to natspec docs --- contracts/misc/WETHGateway.sol | 4 ++++ contracts/protocol/lendingpool/LendingPool.sol | 2 ++ 2 files changed, 6 insertions(+) diff --git a/contracts/misc/WETHGateway.sol b/contracts/misc/WETHGateway.sol index 1ddceaa0..39ecf909 100644 --- a/contracts/misc/WETHGateway.sol +++ b/contracts/misc/WETHGateway.sol @@ -136,6 +136,10 @@ contract WETHGateway is IWETHGateway, Ownable { * @param lendingPool address of the targeted underlying lending pool * @param amount amount of aWETH to withdraw and receive native ETH * @param to address of the user who will receive native ETH + * @param deadline validity deadline of permit and so depositWithPermit signature + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig */ function withdrawETHWithPermit( address lendingPool, diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index a86dc4aa..664b2fe3 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -247,6 +247,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * is a different wallet * @param referralCode Code used to register the integrator originating the operation, for potential rewards. * 0 if the action is executed directly by the user, without any middle-man + * @param deadline validity deadline of permit and so depositWithPermit signature * @param permitV V parameter of ERC712 permit sig * @param permitR R parameter of ERC712 permit sig * @param permitS S parameter of ERC712 permit sig @@ -275,6 +276,7 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the * user calling the function if he wants to reduce/remove his own debt, or the address of any other * other borrower whose debt should be removed + * @param deadline validity deadline of permit and so depositWithPermit signature * @param permitV V parameter of ERC712 permit sig * @param permitR R parameter of ERC712 permit sig * @param permitS S parameter of ERC712 permit sig From b294a96ef45d9c133042b471c36341157a28f97f Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 27 Apr 2021 09:45:49 +0200 Subject: [PATCH 41/45] refactor: changed function definitions order for more clarity --- .../protocol/lendingpool/LendingPool.sol | 118 +++++++++--------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/contracts/protocol/lendingpool/LendingPool.sol b/contracts/protocol/lendingpool/LendingPool.sol index 664b2fe3..def5606c 100644 --- a/contracts/protocol/lendingpool/LendingPool.sol +++ b/contracts/protocol/lendingpool/LendingPool.sol @@ -111,6 +111,35 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage _executeDeposit(asset, amount, onBehalfOf, referralCode); } + /** + * @notice Deposit with transfer approval of asset to be deposited done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the underlying asset to deposit + * @param amount The amount to be deposited + * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user + * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens + * is a different wallet + * @param referralCode Code used to register the integrator originating the operation, for potential rewards. + * 0 if the action is executed directly by the user, without any middle-man + * @param deadline validity deadline of permit and so depositWithPermit signature + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + **/ + function depositWithPermit( + address asset, + uint256 amount, + address onBehalfOf, + uint16 referralCode, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external override { + IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); + _executeDeposit(asset, amount, onBehalfOf, referralCode); + } + /** * @dev Withdraws an `amount` of underlying asset from the reserve, burning the equivalent aTokens owned * E.g. User has 100 aUSDC, calls withdraw() and receives 100 USDC, burning the 100 aUSDC @@ -188,6 +217,36 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage return _executeRepay(asset, amount, rateMode, onBehalfOf); } + /** + * @notice Repay with transfer approval of asset to be repaid done via permit function + * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 + * @param asset The address of the borrowed underlying asset previously borrowed + * @param amount The amount to repay + * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` + * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable + * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the + * user calling the function if he wants to reduce/remove his own debt, or the address of any other + * other borrower whose debt should be removed + * @param deadline validity deadline of permit and so depositWithPermit signature + * @param permitV V parameter of ERC712 permit sig + * @param permitR R parameter of ERC712 permit sig + * @param permitS S parameter of ERC712 permit sig + * @return The final amount repaid + **/ + function repayWithPermit( + address asset, + uint256 amount, + uint256 rateMode, + address onBehalfOf, + uint256 deadline, + uint8 permitV, + bytes32 permitR, + bytes32 permitS + ) external override returns (uint256) { + IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); + return _executeRepay(asset, amount, rateMode, onBehalfOf); + } + /** * @dev Allows a borrower to swap his debt between stable and variable mode, or viceversa * @param asset The address of the underlying asset borrowed @@ -237,65 +296,6 @@ contract LendingPool is VersionedInitializable, ILendingPool, LendingPoolStorage emit Swap(asset, msg.sender, rateMode); } - /** - * @notice Deposit with transfer approval of asset to be deposited done via permit function - * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 - * @param asset The address of the underlying asset to deposit - * @param amount The amount to be deposited - * @param onBehalfOf The address that will receive the aTokens, same as msg.sender if the user - * wants to receive them on his own wallet, or a different address if the beneficiary of aTokens - * is a different wallet - * @param referralCode Code used to register the integrator originating the operation, for potential rewards. - * 0 if the action is executed directly by the user, without any middle-man - * @param deadline validity deadline of permit and so depositWithPermit signature - * @param permitV V parameter of ERC712 permit sig - * @param permitR R parameter of ERC712 permit sig - * @param permitS S parameter of ERC712 permit sig - **/ - function depositWithPermit( - address asset, - uint256 amount, - address onBehalfOf, - uint16 referralCode, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external override { - IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); - _executeDeposit(asset, amount, onBehalfOf, referralCode); - } - - /** - * @notice Repay with transfer approval of asset to be repaid done via permit function - * see: https://eips.ethereum.org/EIPS/eip-2612 and https://eips.ethereum.org/EIPS/eip-713 - * @param asset The address of the borrowed underlying asset previously borrowed - * @param amount The amount to repay - * - Send the value type(uint256).max in order to repay the whole debt for `asset` on the specific `debtMode` - * @param rateMode The interest rate mode at of the debt the user wants to repay: 1 for Stable, 2 for Variable - * @param onBehalfOf Address of the user who will get his debt reduced/removed. Should be the address of the - * user calling the function if he wants to reduce/remove his own debt, or the address of any other - * other borrower whose debt should be removed - * @param deadline validity deadline of permit and so depositWithPermit signature - * @param permitV V parameter of ERC712 permit sig - * @param permitR R parameter of ERC712 permit sig - * @param permitS S parameter of ERC712 permit sig - * @return The final amount repaid - **/ - function repayWithPermit( - address asset, - uint256 amount, - uint256 rateMode, - address onBehalfOf, - uint256 deadline, - uint8 permitV, - bytes32 permitR, - bytes32 permitS - ) external override returns (uint256) { - IERC20WithPermit(asset).permit(msg.sender, address(this), amount, deadline, permitV, permitR, permitS); - return _executeRepay(asset, amount, rateMode, onBehalfOf); - } - /** * @dev Rebalances the stable interest rate of a user to the current stable rate defined on the reserve. * - Users can be rebalanced if the following conditions are satisfied: From 10a083d8f054d0b9705f7823505fce6eae8a250a Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Tue, 27 Apr 2021 09:46:39 +0200 Subject: [PATCH 42/45] fix: typo --- test-suites/test-aave/scenario.spec.ts | 2 +- test-suites/test-amm/scenario.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-suites/test-aave/scenario.spec.ts b/test-suites/test-aave/scenario.spec.ts index e658948a..3a5ee6eb 100644 --- a/test-suites/test-aave/scenario.spec.ts +++ b/test-suites/test-aave/scenario.spec.ts @@ -35,7 +35,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => { for (const story of scenario.stories) { it(story.description, async function () { - // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors + // Retry the test scenarios up to 4 times if an error happens, due to erratic HEVM network errors this.retries(4); await executeStory(story, testEnv); }); diff --git a/test-suites/test-amm/scenario.spec.ts b/test-suites/test-amm/scenario.spec.ts index f9c4d78b..4f663e4f 100644 --- a/test-suites/test-amm/scenario.spec.ts +++ b/test-suites/test-amm/scenario.spec.ts @@ -35,7 +35,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => { for (const story of scenario.stories) { it(story.description, async function () { - // Retry the test scenarios up to 4 times if an error happens, due erratic HEVM network errors + // Retry the test scenarios up to 4 times if an error happens, due to erratic HEVM network errors this.retries(4); await executeStory(story, testEnv); }); From ada4994c7f39a6c10cd64418da4c0b90e1329e5d Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 27 Apr 2021 15:31:11 +0200 Subject: [PATCH 43/45] refactor: Replaced balanceOf() with scaledBalanceOf() + normalizedIncome/debt --- .../protocol/libraries/logic/GenericLogic.sol | 25 +- package-lock.json | 313 +++++++++--------- 2 files changed, 184 insertions(+), 154 deletions(-) diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol index d4081dda..e07dc3e2 100644 --- a/contracts/protocol/libraries/logic/GenericLogic.sol +++ b/contracts/protocol/libraries/logic/GenericLogic.sol @@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2; import {SafeMath} from '../../../dependencies/openzeppelin/contracts/SafeMath.sol'; import {IERC20} from '../../../dependencies/openzeppelin/contracts/IERC20.sol'; +import {IScaledBalanceToken} from '../../../interfaces/IScaledBalanceToken.sol'; import {ReserveLogic} from './ReserveLogic.sol'; import {ReserveConfiguration} from '../configuration/ReserveConfiguration.sol'; import {UserConfiguration} from '../configuration/UserConfiguration.sol'; @@ -130,6 +131,8 @@ library GenericLogic { uint256 avgLtv; uint256 avgLiquidationThreshold; uint256 reservesLength; + uint256 normalizedIncome; + uint256 normalizedDebt; bool healthFactorBelowThreshold; address currentReserveAddress; bool usageAsCollateralEnabled; @@ -186,7 +189,11 @@ library GenericLogic { vars.reserveUnitPrice = IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress); if (vars.liquidationThreshold != 0 && userConfig.isUsingAsCollateral(vars.i)) { - vars.compoundedLiquidityBalance = IERC20(currentReserve.aTokenAddress).balanceOf(user); + vars.compoundedLiquidityBalance = IScaledBalanceToken(currentReserve.aTokenAddress).scaledBalanceOf(user); + if(vars.compoundedLiquidityBalance > 0){ + vars.normalizedIncome = currentReserve.getNormalizedIncome(); + vars.compoundedLiquidityBalance = vars.compoundedLiquidityBalance.rayMul(vars.normalizedIncome); + } uint256 liquidityBalanceETH = vars.reserveUnitPrice.mul(vars.compoundedLiquidityBalance).div(vars.tokenUnit); @@ -200,12 +207,18 @@ library GenericLogic { } if (userConfig.isBorrowing(vars.i)) { - vars.compoundedBorrowBalance = IERC20(currentReserve.stableDebtTokenAddress).balanceOf( + vars.compoundedBorrowBalance = + IScaledBalanceToken(currentReserve.variableDebtTokenAddress).scaledBalanceOf(user); + + if(vars.compoundedBorrowBalance > 0) { + vars.normalizedDebt = currentReserve.getNormalizedDebt(); + vars.compoundedLiquidityBalance = vars.compoundedBorrowBalance.rayMul(vars.normalizedDebt); + } + + vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(IERC20(currentReserve.stableDebtTokenAddress).balanceOf( user - ); - vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add( - IERC20(currentReserve.variableDebtTokenAddress).balanceOf(user) - ); + )); + vars.totalDebtInETH = vars.totalDebtInETH.add( vars.reserveUnitPrice.mul(vars.compoundedBorrowBalance).div(vars.tokenUnit) diff --git a/package-lock.json b/package-lock.json index 4b51bc02..6cd1ef03 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3118,7 +3118,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5530,8 +5529,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -6370,36 +6368,6 @@ "@ethersproject/strings": ">=5.0.0-beta.130" } }, - "@ethersproject/abstract-provider": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.0.8.tgz", - "integrity": "sha512-fqJXkewcGdi8LogKMgRyzc/Ls2js07yor7+g9KfPs09uPOcQLg7cc34JN+lk34HH9gg2HU0DIA5797ZR8znkfw==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/networks": "^5.0.7", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/transactions": "^5.0.9", - "@ethersproject/web": "^5.0.12" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.0.10.tgz", - "integrity": "sha512-irx7kH7FDAeW7QChDPW19WsxqeB1d3XLyOLSXm0bfPqL1SS07LXWltBJUBUxqC03ORpAOcM3JQj57DU8JnVY2g==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/abstract-provider": "^5.0.8", - "@ethersproject/bignumber": "^5.0.13", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7" - } - }, "@ethersproject/address": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.0.9.tgz", @@ -6414,16 +6382,6 @@ "@ethersproject/rlp": "^5.0.7" } }, - "@ethersproject/base64": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.0.7.tgz", - "integrity": "sha512-S5oh5DVfCo06xwJXT8fQC68mvJfgScTl2AXvbYMsHNfIBTDb084Wx4iA9MNlEReOv6HulkS+gyrUM/j3514rSw==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/bytes": "^5.0.9" - } - }, "@ethersproject/bignumber": { "version": "5.0.13", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.0.13.tgz", @@ -6491,16 +6449,6 @@ "dev": true, "optional": true }, - "@ethersproject/networks": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.0.7.tgz", - "integrity": "sha512-dI14QATndIcUgcCBL1c5vUr/YsI5cCHLN81rF7PU+yS7Xgp2/Rzbr9+YqpC6NBXHFUASjh6GpKqsVMpufAL0BQ==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/logger": "^5.0.8" - } - }, "@ethersproject/properties": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.0.7.tgz", @@ -6565,20 +6513,6 @@ "@ethersproject/signing-key": "^5.0.8" } }, - "@ethersproject/web": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.0.12.tgz", - "integrity": "sha512-gVxS5iW0bgidZ76kr7LsTxj4uzN5XpCLzvZrLp8TP+4YgxHfCeetFyQkRPgBEAJdNrexdSBayvyJvzGvOq0O8g==", - "dev": true, - "optional": true, - "requires": { - "@ethersproject/base64": "^5.0.7", - "@ethersproject/bytes": "^5.0.9", - "@ethersproject/logger": "^5.0.8", - "@ethersproject/properties": "^5.0.7", - "@ethersproject/strings": "^5.0.8" - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -7775,15 +7709,6 @@ "requires": { "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", - "dev": true, - "optional": true - } } }, "browserify-sign": { @@ -7891,6 +7816,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } } }, "bytes": { @@ -7991,16 +7924,6 @@ } } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, "caniuse-lite": { "version": "1.0.30001174", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001174.tgz", @@ -8519,7 +8442,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -8745,7 +8667,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -10915,8 +10836,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -10924,17 +10844,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -10982,6 +10891,14 @@ "requires": { "min-document": "^2.19.0", "process": "^0.11.10" + }, + "dependencies": { + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "dev": true + } } }, "got": { @@ -11042,7 +10959,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -11080,8 +10996,7 @@ "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" }, "has-to-string-tag-x": { "version": "1.4.1", @@ -11354,8 +11269,7 @@ "is-callable": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", - "dev": true + "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" }, "is-ci": { "version": "2.0.0", @@ -11378,8 +11292,7 @@ "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" }, "is-descriptor": { "version": "1.0.2", @@ -11428,8 +11341,7 @@ "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" }, "is-object": { "version": "1.0.2", @@ -11458,7 +11370,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, "requires": { "has-symbols": "^1.0.1" } @@ -11474,7 +11385,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "dev": true, "requires": { "has-symbols": "^1.0.1" } @@ -12317,8 +12227,7 @@ "object-inspect": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", - "dev": true + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" }, "object-is": { "version": "1.1.4", @@ -12328,13 +12237,33 @@ "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object-visit": { "version": "1.0.1", @@ -12349,12 +12278,32 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", "has-symbols": "^1.0.1", "object-keys": "^1.1.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "object.getownpropertydescriptors": { @@ -12626,12 +12575,6 @@ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -12892,22 +12835,71 @@ }, "dependencies": { "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + } } } } @@ -12995,6 +12987,15 @@ "uuid": "^3.3.2" } }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -13653,13 +13654,34 @@ "call-bind": "^1.0.0", "define-properties": "^1.1.3", "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.18.0-next.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", + "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.0", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.1", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + } } }, "string.prototype.trimend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -13669,7 +13691,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", - "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3" @@ -13856,15 +13877,6 @@ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", "dev": true - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, @@ -14226,6 +14238,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.7.0.tgz", + "integrity": "sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w==", + "dev": true + } } }, "utf8": { @@ -15204,7 +15224,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -15761,7 +15780,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -15787,8 +15805,7 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-to-string-tag-x": { "version": "1.4.1", From 45acc0b8545b1fb6d0a22d679f85501caeed78ae Mon Sep 17 00:00:00 2001 From: The3D Date: Tue, 27 Apr 2021 17:21:36 +0200 Subject: [PATCH 44/45] refactor: improved variables naming --- .../protocol/libraries/logic/GenericLogic.sol | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/contracts/protocol/libraries/logic/GenericLogic.sol b/contracts/protocol/libraries/logic/GenericLogic.sol index e07dc3e2..5722dd2b 100644 --- a/contracts/protocol/libraries/logic/GenericLogic.sol +++ b/contracts/protocol/libraries/logic/GenericLogic.sol @@ -117,10 +117,12 @@ library GenericLogic { } struct CalculateUserAccountDataVars { - uint256 reserveUnitPrice; - uint256 tokenUnit; - uint256 compoundedLiquidityBalance; - uint256 compoundedBorrowBalance; + uint256 assetPrice; + uint256 assetUnit; + uint256 userBalance; + uint256 userBalanceETH; + uint256 userDebt; + uint256 userDebtETH; uint256 decimals; uint256 ltv; uint256 liquidationThreshold; @@ -185,44 +187,41 @@ library GenericLogic { .configuration .getParams(); - vars.tokenUnit = 10**vars.decimals; - vars.reserveUnitPrice = IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress); + vars.assetUnit = 10**vars.decimals; + vars.assetPrice = IPriceOracleGetter(oracle).getAssetPrice(vars.currentReserveAddress); if (vars.liquidationThreshold != 0 && userConfig.isUsingAsCollateral(vars.i)) { - vars.compoundedLiquidityBalance = IScaledBalanceToken(currentReserve.aTokenAddress).scaledBalanceOf(user); - if(vars.compoundedLiquidityBalance > 0){ + vars.userBalance = IScaledBalanceToken(currentReserve.aTokenAddress).scaledBalanceOf(user); + if (vars.userBalance > 0) { vars.normalizedIncome = currentReserve.getNormalizedIncome(); - vars.compoundedLiquidityBalance = vars.compoundedLiquidityBalance.rayMul(vars.normalizedIncome); + vars.userBalance = vars.userBalance.rayMul(vars.normalizedIncome); } - uint256 liquidityBalanceETH = - vars.reserveUnitPrice.mul(vars.compoundedLiquidityBalance).div(vars.tokenUnit); + vars.userBalanceETH = vars.assetPrice.mul(vars.userBalance).div(vars.assetUnit); - vars.totalCollateralInETH = vars.totalCollateralInETH.add(liquidityBalanceETH); + vars.totalCollateralInETH = vars.totalCollateralInETH.add(vars.userBalanceETH); - vars.avgLtv = vars.avgLtv.add(liquidityBalanceETH.mul(vars.ltv)); + vars.avgLtv = vars.avgLtv.add(vars.userBalanceETH.mul(vars.ltv)); vars.avgLiquidationThreshold = vars.avgLiquidationThreshold.add( - liquidityBalanceETH.mul(vars.liquidationThreshold) + vars.userBalanceETH.mul(vars.liquidationThreshold) ); } if (userConfig.isBorrowing(vars.i)) { - vars.compoundedBorrowBalance = - IScaledBalanceToken(currentReserve.variableDebtTokenAddress).scaledBalanceOf(user); - - if(vars.compoundedBorrowBalance > 0) { + vars.userDebt = IScaledBalanceToken(currentReserve.variableDebtTokenAddress) + .scaledBalanceOf(user); + + if (vars.userDebt > 0) { vars.normalizedDebt = currentReserve.getNormalizedDebt(); - vars.compoundedLiquidityBalance = vars.compoundedBorrowBalance.rayMul(vars.normalizedDebt); + vars.userDebt = vars.userDebt.rayMul(vars.normalizedDebt); } - vars.compoundedBorrowBalance = vars.compoundedBorrowBalance.add(IERC20(currentReserve.stableDebtTokenAddress).balanceOf( - user - )); - - - vars.totalDebtInETH = vars.totalDebtInETH.add( - vars.reserveUnitPrice.mul(vars.compoundedBorrowBalance).div(vars.tokenUnit) + vars.userDebt = vars.userDebt.add( + IERC20(currentReserve.stableDebtTokenAddress).balanceOf(user) ); + vars.userDebtETH = vars.assetPrice.mul(vars.userDebt).div(vars.assetUnit); + vars.totalDebtInETH = vars.totalDebtInETH.add(vars.userDebtETH); + } } From 39ab410ba58429eb5231d98f90076403112bca60 Mon Sep 17 00:00:00 2001 From: Hadrien Charlanes Date: Wed, 5 May 2021 13:05:02 +0200 Subject: [PATCH 45/45] fix: grammar comment --- test-suites/test-aave/scenario.spec.ts | 2 +- test-suites/test-amm/scenario.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-suites/test-aave/scenario.spec.ts b/test-suites/test-aave/scenario.spec.ts index 3a5ee6eb..8eeb0a95 100644 --- a/test-suites/test-aave/scenario.spec.ts +++ b/test-suites/test-aave/scenario.spec.ts @@ -35,7 +35,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => { for (const story of scenario.stories) { it(story.description, async function () { - // Retry the test scenarios up to 4 times if an error happens, due to erratic HEVM network errors + // Retry the test scenarios up to 4 times in case random HEVM network errors happen this.retries(4); await executeStory(story, testEnv); }); diff --git a/test-suites/test-amm/scenario.spec.ts b/test-suites/test-amm/scenario.spec.ts index 4f663e4f..0e457217 100644 --- a/test-suites/test-amm/scenario.spec.ts +++ b/test-suites/test-amm/scenario.spec.ts @@ -35,7 +35,7 @@ fs.readdirSync(scenarioFolder).forEach((file) => { for (const story of scenario.stories) { it(story.description, async function () { - // Retry the test scenarios up to 4 times if an error happens, due to erratic HEVM network errors + // Retry the test scenarios up to 4 times in case random HEVM network errors happen this.retries(4); await executeStory(story, testEnv); });