关于 copy-trade
copy-trade 是定时运行的策略技能,可在配置的限制内将目标钱包的兑换操作镜像到跟随钱包。它解析链上活动并委托执行,不自行实现兑换逻辑。
主要功能
- 01扫描目标交易以识别兑换
- 02将多跳路径合并为意图
- 03应用资产、金额和余额限制
- 04防止重复镜像已处理操作
- 05委托集成执行兑换
适用场景
- 01镜像指定钱包符合条件的交易
- 02跳过超出代币或支出限制的交易
- 03重复运行后安全续接处理
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ uniswap/ uniswap-ai --skill copy-trade安装后在 Claude Code 中输入/copy-trade确认已加载。
详细介绍
Copy Trade(跟单交易)
在目标链上监控目标(“领队”)钱包,并在防护限制范围内,将其兑换操作镜像到跟随者的钱包中。这是一个轻量的策略层:它决定镜像哪些操作以及是否镜像,然后将实际兑换委托给 swap-integration 和 viem-integration。此技能不会自行构建报价、授权、兑换或签名逻辑。
运行时兼容性: 此技能使用
AskUserQuestion询问执行模式和确认事项。如果运行时不支持AskUserQuestion,请通过自然语言对话收集相同的参数和确认信息。
概览
宿主调度器按固定周期(约每 5 分钟)调用此技能。每次调用都是一次独立、完整且确定性的运行:
- 读取存储的游标(上次处理的区块)。
- 读取领队钱包自游标以来新增的链上操作。
- 对每项新操作应用防护限制。
- 对通过限制的操作,将镜像兑换委托给
swap-integration。 - 更新游标,并记录已镜像的领队操作。
请将此流程视为状态机,而不是自由形式的推理。读取状态,与链上数据进行比较,逐项决定操作,执行并更新游标。不要超出链上事件所述内容推断意图,也不要重新推导先前运行已记录的决定。
前提条件
此技能将所有基础设施操作委托出去,不会重新实现报价、授权、签名或兑换构建逻辑。
- swap-integration(uniswap-trading):唯一的执行路径。每笔镜像兑换都必须通过其 Trading API 流程完成(依次执行
check_approval、quote、swap,然后签名并广播)。不得重新实现其中任何部分。 - viem-integration(uniswap-viem):提供账户、客户端、签名、交易广播,以及读取领队钱包活动的功能。读取领队自游标区块以来的交易和收据,以检测兑换(参见步骤 2)。
执行前请阅读以下插件参考文档,并将其视为权威依据:
- 所选目标链模板:chainId、链名称、合约地址、可交易代币来源、RPC/读取路径、索引器可用性、资金限制和模板特定注意事项。Robinhood Chain 参考模板见
../../references/robinhood-chain.md。 ../../references/execution-model.md:Trading API 要求、执行模式、限制和免责声明规则。../../references/strategy-state.md:共享状态文件和调度器模式。
模板输入
所选目标链模板必须提供:
- 链 ID、链名称、原生 Gas 代币和 RPC/读取路径。
- 解码领队活动所需的已部署 Uniswap 路由器、Permit2、PoolManager 和 v2/v3/v4 池工厂/读取器地址。
- 是否存在公共索引器;如果不存在,此技能将轮询 RPC 并扫描有界区块范围。
- 可交易代币解析规则,包括任何代币列表或允许列表来源。
- 资金限制、转账限制注意事项和市场交易时间指南。
工作流(确定性状态机)
步骤 1:读取状态游标
加载 JSON 状态文件(格式见 strategy-state.md)。对于跟单交易,相关字段包括上次处理的游标(区块或日志位置)以及已镜像的领队意图集合(按交易级别的 leaderTxHash 作为键;如果单笔交易产生多个独立意图,则添加子索引;参见步骤 2)。如果状态文件不存在,则视为首次运行:将游标初始化为当前最新区块,本次不镜像任何内容(避免重放领队的完整历史,除非操作员明确选择这样做)。
首次运行时将游标设为最新区块的行为仅适用于此技能,并非模板特定行为。此做法可避免在任何目标链上意外重放历史记录。
步骤 2:读取游标以来的领队操作
通过扫描 leader 自身的交易来检测其换币,而不是按 leader 地址筛选池事件主题。池的 Swap 事件不包含 leader 的 EOA:v2 对 sender/to 建立索引,v3 对 recipient 建立索引(交易经由 UniversalRouter / SwapRouter02 路由时,这些字段都是路由器,而不是 leader),v4 的 Swap 仅对 PoolId 和 sender 建立索引(这里的 sender 是 PoolManager 的调用方,同样是路由器)。因此,按 leader 地址设置的 getLogs 筛选器无法返回经由路由器路由的交易。应改为:
- 遍历范围
(cursor, head]内的区块,并筛选出tx.from等于 leader 的交易。(通过viem-integration使用 viem 读取区块/交易;分段扫描,避免超出 RPC 限制。) - 对每笔此类交易获取其收据,并解码其中包含的
Swap日志。一笔 leader 交易可能会发出一个或多个Swap日志(多跳路由每条路径会发出一条日志;批处理/多调用会为每笔独立换币发出一条日志)。协议版本由发出日志的合约确定:v4Swap由PoolManager发出;v2/v3Swap日志由各个池合约发出。 - 在判断方向前,先解析每个池的代币对。v2/v3
Swap日志不会标明代币——调用发出日志的池上的token0()/token1()(或从PoolId解码 v4PoolKey),以确定代币对。代币地址来自这些读取结果以及选定的目标链模板;切勿臆造地址。池的Swap日志始终引用WETH(ERC-20),绝不会引用原生ETH:涉及原生 ETH 的路径由路由器包装/解包,不会发出 ERC-20Swap事件。此处将任何解析为WETH的路径代币规范化为WETH,并在与允许列表匹配时应用execution-model.md中的 ETH/WETH 规范化规则(步骤 3)。 - 根据金额的正负确定流入和流出,并注意 v3 与 v4 的符号约定相反。v2 报告无符号的
amount0In/amount1In/amount0Out/amount1Out;非零的*In代币就是tokenIn。v3(int256)报告池的余额变化,因此正数表示流入池的代币(tokenIn),负数表示流出池的代币(tokenOut)。v4(int128)报告换币方的余额变化,因此符号相反:负数表示换币方支付的代币(tokenIn),正数表示换币方收到的代币(tokenOut)。(v4Swap的 NatSpec 沿用了 v3 对池余额的描述,但经对照实时 v4 换币验证,合约发出的是换币方的有符号BalanceDelta;请遵循换币方余额变化的约定。)确定方向后,将amountIn/amountOut取绝对值。
现在将每条路径解码为 { tokenIn, tokenOut, amountIn, amountOut, leaderTxHash, logIndex, blockNumber }。在生成要镜像的操作前,先合并同一笔 leader 交易中构成一条路径的路径:
- 通过匹配
tokenOut->tokenIn串联路径。 若一条路径的tokenOut等于下一条路径的tokenIn(同一笔交易内,按logIndex顺序),则它们属于同一条路径。这类最长链合并为一个净意图:tokenIn= 第一条路径的tokenIn,tokenOut= 最后一条路径的tokenOut,amountIn= 第一条路径的amountIn,amountOut= 最后一条路径的amountOut。丢弃中间路径。(例如:USDG -> WETH -> AAAx是两条Swap日志,合并后变为一个USDG -> AAAx意图;镜像两条路径会错误地买入中间的WETH,然后又将其卖出。)如果合并后的链回到起始代币,导致净tokenIn等于tokenOut(例如套利往返USDG -> WETH -> USDG),则它是净空操作:丢弃,不镜像该链。 - 独立换币保持分开。 一笔交易也可能是批处理/多调用,其中各条路径并未串联(没有路径的
tokenOut会成为另一条路径的tokenIn)。这些是独立换币,而非一条路由:每条路径都是单独的净意图,应分别镜像。 结果是每条最长链对应一个镜像意图(每条独立路径也对应一个)。在交易级别使用leaderTxHash为每个生成的意图设置键。如果单笔交易产生多个独立意图,则追加一个子索引,值为该意图第一条路径的logIndex;logIndex在每笔交易中不可变,因此该键在重新扫描和崩溃恢复时都可复现,多跳路线最多只会镜像一次。单笔交易只产生一个意图时,仅使用leaderTxHash。按(blockNumber, first-leg logIndex)对生成的意图排序,以确保处理顺序确定。
重要:请根据所选模板读取活动。 如果模板未提供公共索引器,则轮询 RPC,并直接扫描已部署合约的日志。以有界区块范围进行扫描,以遵守 RPC
getLogs限制,并在每次运行时持久化游标,使连续范围通常不会重叠;第 3 步的幂等性防护措施(跳过任何已镜像的leaderTxHash意图)可在游标未前进时(例如崩溃后)确保重叠范围安全。
第 3 步:针对每项操作应用防护措施
按顺序处理每项新操作。跳过(不进行镜像)任何未通过防护措施的操作,并记录跳过原因。防护措施:
处理操作前,读取已配置的防护措施。如果缺少单次镜像、单次运行或单个周期的支出上限,则使用 AskUserQuestion(如果不可用,则使用自然语言)向操作员询问这些上限;同时说明用于比较的资金代币或计价单位。如果仍有任何上限未设置,则不要进入 autonomous 模式。在 confirm 模式下,仅在逐次确认后继续,并说明 autonomous 模式仍不可用。
| 防护规则 | 规则 |
|---|---|
| 链过滤 | 操作必须发生在所选目标链上。忽略其他所有内容。 |
| 资产匹配 | tokenIn 和 tokenOut 都必须属于操作者允许的代币集合(默认:所选模板中的可交易代币)。对于此匹配,ETH 和 WETH 等价:解码为 WETH 的交易腿(池日志始终引用 ERC-20 代币,见步骤 2)符合 ETH 或 WETH 白名单条目,因此解码为 WETH 的交易腿绝不会因白名单中有 ETH 条目而被错误跳过。比较前,按照 execution-model.md 中的规则进行 ETH/WETH 规范化。 |
| 仓位规模上限 | 镜像交易金额不得超过单笔交易上限和每周期支出上限。超出时应缩减金额或跳过。 |
| 跟随者余额 | 跟随者钱包必须持有足够的 tokenIn(以及 Gas)才能执行交易。如果不足,则跳过并报告。 |
| 幂等性 | 如果此意图的 leaderTxHash(如有子索引,也包括该子索引)已在镜像集合中,则跳过;绝不重复镜像。按交易级别作为键意味着多跳路由最多只会镜像一次。 |
仓位规模由操作者选择:可以为每笔镜像交易设置固定名义金额,也可以按领导者的金额设置比例,但始终不得超过上述上限。镜像金额绝不得超过上限。
第 4 步:委托镜像兑换
对于通过所有防护措施的每个意图,将其交给 swap-integration。传入所选模板中的目标链 ID 和代币地址。Trading API 流程(先执行 check_approval,再执行 quote,然后执行 swap)会处理路由、授权、Permit2、签名和广播。此技能仅提供:tokenIn、tokenOut、定量后的 amount、目标链 ID 和跟随者的钱包。不要重新实现报价、授权、兑换或签名逻辑。ETH/WETH 交易腿的执行形式(原生 ETH 还是包装后的 WETH,以及任何包装或解包操作)由 swap-integration Trading API 路径决定:不要假设跟随者的镜像兑换必须采用领导者使用的相同形式,也不要自行处理包装或解包。传入规范化后的代币,并让 Trading API 选择执行形式。
第 5 步:推进游标并记录
每个领导者意图处理完毕后,立即将状态写入磁盘——不要等到本次运行结束才批量写入。每个意图处理完毕时(广播已确认,或已记录为跳过),将其 leaderTxHash 键(如有子索引,也一并记录)及结果和跟随者的交易哈希,追加到已镜像(或已跳过)集合中,然后持久化。只有在相关记录已提交后,才推进持久化的 cursor,确保不会将部分处理的范围标记为已完成。按意图写入可保证幂等性:如果本次运行在批处理中途崩溃,且广播已确认,该意图的记录已写入磁盘,下次唤醒时,第 3 步中的幂等性检查会跳过它。如果等到运行结束才批量写入,那么运行中途崩溃时,已广播的镜像兑换就不会被记录,下次将再次使用真实资金进行镜像兑换。
执行模式
按操作员的选择,公开 execution-model.md 中的执行模式:
| 模式 | 行为 |
|---|---|
confirm(默认) | 使用 AskUserQuestion 在广播前确认每笔镜像兑换,并显示代币、定量后的金额、链以及要镜像的领导者操作。复用 swap-integration 的支出关卡。 |
autonomous | 在严格遵守防护措施的前提下,无需逐笔交易提示即可进行镜像操作。要求设置每次运行和每个周期的支出上限、每笔镜像交易的名义金额上限、代币允许列表、先进行干运行,以及设置紧急停止开关。 |
默认使用 confirm。完整规范请参阅 ../../references/execution-model.md。
状态
状态遵循 ../../references/strategy-state.md。复制交易专门存储:
cursor:所选目标链上最后处理的区块/日志位置。- 已镜像的领导者意图键集合(
leaderTxHash;如果一笔交易产生多个独立意图,则还包括子索引)及其结果。
这样可确保运行具有幂等性:即使发生重启或调度器唤醒时间重叠,同一领导者意图最多只会被镜像一次;而在第 2 步中合并为一个意图的多跳路由也最多只会被镜像一次,而不是每条腿都镜像一次。
限制与免责声明
RWA 门控因链和代币而异,并且可能在代币层面强制执行(转账受限的 ERC-20)。因此:
- 即使领头钱包的相同交易已成功,镜像兑换仍可能在转账时回滚(跟随者可能不具备持有该资产的资格)。请妥善处理转账限制导致的回滚,记录失败情况,且不要盲目重试。
- 遵循所选模板关于股票市场交易时段的指引;部分 RWA 在非交易时段可能流动性受限,因此在交易时段外可能会跳过或延迟买入。
- 在仓库根目录的
DISCLAIMER.md中展示免责声明。Uniswap Labs 不提供投资建议或推荐。跟单交易会按照运营者的单独指示复制另一个钱包的交易;运营者需独自对策略以及遵守适用法律负责。
输入验证
在将运营者提供的任何值插入代码、API 调用或 shell 命令之前:
- 领头钱包和跟随者钱包地址、代币地址:必须匹配
^0x[a-fA-F0-9]{40}$;否则拒绝。 - 持仓上限和金额:必须是非负数值,并匹配
^[0-9]+\.?[0-9]*$。 - 链 ID:必须是运营者配置的目标链 ID,应从所选模板读取,而不是硬编码。
- API 密钥和私钥:必须来自环境变量,不得硬编码。
- 拒绝任何包含 shell 元字符的输入:
;、|、&、$、`、(、)、>、<、\、'、"或换行符。