monad-wingman

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Monad Wingman

Monad 助手

Comprehensive Monad blockchain development guide for AI agents. Covers smart contract development on Monad (parallel execution EVM-compatible L1), DeFi protocols, security best practices, deployment workflows, and the SpeedRun Ethereum curriculum adapted for Monad.

面向AI Agent的Monad区块链开发综合指南。涵盖Monad(兼容并行执行EVM的Layer1公链)上的智能合约开发、DeFi协议、安全最佳实践、部署工作流,以及适配Monad的SpeedRun Ethereum学习课程。

MONAD CRITICAL DIFFERENCES FROM ETHEREUM

Monad与以太坊的核心差异

Before doing ANYTHING, internalize these Monad-specific rules:
在开展任何工作前,请牢记这些Monad专属规则:

Chain Configuration

链配置

  • Mainnet chain ID: 143 | Testnet chain ID: 10143
  • DEFAULT TO TESTNET unless the user explicitly says mainnet
  • Native token: MON (18 decimals) — NOT ETH
  • RPC (testnet):
    https://testnet-rpc.monad.xyz
  • RPC (mainnet):
    https://rpc.monad.xyz
  • Block explorers: MonadVision, Monadscan, Socialscan
  • 主网链ID: 143 | 测试网链ID: 10143
  • 默认使用测试网,除非用户明确指定主网
  • 原生代币: MON(18位小数)—— 不是ETH
  • 测试网RPC:
    https://testnet-rpc.monad.xyz
  • 主网RPC:
    https://rpc.monad.xyz
  • 区块浏览器: MonadVision、Monadscan、Socialscan

Solidity & Compilation

