Technical Specifications

M Token Specification

Low-level technical specification for the M token - function signatures, events, errors, and storage layout.

Contract overview

The MToken contract is an immutable ERC20-compliant token with a dual-balance accounting system. It implements continuous compounding for earning accounts via a global index mechanism.

  • Decimals: 6
  • Index precision: 12 decimal places (scaled by 1e12)
  • Inherits: ContinuousIndexing, ERC20, EIP-2612, EIP-3009

Key functions

ERC20 Standard

FunctionDescription
transfer(address to, uint256 amount)Transfer tokens to an address
transferFrom(address from, address to, uint256 amount)Transfer tokens on behalf of another address
approve(address spender, uint256 amount)Approve a spender allowance
balanceOf(address account)Returns current balance including accrued interest for earners
totalSupply()Returns totalEarningSupply() + totalNonEarningSupply()

EIP-2612 Permit

FunctionDescription
permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)Gasless approval via signature

EIP-3009 Transfer with Authorization

FunctionDescription
transferWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s)Transfer via signed authorization
receiveWithAuthorization(address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s)Receive via signed authorization

Earning Management

FunctionDescription
startEarning()Convert caller's balance to earning mode (must be approved earner)
stopEarning()Convert caller's balance back to non-earning mode
stopEarning(address account_)Force-stop earning for an account no longer on the approved list

Balance Queries

FunctionReturns
balanceOf(address account)Current balance (including accrued interest for earners)
principalBalanceOf(address account)Underlying principal for earning accounts (0 for non-earners)
isEarning(address account)Whether the account is in earning mode
totalEarningSupply()Total tokens in earning balances (present value)
totalNonEarningSupply()Total tokens in non-earning balances

Index Management

FunctionDescription
updateIndex()Update the global earning index; called by MinterGateway and internally
currentIndex()Returns the current index value (on-demand calculation)
latestIndexLast stored index value (uint128)
latestUpdateTimestampTimestamp of last index update (uint40)

Supply Control (MinterGateway only)

FunctionDescription
mint(address recipient, uint240 amount)Mint tokens to an address
burn(address account, uint240 amount)Burn tokens from an address

Events

EventDescription
Transfer(address indexed from, address indexed to, uint256 value)Standard ERC20 transfer
Approval(address indexed owner, address indexed spender, uint256 value)Standard ERC20 approval
StartedEarning(address indexed account)Account entered earning mode
StoppedEarning(address indexed account)Account exited earning mode

Errors

ErrorCondition
NotApprovedEarner()Account is not on the approved earners list
IsApprovedEarner()Attempted to force-stop an account that is still approved
NotMinterGateway()Caller is not the MinterGateway
InsufficientBalance(address account, uint256 balance, uint256 amount)Transfer or burn exceeds balance

Continuous compounding formula

The global index grows via continuous compounding:

newIndex=oldIndex×e(rate×timeElapsed/SECONDS_PER_YEAR)\text{newIndex} = \text{oldIndex} \times e^{(\text{rate} \times \text{timeElapsed} / \text{SECONDS\_PER\_YEAR})}

The e^x function uses a Padé approximant R(4,4):

e(x)1+x2+3x228+x384+x416801x2+3x228x384+x41680e(x) \approx \frac{1 + \frac{x}{2} + \frac{3x^2}{28} + \frac{x^3}{84} + \frac{x^4}{1680}}{1 - \frac{x}{2} + \frac{3x^2}{28} - \frac{x^3}{84} + \frac{x^4}{1680}}

Rounding rules

OperationRoundingProtocol favored
Start earning (present → principal)DownYes
Stop earning (principal → present)DownYes
Earner-to-earner transfer (sender)UpYes
Non-earner-to-earner transfer (receiver)DownYes
Mint to earnerDownYes
Burn from earnerUpYes

Copyright © M0 Foundation 2026