mToken
In the Market Protocol, each
mToken
contract can be thought of as an individual vault that stores an underlying asset for a pool. Each underlying asset has its own mToken
and they are unique to each pool, thanks to the isolation provided by the protocol. Also in our docs, we use CToken
and MToken
interchangeably.The
mToken
contract is implemented as an upgradable proxy, where the CTokenDelegator
contract proxies all interactions/logic to CTokenDelegate
while using the storage of CTokenDelegator
. To learn more about upgradable proxies, read Proxy Upgradable Pattern by OpenZeppelin.Each
mToken
is convertible into an ever increasing quantity of the underlying asset, as interest accrues in the market.The APY for supplying or borrowing into a
mToken
in any given pool, can be calculated very easily, here's a sample snippet:uint256 supplyRate = mToken.supplyRatePerBlock();
uint256 blocksPerDay = (60 * 60 * 24)/2 // for polygon that has 1 block per 2s
uint256 year = 365; // 1yr = 365d
uint256 mantissa = 1e18;
uint256 APY = ((((supplyRate * blocksPerDay)/mantissa)+1)**year - 1) * 100;
Reserves are an accounting entry in each mToken contract that represents a portion of historical interest set aside as cash which can be withdrawn or transferred through the protocol's governance. A small portion of borrower interest accrues into the protocol, determined by the reserve factor.
Reserve factor is the fraction of interest that is set-aside for reserves.
function exchangeRateCurrent() external returns (uint);
- returns - The current exchange rate as an unsigned integer, scaled by 1e18.
function getCash() external view returns (uint);
- returns - The total amount of underlying balance owned by the contract as an unsigned integer, scaled by 1e18.
function totalBorrowsCurrent() external returns (uint);
- returns - The total amount of underlying that has been currently loaned out to users with interest included.
- note - use
eth_call
on this function, otherwise it will create a transaction.
function totalSupply() external view returns(uint);
- returns - The total number of tokens that are in circulation
function totalReserves() external view returns(uint);
- returns - The total amount of reserves of the underlying held in this
mToken
function balanceOfUnderlying(address account) external returns(uint);
- returns - The total amount of underlying asset owned by a user that is held in this contract
- note - use
eth_call
on this function, otherwise it will create a transaction. - This is calculated by multiplying the exchangeRate with the number of
mTokens
the user holds
function borrowRatePerBlock() external view returns (uint);
- returns - The current per-block borrow interest rate for this
mToken
scaled by 1e18.
function supplyRatePerBlock() external view returns (uint);
- returns - The current per-block supply interest rate for this
mToken
scaled by 1e18.
function reserveFactorMantissa() external view returns(uint);
- returns - Reserve Factor of the
mToken
which is fraction of interest currently set aside for reserves. It is scaled to 18 decimals.
function adminFeeMantissa() external view returns(uint);
- returns - The admin fee charged by the pool administrator. It is scaled to 18 decimals.
function mint(uint mintAmount) external returns (uint);
Allows a user to deposit underlying into this
mToken
. approve
must be called on the underlying for this contract.- mintAmount - the amount of underlying to be deposited
- returns - an error code. 0 is a success and anything else is a failure.
function borrow(uint borrowAmount) external returns (uint);
Allows a user who has collateral in the pool, to borrow from this
mToken
. - borrowAmount - the amount of underlying to be borrowed
- returns - an error code. 0 is a success and anything else is a failure.
function redeem(uint redeemTokens) external returns (uint);
Allows a user who has supplied underlying in this
mToken
to redeem it back based on the number of mTokens
they want. It uses exchangeRate internally to convert number of mTokens
to underlying tokens.- redeemAmount - the number of
mTokens
against which the user wants to redeem underlying - returns - an error code. 0 is a success and anything else is a failure
function redeemUnderlying(uint redeemAmount) external returns (uint);
Allows a user who has supplied underlying in this
mToken
to redeem it back based on the number of underlying tokens they want.- redeemAmount - the number of underlying tokens which they want to redeem
- returns - an error code. 0 is a success and anything else is a failure
function repayBorrow(uint repayAmount) external returns (uint);
Allows a user to repay their loan previously taken from this
mToken
- repayAmount - the number of underlying tokens the user wants to repay
- returns - an error code. 0 is a success and anything else is a failure
function repayBorrowBehalf(
address borrower,
uint repayAmount
) external returns (uint);
Allows a user to repay a loan on someone else's behalf
- borrower - address of the borrower's account for which the user wants to repay
- repayAmount - the number of underlying tokens the user wants to repay
- returns - an error code. 0 is a success and anything else is a failure
function liquidateBorrow(
address borrower,
uint repayAmount,
address mTokenCollateral
) external returns (uint);
Allows a user to liquidate an unhealthy borrower's debt and gain liquidation incentive for doing this.
- borrower - the account which is being liquidated
- repayAmount - the number of underlying tokens the user wants to repay
- mTokenCollateral - the mToken to be received for liquidating this account's debt
- returns - an error code. 0 is a success and anything else is a failure
function _setAdminFee(uint newAdminFeeMantissa) external returns (uint);
Allows pool administrators to set an admin fee for managing this asset.
- newAdminFeeMantissa - the new admin fee to be set. scaled to 18 decimals.
- returns - an error code. 0 is a success and anything else is a failure.
function _setReserveFactor(uint newReserveFactorMantissa) external returns (uint);
Allows pool administrators to set the reserve factor, which contributes a fraction of the interest into reserves.
- newReserveFactorMantissa - the new reserve factor value to be set. scaled to 18 decimals.
- returns - an error code. 0 is a success and anything else is a failure.
function _setInterestRateModel(
address newInterestRateModel
) external returns (uint);
Allows pool administrators to set a new interest rate model for this
mToken
.- newInterestRateModel - address of the new interest rate model contract
- returns - an error code. 0 is a success and anything else is a failure.
function _setNameAndSymbol(
string calldata _name,
string calldata _symbol
) external;
Allows pool administrators to change the name/symbol of this
mToken
to their desired name/symbol.Code | Name | Description |
---|---|---|
0 | NO_ERROR | Success. Not an error. |
1 | UNAUTHORIZED | The sender is not authorized to perform this action. |
2 | BAD_INPUT | An invalid argument was supplied by the caller. |
3 | COMPTROLLER_REJECTION | The comptroller rejects the action requested by the market/mToken. |
4 | COMPTROLLER_CALCULATION_ERROR | An internal calculation has failed in the comptroller. |
5 | INTEREST_RATE_MODEL_ERROR | The interest rate model returned an invalid value. |
6 | INVALID_ACCOUNT_PAIR | The specified combination of accounts is invalid. |
7 | INVALID_CLOSE_AMOUNT_REQUESTED | The amount to liquidate is invalid. |
8 | INVALID_COLLATERAL_FACTOR | The collateral factor is invalid. |
9 | MATH_ERROR | A math calculation error occurred. |
10 | MARKET_NOT_FRESH | Interest has not been properly accrued. |
11 | MARKET_NOT_LISTED | The mToken is not currently listed by its comptroller. |
12 | TOKEN_INSUFFICIENT_ALLOWANCE | ERC-20 contract must allow mToken contract to call transferFrom. The current allowance is either 0 or less than the requested supply, repayBorrow or liquidate amount. |
13 | TOKEN_INSUFFICIENT_BALANCE | Caller does not have sufficient balance in the ERC-20 contract to complete the desired action. |
14 | TOKEN_INSUFFICIENT_CASH | The mToken does not have a sufficient cash balance to complete the transaction. You may attempt this transaction again later. |
15 | TOKEN_TRANSFER_IN_FAILED | Failure in ERC-20 when transferring token into the mToken . |
16 | TOKEN_TRANSFER_OUT_FAILED | Failure in ERC-20 when transferring token out of the mToken . |
17 | UTILIZATION_ABOVE_MAX | No more of this token can be borrowed right now. |
Code | Name |
---|---|
0 | ACCEPT_ADMIN_PENDING_ADMIN_CHECK |
1 | ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED |
2 | ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED |
3 | ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED |
4 | ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED |
5 | ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED |
6 | ACCRUE_INTEREST_NEW_TOTAL_FUSE_FEES_CALCULATION_FAILED |
7 | ACCRUE_INTEREST_NEW_TOTAL_ADMIN_FEES_CALCULATION_FAILED |
8 | ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED |
9 | BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED |
10 | BORROW_ACCRUE_INTEREST_FAILED |
11 | BORROW_CASH_NOT_AVAILABLE |
12 | BORROW_FRESHNESS_CHECK |
13 | BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED |
14 | BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED |
15 | BORROW_MARKET_NOT_LISTED |
16 | BORROW_COMPTROLLER_REJECTION |
17 | LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED |
18 | LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED |
19 | LIQUIDATE_COLLATERAL_FRESHNESS_CHECK |
20 | LIQUIDATE_COMPTROLLER_REJECTION |
21 | LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED |
22 | LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX |
23 | LIQUIDATE_CLOSE_AMOUNT_IS_ZERO |
24 | LIQUIDATE_FRESHNESS_CHECK |
25 | LIQUIDATE_LIQUIDATOR_IS_BORROWER |
26 | LIQUIDATE_REPAY_BORROW_FRESH_FAILED |
27 | LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED |
28 | LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED |
29 | LIQUIDATE_SEIZE_COMPTROLLER_REJECTION |
30 | LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER |
31 | LIQUIDATE_SEIZE_TOO_MUCH |
32 | MINT_ACCRUE_INTEREST_FAILED |
33 | MINT_COMPTROLLER_REJECTION |
34 | MINT_EXCHANGE_CALCULATION_FAILED |
35 | MINT_EXCHANGE_RATE_READ_FAILED |
36 | MINT_FRESHNESS_CHECK |
37 | MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED |
38 | MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED |
39 | MINT_TRANSFER_IN_FAILED |
40 | MINT_TRANSFER_IN_NOT_POSSIBLE |
41 | NEW_UTILIZATION_RATE_ABOVE_MAX |
42 | REDEEM_ACCRUE_INTEREST_FAILED |
43 | REDEEM_COMPTROLLER_REJECTION |
44 | REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED |
45 | REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED |
46 | REDEEM_EXCHANGE_RATE_READ_FAILED |
47 | REDEEM_FRESHNESS_CHECK |
48 | REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED |
49 | REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED |
50 | REDEEM_TRANSFER_OUT_NOT_POSSIBLE |
51 | WITHDRAW_PROTOCOL_FEES_ACCRUE_INTEREST_FAILED |
52 | WITHDRAW_PROTOCOL_FEES_CASH_NOT_AVAILABLE |
53 | WITHDRAW_PROTOCOL_FEES_FRESH_CHECK |
54 | WITHDRAW_PROTOCOL_FEES_VALIDATION |
55 | WITHDRAW_ADMIN_FEES_ACCRUE_INTEREST_FAILED |
56 | WITHDRAW_ADMIN_FEES_CASH_NOT_AVAILABLE |
57 | WITHDRAW_ADMIN_FEES_FRESH_CHECK |
58 | WITHDRAW_ADMIN_FEES_VALIDATION |
59 | REDUCE_RESERVES_ACCRUE_INTEREST_FAILED |
60 | REDUCE_RESERVES_ADMIN_CHECK |
61 | REDUCE_RESERVES_CASH_NOT_AVAILABLE |
62 | REDUCE_RESERVES_FRESH_CHECK |
63 | REDUCE_RESERVES_VALIDATION |
64 | REPAY_BEHALF_ACCRUE_INTEREST_FAILED |
65 | REPAY_BORROW_ACCRUE_INTEREST_FAILED |
66 | REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED |
67 | REPAY_BORROW_COMPTROLLER_REJECTION |
68 | REPAY_BORROW_FRESHNESS_CHECK |
69 | REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED |
70 | REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED |
71 | REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE |
72 | SET_COLLATERAL_FACTOR_OWNER_CHECK |
73 | SET_COLLATERAL_FACTOR_VALIDATION |
74 | SET_COMPTROLLER_OWNER_CHECK |
75 | SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED |
76 | SET_INTEREST_RATE_MODEL_FRESH_CHECK |
77 | SET_INTEREST_RATE_MODEL_OWNER_CHECK |
78 | SET_MAX_ASSETS_OWNER_CHECK |
79 | SET_ORACLE_MARKET_NOT_LISTED |
80 | SET_ORACLE_MARKET_NOT_LISTED |
81 | SET_PENDING_ADMIN_OWNER_CHECK |
82 | SET_ADMIN_FEE_ACCRUE_INTEREST_FAILED |
83 | SET_ADMIN_FEE_ADMIN_CHECK |
84 | SET_ADMIN_FEE_FRESH_CHECK |
85 | SET_ADMIN_FEE_BOUNDS_CHECK |
86 | SET_PROTOCOL_FEE_ACCRUE_INTEREST_FAILED |
87 | SET_PROTOCOL_FEE_FRESH_CHECK |
88 | SET_PROTOCOL_FEE_BOUNDS_CHECK |
89 | SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED |
90 | SET_RESERVE_FACTOR_ADMIN_CHECK |
91 | SET_RESERVE_FACTOR_FRESH_CHECK |
92 | SET_RESERVE_FACTOR_BOUNDS_CHECK |
93 | TRANSFER_COMPTROLLER_REJECTION |
94 | TRANSFER_NOT_ALLOWED |
95 | TRANSFER_NOT_ENOUGH |
96 | TRANSFER_TOO_MUCH |
97 | ADD_RESERVES_ACCRUE_INTEREST_FAILED |
98 | ADD_RESERVES_FRESH_CHECK |
99 | ADD_RESERVES_TRANSFER_IN_NOT_POSSIBLE |
Last modified 1yr ago