Solidity与编译

  • EVM version: MUST be
    prague
    — set in
    foundry.toml
    as
    evm_version = "prague"
  • Solidity version: 0.8.27+ required, 0.8.28 recommended
  • Max contract size: 128KB (vs Ethereum's 24.5KB) — much more room
  • EVM版本: 必须设置为
    prague
    ——在
    foundry.toml
    中配置
    evm_version = "prague"
  • Solidity版本: 要求0.8.27及以上,推荐0.8.28
  • 最大合约大小: 128KB(以太坊为24.5KB)——拥有更大的开发空间

Deployment Rules (CRITICAL)

部署规则(至关重要)

  • ALWAYS use
    --legacy
    flag
    — Monad does NOT support EIP-1559 type 2 transactions
  • ALWAYS use
    forge script
    — NEVER use
    forge create
  • No blob transactions — EIP-4844 type 3 txs are NOT supported
  • Gas is charged on gas_limit, not actual usage — set gas limits carefully
  • No global mempool — transactions go directly to the block producer
  • 必须使用
    --legacy
    参数
    ——Monad不支持EIP-1559类型2交易
  • 必须使用
    forge script
    ——绝对不要使用
    forge create
  • 不支持Blob交易——EIP-4844类型3交易不受支持
  • Gas费用按gas_limit收取,而非实际使用量——需谨慎设置gas上限
  • 无全局内存池——交易直接发送给区块生产者

Wallet Persistence

钱包持久化

  • Store keys at
    ~/.monad-wallet
    with
    chmod 600
  • Mainnet key safety: use
    --ledger
    ,
    --trezor
    , or keystore files — NEVER
    --private-key
    for mainnet
  • 将密钥存储在
    ~/.monad-wallet
    ,并设置权限
    chmod 600
  • 主网密钥安全: 使用
    --ledger
    --trezor
    或密钥库文件——绝对不要在主网部署时使用
    --private-key

Monad Architecture

Monad架构

  • Parallel execution = optimistic concurrency, produces same results as sequential
  • Reserve Balance mechanism — understand this for DeFi
  • Historical state NOT available on full nodes — do not rely on archive queries
  • secp256r1 (P256) precompile at address
    0x0100
    — enables passkey/WebAuthn signing
  • 并行执行 = 乐观并发,产生与顺序执行相同的结果
  • 储备余额机制——开发DeFi时需理解此机制
  • 全节点不提供历史状态——不要依赖归档查询
  • secp256r1 (P256)预编译合约位于地址
    0x0100
    ——支持passkey/WebAuthn签名

Faucet (Testnet)

测试网水龙头

bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_ADDRESS"}'
bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_ADDRESS"}'

Contract Verification

合约验证

bash
curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xCONTRACT", "source": "...", "compilerVersion": "0.8.28"}'

bash
curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xCONTRACT", "source": "...", "compilerVersion": "0.8.28"}'

AI AGENT INSTRUCTIONS - READ THIS FIRST

AI Agent 指令 - 请先阅读

Dual Workflow: Foundry (Primary) + Scaffold-Monad

双工作流:Foundry(首选)+ Scaffold-Monad

Monad development supports two workflows. Use Foundry for contracts-only projects; use Scaffold-Monad for fullstack dApps.
Monad开发支持两种工作流。纯合约项目使用Foundry;全栈dApp使用Scaffold-Monad。

Workflow A: Foundry (Primary — Contracts Only)

工作流A:Foundry(首选——纯合约)

Step 1: Initialize Foundry Project
bash
forge init my-monad-project
cd my-monad-project
Step 2: Configure foundry.toml for Monad
toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = "prague"
solc_version = "0.8.28"

[rpc_endpoints]
monad_testnet = "https://testnet-rpc.monad.xyz"
monad_mainnet = "https://rpc.monad.xyz"
Step 3: Write and Test Contracts
bash
forge test
Step 4: Deploy to Monad Testnet
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast \
  --legacy
NEVER use
forge create
. ALWAYS use
forge script
with
--legacy
.
Step 5: Verify Contract
bash
curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xDEPLOYED", "source": "...", "compilerVersion": "0.8.28"}'
步骤1:初始化Foundry项目
bash
forge init my-monad-project
cd my-monad-project
步骤2:为Monad配置foundry.toml
toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
evm_version = "prague"
solc_version = "0.8.28"

[rpc_endpoints]
monad_testnet = "https://testnet-rpc.monad.xyz"
monad_mainnet = "https://rpc.monad.xyz"
步骤3:编写并测试合约
bash
forge test
步骤4:部署到Monad测试网
bash
forge script script/Deploy.s.sol:DeployScript \
  --rpc-url https://testnet-rpc.monad.xyz \
  --private-key $PRIVATE_KEY \
  --broadcast \
  --legacy
绝对不要使用
forge create
。必须使用带
--legacy
参数的
forge script
步骤5:验证合约
bash
curl -X POST https://agents.devnads.com/v1/verify \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xDEPLOYED", "source": "...", "compilerVersion": "0.8.28"}'

Workflow B: Scaffold-Monad (Fullstack dApps)

工作流B:Scaffold-Monad(全栈dApp)

Step 1: Create Project
bash
undefined
步骤1:创建项目
bash
undefined

Foundry variant (recommended)

推荐使用Foundry变体


**Step 2: Configure for Monad**

Edit `packages/nextjs/scaffold.config.ts`:
```typescript
import { monadTestnet } from "viem/chains";

const scaffoldConfig = {
  targetNetworks: [monadTestnet],
  pollingInterval: 3000,   // 3 seconds (default 30000 is too slow)
};
IMPORTANT: Import
monadTestnet
from
viem/chains
. Do NOT define a custom chain object.
Step 3: Configure Foundry for Monad
Edit
packages/foundry/foundry.toml
:
toml
evm_version = "prague"
solc_version = "0.8.28"
Step 4: Install and Start
bash
cd <project-name>
yarn install
yarn start
Step 5: Deploy
bash
yarn deploy --network monadTestnet
Step 6: Fund Wallet via Faucet
bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_BURNER_WALLET"}'
Step 7: Test the Frontend
  1. Navigate to
    http://localhost:3000
  2. Take a snapshot to get page elements
  3. Fund the wallet via faucet (MON, not ETH)
  4. Click through the app to verify functionality

**步骤2:为Monad配置项目**

编辑`packages/nextjs/scaffold.config.ts`:
```typescript
import { monadTestnet } from "viem/chains";

const scaffoldConfig = {
  targetNetworks: [monadTestnet],
  pollingInterval: 3000,   // 3秒(默认30000太慢)
};
重要提示:从
viem/chains
导入
monadTestnet
。不要自定义链对象。
步骤3:为Monad配置Foundry
编辑
packages/foundry/foundry.toml
toml
evm_version = "prague"
solc_version = "0.8.28"
步骤4:安装依赖并启动项目
bash
cd <project-name>
yarn install
yarn start
步骤5:部署合约
bash
yarn deploy --network monadTestnet
步骤6:通过水龙头为钱包充值
bash
curl -X POST https://agents.devnads.com/v1/faucet \
  -H "Content-Type: application/json" \
  -d '{"chainId": 10143, "address": "0xYOUR_BURNER_WALLET"}'
步骤7:测试前端
  1. 访问
    http://localhost:3000
  2. 快照页面获取页面元素
  3. 通过水龙头为钱包充值(使用MON,而非ETH)
  4. 点击操作应用验证功能

Fork Mode (Testing Against Live Monad State)

分叉模式(针对Monad实时状态测试)

bash
anvil --fork-url https://rpc.monad.xyz --block-time 1
Or for testnet:
bash
anvil --fork-url https://testnet-rpc.monad.xyz --block-time 1
bash
anvil --fork-url https://rpc.monad.xyz --block-time 1
测试网分叉:
bash
anvil --fork-url https://testnet-rpc.monad.xyz --block-time 1

DO NOT:

禁止操作:

  • Use
    forge create
    (use
    forge script
    with
    --legacy
    instead)
  • Send EIP-1559 type 2 transactions (always use
    --legacy
    )
  • Send blob transactions (EIP-4844 type 3 not supported)
  • Use
    --private-key
    for mainnet deployments (use
    --ledger
    /
    --trezor
    /keystore)
  • Define custom chain objects in frontend (use
    import { monadTestnet } from 'viem/chains'
    )
  • Rely on historical state queries (not available on full nodes)
  • Assume gas is charged on usage (it is charged on gas_limit)

  • 不要使用
    forge create
    (请使用带
    --legacy
    参数的
    forge script
    替代)
  • 不要发送EIP-1559类型2交易(始终使用
    --legacy
  • 不要发送Blob交易(不支持EIP-4844类型3交易)
  • 主网部署时不要使用
    --private-key
    (使用
    --ledger
    /
    --trezor
    /密钥库文件)
  • 前端不要自定义链对象(使用
    import { monadTestnet } from 'viem/chains'
  • 不要依赖历史状态查询(全节点不提供)
  • 不要假设Gas费用按实际使用量收取(按gas_limit收取)

Monad Deployment Workflow

Monad部署工作流

Deploy Script Template

部署脚本模板

solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "forge-std/Script.sol";
import "../src/MyContract.sol";

contract DeployScript is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        MyContract myContract = new MyContract();

        vm.stopBroadcast();

        console.log("MyContract deployed to:", address(myContract));
    }
}
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import "forge-std/Script.sol";
import "../src/MyContract.sol";

contract DeployScript is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        MyContract myContract = new MyContract();

        vm.stopBroadcast();

        console.log("MyContract deployed to:", address(myContract));
    }
}

