From 95aaf9f0bae0d27d721e22cc7a65acc000047415 Mon Sep 17 00:00:00 2001 From: Guillaume Felley Date: Fri, 26 Mar 2021 14:11:06 +0100 Subject: [PATCH] Start with Maker resolver --- contracts/protocols/reflexer.sol | 276 +++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 contracts/protocols/reflexer.sol diff --git a/contracts/protocols/reflexer.sol b/contracts/protocols/reflexer.sol new file mode 100644 index 0000000..3dcddce --- /dev/null +++ b/contracts/protocols/reflexer.sol @@ -0,0 +1,276 @@ +/** + *Submitted for verification at Etherscan.io on 2020-07-29 +*/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +interface ManagerLike { + 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); +} + +interface CdpsLike { + function getCdpsAsc(address, address) external view returns (uint[] memory, address[] memory, bytes32[] memory); +} + +interface VatLike { + 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 gem(bytes32, address) external view returns (uint); +} + +interface JugLike { + function ilks(bytes32) external view returns (uint, uint); + function base() external view returns (uint); +} + +interface PotLike { + function dsr() external view returns (uint); + function pie(address) external view returns (uint); + function chi() external view returns (uint); +} + +interface SpotLike { + function ilks(bytes32) external view returns (PipLike, uint); +} + +interface PipLike { + function peek() external view returns (bytes32, bool); +} + +interface InstaMcdAddress { + function manager() external view returns (address); + function vat() external view returns (address); + function jug() external view returns (address); + function spot() external view returns (address); + function pot() external view returns (address); + function getCdps() external view returns (address); +} + + +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; + } + +} + + +contract Helpers is DSMath { + /** + * @dev get MakerDAO MCD Address contract + */ + function getMcdAddresses() public pure returns (address) { + return 0xF23196DF1C440345DE07feFbe556a5eF0dcD29F0; + } + + struct VaultData { + uint id; + address owner; + string colType; + uint collateral; + uint art; + uint debt; + uint liquidatedCol; + uint borrowRate; + uint colPrice; + uint liquidationRatio; + address vaultAddress; + } + + struct ColInfo { + uint borrowRate; + uint price; + uint liquidationRatio; + uint debtCelling; + uint totalDebt; + } + + /** + * @dev Convert String to bytes32. + */ + function stringToBytes32(string memory str) internal pure returns (bytes32 result) { + require(bytes(str).length != 0, "String-Empty"); + // solium-disable-next-line security/no-inline-assembly + assembly { + result := mload(add(str, 32)) + } + } + + /** + * @dev Convert bytes32 to String. + */ + function bytes32ToString(bytes32 _bytes32) internal pure returns (string memory) { + bytes32 _temp; + uint count; + for (uint256 i; i < 32; i++) { + _temp = _bytes32[i]; + if( _temp != bytes32(0)) { + count += 1; + } + } + bytes memory bytesArray = new bytes(count); + for (uint256 i; i < count; i++) { + bytesArray[i] = (_bytes32[i]); + } + return (string(bytesArray)); + } + + + function getFee(bytes32 ilk) internal view returns (uint fee) { + address jug = InstaMcdAddress(getMcdAddresses()).jug(); + (uint duty,) = JugLike(jug).ilks(ilk); + uint base = JugLike(jug).base(); + fee = add(duty, base); + } + + function getColPrice(bytes32 ilk) internal view returns (uint price) { + address spot = InstaMcdAddress(getMcdAddresses()).spot(); + address vat = InstaMcdAddress(getMcdAddresses()).vat(); + (, uint mat) = SpotLike(spot).ilks(ilk); + (,,uint spotPrice,,) = VatLike(vat).ilks(ilk); + price = rmul(mat, spotPrice); + } + + function getColRatio(bytes32 ilk) internal view returns (uint ratio) { + address spot = InstaMcdAddress(getMcdAddresses()).spot(); + (, ratio) = SpotLike(spot).ilks(ilk); + } + + function getDebtCeiling(bytes32 ilk) internal view returns (uint debtCeiling, uint totalDebt) { + address vat = InstaMcdAddress(getMcdAddresses()).vat(); + (uint totalArt,uint rate,,uint debtCeilingRad,) = VatLike(vat).ilks(ilk); + debtCeiling = debtCeilingRad / 10 ** 45; + totalDebt = rmul(totalArt, rate); + } +} + + +contract VaultResolver is Helpers { + function getVaults(address owner) external view returns (VaultData[] memory) { + address manager = InstaMcdAddress(getMcdAddresses()).manager(); + address cdpManger = InstaMcdAddress(getMcdAddresses()).getCdps(); + + (uint[] memory ids, address[] memory urns, bytes32[] memory ilks) = CdpsLike(cdpManger).getCdpsAsc(manager, owner); + VaultData[] memory vaults = new VaultData[](ids.length); + + for (uint i = 0; i < ids.length; i++) { + (uint ink, uint art) = VatLike(ManagerLike(manager).vat()).urns(ilks[i], urns[i]); + (,uint rate, uint priceMargin,,) = VatLike(ManagerLike(manager).vat()).ilks(ilks[i]); + uint mat = getColRatio(ilks[i]); + + vaults[i] = VaultData( + ids[i], + owner, + bytes32ToString(ilks[i]), + ink, + art, + rmul(art,rate), + VatLike(ManagerLike(manager).vat()).gem(ilks[i], urns[i]), + getFee(ilks[i]), + rmul(priceMargin, mat), + mat, + urns[i] + ); + } + return vaults; + } + + function getVaultById(uint id) external view returns (VaultData memory) { + address manager = InstaMcdAddress(getMcdAddresses()).manager(); + address urn = ManagerLike(manager).urns(id); + bytes32 ilk = ManagerLike(manager).ilks(id); + + (uint ink, uint art) = VatLike(ManagerLike(manager).vat()).urns(ilk, urn); + (,uint rate, uint priceMargin,,) = VatLike(ManagerLike(manager).vat()).ilks(ilk); + + uint mat = getColRatio(ilk); + + uint feeRate = getFee(ilk); + VaultData memory vault = VaultData( + id, + ManagerLike(manager).owns(id), + bytes32ToString(ilk), + ink, + art, + rmul(art,rate), + VatLike(ManagerLike(manager).vat()).gem(ilk, urn), + feeRate, + rmul(priceMargin, mat), + mat, + urn + ); + return vault; + } + + function getColInfo(string[] memory name) public view returns (ColInfo[] memory) { + ColInfo[] memory colInfo = new ColInfo[](name.length); + + for (uint i = 0; i < name.length; i++) { + bytes32 ilk = stringToBytes32(name[i]); + (uint debtCeiling, uint totalDebt) = getDebtCeiling(ilk); + colInfo[i] = ColInfo( + getFee(ilk), + getColPrice(ilk), + getColRatio(ilk), + debtCeiling, + totalDebt + ); + } + return colInfo; + } + +} + + +contract DSRResolver is VaultResolver { + function getDsrRate() public view returns (uint dsr) { + address pot = InstaMcdAddress(getMcdAddresses()).pot(); + dsr = PotLike(pot).dsr(); + } + + function getDaiPosition(address owner) external view returns (uint amt, uint dsr) { + address pot = InstaMcdAddress(getMcdAddresses()).pot(); + uint chi = PotLike(pot).chi(); + uint pie = PotLike(pot).pie(owner); + amt = rmul(pie,chi); + dsr = getDsrRate(); + } +} + + +contract InstaMakerResolver is DSRResolver { + string public constant name = "Maker-Resolver-v1.2"; +} \ No newline at end of file