Skip to content

Commit c1ada1c

Browse files
authored
Merge pull request #220 from aave/feat/188-avalanche-market
Feat/188 Avalanche market
2 parents 7b88c4f + fa1f134 commit c1ada1c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1254
-397
lines changed

contracts/interfaces/IAaveIncentivesController.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ interface IAaveIncentivesController {
3030
uint256
3131
);
3232

33+
/*
34+
* LEGACY **************************
35+
* @dev Returns the configuration of the distribution for a certain asset
36+
* @param asset The address of the reference asset of the distribution
37+
* @return The asset index, the emission per second and the last updated timestamp
38+
**/
39+
function assets(address asset)
40+
external
41+
view
42+
returns (
43+
uint128,
44+
uint128,
45+
uint256
46+
);
47+
3348
/**
3449
* @dev Whitelists an address to claim the rewards on behalf of another address
3550
* @param user The address of the user

contracts/misc/AaveOracle.sol

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,34 @@ import {SafeERC20} from '../dependencies/openzeppelin/contracts/SafeERC20.sol';
1818
contract AaveOracle is IPriceOracleGetter, Ownable {
1919
using SafeERC20 for IERC20;
2020

21-
event WethSet(address indexed weth);
21+
event BaseCurrencySet(address indexed baseCurrency, uint256 baseCurrencyUnit);
2222
event AssetSourceUpdated(address indexed asset, address indexed source);
2323
event FallbackOracleUpdated(address indexed fallbackOracle);
2424

2525
mapping(address => IChainlinkAggregator) private assetsSources;
2626
IPriceOracleGetter private _fallbackOracle;
27-
address public immutable WETH;
27+
address public immutable BASE_CURRENCY;
28+
uint256 public immutable BASE_CURRENCY_UNIT;
2829

2930
/// @notice Constructor
3031
/// @param assets The addresses of the assets
3132
/// @param sources The address of the source of each asset
3233
/// @param fallbackOracle The address of the fallback oracle to use if the data of an
3334
/// aggregator is not consistent
35+
/// @param baseCurrency the base currency used for the price quotes. If USD is used, base currency is 0x0
36+
/// @param baseCurrencyUnit the unit of the base currency
3437
constructor(
3538
address[] memory assets,
3639
address[] memory sources,
3740
address fallbackOracle,
38-
address weth
41+
address baseCurrency,
42+
uint256 baseCurrencyUnit
3943
) public {
4044
_setFallbackOracle(fallbackOracle);
4145
_setAssetsSources(assets, sources);
42-
WETH = weth;
43-
emit WethSet(weth);
46+
BASE_CURRENCY = baseCurrency;
47+
BASE_CURRENCY_UNIT = baseCurrencyUnit;
48+
emit BaseCurrencySet(baseCurrency, baseCurrencyUnit);
4449
}
4550

4651
/// @notice External function called by the Aave governance to set or replace sources of assets
@@ -83,8 +88,8 @@ contract AaveOracle is IPriceOracleGetter, Ownable {
8388
function getAssetPrice(address asset) public view override returns (uint256) {
8489
IChainlinkAggregator source = assetsSources[asset];
8590

86-
if (asset == WETH) {
87-
return 1 ether;
91+
if (asset == BASE_CURRENCY) {
92+
return BASE_CURRENCY_UNIT;
8893
} else if (address(source) == address(0)) {
8994
return _fallbackOracle.getAssetPrice(asset);
9095
} else {

contracts/misc/UiPoolDataProvider.sol

Lines changed: 186 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
2525
using UserConfiguration for DataTypes.UserConfigurationMap;
2626

2727
address public constant MOCK_USD_ADDRESS = 0x10F7Fc1F91Ba351f9C629c5947AD69bD03C05b96;
28-
IAaveIncentivesController public immutable incentivesController;
28+
IAaveIncentivesController public immutable override incentivesController;
2929
IPriceOracleGetter public immutable oracle;
3030

3131
constructor(IAaveIncentivesController _incentivesController, IPriceOracleGetter _oracle) public {
@@ -51,6 +51,185 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
5151
);
5252
}
5353

54+
function getReservesList(ILendingPoolAddressesProvider provider)
55+
public
56+
view
57+
override
58+
returns (address[] memory)
59+
{
60+
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
61+
return lendingPool.getReservesList();
62+
}
63+
64+
function getSimpleReservesData(ILendingPoolAddressesProvider provider)
65+
public
66+
view
67+
override
68+
returns (
69+
AggregatedReserveData[] memory,
70+
uint256,
71+
uint256
72+
)
73+
{
74+
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
75+
address[] memory reserves = lendingPool.getReservesList();
76+
AggregatedReserveData[] memory reservesData = new AggregatedReserveData[](reserves.length);
77+
78+
for (uint256 i = 0; i < reserves.length; i++) {
79+
AggregatedReserveData memory reserveData = reservesData[i];
80+
reserveData.underlyingAsset = reserves[i];
81+
82+
// reserve current state
83+
DataTypes.ReserveData memory baseData =
84+
lendingPool.getReserveData(reserveData.underlyingAsset);
85+
reserveData.liquidityIndex = baseData.liquidityIndex;
86+
reserveData.variableBorrowIndex = baseData.variableBorrowIndex;
87+
reserveData.liquidityRate = baseData.currentLiquidityRate;
88+
reserveData.variableBorrowRate = baseData.currentVariableBorrowRate;
89+
reserveData.stableBorrowRate = baseData.currentStableBorrowRate;
90+
reserveData.lastUpdateTimestamp = baseData.lastUpdateTimestamp;
91+
reserveData.aTokenAddress = baseData.aTokenAddress;
92+
reserveData.stableDebtTokenAddress = baseData.stableDebtTokenAddress;
93+
reserveData.variableDebtTokenAddress = baseData.variableDebtTokenAddress;
94+
reserveData.interestRateStrategyAddress = baseData.interestRateStrategyAddress;
95+
reserveData.priceInEth = oracle.getAssetPrice(reserveData.underlyingAsset);
96+
97+
reserveData.availableLiquidity = IERC20Detailed(reserveData.underlyingAsset).balanceOf(
98+
reserveData.aTokenAddress
99+
);
100+
(
101+
reserveData.totalPrincipalStableDebt,
102+
,
103+
reserveData.averageStableRate,
104+
reserveData.stableDebtLastUpdateTimestamp
105+
) = IStableDebtToken(reserveData.stableDebtTokenAddress).getSupplyData();
106+
reserveData.totalScaledVariableDebt = IVariableDebtToken(reserveData.variableDebtTokenAddress)
107+
.scaledTotalSupply();
108+
109+
// reserve configuration
110+
111+
// we're getting this info from the aToken, because some of assets can be not compliant with ETC20Detailed
112+
reserveData.symbol = IERC20Detailed(reserveData.underlyingAsset).symbol();
113+
reserveData.name = '';
114+
115+
(
116+
reserveData.baseLTVasCollateral,
117+
reserveData.reserveLiquidationThreshold,
118+
reserveData.reserveLiquidationBonus,
119+
reserveData.decimals,
120+
reserveData.reserveFactor
121+
) = baseData.configuration.getParamsMemory();
122+
(
123+
reserveData.isActive,
124+
reserveData.isFrozen,
125+
reserveData.borrowingEnabled,
126+
reserveData.stableBorrowRateEnabled
127+
) = baseData.configuration.getFlagsMemory();
128+
reserveData.usageAsCollateralEnabled = reserveData.baseLTVasCollateral != 0;
129+
(
130+
reserveData.variableRateSlope1,
131+
reserveData.variableRateSlope2,
132+
reserveData.stableRateSlope1,
133+
reserveData.stableRateSlope2
134+
) = getInterestRateStrategySlopes(
135+
DefaultReserveInterestRateStrategy(reserveData.interestRateStrategyAddress)
136+
);
137+
138+
// incentives
139+
if (address(0) != address(incentivesController)) {
140+
(
141+
reserveData.aTokenIncentivesIndex,
142+
reserveData.aEmissionPerSecond,
143+
reserveData.aIncentivesLastUpdateTimestamp
144+
) = incentivesController.getAssetData(reserveData.aTokenAddress);
145+
146+
(
147+
reserveData.sTokenIncentivesIndex,
148+
reserveData.sEmissionPerSecond,
149+
reserveData.sIncentivesLastUpdateTimestamp
150+
) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress);
151+
152+
(
153+
reserveData.vTokenIncentivesIndex,
154+
reserveData.vEmissionPerSecond,
155+
reserveData.vIncentivesLastUpdateTimestamp
156+
) = incentivesController.getAssetData(reserveData.variableDebtTokenAddress);
157+
}
158+
}
159+
160+
uint256 emissionEndTimestamp;
161+
if (address(0) != address(incentivesController)) {
162+
emissionEndTimestamp = incentivesController.DISTRIBUTION_END();
163+
}
164+
165+
return (reservesData, oracle.getAssetPrice(MOCK_USD_ADDRESS), emissionEndTimestamp);
166+
}
167+
168+
function getUserReservesData(ILendingPoolAddressesProvider provider, address user)
169+
external
170+
view
171+
override
172+
returns (UserReserveData[] memory, uint256)
173+
{
174+
ILendingPool lendingPool = ILendingPool(provider.getLendingPool());
175+
address[] memory reserves = lendingPool.getReservesList();
176+
DataTypes.UserConfigurationMap memory userConfig = lendingPool.getUserConfiguration(user);
177+
178+
UserReserveData[] memory userReservesData =
179+
new UserReserveData[](user != address(0) ? reserves.length : 0);
180+
181+
for (uint256 i = 0; i < reserves.length; i++) {
182+
DataTypes.ReserveData memory baseData = lendingPool.getReserveData(reserves[i]);
183+
// incentives
184+
if (address(0) != address(incentivesController)) {
185+
userReservesData[i].aTokenincentivesUserIndex = incentivesController.getUserAssetData(
186+
user,
187+
baseData.aTokenAddress
188+
);
189+
userReservesData[i].vTokenincentivesUserIndex = incentivesController.getUserAssetData(
190+
user,
191+
baseData.variableDebtTokenAddress
192+
);
193+
userReservesData[i].sTokenincentivesUserIndex = incentivesController.getUserAssetData(
194+
user,
195+
baseData.stableDebtTokenAddress
196+
);
197+
}
198+
// user reserve data
199+
userReservesData[i].underlyingAsset = reserves[i];
200+
userReservesData[i].scaledATokenBalance = IAToken(baseData.aTokenAddress).scaledBalanceOf(
201+
user
202+
);
203+
userReservesData[i].usageAsCollateralEnabledOnUser = userConfig.isUsingAsCollateral(i);
204+
205+
if (userConfig.isBorrowing(i)) {
206+
userReservesData[i].scaledVariableDebt = IVariableDebtToken(
207+
baseData
208+
.variableDebtTokenAddress
209+
)
210+
.scaledBalanceOf(user);
211+
userReservesData[i].principalStableDebt = IStableDebtToken(baseData.stableDebtTokenAddress)
212+
.principalBalanceOf(user);
213+
if (userReservesData[i].principalStableDebt != 0) {
214+
userReservesData[i].stableBorrowRate = IStableDebtToken(baseData.stableDebtTokenAddress)
215+
.getUserStableRate(user);
216+
userReservesData[i].stableBorrowLastUpdateTimestamp = IStableDebtToken(
217+
baseData
218+
.stableDebtTokenAddress
219+
)
220+
.getUserLastUpdated(user);
221+
}
222+
}
223+
}
224+
225+
uint256 userUnclaimedRewards;
226+
if (address(0) != address(incentivesController)) {
227+
userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user);
228+
}
229+
230+
return (userReservesData, userUnclaimedRewards);
231+
}
232+
54233
function getReservesData(ILendingPoolAddressesProvider provider, address user)
55234
external
56235
view
@@ -104,7 +283,7 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
104283
// reserve configuration
105284

106285
// we're getting this info from the aToken, because some of assets can be not compliant with ETC20Detailed
107-
reserveData.symbol = IERC20Detailed(reserveData.aTokenAddress).symbol();
286+
reserveData.symbol = IERC20Detailed(reserveData.underlyingAsset).symbol();
108287
reserveData.name = '';
109288

110289
(
@@ -136,14 +315,14 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
136315
reserveData.aTokenIncentivesIndex,
137316
reserveData.aEmissionPerSecond,
138317
reserveData.aIncentivesLastUpdateTimestamp
139-
) = incentivesController.getAssetData(reserveData.aTokenAddress);
140-
318+
) = incentivesController.getAssetData(reserveData.aTokenAddress);
319+
141320
(
142321
reserveData.sTokenIncentivesIndex,
143322
reserveData.sEmissionPerSecond,
144323
reserveData.sIncentivesLastUpdateTimestamp
145324
) = incentivesController.getAssetData(reserveData.stableDebtTokenAddress);
146-
325+
147326
(
148327
reserveData.vTokenIncentivesIndex,
149328
reserveData.vEmissionPerSecond,
@@ -200,12 +379,12 @@ contract UiPoolDataProvider is IUiPoolDataProvider {
200379
}
201380
}
202381

203-
204382
IncentivesControllerData memory incentivesControllerData;
205383

206384
if (address(0) != address(incentivesController)) {
207385
if (user != address(0)) {
208-
incentivesControllerData.userUnclaimedRewards = incentivesController.getUserUnclaimedRewards(user);
386+
incentivesControllerData.userUnclaimedRewards = incentivesController
387+
.getUserUnclaimedRewards(user);
209388
}
210389
incentivesControllerData.emissionEndTimestamp = incentivesController.DISTRIBUTION_END();
211390
}

contracts/misc/interfaces/IUiPoolDataProvider.sol

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,31 @@ interface IUiPoolDataProvider {
7373
uint256 emissionEndTimestamp;
7474
}
7575

76+
function getReservesList(ILendingPoolAddressesProvider provider)
77+
external
78+
view
79+
returns (address[] memory);
80+
81+
function incentivesController() external view returns (IAaveIncentivesController);
82+
83+
function getSimpleReservesData(ILendingPoolAddressesProvider provider)
84+
external
85+
view
86+
returns (
87+
AggregatedReserveData[] memory,
88+
uint256, // usd price eth
89+
uint256 // emission end timestamp
90+
);
91+
92+
function getUserReservesData(ILendingPoolAddressesProvider provider, address user)
93+
external
94+
view
95+
returns (
96+
UserReserveData[] memory,
97+
uint256 // user unclaimed rewards
98+
);
7699

100+
// generic method with full data
77101
function getReservesData(ILendingPoolAddressesProvider provider, address user)
78102
external
79103
view

hardhat.config.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import fs from 'fs';
33
import { HardhatUserConfig } from 'hardhat/types';
44
// @ts-ignore
55
import { accounts } from './test-wallets.js';
6-
import { eEthereumNetwork, eNetwork, ePolygonNetwork, eXDaiNetwork } from './helpers/types';
6+
import {
7+
eAvalancheNetwork,
8+
eEthereumNetwork,
9+
eNetwork,
10+
ePolygonNetwork,
11+
eXDaiNetwork,
12+
} from './helpers/types';
713
import { BUIDLEREVM_CHAINID, COVERAGE_CHAINID } from './helpers/buidler-constants';
814
import {
915
NETWORKS_RPC_URL,
@@ -24,7 +30,7 @@ import 'solidity-coverage';
2430
import { fork } from 'child_process';
2531

2632
const SKIP_LOAD = process.env.SKIP_LOAD === 'true';
27-
const DEFAULT_BLOCK_GAS_LIMIT = 12450000;
33+
const DEFAULT_BLOCK_GAS_LIMIT = 8000000;
2834
const DEFAULT_GAS_MUL = 5;
2935
const HARDFORK = 'istanbul';
3036
const ETHERSCAN_KEY = process.env.ETHERSCAN_KEY || '';
@@ -96,10 +102,12 @@ const buidlerConfig: HardhatUserConfig = {
96102
kovan: getCommonNetworkConfig(eEthereumNetwork.kovan, 42),
97103
ropsten: getCommonNetworkConfig(eEthereumNetwork.ropsten, 3),
98104
main: getCommonNetworkConfig(eEthereumNetwork.main, 1),
99-
tenderlyMain: getCommonNetworkConfig(eEthereumNetwork.tenderlyMain, 3030),
105+
tenderly: getCommonNetworkConfig(eEthereumNetwork.tenderly, 3030),
100106
matic: getCommonNetworkConfig(ePolygonNetwork.matic, 137),
101107
mumbai: getCommonNetworkConfig(ePolygonNetwork.mumbai, 80001),
102108
xdai: getCommonNetworkConfig(eXDaiNetwork.xdai, 100),
109+
avalanche: getCommonNetworkConfig(eAvalancheNetwork.avalanche, 43114),
110+
fuji: getCommonNetworkConfig(eAvalancheNetwork.fuji, 43113),
103111
hardhat: {
104112
hardfork: 'berlin',
105113
blockGasLimit: DEFAULT_BLOCK_GAS_LIMIT,

0 commit comments

Comments
 (0)