Deploy Commands

部署命令

bash
undefined
bash
undefined

Testnet (default)

测试网(默认)

forge script script/Deploy.s.sol:DeployScript
--rpc-url https://testnet-rpc.monad.xyz
--private-key $PRIVATE_KEY
--broadcast
--legacy
forge script script/Deploy.s.sol:DeployScript
--rpc-url https://testnet-rpc.monad.xyz
--private-key $PRIVATE_KEY
--broadcast
--legacy

Mainnet (use hardware wallet!)

主网(使用硬件钱包!)

forge script script/Deploy.s.sol:DeployScript
--rpc-url https://rpc.monad.xyz
--ledger
--broadcast
--legacy

---
forge script script/Deploy.s.sol:DeployScript
--rpc-url https://rpc.monad.xyz
--ledger
--broadcast
--legacy

---

THE MOST CRITICAL CONCEPT

最核心的概念

NOTHING IS AUTOMATIC ON ANY EVM CHAIN, INCLUDING MONAD.
Smart contracts cannot execute themselves. There is no cron job, no scheduler, no background process. For EVERY function that "needs to happen":
  1. Make it callable by ANYONE (not just admin)
  2. Give callers a REASON (profit, reward, their own interest)
  3. Make the incentive SUFFICIENT to cover gas + profit
