Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions .claude/skills/choose-extension/COMPARISON.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# M Extension Comparison

Detailed comparison of all M extension types to help you make an informed decision.

## Feature Matrix

| Feature | MYieldToOne | MYieldToOneForcedTransfer | MYieldFee | MSpokeYieldFee | MEarnerManager | JMIExtension |
|---------|:-----------:|:-------------------------:|:---------:|:--------------:|:--------------:|:------------:|
| **Yield Model** | Single | Single | All holders | All holders | Whitelisted | Single |
| **Freezable accounts** | Yes | Yes | Yes | Yes | No | Yes |
| **Pausable** | Yes | Yes | Yes | Yes | Yes | Yes |
| **Forced transfers** | No | Yes | No | No | No | No |
| **Whitelist required** | No | No | No | No | Yes | No |
| **Per-address fee rates** | No | No | No | No | Yes | No |
| **Global fee rate** | No | No | Yes | Yes | No | No |
| **Custom claim recipients** | No | No | Yes | Yes | No | No |
| **Multi-asset collateral** | No | No | No | No | No | Yes |
| **L2 compatible** | Yes | Yes | L1 only | L2 only | Yes | Yes |

## Yield Models Explained

### Single Recipient (Treasury Model)
All yield accumulates and is claimable by a single designated address. Best for protocols where yield should flow to a treasury, DAO, or specific entity.

**Yield calculation:** `yield = M_balance - totalSupply`

**Extensions:** MYieldToOne, MYieldToOneForcedTransfer, JMIExtension

### All Holders (User Yield Model)
Every token holder earns yield proportionally to their balance. A global fee percentage can be deducted from all yield.

**Yield calculation:** Uses continuous index-based accrual with adjustable fee rate.

**Extensions:** MYieldFee (L1), MSpokeYieldFee (L2)

### Whitelisted Holders (Institutional Model)
Only approved addresses can hold tokens. Each address can have a custom fee rate, enabling tiered arrangements.

**Yield calculation:** Per-account principal tracking with individual fee deductions.

**Extensions:** MEarnerManager

## Role Requirements

### MYieldToOne
| Role | Purpose |
|------|---------|
| `DEFAULT_ADMIN_ROLE` | Grant/revoke other roles |
| `YIELD_RECIPIENT_MANAGER_ROLE` | Change yield recipient address |
| `FREEZE_MANAGER_ROLE` | Freeze/unfreeze accounts |
| `PAUSER_ROLE` | Pause/unpause contract |

### MYieldToOneForcedTransfer
All MYieldToOne roles plus:
| Role | Purpose |
|------|---------|
| `FORCED_TRANSFER_MANAGER_ROLE` | Transfer tokens from frozen accounts |

### MYieldFee / MSpokeYieldFee
| Role | Purpose |
|------|---------|
| `DEFAULT_ADMIN_ROLE` | Grant/revoke other roles |
| `FEE_MANAGER_ROLE` | Set fee rate and fee recipient |
| `CLAIM_RECIPIENT_MANAGER_ROLE` | Set custom claim recipients per account |
| `FREEZE_MANAGER_ROLE` | Freeze/unfreeze accounts |
| `PAUSER_ROLE` | Pause/unpause contract |

### MEarnerManager
| Role | Purpose |
|------|---------|
| `DEFAULT_ADMIN_ROLE` | Grant/revoke other roles |
| `EARNER_MANAGER_ROLE` | Whitelist accounts, set fee rates, manage fee recipient |
| `PAUSER_ROLE` | Pause/unpause contract |

### JMIExtension
All MYieldToOne roles plus:
| Role | Purpose |
|------|---------|
| `ASSET_CAP_MANAGER_ROLE` | Set caps for non-M collateral assets |

## Storage Patterns

All extensions use ERC-7201 namespaced storage for upgrade safety.

### Per-Account Storage
- **MYieldToOne/MYieldToOneForcedTransfer:** Balance, frozen status
- **MYieldFee/MSpokeYieldFee:** Balance, principal, custom claim recipient, frozen status
- **MEarnerManager:** Balance, principal, whitelisted status, fee rate
- **JMIExtension:** Balance, frozen status

### Global Storage
- **MYieldToOne/MYieldToOneForcedTransfer:** Total supply, yield recipient
- **MYieldFee/MSpokeYieldFee:** Total supply, total principal, fee rate, fee recipient, latest index
- **MEarnerManager:** Total supply, total principal, fee recipient, earning enabled flag
- **JMIExtension:** Total supply, yield recipient, per-asset caps and balances, total assets

## Gas Considerations

| Operation | Lower Gas | Higher Gas | Notes |
|-----------|-----------|------------|-------|
| Transfer | MYieldToOne | MEarnerManager | Whitelist checks add overhead |
| Wrap | MYieldToOne | JMIExtension | Multi-asset logic adds cost |
| Claim yield | MYieldToOne | MYieldFee | Index updates more complex |

