diff --git a/contracts/protocols/MoatKyber.sol b/contracts/protocols/MoatKyber.sol index 1708af3..5daf4a7 100644 --- a/contracts/protocols/MoatKyber.sol +++ b/contracts/protocols/MoatKyber.sol @@ -3,9 +3,8 @@ pragma solidity ^0.4.24; interface token { - function approve(address spender, uint256 value) external returns (bool); function transfer(address receiver, uint amount) external returns (bool); - function balanceOf(address who) external returns(uint256); + function approve(address spender, uint256 value) external returns (bool); function transferFrom(address from, address to, uint amount) external returns (bool); } @@ -80,10 +79,9 @@ contract Trade is Registry { address affiliate ); - address eth = 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee; - - // ropsten network - address kyberAddr = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755; + // ropsten network + address public kyberAddr = 0x818E6FECD516Ecc3849DAf6845e3EC868087B755; + address public eth = 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee; function executeTrade( address trader, @@ -160,7 +158,7 @@ contract MoatKyber is Trade { function () public payable {} - function collectFees(address tokenAddress, uint amount) public onlyAdmin { + function collectAssets(address tokenAddress, uint amount) public onlyAdmin { if (tokenAddress == eth) { msg.sender.transfer(amount); } else { diff --git a/contracts/protocols/MoatMaker.sol b/contracts/protocols/MoatMaker.sol index 2058bb3..8944dc5 100644 --- a/contracts/protocols/MoatMaker.sol +++ b/contracts/protocols/MoatMaker.sol @@ -1,13 +1,14 @@ -// get back the ownership of CDP // mechanism to transfer an existing CDP (2 txn process) -// factor the WETH to PETH conversion rate - https://chat.makerdao.com/direct/Sean -// implement repay loan function +// MKR fee when wiped DAI - buy MRK from OasisDEX onchain maybe +// global variable to freeze operations like stop locking & drawing +// (Think again) store MKR tokens on contract by yourself and charge user 1% instead for now pragma solidity 0.4.24; interface token { - function transfer(address receiver, uint amount) external returns(bool); + function transfer(address receiver, uint amount) external returns (bool); function approve(address spender, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint amount) external returns (bool); } interface AddressRegistry { @@ -28,8 +29,6 @@ interface MakerCDP { function free(bytes32 cup, uint wad) external; function draw(bytes32 cup, uint wad) external; function wipe(bytes32 cup, uint wad) external; - function shut(bytes32 cup) external; - function bite(bytes32 cup) external; function per() external returns (uint ray); } @@ -82,88 +81,58 @@ contract GlobalVar is Registry { address public peth = 0xf4d791139cE033Ad35DB2B2201435fAd668B1b64; address public mkr = 0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD; address public dai = 0xC4375B7De8af5a38a93548eb8453a498222C4fF2; + address public eth = 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee; address public cdpAddr = 0xa71937147b55Deb8a530C7229C442Fd3F31b7db2; MakerCDP loanMaster = MakerCDP(cdpAddr); - mapping (address => bytes32) public borrowerCDPs; // borrower >>> CDP Bytes + mapping (address => bytes32) public CDPs; // borrower >>> CDP Bytes } -contract BorrowTasks is GlobalVar { - - function openCDP() internal returns (bytes32) { - return loanMaster.open(); - } - - function convertToWETH(uint weiAmt) internal { - WETHFace wethFunction = WETHFace(weth); - wethFunction.deposit.value(weiAmt)(); - } - - function convertToPETH(uint weiAmt) internal { - loanMaster.join(weiAmt); - } - - function lockPETH(address borrower, uint weiAmt) internal { - loanMaster.lock(borrowerCDPs[borrower], weiAmt); - } - - function transferCDP(address nextOwner) public { - require(nextOwner != 0, "Invalid Address."); - loanMaster.give(borrowerCDPs[msg.sender], nextOwner); - } - - function approveERC20() public { - token wethTkn = token(weth); - wethTkn.approve(cdpAddr, 2**256 - 1); - token pethTkn = token(peth); - pethTkn.approve(cdpAddr, 2**256 - 1); - token mkrTkn = token(mkr); - mkrTkn.approve(cdpAddr, 2**256 - 1); - token daiTkn = token(dai); - daiTkn.approve(cdpAddr, 2**256 - 1); - } - -} - - -contract Borrow is BorrowTasks { +contract IssueLoan is GlobalVar { event LockedETH(address borrower, uint lockETH, uint lockPETH); event LoanedDAI(address borrower, uint loanDAI, uint fees); + event OpenedNewCDP(address borrower, bytes32 CDPBytes); - function getLoan( + function borrow( address borrower, - uint lockETH, - uint loanDAI - ) public payable onlyUserOrResolver(borrower) returns (uint daiMinted) - { - if (borrowerCDPs[borrower] == 0x0000000000000000000000000000000000000000000000000000000000000000) { - borrowerCDPs[borrower] = openCDP(); + uint ethLock, + uint daiDraw + ) public payable onlyUserOrResolver(borrower) { + if (CDPs[borrower] == 0x0000000000000000000000000000000000000000000000000000000000000000) { + CDPs[borrower] = loanMaster.open(); + emit OpenedNewCDP(borrower, CDPs[borrower]); } - - if (lockETH != 0) { - convertToWETH(lockETH); - convertToPETH(lockETH - ratioedETH(lockETH)); - lockPETH(borrower, lockETH - ratioedETH(lockETH)); - emit LockedETH(borrower, lockETH, ratioedETH(lockETH)); + if (ethLock > 0) { + lockETH(borrower, ethLock); } - - if (loanDAI != 0) { - loanMaster.draw(borrowerCDPs[borrower], loanDAI); - uint fees = deductFees(loanDAI); - token tokenFunctions = token(dai); - tokenFunctions.transfer(getAddress("resolver"), loanDAI - fees); - daiMinted = loanDAI; - emit LoanedDAI(borrower, loanDAI, fees); + if (daiDraw > 0) { + drawDAI(borrower, daiDraw); } - } - function ratioedETH(uint eth) internal returns (uint rETH) { - rETH = (eth * loanMaster.per()) / 10 ** 27; + function lockETH(address borrower, uint ethLock) public payable { + WETHFace wethFunction = WETHFace(weth); + wethFunction.deposit.value(ethLock)(); // ETH to WETH + uint pethToLock = ratioedPETH(ethLock); + loanMaster.join(pethToLock); // WETH to PETH + loanMaster.lock(CDPs[borrower], pethToLock); // PETH to CDP + emit LockedETH(borrower, ethLock, pethToLock); + } + + function drawDAI(address borrower, uint daiDraw) public onlyUserOrResolver(borrower) { + loanMaster.draw(CDPs[borrower], daiDraw); + uint fees = deductFees(daiDraw); + token tokenFunctions = token(dai); + tokenFunctions.transfer(getAddress("resolver"), daiDraw - fees); + emit LoanedDAI(borrower, daiDraw, fees); + } + + function ratioedPETH(uint eth) internal returns (uint rPETH) { + rPETH = eth * (10 ** 27) / loanMaster.per(); } function deductFees(uint volume) internal returns(uint fees) { @@ -179,12 +148,84 @@ contract Borrow is BorrowTasks { } -contract MoatMaker is Borrow { +contract RepayLoan is IssueLoan { - constructor() public { + event WipedDAI(address borrower, uint daiWipe); + event UnlockedETH(address borrower, uint ethFree); + + function repay( + address borrower, + uint daiWipe, + uint ethFree + ) public onlyUserOrResolver(borrower) { + if (daiWipe > 0) { + wipeDAI(borrower, daiWipe); + } + if (ethFree > 0) { + UnlockETH(borrower, ethFree); + } + } + + function wipeDAI(address borrower, uint daiWipe) public { + token tokenFunction = token(dai); + tokenFunction.transferFrom(msg.sender, address(this), daiWipe); + loanMaster.wipe(CDPs[borrower], daiWipe); + emit WipedDAI(borrower, daiWipe); + } + + function UnlockETH(address borrower, uint ethFree) public onlyUserOrResolver(borrower) { + uint pethToUnlock = ratioedPETH(ethFree); + loanMaster.free(CDPs[borrower], pethToUnlock); // CDP to PETH + loanMaster.exit(pethToUnlock); // PETH to WETH + WETHFace wethFunction = WETHFace(weth); + wethFunction.withdraw(ethFree); // WETH to ETH + msg.sender.transfer(ethFree); + emit UnlockedETH(borrower, ethFree); + } + + // function freeETH + // free(bytes32 cup, uint wad) + +} + +contract BorrowTasks is RepayLoan { + + // transfer existing CDP 2 txn process + + function claimCDP(address nextOwner) public { + require(nextOwner != 0, "Invalid Address."); + loanMaster.give(CDPs[msg.sender], nextOwner); + } + + function approveERC20() public { + token wethTkn = token(weth); + wethTkn.approve(cdpAddr, 2**256 - 1); + token pethTkn = token(peth); + pethTkn.approve(cdpAddr, 2**256 - 1); + token mkrTkn = token(mkr); + mkrTkn.approve(cdpAddr, 2**256 - 1); + token daiTkn = token(dai); + daiTkn.approve(cdpAddr, 2**256 - 1); + } +} + + +contract MoatMaker is BorrowTasks { + + constructor(address rAddr) public { + registryAddress = rAddr; approveERC20(); } function () public payable {} + function collectAssets(address tokenAddress, uint amount) public onlyAdmin { + if (tokenAddress == eth) { + msg.sender.transfer(amount); + } else { + token tokenFunctions = token(tokenAddress); + tokenFunctions.transfer(msg.sender, amount); + } + } + } \ No newline at end of file