# Comptroller

The Comptroller is the risk management layer of the Moonwell protocol. It acts as a gatekeeper for all market operations - every mint, redeem, borrow, repay, liquidation, and transfer is validated by the Comptroller before execution.

The Comptroller is deployed as an upgradeable proxy (Unitroller pattern). The Unitroller holds storage and delegates calls to the Comptroller implementation.

## Responsibilities

* **Market membership** - Users must call `enterMarkets` to enable their supplied assets as collateral before borrowing
* **Collateral calculations** - Determines each account's liquidity based on supplied collateral, collateral factors, and oracle prices
* **Borrow authorization** - Checks that a borrower has sufficient collateral before allowing borrows
* **Liquidation authorization** - Determines whether a position is underwater and can be liquidated
* **Supply/borrow caps** - Enforces per-market limits on total supply and total borrows
* **Pause controls** - Allows guardians to pause mint, borrow, transfer, or seize operations
* **Reward distribution** - Manages WELL token distribution to suppliers and borrowers via the Multi-Reward Distributor

## Architecture

The Comptroller uses a **policy hook** pattern. Each mToken operation calls into the Comptroller to check whether it is allowed:

```
User → mToken.mint() → Comptroller.mintAllowed() → ✓ or ✗
User → mToken.borrow() → Comptroller.borrowAllowed() → ✓ or ✗
User → mToken.redeem() → Comptroller.redeemAllowed() → ✓ or ✗
```

The Comptroller can reject operations in two ways:

* **Reverts** - Pause checks, supply/borrow cap enforcement, and authorization checks use `require()`, which **reverts the transaction** (e.g. `"mint is paused"`, `"market supply cap reached"`, `"market borrow cap reached"`, `"seize is paused"`, `"transfer is paused"`)
* **Error codes** - Other rejection reasons (e.g. insufficient collateral, market not listed) return a non-zero error code, and the mToken function returns a non-zero `uint` **without reverting**

{% hint style="info" %}
**Redeem and repay have no pause mechanism** - users can always withdraw and repay debt, by design.
{% endhint %}

Integrators should handle both: wrap calls in try/catch for reverts, and check return values for error codes.

## Deployed Addresses

| Network    | Address                                                                                                                            |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Base       | [`0xfBb21d0380beE3312B33c4353c8936a0F13EF26C`](https://basescan.org/address/0xfBb21d0380beE3312B33c4353c8936a0F13EF26C)            |
| OP Mainnet | [`0xCa889f40aae37FFf165BccF69aeF1E82b5C511B9`](https://optimistic.etherscan.io/address/0xCa889f40aae37FFf165BccF69aeF1E82b5C511B9) |
| Moonbeam   | [`0x8E00D5e02E65A19337Cdba98bbA9F84d4186a180`](https://moonscan.io/address/0x8e00d5e02e65a19337cdba98bba9f84d4186a180)             |
| Moonriver  | [`0x0b7a0EAA884849c6Af7a129e899536dDDcA4905E`](https://moonriver.moonscan.io/address/0x0b7a0EAA884849c6Af7a129e899536dDDcA4905E)   |

{% content-ref url="/pages/u89jFIzbKYYsqhnqQg77" %}
[Contract Interactions](/moonwell/developers/protocol/mtokens/contract-interactions.md)
{% endcontent-ref %}

{% content-ref url="/pages/HLqs7KPqvS9RN7QfePZY" %}
[Risk Parameters](/moonwell/developers/protocol/comptroller/risk-parameters.md)
{% endcontent-ref %}

{% content-ref url="/pages/igpeNnpNZH3nMWuxVxmS" %}
[Guardian Roles](/moonwell/developers/protocol/comptroller/guardian-roles.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.moonwell.fi/moonwell/developers/protocol/comptroller.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
