diff --git a/.gitignore b/.gitignore index 5b099b1..91449f2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ indexer-dist tsconfig.tsbuildinfo *.log .vite + +# 打包产物(tar.gz 是部署用的临时包,不进仓库) +*.tar.gz diff --git a/lp-terminal使用文档.md b/lp-terminal使用文档.md new file mode 100644 index 0000000..f069847 --- /dev/null +++ b/lp-terminal使用文档.md @@ -0,0 +1,632 @@ +# LP TERMINAL 使用文档 + +> LP TERMINAL v0.2 · Robinhood Chain (链 ID 4663) 上的 LP(流动性提供者)终端 +> 面向 UP33(ve(3,3) DEX)与官方 Uniswap v2 / v3 部署,提供池子浏览、仓位管理、兑换与限价挂单功能。 + +--- + +## 目录 + +1. [基本常识:这是什么 / 给谁用](#1-基本常识这是什么--给谁用) +2. [启动与运行环境](#2-启动与运行环境) +3. [界面总览:顶栏 / 底栏 / 快捷键](#3-界面总览顶栏--底栏--快捷键) +4. [连接钱包](#4-连接钱包) +5. [POOLS 池子页](#5-pools-池子页) + - 5.1 筛选与搜索 + - 5.2 表格列含义 + - 5.3 添加流动性(双币 / ZAP 单币) + - 5.4 区间选择器(CL 池) +6. [POSITIONS 仓位页](#6-positions-仓位页) + - 6.1 汇总条 + - 6.2 CL 仓位卡片 + - 6.3 V2 仓位卡片 + - 6.4 区间订单 +7. [SWAP 兑换页](#7-swap-兑换页) + - 7.1 市价模式 + - 7.2 限价模式(挂 LP 卖出) +8. [实盘操作全流程](#8-实盘操作全流程) +9. [安全机制](#9-安全机制) +10. [常见问题](#10-常见问题) + +--- + +## 1. 基本常识:这是什么 / 给谁用 + +### 1.1 一句话定义 + +LP TERMINAL 是一个 **终端风格** 的网页前端,让你在 Robinhood Chain 上做三件事: + +- **浏览池子**:全协议(UP33 + Uniswap v2/v3)的池子目录,按 TVL/量/费率排序,找到一个值得投入的池子。 +- **管理仓位**:集中查看你所有的 LP 仓位(CL + v2、UP33 + Uniswap),一站式做质押 / 解押 / 领取 / 加减仓。 +- **兑换与挂单**:市价兑换(比价 Kyber 与原生路由取最优),或用单边 LP「区间订单」挂单卖出代币(做挂单方,不付手续费还赚手续费)。 + +### 1.2 涉及的协议 + +| 协议 | 说明 | 在本终端的体现 | +|---|---|---| +| **UP33** | Robinhood Chain 上的 ve(3,3) DEX(类 Velodrome/Solidly 架构)。有 v2 恒定乘积池和 CL(集中流动性)池,带 **gauge 质押** 与 **UP 代币排放**。 | 池子标记 `CL` / `v2`,带 `gauge` 字样的有排放奖励。质押 LP 赚 UP,不质押赚手续费,**二选一**。 | +| **Uniswap v3** | 官方 Uniswap v3 部署。集中流动性(CL),无 gauge、无质押,LP 100% 拿手续费。 | 池子标记 `v3 tsX`(ts = tick spacing)。仓位以 NFT 形式存在官方 NPM。 | +| **Uniswap v2** | 官方 Uniswap v2 部署。恒定乘积 0.30% 池,LP 代币是普通 ERC-20。 | 池子标记 `v2 · 0.30%`。手续费自动滚入储备复利。 | + +### 1.3 关键代币 + +| 代币 | 合约地址 | 作用 | +|---|---|---| +| **WETH** | `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` | 链上 ETH 的封装版本,绝大多数池子的报价基准 | +| **USDG** | `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` | 稳定币锚(≈ $1),价格传播的启动锚点 | +| **UP** | `0x57C0E45cB534413D1C20A4240955d6bB250BB4F1` | UP33 的排放代币;质押 LP 赚取 | +| **ETH**(原生) | — | gas 代币;与 WETH 1:1 可互转 | + +### 1.4 ve(3,3) 收益模型(UP33 独有,必读) + +UP33 池的 LP 收益是 **二选一** 的: + +- **不质押** → 赚 **交易手续费**(费率 APR)。CL 池还要扣 10% 未质押抽成给投票者。 +- **质押进 gauge** → 赚 **UP 代币排放**(排放 APR)。但质押期间你的手续费份额归该池的投票者,自己拿不到手续费。 + +> 一个仓位只能赚其一,不能兼得。APR 都是单利、不复利,且随 TVL / 质押量增长而稀释。 + +### 1.5 重要约定 + +- 所有写入操作 **只认 chainId 4663**;连错网络会有红色横幅提示。 +- 签名只在浏览器钱包完成(RainbowKit / 注入钱包),**应用本身不存任何私钥**。 +- 所有授权都是 **精确金额授权**(exact-amount approval),无无限授权。 +- 链上状态每 ~15 秒刷新一次;你持有的区间订单所在池子有 **4 秒** 的专项 slot0 推送。 + +--- + +## 2. 启动与运行环境 + +### 2.1 依赖 + +- Node.js **≥ 22.13**(indexer 用了内置的 `node:sqlite`) +- npm + +### 2.2 首次启动(开发模式) + +```bash +npm install +cp .env.example .env # 所有 key 都可选;默认走公共端点 +npm run indexer # 池索引器,端口 :8787(首次回填约 18 分钟,后续启动很快) +npm run dev # 前端,http://localhost:5173(自动代理 /api -> :8787) +``` + +> **首次 indexer 启动耗时**(实测): +> - V3 池回填(Blockscout 分页扫 ~14.2 万池):约 18 分钟 +> - V2 池同步(allPairs 枚举 ~1.5 万):约 2 分钟 +> - token 元数据拉取(symbol/decimals,~15.5 万 token):约 13 分钟 +> - 全量状态扫描(slot0/getReserves,~15.7 万池):约 32 分钟 +> - GT 统计 + 定价:约 1 分钟 +> - **总计约 65 分钟** 首次 boot。之后重启因有 `v3_backfilled` 标记和已存 `pool_state`,会快很多。 + +### 2.3 网络代理(重要!) + +如果你的环境需要代理才能访问 Blockscout / Alchemy(例如系统已开 `127.0.0.1:7890` 代理但 Node 默认不读系统代理),启动 indexer 前必须设: + +```powershell +$env:NODE_USE_ENV_PROXY='1' +$env:HTTPS_PROXY='http://127.0.0.1:7890' +$env:HTTP_PROXY='http://127.0.0.1:7890' +npm run indexer +``` + +否则 indexer 会卡在 Blockscout 回填阶段(Node 的 fetch 连不上被墙域名)。 + +### 2.4 `.env` 配置项 + +| key | 说明 | +|---|---| +| `RPC` | 私有 Robinhood Chain RPC。**注意:Vite 会把它打进 JS bundle,公开部署务必留空**。留空 → 公共 RPC(`https://rpc.mainnet.chain.robinhood.com`)。 | +| `KYBERSWAP_AGGREGATOR_API_BASE_URL` | Kyber 聚合器基础 URL | +| `KYBERSWAP_CHAIN` | 链 slug(`robinhood`) | +| `KYBERSWAP_ROUTER_ADDRESS` | **白名单**:兑换 calldata 只发往这个地址 | +| `KYBERSWAP_FEE_BPS` | 可选平台费(bps),如 `10` = 0.1% | +| `KYBERSWAP_FEE_RECEIVER` | 平台费接收地址(必须与上一项同时设才生效) | +| `VITE_WALLETCONNECT_PROJECT_ID` | 可选;仅 WalletConnect 二维码配对需要,注入钱包不需要 | + +### 2.5 生产部署 + +```bash +RPC="" npm run build # 公开部署 RPC 必须为空 +``` + +产出静态 `dist/`,hash 路由无需 rewrite,任意静态托管(CF Pages / Netlify / S3)均可。若想保留私有 RPC,在反向代理后端终止 `/rpc`、`/api`、`/kyber` 等同源路径。 + +--- + +## 3. 界面总览:顶栏 / 底栏 / 快捷键 + +### 3.1 顶栏 + +``` +LP▮TERMINAL [1]池子 [2]仓位 [3]兑换 epoch 1 · 翻转 4d 5h · 块 13195940 [ 连接 ] +``` + +| 元素 | 含义 | +|---|---| +| `LP▮TERMINAL` | 品牌标题 | +| `[1]池子` `[2]仓位` `[3]兑换` | 三个主标签页,数字是快捷键 | +| `epoch N · 翻转 Xd Yh · 块 N` | UP33 epoch 编号、距下次 epoch 翻转(每周四)的倒计时、当前区块高度 | +| `[ 连接 ]` | 连接钱包按钮(连错链显示 `[ 链错误 ]`) | + +### 3.2 底栏 + +``` +LP TERMINAL v0.2 · 精确授权 · 链上实时读取 +快捷键: [1] 池子 [2] 仓位 [3] 兑换 [4] 限价 +rpc:DEFAULT theme: MONO PHOSPHOR AMBER ICE VIOLET lang: EN 中文 blockscout↗ +``` + +| 控件 | 作用 | +|---|---| +| `rpc:DEFAULT` | 点击可设置 **自己的 RPC**(仅存于本浏览器 localStorage,经 `eth_chainId` 探针校验必须返回 4663)。优先级高于部署默认。 | +| `theme:` | 5 个主题:MONO / PHOSPHOR / AMBER / ICE / VIOLET | +| `lang:` | 中英双语切换,持久化在 `up33.lang.v1`;也可用 URL `?lang=zh` 临时覆盖(截图用) | +| `blockscout↗` | 跳转区块浏览器 | + +### 3.3 快捷键 + +| 键 | 动作 | +|---|---| +| `1` | 切到 **POOLS** 池子页 | +| `2` | 切到 **POSITIONS** 仓位页 | +| `3` | 切到 **SWAP** 兑换页(市价) | +| `4` | 切到 **LIMIT** 限价挂单页 | +| `/` | 聚焦池子搜索框 | + +标签页是 **hash 路由**(`#pools` / `#swap` / `#limit` / `#positions`),刷新和深链都能保持位置。`#lab` 是组件实验室(合成数据,仅供视觉调试)。 + +--- + +## 4. 连接钱包 + +1. 点击顶栏 `[ 连接 ]`。 +2. 选择钱包(RainbowKit 弹窗:MetaMask 等注入钱包,或 WalletConnect 二维码)。 +3. 钱包会请求切换 / 添加 **Robinhood Chain (4663)**: + - 链 ID:`4663` + - RPC:`https://rpc.mainnet.chain.robinhood.com`(公共,钱包端始终用公共 RPC) + - 原生货币:ETH(18 位小数) +4. 连错链时顶栏显示 `[ 链错误 ]`,页面顶部出现红色 `!! 网络错误 - 本终端只在 Robinhood Chain (4663) 上写入` 横幅,点「切换」回到正确链。 + +> 应用是纯静态 SPA,无后端账户系统。你的钱包地址只存在浏览器内存中,关闭即清。 + +--- + +## 5. POOLS 池子页 + +`#pools`,快捷键 `1`。这是默认首页,也是发现池子、添加流动性的入口。 + +### 5.1 筛选与搜索 + +页面顶部一行控件: + +``` +[搜索框] [全部] [UP33] [UNI V3] [UNI V2] [隐藏 <$1K] +显示 149 · up33 29 · uniswap 目录 158,275 · 匹配 2,629 +``` + +| 控件 | 作用 | +|---|---| +| **搜索框** | 支持四种输入:代币地址(`0x…40`)、池地址、代币符号(如 `WETH`)、交易对符号 `sym0/sym1`(如 `WETH/UP`,两侧都要匹配,方向不限)。空 = 全部按 TVL 排序。快捷键 `/` 聚焦。 | +| `全部` / `UP33` / `UNI V3` / `UNI V2` | 协议过滤。`UP33` 只看 ve(3,3) 池(含排放奖励明细);`UNI V3` / `UNI V2` 看官方 Uniswap 池。 | +| `隐藏 <$1K` | 默认开启,隐藏 TVL 低于 $1K 的灰尘池(目录里 95% 是 meme 灰尘池)。 | +| `● 我的 (N)` | 仅在你连接钱包且持有仓位时出现:筛选你已参与的池子。 | +| 统计行 | `显示 N`(当前页显示数)· `up33 N`(UP33 池数)· `uniswap 目录 N`(索引器全目录)· `匹配 N`(当前筛选命中数) | + +### 5.2 表格列含义 + +| 列 | 含义 | +|---|---| +| **交易对** | 代币对符号 + 协议徽章。例如 `WETH/UP CL ts200 · 1.00% · gauge` 表示 UP33 的 CL 池,tick 间距 200,费率 1%,有 gauge(可质押)。`v3 ts200 · 1.00%` 是 Uniswap v3。`v2 · 0.30%` 是 Uniswap v2。鼠标悬停费率可见说明 tooltip。 | +| **价格 / 储备** | CL 池显示 `价格 报价币/基准币`(如 `11,579 UP/WETH`);v2 池显示两侧储备 `587.9 WETH + 1.1M USDG`。`⇄` 可翻转价格方向。 | +| **TVL** | 池子总锁仓量(USD)。链上推导:已定价侧之和;只有一侧有价时按 2× 该侧估算并标记 approximate。点击表头排序。 | +| **24H 量** | 24 小时成交量(USD)。Uniswap 池来自 GeckoTerminal;UP33 池来自 DexScreener + Goldsky 子图。`-` 表示长尾池无数据。 | +| **24H 费** | 24 小时手续费(USD)= 量 × 费率(毛,不含 ve(3,3) 抽成)。 | +| **费率 APR** | **未质押** LP 的手续费年化收益 = `vol24h × feeRate × 365 / TVL`。CL 池再 ×(1 − 10% 未质押抽成)。注意这是池平均,集中区间内的仓位会成倍高。 | +| **排放奖励** | 仅 UP33 池有值:**质押** LP 的 UP 排放 APR = `rewardRate × 31.536M × UP价格 / 质押TVL`。`∞` = 排放流向几乎零质押量的池(首个质押者全拿)。 | +| **操作列** | `+ LP`(展开添加流动性面板)· `↗`(跳转 Blockscout 查看池合约) | + +> **脚注**:表格下方有说明:费率 APR = 未质押 LP 手续费收益;排放奖励 = UP33 质押 UP 排放 APR;一个仓位只赚其一。 + +### 5.3 添加流动性(双币 / ZAP 单币) + +点击任一池子的 `+ LP`,行内展开面板。 + +#### 区间选择器(CL 池独有,v2 无区间) + +``` +区间 ±0.5% ±1% ±2% ±5% ±10% ±20% ±30% 全区间 ± % … ↑上方 ↓下方 价格 TICKS + 10,504 12,830 +-9.28% -> 下界 px 11,579 UP/WETH ⇄ 上界 ← +10.8% +区间内 · 已穿过 48.7% · 带宽 ±10.5% +``` + +| 控件 | 作用 | +|---|---| +| `±0.5%` … `±30%` / `全区间` | 对称区间预设:以当前价为中心,±N%。`全区间` = 全价格区间。 | +| `± % …` | 自定义对称百分比。 | +| `↑ 上方` | 单边存入:只在当前价**上方**建区间,只存 token1,价格涨入区间后开始赚钱(涨了才卖)。 | +| `↓ 下方` | 单边存入:只在当前价**下方**建区间,只存 token0,价格跌入区间后开始赚钱(跌了才接)。 | +| `价格` | 直接输入价格上下界(对齐 tick spacing)。 | +| `TICKS` | 直接输入原始 tick 上下界(高级)。 | +| 区间条 | 可视化:两端 = 你的价格边界,标记 = 当前价,显示到上下界的偏离百分比、带宽。区间不含当前价时会提示「不产生任何收益」。 | + +> 切换区间时,下方输入框的金额会按新比例**自动联动**。 + +#### 资金模式 + +面板有 `双币` / `⚡ ZAP - 单币` 切换: + +**双币模式**(CL): +``` +资金 双币 | ⚡ ZAP - 单币 +WETH [0.0] +UP [0.0] +[铸造仓位] NFT 进入钱包 - 去仓位页质押赚 UP +``` +- 两个输入框,按当前价自动配比;改一个另一个联动。 +- `铸造仓位` 按钮铸造一个 NFT 仓位进钱包(CL 用 NPM,UP33 用 CL_PM)。 + +**双币模式**(v2): +- 数量按储备自动配平,最小值容差保护。 +- UP33 v2 → LP 代币进钱包,去仓位页质押;Uniswap v2 → LP 代币进钱包,手续费在储备中自动复利。 + +**ZAP 单币模式**: +``` +ZAP 输入 WETH | UP | ETH [0.0] +滑点 0.5% | 1% | 3% +[连接钱包] 任一步失败即停 - 资金都在你钱包里,不会悬空 +``` +- 只持有一边代币(或原生 ETH)即可注入流动性:ZAP 先用 Kyber 把一部分换成对手代币,再按池子需要的比例双币存入。 +- 输入代币三选一:池子的 token0 / token1 / 原生 ETH(若某侧是 WETH,ETH 会先包装成 WETH)。 +- 滑点挡位控制兑换腿最小到账;存入最小值按 1% 带边计算。 +- 执行时列出完整交易序列(wrap? → 授权 → Kyber 兑换 → 授权双方 → mint/increase),**逐步执行,任一步失败即停**——所有中间资产都是普通钱包余额,不会悬空。 +- 存入金额用 **实际到账**(receipt Transfer 日志),而非报价,杜绝报价与执行不符。 + +### 5.4 索引器离线兜底 + +如果 indexer 进程没启动或还在首次回填(`ready:false`),POOLS 页顶部会出现琥珀色提示 `索引器离线 - dexscreener 兜底(v3 前 30)`,此时改用客户端 DexScreener 发现 + 链上 `factory.getPool` 验证(仅 v3 前 30 个)。伪造池会被结构性地拦截。 + +--- + +## 6. POSITIONS 仓位页 + +`#positions`,快捷键 `2`。连接钱包后显示你所有的 LP 仓位。 + +未连接时显示空态:`> 连接钱包以枚举仓位。还没有仓位?去池子页看看 ->` + +### 6.1 汇总条 + +页面顶部一条全局汇总: + +| 字段 | 含义 | +|---|---| +| **LP 总值** | 你所有仓位(含未领手续费)的 USD 总值。子标题:`X CL · Y v2 · Z 已质押` | +| **未领手续费** | 所有仓位累计的未领取手续费(USD) | +| **待领 UP** | 所有质押仓位累计的待领取 UP 数量 + USD 估值 + 实时 `+UP/天` 累积速率 | +| **全部领取(N 笔)** | 一键领取所有可领 UP(N = 涉及的笔数)。无可领时显示「暂无可领取」。 | +| **区间状态** | `全部在区间内` 或 `N 个超出区间`,子标题提示「超出区间的 CL 没有任何收益」。区间订单不计入。 | +| **区间订单** | `N 个挂单` / `N 个已完全成交 - 提取以锁定` / `尚无成交 - 卖出代币升值时逐步成交` | + +### 6.2 CL 仓位卡片(UP33 CL + Uniswap v3) + +每张卡片带协议徽章(UP 箭头 / Uniswap 独角兽,品牌色)。按「质押优先、价值降序」排列。 + +**信息区**: + +| 区块 | 内容 | +|---|---| +| **价值** | `value ≈ $…`,代币按池子自身价格对 USDG/WETH/UP 锚定价。无锚时显示 `- 无价格锚`。 | +| **收益中** | 质押:`≈ N UP/天 (≈$X/天) APR ≈ Y% 占质押流动性 Z%`;未质押且在区间:`费率 APR ≈ X 占活跃流动性 Y% 区间内有效`;超出区间:红色 `0 - 超出区间`;排放干涸:琥珀色 `0 - 本 epoch 无 UP 排放流入`。 | +| **持有** | 仓位持有的 token0 / token1 数量。 | +| **未领手续费** | 精确值(经 `collect` 模拟),USD 估值。UP33 未质押 CL 显示 `(10% 未质押抽成已扣除)`。 | +| **待领 UP** | 质押仓位才有。 | +| **区间条** | 两端 = 你的价格边界,标记 = 当前价,显示到上下界偏离 %、超出时的回入距离、在/近/出着色。 | + +**操作按钮**(视仓位状态显示): + +| 按钮 | 作用 | +|---|---| +| `质押` | 把 NFT 质押进 gauge 赚 UP(质押期间手续费归投票者) | +| `解押` | 解押后才能调整流动性或领手续费;解押会**自动领取**待发 UP | +| `领取 UP` | 领取待发 UP 排放 | +| `领取手续费` | 领取未领交易手续费 | +| `+ 加仓` | 在同一区间追加流动性(区间铸造时固定,不可移动);面板显示钱包余额 + MAX,按实时池价联动两币,预览拉取量 / 新规模 | +| `− 减仓` | 减仓 + 领取(2 笔交易),最小值容差保护 | +| `全部撤出` | 移除 100% 流动性并领取全部,**双击确认** | + +> 领取 UP(或 CL 解押自动领取)后,日志显示收到的 UP 数量,并附 **SWAP -> ETH** 按钮——一键跳到 SWAP 页预填该金额。 + +### 6.3 V2 仓位卡片(UP33 v2) + +UP33 v2 LP 是普通 ERC-20,分「钱包 LP」与「质押 LP」两部分: + +| 区块 | 内容 | +|---|---| +| **合计 / 钱包 LP / 质押 LP** | 各自的 LP 代币数量与对应底层 token 数量 | +| **可领手续费** | 钱包 LP 可领的池手续费 | +| **待领 UP** | 质押 LP 的待领 UP | + +操作:`全部质押` / `全部解押` / `领取 UP` / `领取手续费` / `移除 %`(按钱包 LP 计,质押的需先解押)。 + +> Uniswap v2 的仓位管理(LP 余额、移除流动性)尚未接入——POOLS 浏览 + 添加可用,仓位追踪靠钱包层面。 + +### 6.4 区间订单(通过 SWAP→LIMIT 挂出) + +挂出的单边 CL 区间订单会带 `限价 sell->buy` 徽章,在仓位页有专门的订单模式展示: + +- **区间条**:等待 / 成交中 X% / 已成交,以卖出代币计价(不是红色的超出区间告警)。 +- **状态感知一键操作**: + - 未成交 → `取消 - 拿回 <卖出币>` + - 部分成交 → `立即平仓(部分成交)` + - 已完全成交 → `提取 -> 锁定 <买入币>` +- 100% 提取后徽章清除。 + +> 区间订单所在池有 **4 秒** 的专项 slot0 推送,成交 % / 持有 / 区间条近实时跟踪;数值更新按方向闪绿 ▲ / 红 ▼。 + +--- + +## 7. SWAP 兑换页 + +`#swap`,快捷键 `3`。两种模式:市价 / 限价。 + +### 7.1 市价模式 + +``` +模式 市价 | 限价 · 挂 LP 卖出 +卖出 ETH ▾ [0.0] 余额 - MAX + ⇅ +买入 UP ▾ 0.0 余额 - +┌─ 报价 ─ +(输入数量后显示两路报价) +``` + +| 控件 | 作用 | +|---|---| +| 卖出 / 买入代币选择 | 点 `▾` 弹出代币选择器:搜索框(符号或地址)+ 代币列表,**每行都显示合约地址缩写**(反 symbol 伪造)。 | +| `[0.0]` 输入 | 输入卖出数量;`MAX` 一键填入余额。 | +| `⇅` | 翻转买卖方向。 | +| 报价区 | 输入数量后并排显示两路报价:**KYBER 聚合**(多跳路由)vs **UP33 原生**(v2 `getAmountsOut` + CL quoter 全匹配池直连),标出 bps 差与「最优」。 | +| `gas $X` | 估算 gas 成本。 | +| `最少到账: N SYM @ 滑点%` | 最小到账保护。 | +| 滑点 | 可调。 | +| `↻ 刷新` | 手动刷新报价。 | +| `通过 <路由> 执行 ->` | 选定路由执行。 | + +**ETH / WETH 处理**: +- 原生 ETH 买入 / 卖出自动 wrap / unwrap(1:1,无费用,WETH9 = `0x0Bd7…AD73`)。 +- UP33 原生路由需要 WETH——选 ETH→UP 时会提示「需要 WETH - 先包装」,点 `包装 N ETH` 即可。 +- 原生路由到账的是 WETH(不是 ETH),会有提示。 + +### 7.2 限价模式(挂 LP 卖出) + +`#limit`,快捷键 `4`。这是本终端的特色功能:**用单边 CL 区间订单卖出代币,做挂单方而非吃单方**。 + +核心理念:市价兑换是「吃单」付池子费;限价挂单是「挂单方」——不付手续费,成交过程中还**赚**手续费。 + +#### 面板结构 + +``` +卖出 UP ▾ [0.0] 25% 50% 75% MAX 余额 - +换成 WETH ▾ + 市价: 1 UP = 0.000086361 WETH · 1 WETH = 11,579 UP · 池 CL ts200 1.00% + +卖出区间 [?] 贴市·1TICK +1->3% +2->5% +5->10% +10->25% 自定义 + +── 订单 ── +开始成交 +1.8% 1 UP = 0.00008788 WETH +全部卖出 +3.8% 1 UP = 0.000089656 WETH +平均成交 +2.8% 1 UP ≈ 0.000088764 WETH · √(起点·终点) +区间 [93200 -> 93400] tick 网格 ts200 · 约 2.0% 步长 · 最窄合法区间 + +[区间条] 订单等待中 · 价格需上涨 1.76% 开始成交 + +── 费用 · 挂单 VS 吃单 ── +本订单 0% 挂单方 - 不付交易费,成交时还赚手续费 +市价兑换 1.00% 吃单方 - 池子费付给 LP + +── 机制 ── +成交 UP ↑ 价格向上穿过区间时逐步转换为 WETH +回吐 UP ↓ 价格回落会转换回来 - 不是挂单簿订单,没有自动执行 +成交后 提取 仓位 -> 一键锁定 · 限价徽章,实时成交 % +质押 不要 质押的 LP 会放弃交易手续费 - 订单保持不质押 + +[连接钱包] +``` + +#### 卖出区间预设 + +| 预设 | 含义 | +|---|---| +| `贴市 · 1 TICK` | 最窄合法区间,贴着市场一个 tick 间距;第一个上涨 tick 就开始成交,手续费捕获最大。 | +| `+1->3%` / `+2->5%` / `+5->10%` / `+10->25%` | 阶梯区间:起点在市价 +X%,终点在 +Y%。 | +| `自定义` | 自定义起点 / 终点百分比(< tick 间距的输入会吸附到贴市区间,标 `≡ 贴市`)。 | + +点 `?` 打开结构化区间说明:起点 / 终点 / 均价(几何平均 √(起点·终点))/ 网格(tick 步长)。 + +#### 订单关键字段 + +- **开始成交**:区间起点价(第一批卖出位置)。越近越早成交,但回调也越容易回吐。 +- **全部卖出**:区间终点价。 +- **平均成交**:起终点的几何平均,即你的混合退出溢价。 +- **区间**:`[tickLo -> tickHi]`,对齐 tick 网格。 + +#### 费用对比 + +直观对比挂单(0%)vs 市价吃单(池费,约 $X)。 + +#### 机制(必读) + +- **成交**:价格向上穿过区间时逐步转换为买入代币。 +- **回吐**:价格回落会转换回来——**这不是挂单簿订单,没有自动执行**。 +- **成交后**:去仓位页「提取」一键锁定;带限价徽章,实时成交 %。 +- **不要质押**:质押的 LP 放弃交易手续费,订单必须保持不质押。 + +#### 下单 + +`挂出区间订单 ->` 最多 2 笔交易(精确授权 + 铸造),无自动执行。铸一个区间起点 ≈ 100% 的单边仓位(防价格已进入区间)。下单后跳仓位页跟踪。 + +--- + +## 8. 实盘操作全流程 + +### 8.1 流程一:用 WETH 给 UP33 CL 池加流动性并质押赚 UP + +1. **启动**:`npm run indexer` + `npm run dev`,浏览器开 `http://localhost:5173`。 +2. **连钱包**:顶栏 `[ 连接 ]`,选 MetaMask,切到 Robinhood Chain (4663)。 +3. **找池子**:POOLS 页,搜 `WETH/UP`,点 `UNI V3` 过滤看 UP33 的 CL 池(带 `gauge` 字样)。 +4. **选区间**:点 `+ LP`,区间选 `±10%`(对称)或 `↓ 下方`(单边接)。 +5. **输入金额**:双币模式下输入 WETH 数量,UP 自动联动。 +6. **预览**:面板显示 `预估`:存入 ≈ $X、占活跃流动性 Y%、费率 APR(不质押时)、排放 APR(质押时)。超出区间会警告。 +7. **铸造**:点 `铸造仓位`,钱包确认授权 + mint(CL_PM),NFT 进钱包。 +8. **质押**:去 POSITIONS 页找到新仓位,点 `质押`,授权 NFT 给 gauge + 质押。开始赚 UP。 +9. **领取**:累计后点 `领取 UP` 或汇总条 `全部领取`。日志显示收到的 UP,附 `SWAP -> ETH` 一键卖出。 + +### 8.2 流程二:用单币(ETH)ZAP 进 WETH/UP 池 + +1. POOLS 页找到 WETH/UP CL 池,点 `+ LP`。 +2. 资金模式切到 `⚡ ZAP - 单币`。 +3. 输入选 `ETH`,填数量,选滑点 `1%`。 +4. 点 `连接钱包`(实为执行),ZAP 列出交易序列:`包装 ETH -> WETH` → `授权 WETH -> kyber 路由` → `兑换 N WETH -> ≈M UP` → `授权 WETH -> 仓位管理器` → `授权 UP -> 仓位管理器` → `铸造仓位`。 +5. 逐步执行,任一步失败即停,资金始终在钱包。 +6. 完成后去仓位页质押。 + +### 8.3 流程三:用限价单卖出 UP 换 WETH + +1. SWAP 页,切 `限价 · 挂 LP 卖出`。 +2. 卖出选 `UP`,换成 `WETH`。金额选 `50%`。 +3. 区间选 `+1->3%`(在市价上方 1%~3% 阶梯卖出)。 +4. 查看「订单」区:开始成交价 / 全部卖出价 / 平均成交价 / 区间 tick。 +5. 查看费用对比:挂单 0% vs 市价 1.00%。 +6. 点 `挂出区间订单 ->`,授权 UP + 铸造单边仓位。 +7. 去 POSITIONS 页,该仓位带 `限价 UP->WETH` 徽章,显示 `订单等待中 · 价格需上涨 1.76% 开始成交`。 +8. UP 升值进入区间后逐步成交为 WETH,期间还赚手续费;价格回落会回吐。 +9. 完全成交后点 `提取 -> 锁定 WETH`。 + +### 8.4 流程四:仓位管理日常 + +- **加仓**:仓位卡片 `+ 加仓`,同区间追加流动性。 +- **减仓**:`− 减仓`,按百分比移除 + 领取(2 笔交易)。 +- **调整区间**:CL 区间不可移动——要换区间需 `全部撤出` 后重新 mint。 +- **领手续费**:未质押 CL / v2 钱包 LP 点 `领取手续费`。 +- **解押**:`解押` 自动领 UP,之后才能动流动性或领手续费。 + +--- + +## 9. 安全机制 + +### 9.1 钱包交互 + +- 仅浏览器钱包签名,应用 / 服务端 / 存储均无任何私钥。 +- **精确金额授权**(exact-amount),无无限授权。 +- 所有写入 chainId 4663 锁定,带 deadline;原生路由最小值从实时链上价推导。 + +### 9.2 Kyber 兑换四道闸门(`lib/kyberExec.ts`) + +Kyber 的 calldata 是不透明的,发送前过四道闸: + +1. API 返回的 `routerAddress` 必须等于 `.env` 白名单(且 tx `to` 永远是白名单地址,不是 API 给的)。 +2. `transactionValue` 必须精确匹配预期(ERC-20 入 = 0,原生 ETH 入 = amountIn)。 +3. 构建的 `amountIn` 必须等于请求。 +4. 构建的 `amountOut` 必须 ≥ 新鲜报价 − 用户滑点。 + +SWAP 和 ZAP 共用同一处闸门,永不分叉。 + +### 9.3 ZAP 额外两道闸 + +- 新鲜路由的 `tokenOut` 必须是池子的对手代币。 +- 新鲜输出必须仍在预览计划的滑点内(+0.5% 宽容),否则在钱包看到交易前就停。 +- 存入用 receipt 的实际到账,授权每步精确金额。 + +### 9.4 反 spoofing + +- 代币选择器每行都显示合约地址缩写。 +- 合约目录列出完整地址并链接区块浏览器。 +- 索引器只从官方工厂事件 / 枚举接纳池子,第三方 API 只能富化不能引入——伪造 / 分叉池结构性被排除。 + +### 9.5 XSS / 注入防御 + +- 内置 CSP `script-src 'self'` 思路:无内联脚本、无 eval、无第三方 / CDN 脚本,全部自托管 + content-hash。 +- React 转义,无 `dangerouslySetInnerHTML`;外链 `noreferrer`。 +- 依赖精确锁定(`.npmrc save-exact`)+ lockfile,防供应链 patch 投毒。 + +### 9.6 区间订单所在池的近实时推送 + +你持有区间订单的池有 **4 秒** 的专项 slot0 推送(单次 multicall),成交 % / 持有 / 区间条近实时跟踪;数值更新按方向闪绿 ▲ / 红 ▼,区间条标记滑动显示漂移方向。 + +--- + +## 10. 常见问题 + +### Q1:POOLS 页显示「索引器离线 - dexscreener 兜底」? +indexer 进程没启动或还在首次回填(`ready:false`)。启动 `npm run indexer` 并等首次 boot 完成(约 1 小时)。期间前端用 DexScreener 兜底(v3 前 30),功能可用但池子不全。 + +### Q2:indexer 启动报 `EADDRINUSE: address already in use :::8787`? +8787 端口被占。先停掉旧 indexer 进程(任务管理器找 node.exe,或 `Get-Process node | Stop-Process -Force`)再重启。 + +### Q3:indexer 卡在 `v3 backfill` 不动? +Blockscout 被墙 / Node fetch 不走代理。设 `NODE_USE_ENV_PROXY=1` + `HTTPS_PROXY=http://127.0.0.1:7890`(换成你的代理)后重启 indexer。或设 `INDEXER_BACKFILL=rpc` 走 RPC 窗口扫描(较慢但无需 Blockscout)。 + +### Q4:连钱包后显示「链错误」? +钱包不在 Robinhood Chain (4663)。点顶栏 `[ 链错误 ]` 或横幅「切换」按钮,钱包会请求切链。 + +### Q5:CL 仓位的 APR 跟池子表格里的不一样? +表格里是 **池平均** APR;仓位卡片是 **你的区间专属** APR:`share = L_yours / (activeLiquidity + L_yours)`。集中区间内的仓位会成倍高于池平均,超出区间则 0。 + +### Q6:质押了为什么手续费归零? +ve(3,3) 模型:质押 LP 赚 UP 排放,**手续费份额归该池投票者**。想赚手续费就解押。二者不可兼得。 + +### Q7:限价单为什么「回吐」?不是挂单吗? +区间订单是单边 LP,不是订单簿限价单。价格穿过区间时逐步成交,**价格回落会转换回来**,没有自动执行。完全成交后需手动「提取」锁定买入代币。 + +### Q8:ZAP 中途失败了怎么办? +ZAP 任一步失败即停,所有中间资产都是普通钱包余额,不会悬空。解决后重新执行(按当前余额重新规划),或切双币模式手动收尾。 + +### Q9:想创建全新的 Uniswap v3 池子? +v1 不支持 `createAndInitializePoolIfNecessary`,只能 mint 进已有池子。 + +### Q10:Uniswap v2 仓位怎么管理? +v1 未接入 v2 LP 余额 / 移除流动性。POOLS 浏览 + 添加可用;仓位追踪靠钱包层面(v2 LP 是普通 ERC-20)。 + +--- + +## 附录:关键合约地址 + +### UP33(ve(3,3) DEX) + +| 合约 | 地址 | +|---|---| +| UP 代币 | `0x57C0E45cB534413D1C20A4240955d6bB250BB4F1` | +| veUP | `0x5d321dE36F0bf98D92b291280514F3878582B7B6` | +| Voter | `0x7F749fDD351C1Ceed82d76d7699CB631Eb8332a7` | +| Minter | `0x912EC7A90e8C9829eE0e0f6a4Db5270776Fc3Da5` | +| V2 Factory | `0xFA5429AEBa338BEa2BFcc1b9a889862Ee395bc28` | +| V2 Router | `0xf5198743240fAC98db71868F34c70139b1eb0474` | +| CL Factory | `0x1ac9dB4a2608ba45D6127B1737949b51Bb54B7F3` | +| CL PositionManager | `0x07F44c47743A2f36414A82b9F558ECFCf0EEdCEf` | +| CL SwapRouter | `0xC062b870E813fcA720f1e002c234369Ab3aB9415` | +| CL Quoter | `0x03983AB2C057a2eac211ff01738a1e49ff325B49` | +| WETH | `0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73` | +| USDG | `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168` | + +### Uniswap(官方部署,链 4663) + +| 合约 | 地址 | +|---|---| +| V3 Factory | `0x1f7d7550B1b028f7571E69A784071F0205FD2EfA` | +| V3 NonfungiblePositionManager | `0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3` | +| V2 Factory | `0x8bcEaA40B9AcdfAedF85AdF4FF01F5Ad6517937f` | +| V2 Router02 | `0x89e5DB8B5aA49aA85AC63f691524311AEB649eba` | + +### 其他 + +| 项 | 值 | +|---|---| +| 链 ID | 4663 | +| 区块浏览器 | https://robinhoodchain.blockscout.com | +| 公共 RPC | https://rpc.mainnet.chain.robinhood.com | +| Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | + +--- + +*本文档基于 LP TERMINAL v0.2 实测整理。协议参数由 Safe 控制,随时可能变化;一切以链上实时状态为准。本文不构成财务建议。* diff --git a/package-lock.json b/package-lock.json index 0987a73..90d73be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "lp-terminal", "version": "0.1.0", + "license": "MIT", "dependencies": { "@rainbow-me/rainbowkit": "2.2.11", "@tanstack/react-query": "5.101.2", @@ -3260,9 +3261,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3277,9 +3275,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3294,9 +3289,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3311,9 +3303,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3328,9 +3317,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3345,9 +3331,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3362,9 +3345,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3379,9 +3359,6 @@ "ppc64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3396,9 +3373,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3413,9 +3387,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3430,9 +3401,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3447,9 +3415,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3464,9 +3429,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ diff --git a/部署方案.md b/部署方案.md new file mode 100644 index 0000000..e69de29