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;
|
eth = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev get MakerDAO CDP engine
|
* @dev get MakerDAO CDP engine
|
||||||
*/
|
*/
|
||||||
function getSaiTubAddress() public pure returns (address sai) {
|
function getSaiTubAddress() public pure returns (address sai) {
|
||||||
|
|
|
@ -34,17 +34,6 @@ interface PepInterface {
|
||||||
function peek() external returns (bytes32, bool);
|
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 {
|
interface ERC20Interface {
|
||||||
function allowance(address, address) external view returns (uint);
|
function allowance(address, address) external view returns (uint);
|
||||||
function balanceOf(address) external view returns (uint);
|
function balanceOf(address) external view returns (uint);
|
||||||
|
@ -67,6 +56,15 @@ interface UniswapExchange {
|
||||||
) external returns (uint256 tokensSold);
|
) 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 {
|
interface CETHInterface {
|
||||||
function mint() external payable; // For ETH
|
function mint() external payable; // For ETH
|
||||||
function transfer(address, uint) external returns (bool);
|
function transfer(address, uint) external returns (bool);
|
||||||
|
@ -74,6 +72,7 @@ interface CETHInterface {
|
||||||
|
|
||||||
interface CDAIInterface {
|
interface CDAIInterface {
|
||||||
function mint(uint mintAmount) external returns (uint); // For ERC20
|
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 LogWipe(uint cdpNum, uint daiAmt, uint mkrFee, uint daiFee, address owner);
|
||||||
event LogShut(uint cdpNum);
|
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) {
|
if (_wad > 0) {
|
||||||
TubInterface tub = TubInterface(sai);
|
TubInterface tub = TubInterface(sai);
|
||||||
UniswapExchange daiEx = UniswapExchange(ude);
|
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) {
|
if (jam > 0) {
|
||||||
bytes32 cup = bytes32(cdpNum);
|
bytes32 cup = bytes32(cdpNum);
|
||||||
address tubAddr = sai;
|
address tubAddr = sai;
|
||||||
|
@ -234,11 +246,60 @@ contract MakerResolver is Helper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wipeAndFree(uint cdpNum, uint jam, uint _wad) internal {
|
function lock(uint cdpNum, uint ethAmt) internal {
|
||||||
wipe(cdpNum, _wad);
|
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);
|
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 LogBorrow(address erc20, address cErc20, uint tokenAmt, address owner);
|
||||||
event LogRepay(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
|
* @dev Deposit ETH/ERC20 and mint Compound Tokens
|
||||||
*/
|
*/
|
||||||
function mintCETH(uint tokenAmt) internal {
|
function mintCETH(uint tokenAmt) internal {
|
||||||
CETHInterface cToken = CETHInterface(cEth);
|
CETHInterface cToken = CETHInterface(cEth);
|
||||||
cToken.mint.value(tokenAmt)();
|
cToken.mint.value(tokenAmt)();
|
||||||
cToken.transfer(msg.sender, tokenAmt);
|
uint cEthToReturn = wdiv(tokenAmt, CTokenInterface(cEth).exchangeRateCurrent());
|
||||||
|
cToken.transfer(msg.sender, cEthToReturn);
|
||||||
emit LogMint(
|
emit LogMint(
|
||||||
ethAddr,
|
ethAddr,
|
||||||
cEth,
|
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 {
|
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) {
|
function makerToCompound(uint cdpId, uint ethCol, uint daiDebt) public payable isUserWallet returns (uint daiAmt) {
|
||||||
daiAmt = wipeAndFree(cdpId, ethCol, daiDebt);
|
daiAmt = wipeAndFree(cdpId, ethCol, daiDebt);
|
||||||
mintCETH(ethCol);
|
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