mcpField
C
copy-trade

copy-trade

github.com/uniswap其他236412 次安装2 天前更新
代码仓库

关于 copy-trade

copy-trade 是定时运行的策略技能,可在配置的限制内将目标钱包的兑换操作镜像到跟随钱包。它解析链上活动并委托执行,不自行实现兑换逻辑。

主要功能

  1. 01扫描目标交易以识别兑换
  2. 02将多跳路径合并为意图
  3. 03应用资产、金额和余额限制
  4. 04防止重复镜像已处理操作
  5. 05委托集成执行兑换

适用场景

  1. 01镜像指定钱包符合条件的交易
  2. 02跳过超出代币或支出限制的交易
  3. 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 分钟)调用此技能。每次调用都是一次独立、完整且确定性的运行:

  1. 读取存储的游标(上次处理的区块)。
  2. 读取领队钱包自游标以来新增的链上操作。
  3. 对每项新操作应用防护限制。
  4. 对通过限制的操作,将镜像兑换委托给 swap-integration。
  5. 更新游标,并记录已镜像的领队操作。

请将此流程视为状态机,而不是自由形式的推理。读取状态,与链上数据进行比较,逐项决定操作,执行并更新游标。不要超出链上事件所述内容推断意图,也不要重新推导先前运行已记录的决定。

前提条件

此技能将所有基础设施操作委托出去,不会重新实现报价、授权、签名或兑换构建逻辑。

  • 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 筛选器无法返回经由路由器路由的交易。应改为:

  1. 遍历范围 (cursor, head] 内的区块,并筛选出 tx.from 等于 leader 的交易。(通过 viem-integration 使用 viem 读取区块/交易;分段扫描,避免超出 RPC 限制。)
  2. 对每笔此类交易获取其收据,并解码其中包含的 Swap 日志。一笔 leader 交易可能会发出一个或多个 Swap 日志(多跳路由每条路径会发出一条日志;批处理/多调用会为每笔独立换币发出一条日志)。协议版本由发出日志的合约确定:v4 Swap 由 PoolManager 发出;v2/v3 Swap 日志由各个池合约发出。
  3. 在判断方向前,先解析每个池的代币对。v2/v3 Swap 日志不会标明代币——调用发出日志的池上的 token0() / token1()(或从 PoolId 解码 v4 PoolKey),以确定代币对。代币地址来自这些读取结果以及选定的目标链模板;切勿臆造地址。池的 Swap 日志始终引用 WETH(ERC-20),绝不会引用原生 ETH:涉及原生 ETH 的路径由路由器包装/解包,不会发出 ERC-20 Swap 事件。此处将任何解析为 WETH 的路径代币规范化为 WETH,并在与允许列表匹配时应用 execution-model.md 中的 ETH/WETH 规范化规则(步骤 3)。
  4. 根据金额的正负确定流入和流出,并注意 v3 与 v4 的符号约定相反。v2 报告无符号的 amount0In/amount1In/amount0Out/amount1Out;非零的 *In 代币就是 tokenIn。v3(int256)报告池的余额变化,因此正数表示流入池的代币(tokenIn),负数表示流出池的代币(tokenOut)。v4(int128)报告换币方的余额变化,因此符号相反:负数表示换币方支付的代币(tokenIn),正数表示换币方收到的代币(tokenOut)。(v4 Swap 的 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)。因此:

  1. 即使领头钱包的相同交易已成功,镜像兑换仍可能在转账时回滚(跟随者可能不具备持有该资产的资格)。请妥善处理转账限制导致的回滚,记录失败情况,且不要盲目重试。
  2. 遵循所选模板关于股票市场交易时段的指引;部分 RWA 在非交易时段可能流动性受限,因此在交易时段外可能会跳过或延迟买入。
  3. 在仓库根目录的 DISCLAIMER.md 中展示免责声明。Uniswap Labs 不提供投资建议或推荐。跟单交易会按照运营者的单独指示复制另一个钱包的交易;运营者需独自对策略以及遵守适用法律负责。

输入验证

在将运营者提供的任何值插入代码、API 调用或 shell 命令之前:

  • 领头钱包和跟随者钱包地址、代币地址:必须匹配 ^0x[a-fA-F0-9]{40}$;否则拒绝。
  • 持仓上限和金额:必须是非负数值,并匹配 ^[0-9]+\.?[0-9]*$。
  • 链 ID:必须是运营者配置的目标链 ID,应从所选模板读取,而不是硬编码。
  • API 密钥和私钥:必须来自环境变量,不得硬编码。
  • 拒绝任何包含 shell 元字符的输入:;、|、&、$、`、(、)、>、<、\、'、" 或换行符。

评论

支持 Markdown