Always ask: "Who calls this function? Why would they pay gas?"
If you cannot answer this, your function will not get called.
Monad note: Gas on Monad is cheap due to parallel execution throughput, but the incentive principle still applies. Gas is charged on gas_limit, not usage — so set limits carefully.
在任何EVM链上,包括Monad,没有任何功能是自动执行的。
智能合约无法自行执行。没有定时任务、调度器或后台进程。对于每一个“需要自动执行”的函数:
  1. 任何人都能调用(不局限于管理员)
  2. 给调用者一个理由(利润、奖励、自身利益)
  3. 确保激励足够覆盖Gas费用+利润
始终要问:“谁会调用这个函数?他们为什么愿意支付Gas费用?”
如果无法回答这个问题,你的函数将永远不会被调用。
Monad提示:由于并行执行的高吞吐量,Monad的Gas费用很低,但激励原则仍然适用。Gas费用按gas_limit收取,而非实际使用量——因此需谨慎设置上限。

Examples of Proper Incentive Design

合理激励设计示例

solidity
// LIQUIDATIONS: Caller gets bonus collateral
function liquidate(address user) external {
    require(getHealthFactor(user) < 1e18, "Healthy");
    uint256 bonus = collateral * 5 / 100; // 5% bonus
    collateralToken.transfer(msg.sender, collateral + bonus);
}

// YIELD HARVESTING: Caller gets % of harvest
function harvest() external {
    uint256 yield = protocol.claimRewards();
    uint256 callerReward = yield / 100; // 1%
    token.transfer(msg.sender, callerReward);
}

// CLAIMS: User wants their own tokens
function claimRewards() external {
    uint256 reward = pendingRewards[msg.sender];
    pendingRewards[msg.sender] = 0;
    token.transfer(msg.sender, reward);
}

solidity
// 清算:调用者获得额外抵押品
function liquidate(address user) external {
    require(getHealthFactor(user) < 1e18, "健康账户");
    uint256 bonus = collateral * 5 / 100; // 5%额外奖励
    collateralToken.transfer(msg.sender, collateral + bonus);
}

// 收益收割:调用者获得部分收益
function harvest() external {
    uint256 yield = protocol.claimRewards();
    uint256 callerReward = yield / 100; // 1%
    token.transfer(msg.sender, callerReward);
}

// 领取奖励:用户想要自己的代币
function claimRewards() external {
    uint256 reward = pendingRewards[msg.sender];
    pendingRewards[msg.sender] = 0;
    token.transfer(msg.sender, reward);
}

Critical Gotchas (Memorize These)

关键陷阱(牢记)

1. Token Decimals Vary

1. 代币小数位数不同

USDC = 6 decimals, not 18!
solidity
// BAD: Assumes 18 decimals - transfers 1 TRILLION USDC!
uint256 oneToken = 1e18;

// GOOD: Check decimals
uint256 oneToken = 10 ** token.decimals();
Common decimals:
  • USDC, USDT: 6 decimals
  • WBTC: 8 decimals
  • Most tokens (DAI, WMON): 18 decimals
  • MON (native): 18 decimals
USDC的小数位数是6位,不是18位!
solidity
// 错误:假设18位小数——会转移1万亿USDC!
uint256 oneToken = 1e18;

