Ethereum Wingman
Comprehensive Ethereum development guide for AI agents. Covers smart contract development, DeFi protocols, security best practices, and the SpeedRun Ethereum curriculum.
AI AGENT INSTRUCTIONS - READ THIS FIRST
Default Stack: Scaffold-ETH 2 with Fork Mode
When a user wants to BUILD any Ethereum project, follow these steps:
Step 1: Create Project
CODEBLOCK0
Step 2: Fix Polling Interval
Edit packages/nextjs/scaffold.config.ts and change:
pollingInterval: 30000, // Default: 30 seconds (way too slow!)
to:
CODEBLOCK2
Step 3: Install & Fork a Live Network
CODEBLOCK3
Step 4: Enable Auto Block Mining (REQUIRED!)
CODEBLOCK4
Without this, block.timestamp stays FROZEN and time-dependent logic breaks!
Optional: Make it permanent by editing packages/foundry/package.json to add --block-time 1 to the fork script.
Step 5: Deploy to Local Fork (FREE!)
CODEBLOCK5
Step 6: Start Frontend
CODEBLOCK6
Step 7: Test the Frontend
After the frontend is running, open a browser and test the app:
- 1. Navigate to INLINECODE4
- Take a snapshot to get page elements (burner wallet address is in header)
- Click the faucet to fund the burner wallet with ETH
- Transfer tokens from whales if needed (use burner address from page)
- Click through the app to verify functionality
Use the cursor-browser-extension MCP tools for browser automation.
See tools/testing/frontend-testing.md for detailed workflows.
DO NOT:
- - Run
yarn chain (use yarn fork --network <chain> instead!) - Manually run
forge init or set up Foundry from scratch - Manually create Next.js projects
- Set up wallet connection manually (SE2 has RainbowKit pre-configured)
Why Fork Mode?
CODEBLOCK7
Address Data Available
Token, protocol, and whale addresses are in data/addresses/:
- -
tokens.json - WETH, USDC, DAI, etc. per chain - INLINECODE12 - Uniswap, Aave, Chainlink per chain
- INLINECODE13 - Large token holders for test funding
THE MOST CRITICAL CONCEPT
NOTHING IS AUTOMATIC ON ETHEREUM.
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)
- Give callers a REASON (profit, reward, their own interest)
- Make the incentive SUFFICIENT to cover gas + profit
Always ask: "Who calls this function? Why would they pay gas?"
If you can't answer this, your function won't get called.
Examples of Proper Incentive Design
CODEBLOCK8
Critical Gotchas (Memorize These)
1. Token Decimals Vary
USDC = 6 decimals, not 18!
CODEBLOCK9
Common decimals:
- - USDC, USDT: 6 decimals
- WBTC: 8 decimals
- Most tokens (DAI, WETH): 18 decimals
2. ERC-20 Approve Pattern Required
Contracts cannot pull tokens directly. Two-step process:
CODEBLOCK10
Never use infinite approvals:
CODEBLOCK11
3. No Floating Point in Solidity
Use basis points (1 bp = 0.01%):
CODEBLOCK12
4. Reentrancy Attacks
External calls can call back into your contract:
CODEBLOCK13
Always use OpenZeppelin's ReentrancyGuard.
5. Never Use DEX Spot Prices as Oracles
Flash loans can manipulate spot prices instantly:
CODEBLOCK14
6. Vault Inflation Attack
First depositor can steal funds via share manipulation:
CODEBLOCK15
7. Use SafeERC20
Some tokens (USDT) don't return bool on transfer:
CODEBLOCK16
Scaffold-ETH 2 Development
Project Structure
CODEBLOCK17
Essential Hooks
// 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,
});
SpeedRun Ethereum Challenges
Reference these for hands-on learning:
| Challenge | Concept | Key Lesson |
|---|
| 0: Simple NFT | ERC-721 | Minting, metadata, tokenURI |
| 1: Staking |
Coordination | Deadlines, escrow, thresholds |
| 2: Token Vendor | ERC-20 | Approve pattern, buy/sell |
| 3: Dice Game | Randomness | On-chain randomness is insecure |
| 4: DEX | AMM | x*y=k formula, slippage |
| 5: Oracles | Price Feeds | Chainlink, manipulation resistance |
| 6: Lending | Collateral | Health factor, liquidation incentives |
| 7: Stablecoins | Pegging | CDP, over-collateralization |
| 8: Prediction Markets | Resolution | Outcome determination |
| 9: ZK Voting | Privacy | Zero-knowledge proofs |
| 10: Multisig | Signatures | Threshold approval |
| 11: SVG NFT | On-chain Art | Generative, base64 encoding |
DeFi Protocol Patterns
Uniswap (AMM)
- - Constant product formula: x * y = k
- Slippage protection required
- LP tokens represent pool share
Aave (Lending)
- - Supply collateral, borrow assets
- Health factor = collateral value / debt value
- Liquidation when health factor < 1
ERC-4626 (Tokenized Vaults)
- - 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
- [ ] Integer overflow handled (0.8+ or SafeMath)
- [ ] Return values checked (SafeERC20)
- [ ] Input validation present
- [ ] Events emitted for state changes
- [ ] Incentives designed for maintenance functions
Response Guidelines
When helping developers:
- 1. Follow the fork workflow - Always use
yarn fork, never INLINECODE15 - Answer directly - Address their question first
- Show code - Provide working examples
- Warn about gotchas - Proactively mention relevant pitfalls
- Reference challenges - Point to SpeedRun Ethereum for practice
- Ask about incentives - For any "automatic" function, ask who calls it and why
Ethereum Wingman
面向AI代理的全面以太坊开发指南。涵盖智能合约开发、DeFi协议、安全最佳实践以及SpeedRun以太坊课程。
AI代理指令 - 请先阅读此部分
默认技术栈:Scaffold-ETH 2 + Fork模式
当用户想要构建任何以太坊项目时,请遵循以下步骤:
步骤1:创建项目
bash
npx create-eth@latest
选择:foundry(推荐)、目标链、项目名称
步骤2:修复轮询间隔
编辑 packages/nextjs/scaffold.config.ts 并修改:
typescript
pollingInterval: 30000, // 默认:30秒(太慢了!)
改为:
typescript
pollingInterval: 3000, // 3秒(开发时更合适)
步骤3:安装并Fork一个实时网络
bash
cd <项目名称>
yarn install
yarn fork --network base # 或 mainnet、arbitrum、optimism、polygon
步骤4:启用自动区块挖矿(必需!)
bash
在新终端中,启用间隔挖矿(1区块/秒)
cast rpc anvil_setIntervalMining 1
不执行此操作,block.timestamp 将保持冻结状态,依赖时间的逻辑将失效!
可选:使其永久生效,编辑 packages/foundry/package.json,在fork脚本中添加 --block-time 1。
步骤5:部署到本地Fork(免费!)
bash
yarn deploy
步骤6:启动前端
bash
yarn start
步骤7:测试前端
前端运行后,打开浏览器测试应用:
- 1. 导航到 http://localhost:3000
- 截图获取页面元素(钱包地址在头部)
- 点击水龙头为钱包充值ETH
- 从大户转账代币(使用页面上的钱包地址)
- 点击浏览应用验证功能
使用 cursor-browser-extension MCP工具进行浏览器自动化。
详细工作流程见 tools/testing/frontend-testing.md。
禁止操作:
- - 运行 yarn chain(应使用 yarn fork --network <链> 替代!)
- 手动运行 forge init 或从头搭建Foundry
- 手动创建Next.js项目
- 手动设置钱包连接(SE2已预配置RainbowKit)
为什么使用Fork模式?
yarn chain(错误) yarn fork --network base(正确)
└─ 空的本地链 └─ 真实Base主网的Fork
└─ 无协议 └─ Uniswap、Aave等可用
└─ 无代币 └─ 真实USDC、WETH存在
└─ 隔离测试 └─ 针对真实状态测试
可用地址数据
代币、协议和大户地址位于 data/addresses/:
- - tokens.json - 各链的WETH、USDC、DAI等
- protocols.json - 各链的Uniswap、Aave、Chainlink
- whales.json - 用于测试资金的大额代币持有者
最关键的概念
以太坊上没有什么是自动执行的。
智能合约无法自行执行。没有定时任务、调度器或后台进程。对于每个需要发生的函数:
- 1. 使其可被任何人调用(不仅是管理员)
- 给调用者一个理由(利润、奖励、自身利益)
- 确保激励足够覆盖Gas费+利润
始终问:谁会调用这个函数?他们为什么要支付Gas费?
如果无法回答,你的函数将永远不会被调用。
正确激励设计示例
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);
}
关键陷阱(务必记住)
1. 代币小数位数不同
USDC = 6位小数,不是18位!
solidity
// 错误:假设18位小数 - 会转移1万亿USDC!
uint256 oneToken = 1e18;
// 正确:检查小数位数
uint256 oneToken = 10 token.decimals();
常见小数位数:
- - USDC、USDT:6位小数
- WBTC:8位小数
- 大多数代币(DAI、WETH):18位小数
2. 需要ERC-20授权模式
合约不能直接拉取代币。两步流程:
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. Solidity中没有浮点数
使用基点(1 bp = 0.01%):
solidity
// 错误:这等于0
uint256 fivePercent = 5 / 100;
// 正确:基点
uint256 FEE_BPS = 500; // 5% = 500基点
uint256 fee = (amount * FEE_BPS) / 10000;
4. 重入攻击
外部调用可能回调你的合约:
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。
5. 切勿使用DEX现货价格作为预言机
闪电贷可以瞬间操纵现货价格:
solidity
// 安全:使用Chainlink
function getPrice() internal view returns (uint256) {
(, int256 price,, uint256 updatedAt,) = priceFeed.latestRoundData();
require(block.timestamp - updatedAt < 3600, 过时);
require(price > 0, 无效);
return uint256(price);
}
6. 金库通胀攻击
第一个存款人可以通过份额操纵窃取资金:
solidity
// 缓解措施:虚拟偏移
function convertToShares(uint256 assets) public view returns (uint256) {
return assets.mulDiv(totalSupply() + 1e3, totalAssets() + 1);
}
7. 使用SafeERC20
某些代币(USDT)在transfer时不返回布尔值:
solidity
import @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol;
using SafeERC20 for IERC20;
token.safeTransfer(to, amount); // 处理非标准代币
Scaffold-ETH 2 开发
项目结构
packages/
├── foundry/ # 智能合约
│ ├── contracts/ # 你的Solidity文件
│ └── script/ # 部署脚本
└── nextjs/
├── app/ # React页面
└── contracts/ # 生成的ABI + externalContracts.ts
必备Hooks
typescript
// 读取合约数据
const { data } = useScaffoldReadContract({
contractName: YourContract,
functionName: greeting,
});
// 写入合约
const { writeContractAsync } = useScaffoldWriteContract(YourContract);
// 监听事件
useScaffoldEventHistory({
contractName: YourContract,
eventName: Transfer,
fromBlock: 0n,
});
SpeedRun以太坊挑战
参考这些进行实践学习:
| 挑战 | 概念 | 关键要点 |
|---|
| 0:简单NFT | ERC-721 | 铸造、元数据、tokenURI |
| 1:质押 |
协调 | 截止日期、托管、阈值 |
| 2:代币供应商 | ERC-20 | 授权模式、