SC Day 45
复习 - Week 7 总结 (AMM/Oracle + Solana Token)
### Week 7 知识图谱
2026-05-15
第二阶段:框架实战 (41-48)复习AMMOracleSolana对比分析
日期: 2026-05-15 方向: Solidity / Solana 阶段: 第二阶段:框架实战 (41-48) 标签: #复习 #AMM #Oracle #Solana #对比分析
今日目标
- 系统回顾 Week 7 所有知识点(AMM 进阶、CPI、Chainlink、Anchor 事件)
- 深入理解 AMM 数学公式推导
- 对比 EVM DeFi 和 Solana DeFi 的开发模式差异
- 建立跨链开发的知识框架
核心概念
Week 7 知识图谱
Week 7 知识结构:
├── Day 41: AMM 进阶 (Solidity)
│ ├── 手续费机制 (997/1000)
│ ├── 滑点保护 (minAmountOut)
│ ├── TWAP 预言机
│ └── Uniswap V2 vs V3
│
├── Day 42: Vault + CPI (Solana)
│ ├── CPI 原理
│ ├── PDA 签名 (invoke_signed)
│ ├── SPL Token 操作
│ └── CPI 安全考虑
│
├── Day 43: Chainlink 集成 (Solidity)
│ ├── AggregatorV3Interface
│ ├── 安全检查五件套
│ ├── Fork 主网测试
│ └── 预言机攻击防御
│
└── Day 44: 事件 + 前端 (Solana)
├── Anchor 事件系统
├── IDL 结构
├── TypeScript 客户端
└── React 集成模式
AMM 数学深入回顾
恒定乘积公式完整推导
基础公式
初始状态:池子中有 x 个 Token A 和 y 个 Token B
x * y = k (恒定乘积)
用户输入 Δx 个 Token A,获得 Δy 个 Token B:
(x + Δx) * (y - Δy) = k
展开: xy - xΔy + yΔx - ΔxΔy = k
因为 xy = k:
-xΔy + yΔx - ΔxΔy = 0
解 Δy:
Δy(x + Δx) = yΔx
Δy = yΔx / (x + Δx)
加入手续费(Uniswap V2 方式)
手续费 = 0.3%,实际有效输入 = Δx * 0.997
Δy = y * (Δx * 997) / (x * 1000 + Δx * 997)
整数实现(Solidity):
uint256 amountInWithFee = amountIn * 997;
uint256 numerator = reserveB * amountInWithFee;
uint256 denominator = reserveA * 1000 + amountInWithFee;
uint256 amountOut = numerator / denominator;
价格公式
瞬时价格(边际价格):
dP/dx 在 x*y=k 曲线上:
y = k/x
dy/dx = -k/x²
即时价格 P = y/x (Token B per Token A)
价格冲击公式
理想输出(无冲击): Δy_ideal = Δx * (y/x)
实际输出: Δy_actual = y * Δx / (x + Δx)
价格冲击: Impact = 1 - Δy_actual / Δy_ideal
= 1 - x / (x + Δx)
= Δx / (x + Δx)
当 Δx << x 时,价格冲击约为 Δx/x(交易量占池子的比例)。
无常损失公式
假设初始价格 P₀ = y₀/x₀,后来价格变为 P₁ = r * P₀(r 为价格变动倍数)
无常损失 = 2√r / (1+r) - 1
r=1.25 (涨25%): IL = -0.6%
r=1.50 (涨50%): IL = -2.0%
r=2.00 (涨100%): IL = -5.7%
r=3.00 (涨200%): IL = -13.4%
r=5.00 (涨400%): IL = -25.5%
AMM 设计权衡总结
| 设计决策 | 选项A | 选项B | 权衡 |
|---|---|---|---|
| 流动性范围 | 全范围 (V2) | 集中 (V3) | 资本效率 vs 复杂度 |
| 费率 | 固定 | 动态 | 简单性 vs 最优定价 |
| 预言机 | 内建 TWAP | 外部 Chainlink | 去中心化 vs 准确性 |
| LP Token | ERC20 (同质) | ERC721 (NFT) | 可组合性 vs 灵活性 |
| 交换路径 | 单池直接 | 多跳聚合 | Gas 成本 vs 最优价格 |
Solana 开发工作流回顾
完整开发周期
1. 初始化项目
anchor init my-project
cd my-project
2. 编写程序 (Rust)
programs/my-project/src/lib.rs
- #[program] 模块: 业务逻辑
- #[derive(Accounts)]: 账户约束
- #[account]: 数据结构
- #[event]: 事件定义
- #[error_code]: 错误码
3. 构建
anchor build
→ 生成 target/idl/my_project.json (IDL)
→ 生成 target/types/my_project.ts (TypeScript 类型)
→ 生成 target/deploy/my_project.so (可执行文件)
4. 测试
anchor test
→ 本地验证者 + 部署 + 运行 tests/my-project.ts
5. 部署
anchor deploy --provider.cluster devnet
→ 部署到 Solana devnet
6. 前端集成
→ 导入 IDL + @coral-xyz/anchor
→ 创建 Program 实例
→ 调用方法 / 读取账户 / 监听事件
核心概念速查
| 概念 | 说明 | EVM 类比 |
|---|---|---|
| Program | 链上可执行代码 | Smart Contract |
| Account | 数据存储单元 | Storage Slot |
| PDA | 程序派生地址 | 无直接类比(类似 CREATE2) |
| CPI | 程序间调用 | Contract Call |
| IDL | 接口描述 | ABI |
| Instruction | 交易中的操作 | Function Call |
| Signer | 交易签名者 | msg.sender(但更灵活) |
| Rent | 账户存储费 | 无(但有 storage gas) |
EVM DeFi vs Solana DeFi 模式对比
1. Token 操作
EVM (Solidity):
// 合约直接调用 ERC20
IERC20(token).transferFrom(from, to, amount);
// 一行代码,简洁
Solana (Anchor):
// 需要通过 CPI 调用 Token Program
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
Transfer {
from: ctx.accounts.user_token.to_account_info(),
to: ctx.accounts.vault_token.to_account_info(),
authority: ctx.accounts.user.to_account_info(),
},
);
token::transfer(cpi_ctx, amount)?;
// 更多代码,但账户关系更明确
2. 授权模式
EVM:
用户 → approve(spender, amount) → spender 调用 transferFrom
问题: 无限授权风险
Solana:
用户签名交易 → signer 权限传递给 CPI
或: delegate + transfer_checked
优势: 每次交易独立授权
3. 价格预言机
EVM:
AggregatorV3Interface feed = AggregatorV3Interface(FEED_ADDR);
(, int256 price, , uint256 updatedAt, ) = feed.latestRoundData();
// 直接调用,简单
Solana (Pyth Network):
// 需要传入 price feed 账户
let price_account = &ctx.accounts.price_feed;
let price_data = Price::get_price(price_account)?;
// 账户需要在客户端预先传入
4. AMM 实现差异
| 维度 | EVM AMM (Uniswap) | Solana AMM (Raydium/Orca) |
|---|---|---|
| 状态存储 | 合约 storage | PDA 账户 |
| LP Token | 合约内铸造 | CPI 调用 Token Program |
| 路由 | Router 合约 | 链下计算 + 链上验证 |
| 手续费 | 自动累积到池子 | 可以分离到独立账户 |
| 并行性 | 无(串行 EVM) | 不同池子可并行执行 |
| Gas/CU | 动态 Gas 价格 | 固定 CU,优先费可选 |
5. 事件/日志
EVM:
event Transfer(address indexed from, address indexed to, uint256 amount);
emit Transfer(from, to, amount);
// indexed 参数可以高效过滤
Solana:
#[event]
pub struct TransferEvent {
pub from: Pubkey,
pub to: Pubkey,
pub amount: u64,
}
emit!(TransferEvent { from, to, amount });
// 无索引,需要客户端全量解析
安全检查清单回顾
Solidity 安全检查
□ 重入保护: ReentrancyGuard 或 CEI 模式
□ 整数溢出: Solidity 0.8+ 自动检查
□ 授权检查: onlyOwner / access control
□ 预言机安全: staleness + 正数 + round 完整性
□ 滑点保护: minAmountOut 参数
□ 闪电贷防护: 不使用即时价格做重要决策
□ 前跑保护: commit-reveal 或 MEV 保护
Solana/Anchor 安全检查
□ 账户验证: 所有账户用 constraint 约束
□ Signer 检查: 必须的签名者标记为 Signer
□ PDA 验证: seeds + bump 验证
□ 所有者检查: token account 的 owner 和 mint 验证
□ CPI 程序验证: 使用 Program<'info, Token> 而非 AccountInfo
□ 数学安全: checked_add / checked_sub
□ 关闭账户: 注意 rent 和账户关闭时的资金处理
□ 重初始化: 防止已初始化的账户被重新初始化
本周关键代码模式总结
模式1: 手续费 Swap(Solidity)
// 核心: 997/1000 整数运算
uint256 amountInWithFee = amountIn * 997;
uint256 amountOut = (reserveOut * amountInWithFee) /
(reserveIn * 1000 + amountInWithFee);
require(amountOut >= minAmountOut, "Slippage");
模式2: PDA 签名 CPI(Solana)
// 核心: seeds + bump → PDA 可以作为 signer
let seeds = &[b"vault", authority.as_ref(), &[bump]];
let cpi_ctx = CpiContext::new_with_signer(program, accounts, &[seeds]);
token::transfer(cpi_ctx, amount)?;
模式3: Chainlink 安全读取(Solidity)
// 核心: 五项安全检查
(uint80 roundId, int256 answer, , uint256 updatedAt, uint80 answeredInRound)
= feed.latestRoundData();
require(answer > 0, "Invalid price");
require(answeredInRound >= roundId, "Stale round");
require(block.timestamp - updatedAt <= MAX_STALE, "Stale price");
模式4: Anchor 事件监听(TypeScript)
// 核心: addEventListener + cleanup
const listener = program.addEventListener("eventName", (event, slot) => {
console.log(event);
});
// cleanup
program.removeEventListener(listener);
实战练习题
练习1: AMM 手续费计算
池子状态: reserveA = 10,000 ETH, reserveB = 20,000,000 USDC
用户输入: 100 ETH
问题:
1. 无手续费时输出多少 USDC?
2. 0.3% 手续费时输出多少 USDC?
3. 价格冲击是多少?
答案:
1. Δy = 20000000 * 100 / (10000 + 100) = 198,019.80 USDC
2. amountInWithFee = 100 * 997 = 99,700
Δy = 20000000 * 99700 / (10000 * 1000 + 99700)
= 1,994,000,000,000 / 10,099,700
= 197,431.54 USDC
3. 理想输出 = 100 * 2000 = 200,000 USDC (按即时价格)
价格冲击 = (200000 - 197431.54) / 200000 = 1.28%
(其中 0.3% 是手续费,约 0.99% 是纯价格冲击)
练习2: Solana 账户大小计算
VaultState 结构:
authority: Pubkey (32)
token_mint: Pubkey (32)
vault_token_account: Pubkey (32)
total_deposited: u64 (8)
depositor_count: u32 (4)
bump: u8 (1)
created_at: i64 (8)
问题: init 时 space 应该设置为多少?
答案:
8 (discriminator) + 32 + 32 + 32 + 8 + 4 + 1 + 8 = 125 bytes
使用 #[derive(InitSpace)] 后 Anchor 自动计算
space = 8 + VaultState::INIT_SPACE
练习3: Chainlink 精度转换
ETH/USD 价格: 250000000000 (8 decimals) → $2,500.00
用户抵押: 1.5 ETH (1_500_000_000_000_000_000 wei, 18 decimals)
USDC: 6 decimals
问题: 抵押品的 USDC 价值是多少?
答案:
value_usdc = (1.5e18 * 2500e8) / 1e20
= (1.5e18 * 2.5e11) / 1e20
= 3.75e29 / 1e20
= 3.75e9
= 3,750,000,000 (6 decimals)
= $3,750.00 USDC
转换因子 1e20 = 1e18(ETH) * 1e8(price) / 1e6(USDC)
关键要点总结
- AMM 数学是 DeFi 的基石: 恒定乘积公式简洁但威力巨大,理解它就理解了 DEX 的核心
- Solana 的账户模型需要思维转变: 从"合约拥有状态"到"显式传入所有账户"
- CPI 是 Solana 可组合性的关键: 但比 EVM 的合约调用需要更多样板代码
- 预言机安全不可忽视: Chainlink 五项检查是最低标准,生产环境需要更多防护
- 前端集成模式差异大: Solana 需要客户端计算 PDA、构建完整账户列表,比 EVM 复杂
常见误区
误区1: "Solana 比 EVM 难,所以不值得学"
纠正: 难度更高但有回报。Solana 的并行执行模型带来性能优势,理解两个生态让你成为更全面的开发者。实际上 Anchor 已经大幅降低了入门门槛。
误区2: "AMM 的无常损失使 LP 不赚钱"
纠正: 无常损失是"相对于持有"的机会成本。LP 通过手续费收入可以超过无常损失。关键是选择合适的池子和价格范围(V3)。高交易量 + 低波动率的池子通常对 LP 有利。
误区3: "所有 DeFi 协议都用 Chainlink"
纠正: 虽然 Chainlink 最主流,但不同协议有不同选择。Maker 用自己的预言机模块、Uniswap 用内建 TWAP、Compound 使用多预言机方案。选择取决于安全需求、成本和可用性。
面试关联
Q: "比较 EVM 和 Solana 的 DeFi 开发体验,各有什么优劣?"
参考回答:
EVM 优势:
- 开发者工具更成熟(Foundry/Hardhat/Ethers.js)
- 合约调用简洁(不需要显式传入所有账户)
- 可组合性极强(无限嵌套调用)
- 更多开源代码和审计资源
Solana 优势:
- 高 TPS(每秒可处理数千交易)
- 低交易成本(通常 < $0.01)
- 并行执行提高吞吐量
- 账户模型让并发更安全
EVM 劣势:
- Gas 成本高(复杂交易可能 $50+)
- 串行执行限制吞吐量
- MEV 问题更严重
Solana 劣势:
- 开发复杂度更高(Rust + 账户模型)
- 工具生态不如 EVM 成熟
- 历史上有宕机事件
- 事件索引能力弱
Q: "如果要设计一个跨 EVM 和 Solana 的 DeFi 产品,架构上怎么考虑?"
参考回答:
- 核心逻辑分别实现: EVM 用 Solidity,Solana 用 Anchor,保持接口一致
- 前端统一: 使用适配器模式,抽象出统一的 DeFi 交互接口
- 跨链桥接: 使用 Wormhole 等跨链消息协议同步状态
- 预言机统一: 两边都用 Chainlink/Pyth,保证价格一致性
- 治理统一: 可以在一条链上做治理,通过跨链消息在另一条链执行
参考资源
- Uniswap V2 数学推导 - 官方数学文档
- Solana vs EVM 对比 - 官方迁移指南
- Anchor Book - 完整 Anchor 文档
- Chainlink 架构 - 预言机网络架构
- DeFi Developer Road Map - DeFi 开发路线图