From 460d8bd74d4f383bdf891e05e54192e216ec748a Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Mon, 6 May 2019 15:06:46 +0530 Subject: [PATCH 01/17] fees removed --- contracts/ProxyLogics/InstaSave.sol | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/contracts/ProxyLogics/InstaSave.sol b/contracts/ProxyLogics/InstaSave.sol index db1b67f..48daec1 100644 --- a/contracts/ProxyLogics/InstaSave.sol +++ b/contracts/ProxyLogics/InstaSave.sol @@ -378,7 +378,6 @@ contract GetDetails is MakerHelpers { colToFree = ethToSwap; } (uint expectedRate,) = KyberInterface(getAddressKyber()).getExpectedRate(getAddressETH(), getAddressDAI(), colToFree); - expectedRate = wdiv(wmul(expectedRate, 99750000000000000000), 100000000000000000000); uint expectedDAI = wmul(colToFree, expectedRate); if (expectedDAI < daiDebt) { finalEthCol = sub(ethCol, colToFree); @@ -413,7 +412,6 @@ contract GetDetails is MakerHelpers { debtToBorrow = daiToSwap; } (uint expectedRate,) = KyberInterface(getAddressKyber()).getExpectedRate(getAddressDAI(), getAddressETH(), debtToBorrow); - expectedRate = wdiv(wmul(expectedRate, 99750000000000000000), 100000000000000000000); uint expectedETH = wmul(debtToBorrow, expectedRate); if (ethCol != 0) { finalEthCol = add(ethCol, expectedETH); @@ -470,11 +468,9 @@ contract Save is GetDetails { } uint thisBalance = address(this).balance; free(cdpID, colToFree); - uint ethToSwap = wdiv(wmul(colToFree, 99750000000000000000), 100000000000000000000); - getAddressAdmin().transfer(sub(colToFree, ethToSwap)); - uint destAmt = KyberInterface(getAddressKyber()).trade.value(ethToSwap)( + uint destAmt = KyberInterface(getAddressKyber()).trade.value(colToFree)( getAddressETH(), - ethToSwap, + colToFree, getAddressDAI(), address(this), daiDebt, @@ -488,7 +484,7 @@ contract Save is GetDetails { lock(cdpID, balToLock); } - emit LogSaveCDP(cdpID, ethToSwap, destAmt); + emit LogSaveCDP(cdpID, colToFree, destAmt); emit LogTrade( 0, @@ -521,9 +517,7 @@ contract Save is GetDetails { 0, getAddressAdmin() ); - uint ethToDeposit = wdiv(wmul(destAmt, 99750000000000000000), 100000000000000000000); - getAddressAdmin().transfer(sub(destAmt, ethToDeposit)); - lock(cdpID, ethToDeposit); + lock(cdpID, destAmt); emit LogLeverageCDP(cdpID, debtToBorrow, destAmt); From af1e0760fa2b84f5528a9599e87b3d4d17e12b60 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Mon, 6 May 2019 19:25:00 +0530 Subject: [PATCH 02/17] maxETH fixed --- contracts/ProxyLogics/InstaSave.sol | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contracts/ProxyLogics/InstaSave.sol b/contracts/ProxyLogics/InstaSave.sol index 48daec1..6cd26e2 100644 --- a/contracts/ProxyLogics/InstaSave.sol +++ b/contracts/ProxyLogics/InstaSave.sol @@ -325,6 +325,13 @@ contract GetDetails is MakerHelpers { uint maxDebtLimit = wdiv(colToUSD, 1500000000000000000) - 10; maxDaiToDraw = sub(maxDebtLimit, daiDebt); ethInUSD = usdPerEth; + + (uint expectedRate,) = KyberInterface(getAddressKyber()).getExpectedRate(getAddressETH(), getAddressDAI(), maxColToFree); + uint expectedDai = wmul(maxColToFree, expectedRate); + if (expectedDai > maxDaiToDraw) { + maxColToFree = wmul(maxColToFree, wdiv(maxDaiToDraw, expectedDai)); + } + } function getSave(uint cdpID, uint ethToSwap) public view returns (uint finalEthCol, uint finalDaiDebt, uint finalColToUSD, bool canSave) { From 0d383ee4d3bf783020c758dd854715c3805ac434 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Mon, 6 May 2019 21:05:55 +0530 Subject: [PATCH 03/17] removed maxEth --- contracts/ProxyLogics/InstaSave.sol | 7 ------- 1 file changed, 7 deletions(-) diff --git a/contracts/ProxyLogics/InstaSave.sol b/contracts/ProxyLogics/InstaSave.sol index 6cd26e2..48daec1 100644 --- a/contracts/ProxyLogics/InstaSave.sol +++ b/contracts/ProxyLogics/InstaSave.sol @@ -325,13 +325,6 @@ contract GetDetails is MakerHelpers { uint maxDebtLimit = wdiv(colToUSD, 1500000000000000000) - 10; maxDaiToDraw = sub(maxDebtLimit, daiDebt); ethInUSD = usdPerEth; - - (uint expectedRate,) = KyberInterface(getAddressKyber()).getExpectedRate(getAddressETH(), getAddressDAI(), maxColToFree); - uint expectedDai = wmul(maxColToFree, expectedRate); - if (expectedDai > maxDaiToDraw) { - maxColToFree = wmul(maxColToFree, wdiv(maxDaiToDraw, expectedDai)); - } - } function getSave(uint cdpID, uint ethToSwap) public view returns (uint finalEthCol, uint finalDaiDebt, uint finalColToUSD, bool canSave) { From f9a33dc7f6275a01c2535b458a03f9e3cf3a2d02 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Mon, 6 May 2019 21:09:38 +0530 Subject: [PATCH 04/17] added sub and add --- contracts/ProxyLogics/InstaSave.sol | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/ProxyLogics/InstaSave.sol b/contracts/ProxyLogics/InstaSave.sol index 48daec1..9f53027 100644 --- a/contracts/ProxyLogics/InstaSave.sol +++ b/contracts/ProxyLogics/InstaSave.sol @@ -319,10 +319,10 @@ contract GetDetails is MakerHelpers { function getMax(uint cdpID) public view returns (uint maxColToFree, uint maxDaiToDraw, uint ethInUSD) { bytes32 cup = bytes32(cdpID); (uint ethCol, uint daiDebt, uint usdPerEth) = getCDPStats(cup); - uint colToUSD = wmul(ethCol, usdPerEth) - 10; - uint minColNeeded = wmul(daiDebt, 1500000000000000000) + 10; + uint colToUSD = sub(wmul(ethCol, usdPerEth), 10); + uint minColNeeded = add(wmul(daiDebt, 1500000000000000000), 10); maxColToFree = wdiv(sub(colToUSD, minColNeeded), usdPerEth); - uint maxDebtLimit = wdiv(colToUSD, 1500000000000000000) - 10; + uint maxDebtLimit = sub(wdiv(colToUSD, 1500000000000000000), 10); maxDaiToDraw = sub(maxDebtLimit, daiDebt); ethInUSD = usdPerEth; } @@ -371,8 +371,8 @@ contract GetDetails is MakerHelpers { bool canSave ) { - uint colToUSD = wmul(ethCol, usdPerEth) - 10; - uint minColNeeded = wmul(daiDebt, 1500000000000000000) + 10; + uint colToUSD = sub(wmul(ethCol, usdPerEth), 10); + uint minColNeeded = add(wmul(daiDebt, 1500000000000000000), 10); uint colToFree = wdiv(sub(colToUSD, minColNeeded), usdPerEth); if (ethToSwap < colToFree) { colToFree = ethToSwap; @@ -405,8 +405,8 @@ contract GetDetails is MakerHelpers { bool canLeverage ) { - uint colToUSD = wmul(ethCol, usdPerEth) - 10; - uint maxDebtLimit = wdiv(colToUSD, 1500000000000000000) - 10; + uint colToUSD = sub(wmul(ethCol, usdPerEth), 10); + uint maxDebtLimit = sub(wdiv(colToUSD, 1500000000000000000), 10); uint debtToBorrow = sub(maxDebtLimit, daiDebt); if (daiToSwap < debtToBorrow) { debtToBorrow = daiToSwap; @@ -480,7 +480,7 @@ contract Save is GetDetails { wipe(cdpID, destAmt); if (thisBalance < address(this).balance) { - uint balToLock = address(this).balance - thisBalance; + uint balToLock = sub(address(this).balance, thisBalance); lock(cdpID, balToLock); } From a01b9c0370581d06724209aaeb76e6e6417c58c2 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sun, 12 May 2019 17:56:46 -0400 Subject: [PATCH 05/17] borrow and send implemented --- contracts/ProxyLogics/InstaMaker.sol | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/contracts/ProxyLogics/InstaMaker.sol b/contracts/ProxyLogics/InstaMaker.sol index c336dfe..0679900 100644 --- a/contracts/ProxyLogics/InstaMaker.sol +++ b/contracts/ProxyLogics/InstaMaker.sol @@ -117,6 +117,7 @@ contract CDPResolver is Helpers { event LogLock(uint cdpNum, uint amtETH, uint amtPETH, address owner); event LogFree(uint cdpNum, uint amtETH, uint amtPETH, address owner); event LogDraw(uint cdpNum, uint amtDAI, address owner); + event LogDrawSend(uint cdpNum, uint amtDAI, address to); event LogWipe(uint cdpNum, uint daiAmt, uint mkrFee, uint daiFee, address owner); event LogShut(uint cdpNum); @@ -208,6 +209,19 @@ contract CDPResolver is Helpers { } } + function drawSend(uint cdpNum, uint _wad, address to) public { + bytes32 cup = bytes32(cdpNum); + if (_wad > 0) { + TubInterface tub = TubInterface(getSaiTubAddress()); + + tub.draw(cup, _wad); + tub.sai().transfer(to, _wad); + + emit LogDraw(cdpNum, _wad, address(this)); + emit LogDrawSend(cdpNum, _wad, to); + } + } + function wipe(uint cdpNum, uint _wad) public { if (_wad > 0) { TubInterface tub = TubInterface(getSaiTubAddress()); From f8d71bd4032fbdd75dfdce3ad0bba8271129882f Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sun, 12 May 2019 18:12:18 -0400 Subject: [PATCH 06/17] require 0x0 in draw & send --- contracts/ProxyLogics/InstaMaker.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/ProxyLogics/InstaMaker.sol b/contracts/ProxyLogics/InstaMaker.sol index 0679900..fa29733 100644 --- a/contracts/ProxyLogics/InstaMaker.sol +++ b/contracts/ProxyLogics/InstaMaker.sol @@ -210,6 +210,7 @@ contract CDPResolver is Helpers { } function drawSend(uint cdpNum, uint _wad, address to) public { + require(to != address(0x0), "address-not-valid"); bytes32 cup = bytes32(cdpNum); if (_wad > 0) { TubInterface tub = TubInterface(getSaiTubAddress()); From fa2fb6ee1a619cd611de8ef0a68c4cf213c99aab Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sun, 26 May 2019 01:27:44 +0530 Subject: [PATCH 07/17] compound interface for write functions --- contracts/ProxyLogics/InstaCompound.sol | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 contracts/ProxyLogics/InstaCompound.sol diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol new file mode 100644 index 0000000..05c6185 --- /dev/null +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.5.0; + +interface CTokenInterface { + function mint(uint mintAmount) external returns (uint); // For ERC20 + function mint() external payable; // For ETH + function redeem(uint redeemTokens) external returns (uint); + function redeemUnderlying(uint redeemAmount) external returns (uint); + function borrow(uint borrowAmount) external returns (uint); + function repayBorrow(uint repayAmount) external returns (uint); // For ERC20 + function repayBorrow() external payable; // For ETH + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20 + function repayBorrowBehalf(address borrower) external payable; // For ETH + function liquidateBorrow(address borrower, uint repayAmount, address cTokenCollateral) external returns (uint); + function liquidateBorrow(address borrower, address cTokenCollateral) external payable; +} \ No newline at end of file From 02c21a9b28a3bc3da34ccefc86d57c4ea604d003 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sun, 26 May 2019 02:05:56 +0530 Subject: [PATCH 08/17] basic contract interface --- contracts/ProxyLogics/InstaCompound.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 05c6185..e5c3692 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -12,4 +12,14 @@ interface CTokenInterface { function repayBorrowBehalf(address borrower) external payable; // For ETH function liquidateBorrow(address borrower, uint repayAmount, address cTokenCollateral) external returns (uint); function liquidateBorrow(address borrower, address cTokenCollateral) external payable; + function exchangeRateCurrent() external returns (uint); + function getCash() external view returns (uint); + function totalBorrowsCurrent() external returns (uint); + function borrowBalanceCurrent(address account) external returns (uint); + function borrowRatePerBlock() external view returns (uint); + function totalSupply() external view returns (uint256); + function balanceOf(address owner) external view returns (uint256 balance); + function supplyRatePerBlock() external view returns (uint); + function totalReserves() external view returns (uint); + function reserveFactorMantissa() external view returns (uint); } \ No newline at end of file From 12b01426151402dae09e677823ace256085687ee Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Tue, 28 May 2019 04:36:05 +0530 Subject: [PATCH 09/17] interface & basic read functions --- contracts/ProxyLogics/InstaCompound.sol | 66 +++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index e5c3692..1cad898 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -1,6 +1,6 @@ -pragma solidity ^0.5.0; +pragma solidity ^0.5.7; -interface CTokenInterface { +interface CERC20Interface { function mint(uint mintAmount) external returns (uint); // For ERC20 function mint() external payable; // For ETH function redeem(uint redeemTokens) external returns (uint); @@ -17,9 +17,65 @@ interface CTokenInterface { function totalBorrowsCurrent() external returns (uint); function borrowBalanceCurrent(address account) external returns (uint); function borrowRatePerBlock() external view returns (uint); - function totalSupply() external view returns (uint256); - function balanceOf(address owner) external view returns (uint256 balance); function supplyRatePerBlock() external view returns (uint); function totalReserves() external view returns (uint); function reserveFactorMantissa() external view returns (uint); -} \ No newline at end of file + + function totalSupply() external view returns (uint256); + 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); +} + +interface ERC20Interface { + function allowance(address, address) external view returns (uint); + function balanceOf(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); +} + +interface ComptrollerInterface { + 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 getAccountLiquidity(address account) external view returns (uint, uint, uint); +} + + +contract Helpers { + + /** + * @dev get Compound Comptroller + */ + function getComptrollerAddress() public pure returns (address troller) { + troller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; + } + + // Need to check at the end + function exchangeRate(address cERC20) public returns (uint exchangeRateMantissa) { + CERC20Interface cToken = CERC20Interface(cERC20); + exchangeRateMantissa = cToken.exchangeRateCurrent(); + } + + function getCash(address cERC20) public view returns (uint cash) { + CERC20Interface cToken = CERC20Interface(cERC20); + cash = cToken.getCash(); + } + + // Need to check at the end + function totalBorrow(address cERC20) public returns (uint borrows) { + CERC20Interface cToken = CERC20Interface(cERC20); + borrows = cToken.totalBorrowsCurrent(); + } + + // Need to check at the end + function borrowBalance(address user, address cERC20) public returns (uint borrowAmt) { + CERC20Interface cToken = CERC20Interface(cERC20); + borrowAmt = cToken.borrowBalanceCurrent(user); + } + +} + From 821eee499b20c73e578c25ac9136f64c22efa347 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Tue, 28 May 2019 22:24:09 +0530 Subject: [PATCH 10/17] functions almost completed --- contracts/ProxyLogics/InstaCompound.sol | 167 ++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 12 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 1cad898..83f2f02 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -1,15 +1,9 @@ pragma solidity ^0.5.7; -interface CERC20Interface { - function mint(uint mintAmount) external returns (uint); // For ERC20 - function mint() external payable; // For ETH +interface CTokenInterface { function redeem(uint redeemTokens) external returns (uint); function redeemUnderlying(uint redeemAmount) external returns (uint); function borrow(uint borrowAmount) external returns (uint); - function repayBorrow(uint repayAmount) external returns (uint); // For ERC20 - function repayBorrow() external payable; // For ETH - function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20 - function repayBorrowBehalf(address borrower) external payable; // For ETH function liquidateBorrow(address borrower, uint repayAmount, address cTokenCollateral) external returns (uint); function liquidateBorrow(address borrower, address cTokenCollateral) external payable; function exchangeRateCurrent() external returns (uint); @@ -29,6 +23,18 @@ interface CERC20Interface { function transferFrom(address, address, uint) external returns (bool); } +interface CERC20Interface { + function mint(uint mintAmount) external returns (uint); // For ERC20 + function repayBorrow(uint repayAmount) external returns (uint); // For ERC20 + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20 +} + +interface CETHInterface { + function mint() external payable; // For ETH + function repayBorrow() external payable; // For ETH + function repayBorrowBehalf(address borrower) external payable; // For ETH +} + interface ERC20Interface { function allowance(address, address) external view returns (uint); function balanceOf(address) external view returns (uint); @@ -45,7 +51,42 @@ interface ComptrollerInterface { } -contract Helpers { +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; + } + +} + + +contract Helpers is DSMath { + + /** + * @dev setting allowance to kyber for the "user proxy" if required + * @param token is the token address + */ + function setApproval(address token, uint srcAmt, address to) internal { + ERC20Interface erc20Contract = ERC20Interface(token); + uint tokenAllowance = erc20Contract.allowance(address(this), to); + if (srcAmt > tokenAllowance) { + erc20Contract.approve(to, 2**255); + } + } /** * @dev get Compound Comptroller @@ -54,28 +95,130 @@ contract Helpers { troller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; } + /** + * @dev get CETH Address + */ + function getCETHAddress() public pure returns (address cEthAdd) { + cEthAdd = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; + } + // Need to check at the end function exchangeRate(address cERC20) public returns (uint exchangeRateMantissa) { - CERC20Interface cToken = CERC20Interface(cERC20); + CTokenInterface cToken = CTokenInterface(cERC20); exchangeRateMantissa = cToken.exchangeRateCurrent(); } function getCash(address cERC20) public view returns (uint cash) { - CERC20Interface cToken = CERC20Interface(cERC20); + CTokenInterface cToken = CTokenInterface(cERC20); cash = cToken.getCash(); } // Need to check at the end function totalBorrow(address cERC20) public returns (uint borrows) { - CERC20Interface cToken = CERC20Interface(cERC20); + CTokenInterface cToken = CTokenInterface(cERC20); borrows = cToken.totalBorrowsCurrent(); } // Need to check at the end function borrowBalance(address user, address cERC20) public returns (uint borrowAmt) { - CERC20Interface cToken = CERC20Interface(cERC20); + CTokenInterface cToken = CTokenInterface(cERC20); borrowAmt = cToken.borrowBalanceCurrent(user); } } + +contract CompoundResolver is Helpers { + + function enterMarkets(address[] calldata cTokensAdd) external returns (uint[] memory isSuccess) { + isSuccess = ComptrollerInterface(getComptrollerAddress()).enterMarkets(cTokensAdd); + } + + function exitMarket(address cTokensAdd) external returns (uint isSuccess) { + isSuccess = ComptrollerInterface(getComptrollerAddress()).exitMarket(cTokensAdd); + } + + function mintCETH() external payable { + CETHInterface cToken = CETHInterface(getCETHAddress()); + cToken.mint.value(msg.value)(); + } + + function mintCToken(address erc20, address cErc20, uint tokenAmt) external { + ERC20Interface token = ERC20Interface(erc20); + uint toDeposit = token.balanceOf(msg.sender); + if (toDeposit > tokenAmt) { + toDeposit = tokenAmt; + } + token.transferFrom(msg.sender, address(this), toDeposit); + CERC20Interface cToken = CERC20Interface(cErc20); + setApproval(erc20, toDeposit, cErc20); + assert(cToken.mint(toDeposit) == 0); + } + + function redeem(address cErc20, uint cTokenAmt) external { + CTokenInterface cToken = CTokenInterface(cErc20); + uint toBurn = cToken.balanceOf(address(this)); + if (toBurn > cTokenAmt) { + toBurn = cTokenAmt; + } + setApproval(cErc20, toBurn, cErc20); + require(cToken.redeem(toBurn) == 0, "something went wrong"); + } + + function redeemUnderlying(address cErc20, uint tokenAmt) external { + CTokenInterface cToken = CTokenInterface(cErc20); + setApproval(cErc20, 10**50, cErc20); + require(cToken.redeemUnderlying(tokenAmt) == 0, "something went wrong"); + } + + function borrow(address erc20, address cErc20, uint tokenAmt) external { + require(CTokenInterface(cErc20).borrow(tokenAmt) == 0, "got collateral?"); + ERC20Interface(erc20).transfer(msg.sender, tokenAmt); + } + + function repayEth() external payable { + CETHInterface cToken = CETHInterface(getCETHAddress()); + cToken.repayBorrow.value(msg.value)(); + } + + function repaytoken(address erc20, address cErc20, uint tokenAmt) external payable { + CERC20Interface cToken = CERC20Interface(cErc20); + ERC20Interface token = ERC20Interface(erc20); + uint toRepay = token.balanceOf(msg.sender); + if (toRepay > tokenAmt) { + toRepay = tokenAmt; + } + setApproval(erc20, toRepay, cErc20); + token.transferFrom(msg.sender, address(this), toRepay); + require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); + } + + function repayEthBehalf(address borrower) external payable { + CETHInterface cToken = CETHInterface(getCETHAddress()); + cToken.repayBorrowBehalf.value(msg.value)(borrower); + } + + function repaytokenBehalf( + address borrower, + address erc20, + address cErc20, + uint tokenAmt + ) external payable + { + CERC20Interface cToken = CERC20Interface(cErc20); + ERC20Interface token = ERC20Interface(erc20); + uint toRepay = token.balanceOf(msg.sender); + if (toRepay > tokenAmt) { + toRepay = tokenAmt; + } + setApproval(erc20, toRepay, cErc20); + uint tokenAllowance = token.allowance(address(this), cErc20); + if (toRepay > tokenAllowance) { + token.approve(cErc20, toRepay); + } + token.transferFrom(msg.sender, address(this), toRepay); + require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); + } + + +} \ No newline at end of file From c5d5176923abad8d11d39959ac6d543bf197c668 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Wed, 29 May 2019 19:36:23 +0530 Subject: [PATCH 11/17] removed read functions --- contracts/ProxyLogics/InstaCompound.sol | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 83f2f02..2bc03af 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -102,29 +102,6 @@ contract Helpers is DSMath { cEthAdd = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; } - // Need to check at the end - function exchangeRate(address cERC20) public returns (uint exchangeRateMantissa) { - CTokenInterface cToken = CTokenInterface(cERC20); - exchangeRateMantissa = cToken.exchangeRateCurrent(); - } - - function getCash(address cERC20) public view returns (uint cash) { - CTokenInterface cToken = CTokenInterface(cERC20); - cash = cToken.getCash(); - } - - // Need to check at the end - function totalBorrow(address cERC20) public returns (uint borrows) { - CTokenInterface cToken = CTokenInterface(cERC20); - borrows = cToken.totalBorrowsCurrent(); - } - - // Need to check at the end - function borrowBalance(address user, address cERC20) public returns (uint borrowAmt) { - CTokenInterface cToken = CTokenInterface(cERC20); - borrowAmt = cToken.borrowBalanceCurrent(user); - } - } From af8a388c84059e92c7fa6366a5cf87a424000977 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Fri, 31 May 2019 16:31:28 +0530 Subject: [PATCH 12/17] function optimization --- contracts/ProxyLogics/InstaCompound.sol | 138 +++++++++++++++--------- 1 file changed, 86 insertions(+), 52 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 2bc03af..f4c7400 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -80,14 +80,20 @@ contract Helpers is DSMath { * @dev setting allowance to kyber for the "user proxy" if required * @param token is the token address */ - function setApproval(address token, uint srcAmt, address to) internal { - ERC20Interface erc20Contract = ERC20Interface(token); + function setApproval(ERC20Interface erc20Contract, uint srcAmt, address to) internal { uint tokenAllowance = erc20Contract.allowance(address(this), to); if (srcAmt > tokenAllowance) { erc20Contract.approve(to, 2**255); } } + /** + * @dev get ethereum address for trade + */ + function getAddressETH() public pure returns (address eth) { + eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; + } + /** * @dev get Compound Comptroller */ @@ -115,64 +121,73 @@ contract CompoundResolver is Helpers { isSuccess = ComptrollerInterface(getComptrollerAddress()).exitMarket(cTokensAdd); } - function mintCETH() external payable { - CETHInterface cToken = CETHInterface(getCETHAddress()); - cToken.mint.value(msg.value)(); - } - - function mintCToken(address erc20, address cErc20, uint tokenAmt) external { - ERC20Interface token = ERC20Interface(erc20); - uint toDeposit = token.balanceOf(msg.sender); - if (toDeposit > tokenAmt) { - toDeposit = tokenAmt; + function mintCToken(address erc20, address cErc20, uint tokenAmt) external payable { + if (erc20 == getAddressETH()) { + CETHInterface cToken = CETHInterface(cErc20); + cToken.mint.value(msg.value)(); + } else { + ERC20Interface token = ERC20Interface(erc20); + uint toDeposit = token.balanceOf(msg.sender); + if (toDeposit > tokenAmt) { + toDeposit = tokenAmt; + } + token.transferFrom(msg.sender, address(this), toDeposit); + CERC20Interface cToken = CERC20Interface(cErc20); + setApproval(token, toDeposit, cErc20); + assert(cToken.mint(toDeposit) == 0); } - token.transferFrom(msg.sender, address(this), toDeposit); - CERC20Interface cToken = CERC20Interface(cErc20); - setApproval(erc20, toDeposit, cErc20); - assert(cToken.mint(toDeposit) == 0); } - function redeem(address cErc20, uint cTokenAmt) external { + function redeemCToken(address erc20, address cErc20, uint cTokenAmt) external { CTokenInterface cToken = CTokenInterface(cErc20); uint toBurn = cToken.balanceOf(address(this)); if (toBurn > cTokenAmt) { toBurn = cTokenAmt; } - setApproval(cErc20, toBurn, cErc20); + setApproval(cToken, toBurn, cErc20); require(cToken.redeem(toBurn) == 0, "something went wrong"); + transferToken(erc20); } - function redeemUnderlying(address cErc20, uint tokenAmt) external { + function redeemUnderlying(address erc20, address cErc20, uint tokenAmt) external { CTokenInterface cToken = CTokenInterface(cErc20); - setApproval(cErc20, 10**50, cErc20); + setApproval(cToken, 10**50, cErc20); require(cToken.redeemUnderlying(tokenAmt) == 0, "something went wrong"); + transferToken(erc20); + } + + function transferToken(address erc20) internal { + if (erc20 == getAddressETH()) { + msg.sender.transfer(address(this).balance); + } else { + ERC20Interface erc20Contract = ERC20Interface(erc20); + uint srcBal = erc20Contract.balanceOf(address(this)); + if (srcBal > 0) { + erc20Contract.transfer(msg.sender, srcBal); + } + } } function borrow(address erc20, address cErc20, uint tokenAmt) external { require(CTokenInterface(cErc20).borrow(tokenAmt) == 0, "got collateral?"); - ERC20Interface(erc20).transfer(msg.sender, tokenAmt); + transferToken(erc20); } - function repayEth() external payable { - CETHInterface cToken = CETHInterface(getCETHAddress()); - cToken.repayBorrow.value(msg.value)(); - } - - function repaytoken(address erc20, address cErc20, uint tokenAmt) external payable { - CERC20Interface cToken = CERC20Interface(cErc20); - ERC20Interface token = ERC20Interface(erc20); - uint toRepay = token.balanceOf(msg.sender); - if (toRepay > tokenAmt) { - toRepay = tokenAmt; + function repayToken(address erc20, address cErc20, uint tokenAmt) external payable { + if (erc20 == getAddressETH()) { + CETHInterface cToken = CETHInterface(cErc20); + cToken.repayBorrow.value(msg.value)(); + } else { + CERC20Interface cToken = CERC20Interface(cErc20); + ERC20Interface token = ERC20Interface(erc20); + uint toRepay = token.balanceOf(msg.sender); + if (toRepay > tokenAmt) { + toRepay = tokenAmt; + } + setApproval(token, toRepay, cErc20); + token.transferFrom(msg.sender, address(this), toRepay); + require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); } - setApproval(erc20, toRepay, cErc20); - token.transferFrom(msg.sender, address(this), toRepay); - require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); - } - - function repayEthBehalf(address borrower) external payable { - CETHInterface cToken = CETHInterface(getCETHAddress()); - cToken.repayBorrowBehalf.value(msg.value)(borrower); } function repaytokenBehalf( @@ -182,20 +197,39 @@ contract CompoundResolver is Helpers { uint tokenAmt ) external payable { - CERC20Interface cToken = CERC20Interface(cErc20); - ERC20Interface token = ERC20Interface(erc20); - uint toRepay = token.balanceOf(msg.sender); - if (toRepay > tokenAmt) { - toRepay = tokenAmt; + if (erc20 == getAddressETH()) { + CETHInterface cToken = CETHInterface(getCETHAddress()); + cToken.repayBorrowBehalf.value(msg.value)(borrower); + } else { + CERC20Interface cToken = CERC20Interface(cErc20); + ERC20Interface token = ERC20Interface(erc20); + uint toRepay = token.balanceOf(msg.sender); + if (toRepay > tokenAmt) { + toRepay = tokenAmt; + } + setApproval(token, toRepay, cErc20); + uint tokenAllowance = token.allowance(address(this), cErc20); + if (toRepay > tokenAllowance) { + token.approve(cErc20, toRepay); + } + token.transferFrom(msg.sender, address(this), toRepay); + require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); } - setApproval(erc20, toRepay, cErc20); - uint tokenAllowance = token.allowance(address(this), cErc20); - if (toRepay > tokenAllowance) { - token.approve(cErc20, toRepay); - } - token.transferFrom(msg.sender, address(this), toRepay); - require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); } +} + + +contract InstaCompound is CompoundResolver { + + uint public version; + + /** + * @dev setting up variables on deployment + * 1...2...3 versioning in each subsequent deployments + */ + constructor(uint _version) public { + version = _version; + } } \ No newline at end of file From 0e514897ffbb91e1d3ba15f4af1a353b39116539 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Fri, 31 May 2019 19:13:52 +0530 Subject: [PATCH 13/17] compound events integration --- contracts/ProxyLogics/InstaCompound.sol | 73 +++++++++++++++++++++---- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index f4c7400..a1450ba 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -108,11 +108,34 @@ contract Helpers is DSMath { cEthAdd = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; } + function getTokenAmt(CTokenInterface cToken, uint cTokenAmt) public returns(uint tokenAmt) { + uint exchangeRate = cToken.exchangeRateCurrent(); + tokenAmt = wmul(exchangeRate, cTokenAmt); + } + + function transferToken(address erc20) internal { + if (erc20 == getAddressETH()) { + msg.sender.transfer(address(this).balance); + } else { + ERC20Interface erc20Contract = ERC20Interface(erc20); + uint srcBal = erc20Contract.balanceOf(address(this)); + if (srcBal > 0) { + erc20Contract.transfer(msg.sender, srcBal); + } + } + } + } contract CompoundResolver is Helpers { + event LogMint(address erc20, address cErc20, uint tokenAmt, address owner); + event LogRedeem(address erc20, address cErc20, uint tokenAmt, address owner); + event LogBorrow(address erc20, address cErc20, uint tokenAmt, address owner); + event LogRepay(address erc20, address cErc20, uint tokenAmt, address owner); + event LogRepayBehalf(address erc20, address cErc20, uint tokenAmt, address owner, address borrower); + function enterMarkets(address[] calldata cTokensAdd) external returns (uint[] memory isSuccess) { isSuccess = ComptrollerInterface(getComptrollerAddress()).enterMarkets(cTokensAdd); } @@ -136,6 +159,12 @@ contract CompoundResolver is Helpers { setApproval(token, toDeposit, cErc20); assert(cToken.mint(toDeposit) == 0); } + emit LogMint( + erc20, + cErc20, + tokenAmt, + msg.sender + ); } function redeemCToken(address erc20, address cErc20, uint cTokenAmt) external { @@ -147,6 +176,13 @@ contract CompoundResolver is Helpers { setApproval(cToken, toBurn, cErc20); require(cToken.redeem(toBurn) == 0, "something went wrong"); transferToken(erc20); + uint tokenReturned = wmul(cToken.balanceOf(address(this)), cToken.exchangeRateCurrent()); + emit LogRedeem( + erc20, + cErc20, + tokenReturned, + address(this) + ); } function redeemUnderlying(address erc20, address cErc20, uint tokenAmt) external { @@ -154,23 +190,23 @@ contract CompoundResolver is Helpers { setApproval(cToken, 10**50, cErc20); require(cToken.redeemUnderlying(tokenAmt) == 0, "something went wrong"); transferToken(erc20); - } - - function transferToken(address erc20) internal { - if (erc20 == getAddressETH()) { - msg.sender.transfer(address(this).balance); - } else { - ERC20Interface erc20Contract = ERC20Interface(erc20); - uint srcBal = erc20Contract.balanceOf(address(this)); - if (srcBal > 0) { - erc20Contract.transfer(msg.sender, srcBal); - } - } + emit LogRedeem( + erc20, + cErc20, + tokenAmt, + address(this) + ); } function borrow(address erc20, address cErc20, uint tokenAmt) external { require(CTokenInterface(cErc20).borrow(tokenAmt) == 0, "got collateral?"); transferToken(erc20); + emit LogBorrow( + erc20, + cErc20, + tokenAmt, + address(this) + ); } function repayToken(address erc20, address cErc20, uint tokenAmt) external payable { @@ -188,6 +224,12 @@ contract CompoundResolver is Helpers { token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); } + emit LogRepay( + erc20, + cErc20, + tokenAmt, + address(this) + ); } function repaytokenBehalf( @@ -215,6 +257,13 @@ contract CompoundResolver is Helpers { token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); } + emit LogRepay( + erc20, + cErc20, + tokenAmt, + address(this), + borrower + ); } } From 1552411409968aa5e1eece3162088c1e2df4f67e Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Fri, 31 May 2019 19:17:56 +0530 Subject: [PATCH 14/17] removed unnecessary things --- contracts/ProxyLogics/InstaCompound.sol | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index a1450ba..76f4df1 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -102,17 +102,8 @@ contract Helpers is DSMath { } /** - * @dev get CETH Address + * @dev Transfer ETH/ERC20 to user */ - function getCETHAddress() public pure returns (address cEthAdd) { - cEthAdd = 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; - } - - function getTokenAmt(CTokenInterface cToken, uint cTokenAmt) public returns(uint tokenAmt) { - uint exchangeRate = cToken.exchangeRateCurrent(); - tokenAmt = wmul(exchangeRate, cTokenAmt); - } - function transferToken(address erc20) internal { if (erc20 == getAddressETH()) { msg.sender.transfer(address(this).balance); @@ -240,7 +231,7 @@ contract CompoundResolver is Helpers { ) external payable { if (erc20 == getAddressETH()) { - CETHInterface cToken = CETHInterface(getCETHAddress()); + CETHInterface cToken = CETHInterface(cErc20); cToken.repayBorrowBehalf.value(msg.value)(borrower); } else { CERC20Interface cToken = CERC20Interface(cErc20); From 0577aee2216d010476e1dbad8338a84ea7c9b43d Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sat, 1 Jun 2019 10:37:45 +0530 Subject: [PATCH 15/17] removed white space --- contracts/ProxyLogics/InstaCompound.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 76f4df1..64ca15b 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -102,7 +102,7 @@ contract Helpers is DSMath { } /** - * @dev Transfer ETH/ERC20 to user + * @dev Transfer ETH/ERC20 to user */ function transferToken(address erc20) internal { if (erc20 == getAddressETH()) { From c91dddaa6beb9438716ebb328779eb821b8178a0 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sat, 1 Jun 2019 15:48:39 +0530 Subject: [PATCH 16/17] functions description --- contracts/ProxyLogics/InstaCompound.sol | 49 ++++++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index 64ca15b..e16940f 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -77,10 +77,10 @@ contract DSMath { contract Helpers is DSMath { /** - * @dev setting allowance to kyber for the "user proxy" if required - * @param token is the token address + * @dev setting allowance to compound for the "user proxy" if required */ - function setApproval(ERC20Interface erc20Contract, uint srcAmt, address to) internal { + function setApproval(address erc20, uint srcAmt, address to) internal { + ERC20Interface erc20Contract = ERC20Interface(erc20); uint tokenAllowance = erc20Contract.allowance(address(this), to); if (srcAmt > tokenAllowance) { erc20Contract.approve(to, 2**255); @@ -95,10 +95,11 @@ contract Helpers is DSMath { } /** - * @dev get Compound Comptroller + * @dev get Compound Comptroller Address */ function getComptrollerAddress() public pure returns (address troller) { troller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; + // troller = 0x2EAa9D77AE4D8f9cdD9FAAcd44016E746485bddb; // Rinkeby } /** @@ -127,14 +128,23 @@ contract CompoundResolver is Helpers { event LogRepay(address erc20, address cErc20, uint tokenAmt, address owner); event LogRepayBehalf(address erc20, address cErc20, uint tokenAmt, address owner, address borrower); + /** + * @dev Enter Compound Market to start borrowing + */ function enterMarkets(address[] calldata cTokensAdd) external returns (uint[] memory isSuccess) { isSuccess = ComptrollerInterface(getComptrollerAddress()).enterMarkets(cTokensAdd); } + /** + * @dev Exit Compound Market to stop borrowing + */ function exitMarket(address cTokensAdd) external returns (uint isSuccess) { isSuccess = ComptrollerInterface(getComptrollerAddress()).exitMarket(cTokensAdd); } + /** + * @dev Deposit ETH/ERC20 and mint Compound Tokens + */ function mintCToken(address erc20, address cErc20, uint tokenAmt) external payable { if (erc20 == getAddressETH()) { CETHInterface cToken = CETHInterface(cErc20); @@ -147,7 +157,7 @@ contract CompoundResolver is Helpers { } token.transferFrom(msg.sender, address(this), toDeposit); CERC20Interface cToken = CERC20Interface(cErc20); - setApproval(token, toDeposit, cErc20); + setApproval(erc20, toDeposit, cErc20); assert(cToken.mint(toDeposit) == 0); } emit LogMint( @@ -158,13 +168,17 @@ contract CompoundResolver is Helpers { ); } + /** + * @dev Redeem ETH/ERC20 and burn Compound Tokens + * @param cTokenAmt Amount of CToken To burn + */ function redeemCToken(address erc20, address cErc20, uint cTokenAmt) external { CTokenInterface cToken = CTokenInterface(cErc20); uint toBurn = cToken.balanceOf(address(this)); if (toBurn > cTokenAmt) { toBurn = cTokenAmt; } - setApproval(cToken, toBurn, cErc20); + setApproval(cErc20, toBurn, cErc20); require(cToken.redeem(toBurn) == 0, "something went wrong"); transferToken(erc20); uint tokenReturned = wmul(cToken.balanceOf(address(this)), cToken.exchangeRateCurrent()); @@ -176,9 +190,13 @@ contract CompoundResolver is Helpers { ); } + /** + * @dev Redeem ETH/ERC20 and mint Compound Tokens + * @param tokenAmt Amount of token To Redeem + */ function redeemUnderlying(address erc20, address cErc20, uint tokenAmt) external { CTokenInterface cToken = CTokenInterface(cErc20); - setApproval(cToken, 10**50, cErc20); + setApproval(cErc20, 10**50, cErc20); require(cToken.redeemUnderlying(tokenAmt) == 0, "something went wrong"); transferToken(erc20); emit LogRedeem( @@ -189,6 +207,9 @@ contract CompoundResolver is Helpers { ); } + /** + * @dev borrow ETH/ERC20 + */ function borrow(address erc20, address cErc20, uint tokenAmt) external { require(CTokenInterface(cErc20).borrow(tokenAmt) == 0, "got collateral?"); transferToken(erc20); @@ -200,6 +221,9 @@ contract CompoundResolver is Helpers { ); } + /** + * @dev Pay Debt ETH/ERC20 + */ function repayToken(address erc20, address cErc20, uint tokenAmt) external payable { if (erc20 == getAddressETH()) { CETHInterface cToken = CETHInterface(cErc20); @@ -211,7 +235,7 @@ contract CompoundResolver is Helpers { if (toRepay > tokenAmt) { toRepay = tokenAmt; } - setApproval(token, toRepay, cErc20); + setApproval(erc20, toRepay, cErc20); token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); } @@ -223,6 +247,9 @@ contract CompoundResolver is Helpers { ); } + /** + * @dev Pay Debt for someone else + */ function repaytokenBehalf( address borrower, address erc20, @@ -240,7 +267,7 @@ contract CompoundResolver is Helpers { if (toRepay > tokenAmt) { toRepay = tokenAmt; } - setApproval(token, toRepay, cErc20); + setApproval(erc20, toRepay, cErc20); uint tokenAllowance = token.allowance(address(this), cErc20); if (toRepay > tokenAllowance) { token.approve(cErc20, toRepay); @@ -248,7 +275,7 @@ contract CompoundResolver is Helpers { token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); } - emit LogRepay( + emit LogRepayBehalf( erc20, cErc20, tokenAmt, @@ -272,4 +299,6 @@ contract InstaCompound is CompoundResolver { version = _version; } + function() external payable {} + } \ No newline at end of file From 18958f2ad2807d45c4853e54f38f3dae4f318d36 Mon Sep 17 00:00:00 2001 From: Samyak Jain Date: Sat, 1 Jun 2019 16:13:16 +0530 Subject: [PATCH 17/17] in access repay set max --- contracts/ProxyLogics/InstaCompound.sol | 27 ++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/contracts/ProxyLogics/InstaCompound.sol b/contracts/ProxyLogics/InstaCompound.sol index e16940f..5c179d9 100644 --- a/contracts/ProxyLogics/InstaCompound.sol +++ b/contracts/ProxyLogics/InstaCompound.sol @@ -9,7 +9,6 @@ interface CTokenInterface { function exchangeRateCurrent() external returns (uint); function getCash() external view returns (uint); function totalBorrowsCurrent() external returns (uint); - function borrowBalanceCurrent(address account) external returns (uint); function borrowRatePerBlock() external view returns (uint); function supplyRatePerBlock() external view returns (uint); function totalReserves() external view returns (uint); @@ -27,12 +26,14 @@ interface CERC20Interface { function mint(uint mintAmount) external returns (uint); // For ERC20 function repayBorrow(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); } interface CETHInterface { function mint() external payable; // For ETH function repayBorrow() external payable; // For ETH function repayBorrowBehalf(address borrower) external payable; // For ETH + function borrowBalanceCurrent(address account) external returns (uint); } interface ERC20Interface { @@ -227,14 +228,24 @@ contract CompoundResolver is Helpers { function repayToken(address erc20, address cErc20, uint tokenAmt) external payable { if (erc20 == getAddressETH()) { CETHInterface cToken = CETHInterface(cErc20); + uint toRepay = msg.value; + uint borrows = cToken.borrowBalanceCurrent(address(this)); + if (toRepay > borrows) { + toRepay = borrows; + msg.sender.transfer(msg.value - toRepay); + } cToken.repayBorrow.value(msg.value)(); } else { CERC20Interface cToken = CERC20Interface(cErc20); ERC20Interface token = ERC20Interface(erc20); uint toRepay = token.balanceOf(msg.sender); + uint borrows = cToken.borrowBalanceCurrent(address(this)); if (toRepay > tokenAmt) { toRepay = tokenAmt; } + if (toRepay > borrows) { + toRepay = borrows; + } setApproval(erc20, toRepay, cErc20); token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrow(toRepay) == 0, "transfer approved?"); @@ -259,19 +270,25 @@ contract CompoundResolver is Helpers { { if (erc20 == getAddressETH()) { CETHInterface cToken = CETHInterface(cErc20); + uint toRepay = msg.value; + uint borrows = cToken.borrowBalanceCurrent(address(this)); + if (toRepay > borrows) { + toRepay = borrows; + msg.sender.transfer(msg.value - toRepay); + } cToken.repayBorrowBehalf.value(msg.value)(borrower); } else { CERC20Interface cToken = CERC20Interface(cErc20); ERC20Interface token = ERC20Interface(erc20); uint toRepay = token.balanceOf(msg.sender); + uint borrows = cToken.borrowBalanceCurrent(address(this)); if (toRepay > tokenAmt) { toRepay = tokenAmt; } - setApproval(erc20, toRepay, cErc20); - uint tokenAllowance = token.allowance(address(this), cErc20); - if (toRepay > tokenAllowance) { - token.approve(cErc20, toRepay); + if (toRepay > borrows) { + toRepay = borrows; } + setApproval(erc20, toRepay, cErc20); token.transferFrom(msg.sender, address(this), toRepay); require(cToken.repayBorrowBehalf(borrower, tokenAmt) == 0, "transfer approved?"); }