$M on Solana is a Token-2022 mint whose yield accrues automatically through the
ScaledUiAmount
multiplier. The earn program receives the $M index from Ethereum (via the Portal) and raises
the multiplier accordingly — there are no discrete claim cycles for base $M. Holding $M is
permissioned: token accounts are frozen by default, and only approved earners (extensions and
other governance-approved actors) are thawed.
| Path | Contents |
|---|---|
programs/earn/ |
The only on-chain program in this repo: earner registry + index/multiplier updates |
sdk/ |
TypeScript SDK, published as @m0-foundation/solana-m-sdk |
services/ |
Off-chain services: index-bot, yield-bot, cli, switchboard, shared |
substreams/ |
Substreams indexing $M transfer events into MongoDB |
tests/ |
Jest + LiteSVM integration tests |
audits/ |
Audit reports |
Related repos: the Portal program lives in
solana-portal; $M extensions (wM and
others, including the ext_swap program) live in
solana-m-extensions.
- The $M index grows continuously on Ethereum (M protocol).
index-botcalls the hub executor entry point on Ethereum, which delivers the index (and earner merkle root) to Solana through the Wormhole Executor.- The Portal program receives the message and calls
earn.propagate_index(index, earner_merkle_root). earnraises the mint's ScaledUiAmount multiplier (multiplier = index / 1e12) and stores the earner merkle root. Every thawed $M holder's UI balance grows with the multiplier.yield-botseparately cranks yield distribution for extension tokens (wM, USDKY) whose programs live insolana-m-extensions.
See programs/earn/README.md for program internals.
- Rust ≥ 1.75
- Solana CLI v2.1.0
- Anchor CLI 0.31.1
- Node.js 22, pnpm ≥ 10
- 1Password CLI (
op) — only formake/pnpmcommands that read team secrets - Docker — only for service/substream deployment
pnpm install
anchor buildTest fixtures must be built once before running the tests. The fixture build moves the
regular build artifacts, so re-run anchor build afterwards (same order as CI):
make build-test-earn-programs # builds earn with `testing` and `migrate,testing` features
anchor build -p earn # restores target/{deploy,idl,types}/earn.* used by the testsmake test-earn # earn program (LiteSVM)
make test-sdk # SDK (rebuilds sdk first)
make test-yield-bot # yield-bot integration
make test-merkle # merkle proof logicRun a single file with cd tests && pnpm jest --preset ts-jest tests/unit/<file>.test.ts.
make build-test-swap-program refreshes the ext_swap test fixture and requires a sibling
checkout of solana-m-extensions at ../solana-extensions.
pnpm lint # check
pnpm lint:fix # writeAudited by Asymmetric Research, Sec3, OtterSec, and Halborn — reports in audits/.
Security policy: SECURITY.md.