对接
前端或索引器需要的东西。协议那页讲原理,这页讲接口。
六个核心合约已经部署在链 4663 上并且冻结,12 只股票已上架,而且公开发射已经开了:2026-09-22 读到 publicLaunch 为
true、strategyCount 为 1。
下面是生产地址,当天在链上只读核对过。这一页上的地址就是协议本身——沙盒 hook 是另一个合约、地址看起来很像,别把任何 东西指过去。
网络
| 链 | Robinhood Chain |
| Chain ID | 4663 |
| 台面 | hedgefun.trade——独立域名,不是应用的子域名 |
| 区块浏览器 | robinhoodchain.blockscout.com |
| 发射自己的池子 | Uniswap V4,挂共用 hook,用股票计价 |
| 国库的股票腿 | 只有 Uniswap V3,并用 10 分钟 TWAP 印证现价 |
| 股票预言机 | Chainlink,RHxxx / USD ÷ USDG 喂价——见三个价 |
| 出块时间 | 约 0.1 秒,所以这里每一处衰减都按秒计时而不是按块 |
合约
生产地址
从提交 3dc07eb 部署,链 4663 的第 69,454,565 块;2026-09-22 在第 69,459,976 块做过只读核对。六个合约都有 Sourcify 的
creation 与 runtime match(不是 exact_match);Blockscout 的源码展示和 Uniswap 的路由批准是另外两回事,不会因此自动
成立。
| 合约 | 地址 |
|---|---|
HedgeFunFactory | 0x58F6Ced8d02cD2567f1458801440Bc4eb67fA961 |
HedgeFunHook | 0x2A16d0973385952cFBE750D37f803d0958472844 |
TradingCalendar | 0xFE9E85f0C258Fc2757eB6Acd1ca032Ec860487F5 |
HedgeFunLaunchRouter | 0x470F5DeB0897118F6575F72183781C6a0610E1FA |
TreasuryDeployer | 0x05BC7875a7d61C3bbA2D7737D40C81aF5fD10DBE |
TokenDeployer | 0x9C0440dCc1b651C4707aa44E0eA083Fa4E0E8A6b |
HedgeFunTradeRouter | 0xb281F7D91325A3A386A00cA0F6010BC8B1491c8C |
owner、protocol 和日历的 owner 是同一个 Safe:0x2910117dd2cB431173Ae9Fb6eAF30726321d1693,3/4 多签,
pendingOwner 为零。
已上架的股票
12 只,由 owner 上架,每只开盘 FDV 大约 $10k。一次上架定死了创作者不能自己选的预言机和 V3 池:
listings(stock) -> (oracle, pool, openingPrice)
bandCeiling(stock) -> 创作者最多能选多大的过期带宽,单位 bps/小时
2026-09-22 链上核对。开盘价是 openPriceE18(每枚代币多少股),最后一列是带宽上限。
| 股票 | 股票代币 | 价格预言机 | 开盘价 · 带宽上限 |
|---|---|---|---|
| NVDA | 0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC | 0x03c77f527Aa1B0B304602e3fB9Ac994dd1c157f8 | 44200000000 · 0 |
| SPCX | 0x4a0E65A3EcceC6dBe60AE065F2e7bb85Fae35eEa | 0xC109426706b9D01719ED82e8cd027fA91fBcdC0b | 65600000000 · 0 |
| CRCL | 0xdF0992E440dD0be65BD8439b609d6D4366bf1CB5 | 0x3bd2c093948D38A5eC2D945C5b065e5Db89aaB36 | 109000000000 · 10 |
| GOOGL | 0x2e0847E8910a9732eB3fb1bb4b70a580ADAD4FE3 | 0x15400359B0D14B4151FAe80b837abF3fA1977256 | 28000000000 · 0 |
| AMZN | 0x12f190a9F9d7D37a250758b26824B97CE941bF54 | 0xb34d278D2c792B7C48252C5eB8130Db45e35294e | 38500000000 · 5 |
| GME | 0x1b0E319c6A659F002271B69dB8A7df2F911c153E | 0x7548A343D06E45507Dd8F546D9d9Fdf684575ecE | 423000000000 · 5 |
| META | 0xc0D6457C16Cc70d6790Dd43521C899C87ce02f35 | 0x699E34068b8975bE113eD5fF12e429c69BCf1011 | 13400000000 · 5 |
| USAR | 0xd917B029C761D264c6A312BBbcDA868658eF86a6 | 0x02dE419166CED89fc9FCe2687CdBcBbc9eDe2612 | 596000000000 · 5 |
| MSTR | 0xec262a75e413fAfD0dF80480274532C79D42da09 | 0x19d0328F3152d1361db7B3Dd7708Cc36A779d612 | 61100000000 · 0 |
| AMD | 0x86923f96303D656E4aa86D9d42D1e57ad2023fdC | 0xc809bDf7E31E4830de2b03e6f809869Fb99f2246 | 16300000000 · 0 |
| MU | 0xfF080c8ce2E5feadaCa0Da81314Ae59D232d4afD | 0x4D15A4A1028f001800774A3d2DC31d77945399a4 | 9620000000 · 0 |
| INTC | 0xc72b96e0E48ecd4DC75E1e45396e26300BC39681 | 0xd399113f3196044A001614Ca9dda9cD8c9424264 | 82700000000 · 0 |
V3 池由同一个 listings 调用一并返回——NVDA 的是 0xD4EB21209c4d6093F80B5b84f5C45cC093eA14A3——两条腿创作者都换不了。
publicLaunch 读出来是 true、strategyCount 是 1。这两个值请实时读,别把状态写死。
已发射
平台测试,启动配置失败。 CRCLGRID 发射时没有配置双边流动性,也没有预先注入国库 USDG 储备。 如果始终没有 lot 达到第一档止盈位,也没有补充储备,策略可能无限期不执行买卖。详见发射复盘。
| CRCLGRID —— Hedgefun CRCL Range Grid | |
|---|---|
| 代币 | 0xF5501c0D85992dD59371e15e3e7b60654ebaF332 |
| 国库 | 0xc21873529515990C80BACe0931141e6B9D5A4fe0 |
| 股票 | CRCL,0xdF0992E440dD0be65BD8439b609d6D4366bf1CB5 |
| V4 pool id | 0xfe98797b4dc2e5008712f812f3d90acba5adb216f8aa32e412fa377fb90b0b64 |
| pool key | currency0 是 CRCL,currency1 是代币,fee 0,tickSpacing 60,hook 0x2A16d097…2844 |
| 发射交易 | 0x9a0c0240e9d2172440b70968294896a2b236e42ebf717fe781262b5666a1ca82,区块 69,523,800 |
| 规则 | tp1 2000、tp2 4000、dip 1500、stop 0、lotBps 2000、bandBpsPerHour 10 |
| 税率,2026-09-22 | buyRateBps 1000、sellRateBps 1000——两个窗口都已过期,现在是平常税率 |
其余的用 strategies(i)(i < strategyCount())枚举,每一项是 (token, treasury, hook, stock, creator)。
每个合约干什么
| 合约 | 你为什么会调它 |
|---|---|
HedgeFunFactory | predict(request) 拿报价和它的哈希,launch(request, terms) 发射,以及创作者能选的上架清单 |
HedgeFunHook | 所有发射共用一个实例,状态按 pool id 分。实时税率、分账、以及税的事件 |
HedgeFunToken | 代币本身,外加它的页面——logo()、description()、socials()、getTokenInfo(),沿用 pons 的读取函数名和选择器,所以给 pons 代币写的工具不用改就能读它 |
HedgeFunTreasury | lot、储备,以及 health() |
HedgeFunLaunchRouter | 一笔交易完成:发射 + 创作者第一笔买入 + 给国库第一批股票 |
HedgeFunTradeRouter | 一笔交易完成 USDG ↔ 发射代币:先走 V3 这一跳(全成或全不成),再进 V4 池 |
PriceOracle、TradingCalendar | 股票的 USDG 价格,以及它查询的 24/5 交易日历 |
ABI 打包在合约仓库的 abi/ 里,旁边有一份生成的接口清单。要按真正部署的那个 commit 生成:止盈字段在 09f42b4 加宽成了
uint32,这改变了 launch、launchWithMetadata 和 predict 的选择器。
发射
发射要传请求和 terms——也就是 predict(request) 返回的哈希,代表发射者对自己看到的全部报价的承诺。如果中间有上架、默认值或
费用变了,launch 会 revert,而不是按新的值成交。
| 字段 | 是什么 |
|---|---|
name、symbol | 代币的名字和符号 |
stock | 工厂已经上架的股票。自带地址会被拒绝:创作者提供的预言机就是创作者控制的价格 |
creator | 永久接收股票计价卖出税里创作者那一份。必须是能调用 vetoCreator 的地址——EOA 或 Safe,不能是分账合约 |
taxBps、creatorBps | 税率和创作者的分成,都被工厂限住 |
tp1Bps、tp2Bps | 两档止盈,uint32 且没有上限——创作者设了多大就如实显示多大 |
dipBps | 抄底在上一次卖出价往下多少处买 |
stopBps | 可选止损。0 表示没有止损,此时每个 lot 都卖在自己的成本之上 |
lotBps | 规则按多大的 lot 工作 |
bandBpsPerHour | 过期带宽——见下。合法范围是 0..bandCeiling(stock),而这个上限在 owner 设定之前是 0;合约还会再把它限在 200 以内。出生时写进国库,之后不可改 |
发射费可选,三种币之一:原生 gas 代币(直接给,不换币)、USDG,或所发射的同一只股票——这样只持有 NVDA 的创作者完全不用碰
USDG。非原生币支付时多带的 msg.value 会 revert,而不是被吞掉。
launchWithMetadata 还能在同一笔交易里写代币页面。页面属于发射它的地址,该地址可以指定一个编辑者,也可以 lock() 永久
锁死;协议方对它没有任何权力。
报价
必须读实时税率。 一个池子刚开盘的几秒里,买入最高付 99%;而每次回购之后,卖出会带尖峰税率:
买入 → hook.buyRateBps(poolId) // 开盘 3 秒内 99% → 66% → 33% → 平常
卖出 → hook.sellRateBps(poolId) // 开盘时和每次回购后是尖峰,线性衰减回平常
在那些窗口里显示平常税率,报价会错最多 99 个百分点。显示 hook 返回的那个值,并且显示它正在衰减。
其他会影响你能提供什么的规则:
- 卖出只支持 exact-input。
- exact-output 只有「按平常税率的买入」被接受,税收在进来的股票上并做毛额换算,使路径成本相同;其余一律拒绝。
- 发射者在发射交易里的买入不受窗口约束,且不限金额、不限笔数。展示早期成交历史时把它显示出来,不要被平均掉。
- 每个代币都要显示首买集中度——发射者在发射交易里给自己拿走了多少供应量。这是告诉买家「还有多少流通在外面」的那个数。
过期带宽,以及表单该怎么问
带宽放宽的是「现价距离上一次 Chainlink 打印可以有多远,而 health() 还不关闭」——
maxDeviationBps + bandBpsPerHour × 喂价过期小时数,上限 3000——成交本身仍然按预言机推出来的价格边界执行。
读 bandCeiling(stock) 然后分支,不要无条件渲染这个字段:
- 上限是 0(目前 12 只里有 7 只是这样):唯一合法值就是 0。直接省掉这个字段,说清这个国库只认 Chainlink、按开市 时间工作。
- 上限大于 0:给一个 0 到上限的滑块,默认取上限。明说调紧更严格,选 0 也是正当选择——只在开市时间交易。
带宽更宽买到的是容忍度,不是更好的价格:成交仍然按预言机推出来的边界执行,多出来的时段是休市时段。无论哪种情况,都要标明 它在发射时冻结——由创作者设一次,管这个国库一辈子。
读一次发射
| 视图 | 告诉你什么 |
|---|---|
lotCount() | 规则现在扛着几个 lot |
reserveUsdg() | 抄底储备 |
unbookedStock() | 已到账但还没记成 lot 的股票——任何人都可以调 book() |
health() | 现在能不能定价和交易,以及按什么价 |
把一次发射显示成「在交易」之前先读 health()。 它为 true 的条件是:喂价在带宽内新鲜、股票代币的 oraclePaused() 没被
置上、日历说开市、池子与预言机的偏离在执行闸门以内。国库只按它能验证的价格交易,这是结构决定的——而与此同时,它的代币
一周七天照常交易。
替国库干活,并拿到赏金
国库没有 keeper,也没有特权调用者。下面这五个写操作对所有人开放,它们各自拿预言机的价格对自己的触发条件,而且每一个都按
bountyBps × 这次调用产生的东西付给调用者——上线值 50(0.5%),合约上限 200(2%),从 params() 读。
| 调用 | 什么时候可以调 | 付给你什么 | 会以什么 revert |
|---|---|---|---|
book() | 有股票到账且预言机在线 | 不付钱——不满足条件时返回 false,不 revert | (不 revert,返回 bool) |
takeProfit(id) | 价格到了 成本 + tp1,之后是 成本 + tp2 | 抽利润的一份,用股票付 | NotDue、Unhealthy |
stopLoss(id) | 创作者设了止损,且价格跌到了那里 | 抽成交额的一份,用 USDG 付 | NotDue、Unhealthy |
buyDip() | 价格比上次卖出低了 dip,且这次花的钱够 minLotUsdg | 抽花出去那笔钱的一份,用 USDG 付 | NotDue、Unhealthy |
buyback() | 国库有利润,且冷却期已过 | 抽买回来那批代币的一份,用代币付 | NotDue、Cooldown、Unhealthy |
hook.sweep(poolId) | 某个池子上累积了税 | 这次 sweep 分出去的量的 sweepTipBps | — |
takeProfit 会先帮你调一次 book(),所以单独发 book() 只在「别的都不到点、但你想把到账的股票按今天的价格入账」时才值得。
怎么找活干
for i in 0 .. factory.strategyCount()-1:
(token, treasury, hook, stock, creator) = factory.strategies(i)
(ok, p) = treasury.health() # false → 除了 buyback 都动不了
params = treasury.params() # tp1Bps、tp2Bps、dipBps、stopBps、lotBps、bountyBps …
for id in 0 .. treasury.lotCount()-1:
(qty, cost, half, tp1Left) = treasury.lots(id)
# half 为 false 时,tp1 在 cost*(1+tp1Bps/1e4) 到点;之后 tp2 在 cost*(1+tp2Bps/1e4)
# stopBps != 0 时,止损在 cost*(1-stopBps/1e4)
treasury.unbookedStock() # > 0 → book() 有活干
treasury.reserveUsdg() # buyDip 花的是它的 lotBps
先模拟,再发。 NotDue 是正常答案而不是错误:一次 eth_call 不花钱,就能告诉你这笔交易到底能不能赚到。
一次调用的边界
- 一次调用只动一块。
takeProfit和stopLoss单次最多按规则价提供sellChunkUsdg,buyDip花掉储备的lotBps。 比一块大的 lot 要分几次调,每一次都付钱。 - 卖出只成交到「预言机价减滑点上限」允许的程度,而且 lot、事件、你的赏金全都按实际成交的量计算。
buyback()有冷却(buybackCooldown,上线值 60 秒),而且它按代币池自己的 10 分钟 TWAP 定价,所以股票喂价周末冻住 时它照样能干活。buyDip()的赏金是从花出去的钱里扣的,不是从报价里扣,所以你赚到的跟国库真正买到的挂钩。
定价
发射池的价格是代币对股票的价格,不是对 USDG。要显示 USDG 价或市值,乘以股票自己的预言机价:
price_usdg = price_in_stock × oracle_usdg(stock)
market_cap = price_usdg × (总供应量 − 已销毁量)
两件要从链上读、不要假设的事:
- token 顺序。 哪一边是 token0 在这条链的股票池上不是常数。假定一种顺序会算出接近零的数字而且不报错,读起来像「没有 流动性」而不像 bug。这个坑已经栽过两次。
- 种池区间。 发射仓位是单边的,从开盘 tick 上方一直到可用区间顶端,所以「走了多远」要从池子当前的 tick 算。没有毕业事件 可以监听,因为什么都不迁移。
这三个数怎么算
前端要显示市场 FDV、池子里躺着的股票、以及国库持有什么。它们来自三个不同的地方,而且每一个都有一个「长得很像、会返回一个 很自信的数而不是报错」的替身。
FDV = 池子价格(代币对股票) × 供应量 × oracleUsdg(股票)
^ 边际价格,不是均价,更不是真卖能成交的价
^ 说清用哪个供应量:已发行 / 已发行减销毁——而且销毁只能减一次
^ 开盘 FDV 是用股票计价的:supply × listings(stock).openPriceE18
NVDA 发射 = 1e9 × 4.42e-8 = 44.2 股 NVDA;只有再乘上股票自己的价格
之后,它才变成一个美元数
池内储备 = 这个池子持有的股票,从池子自己的状态读
✗ balanceOf(PoolManager)——V4 把所有池子的余额都放在同一个合约里,
那个地址上是全链的股票,不是这一个池子的
代币那一侧按数量列在旁边,绝不按它自己的边际价格估值后加进来
国库 = 国库地址持有的股票 + USDG,拆成本金、已实现收益、
以及下一次回购可用的额度
✗ 本金 + 已实现 + 额度 相加——它们是同一堆钱的不同阶段
✗ 国库 ÷ 供应量 当成赎回价展示——没有赎回这回事
✗ 池内储备 + 国库——两个不同的锅,归属也不同
由此得出四条展示规则:
- 读不到的数是「未获取」,不是
0。 零是关于余额的事实,读取失败是关于你的连接的事实。 - 每个数字都各读各的——储备只能从池子读,不能拿 FDV 或任何手头碰巧有的数去填。
- 带上出处:哪个价格、什么时候读的、是否已过期。喂价是 24/5 的,所以工作日傍晚读到过期是正常状态,标出来即可。
- 只要列出代币的地方都显示首买集中度。
事件
事件 topic 和解码示例会和地址一起出现在这里。值得索引的路径:发射本身、hook 在每次交易时的税分账,以及国库的 book /
takeProfit / stopLoss / buyDip / buyback——它们合起来就能重建每一个 lot,不需要依赖我们的 API。
支持
[email protected],或 @0xHedgehood。
这是一个界面,不是投资建议。见使用条款。