// 正确:检查小数位数
uint256 oneToken = 10 ** token.decimals();
常见小数位数:
  • USDC、USDT:6位小数
  • WBTC:8位小数
  • 大多数代币(DAI、WMON):18位小数
  • MON(原生代币):18位小数

2. ERC-20 Approve Pattern Required

2. 必须使用ERC-20授权模式

Contracts cannot pull tokens directly. Two-step process:
solidity
// Step 1: User approves
token.approve(spenderContract, amount);

// Step 2: Contract pulls tokens
token.transferFrom(user, address(this), amount);
Never use infinite approvals:
solidity
// DANGEROUS
token.approve(spender, type(uint256).max);

// SAFE
token.approve(spender, exactAmount);
合约无法直接提取代币。需分两步操作:
solidity
// 步骤1:用户授权
token.approve(spenderContract, amount);

// 步骤2:合约提取代币
token.transferFrom(user, address(this), amount);
绝对不要使用无限授权:
solidity
// 危险
token.approve(spender, type(uint256).max);

// 安全
token.approve(spender, exactAmount);

3. No Floating Point in Solidity

3. Solidity不支持浮点数

Use basis points (1 bp = 0.01%):
solidity
// BAD: This equals 0
uint256 fivePercent = 5 / 100;

// GOOD: Basis points
uint256 FEE_BPS = 500; // 5% = 500 basis points
uint256 fee = (amount * FEE_BPS) / 10000;
使用基点(1 bp = 0.01%):
solidity
// 错误:结果为0
uint256 fivePercent = 5 / 100;

// 正确:使用基点
uint256 FEE_BPS = 500; // 5% = 500基点
uint256 fee = (amount * FEE_BPS) / 10000;

4. Reentrancy Attacks

4. 重入攻击

External calls can call back into your contract:
solidity
// SAFE: Checks-Effects-Interactions pattern
function withdraw() external nonReentrant {
    uint256 bal = balances[msg.sender];
    balances[msg.sender] = 0; // Effect BEFORE interaction
    (bool success,) = msg.sender.call{value: bal}("");
    require(success);
}
Always use OpenZeppelin's ReentrancyGuard. Reentrancy is still possible on Monad despite parallel execution — parallel execution produces the same results as sequential.
外部调用可以回调到你的合约:
solidity
// 安全:检查-影响-交互模式
function withdraw() external nonReentrant {
    uint256 bal = balances[msg.sender];
    balances[msg.sender] = 0; // 先执行影响,再执行交互
    (bool success,) = msg.sender.call{value: bal}("");
    require(success);
}
始终使用OpenZeppelin的ReentrancyGuard。尽管Monad支持并行执行,但重入攻击仍然可能——并行执行产生的结果与顺序执行一致。

5. Never Use DEX Spot Prices as Oracles

5. 不要使用DEX现货价格作为预言机

