> For the complete documentation index, see [llms.txt](https://docs.moonwell.fi/moonwell/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.moonwell.fi/moonwell/developers/protocol/mtokens.md).

# mTokens

mTokens are ERC-20 compliant tokens that represent positions within the Moonwell protocol. When you supply assets, you receive mTokens in return. As interest accrues to the market, the exchange rate between mTokens and the underlying asset increases - meaning your mTokens become redeemable for a growing amount of the underlying over time.

mTokens are transferrable and fungible, and can be redeemed for the underlying asset provided there is sufficient liquidity and the position has not been designated as collateral.

Each market supported by the protocol (e.g. USDC, WETH, cbBTC) is represented by its own mToken contract. The mToken is responsible for:

* Accepting new deposits (minting mTokens)
* Allowing withdrawals of assets from the protocol (redeeming/burning mTokens)
* Managing borrow requests for a specific asset
* Facilitating repayments for a specific market
* Handling liquidations for specific market positions
* Calculating reserve and seize shares to increase protocol reserves

## Integration Quickstart

The following example demonstrates a complete supply → borrow → repay → withdraw flow. All interactions go through the mToken contracts directly. Before borrowing, you must enter the market via the [Comptroller](/moonwell/developers/protocol/comptroller.md).

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;

import {MErc20} from "@moonwell/MErc20.sol";
import {EIP20Interface} from "@moonwell/EIP20Interface.sol";
import {ComptrollerInterface} from "@moonwell/ComptrollerInterface.sol";

contract MoonwellIntegration {
    /// @notice Supply USDC and borrow WETH against it
    function supplyAndBorrow(
        address mUSDC,    // Moonwell USDC mToken
        address mWETH,    // Moonwell WETH mToken
        address comptroller,
        uint256 supplyAmount,
        uint256 borrowAmount
    ) external {
        // 1. Approve the mToken to pull underlying
        EIP20Interface usdc = EIP20Interface(MErc20(mUSDC).underlying());
        usdc.approve(mUSDC, supplyAmount);

        // 2. Supply - mints mTokens to this contract
        uint err = MErc20(mUSDC).mint(supplyAmount);
        require(err == 0, "mint failed");

        // 3. Enter the market - enables USDC as collateral
        address[] memory markets = new address[](1);
        markets[0] = mUSDC;
        uint[] memory results = ComptrollerInterface(comptroller).enterMarkets(markets);
        require(results[0] == 0, "enterMarkets failed");

        // 4. Borrow WETH against USDC collateral
        err = MErc20(mWETH).borrow(borrowAmount);
        require(err == 0, "borrow failed");
    }

    /// @notice Repay WETH borrow and withdraw USDC
    function repayAndWithdraw(
        address mUSDC,
        address mWETH,
        uint256 repayAmount,
        uint256 withdrawAmount
    ) external {
        // 1. Approve and repay the borrow
        EIP20Interface weth = EIP20Interface(MErc20(mWETH).underlying());
        weth.approve(mWETH, repayAmount);

        uint err = MErc20(mWETH).repayBorrow(repayAmount);
        require(err == 0, "repay failed");

        // 2. Withdraw USDC by specifying the underlying amount
        err = MErc20(mUSDC).redeemUnderlying(withdrawAmount);
        require(err == 0, "redeem failed");
    }

    /// @notice Query current positions
    function getPositions(
        address mToken,
        address account
    ) external view returns (
        uint256 mTokenBalance,
        uint256 borrowBalance,
        uint256 exchangeRate
    ) {
        (uint err, uint bal, uint borrows, uint rate) =
            MErc20(mToken).getAccountSnapshot(account);
        require(err == 0, "snapshot failed");
        return (bal, borrows, rate);
    }
}
```

## Key Concepts

### Exchange Rate

The exchange rate determines how many underlying tokens each mToken is worth:

```
exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply
```

As interest accrues, `totalBorrows` grows, increasing the exchange rate. This means suppliers earn interest simply by holding mTokens - no claiming required.

### Interest Accrual

Interest accrues per-second (not per-block). Rates are determined by the market's interest rate model based on utilization:

```
utilization = totalBorrows / (totalCash + totalBorrows - totalReserves)
```

Higher utilization means higher borrow rates and higher supply rates.

### Error Handling

mToken functions use **two failure modes**:

* **Error codes** - Business logic failures (comptroller rejection, insufficient collateral, freshness checks) return a non-zero `uint` **without reverting**. Always check the return value.
* **Reverts** - Underlying token transfer failures, math overflows, and Comptroller pause/cap enforcement use `require()` and **revert the transaction**.

Integrators should handle both: use try/catch for reverts, and check return values for error codes. See [Contract Interactions](/moonwell/developers/protocol/mtokens/contract-interactions.md) for the full error code table.

## Deployed Contracts

### Base

| Market          | Address                                                                                                                 |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Comptroller     | [`0xfBb21d0380beE3312B33c4353c8936a0F13EF26C`](https://basescan.org/address/0xfBb21d0380beE3312B33c4353c8936a0F13EF26C) |
| Moonwell USDC   | [`0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22`](https://basescan.org/token/0xEdc817A28E8B93B03976FBd4a3dDBc9f7D176c22)   |
| Moonwell WETH   | [`0x628ff693426583D9a7FB391E54366292F509D457`](https://basescan.org/address/0x628ff693426583D9a7FB391E54366292F509D457) |
| Moonwell cbETH  | [`0x3bf93770f2d4a794c3d9EBEfBAeBAE2a8f09A5E5`](https://basescan.org/address/0x3bf93770f2d4a794c3d9EBEfBAeBAE2a8f09A5E5) |
| Moonwell wstETH | [`0x627Fe393Bc6EdDA28e99AE648fD6fF362514304b`](https://basescan.org/token/0x627Fe393Bc6EdDA28e99AE648fD6fF362514304b)   |
| Moonwell cbBTC  | [`0xF877ACaFA28c19b96727966690b2f44d35aD5976`](https://basescan.org/address/0xF877ACaFA28c19b96727966690b2f44d35aD5976) |
| Moonwell DAI    | [`0x73b06D8d18De422E269645eaCe15400DE7462417`](https://basescan.org/address/0x73b06D8d18De422E269645eaCe15400DE7462417) |
| Moonwell AERO   | [`0x73902f619CEB9B31FD8EFecf435CbDf89E369Ba6`](https://basescan.org/token/0x73902f619CEB9B31FD8EFecf435CbDf89E369Ba6)   |
| Moonwell EURC   | [`0xb682c840B5F4FC58B20769E691A6fa1305A501a2`](https://basescan.org/address/0xb682c840B5F4FC58B20769E691A6fa1305A501a2) |

### OP Mainnet

| Market          | Address                                                                                                                            |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Comptroller     | [`0xCa889f40aae37FFf165BccF69aeF1E82b5C511B9`](https://optimistic.etherscan.io/address/0xCa889f40aae37FFf165BccF69aeF1E82b5C511B9) |
| Moonwell USDC   | [`0x8E08617b0d66359D73Aa11E11017834C29155525`](https://optimistic.etherscan.io/address/0x8E08617b0d66359D73Aa11E11017834C29155525) |
| Moonwell WETH   | [`0xb4104C02BBf4E9be85AAa41a62974E4e28D59A33`](https://optimistic.etherscan.io/address/0xb4104C02BBf4E9be85AAa41a62974E4e28D59A33) |
| Moonwell USDT   | [`0xa3A53899EE8f9f6E963437C5B3f805FEc538BF84`](https://optimistic.etherscan.io/address/0xa3A53899EE8f9f6E963437C5B3f805FEc538BF84) |
| Moonwell WBTC   | [`0x6e6CA598A06E609c913551B729a228B023f06fDB`](https://optimistic.etherscan.io/address/0x6e6CA598A06E609c913551B729a228B023f06fDB) |
| Moonwell wstETH | [`0xbb3b1aB66eFB43B10923b87460c0106643B83f9d`](https://optimistic.etherscan.io/address/0xbb3b1aB66eFB43B10923b87460c0106643B83f9d) |
| Moonwell OP     | [`0x9fc345a20541Bf8773988515c5950eD69aF01847`](https://optimistic.etherscan.io/address/0x9fc345a20541Bf8773988515c5950eD69aF01847) |

For the complete list of all deployed contracts across all chains, see [Contracts](/moonwell/protocol-information/contracts.md).

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.moonwell.fi/moonwell/developers/protocol/mtokens.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
