返回 SC 笔记
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 #对比分析


今日目标

  1. 系统回顾 Week 7 所有知识点(AMM 进阶、CPI、Chainlink、Anchor 事件)
  2. 深入理解 AMM 数学公式推导
  3. 对比 EVM DeFi 和 Solana DeFi 的开发模式差异
  4. 建立跨链开发的知识框架

核心概念

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 TokenERC20 (同质)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)
状态存储合约 storagePDA 账户
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)?;
// 核心: 五项安全检查
(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
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)

关键要点总结

  1. AMM 数学是 DeFi 的基石: 恒定乘积公式简洁但威力巨大,理解它就理解了 DEX 的核心
  2. Solana 的账户模型需要思维转变: 从"合约拥有状态"到"显式传入所有账户"
  3. CPI 是 Solana 可组合性的关键: 但比 EVM 的合约调用需要更多样板代码
  4. 预言机安全不可忽视: Chainlink 五项检查是最低标准,生产环境需要更多防护
  5. 前端集成模式差异大: Solana 需要客户端计算 PDA、构建完整账户列表,比 EVM 复杂

常见误区

误区1: "Solana 比 EVM 难,所以不值得学"

纠正: 难度更高但有回报。Solana 的并行执行模型带来性能优势,理解两个生态让你成为更全面的开发者。实际上 Anchor 已经大幅降低了入门门槛。

误区2: "AMM 的无常损失使 LP 不赚钱"

纠正: 无常损失是"相对于持有"的机会成本。LP 通过手续费收入可以超过无常损失。关键是选择合适的池子和价格范围(V3)。高交易量 + 低波动率的池子通常对 LP 有利。

纠正: 虽然 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 产品,架构上怎么考虑?"

参考回答:

  1. 核心逻辑分别实现: EVM 用 Solidity,Solana 用 Anchor,保持接口一致
  2. 前端统一: 使用适配器模式,抽象出统一的 DeFi 交互接口
  3. 跨链桥接: 使用 Wormhole 等跨链消息协议同步状态
  4. 预言机统一: 两边都用 Chainlink/Pyth,保证价格一致性
  5. 治理统一: 可以在一条链上做治理,通过跨链消息在另一条链执行

参考资源