Skip to content

Features and Operations

I. Basic Token Operations

Wrapping M to wM

Users can deposit $M tokens to receive an equivalent amount of wM:

wrap(recipient, amount)

The $M tokens are held by the wM contract and can potentially earn yield.

Unwrapping wM to M

Users can burn wM tokens to receive the equivalent amount of M:

unwrap(recipient, amount)

Any accrued yield remains in the user's wM balance if they're in earning mode.

Gasless Operations

The contract supports wrapping with permits for improved UX:

wrapWithPermit(recipient, amount, deadline, signature)

Standard ERC-20 Operations

All standard ERC-20 functions are supported, including:

  • transfer(to, amount)
  • transferFrom(from, to, amount)
  • approve(spender, amount)
  • balanceOf(account)

II. Earning Management

Starting to Earn

Approved accounts can activate earning status:

startEarningFor(account)

This converts their balance to a principal amount that will begin accruing yield.

Stopping Earning

Accounts can deactivate earning status (or anyone can do this for an account that's no longer approved):

stopEarningFor(account)

This claims any outstanding yield and converts the balance back to non-earning.

Global Earning Status

The wM contract itself must be an approved earner in the M token system. Earning can be enabled or disabled for the entire system:

enableEarning()
disableEarning()

A key improvement in wM v2 is the ability to re-enable earning after it has been disabled.

III. Yield Management

Claiming Yield

Accrued yield can be claimed at any time:

claimFor(account)

This increases the account's wM balance by the yielded amount and triggers appropriate transfers based on recipient settings.

Setting Claim Recipients

Users can direct their yield to another address:

setClaimRecipient(recipient)

This allows for flexible yield strategies without changing the underlying balance.

Checking Accrued Yield

Several view functions allow users and integrations to check the yield that has accrued for an earning account but has not yet been claimed:

  • accruedYieldOf(account):
    • Returns the amount of wM tokens earned as yield based on the account's earningPrincipal and the time elapsed (represented by the increase in the currentIndex) since the last claim or since earning started.
    • This represents only the unclaimed portion of the yield. It does not include yield that has already been claimed and added to the balance.
    • If the account is not in Earning Mode, this returns 0.
  • balanceWithYieldOf(account):
    • Returns the sum of the account's current stored balanceOf plus the currently claimable accruedYieldOf.
    • This function effectively shows the total wM value attributable to the account at that moment, representing what the balance would be if the accrued yield were claimed instantly (before considering any fees or alternate claim recipients).

Effect of Claiming: When claimFor(account) is successfully executed, the calculated accrued yield is processed. If the yield (net of fees) is directed to the account owner, their stored balanceOf increases. Consequently, immediately after a claim, accruedYieldOf will return 0 (or a negligible amount due to block timing), as the yield is no longer "accrued but unclaimed". balanceWithYieldOf will then equal balanceOf. New yield will start accumulating again as time passes and the currentIndex increases further.

IV. Excess Management & Value Capture

Concept: The wM contract holds underlying M tokens. Because the wM contract itself earns yield on all these M tokens, but wM yield is only accrued for earning-mode wM holders, a surplus (or "excess") of $M tokens naturally accumulates within the contract over time. This primarily comes from the M yield earned on tokens backing non-earning wM balances.

Important note:

Claiming Excess: This accumulated excess M, representing value captured by the protocol, can be claimed and transferred out using the claimExcess() function.

claimExcess() returns (uint240 claimed_)

Destination: The excessDestination address, set during deployment, receives these claimed tokens. Typically, this is the Distribution Vault, directing this value back to the protocol ecosystem and ultimately benefiting Zero token holders.

V. Admin Operations via EarnerManager

The EarnerManager contract empowers designated admins ('special users') with the delegated authority to approve wM earners, managing status for potentially many accounts outside the standard governance process

Setting Earner Status

Admins can enable accounts for earning and set fee rates:

setEarnerDetails(account, status, feeRate)

Bulk Operations

Multiple accounts can be managed in a single transaction:

setEarnerDetails(accounts[], statuses[], feeRates[])

Checking Earner Status

Various functions provide information about earner status:

earnerStatusFor(account)
getEarnerDetails(account)