pragma solidity ^0.6.0; import {DSMath} from "../../../common/math.sol"; import { TokenInterface, AaveProtocolDataProvider, AaveAddressProvider, AaveLendingPool, AavePriceOracle, ChainLinkInterface, AaveIncentivesInterface } from "./interface.sol"; abstract contract Helpers is DSMath { /** * @dev Return ethereum address */ function getEthAddr() internal pure returns (address) { return 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // ETH Address } /** * @dev Return Weth address */ function getWethAddr() internal pure returns (address) { return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // Mainnet WETH Address // return 0xd0A1E359811322d97991E03f863a0C30C2cF029C; // Kovan WETH Address } /** * @dev get Aave Provider Address */ function getAaveAddressProvider() internal pure returns (address) { return 0xB53C1a33016B2DC2fF3653530bfF1848a515c8c5; // Mainnet // return 0x652B2937Efd0B5beA1c8d54293FC1289672AFC6b; // Kovan } /** * @dev get Aave Protocol Data Provider */ function getAaveProtocolDataProvider() internal pure returns (address) { return 0x057835Ad21a177dbdd3090bB1CAE03EaCF78Fc6d; // Mainnet // return 0x744C1aaA95232EeF8A9994C4E0b3a89659D9AB79; // Kovan } /** * @dev get Chainlink ETH price feed Address */ function getChainlinkEthFeed() internal pure returns (address) { return 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; //mainnet // return 0x9326BFA02ADD2366b30bacB125260Af641031331; //kovan } /** * @dev Aave Incentives address */ function getAaveIncentivesAddress() internal pure returns (address) { return 0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5; // polygon mainnet } struct AaveUserTokenData { uint256 tokenPriceInEth; uint256 tokenPriceInUsd; uint256 supplyBalance; uint256 stableBorrowBalance; uint256 variableBorrowBalance; uint256 supplyRate; uint256 stableBorrowRate; uint256 userStableBorrowRate; uint256 variableBorrowRate; bool isCollateral; AaveTokenData aaveTokenData; } struct AaveUserData { uint256 totalCollateralETH; uint256 totalBorrowsETH; uint256 availableBorrowsETH; uint256 currentLiquidationThreshold; uint256 ltv; uint256 healthFactor; uint256 ethPriceInUsd; uint256 pendingRewards; } struct AaveTokenData { uint256 ltv; uint256 threshold; uint256 reserveFactor; bool usageAsCollEnabled; bool borrowEnabled; bool stableBorrowEnabled; bool isActive; bool isFrozen; uint256 totalSupply; uint256 availableLiquidity; uint256 totalStableDebt; uint256 totalVariableDebt; uint256 collateralEmission; uint256 debtEmission; } struct TokenPrice { uint256 priceInEth; uint256 priceInUsd; } function getTokensPrices( AaveAddressProvider aaveAddressProvider, address[] memory tokens ) internal view returns (TokenPrice[] memory tokenPrices, uint256 ethPrice) { uint256[] memory _tokenPrices = AavePriceOracle(aaveAddressProvider.getPriceOracle()) .getAssetsPrices(tokens); ethPrice = uint256( ChainLinkInterface(getChainlinkEthFeed()).latestAnswer() ); tokenPrices = new TokenPrice[](_tokenPrices.length); for (uint256 i = 0; i < _tokenPrices.length; i++) { tokenPrices[i] = TokenPrice( _tokenPrices[i], wmul(_tokenPrices[i], uint256(ethPrice) * 10**10) ); } } function collateralData(AaveProtocolDataProvider aaveData, address token) internal view returns (AaveTokenData memory aaveTokenData) { ( , aaveTokenData.ltv, aaveTokenData.threshold, , aaveTokenData.reserveFactor, aaveTokenData.usageAsCollEnabled, aaveTokenData.borrowEnabled, aaveTokenData.stableBorrowEnabled, aaveTokenData.isActive, aaveTokenData.isFrozen ) = aaveData.getReserveConfigurationData(token); (address aToken, , address debtToken) = aaveData.getReserveTokensAddresses(token); AaveIncentivesInterface.AssetData memory _data; AaveIncentivesInterface incentives = AaveIncentivesInterface(getAaveIncentivesAddress()); _data = incentives.assets(aToken); aaveTokenData.collateralEmission = _data.emissionPerSecond; _data = incentives.assets(debtToken); aaveTokenData.debtEmission = _data.emissionPerSecond; aaveTokenData.totalSupply = TokenInterface(aToken).totalSupply(); } function getTokenData( AaveProtocolDataProvider aaveData, address user, address token, uint256 tokenPriceInEth, uint256 tokenPriceInUsd ) internal view returns (AaveUserTokenData memory tokenData) { AaveTokenData memory aaveTokenData = collateralData(aaveData, token); ( tokenData.supplyBalance, tokenData.stableBorrowBalance, tokenData.variableBorrowBalance, , , tokenData.userStableBorrowRate, , , tokenData.isCollateral ) = aaveData.getUserReserveData(token, user); ( aaveTokenData.availableLiquidity, aaveTokenData.totalStableDebt, aaveTokenData.totalVariableDebt, tokenData.supplyRate, tokenData.variableBorrowRate, tokenData.stableBorrowRate, , , , ) = aaveData.getReserveData(token); tokenData.tokenPriceInEth = tokenPriceInEth; tokenData.tokenPriceInUsd = tokenPriceInUsd; tokenData.aaveTokenData = aaveTokenData; } function getPendingRewards(address[] memory _tokens, address user) internal view returns (uint256 rewards) { uint256 arrLength = 2 * _tokens.length; address[] memory _atokens = new address[](arrLength); AaveProtocolDataProvider aaveData = AaveProtocolDataProvider(getAaveProtocolDataProvider()); for (uint256 i = 0; i < _tokens.length; i++) { (_atokens[2 * i], , _atokens[2 * i + 1]) = aaveData .getReserveTokensAddresses(_tokens[i]); } rewards = AaveIncentivesInterface(getAaveIncentivesAddress()) .getRewardsBalance(_atokens, user); } function getUserData( AaveLendingPool aave, address user, uint256 ethPriceInUsd, address[] memory tokens ) internal view returns (AaveUserData memory userData) { ( uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor ) = aave.getUserAccountData(user); uint256 pendingRewards = getPendingRewards(tokens, user); userData = AaveUserData( totalCollateralETH, totalDebtETH, availableBorrowsETH, currentLiquidationThreshold, ltv, healthFactor, ethPriceInUsd, pendingRewards ); } }