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: diff --git a/README.md b/README.md index 1609baf9..d59473e7 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)](https://github.com/aave/protocol-v2/actions/workflows/node.js.yml) ``` .///. .///. //. .// `/////////////- `++:++` .++:++` :++` `++: `++:......---.` diff --git a/contracts/interfaces/IAaveIncentivesController.sol b/contracts/interfaces/IAaveIncentivesController.sol index c049bd77..efa132b2 100644 --- a/contracts/interfaces/IAaveIncentivesController.sol +++ b/contracts/interfaces/IAaveIncentivesController.sol @@ -3,9 +3,126 @@ pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IAaveIncentivesController { + 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, + address indexed claimer, + uint256 amount + ); + + event ClaimerSet(address indexed user, address indexed claimer); + + /* + * @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 + * @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); + + /** + * @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); } diff --git a/contracts/misc/UiPoolDataProvider.sol b/contracts/misc/UiPoolDataProvider.sol index 65fdc4dd..63dd7a1c 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'; @@ -24,6 +25,13 @@ contract UiPoolDataProvider is IUiPoolDataProvider { using UserConfiguration for DataTypes.UserConfigurationMap; address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96; + IAaveIncentivesController public immutable incentivesController; + IPriceOracleGetter public immutable oracle; + + constructor(IAaveIncentivesController _incentivesController, IPriceOracleGetter _oracle) public { + incentivesController = _incentivesController; + oracle = _oracle; + } function getInterestRateStrategySlopes(DefaultReserveInterestRateStrategy interestRateStrategy) internal @@ -50,11 +58,11 @@ contract UiPoolDataProvider is IUiPoolDataProvider { returns ( AggregatedReserveData[] memory, UserReserveData[] memory, + uint256, uint256 ) { ILendingPool lendingPool = ILendingPool(provider.getLendingPool()); - IPriceOracleGetter oracle = IPriceOracleGetter(provider.getPriceOracle()); address[] memory reserves = lendingPool.getReservesList(); DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user); @@ -122,7 +130,43 @@ contract UiPoolDataProvider is IUiPoolDataProvider { DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress) ); + // incentives + if (address(0) != address(incentivesController)) { + ( + reserveData.aEmissionPerSecond, + reserveData.aIncentivesLastUpdateTimestamp, + reserveData.aTokenIncentivesIndex + ) = incentivesController.getAssetData(reserveData.aTokenAddress); + + ( + 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 + if (address(0) != address(incentivesController)) { + userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.aTokenAddress + ); + userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.variableDebtTokenAddress + ); + userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData( + user, + reserveData.stableDebtTokenAddress + ); + } // user reserve data userReservesData[i].underlyingAsset = reserveData.underlyingAsset; userReservesData[i].scaledATokenBalance = IAToken(reserveData.aTokenAddress) @@ -155,6 +199,12 @@ 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 81a553e8..34f06d1c 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,12 +42,17 @@ interface IUiPoolDataProvider { uint256 variableRateSlope2; uint256 stableRateSlope1; uint256 stableRateSlope2; + // incentives + uint256 aEmissionPerSecond; + uint256 vEmissionPerSecond; + uint256 sEmissionPerSecond; + uint256 aIncentivesLastUpdateTimestamp; + uint256 vIncentivesLastUpdateTimestamp; + uint256 sIncentivesLastUpdateTimestamp; + uint256 aTokenIncentivesIndex; + uint256 vTokenIncentivesIndex; + uint256 sTokenIncentivesIndex; } - // - // struct ReserveData { - // uint256 averageStableBorrowRate; - // uint256 totalLiquidity; - // } struct UserReserveData { address underlyingAsset; @@ -56,38 +62,19 @@ interface IUiPoolDataProvider { uint256 scaledVariableDebt; uint256 principalStableDebt; uint256 stableBorrowLastUpdateTimestamp; + // incentives + uint256 aTokenincentivesUserIndex; + uint256 vTokenincentivesUserIndex; + uint256 sTokenincentivesUserIndex; } - // - // struct ATokenSupplyData { - // string name; - // string symbol; - // uint8 decimals; - // uint256 totalSupply; - // address aTokenAddress; - // } - function getReservesData(ILendingPoolAddressesProvider provider, address user) external view returns ( AggregatedReserveData[] memory, UserReserveData[] memory, + uint256, uint256 ); - - // 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); } 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-lock.json b/package-lock.json index 4b51bc02..c5cc43eb 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", @@ -7778,9 +7712,9 @@ }, "dependencies": { "bn.js": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "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 } @@ -7891,6 +7825,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "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 + } } }, "bytes": { @@ -7991,16 +7933,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 +8451,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 +8676,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 +10845,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 +10853,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", @@ -11042,7 +10960,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 +10997,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 +11270,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 +11293,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 +11342,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 +11371,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 +11386,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 +12228,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 +12238,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 +12279,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": { @@ -12892,22 +12842,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 +12994,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 +13661,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 +13698,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 +13884,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 +14245,14 @@ "dev": true, "requires": { "node-gyp-build": "^4.2.0" + }, + "dependencies": { + "node-gyp-build": { + "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 + } } }, "utf8": { @@ -15204,7 +15231,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 +15787,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 +15812,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 acd92fc0..699061c5 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,11 @@ "ci:clean": "rm -rf ./artifacts ./cache ./types", "print-contracts:kovan": "npm run hardhat:kovan -- print-contracts", "print-contracts:main": "npm run hardhat:main -- print-contracts", - "print-contracts:ropsten": "npm run hardhat:ropsten -- print-contracts", - "dev:deployUIProvider": "npm run hardhat:kovan deploy-UiPoolDataProvider", + "print-contracts:ropsten": "npm run hardhat:main -- print-contracts", + "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", "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..6cc07449 100644 --- a/tasks/deployments/deploy-UiPoolDataProvider.ts +++ b/tasks/deployments/deploy-UiPoolDataProvider.ts @@ -1,27 +1,44 @@ 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.') .setAction(async ({ verify }, localBRE) => { await localBRE.run('set-DRE'); - if (!localBRE.network.config.chainId) { throw new Error('INVALID_CHAIN_ID'); } + const addressesByNetwork = { + [eEthereumNetwork.kovan]: { + incentivesController: '0x0000000000000000000000000000000000000000', + aaveOracle: '0x8fb777d67e9945e2c01936e319057f9d41d559e6', + }, + [eEthereumNetwork.main]: { + incentivesController: '0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5', + aaveOracle: '0xa50ba011c48153de246e5192c8f9258a2ba79ca9', + }, + [ePolygonNetwork.matic]: { + incentivesController: '0x357D51124f59836DeD84c8a1730D72B749d8BC23', + aaveOracle: '0x21451bD7b528896B4AB2b9764b521D6ed641708d', + }, + [ePolygonNetwork.mumbai]: { + incentivesController: '0xd41aE58e803Edf4304334acCE4DC4Ec34a63C644', + aaveOracle: '0xC365C653f7229894F93994CD0b30947Ab69Ff1D5', + }, + }; + 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}`); });