smart-contract/contracts/ProxyLogics/InstaBridge.sol
2019-06-20 02:00:22 +05:30

206 lines
6.3 KiB
Solidity

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 = ;// <BRIDGE ADDRESS>
}
/**
* @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);
}
}