PYUSDx Quick Guide
Launching a custom token requires a set of decisions, one deploy transaction, and a handoff to M0. M0 operates the shared layer and enables yield for your token. This page maps the full sequence so you can scope the work. For the commands, see the deployment guide.
Before you begin
You need the following:
- A deployer wallet with gas on each target chain. Start on Ethereum Sepolia.
- An admin address, preferably a multisig, to hold
DEFAULT_ADMIN_ROLEon your token, and addresses for the operational roles in step 2. On testnet, one wallet can hold every role. - A treasury address to receive yield.
- Testnet PYUSDx; faucets are deployed on Ethereum Sepolia and Arbitrum Sepolia. Addresses are on the deployments page.
- An initial call with M0. Contact M0 before you deploy.
Launch sequence
| # | Step | Owner | Description | Result |
|---|---|---|---|---|
| 1 | Scope with M0 | You and M0 | Confirm the template, chains, timeline, and yield enablement | Completed decisions table |
| 2 | Assign roles | You | Choose an address for each role on your token | Role assignments |
| 3 | Deploy on testnet | You (M0 can assist) | One call to ExtensionFactory on Ethereum Sepolia | Token address |
| 4 | Test your token | You | Wrap, unwrap, bridge, freeze, and pause | Test checklist complete |
| 5 | Share the address | You | Send your token address and chain to M0 | Handoff complete |
| 6 | M0 enables yield | M0 | M0 registers your token as an earner on PYUSDx | Yield accruing |
| 7 | Deploy on mainnet | You (M0 can assist) | Repeat steps 3, 5, and 6 on each target chain | Token live |
| 8 | Operate your token | You | Claim yield, manage roles, apply controls, manage upgrades | Ongoing |
1. Scope with M0
A short set of decisions defines your token.
| Decision | Options | Notes |
|---|---|---|
| Template | YieldToOne or MultiMint | YieldToOne routes all yield to one treasury. M0 recommends it for most partners. MultiMint adds approved alternative stablecoins as backing under per-asset caps and adds one more role. Fixed at deployment. |
| Name and symbol | Your brand | For example, "Acme Yield USD" and ayUSD. Fixed at deployment. Distinct from the deployment name in step 3. |
| Yield recipient | A treasury address | Where claimed yield is minted. YIELD_RECIPIENT_MANAGER_ROLE can change it later. |
| Role holders | One address per role | See step 2. DEFAULT_ADMIN_ROLE can change them later. |
| Chains | One or more supported chains | Ethereum, Arbitrum, and Monad. Start with one chain and add more later. Reusing the same deployer and deployment name produces the same address on each chain. |
| Compliance policy | Your policy | How and when you apply freeze and pause, and how you coordinate with M0 on forced transfers. |
Fixed at deployment: template, name, and symbol.
Changeable later: yield recipient, role holders, and the set of chains.
2. Assign roles
Each role on your token is independent. On testnet, assign one wallet to every role. For mainnet, separate them based on which wallets own each role.
| Role | Permissions | Suggested holder |
|---|---|---|
DEFAULT_ADMIN_ROLE | Grants and revokes every other role | Multisig |
YIELD_RECIPIENT_MANAGER_ROLE | Calls claimYield and sets the yield recipient | Treasury operations |
FREEZE_MANAGER_ROLE | Freezes and unfreezes accounts on your token | Compliance |
PAUSER_ROLE | Pauses and unpauses transfers on your token | Incident response |
VERSION_MANAGER_ROLE | Pins your token to a specific implementation version, or unpins it | Engineering |
ASSET_CAP_MANAGER_ROLE (MultiMint only) | Sets per-asset caps and manages the replaceAsset caller allowlist | Treasury operations |
3. Deploy on testnet
Call deployYieldToOne(extensionName, params) or deployMultiMint(extensionName, params) on ExtensionFactory. In one transaction, the factory resolves the latest audited implementation from the template's beacon, deploys your proxy at a deterministic address, registers it, and emits ExtensionDeployed. You can deploy from a block explorer without local tooling, or with a script. The deployment guide covers both methods.
extensionName and name are different parameters. extensionName determines your token's address. It must be unique per deployer per network, and reusing it from the same deployer on another network produces the same address there. name and symbol in params are the ERC-20 fields that users see.4. Test your token
Complete these checks on Ethereum Sepolia before you ask M0 to enable yield:
- Wrap testnet PYUSDx into your token with
SwapFacility.swapInand confirm that the amounts match 1:1. - Unwrap with
swapOutand confirm that the full PYUSDx amount is returned. - Bridge a test amount with
Portalto Arbitrum Sepolia or Monad Testnet. Both are peered with Ethereum Sepolia. - Freeze a test account, confirm that its transfers revert, and unfreeze it.
- Pause your token, confirm that transfers revert, and unpause it.
- After step 6, call
claimYieldand confirm that new tokens are minted to your yield recipient.
5. Share the address
Send M0 your deployed token address and the chain it is deployed on.
6. M0 enables yield
M0 registers your token contract as an earner on PYUSDx. From that point, the PYUSDx that your contract holds accrues yield continuously, and your yield manager can claim it with claimYield. Before this step, your token supports wrapping, swapping, and bridging but doesn't accrue yield. Yield enablement is per chain. Repeat steps 5 and 6 for each network you deploy to.
7. Deploy on mainnet
Repeat step 3 on each target chain, followed by steps 5 and 6. On mainnet, every supported chain is peered with every other supported chain, so bridging works on every route as soon as your token is deployed on both ends.
8. Operate your token
- Yield. Call
claimYieldon a schedule that fits your treasury operations. Each call mints the accrued yield to your yield recipient. Yield never accrues to holders. To change the recipient, callsetYieldRecipient. - Compliance. Apply freeze and pause according to your policy.
claimYieldsucceeds while your token is paused, but the minted tokens can't transfer until you unpause. - Upgrades. M0 publishes new audited implementations to the template beacon. By default, your token follows the latest version automatically. Call
pinVersionto stay on a specific version andunpinVersionto follow the latest version again. - Cross-chain. No action is required. If a bridge recipient is frozen on PYUSDx,
Portalroutes the funds to M0's fallback recipient instead of failing. - MultiMint only. Manage backing assets with
setAssetCap. A cap of zero disables new deposits of that asset. Existing balances remain unwrappable to PYUSDx.
Responsibilities
| M0 operates | You control |
|---|---|
| The PYUSDx base token and its issuance | Every role on your token |
SwapFacility and shared liquidity | When yield is claimed and where it goes |
Portal and its bridge adapters | How freeze and pause are applied under your policy |
| The audited template implementations and their upgrades | Whether your token follows upgrades automatically or pins a version |
| Yield enablement for your token | Backing assets and caps (MultiMint only) |
You don't manage reserves, run swap infrastructure, or operate a bridge.