pragma solidity ^0.5.7; 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); function deposit() external payable; function withdraw(uint) external; } interface TubInterface { function open() external returns (bytes32); function join(uint) external; function exit(uint) external; function lock(bytes32, uint) external; function free(bytes32, uint) external; function draw(bytes32, uint) external; function wipe(bytes32, uint) external; function give(bytes32, address) external; function shut(bytes32) external; function cups(bytes32) external view returns (address, uint, uint, uint); function gem() external view returns (ERC20Interface); function gov() external view returns (ERC20Interface); function skr() external view returns (ERC20Interface); function sai() external view returns (ERC20Interface); function ink(bytes32) external view returns (uint); function tab(bytes32) external returns (uint); function rap(bytes32) external returns (uint); function per() external view returns (uint); function pep() external view returns (PepInterface); } interface PepInterface { function peek() external returns (bytes32, 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); } interface CTokenInterface { function borrow(uint borrowAmount) external returns (uint); function exchangeRateCurrent() external returns (uint); function transfer(address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool); } interface BridgeInterface { function makerToCompound(uint, uint, uint) external returns (uint); function compoundToMaker(uint, uint, uint) external; } 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; uint constant RAY = 10 ** 27; function rmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), RAY / 2) / RAY; } function rdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, RAY), y / 2) / y; } 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 Helper is DSMath { /** * @dev get MakerDAO CDP engine */ function getSaiTubAddress() public pure returns (address sai) { sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; } /** * @dev get Compound Comptroller Address */ function getComptrollerAddress() public pure returns (address troller) { troller = 0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B; } /** * @dev get Compound Comptroller Address */ function getDAIAddress() public pure returns (address dai) { dai = 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359; } /** * @dev get Compound Comptroller Address */ function getCDAIAddress() public pure returns (address cDai) { cDai = 0xF5DCe57282A584D2746FaF1593d3121Fcac444dC; } /** * @dev get Compound Comptroller Address */ function getBridgeAddress() public pure returns (address bridge) { bridge = ;// } /** * @dev setting allowance to compound for the "user proxy" if required */ 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); } } } contract MakerHelper is Helper { /** * @dev transfer CDP ownership */ function give(uint cdpNum, address nextOwner) internal { TubInterface(getSaiTubAddress()).give(bytes32(cdpNum), nextOwner); } } contract CompoundHelper is MakerHelper { function enterMarket(address cErc20) internal { ComptrollerInterface troller = ComptrollerInterface(getComptrollerAddress()); address[] memory markets = troller.getAssetsIn(address(this)); bool isEntered = false; for (uint i = 0; i < markets.length; i++) { if (markets[i] == cErc20) { isEntered = true; } } if (!isEntered) { address[] memory toEnter = new address[](1); toEnter[0] = cErc20; troller.enterMarkets(toEnter); } } /** * @dev borrow ETH/ERC20 */ function borrowDAI(uint tokenAmt) internal { enterMarket(getCETHAddress()); enterMarket(getCDAIAddress()); require(CTokenInterface(getCDAIAddress()).borrow(tokenAmt) == 0, "got collateral?"); } } contract InstaBridge is CompoundHelper { function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public { give(cdpId, getBridgeAddress()); BridgeInterface bridge = BridgeInterface(getBridgeAddress()); uint daiAmt = bridge.makerToCompound(cdpId, ethCol, daiDebt); borrowDAI(daiAmt); setApproval(getDaiAddress(), daiAmt, getBridgeAddress()); bridge.takeDebtBack(daiAmt); } function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public { if (cdpId != 0) { give(cdpId, getBridgeAddress()); } BridgeInterface bridge = BridgeInterface(getBridgeAddress()); setApproval(getCEthAddress(), 2**150, getBridgeAddress()); uint daiAmt = bridge.compoundToMaker(cdpId, ethCol, daiDebt); } }