## Upgrade Paths

All extensions deploy behind TransparentUpgradeableProxy, allowing:
- Bug fixes without redeployment
- Feature additions (with care for storage layout)
- Role/parameter adjustments via admin functions

**Important:** Changing yield models (e.g., MYieldToOne to MYieldFee) requires migration to a new contract.

## Chain Deployment Guide

| Chain Type | Recommended Extensions |
|------------|----------------------|
| Ethereum Mainnet | MYieldToOne, MYieldToOneForcedTransfer, MYieldFee, MEarnerManager, JMIExtension |
| Arbitrum | MSpokeYieldFee, MYieldToOne, MEarnerManager, JMIExtension |
| Optimism | MSpokeYieldFee, MYieldToOne, MEarnerManager, JMIExtension |
| Base | MSpokeYieldFee, MYieldToOne, MEarnerManager, JMIExtension |
| Other L2s | Check if Rate Oracle is available for MSpokeYieldFee |
155 changes: 155 additions & 0 deletions .claude/skills/choose-extension/EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# M Extension Use Case Examples

Real-world scenarios to help you identify which extension fits your needs.

## Example 1: Protocol Treasury

**Scenario:** A DeFi protocol wants to wrap M tokens for use in their ecosystem. All yield should go to the protocol treasury to fund development.

**Requirements:**
- Single yield recipient (treasury multisig)
- Open access (anyone can hold tokens)
- No special compliance needs

**Recommendation:** `MYieldToOne`

**Why:** Simplest model for treasury yield collection. Anyone can call `claimYield()` to mint accumulated yield to the designated recipient.

**Configuration:**
```solidity
yieldRecipient = 0x...treasury_multisig
```

---

## Example 2: Regulated Stablecoin

**Scenario:** A regulated financial institution issuing a compliant stablecoin needs the ability to freeze accounts and recover funds from sanctioned addresses.

**Requirements:**
- Single yield recipient
- Account freezing for sanctions compliance
- Ability to recover funds from frozen accounts
- OFAC compliance

**Recommendation:** `MYieldToOneForcedTransfer`

**Why:** Provides all MYieldToOne features plus forced transfer capability for regulatory compliance. Can seize tokens from frozen accounts when legally required.

**Configuration:**
```solidity
yieldRecipient = 0x...compliance_treasury
freezeManager = 0x...compliance_team
forcedTransferManager = 0x...legal_team
```

---

## Example 3: Yield-Bearing Stablecoin for DeFi

**Scenario:** A DeFi protocol wants to offer a yield-bearing stablecoin where all holders automatically earn yield. The protocol takes a 10% fee on yield.

**Requirements:**
- All holders earn yield
- Protocol fee on yield
- Deploying on Ethereum mainnet

**Recommendation:** `MYieldFee`

**Why:** Automatically distributes yield to all holders with a configurable global fee. No claiming required by users - balances grow automatically.

**Configuration:**
```solidity
feeRate = 1000 // 10% (in basis points)
feeRecipient = 0x...protocol_treasury
```

---

## Example 4: L2 Yield Token

**Scenario:** Same as Example 3, but deploying on Arbitrum to reduce gas costs for users.

**Requirements:**
- All holders earn yield
- Protocol fee on yield
- Deploying on Arbitrum

**Recommendation:** `MSpokeYieldFee`

**Why:** Same functionality as MYieldFee but designed for L2 chains. Uses bridged index updates from L1 instead of real-time calculation.

**Configuration:**
```solidity
feeRate = 1000 // 10%
feeRecipient = 0x...protocol_treasury
rateOracle = 0x...arbitrum_rate_oracle
```

---

## Example 5: Institutional Platform

**Scenario:** A fintech company serving multiple institutional clients. Each client has a different fee arrangement based on their AUM. Only approved institutions can hold tokens.

**Requirements:**
- Whitelist-based access
- Different fee rates per client
- KYC/AML compliance (only approved entities)

**Recommendation:** `MEarnerManager`

**Why:** Provides granular control over who can hold tokens and individual fee rates per account. Perfect for B2B platforms with tiered client arrangements.

**Configuration:**
```solidity
// Whitelist institution A with 5% fee
setAccountInfo(institutionA, true, 500)

// Whitelist institution B with 2% fee (VIP rate)
setAccountInfo(institutionB, true, 200)

feeRecipient = 0x...platform_treasury
```

---

## Example 6: Multi-Collateral Stablecoin

**Scenario:** A protocol wants to bootstrap liquidity by accepting multiple stablecoins (USDC, DAI, USDT) as collateral in addition to M. Yield from M backing goes to the treasury.

