diff --git a/contracts/receivers/aave-v2-receiver/variables.sol b/contracts/receivers/aave-v2-receiver/variables.sol index 5e4dbee..42cc62c 100644 --- a/contracts/receivers/aave-v2-receiver/variables.sol +++ b/contracts/receivers/aave-v2-receiver/variables.sol @@ -11,7 +11,7 @@ contract Variables { // This will be used to have debt/collateral ratio always 20% less than liquidation // TODO: Is this number correct for it? - uint public safeRatioGap = 200000000000000000; // 20%? 2e17 + uint public safeRatioGap = 800000000000000000; // 20%? 2e17 // TODO: Add function for flash deposits and withdraw mapping(address => mapping(address => uint)) flashDeposits; // Flash deposits of particular token diff --git a/contracts/senders/aave-v2-migrator/helpers.sol b/contracts/senders/aave-v2-migrator/helpers.sol index 197c822..6cf27ef 100644 --- a/contracts/senders/aave-v2-migrator/helpers.sol +++ b/contracts/senders/aave-v2-migrator/helpers.sol @@ -1,9 +1,8 @@ -pragma solidity >=0.7.0; +pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; import { DSMath } from "../../common/math.sol"; import { Stores } from "../../common/stores-mainnet.sol"; - import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -14,7 +13,9 @@ import { AaveDataProviderInterface, AaveInterface, ATokenInterface, - StateSenderInterface + StateSenderInterface, + AavePriceOracle, + ChainLinkInterface } from "./interfaces.sol"; abstract contract Helpers is DSMath, Stores, Variables { @@ -104,8 +105,45 @@ abstract contract Helpers is DSMath, Stores, Variables { require(isOk, "position-at-risk"); } - function _checkRatio(AaveData memory data) public returns (bool isOk) { - // TODO: @mubaris Check the debt/collateral ratio should be less than "safeRatioGap" from Liquidation of that particular user assets + function getTokensPrices(address[] memory tokens) internal view returns(uint[] memory tokenPricesInEth) { + tokenPricesInEth = AavePriceOracle(aaveProvider.getPriceOracle()).getAssetsPrices(tokens); + } + + // Liquidation threshold + function getTokenLt(address[] memory tokens) internal view returns (uint[] memory decimals, uint[] memory tokenLts) { + for (uint i = 0; i < tokens.length; i++) { + (decimals[i],,tokenLts[i],,,,,,,) = aaveData.getReserveConfigurationData(tokens[i]); + } + } + + function convertTo18(uint amount, uint decimal) internal returns (uint) { + return amount * (10 ** (18 - decimal)); // TODO: verify this + } + + // TODO: need to verify this throughly + /* + * Checks the position to migrate should have a safe gap from liquidation + */ + function _checkRatio(AaveData memory data) public { + uint[] memory supplyTokenPrices = getTokensPrices(data.supplyTokens); + (uint[] memory supplyDecimals, uint[] memory supplyLts) = getTokenLt(data.supplyTokens); + + uint[] memory borrowTokenPrices = getTokensPrices(data.borrowTokens); + (uint[] memory borrowDecimals,) = getTokenLt(data.borrowTokens); + uint netSupply; + uint netBorrow; + uint liquidation; + for (uint i = 0; i < data.supplyTokens.length; i++) { + uint _amt = wmul(convertTo18(data.supplyAmts[i], supplyDecimals[i]), supplyTokenPrices[i]); + netSupply += _amt; + liquidation += (_amt * supplyLts[i]) / 10000; // convert the number 8000 to 0.8 + } + for (uint i = 0; i < data.borrowTokens.length; i++) { + uint _amt = wmul(convertTo18(data.borrowAmts[i], borrowDecimals[i]), borrowTokenPrices[i]); + netBorrow += _amt; + } + uint _dif = wmul(netSupply, sub(1e18, safeRatioGap)); + require(netBorrow < sub(liquidation, _dif), "position-is-risky-to-migrate"); } } \ No newline at end of file diff --git a/contracts/senders/aave-v2-migrator/interfaces.sol b/contracts/senders/aave-v2-migrator/interfaces.sol index 9b5e5a0..504d291 100644 --- a/contracts/senders/aave-v2-migrator/interfaces.sol +++ b/contracts/senders/aave-v2-migrator/interfaces.sol @@ -25,6 +25,7 @@ interface AaveInterface { interface AaveLendingPoolProviderInterface { function getLendingPool() external view returns (address); + function getPriceOracle() external view returns (address); } // Aave Protocol Data Provider @@ -82,4 +83,16 @@ interface IndexInterface { interface FlashloanInterface { function initiateFlashLoan(bytes memory data, uint ethAmt) external; +} + +interface AavePriceOracle { + function getAssetPrice(address _asset) external view returns(uint256); + function getAssetsPrices(address[] calldata _assets) external view returns(uint256[] memory); + function getSourceOfAsset(address _asset) external view returns(uint256); + function getFallbackOracle() external view returns(uint256); +} + +interface ChainLinkInterface { + function latestAnswer() external view returns (int256); + function decimals() external view returns (uint256); } \ No newline at end of file diff --git a/contracts/senders/aave-v2-migrator/main.sol b/contracts/senders/aave-v2-migrator/main.sol index 08c6e86..f5eec61 100644 --- a/contracts/senders/aave-v2-migrator/main.sol +++ b/contracts/senders/aave-v2-migrator/main.sol @@ -209,8 +209,7 @@ contract MigrateResolver is LiquidityResolver { data.borrowAmts = totalBorrows; // Checks the amount that user is trying to migrate is 20% below the Liquidation - bool isOk = _checkRatio(data); - require(isOk, "position-risky-to-migrate"); + _checkRatio(data); if (ethAmt > 0) { aave.withdraw(wethAddr, ethAmt, address(this)); diff --git a/contracts/senders/aave-v2-migrator/variables.sol b/contracts/senders/aave-v2-migrator/variables.sol index 644aea1..cf0a921 100644 --- a/contracts/senders/aave-v2-migrator/variables.sol +++ b/contracts/senders/aave-v2-migrator/variables.sol @@ -27,6 +27,11 @@ contract Variables { address[] borrowTokens; } + struct TokenPrice { + uint priceInEth; + uint priceInUsd; + } + /** * @dev Aave referal code */ @@ -37,7 +42,7 @@ contract Variables { // This will be used to have debt/collateral ratio always 20% less than liquidation // TODO: Is this number correct for it? - uint public safeRatioGap = 80000000000000000; // 20%? + uint public safeRatioGap = 800000000000000000; // 20%? uint public fee = 998000000000000000; // 0.2% (99.8%) on collateral? TODO: Is this right? // TODO: Set by construtor? mapping(address => bool) public isSupportedToken;