dsa-resolvers-deprecated/contracts/protocols/mainnet/reflexer.sol

272 lines
9.3 KiB
Solidity
Raw Permalink Normal View History

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