聚合器运行原理剖析
全文使用1inch和uni v3作为举例
协议分析
1inch
核心架构:Pathfinder 算法
1inch 的核心是其 Pathfinder 算法,这是一个高级的发现和路由算法,专门设计用于以最优汇率促进资产交换。
Pathfinder 算法的工作原理
步骤1: 数据收集
├── 扫描所有支持的 DEX
├── 获取实时价格数据
├── 计算流动性深度
└── 评估 gas 成本
步骤2: 路径计算
├── 使用类似 Dijkstra 的算法
├── 考虑所有可能的池组合
├── 计算多跳路径
└── 优化总成本
步骤3: 执行策略
├── 订单分割
├── 动态填充
├── 滑点保护
└── 失败重试
具体举例:复杂路由优化
假设你想用 1000 USDT 购买 ETH:
场景设置:
Uniswap V2: USDT/ETH = 1500 (流动性: 100万)
Uniswap V3: USDT/ETH = 1505 (流动性: 200万)
SushiSwap: USDT/ETH = 1498 (流动性: 50万)
PancakeSwap: USDT/ETH = 1502 (流动性: 80万)
Pathfinder 的优化决策:
方案1: 全部通过 Uniswap V3
- 输出: 0.664 ETH
- 价格影响: 0.1%
- Gas 费: 0.01 ETH
方案2: 拆分订单
- 60% 通过 Uniswap V3: 0.399 ETH
- 25% 通过 PancakeSwap: 0.166 ETH
- 15% 通过 Uniswap V2: 0.100 ETH
- 总计: 0.665 ETH ✅ (更优)
- Gas 费: 0.025 ETH
最终选择: 方案2,净收益提升 0.001 ETH
四大核心协议
聚合协议 (Aggregation Protocol) v5
这是 1inch 的旗舰协议,提供最佳交易路径发现。
contract AggregationRouterV5 {
function swap(
IAggregationExecutor executor,
SwapDescription calldata desc,
bytes calldata permit,
bytes calldata data
) external payable returns (
uint256 returnAmount,
uint256 spentAmount
) {
// 执行最优路径交换
// 支持多 DEX 聚合
// 动态滑点保护
}
function unoswap(
IERC20 srcToken,
uint256 amount,
uint256 minReturn,
uint256[] calldata pools
) external payable returns (uint256 returnAmount) {
// 单一 DEX 高效交换
// 优化 gas 消耗
}
}
核心特性:
Pathfinder 算法: 寻找最优交易路径
动态填充: 根据市场条件调整执行策略
Gas 优化: 减少交易成本
失败保护: 自动重试和回滚机制
限价单协议 (Limit Order Protocol) v3
允许用户设置限价单,链下撮合,链上结算。
contract LimitOrderProtocol {
struct Order {
uint256 salt;
address makerAsset;
address takerAsset;
address maker;
address receiver;
address allowedSender;
uint256 makingAmount;
uint256 takingAmount;
uint256 offsets;
bytes interactions;
}
function fillOrder(
Order memory order,
bytes calldata signature,
bytes calldata interaction,
uint256 makingAmount,
uint256 takingAmount,
uint256 skipPermitAndThresholdAmount
) external returns (uint256, uint256, bytes32) {
// 验证订单签名
// 执行限价单填充
// 支持部分填充
}
}
核心特性:
零滑点: 固定价格执行
部分填充: 支持订单分批执行
无gas成本: 挂单不消耗gas
RFQ系统: 询价系统支持
流动性协议 (Liquidity Protocol)
这是 1inch 的自有 AMM 协议,提供资本高效的流动性解决方案。
contract MooniswapFactory {
function deploy(
IERC20 token1,
IERC20 token2
) external returns (Mooniswap pool) {
// 创建新的流动性池
// 支持自定义参数
}
}
contract Mooniswap {
function swap(
IERC20 src,
IERC20 dst,
uint256 amount,
uint256 minReturn,
address referral
) external payable returns (uint256 result) {
// 虚拟余额机制
// 减少套利机会
// 保护流动性提供者
}
function deposit(
uint256[] calldata amounts,
uint256[] calldata minAmounts
) external payable returns (uint256 fairSupply) {
// 添加流动性
// 公平价格机制
}
}
核心特性:
虚拟余额: 减少MEV攻击
自适应费率: 根据市场波动调整
资本效率: 优化的流动性利用
LP保护: 减少无常损失
P2P 协议 (P2P Protocol)
点对点交易协议,支持大额交易的直接撮合。
contract P2PProtocol {
struct P2POrder {
address maker;
address taker;
IERC20 makerAsset;
IERC20 takerAsset;
uint256 makerAmount;
uint256 takerAmount;
uint256 deadline;
bytes32 orderHash;
}
function createP2POrder(
P2POrder calldata order,
bytes calldata signature
) external {
// 创建点对点订单
// 支持私人交易
}
function executeP2POrder(
P2POrder calldata order,
bytes calldata makerSignature,
bytes calldata takerSignature
) external {
// 执行双方确认的交易
// 无滑点,固定价格
}
}
核心特性:
大额交易: 专为whale交易设计
零滑点: 固定价格执行
隐私保护: 私人交易撮合
机构级别: 支持机构间交易
实际应用场景
场景1: 小额交易
用户需求: 100 USDT → ETH
选择协议: 聚合协议 v5
执行路径: 自动寻找最优DEX
结果: 最佳价格 + 最低gas费
场景2: 限价交易
用户需求: 当ETH价格跌到2000 USDT时买入
选择协议: 限价单协议 v3
执行方式: 链下监控,价格触发时自动执行
结果: 零滑点,精确价格执行
场景3: 提供流动性
用户需求: 为ETH/USDT提供流动性
选择协议: 流动性协议 (Mooniswap)
优势: 虚拟余额机制,减少无常损失
收益: 交易费用分成 + 减少MEV损失
场景4: 大额交易
用户需求: 100万USDT → ETH (避免市场冲击)
选择协议: P2P协议
执行方式: 与对手方私下协商固定价格
结果: 零滑点,无市场影响
协议间的智能路由
1inch 会根据交易特征自动选择最适合的协议:
function selectProtocol(amount, slippage, urgency) {
if (amount > 1000000) {
return "P2P Protocol"; // 大额交易
} else if (slippage === 0) {
return "Limit Order Protocol"; // 零滑点需求
} else if (urgency === "high") {
return "Aggregation Protocol"; // 立即执行
} else {
return "Liquidity Protocol"; // 最优费率
}
}
Uniswap V3
核心创新:集中流动性
Uniswap V3 的集中流动性是其最大创新,允许流动性提供者在自定义价格范围内分配流动性。
Tick 系统机制
价格范围划分:
├── 每个 tick 代表 0.01% 的价格变化
├── tick 间距由手续费等级决定
├── 流动性在 tick 边界处激活/停用
└── 价格公式: price = 1.0001^tick
具体举例:集中流动性的优势
传统 Uniswap V2 vs V3 对比:
V2 场景:
ETH/USDT 池,当前价格 2000 USDT
流动性提供者 Alice 提供:
- 1 ETH + 2000 USDT
- 流动性分布:0 到 ∞ 价格范围
- 大部分流动性永远不会被使用
- 资本效率低
V3 场景:
ETH/USDT 池,当前价格 2000 USDT
流动性提供者 Alice 提供:
- 1 ETH + 2000 USDT
- 价格范围:1800-2200 USDT
- 集中流动性,提供更深的深度
- 资本效率提升 4000倍 ✅
数学模型深度解析
恒定乘积公式的演进
V2 公式:
x * y = k (在整个价格范围)
V3 公式:
在每个 tick 区间内:
√(x * y) = L (流动性)
当价格变化时,L 根据 tick 变化
价格计算实例
# Uniswap V3 价格计算示例
def tick_to_price(tick):
return 1.0001 ** tick
def price_to_tick(price):
return math.log(price) / math.log(1.0001)
# 示例:ETH/USDT
current_price = 2000
current_tick = price_to_tick(current_price) # ≈ 69077
# 流动性提供者设置范围
lower_tick = price_to_tick(1800) # ≈ 67991
upper_tick = price_to_tick(2200) # ≈ 70139
手续费机制优化
V3 的三级手续费结构:
0.05%: 稳定币对 (USDT/USDC)
0.30%: 标准对 (ETH/USDT)
1.00%: 异常对 (新代币/ETH)
1inch + Uniswap V3 协同工作实例
完整交易流程分析
让我们用您的实际交易为例,深入分析整个流程:
第1步:1inch 接收订单
// 用户发起交易
const swapParams = {
fromToken: "USDT",
toToken: "BR",
amount: "2936753790000000000", // 2.93675379 USDT
fromAddress: "0x8c99634a7b68a0faff48ee246ba9a93052777412",
slippage: 1 // 1% 滑点容忍度
}
第2步:Pathfinder 算法分析
# 1inch Pathfinder 伪代码
def find_best_path(from_token, to_token, amount):
paths = []
# 扫描所有可能的路径
for dex in supported_dexes:
if dex.has_pair(from_token, to_token):
# 直接路径
rate = dex.get_rate(from_token, to_token, amount)
paths.append(Path(dex, [from_token, to_token], rate))
# 多跳路径
for intermediate in common_tokens:
rate1 = dex.get_rate(from_token, intermediate, amount)
rate2 = dex.get_rate(intermediate, to_token, rate1.output)
paths.append(Path(dex, [from_token, intermediate, to_token], rate1*rate2))
# 选择最优路径
return max(paths, key=lambda p: p.output_amount)
第3步:Uniswap V3 执行交换
// Uniswap V3 Pool 合约
contract UniswapV3Pool {
function swap(
address recipient,
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes calldata data
) external returns (int256 amount0, int256 amount1) {
// 1. 检查流动性
uint128 liquidity = getLiquidityForAmount(amountSpecified);
// 2. 计算价格影响
uint160 sqrtPriceX96 = slot0.sqrtPriceX96;
uint160 sqrtPriceNextX96 = SqrtPriceMath.getNextSqrtPriceFromInput(
sqrtPriceX96,
liquidity,
amountSpecified,
zeroForOne
);
// 3. 执行交换
amount0 = zeroForOne ? amountSpecified : -getAmount0Delta(sqrtPriceX96, sqrtPriceNextX96, liquidity);
amount1 = zeroForOne ? -getAmount1Delta(sqrtPriceX96, sqrtPriceNextX96, liquidity) : amountSpecified;
// 4. 更新状态
slot0.sqrtPriceX96 = sqrtPriceNextX96;
return (amount0, amount1);
}
}
第4步:实际执行结果分析
您的交易分析:
输入: 2.93675379 USDT
输出: 41.017214327166556 BR
有效汇率: 1 USDT = 13.963 BR
可能的优化路径:
1. 直接 USDT→BR (Uniswap V3)
2. USDT→BNB→BR (多跳)
3. 拆分订单到多个池子
选择的路径:直接路径 (最优)
详细交易流程分析
第1步: 用户授权转入
发送方: 0xcfef...9e7ce1b (用户)
接收方: 0x1ac2...451632 (中间合约)
金额: 2.93675379 USDT
作用: 用户将 USDT 转入 1inch 的中间处理合约
第2步: 资金转移到聚合器
发送方: 0x1ac2...451632 (中间合约)
接收方: 0xde9e...0ffca73 (1inch 内部合约)
金额: 2.93675379 USDT
作用: 将 USDT 转移到 1inch 的内部处理系统
第3步: 关键的流动性池交换
发送方: Uniswap V3 LP (流动性池)
接收方: 1inch Network (聚合器)
金额: 41.01721432 BR
作用: 这是实际的代币交换发生地
第4步: 聚合器处理
发送方: 0xde9e...0ffca73 (1inch 内部)
接收方: Uniswap V3 LP (流动性池)
金额: 2.93675379 USDT
作用: 1inch 将 USDT 发送到 Uniswap V3 池进行交换
第5步: 最终交付
发送方: 1inch Network (聚合器)
接收方: 0x4ff1...6709a1 (最终地址)
金额: 41.01721432 BR
作用: 将交换得到的 BR 代币交付给最终接收方
从表面上看第2步和第3步之间缺乏明显的关联性。让我深入分析这个关键的衔接点:
第2步与第3步的关键衔接分析
表面上的断层现象
第2步(资金流入)
发送方: 0x1ac2...451632 (中间合约)
接收方: 0xde9e...0ffca73 (1inch 内部合约)
金额: 2.93675379 USDT
第3步(代币流出)
发送方: Uniswap V3 LP (流动性池)
接收方: 1inch Network (聚合器)
金额: 41.01721432 BR
看起来的问题: USDT 流入了 1inch 内部合约,但 BR 却是从 Uniswap V3 LP 流出的,具体来看看中间发生了什么。
真实的衔接机制
隐藏的第2.5步:内部路由调用
在区块链浏览器中,我们看到的只是 外部可见的转账,但实际上在第2步和第3步之间,发生了以下内部操作:
contract OneInchInternalRouter {
function processSwap(uint256 usdtAmount) internal {
// 第2步完成后,内部合约持有 USDT
// 第2.5步:内部路由决策(不产生外部转账记录)
address targetDEX = pathfinder.findBestDEX(USDT, BR, usdtAmount);
// 第2.6步:调用目标 DEX(这里是 Uniswap V3)
if (targetDEX == UNISWAP_V3) {
// 内部调用 Uniswap V3
IUniswapV3Pool(targetPool).swap(
address(this), // recipient = 1inch 合约
true, // zeroForOne = USDT -> BR
int256(usdtAmount), // amountSpecified
sqrtPriceLimitX96,
abi.encode(swapData)
);
}
// 此时触发第3步:Uniswap V3 LP 向 1inch 发送 BR
}
}
关键细节
合约内部调用 vs 外部转账
外部转账(在浏览器中可见):
User → 1inch → Uniswap V3 → 1inch → User
内部合约调用(在浏览器中不可见):
// 这些调用不会产生 Transfer 事件
1inch.internalRouter.swap()
└── uniswapV3Pool.swap()
└── callback: uniswapV3SwapCallback()
Uniswap V3 的回调机制(关键点)
这是关键的衔接点!Uniswap V3 使用回调机制:
// Uniswap V3 Pool 合约
function swap(...) external {
// 1. 先发送 BR 给调用者(1inch)
IERC20(tokenOut).transfer(recipient, amountOut); // 这是第3步!
// 2. 然后回调要求付款
IUniswapV3SwapCallback(msg.sender).uniswapV3SwapCallback(
amount0Delta,
amount1Delta,
data
);
}
// 1inch 合约实现回调
function uniswapV3SwapCallback(
int256 amount0Delta,
int256 amount1Delta,
bytes calldata data
) external override {
// 3. 现在 1inch 向 Uniswap V3 支付 USDT
IERC20(USDT).transfer(msg.sender, uint256(amount0Delta)); // 这是第4步!
}
回调机制原理
先发货,后付款
传统交易模式 vs 回调模式
传统模式(先付款,后发货):
1. 用户先发送 USDT 给 DEX
2. DEX 验证收到 USDT
3. DEX 发送 BR 给用户
Uniswap V3 模式(先发货,后付款):
1. DEX 先发送 BR 给调用者
2. DEX 回调要求付款
3. 调用者在回调中支付 USDT
1inch合约 Uniswap V3 Pool BR Token USDT Token
| | | |
|-- swap() --------->| | |
| | | |
| |-- transfer() --->| |
|<-- BR tokens -----| | |
| | | |
|<-- callback() ----| | |
| | | |
|-- transfer() --------------------->| |
| |<-- USDT tokens --| |
| | | |
|<-- return --------| | |
完整的衔接流程重建
真实的执行顺序:
第1步: User → 1inch中间合约 (2.93675379 USDT)
第2步: 1inch中间合约 → 1inch内部合约 (2.93675379 USDT)
--- 内部处理开始 ---
第2.5步: 1inch内部合约调用 Uniswap V3 的 swap() 函数
第3步: Uniswap V3 LP → 1inch内部合约 (41.01721432 BR) ✅
第4步: 1inch内部合约 → Uniswap V3 LP (2.93675379 USDT) ✅ (回调支付)
--- 内部处理结束 ---
第5步: 1inch内部合约 → 最终接收方 (41.01721432 BR)
为什么采用这种机制?
1. 原子性保证
// 如果任何一步失败,整个交易回滚
function atomicSwap() external {
uint256 initialBalance = IERC20(outputToken).balanceOf(address(this));
// 调用 Uniswap V3
uniswapV3Pool.swap(...);
uint256 finalBalance = IERC20(outputToken).balanceOf(address(this));
require(finalBalance > initialBalance, "Swap failed");
}
2. Gas 效率优化
传统方式: 用户 → DEX → 用户 (2次外部调用)
1inch方式: 用户 → 1inch → DEX → 1inch → 用户 (1次外部调用 + 内部优化)
3. 滑点保护
function swapWithSlippageProtection(uint256 minOutput) external {
uint256 outputAmount = performSwap();
require(outputAmount >= minOutput, "Slippage too high");
// 如果滑点过高,整个交易回滚
}
实际的合约交互图
graph TD
A[User] --> B[1inch路由合约]
B --> C[1inch内部合约]
C --> D{内部路由决策}
D --> E[调用 Uniswap V3]
E --> F[Uniswap V3 发送 BR]
F --> C
E --> G[回调要求 USDT]
G --> C
C --> H[发送 USDT]
H --> I[Uniswap V3 LP]
C --> J[最终接收方]
要点总结
第2步和第3步的衔接是通过 Uniswap V3 的回调机制 实现的:
第2步: 1inch 内部合约接收 USDT
隐藏步骤: 1inch 调用 Uniswap V3 的 swap 函数
第3步: Uniswap V3 先发送 BR(这是协议设计)
第4步: 1inch 在回调中支付 USDT
这种"先给货,后付款"的机制是 Uniswap V3 的核心设计,确保了交易的原子性和安全性。这就是为什么表面上看起来第2步和第3步没有直接关联,但实际上它们是通过智能合约的内部调用紧密相连的。