Universal Router 合约
Universal Router 通过编码的命令接口在 V2 和 V3 流动性池之间执行兑换。实际使用中,您不需要自己编码命令 — Swap API 会为您生成 calldata。 概念概述请参阅 Universal Router 概念。核心函数
execute
按顺序执行一系列命令。function execute(
bytes calldata commands,
bytes[] calldata inputs,
uint256 deadline
) external payable;
| 参数 | 类型 | 描述 |
|---|---|---|
commands | bytes | 命令代码序列(每个 1 字节) |
inputs | bytes[] | 每个命令对应的 ABI 编码参数 |
deadline | uint256 | 超过此 Unix 时间戳后交易将回滚 |
通常您不需要直接调用
execute()。请使用 Swap API 生成 { to, data, value } 对象,然后作为交易发送。命令类型
| 命令 | 代码 | 描述 |
|---|---|---|
V2_SWAP_EXACT_IN | 0x00 | V2 精确输入数量兑换 |
V2_SWAP_EXACT_OUT | 0x01 | V2 精确输出数量兑换 |
V3_SWAP_EXACT_IN | 0x02 | V3 精确输入数量兑换 |
V3_SWAP_EXACT_OUT | 0x03 | V3 精确输出数量兑换 |
WRAP_ETH | 0x0b | 将原生 KAS 包装为 WKAS |
UNWRAP_WETH | 0x0c | 将 WKAS 解包为原生 KAS |
PERMIT2_PERMIT | 0x0a | 执行基于 Permit2 签名的授权 |
TRANSFER | 0x04 | 转移代币 |
使用模式
推荐使用 Swap API 生成 calldata:// 1. 从 Swap API 获取 calldata
const response = await fetch('/swap-api/api/v1/swap', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
tokenIn: '0x...',
tokenOut: '0x...',
amountIn: '1000000000000000000',
tradeType: 0,
slippage: 0.5,
recipient: userAddress,
deadline: 1200
})
});
const swapData = await response.json();
// 2. 直接发送交易
const tx = await signer.sendTransaction({
to: swapData.to, // Universal Router 地址
data: swapData.data, // 编码后的 execute() calldata
value: swapData.value // 原生 KAS 金额(ERC-20 兑换时为 0)
});
错误处理
常见的回滚原因:| 错误 | 原因 | 解决方案 |
|---|---|---|
EXPIRED | 交易截止时间已过 | 使用更长的截止时间或更快提交 |
V3_INVALID_AMOUNT_OUT | 输出低于 minAmountOut | 增加滑点容差 |
TRANSFER_FROM_FAILED | 授权不足或余额不足 | 检查 Permit2 授权和代币余额 |
INSUFFICIENT_ETH | 发送的原生 KAS 不足 | 确保 value 与所需金额匹配 |
ABI
[
"function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline) external payable"
]