Skip to content

Core Concepts

I. Dual Mode: Earning vs. Non-Earning

The wM token operates in two distinct modes for each account:

A. Non-Earning Mode

  • Default state for new accounts
  • Balances remain static (standard ERC-20 behavior)
  • No yield accrues on these tokens
  • Simpler accounting with direct token amounts

B. Earning Mode

  • Must be explicitly activated (requires approval via Governance or EarnerManager admin designation)
  • Balances remain static in storage
  • Represents a growing value based on a principal amount and an index, using an accounting model analogous to the native M token.
  • Crucially, the index used is derived from the underlying M token (wM does not maintain its own independent index).
  • Yield accumulates based on this principal and derived index, and can be claimed separately.

Users can switch between Non-Earning and Earning modes if they meet the requirements for earning.

II. Account Status

Each wM account maintains several key properties tracked internally within the WrappedMToken contract:

  • Balance: The current wM token balance held by the account. This value remains static between operations and excludes any unclaimed yield.
  • Earning Status: A boolean flag indicating whether the account is currently in Earning Mode (true) or Non-Earning Mode (false).
  • Earning Principal: For accounts in Earning Mode, this stores the base principal amount used for yield calculations. This value is derived from the account's balance when it starts earning and remains constant while earning.
  • Claim Recipient: An optional address specified by the user via setClaimRecipient() to receive their claimed yield. If not set by the user, and no Governance override exists, yield is sent to the account owner itself. [//]: # "TODO add link"
  • Earner Details: A boolean flag indicating if settings apply when an account's earning status is managed by an EarnerManager admin.
    • If true, it implies the EarnerManager contract holds details (managing admin address, fee rate) for this account.
    • When a fee rate is set by the admin, a portion of the claimed yield (calculated as yield * feeRate / 10000) is sent to that admin upon claiming, and the remaining net yield goes to the designated claim recipient (user-set, governance-set, or default owner).
Principal, Balance, and Yield Relationship:

When an account enters Earning Mode (startEarningFor), its current balance is converted into its initial earningPrincipal.

This conversion is performed by the IndexingMath.getPrincipalAmountRoundedDown(balance, currentIndex) function, which calculates the principal amount corresponding to the balance at the currentIndex, taking into account the system's fixed-point scaling for the index and applying rounding rules that slightly favor the protocol.

This earningPrincipal remains fixed while the account continues in Earning Mode. As the global currentIndex (derived from the M token's index) increases over time, the value represented by this fixed principal grows.

The fundamental relationship is:

Value Represented=earningPrincipal×currentIndex\text{Value Represented} = \text{earningPrincipal} \times \text{currentIndex}

The account's stored balance only increases when yield is explicitly claimed. Therefore, the accruedYield represents the difference between the current value represented by the principal and the static stored balance:

accruedYield=earningPrincipal×currentIndexbalance\text{accruedYield} = \text{earningPrincipal}\times\text{currentIndex}-\text{balance}

So, the target state before claiming is effectively:

balance+accruedYieldearningPrincipal×currentIndex\text{balance} + \text{accruedYield}≈\text{earningPrincipal}\times\text{currentIndex}

Calling the claimFor() function calculates this accruedYield. It then handles potential fee deductions if hasEarnerDetails is true (sending the fee portion to the managing admin). The remaining net yield is transferred to the designated claimRecipient. If the claimRecipient is the account owner itself, their stored balance is increased by this net yield amount. This operation "catches up" the account's stored balance to reflect the value earned up to that point (minus any fees paid).

III. Yield Generation and Claiming

How Yield Accrues

For accounts in earning mode, yield accrues based on:

  • The account's principal amount
  • The global wM index (derived from the M token's index)
  • The time elapsed since the last index update

The formula is:

accruedYield=(principal×currentIndex)balanceaccruedYield=(principal\times currentIndex) - balance

Where:

  • principal is the stored earning principal for the account
  • currentIndex is the current wM index
  • balance is the current token balance

Claiming Process

When yield is claimed:

  1. The accrued yield is calculated based on the current index
  2. The account's balance is provisionally increased by the full yield amount
  3. If the account's earning status is managed by an active EarnerManager admin with a configured fee rate, a percentage of the yield is deducted and sent to that admin as a fee
  4. The remaining yield (minus any fees) is transferred to the designated recipient (or remains with the account owner if they are the recipient)

Claiming doesn't change the principal amount, only the final balance reflects the net yield received

IV. Index Mechanism

Rather than maintaining its own independent index, wM derives its index from the M token's index:

When Earning is Enabled

The wM index is calculated as:

wMindex=(Mcurrentindex / enableMIndex)×disableIndexwM_{index} = (M_{current index} \text{ }/ \text{ }enableMIndex) \times disableIndex

Where:

  • M current index is the current index from the M token
  • enableMIndex is the M index when earning was enabled
  • disableIndex is the previous wM index (if earning was previously disabled)

When Earning is Disabled

The wM index becomes static:

wMindex=disableIndexwM_{index} = disableIndex

This approach ensures that wM's yield calculation accurately reflects the underlying M token's yield performance.

V. Yield Recipients

The wM system provides flexible options for directing claimed yield:

Default Behavior

By default, yield is claimed to the same account that generated it.

Custom Recipients

Account holders can specify a different address to receive their yield by calling setClaimRecipient().

Governance Overrides

The TTG governance can set override recipients for specific accounts through the Registrar.

Priority Order

When determining where to send claimed yield:

  1. User-specified recipient (if set)
  2. Governance-specified override (if set)
  3. The account itself (default)

This flexibility allows for a variety of yield utilization strategies.

VI. System Invariants and Excess

The wM system is designed around a critical solvency invariant to ensure it's always fully backed by the underlying M token.

Balance Invariant: The total M token balance held by the WrappedMToken contract must always be greater than or equal to the sum of all wM tokens in circulation plus all accrued yield owed to earners.

Expressed conceptually:

M Balance(wM contract)Total wM Supply+Total Accrued Yield\text{M Balance}_{(\text{wM contract})} \ge \text{Total wM Supply} + \text{Total Accrued Yield}

Expressed using contract variables:

M Balance(wM contract)totalNonEarningSupply+projectedEarningSupplyTotal wM Liabilities\text{M Balance}_{(\text{wM contract})} \ge \underbrace{\text{totalNonEarningSupply} + \text{projectedEarningSupply}}_{\text{Total wM Liabilities}} How the Invariant is Maintained:

Crucially, the M Balance held by the WrappedMToken contract is not static. Since the WrappedMToken contract itself is registered as an M earner (as shown in the M dashboard where the wM contract is the largest holder), the underlying $M tokens it holds continuously accrue yield according to the M token's rebasing mechanism.

This intrinsic yield generation on the entire pool of $M tokens held within the wM contract is fundamental to maintaining the solvency invariant. It ensures the M balance grows naturally over time, actively keeping assets (M held) ahead of liabilities (wM supply + accrued yield).

Excess Reserves:

The difference between the actual M Balance held by the contract and the total calculated liabilities (totalNonEarningSupply + projectedEarningSupply) constitutes the "excess" reserves within the system. This excess primarily accumulates from two sources explained further below:

  1. The yield generated by the underlying $M tokens that back the balances of non-earning wM holders (as this yield isn't owed back to them).
  2. Minor positive rounding effects during various token operations (transfers, wrapping/unwrapping, starting/stopping earning).

This invariant and the resulting excess ensure that the system remains fully solvent, can always honor unwrap requests, and captures additional value for the protocol ecosystem.