mirror of
https://github.com/Instadapp/smart-contract.git
synced 2024-07-29 22:08:07 +00:00
bridge in process
This commit is contained in:
parent
fb62a95d9b
commit
6886c863df
|
@ -0,0 +1,178 @@
|
|||
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 transfer(address, uint) external returns (bool);
|
||||
function transferFrom(address, address, uint) external returns (bool);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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(getCDAIAddress());
|
||||
CTokenInterface cDaiContract = CTokenInterface(getCDAIAddress());
|
||||
require(cDaiContract.borrow(tokenAmt) == 0, "got collateral?");
|
||||
cDaiContract.transfer(getBridgeAddress());
|
||||
}
|
||||
|
||||
}
|
|
@ -168,7 +168,7 @@ contract Helper is DSMath {
|
|||
eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* @dev get MakerDAO CDP engine
|
||||
*/
|
||||
function getSaiTubAddress() public pure returns (address sai) {
|
||||
|
|
|
@ -34,17 +34,6 @@ interface PepInterface {
|
|||
function peek() external returns (bytes32, bool);
|
||||
}
|
||||
|
||||
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 exchangeRateCurrent() external returns (uint);
|
||||
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);
|
||||
|
@ -67,6 +56,15 @@ interface UniswapExchange {
|
|||
) external returns (uint256 tokensSold);
|
||||
}
|
||||
|
||||
interface CTokenInterface {
|
||||
function redeem(uint redeemTokens) external returns (uint);
|
||||
function redeemUnderlying(uint redeemAmount) external returns (uint);
|
||||
function exchangeRateCurrent() external returns (uint);
|
||||
function transfer(address, uint) external returns (bool);
|
||||
function transferFrom(address, address, uint) external returns (bool);
|
||||
function balanceOf(address) external view returns (uint);
|
||||
}
|
||||
|
||||
interface CETHInterface {
|
||||
function mint() external payable; // For ETH
|
||||
function transfer(address, uint) external returns (bool);
|
||||
|
@ -74,6 +72,7 @@ interface CETHInterface {
|
|||
|
||||
interface CDAIInterface {
|
||||
function mint(uint mintAmount) external returns (uint); // For ERC20
|
||||
function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint);
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,7 +154,20 @@ contract MakerResolver is Helper {
|
|||
event LogWipe(uint cdpNum, uint daiAmt, uint mkrFee, uint daiFee, address owner);
|
||||
event LogShut(uint cdpNum);
|
||||
|
||||
function wipe(uint cdpNum, uint _wad) public returns (uint daiAmt) {
|
||||
function open() internal returns (uint) {
|
||||
bytes32 cup = TubInterface(sai).open();
|
||||
emit LogOpen(uint(cup), address(this));
|
||||
return uint(cup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev transfer CDP ownership
|
||||
*/
|
||||
function give(uint cdpNum, address nextOwner) internal {
|
||||
TubInterface(sai).give(bytes32(cdpNum), nextOwner);
|
||||
}
|
||||
|
||||
function wipe(uint cdpNum, uint _wad) internal returns (uint daiAmt) {
|
||||
if (_wad > 0) {
|
||||
TubInterface tub = TubInterface(sai);
|
||||
UniswapExchange daiEx = UniswapExchange(ude);
|
||||
|
@ -204,7 +216,7 @@ contract MakerResolver is Helper {
|
|||
}
|
||||
}
|
||||
|
||||
function free(uint cdpNum, uint jam) public {
|
||||
function free(uint cdpNum, uint jam) internal {
|
||||
if (jam > 0) {
|
||||
bytes32 cup = bytes32(cdpNum);
|
||||
address tubAddr = sai;
|
||||
|
@ -234,11 +246,60 @@ contract MakerResolver is Helper {
|
|||
}
|
||||
}
|
||||
|
||||
function wipeAndFree(uint cdpNum, uint jam, uint _wad) internal {
|
||||
wipe(cdpNum, _wad);
|
||||
function lock(uint cdpNum, uint ethAmt) internal {
|
||||
if (msg.value > 0) {
|
||||
bytes32 cup = bytes32(cdpNum);
|
||||
address tubAddr = sai;
|
||||
|
||||
TubInterface tub = TubInterface(tubAddr);
|
||||
ERC20Interface weth = tub.gem();
|
||||
// ERC20Interface peth = tub.skr();
|
||||
|
||||
(address lad,,,) = tub.cups(cup);
|
||||
require(lad == address(this), "cup-not-owned");
|
||||
|
||||
weth.deposit.value(ethAmt)();
|
||||
|
||||
uint ink = rdiv(ethAmt, tub.per());
|
||||
ink = rmul(ink, tub.per()) <= ethAmt ? ink : ink - 1;
|
||||
|
||||
// setAllowance(weth, tubAddr);
|
||||
tub.join(ink);
|
||||
|
||||
// setAllowance(peth, tubAddr);
|
||||
tub.lock(cup, ink);
|
||||
|
||||
emit LogLock(
|
||||
cdpNum,
|
||||
ethAmt,
|
||||
ink,
|
||||
address(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function draw(uint cdpNum, uint _wad) internal {
|
||||
bytes32 cup = bytes32(cdpNum);
|
||||
if (_wad > 0) {
|
||||
TubInterface tub = TubInterface(sai);
|
||||
|
||||
tub.draw(cup, _wad);
|
||||
// tub.sai().transfer(msg.sender, _wad);
|
||||
|
||||
emit LogDraw(cdpNum, _wad, address(this));
|
||||
}
|
||||
}
|
||||
|
||||
function wipeAndFree(uint cdpNum, uint jam, uint _wad) internal returns (uint daiAmt) {
|
||||
daiAmt = wipe(cdpNum, _wad);
|
||||
free(cdpNum, jam);
|
||||
}
|
||||
|
||||
function lockAndDraw(uint cdpNum, uint jam, uint _wad) internal {
|
||||
lock(cdpNum, jam);
|
||||
draw(cdpNum, _wad);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,40 +310,14 @@ contract CompoundResolver is MakerResolver {
|
|||
event LogBorrow(address erc20, address cErc20, uint tokenAmt, address owner);
|
||||
event LogRepay(address erc20, address cErc20, uint tokenAmt, address owner);
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH/ERC20 and mint Compound Tokens
|
||||
*/
|
||||
function mintCToken(address erc20, address cErc20, uint tokenAmt) external payable {
|
||||
enterMarket(cErc20);
|
||||
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(erc20, toDeposit, cErc20);
|
||||
assert(cToken.mint(toDeposit) == 0);
|
||||
}
|
||||
emit LogMint(
|
||||
erc20,
|
||||
cErc20,
|
||||
tokenAmt,
|
||||
msg.sender
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Deposit ETH/ERC20 and mint Compound Tokens
|
||||
*/
|
||||
function mintCETH(uint tokenAmt) internal {
|
||||
CETHInterface cToken = CETHInterface(cEth);
|
||||
cToken.mint.value(tokenAmt)();
|
||||
cToken.transfer(msg.sender, tokenAmt);
|
||||
uint cEthToReturn = wdiv(tokenAmt, CTokenInterface(cEth).exchangeRateCurrent());
|
||||
cToken.transfer(msg.sender, cEthToReturn);
|
||||
emit LogMint(
|
||||
ethAddr,
|
||||
cEth,
|
||||
|
@ -310,14 +345,57 @@ contract CompoundResolver is MakerResolver {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Redeem ETH/ERC20 and mint Compound Tokens
|
||||
* @param tokenAmt Amount of token To Redeem
|
||||
*/
|
||||
function redeemUnderlying(address cErc20, uint tokenAmt) internal {
|
||||
CTokenInterface cToken = CTokenInterface(cErc20);
|
||||
// setApproval(cErc20, 10**50, cErc20);
|
||||
uint toBurn = cToken.balanceOf(address(this));
|
||||
uint tokenToReturn = wmul(toBurn, cToken.exchangeRateCurrent());
|
||||
tokenToReturn = tokenToReturn > tokenAmt ? tokenAmt : tokenToReturn;
|
||||
require(cToken.redeemUnderlying(tokenToReturn) == 0, "something went wrong");
|
||||
}
|
||||
|
||||
function takeCETH(uint ethAmt) internal {
|
||||
CTokenInterface cToken = CTokenInterface(cEth);
|
||||
uint cTokenAmt = wdiv(ethAmt, cToken.exchangeRateCurrent());
|
||||
uint cEthBal = cToken.balanceOf(msg.sender);
|
||||
cTokenAmt = cEthBal > cTokenAmt ? cTokenAmt : cTokenAmt - 1;
|
||||
require(ERC20Interface(cEth).transferFrom(msg.sender, address(this), cTokenAmt), "Contract Approved?");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
contract Bridge is CompoundResolver {
|
||||
|
||||
function payUsersDebt(uint daiDebt) internal {
|
||||
redeemUnderlying(cDai, daiDebt);
|
||||
// setApproval(dai, daiDebt, cDai);
|
||||
require(CDAIInterface(cDai).repayBorrowBehalf(msg.sender, daiDebt) == 0, "Enough DAI?");
|
||||
}
|
||||
|
||||
function takeDebtBack(uint daiDebt) external {
|
||||
require(ERC20Interface(daiAddr).transferFrom(msg.sender, address(this),daiDebt), "Contract Approved?");
|
||||
mintCDAI(daiDebt);
|
||||
}
|
||||
|
||||
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) {
|
||||
daiAmt = wipeAndFree(cdpId, ethCol, daiDebt);
|
||||
mintCETH(ethCol);
|
||||
give(cdpId, msg.sender);
|
||||
}
|
||||
|
||||
function compoundToMaker(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) {
|
||||
payUsersDebt(daiDebt);
|
||||
takeCETH(ethCol);
|
||||
redeemUnderlying(cEth, ethCol);
|
||||
uint cdpNum = cdpId > 0 ? cdpId : open();
|
||||
lockAndDraw(cdpNum, ethCol, daiDebt);
|
||||
mintCDAI(daiDebt);
|
||||
give(cdpNum, msg.sender);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user