Skip to content

m0-foundation/m-portal

Repository files navigation

M Portal

The aim of M^0 cross-chain strategy is to make $M token natively multichain, offering users the same yield-earning capabilities on different chains while maintaining $M issuance and governance on Ethereum.

M Portals are the main components of M^0 multichain model responsible for bridging tokens and propagating system information. They utilize Wormhole's NTT framework for cross-chain communication.

Architecture

Since both governance and issuance of new $M tokens are done exclusively on Ethereum, the M^0 multichain model employs different implementations of the Portal contract on different chains. On Ethereum, HubPortal uses a lock-and-release mechanism for token transfers and enables the propagation of $M earning index and TTG registrar values to other chains. Conversely, SpokePortal, deployed on all other chains, follows a mint-and-burn model for bridging tokens and is responsible for updating $M earning index and TTG registrar values based on messages received from HubPortal.

Both HubPortal and SpokePortal inherit Wormhole's NttManager contract that encapsules all the necessary cross-chain messaging functionality.

M Token Transfer

When a user transfers tokens from the Hub chain to a Spoke chain, the tokens are locked in the HubPortal, and a cross-chain message is sent to the Spoke chain via WormholeTransceiver. Upon receiving the message, an equivalent number of tokens is minted on the Spoke chain and transferred to the user. Similarly, when transferring M tokens from a Spoke chain back to the Hub, the tokens are burned on the Spoke chain, and an equivalent number of tokens is released on the Hub chain. Bridging $M tokens between Spoke chains involves minting and burning operations on both chains, without affecting the total number of $M tokens locked in HubPortal.

Earning Index Propagation

$M is a yield-bearing token with built-in earning functionality for a selected set of earners approved by TTG. The maximum earner rate is determined through TTG governance, while an additional safe earner rate is automatically derived based on the total active owed $M and the total earning supply.

This safe rate is calculated in EarnerRateModel contract on Ethereum. The $M index represents the accrual of this rate to all earners in the system. Propagating the earner rate is essential for accurate yield distribution across the M^0 Protocol on Ethereum and other chains.

There are two ways to update the $M earning index on a Spoke chain:

  • Perform a cross-chain transfer from the Hub chain.
  • Explicitly call sendMTokenIndex function in HubPortal.

TTG Registrar Values Propagation

M^0 system parameters approved by the governance are stored in Registrar contract on Ethereum. HubPortal propagates those parameters to Spoke chains.

Development

Installation

You may have to install the following tools to use this repository:

  • Foundry to compile and test contracts
  • lcov to generate the code coverage report
  • slither to static analyze contracts

Install dependencies:

npm install
forge install

Env

Copy .env and write down the env variables needed to run this project.

cp .env.example .env

Compile

Run the following command to compile the contracts:

npm run compile

Coverage

Forge is used for coverage, run it with:

npm run coverage

You can then consult the report by opening coverage/index.html:

open coverage/index.html

Test

To run all tests:

npm test

Run test that matches a test contract:

forge test --mc <test-contract-name>

Test a specific test case:

forge test --mt <test-case-name>

To run slither:

npm run slither

Code quality

Husky is used to run lint-staged and tests when committing.

Prettier is used to format code. Use it by running:

npm run prettier

Solhint is used to lint Solidity files. Run it with:

npm run solhint

To fix solhint errors, run:

npm run solhint-fix

Documentation

The documentation can be generated by running:

npm run doc

It will run a server on port 4000, you can then access the documentation by opening http://localhost:4000.

Deployment

Build

To compile the contracts for production, run:

npm run build

Deploy

Local

Open a new terminal window and run anvil to start a local chain:

anvil

Deploy the contracts by running:

npm run deploy-local

Sepolia

To deploy to the Sepolia testnet, run:

npm run deploy-sepolia

About

M^0 ecosystem EVM bridging components

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •