From 6105f0d6e73bdb142f78ebfaf1a3895051c598d0 Mon Sep 17 00:00:00 2001 From: Mubaris NK Date: Mon, 4 Jan 2021 19:32:26 +0530 Subject: [PATCH] Add compound helpers --- contracts/connectors/refinance.sol | 222 +++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 contracts/connectors/refinance.sol diff --git a/contracts/connectors/refinance.sol b/contracts/connectors/refinance.sol new file mode 100644 index 0000000..7542ef2 --- /dev/null +++ b/contracts/connectors/refinance.sol @@ -0,0 +1,222 @@ +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +interface MemoryInterface { + function getUint(uint _id) external returns (uint _num); + function setUint(uint _id, uint _val) external; +} + +interface TokenInterface { + function approve(address, uint256) external; + function transfer(address, uint) external; + function transferFrom(address, address, uint) external; + function deposit() external payable; + function withdraw(uint) external; + function balanceOf(address) external view returns (uint); + function decimals() external view returns (uint); +} + +interface DSAInterface { + function isAuth(address) external view returns(bool); +} + +// Compound Helpers +interface CTokenInterface { + function mint(uint mintAmount) external returns (uint); + function redeem(uint redeemTokens) external returns (uint); + function borrow(uint borrowAmount) external returns (uint); + function repayBorrow(uint repayAmount) external returns (uint); + function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); // For ERC20 + function liquidateBorrow(address borrower, uint repayAmount, address cTokenCollateral) external returns (uint); + + function borrowBalanceCurrent(address account) external returns (uint); + function redeemUnderlying(uint redeemAmount) external returns (uint); + function exchangeRateCurrent() external returns (uint); + + function balanceOf(address owner) external view returns (uint256 balance); + function transferFrom(address, address, uint) external returns (bool); +} + +interface CETHInterface { + function mint() external payable; + function repayBorrow() external payable; + function repayBorrowBehalf(address borrower) external payable; + function liquidateBorrow(address borrower, address cTokenCollateral) external payable; +} + +interface InstaMapping { + function cTokenMapping(address) external view returns (address); +} + +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); +} +// End Compound 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 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 Return Memory Variable Address + */ + function getMemoryAddr() internal pure returns (address) { + return 0x8a5419CfC711B2343c17a6ABf4B2bAFaBb06957F; // InstaMemory Address + } + + /** + * @dev Return InstaDApp Mapping Address + */ + function getMappingAddr() internal pure returns (address) { + return 0xe81F70Cc7C0D46e12d70efc60607F16bbD617E88; // InstaMapping Address + } + + /** + * @dev Return CETH Address + */ + function getCETHAddr() internal pure returns (address) { + return 0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5; + } + + /** + * @dev Return Compound Comptroller Address + */ + function getComptrollerAddress() internal pure returns (address) { + return 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; + } + + /** + * @dev enter compound market + */ + function enterMarkets(address[] memory cErc20) internal { + ComptrollerInterface(getComptrollerAddress()).enterMarkets(cErc20); + } + + /** + * @dev Get Uint value from InstaMemory Contract. + */ + function getUint(uint getId, uint val) internal returns (uint returnVal) { + returnVal = getId == 0 ? val : MemoryInterface(getMemoryAddr()).getUint(getId); + } + + /** + * @dev Set Uint value in InstaMemory Contract. + */ + function setUint(uint setId, uint val) internal { + if (setId != 0) MemoryInterface(getMemoryAddr()).setUint(setId, val); + } +} + +contract CompoundHelpers is Helpers { + + function _compEnterMarkets(uint length, address[] memory tokens) { + ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress()); + address[] memory cTokens = new address[](length); + + for (uint i = 0; i < length; i++) { + cTokens[i] = InstaMapping(getMappingAddr()).cTokenMapping(tokens[i]); + } + troller.enterMarkets(cTokens); + } + + function _compBorrow( + uint length, + address[] memory tokens, + uint[] memory amts + ) internal { + for (uint i = 0; i < length; i++) { + if (amts[i] > 0) + address cToken = InstaMapping(getMappingAddr()).cTokenMapping(tokens[i]); + require(CTokenInterface(cToken).borrow(amts[i]) == 0, "borrow-failed-collateral?"); + } + } + + function _compDeposit( + uint length, + address[] memory tokens, + uint[] memory amts + ) internal { + for (uint i = 0; i < length; i++) { + if (amts[i] > 0) { + address cToken = InstaMapping(getMappingAddr()).cTokenMapping(tokens[i]); + if (tokens[i] != getEthAddr()) { + TokenInterface tokenContract = TokenInterface(tokens[i]); + tokenContract.approve(cToken, amts[i]); + require(CTokenInterface(cToken).mint(amts[i]) == 0, "deposit-failed"); + } else { + CETHInterface(cToken).mint.value(amts[i])(); + } + } + } + } + + function _compWithdraw( + uint length, + address[] memory tokens, + uint[] memory amts + ) internal { + for (uint i = 0; i < length; i++) { + if (amts[i] > 0) { + address cToken = InstaMapping(getMappingAddr()).cTokenMapping(tokens[i]); + CTokenInterface cTokenContract = CTokenInterface(cToken); + require(cTokenContract.redeemUnderlying(amts[i]) == 0, "withdraw-failed"); + } + } + } + + function _compPayback( + uint length, + address[] memory tokens, + uint[] memory amts + ) internal { + for (uint i = 0; i < length; i++) { + if (amts[i] > 0) { + address cToken = InstaMapping(getMappingAddr()).cTokenMapping(tokens[i]); + if (tokens[i] != getEthAddr()) { + TokenInterface tokenContract = TokenInterface(tokens[i]); + tokenContract.approve(cToken, amts[i]); + require(cTokenContract.repayBorrow(amts[i]) == 0, "repay-failed."); + } else { + CETHInterface(cToken).repayBorrow.value(amts[i])(); + } + } + } + } +}