This M extension is derived from MYieldToOne, an upgradeable ERC20 token contract designed to wrap $M into a non-rebasing token, where all accrued $M yield is claimable by a single designated recipient.
Additionally, MUSD includes the following functionality:
- Pausing logic.
- Ability to force transfers from frozen accounts.
- Restrictions on who can trigger claiming of yield for
claimRecipient.
M Extension Framework is a modular templates of ERC-20 stablecoin extensions that wrap the yield-bearing $M token into non-rebasing variants for improved composability within DeFi. Each extension manages yield distribution differently and integrates with a central SwapFacility contract that acts as the exclusive entry point for wrapping (swapping into extension) and unwrapping(swapping out of extension).
All contracts are deployed behind transparent upgradeable proxies (by default).
MUSD is derived from MYieldToOne.
MYieldToOne core features:
- All yield goes to a single configurable
yieldRecipient - Includes a freeze list enforced on all user actions
- Handles loss of
$Mearner status gracefully
The SwapFacility contract acts as the exclusive router for all wrapping and swapping operations involving $M and its extensions.
swap()– Switch between extensions by unwrapping and re-wrappingswapInM(),swapInMWithPermit()– Accept$Mand wrap into the selected extensionswapOutM()– Unwrap to$M(restricted to whitelisted addresses only)
All actions are subject to the rules defined by each extension (e.g., blacklists, whitelists)
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 iCopy .env.example and write down the env variables needed to run this project.
cp .env.example .envRun the following command to compile the contracts:
npm run compileForge is used for coverage, run it with:
npm run coverageYou can then consult the report by opening coverage/index.html:
open coverage/index.htmlTo run all tests:
npm testRun 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 slitherTo compile the contracts for production, run:
npm run buildMUSD is deployed via CREATE3 behind an Open Zeppelin's transparent upgradeable proxy.
Open a new terminal window and run anvil to start a local fork:
anvil --fork-url ${ETHEREUM_RPC_URL}Deploy the contracts by running:
npm run deploy-localTo deploy to the Sepolia testnet, run:
npm run deploy-sepoliaTo deploy to Linea Sepolia testnet, run:
npm run deploy-linea-sepoliaTo deploy to Ethereum Mainnet, run:
npm run deploy-mainnetTo deploy to Linea Mainnet, run:
npm run deploy-linea| Network | MUSD (Governance aware) | MUSD (Governanceless) |
|---|---|---|
| Sepolia | 0x35f35B91A16fe5b3869f4a2A9c79782DF4443316 | 0x6539fa0DfA46Ad0Fac8F7694e7521f233fa0926C |