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
$M
earner 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$M
and 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 i
Copy .env.example
and write down the env variables needed to run this project.
cp .env.example .env
Run the following command to compile the contracts:
npm run compile
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
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
To compile the contracts for production, run:
npm run build
MUSD 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-local
To deploy to the Sepolia testnet, run:
npm run deploy-sepolia
To deploy to Linea Sepolia testnet, run:
npm run deploy-linea-sepolia
To deploy to Ethereum Mainnet, run:
npm run deploy-mainnet
To deploy to Linea Mainnet, run:
npm run deploy-linea
Network | Implementation | Proxy | Proxy Admin |
---|---|---|---|
-- | |||
Ethereum | 0x37A309611E1d278cDdC341E479957Ec8Bc6256CE | 0xacA92E438df0B2401fF60dA7E4337B687a2435DA | 0x685E7F8C9414bfa716b254b349153e2317929ac9 |
Linea | 0x58a3A9C561591bab0dd11110EcA755EA455f1841 | 0xacA92E438df0B2401fF60dA7E4337B687a2435DA | 0x685E7F8C9414bfa716b254b349153e2317929ac9 |
Network | MUSD (Governance aware) | MUSD (Governanceless) |
---|---|---|
Sepolia | 0x35f35B91A16fe5b3869f4a2A9c79782DF4443316 | 0x6539fa0DfA46Ad0Fac8F7694e7521f233fa0926C |