code refactrinig & small bugs

This commit is contained in:
Samyak Jain 2019-10-11 15:02:38 +05:30
parent 68f24c2492
commit a782d0d9c9

View File

@ -1,34 +1,17 @@
pragma solidity ^0.5.8; pragma solidity ^0.5.8;
interface RegistryInterface {
function proxies(address) external view returns (address);
}
interface UserWalletInterface {
function owner() external view returns (address);
}
interface CTokenInterface { interface CTokenInterface {
function mint(uint mintAmount) external returns (uint); // For ERC20
function redeem(uint redeemTokens) external returns (uint);
function redeemUnderlying(uint redeemAmount) external returns (uint);
function borrow(uint borrowAmount) external returns (uint); function borrow(uint borrowAmount) external returns (uint);
function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20 function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20
function borrowBalanceCurrent(address account) external returns (uint); function borrowBalanceCurrent(address account) external returns (uint);
function balanceOf(address owner) external view returns (uint256 balance); function balanceOf(address owner) external view returns (uint256 balance);
function allowance(address, address) external view returns (uint);
function approve(address, uint) external;
function transfer(address, uint) external returns (bool);
function transferFrom(address, address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool);
function underlying() external view returns (address); function underlying() external view returns (address);
} }
interface CETHInterface { interface CETHInterface {
function mint() external payable; // For ETH
function repayBorrow() external payable; // For ETH
function repayBorrowBehalf(address borrower) external payable; // For ETH function repayBorrowBehalf(address borrower) external payable; // For ETH
function borrowBalanceCurrent(address account) external returns (uint);
} }
interface ERC20Interface { interface ERC20Interface {
@ -41,11 +24,10 @@ interface ERC20Interface {
interface ComptrollerInterface { interface ComptrollerInterface {
function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); function enterMarkets(address[] calldata cTokens) external returns (uint[] memory);
function exitMarket(address cTokenAddress) external returns (uint);
function getAssetsIn(address account) external view returns (address[] memory); function getAssetsIn(address account) external view returns (address[] memory);
} }
interface LiquidityInterface { interface PoolInterface {
function accessToken(uint useLiqFrom, address[] calldata ctknAddr, uint[] calldata tknAmt) external; function accessToken(uint useLiqFrom, address[] calldata ctknAddr, uint[] calldata tknAmt) external;
function paybackToken(uint useLiqFrom, address[] calldata ctknAddr) external payable; function paybackToken(uint useLiqFrom, address[] calldata ctknAddr) external payable;
} }
@ -53,6 +35,10 @@ interface LiquidityInterface {
contract DSMath { contract DSMath {
function sub(uint x, uint y) internal pure returns (uint z) {
z = x - y <= x ? x - y : 0;
}
function add(uint x, uint y) internal pure returns (uint z) { function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, "math-not-safe"); require((z = x + y) >= x, "math-not-safe");
} }
@ -76,8 +62,6 @@ contract DSMath {
contract Helpers is DSMath { contract Helpers is DSMath {
address ethAddr = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
address public registry = 0x498b3BfaBE9F73db90D252bCD4Fa9548Cd0Fd981;
address public comptrollerAddr = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; address public comptrollerAddr = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B;
address payable public liquidityAddr = 0x8179d350fFFc69A8b256e781ADDE8A1bb915766E; address payable public liquidityAddr = 0x8179d350fFFc69A8b256e781ADDE8A1bb915766E;
@ -87,28 +71,30 @@ contract Helpers is DSMath {
/** /**
* @dev check if the user has entered the market and enter if not * @dev check if the user has entered the market and enter if not
*/ */
function enterMarket(address cErc20) internal { function enterMarket(address[] memory cErc20) internal {
ComptrollerInterface troller = ComptrollerInterface(comptrollerAddr); ComptrollerInterface troller = ComptrollerInterface(comptrollerAddr);
address[] memory markets = troller.getAssetsIn(address(this)); address[] memory markets = troller.getAssetsIn(address(this));
bool isEntered = false; address[] memory toEnter;
for (uint i = 0; i < markets.length; i++) { for (uint j = 0; j < cErc20.length; j++) {
if (markets[i] == cErc20) { bool isEntered = false;
isEntered = true; for (uint i = 0; i < markets.length; i++) {
if (markets[i] == cErc20[j]) {
isEntered = true;
break;
}
}
if (!isEntered) {
toEnter[toEnter.length] = cErc20[j];
} }
} }
if (!isEntered) { troller.enterMarkets(toEnter);
address[] memory toEnter = new address[](1);
toEnter[0] = cErc20;
troller.enterMarkets(toEnter);
}
} }
/** /**
* @dev get markets address user has entered * @dev get markets address owner has entered
*/ */
function enteredMarkets() internal view returns (address[] memory) { function enteredMarkets() internal view returns (address[] memory) {
ComptrollerInterface troller = ComptrollerInterface(comptrollerAddr); address[] memory markets = ComptrollerInterface(comptrollerAddr).getAssetsIn(msg.sender);
address[] memory markets = troller.getAssetsIn(address(this));
return markets; return markets;
} }
@ -123,32 +109,15 @@ contract Helpers is DSMath {
} }
} }
/**
* FOR SECURITY PURPOSE
* only InstaDApp smart wallets can access the liquidity pool contract
*/
modifier isUserWallet {
address userAdd = UserWalletInterface(msg.sender).owner();
address walletAdd = RegistryInterface(registry).proxies(userAdd);
require(walletAdd != address(0), "not-user-wallet");
require(walletAdd == msg.sender, "not-wallet-owner");
_;
}
struct BorrowData {
address cAddr; // address of cToken
uint256 borrowAmt; //amount to be pay back
}
} }
contract ImportResolver is Helpers { contract ImportResolver is Helpers {
event LogCompoundImport(address owner, uint percentage, uint usedAssetsFrom); event LogCompoundImport(address owner, uint percentage, uint usedAssetsFrom, address[] markets, address[] borrowAddr, uint[] borrowAmt);
function importAssets(uint toConvert, uint getLiqFrom) external isUserWallet { function importAssets(uint toConvert, uint getLiqFrom) external {
uint initBal = liquidityAddr.balance; uint initialBal = sub(liquidityAddr.balance, 10000000000);
address[] memory markets = enteredMarkets(); address[] memory markets = enteredMarkets();
BorrowData[] memory borrowArr;
address[] memory borrowAddr; address[] memory borrowAddr;
uint[] memory borrowAmt; uint[] memory borrowAmt;
@ -160,17 +129,16 @@ contract ImportResolver is Helpers {
if (toPayback > 0) { if (toPayback > 0) {
borrowAddr[borrowAddr.length] = cErc20; borrowAddr[borrowAddr.length] = cErc20;
borrowAmt[borrowAmt.length] = toPayback; borrowAmt[borrowAmt.length] = toPayback;
borrowArr[borrowArr.length] = (BorrowData(cErc20,toPayback));
} }
} }
// Get liquidity assets to payback user wallet borrowed assets // Get liquidity assets to payback user wallet borrowed assets
LiquidityInterface(liquidityAddr).accessToken(getLiqFrom, borrowAddr, borrowAmt); PoolInterface(liquidityAddr).accessToken(getLiqFrom, borrowAddr, borrowAmt);
// payback user wallet borrowed assets // payback user wallet borrowed assets
for (uint i = 0; i < borrowArr.length; i++) { for (uint i = 0; i < borrowAddr.length; i++) {
address cErc20 = borrowArr[i].cAddr; address cErc20 = borrowAddr[i];
uint toPayback = borrowArr[i].borrowAmt; uint toPayback = borrowAmt[i];
if (cErc20 == cEthAddr) { if (cErc20 == cEthAddr) {
CETHInterface(cErc20).repayBorrowBehalf.value(toPayback)(msg.sender); CETHInterface(cErc20).repayBorrowBehalf.value(toPayback)(msg.sender);
} else { } else {
@ -193,26 +161,32 @@ contract ImportResolver is Helpers {
} }
// borrow and transfer assets to payback liquidity // borrow and transfer assets to payback liquidity
for (uint i = 0; i < borrowArr.length; i++) { enterMarket(markets);
address cErc20 = borrowArr[i].cAddr; for (uint i = 0; i < borrowAddr.length; i++) {
uint toBorrow = borrowArr[i].borrowAmt; address cErc20 = borrowAddr[i];
uint toBorrow = borrowAmt[i];
CTokenInterface ctknContract = CTokenInterface(cErc20); CTokenInterface ctknContract = CTokenInterface(cErc20);
address erc20 = ctknContract.underlying(); address erc20 = ctknContract.underlying();
enterMarket(cErc20); require(ctknContract.borrow(toBorrow) == 0, "got collateral?");
require(CTokenInterface(cErc20).borrow(toBorrow) == 0, "got collateral?");
if (cErc20 == cEthAddr) { if (cErc20 == cEthAddr) {
liquidityAddr.transfer(toBorrow); liquidityAddr.transfer(toBorrow);
} else { } else {
setApproval(erc20, toBorrow, liquidityAddr);
require(ERC20Interface(erc20).transfer(liquidityAddr, toBorrow), "Not-enough-amt"); require(ERC20Interface(erc20).transfer(liquidityAddr, toBorrow), "Not-enough-amt");
} }
} }
//payback InstaDApp liquidity //payback InstaDApp liquidity
LiquidityInterface(liquidityAddr).paybackToken(getLiqFrom, borrowAddr); PoolInterface(liquidityAddr).paybackToken(getLiqFrom, borrowAddr);
assert(liquidityAddr.balance == initBal); assert(liquidityAddr.balance >= initialBal);
emit LogCompoundImport(msg.sender, toConvert, getLiqFrom); emit LogCompoundImport(
msg.sender,
toConvert,
getLiqFrom,
markets,
borrowAddr,
borrowAmt
);
} }
} }