dsa-resolvers-deprecated/contracts/protocols/mainnet/reflexer.sol
2021-04-13 10:27:09 +05:30

272 lines
9.3 KiB
Solidity

/**
*Submitted for verification at Etherscan.io on 2020-07-29
*/
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
interface ManagerLike {
function collateralTypes(uint) external view returns (bytes32);
function ownsSAFE(uint) external view returns (address);
function safes(uint) external view returns (address);
function safeEngine() external view returns (address);
}
interface GetSafesLike {
function getSafesAsc(address, address) external view returns (uint[] memory, address[] memory, bytes32[] memory);
}
interface SAFEEngineLike {
function collateralTypes(bytes32) external view returns (uint, uint, uint, uint, uint);
function coinBalance(address) external view returns (uint);
function safes(bytes32, address) external view returns (uint, uint);
function tokenCollateral(bytes32, address) external view returns (uint);
}
interface TaxCollectorLike {
function collateralTypes(bytes32) external view returns (uint, uint);
function globalStabilityFee() external view returns (uint);
}
interface OracleRelayerLike {
function collateralTypes(bytes32) external view returns (OracleLike, uint, uint);
function redemptionRate() external view returns (uint);
}
interface OracleLike {
function getResultWithValidity() external view returns (bytes32, bool);
}
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 {
struct SafeData {
uint id;
address owner;
string colType;
uint collateral;
uint debt;
uint adjustedDebt;
uint liquidatedCol;
uint borrowRate;
uint colPrice;
uint liquidationRatio;
address safeAddress;
}
struct ColInfo {
uint borrowRate;
uint price;
uint liquidationRatio;
uint debtCeiling;
uint debtFloor;
uint totalDebt;
}
struct ReflexerAddresses {
address manager;
address safeEngine;
address taxCollector;
address oracleRelayer;
address getSafes;
}
/**
* @dev get Reflexer Address contract
*/
function getReflexerAddresses() public pure returns (ReflexerAddresses memory) {
return ReflexerAddresses(
0xEfe0B4cA532769a3AE758fD82E1426a03A94F185, // manager
0xCC88a9d330da1133Df3A7bD823B95e52511A6962, // safeEngine
0xcDB05aEda142a1B0D6044C09C64e4226c1a281EB, // taxCollector
0x4ed9C0dCa0479bC64d8f4EB3007126D5791f7851, // oracleRelayer
0xdf4BC9aA98cC8eCd90Ba2BEe73aD4a1a9C8d202B // getSafes
);
}
/**
* @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 collateralType) internal view returns (uint fee) {
address taxCollector = getReflexerAddresses().taxCollector;
(uint stabilityFee,) = TaxCollectorLike(taxCollector).collateralTypes(collateralType);
uint globalStabilityFee = TaxCollectorLike(taxCollector).globalStabilityFee();
fee = add(stabilityFee, globalStabilityFee);
}
function getColPrice(bytes32 collateralType) internal view returns (uint price) {
address oracleRelayer = getReflexerAddresses().oracleRelayer;
address safeEngine = getReflexerAddresses().safeEngine;
(, uint safetyCRatio,) = OracleRelayerLike(oracleRelayer).collateralTypes(collateralType);
(,,uint spotPrice,,) = SAFEEngineLike(safeEngine).collateralTypes(collateralType);
price = rmul(safetyCRatio, spotPrice);
}
function getColRatio(bytes32 collateralType) internal view returns (uint ratio) {
address oracleRelayer = getReflexerAddresses().oracleRelayer;
(, ratio,) = OracleRelayerLike(oracleRelayer).collateralTypes(collateralType);
}
function getDebtState(bytes32 collateralType) internal view returns (uint debtCeiling, uint debtFloor, uint totalDebt) {
address safeEngine = getReflexerAddresses().safeEngine;
(uint globalDebt,uint rate,,uint debtCeilingRad, uint debtFloorRad) = SAFEEngineLike(safeEngine).collateralTypes(collateralType);
debtCeiling = debtCeilingRad / 10 ** 45;
debtFloor = debtFloorRad / 10 ** 45;
totalDebt = rmul(globalDebt, rate);
}
}
contract SafeResolver is Helpers {
function getSafes(address owner) external view returns (SafeData[] memory) {
address manager = getReflexerAddresses().manager;
address safeManger = getReflexerAddresses().getSafes;
(uint[] memory ids, address[] memory handlers, bytes32[] memory collateralTypes) = GetSafesLike(safeManger).getSafesAsc(manager, owner);
SafeData[] memory safes = new SafeData[](ids.length);
for (uint i = 0; i < ids.length; i++) {
(uint collateral, uint debt) = SAFEEngineLike(ManagerLike(manager).safeEngine()).safes(collateralTypes[i], handlers[i]);
(,uint rate, uint priceMargin,,) = SAFEEngineLike(ManagerLike(manager).safeEngine()).collateralTypes(collateralTypes[i]);
uint safetyCRatio = getColRatio(collateralTypes[i]);
safes[i] = SafeData(
ids[i],
owner,
bytes32ToString(collateralTypes[i]),
collateral,
debt,
rmul(debt,rate),
SAFEEngineLike(ManagerLike(manager).safeEngine()).tokenCollateral(collateralTypes[i], handlers[i]),
getFee(collateralTypes[i]),
rmul(priceMargin, safetyCRatio),
safetyCRatio,
handlers[i]
);
}
return safes;
}
function getSafeById(uint id) external view returns (SafeData memory) {
address manager = getReflexerAddresses().manager;
address handler = ManagerLike(manager).safes(id);
bytes32 collateralType = ManagerLike(manager).collateralTypes(id);
(uint collateral, uint debt) = SAFEEngineLike(ManagerLike(manager).safeEngine()).safes(collateralType, handler);
(,uint rate, uint priceMargin,,) = SAFEEngineLike(ManagerLike(manager).safeEngine()).collateralTypes(collateralType);
uint safetyCRatio = getColRatio(collateralType);
uint feeRate = getFee(collateralType);
SafeData memory safe = SafeData(
id,
ManagerLike(manager).ownsSAFE(id),
bytes32ToString(collateralType),
collateral,
debt,
rmul(debt,rate),
SAFEEngineLike(ManagerLike(manager).safeEngine()).tokenCollateral(collateralType, handler),
feeRate,
rmul(priceMargin, safetyCRatio),
safetyCRatio,
handler
);
return safe;
}
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 collateralType = stringToBytes32(name[i]);
(uint debtCeiling, uint debtFloor, uint totalDebt) = getDebtState(collateralType);
colInfo[i] = ColInfo(
getFee(collateralType),
getColPrice(collateralType),
getColRatio(collateralType),
debtCeiling,
debtFloor,
totalDebt
);
}
return colInfo;
}
}
contract RedemptionRateResolver is SafeResolver {
function getRedemptionRate() external view returns (uint redemptionRate) {
address oracleRelayer = getReflexerAddresses().oracleRelayer;
redemptionRate = OracleRelayerLike(oracleRelayer).redemptionRate();
}
}
contract InstaReflexerResolver is RedemptionRateResolver {
string public constant name = "Reflexer-Resolver-v1";
}