From d60fdc6600459751b88d92ee90a6afe1a35e907d Mon Sep 17 00:00:00 2001 From: Thrilok Kumar Date: Mon, 25 Jan 2021 04:08:41 +0530 Subject: [PATCH] Minor changes --- contracts/powerResolver/aave.sol | 56 +++++++++++-- contracts/powerResolver/aave_v2.sol | 18 +++- contracts/powerResolver/compound.sol | 121 +++++++++++++++++++-------- contracts/powerResolver/dsa.sol | 27 ++++++ 4 files changed, 179 insertions(+), 43 deletions(-) create mode 100644 contracts/powerResolver/dsa.sol diff --git a/contracts/powerResolver/aave.sol b/contracts/powerResolver/aave.sol index c5df848..5c11872 100644 --- a/contracts/powerResolver/aave.sol +++ b/contracts/powerResolver/aave.sol @@ -14,18 +14,26 @@ interface AaveInterface { uint256 lastUpdateTimestamp, bool usageAsCollateralEnabled ); + + function getUserAccountData(address user) external view returns ( + uint256 totalLiquidityETH, + uint256 totalCollateralETH, + uint256 totalBorrowsETH, + uint256 totalFeesETH, + uint256 availableBorrowsETH, + uint256 currentLiquidationThreshold, + uint256 ltv, + uint256 healthFactor + ); } interface AaveProviderInterface { function getLendingPool() external view returns (address); - function getLendingPoolCore() external view returns (address); - function getPriceOracle() external view returns (address); } -interface ListInterface { - function accounts() external view returns (uint64); - function accountID(address) external view returns (uint64); - function accountAddr(uint64) external view returns (address); +interface ChainLinkInterface { + function latestAnswer() external view returns (int256); + function decimals() external view returns (uint256); } contract Helpers { @@ -51,9 +59,20 @@ contract Helpers { return 0x24a42fD28C976A61Df5D00D0599C34c4f90748c8; //mainnet // return 0x506B0B2CF20FAA8f38a4E2B524EE43e1f4458Cc5; //kovan } + + /** + * @dev get Chainlink ETH price feed Address + */ + function getChainlinkEthFeed() internal pure returns (address) { + return 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; //mainnet + // return 0x9326BFA02ADD2366b30bacB125260Af641031331; //kovan + } } contract Resolver is Helpers { + function getEthPrice() public view returns (uint ethPrice) { + ethPrice = uint(ChainLinkInterface(getChainlinkEthFeed()).latestAnswer()); + } function getAaveDataByReserve(address[] memory owners, address reserve, AaveInterface aave) public view returns (AaveData[] memory) { AaveData[] memory tokensData = new AaveData[](owners.length); @@ -87,4 +106,29 @@ contract Resolver is Helpers { return _data; } + function getPositionByAddress( + address[] memory owners + ) + public + view + returns (AaveData[] memory) + { + AaveProviderInterface AaveProvider = AaveProviderInterface(getAaveProviderAddress()); + AaveInterface aave = AaveInterface(AaveProvider.getLendingPool()); + AaveData[] memory tokensData = new AaveData[](owners.length); + + for (uint i = 0; i < owners.length; i++) { + ( + , + uint totalCollateralETH, + uint totalBorrowsETH, + ,,,,) = aave.getUserAccountData(owners[i]); + + tokensData[i] = AaveData( + totalCollateralETH, + totalBorrowsETH + ); + } + } + } \ No newline at end of file diff --git a/contracts/powerResolver/aave_v2.sol b/contracts/powerResolver/aave_v2.sol index d8a7898..d9484db 100644 --- a/contracts/powerResolver/aave_v2.sol +++ b/contracts/powerResolver/aave_v2.sol @@ -31,6 +31,11 @@ interface AaveAddressProvider { function getPriceOracle() external view returns (address); } +interface ChainLinkInterface { + function latestAnswer() external view returns (int256); + function decimals() external view returns (uint256); +} + contract Helpers { struct AaveData { @@ -55,9 +60,20 @@ contract Helpers { // return 0x652B2937Efd0B5beA1c8d54293FC1289672AFC6b; // Kovan } + /** + * @dev get Chainlink ETH price feed Address + */ + function getChainlinkEthFeed() internal pure returns (address) { + return 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; //mainnet + // return 0x9326BFA02ADD2366b30bacB125260Af641031331; //kovan + } + } contract Resolver is Helpers { + function getEthPrice() public view returns (uint ethPrice) { + ethPrice = uint(ChainLinkInterface(getChainlinkEthFeed()).latestAnswer()); + } function getPositionByAddress( address[] memory owners @@ -67,7 +83,7 @@ contract Resolver is Helpers { returns (AaveData[] memory tokensData) { AaveAddressProvider addrProvider = AaveAddressProvider(getAaveAddressProvider()); - AaveLendingPool aave = AaveLendingPool(addrProvider.getLendingPool(); + AaveLendingPool aave = AaveLendingPool(addrProvider.getLendingPool()); tokensData = new AaveData[](owners.length); for (uint i = 0; i < owners.length; i++) { (uint256 collateral,uint256 debt,,,,) = aave.getUserAccountData(owners[i]); diff --git a/contracts/powerResolver/compound.sol b/contracts/powerResolver/compound.sol index 1089b5d..c0fb0a1 100644 --- a/contracts/powerResolver/compound.sol +++ b/contracts/powerResolver/compound.sol @@ -6,15 +6,69 @@ interface CTokenInterface { function borrowBalanceStored(address) external view returns (uint); function balanceOf(address) external view returns (uint); + function underlying() external view returns (address); } -interface ListInterface { - function accounts() external view returns (uint64); - function accountID(address) external view returns (uint64); - function accountAddr(uint64) external view returns (address); +interface TokenInterface { + function decimals() external view returns (uint); + function balanceOf(address) external view returns (uint); } -contract Helpers { +interface OrcaleComp { + function getUnderlyingPrice(address) external view returns (uint); +} + +interface ComptrollerLensInterface { + function oracle() external view returns (address); +} + +contract DSMath { + + function add(uint x, uint y) internal pure returns (uint z) { + require((z = x + y) >= x, "math-not-safe"); + } + + function mul(uint x, uint y) internal pure returns (uint z) { + require(y == 0 || (z = x * y) / y == x, "math-not-safe"); + } + + uint constant WAD = 10 ** 18; + + function wmul(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, y), WAD / 2) / WAD; + } + + function wdiv(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, WAD), y / 2) / y; + } + + function sub(uint x, uint y) internal pure returns (uint z) { + require((z = x - y) <= x, "ds-math-sub-underflow"); + } + +} +contract Helpers is DSMath { + /** + * @dev get Compound Comptroller + */ + function getComptroller() public pure returns (ComptrollerLensInterface) { + return ComptrollerLensInterface(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B); + } + + /** + * @dev get Compound Open Feed Oracle Address + */ + function getOracleAddress() public view returns (address) { + return getComptroller().oracle(); + } + + /** + * @dev get ETH Address + */ + function getCETHAddress() public pure returns (address) { + return 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; + } + struct CompData { uint balanceOfUser; @@ -28,22 +82,37 @@ contract Helpers { struct datas { CompData[] tokensData; } + + struct CompoundTokensData { + uint tokenPriceInEth; + uint tokenPriceInUsd; + uint exchangeRateStored; + } } contract Resolver is Helpers { - - function getDSAWallets(uint start, uint end) public view returns(address[] memory) { - assert(start < end); - ListInterface list = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); - uint totalAccounts = uint(list.accounts()); - end = totalAccounts < end ? totalAccounts : end; - uint len = end - start; - address[] memory wallets = new address[](len); - for (uint i = start; i < end; i++) { - wallets[i] = list.accountAddr(uint64(i+1)); + function getPriceInEth(CTokenInterface cToken) public view returns (uint priceInETH, uint priceInUSD) { + uint decimals = getCETHAddress() == address(cToken) ? 18 : TokenInterface(cToken.underlying()).decimals(); + uint price = OrcaleComp(getOracleAddress()).getUnderlyingPrice(address(cToken)); + uint ethPrice = OrcaleComp(getOracleAddress()).getUnderlyingPrice(getCETHAddress()); + priceInUSD = price / 10 ** (18 - decimals); + priceInETH = wdiv(priceInUSD, ethPrice); + } + + function getCompoundTokensData(address[] memory cAddress) public view returns (CompoundTokensData[] memory) { + CompoundTokensData[] memory compoundTokensData = new CompoundTokensData[](cAddress.length); + for (uint i = 0; i < cAddress.length; i++) { + (uint priceInETH, uint priceInUSD) = getPriceInEth(CTokenInterface(cAddress[i])); + CTokenInterface cToken = CTokenInterface(cAddress[i]); + compoundTokensData[i] = CompoundTokensData( + priceInETH, + priceInUSD, + cToken.exchangeRateStored() + ); } - return wallets; + + return compoundTokensData; } function getCompoundData(address owner, address[] memory cAddress) public view returns (CompData[] memory) { @@ -88,24 +157,4 @@ contract Resolver is Helpers { } return _data; } - - function getPositionByAccountIds( - uint start, - uint end, - address[] memory cAddress - ) - public - view - returns (datas[] memory) - { - address[] memory owners = getDSAWallets(start, end); - datas[] memory _data = new datas[](cAddress.length); - for (uint i = 0; i < cAddress.length; i++) { - _data[i] = datas( - getCompoundDataByToken(owners, cAddress[i]) - ); - } - return _data; - } - } diff --git a/contracts/powerResolver/dsa.sol b/contracts/powerResolver/dsa.sol new file mode 100644 index 0000000..c88d2e9 --- /dev/null +++ b/contracts/powerResolver/dsa.sol @@ -0,0 +1,27 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +interface ListInterface { + function accounts() external view returns (uint64); + function accountAddr(uint64) external view returns (address); +} + +contract Resolver { + function getTotalAccounts() public view returns(uint totalAccounts) { + ListInterface list = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); + totalAccounts = uint(list.accounts()); + } + + function getDSAWallets(uint start, uint end) public view returns(address[] memory) { + assert(start < end); + ListInterface list = ListInterface(0x4c8a1BEb8a87765788946D6B19C6C6355194AbEb); + uint totalAccounts = uint(list.accounts()); + end = totalAccounts < end ? totalAccounts : end; + uint len = (end - start) + 1; + address[] memory wallets = new address[](len); + for (uint i = 0; i < len; i++) { + wallets[i] = list.accountAddr(uint64(start + i)); + } + return wallets; + } +}