-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d95b07d
commit 912f08d
Showing
2 changed files
with
177 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
|
||
contract ComptrollerErrorReporter { | ||
enum Error { | ||
NO_ERROR, | ||
UNAUTHORIZED, | ||
COMPTROLLER_MISMATCH, | ||
INSUFFICIENT_SHORTFALL, | ||
INSUFFICIENT_LIQUIDITY, | ||
INVALID_CLOSE_FACTOR, | ||
INVALID_COLLATERAL_FACTOR, | ||
INVALID_LIQUIDATION_INCENTIVE, | ||
MARKET_NOT_ENTERED, // no longer possible | ||
MARKET_NOT_LISTED, | ||
MARKET_ALREADY_LISTED, | ||
MATH_ERROR, | ||
NONZERO_BORROW_BALANCE, | ||
PRICE_ERROR, | ||
REJECTION, | ||
SNAPSHOT_ERROR, | ||
TOO_MANY_ASSETS, | ||
TOO_MUCH_REPAY | ||
} | ||
|
||
enum FailureInfo { | ||
ACCEPT_ADMIN_PENDING_ADMIN_CHECK, | ||
ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK, | ||
EXIT_MARKET_BALANCE_OWED, | ||
EXIT_MARKET_REJECTION, | ||
SET_CLOSE_FACTOR_OWNER_CHECK, | ||
SET_CLOSE_FACTOR_VALIDATION, | ||
SET_COLLATERAL_FACTOR_OWNER_CHECK, | ||
SET_COLLATERAL_FACTOR_NO_EXISTS, | ||
SET_COLLATERAL_FACTOR_VALIDATION, | ||
SET_COLLATERAL_FACTOR_WITHOUT_PRICE, | ||
SET_IMPLEMENTATION_OWNER_CHECK, | ||
SET_LIQUIDATION_INCENTIVE_OWNER_CHECK, | ||
SET_LIQUIDATION_INCENTIVE_VALIDATION, | ||
SET_MAX_ASSETS_OWNER_CHECK, | ||
SET_PENDING_ADMIN_OWNER_CHECK, | ||
SET_PENDING_IMPLEMENTATION_OWNER_CHECK, | ||
SET_PRICE_ORACLE_OWNER_CHECK, | ||
SUPPORT_MARKET_EXISTS, | ||
SUPPORT_MARKET_OWNER_CHECK, | ||
SET_PAUSE_GUARDIAN_OWNER_CHECK | ||
} | ||
|
||
function fail(Error err, FailureInfo info) internal returns (uint) { | ||
emit Failure(uint(err), uint(info), 0); | ||
|
||
return uint(err); | ||
} | ||
|
||
} | ||
|
||
contract CTokenStorage { | ||
address payable public admin; | ||
|
||
|
||
} | ||
|
||
contract ExponentialNoError { | ||
struct Exp { | ||
uint mantissa; | ||
} | ||
|
||
function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) { | ||
return left.mantissa < right.mantissa; | ||
} | ||
|
||
} | ||
|
||
abstract contract CToken is ExponentialNoError { | ||
|
||
|
||
} | ||
|
||
contract UnitrollerAdminStorage { | ||
address public admin; | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV1Storage is UnitrollerAdminStorage { | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV2Storage is ComptrollerV1Storage { | ||
struct Market { | ||
// Whether or not this market is listed | ||
bool isListed; | ||
|
||
// Multiplier representing the most one can borrow against their collateral in this market. | ||
// For instance, 0.9 to allow borrowing 90% of collateral value. | ||
// Must be between 0 and 1, and stored as a mantissa. | ||
uint collateralFactorMantissa; | ||
|
||
// Per-market mapping of "accounts in this asset" | ||
mapping(address => bool) accountMembership; | ||
|
||
// Whether or not this market receives COMP | ||
bool isComped; | ||
} | ||
|
||
mapping(address => Market) public markets; | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV3Storage is ComptrollerV2Storage { | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV4Storage is ComptrollerV3Storage { | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV5Storage is ComptrollerV4Storage { | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV6Storage is ComptrollerV5Storage { | ||
|
||
|
||
} | ||
|
||
contract ComptrollerV7Storage is ComptrollerV6Storage { | ||
|
||
|
||
} | ||
|
||
contract Comptroller is ComptrollerV7Storage, ComptrollerErrorReporter, ExponentialNoError { | ||
uint internal constant collateralFactorMaxMantissa = 0.9e18; | ||
function _setCollateralFactor(CToken cToken, uint newCollateralFactorMantissa) external returns (uint) { | ||
// Check caller is admin | ||
if (msg.sender != admin) { | ||
return fail(Error.UNAUTHORIZED, FailureInfo.SET_COLLATERAL_FACTOR_OWNER_CHECK); | ||
} | ||
|
||
// Verify market is listed | ||
Market storage market = markets[address(cToken)]; | ||
if (!market.isListed) { | ||
return fail(Error.MARKET_NOT_LISTED, FailureInfo.SET_COLLATERAL_FACTOR_NO_EXISTS); | ||
} | ||
|
||
Exp memory newCollateralFactorExp = Exp({mantissa: newCollateralFactorMantissa}); | ||
|
||
// Check collateral factor <= 0.9 | ||
Exp memory highLimit = Exp({mantissa: collateralFactorMaxMantissa}); | ||
if (lessThanExp(highLimit, newCollateralFactorExp)) { | ||
return fail(Error.INVALID_COLLATERAL_FACTOR, FailureInfo.SET_COLLATERAL_FACTOR_VALIDATION); | ||
} | ||
|
||
// If collateral factor != 0, fail if price == 0 | ||
if (newCollateralFactorMantissa != 0 && oracle.getUnderlyingPrice(cToken) == 0) { | ||
return fail(Error.PRICE_ERROR, FailureInfo.SET_COLLATERAL_FACTOR_WITHOUT_PRICE); | ||
} | ||
|
||
// Set market's collateral factor to new collateral factor, remember old value | ||
uint oldCollateralFactorMantissa = market.collateralFactorMantissa; | ||
market.collateralFactorMantissa = newCollateralFactorMantissa; | ||
|
||
// Emit event with asset, old collateral factor, and new collateral factor | ||
emit NewCollateralFactor(cToken, oldCollateralFactorMantissa, newCollateralFactorMantissa); | ||
|
||
return uint(Error.NO_ERROR); | ||
} | ||
|
||
} |