**Requirements:**
- Single yield recipient
- Accept multiple collateral types
- 1:1 peg between all accepted assets
- Caps on non-M collateral

**Recommendation:** `JMIExtension`

**Why:** "Just Mint It" model allows users to deposit M or any approved stablecoin to mint tokens. Simplifies onboarding for users who don't yet hold M.

**Configuration:**
```solidity
yieldRecipient = 0x...treasury

// Allow USDC with 10M cap
setAssetCap(USDC, 10_000_000e6)

// Allow DAI with 5M cap
setAssetCap(DAI, 5_000_000e18)
```

**Important Note:** Yield only accrues on the M portion of backing. Non-M collateral should be periodically swapped to M using `replaceAssetWithM()` to maximize yield.

---

## Decision Summary

| If you need... | Choose... |
|----------------|-----------|
| Simple treasury yield | MYieldToOne |
| Treasury yield + compliance | MYieldToOneForcedTransfer |
| Yield for all holders (L1) | MYieldFee |
| Yield for all holders (L2) | MSpokeYieldFee |
| Per-client fee arrangements | MEarnerManager |
| Multiple collateral types | JMIExtension |
84 changes: 84 additions & 0 deletions .claude/skills/choose-extension/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
name: choose-extension
description: Helps developers choose the right M extension type for their use case. Use when someone asks which extension to use, wants to evaluate extension options, needs help deciding between MYieldToOne, MYieldFee, MEarnerManager, or other M extension types, or mentions "choose extension", "which extension", "extension for my use case".
---

# Choose Extension

Help developers select the appropriate M extension type through an interactive decision process.

## Instructions

When this skill is invoked, guide the developer through selecting the right M extension by asking questions about their requirements. Use the `AskUserQuestion` tool to ask questions step by step.

### Step 1: Yield Distribution Model

First, ask about yield distribution:

**Question:** "How should yield from the wrapped M tokens be distributed?"

**Options:**
1. **Single recipient** - All yield goes to one address (treasury, DAO, protocol)
2. **All token holders** - Every holder earns yield proportionally
3. **Whitelisted holders only** - Only approved addresses can hold tokens and earn yield

### Step 2: Follow-up Questions

Based on the answer to Step 1, ask relevant follow-up questions:

#### If "Single recipient":

Ask: "Do you need compliance features like forced transfers to recover tokens from frozen/sanctioned accounts?"

- **Yes, need forced transfers** - Ask about multi-asset collateral next
- **No forced transfers needed** - Ask about multi-asset collateral next

Then ask: "Do you need to accept multiple collateral types (e.g., USDC, DAI) in addition to M?"

- **Yes, multi-asset** - Recommend **JMIExtension**
- **No, M only** - If forced transfers needed: **MYieldToOneForcedTransfer**, otherwise: **MYieldToOne**

#### If "All token holders":

Ask: "Which chain are you deploying on?"

- **Ethereum mainnet (L1)** - Recommend **MYieldFee**
- **Layer 2 (Arbitrum, Optimism, Base, etc.)** - Recommend **MSpokeYieldFee**

#### If "Whitelisted holders only":

No further questions needed. Recommend **MEarnerManager**.

### Step 3: Provide Recommendation

After determining the appropriate extension, provide:

1. **The recommended extension** with a brief explanation
2. **Key features** of the recommended extension
3. **Required roles** to configure after deployment
4. **Link to the source file** for reference

### Extension Quick Reference

| Extension | Yield Model | Key Feature |
|-----------|-------------|-------------|
| `MYieldToOne` | Single recipient | Simple treasury model |
| `MYieldToOneForcedTransfer` | Single recipient | + Compliance/recovery |
| `MYieldFee` | All holders | Global fee, L1 |
| `MSpokeYieldFee` | All holders | Global fee, L2 |
| `MEarnerManager` | Whitelisted | Per-address fees |
| `JMIExtension` | Single recipient | Multi-asset collateral |

### Source File Locations

- `MYieldToOne`: `src/projects/yieldToOne/MYieldToOne.sol`
- `MYieldToOneForcedTransfer`: `src/projects/yieldToOne/MYieldToOneForcedTransfer.sol`
- `MYieldFee`: `src/projects/yieldToAllWithFee/MYieldFee.sol`
- `MSpokeYieldFee`: `src/projects/yieldToAllWithFee/MSpokeYieldFee.sol`
- `MEarnerManager`: `src/projects/earnerManager/MEarnerManager.sol`
- `JMIExtension`: `src/projects/jmi/JMIExtension.sol`

## Supporting Documentation

For detailed comparisons, see [COMPARISON.md](./COMPARISON.md).
For real-world use case examples, see [EXAMPLES.md](./EXAMPLES.md).
Loading