From ed07214768712fca8bce4df4c50aeed37a0d70bb Mon Sep 17 00:00:00 2001 From: Thrilok kumar Date: Tue, 22 Oct 2019 05:46:58 +0530 Subject: [PATCH] basic MCD functions except wipe --- contracts/ProxyLogics/MCD/InstaMCD.sol | 333 +++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 contracts/ProxyLogics/MCD/InstaMCD.sol diff --git a/contracts/ProxyLogics/MCD/InstaMCD.sol b/contracts/ProxyLogics/MCD/InstaMCD.sol new file mode 100644 index 0000000..f5d4bd0 --- /dev/null +++ b/contracts/ProxyLogics/MCD/InstaMCD.sol @@ -0,0 +1,333 @@ +pragma solidity ^0.5.8; + +interface GemLike { + function approve(address, uint) external; + function transfer(address, uint) external; + function transferFrom(address, address, uint) external; + function deposit() external payable; + function withdraw(uint) external; +} + +interface JugLike { + function drip(bytes32) external; +} + +interface ManagerLike { + function cdpCan(address, uint, address) external view returns (uint); + function ilks(uint) external view returns (bytes32); + function owns(uint) external view returns (address); + function urns(uint) external view returns (address); + function vat() external view returns (address); + function open(bytes32) external returns (uint); + function give(uint, address) external; + function cdpAllow(uint, address, uint) external; + function urnAllow(address, uint) external; + function frob(uint, int, int) external; + function frob( + uint, + address, + int, + int + ) external; + function flux(uint, address, uint) external; + function move(uint, address, uint) external; + function exit( + address, + uint, + address, + uint + ) external; + function quit(uint, address) external; + function enter(address, uint) external; + function shift(uint, uint) external; +} + +interface VatLike { + function can(address, address) external view returns (uint); + function ilks(bytes32) external view returns (uint, uint, uint, uint, uint); + function dai(address) external view returns (uint); + function urns(bytes32, address) external view returns (uint, uint); + function frob( + bytes32, + address, + address, + address, + int, + int + ) external; + function hope(address) external; + function move(address, address, uint) external; +} + +interface GemJoinLike { + function dec() external returns (uint); + function gem() external returns (GemLike); + function join(address, uint) external payable; + function exit(address, uint) external; +} + +interface GNTJoinLike { + function bags(address) external view returns (address); + function make(address) external returns (address); +} + +interface DaiJoinLike { + function vat() external returns (VatLike); + function dai() external returns (GemLike); + function join(address, uint) external payable; + function exit(address, uint) external; +} + +interface TokenInterface { + 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; +} + + + +contract DSMath { + + function add(uint x, uint y) internal pure returns (uint z) { + require((z = x + y) >= x, "math-not-safe"); + } + + function sub(uint x, uint y) internal pure returns (uint z) { + z = x - y <= x ? x - y : 0; + } + + 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 wmul(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, y), WAD / 2) / WAD; + } + + function rdiv(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, RAY), y / 2) / y; + } + + function wdiv(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, WAD), y / 2) / y; + } + + function toInt(uint x) internal pure returns (int y) { + y = int(x); + require(y >= 0, "int-overflow"); + } + + function toRad(uint wad) internal pure returns (uint rad) { + rad = mul(wad, 10 ** 27); + } + +} + + +contract Helpers is DSMath { + + /** + * @dev get MakerDAO CDP engine + */ + function getSaiTubAddress() public pure returns (address sai) { + sai = 0x448a5065aeBB8E423F0896E6c5D525C040f59af3; + } + + /** + * @dev get uniswap MKR exchange + */ + function getUniswapMKRExchange() public pure returns (address ume) { + ume = 0x2C4Bd064b998838076fa341A83d007FC2FA50957; + } + + /** + * @dev get uniswap DAI exchange + */ + function getUniswapDAIExchange() public pure returns (address ude) { + ude = 0x09cabEC1eAd1c0Ba254B09efb3EE13841712bE14; + } + + /** + * @dev get CDP bytes by CDP ID + */ + function getCDPBytes(uint cdpNum) public pure returns (bytes32 cup) { + cup = bytes32(cdpNum); + } + +} + + +contract CDPResolver is Helpers { + + + + function open(address manager) public returns (uint cdp) { + bytes32 ilk = 0x4554482d41000000000000000000000000000000000000000000000000000000; + cdp = ManagerLike(manager).open(ilk); + } + + function lockETH( + address manager, + address ethJoin, + uint cdp + ) public payable + { + // Receives ETH amount, converts it to WETH and joins it into the vat + GemJoinLike(ethJoin).gem().deposit.value(msg.value)(); + // Approves adapter to take the WETH amount + GemJoinLike(ethJoin).gem().approve(address(ethJoin), msg.value); + // Joins WETH collateral into the vat + GemJoinLike(ethJoin).join(address(this), msg.value); + // Locks WETH amount into the CDP + VatLike(ManagerLike(manager).vat()).frob( + ManagerLike(manager).ilks(cdp), + ManagerLike(manager).urns(cdp), + address(this), + address(this), + int(msg.value), + 0 + ); + } + + function freeETH( + address manager, + address ethJoin, + uint cdp, + uint wad + ) public + { + // Unlocks WETH amount from the CDP + ManagerLike(manager).frob( + cdp, + address(this), + -int(wad), + 0 + ); + // Exits WETH amount to proxy address as a token + GemJoinLike(ethJoin).exit(address(this), wad); + // Converts WETH to ETH + GemJoinLike(ethJoin).gem().withdraw(wad); + // Sends ETH back to the user's wallet + msg.sender.transfer(wad); + } + + function draw( + address manager, + address jug, + address daiJoin, + uint cdp, + uint wad + ) public + { + address urn = ManagerLike(manager).urns(cdp); + address vat = ManagerLike(manager).vat(); + bytes32 ilk = ManagerLike(manager).ilks(cdp); + // Updates stability fee rate before generating new debt + JugLike(jug).drip(ilk); + // Generates debt in the CDP + int dart; + // Gets actual rate from the vat + (, uint rate,,,) = VatLike(vat).ilks(ilk); + // Gets DAI balance of the urn in the vat + uint dai = VatLike(vat).dai(urn); + + // If there was already enough DAI in the vat balance, just exits it without adding more debt + if (dai < mul(wad, RAY)) { + // Calculates the needed dart so together with the existing dai in the vat is enough to exit wad amount of DAI tokens + dart = int(sub(mul(wad, RAY), dai) / rate); + // This is neeeded due lack of precision. It might need to sum an extra dart wei (for the given DAI wad amount) + dart = mul(uint(dart), rate) < mul(wad, RAY) ? dart + 1 : dart; + } + + + + ManagerLike(manager).frob(cdp, 0, dart); + // Moves the DAI amount (balance in the vat in rad) to proxy's address + ManagerLike(manager).move(cdp, address(this), toRad(wad)); + // Allows adapter to access to proxy's DAI balance in the vat + if (VatLike(vat).can(address(this), address(daiJoin)) == 0) { + VatLike(vat).hope(daiJoin); + } + // Exits DAI to the user's wallet as a token + DaiJoinLike(daiJoin).exit(msg.sender, wad); + } + + function wipe ( + address manager, + address daiJoin, + uint cdp, + uint wad + ) public + { + address vat = ManagerLike(manager).vat(); + address urn = ManagerLike(manager).urns(cdp); + bytes32 ilk = ManagerLike(manager).ilks(cdp); + + address own = ManagerLike(manager).owns(cdp); + DaiJoinLike(daiJoin).dai().transferFrom(msg.sender, address(this), wad); + // Approves adapter to take the DAI amount + DaiJoinLike(daiJoin).dai().approve(daiJoin, wad); + if (own == address(this) || ManagerLike(manager).cdpCan(own, cdp, address(this)) == 1) { + // Joins DAI amount into the vat + DaiJoinLike(daiJoin).join(urn, wad); + // Paybacks debt to the CDP + ManagerLike(manager).frob(cdp, 0, _getWipeDart( + vat, + VatLike(vat).dai(urn), + urn, + ilk)); + } else { + // Joins DAI amount into the vat + DaiJoinLike(daiJoin).join(address(this), wad); + // Paybacks debt to the CDP + VatLike(vat).frob( + ilk, + urn, + address(this), + address(this), + 0, + _getWipeDart( + vat, + wad * RAY, + urn, + ilk) + ); + } + } + + function _getWipeDart( + address vat, + uint dai, + address urn, + bytes32 ilk + ) internal view returns (int dart) + { + // Gets actual rate from the vat + (, uint rate,,,) = VatLike(vat).ilks(ilk); + // Gets actual art value of the urn + (, uint art) = VatLike(vat).urns(ilk, urn); + + // Uses the whole dai balance in the vat to reduce the debt + dart = toInt(dai / rate); + // Checks the calculated dart is not higher than urn.art (total debt), otherwise uses its value + dart = uint(dart) <= art ? - dart : - toInt(art); + } +} + + +contract InstaMaker is CDPResolver { + + function() external payable {} + +} \ No newline at end of file