1071 lines
22 KiB
Markdown
1071 lines
22 KiB
Markdown
# DeFi协议与AMM
|
||
|
||
## 问题
|
||
|
||
1. 什么是DeFi(去中心化金融)?与传统金融的区别?
|
||
2. 什么是AMM(自动做市商)?它如何工作?
|
||
3. Uniswap V2、V3的区别是什么?
|
||
4. 什么是流动性池(Liquidity Pool)?
|
||
5. 什么是无常损失(Impermanent Loss)?如何计算?
|
||
6. 什么是流动性挖矿(Yield Farming)?
|
||
7. 什么是闪电贷(Flash Loan)?有什么应用场景?
|
||
8. 什么是DEX聚合器?1inch如何工作?
|
||
9. 借贷协议(Aave、Compound)如何工作?
|
||
10. 什么是清算(Liquidation)?如何避免被清算?
|
||
|
||
---
|
||
|
||
## 标准答案
|
||
|
||
### 1. DeFi vs 传统金融
|
||
|
||
#### **对比表**
|
||
|
||
| 特性 | 传统金融(CeFi) | 去中心化金融(DeFi) |
|
||
|------|-----------------|---------------------|
|
||
| **中介** | 银行、券商 | 智能合约 |
|
||
| **准入门槛** | 需要KYC、银行账户 | 只需要钱包 |
|
||
| **营业时间** | 工作日 9-5 | 24/7 |
|
||
| **透明度** | 不透明 | 完全透明 |
|
||
| **速度** | 1-3天 | 几秒到几分钟 |
|
||
| **成本** | 高(中介费) | 低(Gas费) |
|
||
| **风险** | 信用风险、操作风险 | 智能合约风险、黑客攻击 |
|
||
|
||
#### **DeFi核心组件**
|
||
|
||
```
|
||
1. 交易所(DEX)
|
||
- Uniswap(AMM)
|
||
- Curve(稳定币)
|
||
- Balancer
|
||
|
||
2. 借贷
|
||
- Aave
|
||
- Compound
|
||
- MakerDAO
|
||
|
||
3. 稳定币
|
||
- USDT、USDC(中心化)
|
||
- DAI(去中心化)
|
||
|
||
4. 衍生品
|
||
- dYdX
|
||
- Synthetix
|
||
- GMX
|
||
|
||
5. 聚合器
|
||
- 1inch
|
||
- Paraswap
|
||
```
|
||
|
||
---
|
||
|
||
### 2. AMM(自动做市商)
|
||
|
||
#### **传统订单簿 vs AMM**
|
||
|
||
**传统订单簿(CEX)**:
|
||
```
|
||
买单(Bid) 卖单(Ask)
|
||
100 USDT @ 2000 101 USDT @ 2001
|
||
150 USDT @ 1999 200 USDT @ 2002
|
||
200 USDT @ 1998 150 USDT @ 2003
|
||
|
||
需要:
|
||
- 买卖双方
|
||
- 撮合引擎
|
||
- 做市商提供流动性
|
||
```
|
||
|
||
**AMM(DEX)**:
|
||
```
|
||
流动性池:
|
||
- ETH/USDT 池
|
||
- 100 ETH + 200,000 USDT
|
||
- 价格 = 2000 USDT/ETH
|
||
|
||
不需要:
|
||
- 买卖双方匹配
|
||
- 撮合引擎
|
||
- 传统做市商
|
||
|
||
由算法自动定价
|
||
```
|
||
|
||
---
|
||
|
||
#### **Uniswap V2:恒定乘积公式**
|
||
|
||
```
|
||
x * y = k
|
||
|
||
x = Token A 的数量
|
||
y = Token B 的数量
|
||
k = 恒定值(常数)
|
||
```
|
||
|
||
**示例**:
|
||
```solidity
|
||
// Uniswap V2 核心公式
|
||
function getAmountOut(
|
||
uint amountIn,
|
||
uint reserveIn,
|
||
uint reserveOut
|
||
) public pure returns (uint amountOut) {
|
||
uint amountInWithFee = amountIn * 997; // 0.3% 手续费
|
||
uint numerator = amountInWithFee * reserveOut;
|
||
uint denominator = reserveIn * 1000 + amountInWithFee;
|
||
amountOut = numerator / denominator;
|
||
}
|
||
```
|
||
|
||
**交易示例**:
|
||
```
|
||
初始状态:
|
||
ETH Reserve: 100 ETH
|
||
USDT Reserve: 200,000 USDT
|
||
k = 100 * 200,000 = 20,000,000
|
||
|
||
用户用 1 ETH 买 USDT:
|
||
1. 输入:1 ETH
|
||
2. 手续费:1 * 0.3% = 0.003 ETH
|
||
3. 实际参与定价:0.997 ETH
|
||
4. 新的 ETH 储备:100 + 0.997 = 100.997 ETH
|
||
5. 新的 USDT 储备:20,000,000 / 100.997 ≈ 198,025.94 USDT
|
||
6. 用户获得:200,000 - 198,025.94 ≈ 1,974.06 USDT
|
||
|
||
价格影响:
|
||
- 实际价格:1,974.06 USDT/ETH
|
||
- 理论价格:2,000 USDT/ETH
|
||
- 滑点:(2000 - 1974.06) / 2000 ≈ 1.3%
|
||
```
|
||
|
||
---
|
||
|
||
#### **价格滑点(Slippage)**
|
||
|
||
```
|
||
交易量越大,价格滑点越大
|
||
|
||
公式:
|
||
新价格 = (reserveOut * amountIn) / (reserveIn + amountIn)
|
||
|
||
滑点 = (原价格 - 新价格) / 原价格
|
||
```
|
||
|
||
**代码示例**:
|
||
```go
|
||
type AMM struct {
|
||
ReserveTokenA float64
|
||
ReserveTokenB float64
|
||
Fee float64 // 0.003 = 0.3%
|
||
}
|
||
|
||
func (a *AMM) Swap(amountIn float64, tokenIn string) float64 {
|
||
if tokenIn == "A" {
|
||
amountInWithFee := amountIn * (1 - a.Fee)
|
||
amountOut := (a.ReserveTokenB * amountInWithFee) / (a.ReserveTokenA + amountInWithFee)
|
||
|
||
// 更新储备
|
||
a.ReserveTokenA += amountIn
|
||
a.ReserveTokenB -= amountOut
|
||
|
||
return amountOut
|
||
}
|
||
// 反向交易类似
|
||
return 0
|
||
}
|
||
|
||
func (a *AMM) GetPrice() float64 {
|
||
return a.ReserveTokenB / a.ReserveTokenA
|
||
}
|
||
|
||
func (a *AMM) GetSlippage(amountIn float64) float64 {
|
||
spotPrice := a.GetPrice()
|
||
amountOut := a.Swap(amountIn, "A")
|
||
executionPrice := amountIn / amountOut
|
||
|
||
return (executionPrice - spotPrice) / spotPrice
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. Uniswap V3:集中流动性
|
||
|
||
#### **V2 vs V3 对比**
|
||
|
||
| 特性 | Uniswap V2 | Uniswap V3 |
|
||
|------|-----------|-----------|
|
||
| **流动性范围** | 0 ~ ∞(全范围) | 自定义价格区间 |
|
||
| **资金效率** | 低 | 高(最高4000倍) |
|
||
| **手续费** | 固定0.3% | 0.01%/0.05%/0.3%/1% |
|
||
| **LP Token** | ERC-20(可替换) | NFT(不可替换) |
|
||
| **适用场景** | 通用 | 稳定币、高波动币 |
|
||
|
||
---
|
||
|
||
#### **V3核心创新:集中流动性**
|
||
|
||
**V2(全范围流动性)**:
|
||
```
|
||
ETH价格:2000 USDT
|
||
|
||
LP提供流动性:
|
||
- 范围:0 ~ ∞
|
||
- 实际交易区间:1800 ~ 2200 USDT
|
||
- 资金利用率:(2200-1800) / ∞ ≈ 0%
|
||
|
||
大部分资金永远不会被使用
|
||
```
|
||
|
||
**V3(集中流动性)**:
|
||
```
|
||
LP可以选择价格区间:
|
||
- 下限:1800 USDT
|
||
- 上限:2200 USDT
|
||
- 当前价格:2000 USDT
|
||
|
||
资金集中在这个区间,利用率大幅提高
|
||
```
|
||
|
||
**数学公式**:
|
||
```solidity
|
||
// V3 流动性计算
|
||
function getLiquidityForAmounts(
|
||
uint160 sqrtRatioX96, // 当前价格的平方根
|
||
uint160 sqrtRatioAX96, // 价格区间下限的平方根
|
||
uint160 sqrtRatioBX96, // 价格区间上限的平方根
|
||
uint256 amount0,
|
||
uint256 amount1
|
||
) internal pure returns (uint128 liquidity) {
|
||
if (sqrtRatioAX96 > sqrtRatioBX96) {
|
||
(sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96);
|
||
}
|
||
|
||
if (sqrtRatioX96 <= sqrtRatioAX96) {
|
||
// 当前价格低于区间
|
||
liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0);
|
||
} else if (sqrtRatioX96 < sqrtRatioBX96) {
|
||
// 当前价格在区间内
|
||
uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0);
|
||
uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1);
|
||
liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1;
|
||
} else {
|
||
// 当前价格高于区间
|
||
liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
#### **V3实际应用**
|
||
|
||
**稳定币池(USDC/USDT)**:
|
||
```
|
||
价格区间:0.999 ~ 1.001
|
||
手续费:0.01%
|
||
资金效率:V2的2000倍
|
||
|
||
原因:
|
||
- 稳定币价格几乎1:1
|
||
- 集中在极小区间
|
||
- 极高资金利用率
|
||
```
|
||
|
||
**高波动币(ETH/SHIB)**:
|
||
```
|
||
价格区间:0.00000001 ~ 0.0000001
|
||
手续费:1%
|
||
资金效率:V2的100倍
|
||
|
||
原因:
|
||
- 波动大,需要更宽区间
|
||
- 高风险,高手续费
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 流动性池(Liquidity Pool)
|
||
|
||
#### **工作原理**
|
||
|
||
```
|
||
1. 流动性提供者(LP)存入两种代币
|
||
- 例如:10 ETH + 20,000 USDT
|
||
|
||
2. 获得LP Token
|
||
- 代表池子份额
|
||
- 例如:100 LP Token
|
||
|
||
3. 交易者交易
|
||
- 支付手续费(0.3%)
|
||
- 手续费留在池中
|
||
|
||
4. LP提取
|
||
- 返还LP Token
|
||
- 获得本金 + 手续费收益
|
||
```
|
||
|
||
#### **代码实现**
|
||
|
||
```solidity
|
||
pragma solidity ^0.8.0;
|
||
|
||
contract LiquidityPool {
|
||
uint256 public reserve0; // Token0 储备
|
||
uint256 public reserve1; // Token1 储备
|
||
uint256 public totalSupply; // LP Token 总量
|
||
|
||
mapping(address => uint256) public balanceOf; // LP Token 余额
|
||
|
||
// 添加流动性
|
||
function addLiquidity(
|
||
uint256 amount0,
|
||
uint256 amount1
|
||
) external returns (uint256 liquidity) {
|
||
// 转入代币
|
||
IERC20(token0).transferFrom(msg.sender, address(this), amount0);
|
||
IERC20(token1).transferFrom(msg.sender, address(this), amount1);
|
||
|
||
// 计算LP Token数量
|
||
if (totalSupply == 0) {
|
||
// 首次添加
|
||
liquidity = sqrt(amount0 * amount1);
|
||
} else {
|
||
liquidity = min(
|
||
(amount0 * totalSupply) / reserve0,
|
||
(amount1 * totalSupply) / reserve1
|
||
);
|
||
}
|
||
|
||
// 铸造LP Token
|
||
balanceOf[msg.sender] += liquidity;
|
||
totalSupply += liquidity;
|
||
|
||
// 更新储备
|
||
reserve0 += amount0;
|
||
reserve1 += amount1;
|
||
}
|
||
|
||
// 移除流动性
|
||
function removeLiquidity(
|
||
uint256 liquidity
|
||
) external returns (uint256 amount0, uint256 amount1) {
|
||
// 计算可提取数量
|
||
amount0 = (liquidity * reserve0) / totalSupply;
|
||
amount1 = (liquidity * reserve1) / totalSupply;
|
||
|
||
// 销毁LP Token
|
||
balanceOf[msg.sender] -= liquidity;
|
||
totalSupply -= liquidity;
|
||
|
||
// 更新储备
|
||
reserve0 -= amount0;
|
||
reserve1 -= amount1;
|
||
|
||
// 转出代币
|
||
IERC20(token0).transfer(msg.sender, amount0);
|
||
IERC20(token1).transfer(msg.sender, amount1);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 无常损失(Impermanent Loss)
|
||
|
||
#### **定义**
|
||
|
||
无常损失是指:LP提供流动性后,因价格变化导致的损失(相对于单纯持有代币)。
|
||
|
||
#### **计算公式**
|
||
|
||
```
|
||
无常损失 = (池中资产价值 - 单纯持有价值) / 单纯持有价值
|
||
|
||
简化公式:
|
||
IL = 2 * sqrt(price_ratio) / (1 + price_ratio) - 1
|
||
|
||
price_ratio = 新价格 / 初始价格
|
||
```
|
||
|
||
#### **示例**
|
||
|
||
```
|
||
初始状态:
|
||
- ETH价格:2000 USDT
|
||
- 存入:1 ETH + 2000 USDT
|
||
- 总价值:4000 USDT
|
||
|
||
价格上涨到 3000 USDT:
|
||
1. 池子调整(套利者搬砖):
|
||
- 新储备:0.816 ETH + 2449 USDT
|
||
- 池中价值:0.816 * 3000 + 2449 = 4897 USDT
|
||
|
||
2. 单纯持有:
|
||
- 1 ETH + 2000 USDT
|
||
- 价值:1 * 3000 + 2000 = 5000 USDT
|
||
|
||
3. 无常损失:
|
||
IL = (4897 - 5000) / 5000 = -2.06%
|
||
|
||
损失:103 USDT
|
||
```
|
||
|
||
#### **代码计算**
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"math"
|
||
)
|
||
|
||
// 计算无常损失
|
||
func CalculateImpermanentLoss(priceRatio float64) float64 {
|
||
// IL = 2 * sqrt(r) / (1 + r) - 1
|
||
sqrtR := math.Sqrt(priceRatio)
|
||
il := (2*sqrtR)/(1+priceRatio) - 1
|
||
return il
|
||
}
|
||
|
||
// 计算LP收益(考虑手续费)
|
||
func CalculateLPReturn(
|
||
initialPrice float64,
|
||
finalPrice float64,
|
||
feeRate float64,
|
||
volume float64,
|
||
) float64 {
|
||
priceRatio := finalPrice / initialPrice
|
||
|
||
// 无常损失
|
||
il := CalculateImpermanentLoss(priceRatio)
|
||
|
||
// 手续费收益(假设交易量)
|
||
feeReturn := volume * feeRate
|
||
|
||
// 总收益 = 手续费收益 + 无常损失
|
||
totalReturn := feeReturn + il
|
||
|
||
return totalReturn
|
||
}
|
||
|
||
func main() {
|
||
// 价格从 2000 涨到 3000(价格比率 1.5)
|
||
il := CalculateImpermanentLoss(1.5)
|
||
fmt.Printf("无常损失: %.2f%%\n", il*100)
|
||
|
||
// 价格从 2000 跌到 1000(价格比率 0.5)
|
||
il2 := CalculateImpermanentLoss(0.5)
|
||
fmt.Printf("无常损失: %.2f%%\n", il2*100)
|
||
|
||
// 考虑手续费
|
||
totalReturn := CalculateLPReturn(2000, 3000, 0.003, 1000000)
|
||
fmt.Printf("总收益(含手续费): %.2f%%\n", totalReturn*100)
|
||
}
|
||
```
|
||
|
||
**输出**:
|
||
```
|
||
无常损失: -2.06%
|
||
无常损失: -2.06%
|
||
总收益(含手续费): 1.94%
|
||
```
|
||
|
||
#### **无常损失表**
|
||
|
||
| 价格变化 | 无常损失 |
|
||
|---------|---------|
|
||
| 1.25x | -0.6% |
|
||
| 1.50x | -2.0% |
|
||
| 1.75x | -3.8% |
|
||
| 2.00x | -5.7% |
|
||
| 3.00x | -13.4% |
|
||
| 4.00x | -20.0% |
|
||
| 5.00x | -25.5% |
|
||
|
||
**结论**:
|
||
- 价格变化越大,无常损失越大
|
||
- 稳定币池无常损失最小
|
||
- 高波动币池需要高手续费补偿
|
||
|
||
---
|
||
|
||
### 6. 流动性挖矿(Yield Farming)
|
||
|
||
#### **定义**
|
||
|
||
通过提供流动性或借贷,获得代币奖励,实现收益最大化。
|
||
|
||
#### **收益来源**
|
||
|
||
```
|
||
1. 交易手续费
|
||
- Uniswap: 0.3%
|
||
- Curve: 0.04%
|
||
|
||
2. 借贷利息
|
||
- 存款利息
|
||
- 借款利率差
|
||
|
||
3. 代币激励
|
||
- COMP(Compound)
|
||
- AAVE(Aave)
|
||
- UNI(Uniswap)
|
||
|
||
4. 挖矿奖励
|
||
- 质押LP Token
|
||
- 获得项目代币
|
||
```
|
||
|
||
#### **APY计算**
|
||
|
||
```
|
||
APY = (1 + APR/365)^365 - 1
|
||
|
||
APR(年化收益率):
|
||
- 交易手续费收益
|
||
- 借贷利息收益
|
||
- 代币激励收益
|
||
|
||
示例:
|
||
APR = 30%
|
||
APY = (1 + 0.3/365)^365 - 1 = 34.97%
|
||
```
|
||
|
||
#### **策略示例**
|
||
|
||
```go
|
||
type YieldFarm struct {
|
||
Pool string
|
||
TVL float64 // 总锁仓量
|
||
DailyVolume float64 // 日交易量
|
||
FeeRate float64 // 手续费率
|
||
RewardAPR float64 // 代币奖励APR
|
||
}
|
||
|
||
func (yf *YieldFarm) CalculateAPY() float64 {
|
||
// 手续费收益
|
||
dailyFee := yf.DailyVolume * yf.FeeRate
|
||
yearlyFee := dailyFee * 365
|
||
feeAPR := yearlyFee / yf.TVL
|
||
|
||
// 总APR
|
||
totalAPR := feeAPR + yf.RewardAPR
|
||
|
||
// APY
|
||
APY := math.Pow(1+totalAPR/365, 365) - 1
|
||
return APY
|
||
}
|
||
|
||
func main() {
|
||
// Uniswap ETH/USDT 池
|
||
pool := YieldFarm{
|
||
Pool: "ETH/USDT",
|
||
TVL: 10000000, // 1000万
|
||
DailyVolume: 5000000, // 500万
|
||
FeeRate: 0.003, // 0.3%
|
||
RewardAPR: 0.1, // 10% 代币奖励
|
||
}
|
||
|
||
apy := pool.CalculateAPY()
|
||
fmt.Printf("APY: %.2f%%\n", apy*100)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 7. 闪电贷(Flash Loan)
|
||
|
||
#### **定义**
|
||
|
||
无需抵押,在一笔交易内借款并还款的贷款。
|
||
|
||
#### **特点**
|
||
|
||
```
|
||
1. 无需抵押
|
||
2. 必须在同一笔交易内还款
|
||
3. 如果还款失败,整个交易回滚
|
||
4. 手续费:0.09%(Aave)
|
||
```
|
||
|
||
#### **应用场景**
|
||
|
||
**1. 套利**
|
||
```solidity
|
||
// 套利示例
|
||
function executeArbitrage() external {
|
||
// 1. 闪电贷借入 1000 ETH
|
||
uint256 loanAmount = 1000 ether;
|
||
flashLoan(loanAmount);
|
||
|
||
// 2. 在 Uniswap 用 ETH 买 USDT
|
||
// 价格:1 ETH = 2000 USDT
|
||
uint256 usdtAmount = uniswap.swap(loanAmount);
|
||
|
||
// 3. 在 SushiSwap 用 USDT 买回 ETH
|
||
// 价格:1 ETH = 2010 USDT
|
||
uint256 ethAmount = sushiswap.swap(usdtAmount);
|
||
|
||
// 4. 还款 1000 ETH + 手续费
|
||
uint256 repayment = loanAmount * 10009 / 10000;
|
||
repay(repayment);
|
||
|
||
// 5. 利润 = ethAmount - repayment
|
||
// 如果利润 < 0,交易回滚
|
||
}
|
||
```
|
||
|
||
**2. 清算**
|
||
```solidity
|
||
// 清算获利
|
||
function liquidate(address borrower) external {
|
||
// 1. 闪电贷借入 USDT
|
||
flashLoan(10000 * 1e6);
|
||
|
||
// 2. 清算借款人
|
||
// 清算折扣:5%
|
||
uint256 collateral = liquidateBorrower(borrower);
|
||
|
||
// 3. 卖掉抵押品
|
||
uint256 usdtReceived = sellCollateral(collateral);
|
||
|
||
// 4. 还款 + 赚取清算奖励
|
||
repay(10000 * 1e6);
|
||
|
||
// 利润 = usdtReceived - 10000 USDT + 清算奖励
|
||
}
|
||
```
|
||
|
||
**3. 更改DeFi头寸**
|
||
```solidity
|
||
// 无需本金切换协议
|
||
function switchProtocol() external {
|
||
// 1. 闪电贷借入资金
|
||
flashLoan(amount);
|
||
|
||
// 2. 从 Aave 取出抵押品
|
||
aave.withdraw(collateral);
|
||
|
||
// 3. 存入 Compound
|
||
compound.deposit(collateral);
|
||
|
||
// 4. 还款
|
||
repay(amount);
|
||
|
||
// 实现无本金迁移
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 8. DEX聚合器(1inch)
|
||
|
||
#### **工作原理**
|
||
|
||
```
|
||
1. 用户发起交易请求
|
||
- 输入:1 ETH
|
||
- 输出:期望获得最多 USDT
|
||
|
||
2. 聚合器查询多个DEX
|
||
- Uniswap: 2000 USDT
|
||
- SushiSwap: 1995 USDT
|
||
- Curve: 1998 USDT
|
||
|
||
3. 拆分订单(最优路径)
|
||
- Uniswap: 0.6 ETH → 1201 USDT
|
||
- SushiSwap: 0.4 ETH → 799 USDT
|
||
- 总计:2000 USDT
|
||
|
||
4. 执行交易
|
||
```
|
||
|
||
#### **路径优化算法**
|
||
|
||
```go
|
||
type DEX struct {
|
||
Name string
|
||
Reserve0 float64
|
||
Reserve1 float64
|
||
Fee float64
|
||
}
|
||
|
||
type Router struct {
|
||
Dexs []DEX
|
||
}
|
||
|
||
// 计算最优路径
|
||
func (r *Router) FindBestRoute(
|
||
amountIn float64,
|
||
) []struct {
|
||
Dex string
|
||
Amount float64
|
||
} {
|
||
type Route struct {
|
||
Dex string
|
||
AmountIn float64
|
||
AmountOut float64
|
||
}
|
||
|
||
var routes []Route
|
||
|
||
// 1. 单DEX路由
|
||
for _, dex := range r.Dexs {
|
||
amountOut := r.calculateOutput(dex, amountIn)
|
||
routes = append(routes, Route{
|
||
Dex: dex.Name,
|
||
AmountIn: amountIn,
|
||
AmountOut: amountOut,
|
||
})
|
||
}
|
||
|
||
// 2. 多DEX拆分(二分查找最优解)
|
||
for _, dex1 := range r.Dexs {
|
||
for _, dex2 := range r.Dexs {
|
||
if dex1.Name == dex2.Name {
|
||
continue
|
||
}
|
||
|
||
// 二分查找最优拆分
|
||
left, right := 0.0, amountIn
|
||
for i := 0; i < 50; i++ {
|
||
mid1 := (left + right) / 2
|
||
mid2 := amountIn - mid1
|
||
|
||
out1 := r.calculateOutput(dex1, mid1)
|
||
out2 := r.calculateOutput(dex2, mid2)
|
||
|
||
total := out1 + out2
|
||
|
||
routes = append(routes, Route{
|
||
Dex: dex1.Name + " + " + dex2.Name,
|
||
AmountIn: amountIn,
|
||
AmountOut: total,
|
||
})
|
||
}
|
||
}
|
||
}
|
||
|
||
// 3. 选择最优
|
||
sort.Slice(routes, func(i, j int) bool {
|
||
return routes[i].AmountOut > routes[j].AmountOut
|
||
})
|
||
|
||
return routes[0]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 9. 借贷协议(Aave、Compound)
|
||
|
||
#### **工作原理**
|
||
|
||
```
|
||
存款人:
|
||
1. 存入资产(如USDT)
|
||
2. 获得利息
|
||
3. 获得aToken(Aave)或cToken(Compound)
|
||
|
||
借款人:
|
||
1. 存入抵押品(如ETH)
|
||
2. 根据抵押率借款
|
||
3. 支付利息
|
||
```
|
||
|
||
#### **利率模型**
|
||
|
||
```solidity
|
||
// Compound 利率模型
|
||
function getBorrowRate(uint256 cash, uint256 borrows) public view returns (uint256) {
|
||
uint256 utilization = borrows * 1e18 / (cash + borrows);
|
||
|
||
// 分段利率
|
||
if (utilization < kink) {
|
||
// 低利用率:利率增长慢
|
||
return baseRate + utilization * multiplier;
|
||
} else {
|
||
// 高利用率:利率增长快
|
||
uint256 normalRate = baseRate + kink * multiplier;
|
||
uint256 excessUtil = utilization - kink;
|
||
return normalRate + excessUtil * jumpMultiplier;
|
||
}
|
||
}
|
||
|
||
// 示例:
|
||
// 利用率 < 80%: 利率 = 2% + 利用率 * 10%
|
||
// 利用率 > 80%: 利率快速增长到 20%+
|
||
```
|
||
|
||
**利用率(Utilization Rate)**:
|
||
```
|
||
利用率 = 总借款 / (总存款 + 总借款)
|
||
|
||
例如:
|
||
存款:1000万 USDT
|
||
借款:800万 USDT
|
||
利用率:800 / 1000 = 80%
|
||
|
||
利率与利用率的关系:
|
||
- 利用率越高,利率越高
|
||
- 鼓励存款,抑制借款
|
||
```
|
||
|
||
---
|
||
|
||
#### **抵押率(Collateral Factor)**
|
||
|
||
```
|
||
抵押率决定了可以借多少
|
||
|
||
例如:
|
||
- ETH抵押率:75%
|
||
- 存入10 ETH(价值$20,000)
|
||
- 可借款:20,000 * 75% = $15,000
|
||
|
||
不同资产抵押率:
|
||
- ETH: 75%
|
||
- WBTC: 70%
|
||
- USDC: 80%
|
||
- SHIB: 40%(高风险资产)
|
||
```
|
||
|
||
---
|
||
|
||
### 10. 清算(Liquidation)
|
||
|
||
#### **清算机制**
|
||
|
||
```
|
||
健康因子(Health Factor):
|
||
|
||
HF = (抵押品价值 * 抵押率) / 借款价值
|
||
|
||
HF > 1: 安全
|
||
HF < 1: 可被清算
|
||
|
||
清算奖励:5-15%(激励清算人)
|
||
```
|
||
|
||
#### **清算示例**
|
||
|
||
```solidity
|
||
// 清算逻辑
|
||
function liquidate(
|
||
address borrower,
|
||
address collateralAsset,
|
||
address debtAsset,
|
||
uint256 debtToCover
|
||
) external {
|
||
// 1. 检查健康因子
|
||
uint256 healthFactor = getHealthFactor(borrower);
|
||
require(healthFactor < 1e18, "Cannot liquidate");
|
||
|
||
// 2. 计算可清算数量
|
||
uint256 maxDebt = getMaxDebt(borrower);
|
||
uint256 debt = min(debtToCover, maxDebt);
|
||
|
||
// 3. 清算人偿还债务
|
||
IERC20(debtAsset).transferFrom(msg.sender, address(this), debt);
|
||
|
||
// 4. 给清算人抵押品(折扣5%)
|
||
uint256 collateral = (debt * 105) / 100;
|
||
IERC20(collateralAsset).transfer(msg.sender, collateral);
|
||
|
||
// 5. 更新借款人状态
|
||
updateBorrowerState(borrower, debt, collateral);
|
||
}
|
||
```
|
||
|
||
**示例**:
|
||
```
|
||
借款人状态:
|
||
- 存入:10 ETH($20,000)
|
||
- 借款:15,000 USDT
|
||
- ETH价格跌到 $1,800
|
||
- 抵押品价值:$18,000
|
||
|
||
健康因子:
|
||
HF = (18,000 * 0.75) / 15,000 = 0.9 < 1
|
||
|
||
可被清算:
|
||
- 清算人偿还 15,000 USDT
|
||
- 获得抵押品:15,000 * 1.05 = 15,750 USDT价值
|
||
- 实际获得:15,750 / 1,800 ≈ 8.75 ETH
|
||
- 清算人利润:0.75 ETH($1,350)
|
||
```
|
||
|
||
#### **避免被清算**
|
||
|
||
```
|
||
1. 监控健康因子
|
||
- 设置告警(HF < 1.2)
|
||
- 及时还款或增加抵押品
|
||
|
||
2. 选择稳定抵押品
|
||
- 避免高波动资产
|
||
- 优先选择ETH、WBTC
|
||
|
||
3. 不要满仓借款
|
||
- 保持安全边际
|
||
- 借款不超过50%
|
||
|
||
4. 使用DeFi Saver等工具
|
||
- 自动化风险管理
|
||
- 自动还款/增加抵押
|
||
```
|
||
|
||
---
|
||
|
||
## 结合简历的面试题
|
||
|
||
### 1. 高并发与AMM
|
||
|
||
**面试官会问**:
|
||
> "你做过50k+ QPS的消费券系统,AMM DEX如何处理高并发?"
|
||
|
||
**参考回答**:
|
||
```
|
||
传统高并发(Web2):
|
||
- 消费券抢购:50k QPS
|
||
- 使用Redis缓存
|
||
- 使用消息队列削峰
|
||
- 使用分布式锁
|
||
|
||
AMM DEX高并发(Web3):
|
||
- 区块链TPS限制(Ethereum: 15 TPS)
|
||
- 解决方案:
|
||
|
||
1. Layer2
|
||
- Arbitrum: 4000+ TPS
|
||
- Optimism: 2000+ TPS
|
||
- 使用Rollup扩容
|
||
|
||
2. 交易池管理
|
||
- Gas Price竞价
|
||
- 优先级队列
|
||
- 交易打包优化
|
||
|
||
3. MEV(矿工可提取价值)
|
||
- 套利机器人
|
||
- 三明治攻击
|
||
- 需要抗MEV设计
|
||
|
||
4. 链下撮合 + 链上结算
|
||
- Loopring(ZK-Rollup DEX)
|
||
- dYdX(链下订单簿)
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 低代码与智能合约开发
|
||
|
||
**面试官会问**:
|
||
> "你做过低代码平台,智能合约开发有哪些低代码/无代码方案?"
|
||
|
||
**参考回答**:
|
||
```
|
||
传统低代码:
|
||
- aPaaS平台
|
||
- 可视化搭建
|
||
- 模板+配置
|
||
|
||
Web3低代码:
|
||
|
||
1. 智能合约模板
|
||
- OpenZeppelin Wizard
|
||
- 拖拽式生成合约
|
||
- 自动安全审计
|
||
|
||
2. 无代码部署
|
||
- Thirdweb
|
||
- 无需写代码部署NFT、Token
|
||
- 一键发币
|
||
|
||
3. 可视化IDE
|
||
- Remix IDE
|
||
- 图形化调试
|
||
- 在线编译部署
|
||
|
||
4. SDK封装
|
||
- Ethers.js
|
||
- Web3.js
|
||
- 简化合约交互
|
||
|
||
对比:
|
||
- 传统:降本增效
|
||
- Web3:降低开发门槛,加速生态发展
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 营销系统与DeFi激励
|
||
|
||
**面试官会问**:
|
||
> "你做过营销表达和策略玩法,DeFi的激励机制如何设计?"
|
||
|
||
**参考回答**:
|
||
```
|
||
传统营销:
|
||
- 消费券
|
||
- 满减活动
|
||
- 会员等级
|
||
|
||
DeFi激励:
|
||
1. 流动性挖矿
|
||
- 提供流动性获得代币奖励
|
||
- 类似消费券:吸引用户
|
||
|
||
2. 交易挖矿
|
||
- 交易即挖矿
|
||
- 类似满减:降低交易成本
|
||
|
||
3. 治理权
|
||
- 持有代币可投票
|
||
- 类似会员:参与决策
|
||
|
||
4. 质押奖励
|
||
- 锁仓获得高收益
|
||
- 类似定期存款
|
||
|
||
关键差异:
|
||
- 传统:中心化决策
|
||
- DeFi:代币化激励,社区治理
|
||
```
|
||
|
||
---
|
||
|
||
## DeFi面试加分项
|
||
|
||
### 1. 实战经验
|
||
|
||
- 参与过DeFi项目开发
|
||
- 熟悉主流协议(Uniswap、Aave、Compound)
|
||
- 了解链上数据分析(Dune Analytics)
|
||
- 有MEV研究经验
|
||
|
||
### 2. 技术深度
|
||
|
||
- 理解AMM数学原理
|
||
- 了解利率模型设计
|
||
- 熟悉预言机机制
|
||
- 掌握Gas优化技巧
|
||
|
||
### 3. 安全意识
|
||
|
||
- 智能合约审计经验
|
||
- 了解常见漏洞(重入攻击、闪电贷攻击)
|
||
- 熟悉安全工具(Slither、MythX)
|
||
|
||
### 4. 行业理解
|
||
|
||
- DeFi生态全景
|
||
- 协议间组合性
|
||
- 监管趋势
|
||
- 风险管理
|