Comptroller
The comptroller is the management layer of a pool. Each pool has its own unique comptroller and these are deployed by the PoolDirectory contract.
It manages many aspects of a pool, including but not limited to:
Assets/Tokens that are listed in a pool and if they can be supplied/borrowed
LTVs, it helps manage the risk of the pool by managing the amount of debt which can be issued against a particular collateral
User Collateral, it manages which assets supplied by a user are explicitly used as collateral against their debt
Price Oracle, it maps the token balances into prices using a PriceOracle
Implementation
The comptroller is implemented in a proxy-contract fashion, where the Unitroller contract proxies all interactions/logic from the Comptroller while using the storage of Unitroller. To learn more about upgradable proxies, read Proxy Upgrade Pattern by OpenZeppelin.
Some Important Terms
Close Factor
Valid range: 0.01*1e18 to 1*1e18 (corresponds to 1% to 100%)
The close factor decides what percentage of a liquidatable account's debt can be repaid in a single transaction. It applies to any single borrowed asset and not the aggregated value of a userβs outstanding borrowing.
For close factor less than 100%, this ensures positions aren't fully liquidated in one step, and partial liquidations take place.
Collateral Factor
Valid range: 0*1e18 to 0.90*1e18 (corresponds to 0% to 90%)
A mToken's collateral factor represents the proportionate increase in liquidity (borrow limit) that an account receives by minting the mToken.
Generally, large or liquid assets have high collateral factors, while small or illiquid assets have low collateral factors. If an asset has a 0% collateral factor, it can't be used as collateral (or seized in liquidation), though it can still be borrowed. This is often called an LTV ("Loan to Value") too.
Liquidation Incentive
Valid range: 1*1e18 to 1.2*1e18 (corresponds to 0% to 20% extra collateral)
The additional collateral given to liquidators as an incentive to perform liquidation of underwater accounts. For example, if the liquidation incentive is 1.1, liquidators receive an extra 10% of the borrower's collateral for every unit they close.
Supply / Borrow Cap
Caps basically set the max amount of tokens that can be supplied or borrowed from a pool. These are often referred to as ceilings, ie: borrow cap = debt ceiling
Structs
The Market
struct is used to map the relationship between an mToken
and the pool comptroller
.
isListed
implies Whether or not this market is listedcollateralFactorMantissa
View Methods
getAllMarkets() -> mToken[]
Returns list of mToken
addresses corresponding to all assets that are supported in the pool.
getAllBorrowers() -> address[]
Returns list of users who have engaged in borrowing in the pool.
getWhitelist -> address[]
Returns list of users who are whitelisted/allowed to use the pool, if it has a whitelist.
getRewardDistributors -> address[]
Returns all the reward distributor contract addresses that are actively distributing rewards in the pool.
oracle -> address
Returns the address of the price oracle contract used in the pool.
closeFactorMantissa -> uint256
Returns the closeFactor
scaled to 18 decimals. 5% = 0.05e18.
liquidationIncentiveMantissa -> uint256
Returns the liquidationIncentive
scaled by 18 decimals.
markets(address) -> Market (Collateral Factor)
Returns the official metadata for a particular mToken
in the pool. Shares if it is listed and the collateral factor (or "LTV") of this mToken
.
borrowCaps(address) -> uint
Returns the borrow cap (or "debt ceiling") set on a particular mToken
.
supplyCaps(address) -> uint
Returns the supply cap set on a particular mToken
.
Writeable Methods
enterMarkets(address[]) -> uint[]
Enter a list of mTokens whose markets you wish to enter. It is not an error to enter the same market more than once. In order to supply collateral or borrow in a market, you need to execute this first.
mTokens - list of mTokens/markets to set as collateral
returns - an error code for each market. 0 is success, and anything else is a Failure.
exitMarket(address) -> uint
Exit a market. It is not an error to exit a market which is not currently entered. Exited markets do not count towards account liquidity calculations.
mToken - The mToken/market to exclude out of the account liquidity calculations
returns - an error code for the market. 0 is success, and anything else is a Failure.
_addRewardsDistributor(address) -> uint
Adds a rewards distributor, which can be used to incentivise supply/borrow.
distributor - The rewards distributor contract address
returns - an error code. 0 is success, and anything else is a Failure.
_setWhitelistEnforcement(bool) -> uint
Sets the enforcement of a pool's whitelist to true/false and thus enables/disables the pool whitelist.
state - The boolean state for enabling/disabling whitelist
returns - an error code. 0 is success, and anything else is a Failure.
_setWhitelistStatuses(address[], bool[]) -> uint
Sets whitelist statuses for user accounts, this decides which users are on the whitelist and which users are not.
users - The list of users for toggling their status
returns - an error code. 0 is a success, and anything else is a Failure.
_setPriceOracle(address) -> uint
Updates the PriceOracle contract used by the pool.
newOracle - The address of a new oracle to be set on the pool
returns - an error code. 0 is success and anything else is a Failure.
_setCloseFactor(uint) -> uint
Valid range: 0.01*1e18 to 1*1e18 (corresponds to 1% to 100%)
Sets specified close factor on the pool.
newCloseFactorMantissa - The new value to be set for close factor of the pool
returns - an error code. 0 is a success and anything else is a Failure.
_setCollateralFactor(address, uint) -> uint
Valid range: 0*1e18 to 0.90*1e18 (corresponds to 0% to 90%)
Sets specified new collateral factor for a particular mToken in the pool.
mToken - The mToken for which the collateral factor is updated
newCollateralFactorMantissa - The new value to be set as collateral factor of the pool
returns - an error code. 0 is a success and anything else is a Failure.
_setLiquidationIncentive(uint) -> uint
Valid range: 1*1e18 to 1.2*1e18 (corresponds to 0% to 20% extra collateral)
Sets specified new liquidation incentive for the pool.
newLiquidationIncentiveMantissa - The new value to be set as liquidation incentive of the pool
returns - an error code. 0 is a success and anything else is a Failure.
_deployMarket(bool, bytes, uint) -> uint
Deploy an mToken for the pool. Can be called only by pool administrator.
isCEther - if the token is a native token, for example: MATIC on the polygon network
constructorData - the abi-encoded arguments to be passed to the constructor
collateralFactorMantissa - the collateral factor to be set on the new mToken
returns - an error code. 0 is a success and anything else is a Failure.
_unsupportMarket(address) -> uint
Removes support for a particular mToken from the pool. Can be called only by pool administrator. Note that there should be no supply or debt in this mToken to be removed.
mToken - address of the mToken that has to be removed/unSupported.
returns - an error code. 0 is a success and anything else is a Failure.
_setMarketSupplyCaps(address[], uint[])
Sets a supply cap / ceiling for mTokens. Can be called only by pool administrator.
mTokens - list of addresses of mTokens to set supply caps for.
caps - list of token amounts to be set as supply caps.
_setMarketBorrowCaps(address[], uint[])
Sets a borrow cap / debt ceiling for mTokens. Can be called only by pool administrator.
mTokens - list of addresses of mTokens to set borrow caps for.
caps - list of token amounts to be set as borrow caps.
_setBorrowCapGuardian(address)
Sets a borrow cap guardian, which is an account that can change borrow/supply caps/ceilings in the pool in cases of emergency. Can be called only by pool administrator.
newBorrowCapGuardian - address of the account
_setPauseGuardian(address) -> uint
Sets a pause guardian, which is an account that can pause/unpause borrow/supply in the pool in cases of emergency. Can be called only by pool administrator.
newPauseGuardian - address of the account
returns - an error code. 0 is a success, and anything else is a Failure.
_setMintPaused(address, bool) -> bool
Pauses all users' ability to supply in an mToken. Can be called by pool administrator or pauseGuardian.
mToken - address of the mToken to be supply paused
state - boolean state to be set to pause supply
returns - final boolean state of the supply, paused/unPaused
_setBorrowPaused(address, bool) -> bool
Pauses all users' ability to borrow in an mToken. Can be called by pool administrator or pauseGuardian.
mToken - address of the mToken to be borrow paused
state - boolean state to be set to pause borrow
returns - final boolean state of the borrow, paused/unPaused
Error Codes
Code | Name | Description |
---|---|---|
0 | NO_ERROR | Success. Not an error. |
1 | UNAUTHORIZED | The sender is not authorized to perform this action. |
2 | COMPTROLLER_MISMATCH | Liquidation cannot be performed in markets with different comptrollers. |
3 | INSUFFICIENT_SHORTFALL | The account does not have sufficient shortfall to perform this action. |
4 | INSUFFICIENT_LIQUIDITY | The account does not have sufficient liquidity to perform this action. |
5 | INVALID_CLOSE_FACTOR | The close factor is not valid. |
6 | INVALID_COLLATERAL_FACTOR | The collateral factor is not valid. |
7 | INVALID_LIQUIDATION_INCENTIVE | The liquidation incentive is not valid. |
8 | MARKET_NOT_ENTERED | The market has not been entered by the account. |
9 | MARKET_NOT_LISTED | The market is not currently listed by the comptroller. |
10 | MARKET_ALREADY_LISTED | An admin tried to list the same market more than once. |
11 | MATH_ERROR | A math calculation error occurred. |
12 | NONZERO_BORROW_BALANCE | The action cannot be performed since the account carries a borrow balance. |
13 | PRICE_ERROR | The comptroller could not obtain a required price of an asset. |
14 | REJECTION | The comptroller rejects the action requested by the market/mToken. |
15 | SNAPSHOT_ERROR | The comptroller could not get the account borrows and exchange rate from the market. |
16 | TOO_MANY_ASSETS | Attempted to enter more markets than are currently supported. |
17 | TOO_MUCH_REPAY | Attempted to repay more than is allowed by the protocol. |
18 | SUPPLIER_NOT_WHITELISTED | The comptroller could not get the account borrows and exchange rate from the market. |
19 | BORROW_BELOW_MIN | Attempted to borrow less than the minimum allowed amount. |
20 | SUPPLY_ABOVE_MAX | Attempted to supply more than the maximum allowed amount. |
21 | NONZERO_TOTAL_SUPPLY | Admin attempted to unsupport a market that has some supply. |
Failure Info
Code | Name |
---|---|
0 | ACCEPT_ADMIN_PENDING_ADMIN_CHECK |
1 | ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK |
2 | ADD_REWARDS_DISTRIBUTOR_OWNER_CHECK |
3 | EXIT_MARKET_BALANCE_OWED |
4 | EXIT_MARKET_REJECTION |
5 | TOGGLE_ADMIN_RIGHTS_OWNER_CHECK |
6 | TOGGLE_AUTO_IMPLEMENTATIONS_ENABLED_OWNER_CHECK |
7 | SET_CLOSE_FACTOR_OWNER_CHECK |
8 | SET_CLOSE_FACTOR_VALIDATION |
9 | SET_COLLATERAL_FACTOR_OWNER_CHECK |
10 | SET_COLLATERAL_FACTOR_NO_EXISTS |
11 | SET_COLLATERAL_FACTOR_VALIDATION |
12 | SET_COLLATERAL_FACTOR_WITHOUT_PRICE |
13 | SET_LIQUIDATION_INCENTIVE_OWNER_CHECK |
14 | SET_LIQUIDATION_INCENTIVE_VALIDATION |
15 | SET_MAX_ASSETS_OWNER_CHECK |
16 | SET_PENDING_ADMIN_OWNER_CHECK |
17 | SET_PENDING_IMPLEMENTATION_CONTRACT_CHECK |
18 | SET_PENDING_IMPLEMENTATION_OWNER_CHECK |
19 | SET_PRICE_ORACLE_OWNER_CHECK |
20 | SET_WHITELIST_ENFORCEMENT_OWNER_CHECK |
21 | SET_WHITELIST_STATUS_OWNER_CHECK |
22 | SUPPORT_MARKET_EXISTS |
23 | SUPPORT_MARKET_OWNER_CHECK |
24 | SET_PAUSE_GUARDIAN_OWNER_CHECK |
25 | UNSUPPORT_MARKET_OWNER_CHECK |
26 | UNSUPPORT_MARKET_DOES_NOT_EXIST |
27 | UNSUPPORT_MARKET_IN_USE |
Last updated