Flash loans can manipulate spot prices instantly:
solidity
// SAFE: Use Chainlink or Pyth
function getPrice() internal view returns (uint256) {
    (, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
    require(block.timestamp - updatedAt < 3600, "Stale");
    require(price > 0, "Invalid");
    return uint256(price);
}
On Monad, use Chainlink or Pyth for oracle feeds.
闪电贷可以瞬间操纵现货价格:
solidity
// 安全:使用Chainlink或Pyth
function getPrice() internal view returns (uint256) {
    (, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
    require(block.timestamp - updatedAt < 3600, "数据过时");
    require(price > 0, "无效价格");
    return uint256(price);
}
在Monad上,使用ChainlinkPyth作为预言机数据源。

6. Vault Inflation Attack

6. 金库通胀攻击

First depositor can steal funds via share manipulation:
solidity
// Mitigation: Virtual offset
function convertToShares(uint256 assets) public view returns (uint256) {
    return assets.mulDiv(totalSupply() + 1e3, totalAssets() + 1);
}
第一个存款人可以通过份额操纵窃取资金:
solidity
// 缓解方案:虚拟偏移
function convertToShares(uint256 assets) public view returns (uint256) {
    return assets.mulDiv(totalSupply() + 1e3, totalAssets() + 1);
}

7. Use SafeERC20

7. 使用SafeERC20

Some tokens (USDT) don't return bool on transfer:
solidity
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;

token.safeTransfer(to, amount); // Handles non-standard tokens
部分代币(如USDT)的transfer方法不返回布尔值:
solidity
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
using SafeERC20 for IERC20;

token.safeTransfer(to, amount); // 处理非标准代币

8. Monad-Specific Gotchas

8. Monad专属陷阱

Gas limit billing: Monad charges gas on
gas_limit
, NOT actual gas used. Over-estimating gas wastes real MON. Always benchmark and set tight gas limits in production.
No EIP-1559: Always use
--legacy
flag. Type 2 transactions will be rejected.
No blob txs: EIP-4844 type 3 transactions are not supported.
No global mempool: Transactions go directly to the block producer. MEV strategies that rely on mempool monitoring do not work the same way.
Parallel execution safety: Monad's parallel execution is deterministic — it produces the same results as sequential execution. Your contracts do NOT need special handling for parallelism. Standard Solidity patterns work as-is.
Historical state: Full nodes do not serve historical state. Do not rely on
eth_call
at past block numbers.
128KB contract limit: Monad allows contracts up to 128KB (vs Ethereum's 24.5KB). This is generous but not infinite — still optimize if approaching the limit.

Gas上限计费:Monad按
gas_limit
收取Gas费用,而非实际使用量。高估Gas上限会浪费真实的MON。生产环境中务必基准测试并谨慎设置上限。
不支持EIP-1559:始终使用
--legacy
参数。类型2交易将被拒绝。
不支持Blob交易:EIP-4844类型3交易不受支持。
无全局内存池:交易直接发送给区块生产者。依赖内存池监控的MEV策略无法以相同方式工作。
并行执行安全性:Monad的并行执行是确定性的——产生与顺序执行相同的结果。你的合约无需为并行执行做特殊处理。标准Solidity模式可直接使用。
历史状态:全节点不提供历史状态。不要依赖过去区块高度的
eth_call
查询。
128KB合约大小限制:Monad允许最大128KB的合约(以太坊为24.5KB)。尽管空间充裕,但接近上限时仍需优化。

Scaffold-Monad Development

Scaffold-Monad开发

Project Structure

项目结构

packages/
├── foundry/              # Smart contracts
│   ├── contracts/        # Your Solidity files
│   └── script/           # Deploy scripts
└── nextjs/
    ├── app/              # React pages
    └── contracts/        # Generated ABIs + externalContracts.ts
packages/
├── foundry/              # 智能合约
│   ├── contracts/        # Solidity文件
│   └── script/           # 部署脚本
└── nextjs/
    ├── app/              # React页面
    └── contracts/        # 生成的ABI + externalContracts.ts

Essential Hooks

核心Hooks

typescript
// Read contract data
const { data } = useScaffoldReadContract({
  contractName: "YourContract",
  functionName: "greeting",
});

// Write to contract
const { writeContractAsync } = useScaffoldWriteContract("YourContract");

// Watch events
useScaffoldEventHistory({
  contractName: "YourContract",
  eventName: "Transfer",
  fromBlock: 0n,
});
typescript
// 读取合约数据
const { data } = useScaffoldReadContract({
  contractName: "YourContract",
  functionName: "greeting",
});

// 写入合约
const { writeContractAsync } = useScaffoldWriteContract("YourContract");

// 监听事件
useScaffoldEventHistory({
  contractName: "YourContract",
  eventName: "Transfer",
  fromBlock: 0n,
});

Frontend Chain Configuration

前端链配置

typescript
// CORRECT: Import from viem/chains
import { monadTestnet } from "viem/chains";

// WRONG: Do NOT define a custom chain object
const monadTestnet = { id: 10143, ... }; // NEVER DO THIS

typescript
// 正确:从viem/chains导入
import { monadTestnet } from "viem/chains";

// 错误:不要自定义链对象
const monadTestnet = { id: 10143, ... }; // 绝对不要这么做

SpeedRun Ethereum Challenges

SpeedRun Ethereum挑战

These challenges use Scaffold-ETH 2 and target Ethereum. They teach EVM fundamentals that are directly applicable to Monad development. Use them for learning, then deploy your projects to Monad.
ChallengeConceptKey Lesson
0: Simple NFTERC-721Minting, metadata, tokenURI
1: StakingCoordinationDeadlines, escrow, thresholds
2: Token VendorERC-20Approve pattern, buy/sell
3: Dice GameRandomnessOn-chain randomness is insecure
4: DEXAMMx*y=k formula, slippage
5: OraclesPrice FeedsChainlink, manipulation resistance
6: LendingCollateralHealth factor, liquidation incentives
7: StablecoinsPeggingCDP, over-collateralization
8: Prediction MarketsResolutionOutcome determination
9: ZK VotingPrivacyZero-knowledge proofs
10: MultisigSignaturesThreshold approval
11: SVG NFTOn-chain ArtGenerative, base64 encoding

这些挑战基于Scaffold-ETH 2,目标是以太坊。它们教授的EVM基础知识可直接应用于Monad开发。可用于学习,之后将项目部署到Monad。
挑战概念核心知识点
0: 简单NFTERC-721铸造、元数据、tokenURI
1: 质押协同机制截止时间、托管、阈值
2: 代币供应商ERC-20授权模式、买卖
3: 骰子游戏随机性链上随机性不安全
4: DEXAMMx*y=k公式、滑点
5: 预言机价格数据源Chainlink、抗操纵
6: 借贷抵押品健康因子、清算激励
7: 稳定币锚定机制CDP、超额抵押
8: 预测市场结果判定结果确定方式
9: ZK投票隐私零知识证明
10: 多签签名阈值授权
11: SVG NFT链上艺术生成式、base64编码

DeFi Protocol Patterns on Monad

Monad上的DeFi协议模式

Euler (Lending)

Euler(借贷)

  • Modular lending protocol on Monad
  • Supply collateral, borrow assets
  • Health factor = collateral value / debt value
  • Liquidation when health factor < 1
  • Monad上的模块化借贷协议
  • 存入抵押品、借入资产
  • 健康因子 = 抵押品价值 / 债务价值
  • 健康因子<1时触发清算

Morpho (Optimized Lending)

Morpho(优化借贷)

  • Peer-to-peer lending optimization layer
  • Better rates through direct matching
  • Compatible with Monad's parallel execution
  • 点对点借贷优化层
  • 通过直接匹配获得更优利率
  • 兼容Monad的并行执行

AMM / DEX Patterns

AMM/DEX模式

  • Constant product formula: x * y = k
  • Slippage protection required
  • LP tokens represent pool share
  • 恒定乘积公式:x * y = k
  • 需设置滑点保护
  • LP代币代表池份额

Oracles on Monad

Monad上的预言机

  • Chainlink: Standard price feeds,
    latestRoundData()
  • Pyth: Pull-based oracle with sub-second updates, well-suited to Monad's speed
solidity
// Chainlink on Monad
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

function getLatestPrice() public view returns (uint256) {
    (, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
    require(block.timestamp - updatedAt < 3600, "Stale price");
    require(price > 0, "Invalid price");
    return uint256(price);
}
  • Chainlink: 标准价格数据源,
    latestRoundData()
  • Pyth: 拉取式预言机,亚秒级更新,适配Monad的速度
solidity
// Monad上的Chainlink使用示例
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

function getLatestPrice() public view returns (uint256) {
    (, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
    require(block.timestamp - updatedAt < 3600, "价格过时");
    require(price > 0, "无效价格");
    return uint256(price);
}

ERC-4626 (Tokenized Vaults)

ERC-4626(代币化金库)

  • Standard interface for yield-bearing vaults
  • deposit/withdraw with share accounting
  • Protect against inflation attacks

  • 生息金库的标准接口
  • 存入/取出时的份额记账
  • 防范通胀攻击

Security Review Checklist

安全审查清单

Before deployment, verify:
  • Access control on all admin functions
  • Reentrancy protection (CEI + nonReentrant)
  • Token decimal handling correct
  • Oracle manipulation resistant (Chainlink or Pyth, not DEX spot)
  • Integer overflow handled (0.8+ or SafeMath)
  • Return values checked (SafeERC20)
  • Input validation present
  • Events emitted for state changes
  • Incentives designed for maintenance functions
  • NO infinite approvals (use exact amounts, NEVER type(uint256).max)
部署前,请验证:
  • 所有管理员函数的访问控制
  • 重入保护(CEI模式 + nonReentrant修饰器)
  • 代币小数位数处理正确
  • 预言机抗操纵(使用Chainlink或Pyth,而非DEX现货价格)
  • 整数溢出处理(0.8+版本或SafeMath)
  • 返回值检查(使用SafeERC20)
  • 输入验证存在
  • 状态变更时触发事件
  • 维护函数的激励设计合理
  • 无无限授权(使用精确金额,绝对不要用type(uint256).max)

Monad-Specific Checks

Monad专属检查项

  • evm_version = "prague"
    in foundry.toml
  • Solidity version 0.8.27+ (recommend 0.8.28)
  • All deploy commands use
    --legacy
    flag
  • All deploy commands use
    forge script
    (not
    forge create
    )
  • Gas limits set carefully (charged on limit, not usage)
  • No reliance on historical state queries
  • No EIP-4844 blob transactions
  • Mainnet deployments use hardware wallet (not
    --private-key
    )
  • Contract size under 128KB
  • Wallet files stored at
    ~/.monad-wallet
    with chmod 600

  • foundry.toml中设置
    evm_version = "prague"
  • Solidity版本为0.8.27+(推荐0.8.28)
  • 所有部署命令使用
    --legacy
    参数
  • 所有部署命令使用
    forge script
    (而非
    forge create
  • 谨慎设置Gas上限(按上限计费,而非实际使用量)
  • 不依赖历史状态查询
  • 不使用EIP-4844 Blob交易
  • 主网部署使用硬件钱包(而非
    --private-key
  • 合约大小低于128KB
  • 钱包文件存储在
    ~/.monad-wallet
    ,并设置权限chmod 600

Response Guidelines

响应指南

When helping developers:
  1. Default to testnet - Chain ID 10143 unless user says mainnet
  2. Answer directly - Address their question first
  3. Show code - Provide working examples with Monad config
  4. Always use
    --legacy
    - Remind about no EIP-1559 support
  5. Always use
    forge script
    - Never suggest
    forge create
  6. Warn about gotchas - Proactively mention relevant pitfalls
  7. Reference challenges - Point to SpeedRun Ethereum for practice (note: they target Ethereum)
  8. Ask about incentives - For any "automatic" function, ask who calls it and why
  9. Gas limit awareness - Remind that gas is charged on limit, not usage
  10. Verification - Always include contract verification step after deployment
协助开发者时:
  1. 默认使用测试网——链ID 10143,除非用户指定主网
  2. 直接回答问题——先解决用户的核心疑问
  3. 提供代码示例——给出带有Monad配置的可运行示例
  4. 始终提醒使用
    --legacy
    ——强调不支持EIP-1559
  5. 始终推荐
    forge script
    ——绝对不要建议使用
    forge create
  6. 提前预警陷阱——主动提及相关的潜在问题
  7. 参考学习挑战——引导用户使用SpeedRun Ethereum练习(注意:这些挑战针对以太坊)
  8. 询问激励机制——对于任何“自动执行”的函数,询问谁会调用以及调用动机
  9. Gas上限意识——提醒用户Gas费用按上限计费,而非实际使用量
  10. 验证步骤——部署后始终包含合约验证步骤