Comptroller

API reference for the Comptroller, which is responsible for ensuring the safety of the protocol.

Core methods

This section contains the primary methods for interacting with the Comptroller for the Cozy protocol.

Create protection markets

Anyone can create new protection markets with the Comptroller's deployProtectionMarket methods. For more information on creating protection markets, see the Create a protection Mmrket guide.

Entering and exiting markets

When supplying assets to a money market, those funds are not automatically available as collateral for borrowing. Instead, you must specify when you want supplied assets to be used as collateral. Telling the protocol you want to use a certain asset as collateral is known as "entering the market".

All protection markets have collateral factors of zero, meaning funds supplied to protection markets cannot be used as collateral. Therefore, you should only explicitly enter markets for funds supplied to a money market.

To enter a market, call the enterMarkets method on the Comptroller, where cTokens is an array of Cozy money market addresses.

function enterMarkets(address[] calldata cTokens) external returns (uint256[] memory);

When you no longer want to use supplied funds in a market as collateral, you can exit the market with the exitMarket method described below. Notice that you can enter multiple markets in a single transaction, but you can only exit one market per call. When exiting a market, your transaction will fail with an error code if you have an outstanding borrow balance in that market, or if exiting the market would result in insufficient account liquidity.

function exitMarket(address cTokenAddress) external returns (uint256);

Note that borrowing from a market automatically enters you into that market, since liquidity calculations loop through all entered markets to determine if you have sufficient account liquidity.

Both the enterMarkets method and the exitMarket methods return a uint256 value of 0 for a successful call, and return an error code for an unsuccessful call.

View methods

This section contains the primary methods for viewing information managed by the Comptroller.

Account assets

You can use the getAssetsIn method to return a list of markets that a user has entered. The method takes the user's address as an input and returns the full set of markets for the specified user in an array. The array of markets returned by this method is the full set of markets used for liquidity calculations.

function getAssetsIn(address account) external view returns (CToken[] memory);

Collateral factors

Every market has a collateral factor that represents how much borrow power is increased by when that market's assets are used as collateral. This collateral factor can range from 0% to 90% and can be interpreted as:

  • A value of 0% means using that an asset cannot be used as collateral, as it gives you no borrowing power.

  • A value of 90% means supplying $100 of that asset allows you to borrow up to $90 of another asset.

All protection markets have collateral factors of 0%, and money markets can have collateral factors anywhere in the 0–90% range.

You can retrieve the collateral factor for a given market with the following markets function by providing a Cozy token market address as input:

function markets(address cTokenAddress) view returns (bool, uint256, bool)

The function returns the first bool value for the isListed property as true if the market is recognized by the Comptroller or false if it is not.

The uint256 returned by the function is an 18 decimal number for the collateralFactorMantissa property described above. A value of 0.9 means that you can supply this market's assets as collateral to borrow up to 90% of the supplied value.

The second bool value is for the isComped property that is not currently used and can be safely ignored.

Listed markets

You can use the getAllMarkets method to return an array of all Cozy token markets supported by the Comptroller as follows:

function getAllMarkets() external view returns (CToken[] memory);

The addresses returned from this array can be directly passed as inputs to the markets function described in the CollateralFactors section to retrieve various metadata for the specified market.

Account liquidity

Account liquidity specifies a user's borrowing power in USD. If you borrow too much (for example, if the value of your collateral falls), your account liquidity can fall below zero and can result in your account being liquidated.

Account liquidity is based on all markets entered by a user. For each of those assets, the collateral quantity is converted to USD and multiplied by that asset's collateral factor. Summing these values and subtracting current borrow balances results in the current account liquidity for a user.

You can query the account liquidity for a user as follows:

function getAccountLiquidity(address account) external view returns (uint256, uint256, uint256);

The first uint256 returned is zero on success or an error code on failure.

If the account queried has positive account liquidity, that is, the user can borrow more assets, the second uint256 will equal the user's account liquidity and the third uint256 will equal zero. If the account queried has negative account liquidity, that is, the user has a shortfall and can be liquidated, the second uint256 will be zero and the third uint256 will equal the shortfall amount.

Liquidation incentive

To incentivize liquidations of accounts that have a shortfall, the liquidationIncentiveMantissa method specifies additional collateral that liquidators receive. For example, if the liquidation incentive is 1.08e18, then liquidators receive 8% more collateral than the borrow amount they closed.

To illustrate how the incentive works, assume a liquidator repays $1000 worth of a user's borrows. If the liquidation incentive is 1.08e18, then the liquidator will receive $1000 * 1.08 = $1080 of the user's collateral. The liquidation incentive is the same for all markets, and can be changed. You can read the current value as follows:

function liquidationIncentiveMantissa() external view returns (uint256);

Close factor

When liquidating an account, you cannot necessarily repay the full borrow amount and entirely liquidate the borrower. Instead, the close factor specifies what portion of their account can be repaid in a single liquidation. This value applies to individual borrowed assets, not the overall position. The close factor is the same for all markets, and can be changed. You can read the current value as follows:

function closeFactorMantissa() external view returns (uint256);

Events

This sections contains the core events emitted by the Comptroller, and is not a comprehensive list.

// Emitted when a third party adds a protection market
event ProtectionMarketListed(CToken cToken, address trigger);

// Emitted when an account enters a market
event MarketEntered(CToken cToken, address account);

// Emitted when an account exits a market
event MarketExited(CToken cToken, address account);

Error handling

This section contains information about error codes and failure messages that you might see when calling methods on the Comptroller.

Error codes

The following table below contains a list of error codes that you might see when calling methods on the Comptroller.

CodeNameDescription

0

NO_ERROR

Call succeeded

1

UNAUTHORIZED

Caller is not authorized

2

COMPTROLLER_MISMATCH

Cannot liquidate across markets with different comptrollers

3

INSUFFICIENT_SHORTFALL

The account cannot be liquidated since it has no shortfall

4

INSUFFICIENT_LIQUIDITY

Redeem or borrow not allowed because the account has insufficient liquidity

5

INVALID_CLOSE_FACTOR

Outdated, not used

6

INVALID_COLLATERAL_FACTOR

Cannot set new collateral factor, as specified value is invalid

7

INVALID_LIQUIDATION_INCENTIVE

Outdated, not used

8

MARKET_NOT_ENTERED

Outdated, not used

9

MARKET_NOT_LISTED

The specified market is not listed by the Comptroller

10

MARKET_ALREADY_LISTED

Specified market already exists

11

MATH_ERROR

An error occurred in a math operation

12

NONZERO_BORROW_BALANCE

Cannot exit market if borrow balance is above zero

13

PRICE_ERROR

The Comptroller could not get a valid price for an asset

14

REJECTION

The Comptroller rejected the action specified by a Cozy token

15

SNAPSHOT_ERROR

Unable to read a user's account borrows and market exchange rate

16

TOO_MANY_ASSETS

Cannot enter a number of markets greater than `maxAssets'

17

TOO_MUCH_REPAY

Cannot repay more than the protocol will allow

18

INVALID_TRIGGER

The specified trigger is not valid so a protection market cannot be created with it

19

PROTECTION_MARKET_FACTORY_ERROR

The specified ProtectionMarketFactory address is not valid

Failure codes and logged messages

The following table below contains a list of error codes that may be emitted in Failure logs when calling methods on the Comptroller. These codes are descriptive so no additional description is provided.

CodeName

0

ACCEPT_ADMIN_PENDING_ADMIN_CHECK

1

ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK

2

EXIT_MARKET_BALANCE_OWED

3

EXIT_MARKET_REJECTION

4

SET_CLOSE_FACTOR_OWNER_CHECK

5

SET_CLOSE_FACTOR_VALIDATION

6

SET_COLLATERAL_FACTOR_OWNER_CHECK

7

SET_COLLATERAL_FACTOR_NO_EXISTS

8

SET_COLLATERAL_FACTOR_VALIDATION

9

SET_COLLATERAL_FACTOR_WITHOUT_PRICE

10

SET_IMPLEMENTATION_OWNER_CHECK

11

SET_LIQUIDATION_INCENTIVE_OWNER_CHECK

12

SET_LIQUIDATION_INCENTIVE_VALIDATION

13

SET_MAX_ASSETS_OWNER_CHECK

14

SET_PENDING_ADMIN_OWNER_CHECK

15

SET_PENDING_IMPLEMENTATION_OWNER_CHECK

16

SET_PRICE_ORACLE_OWNER_CHECK

17

SUPPORT_MARKET_EXISTS

18

SUPPORT_MARKET_OWNER_CHECK

19

SET_PAUSE_GUARDIAN_OWNER_CHECK

20

SET_TRIGGER_CHECK

21

SET_PROTECTION_WITH_INVALID_UNDERLYING

22

SET_PROTECTION_UNDERLYING_WITHOUT_PRICE

23

SET_PROTECTION_MARKET_FACTORY_OWNER_CHECK

24

SET_PROTECTION_MARKET_FACTORY_VALIDITY_CHECK

25

SET_RESERVE_GUARDIAN_OWNER_CHECK

Last updated