TreasuryVault

每个市场一个金库。它接收每笔交易的 2 %,将其转化为代币化股票,并空投给代币的持有者。它是协议中最重的合约,也是权力最少的合约。

它没有什么

没有 withdraw。没有 transfer。没有 sweep。没有所有者。这些函数在当前的实现合约中并不存在,任何人都可以验证:调用会失败,因为根本没有可调用的东西。自 2026-10-02 起,金库本身可以升级:参见下文。

转换循环

  1. 累积。ETH 随交易流入。每 24 小时一次,如果在 Keeper 检查时(空投时间窗口关闭后的第一轮)金库持有至少 0.1 ETH,循环就会启动;低于这个数额,当天什么也不会触发,即使 ETH 稍后越过门槛——gas 和滑点会吞噬这次操作。Keeper 自 2026-10-06 起遵循这一点;在此之前,只要金库达到门槛,它就会转换。
  2. ETH → USDC,在以太坊的 Uniswap v4 上进行,相对 ETH/USD 喂价的界限为 50 个基点。这是一个深度充足的交易对,因此界限可以很紧。数额由 Keeper 指定,至少为门槛,至多为全部余额,界限按该数额计算。
  3. USDC → USDG,通过 Curve 完成,然后经由 Paxos 在 LayerZero 上的 OFT 跨链。
  4. 买入股票,由镜像金库在 Robinhood Chain 的二级市场池中进行,相对一个独立 Chainlink 喂价的界限为 200 个基点,每只股票都用为它预留的现金买入。
  5. 空投。在同一次每日循环中,Keeper 把买入的股票发送到以太坊上的空投合约,由代币的持有者在那里按比例领取。自第七个审计循环(2026-10-06)起,它在这些股票的价值抵得上发送成本时才发送它们;否则它们会在金库中等待之后的时间窗口。

金库计量它实际收到的数量,如果结果低于 Keeper 的最低数额就拒绝,而这一最低数额从不比界限更宽松(自 2026-10-05 起;在此之前,结果只与界限比较)。它既不信任 Keeper,也不信任通道,也不信任报价。

自 2026-10-05 起,在两种买入股票的金库上,每一段买入都单独执行。失败的段——回滚的路径、被冻结的股票、过期的喂价、低于最低数额的产出、被拒绝的报价,以及自 2026-10-06 起在 Robinhood Chain 上其代币因公司行动而暂停预言机的股票——会让其现金继续为该股票预留,并发出 LegFailed,其他段照常执行。只有当没有任何一段执行时,调用才会失败,并给出第一段的原因,与只有一段时的情形相同。在此之前,一段失败就会让整次买入失败。在 Robinhood Chain 上,如果设置了预言机的排序器检查,排序器宕机或刚刚恢复会阻止每一段(参见Robinhood 通道);在 Chainlink 为该链发布在线状态喂价之前,这项检查处于关闭状态。

门槛和这两项界限是 StockFun 所有者自 2026-10-05 起的设置的默认值,每个金库都实时读取:以太坊金库读取工厂合约的设置,镜像金库的买入读取远端枢纽的设置。变更适用于每个金库的下一次转换。

数额与预留

自 2026-10-01 起,在 2026-09-29 的安全审计之后:

  • 每一步花费 Keeper 指定的数额。一个金库如果大于其交易场所在界限之内所能吸收的规模,就会在多次循环中分批转换。在此之前,每一步都花费全部余额,而规模超出其交易场所的金库就再也无法转换。
  • ETH 这一步的界限按该数额计算,而不是按实时余额计算。在这次转换的交易等待执行期间,各笔交易新增的 ETH 不再会让 Keeper 的最低数额失效。
  • 现金逐只股票预留。现金一到达,就按篮子的权重为每只篮子股票预留出来。每只股票只花费自己的预留额,被 Keeper 跳过的股票会把它保留到以后。在此之前,被跳过的股票的份额会在整个篮子中重新分配:通过跳过股票,Keeper 可以把一个国库的几乎全部资产转入一只股票。

两种买入股票的金库都以这种方式运作:Robinhood Chain 上的镜像金库,以 USDG 计;以及本地通道上的以太坊金库,以 USDC 计。

在这两种金库中,自 2026-10-01 的安全流水线起,一次紧急转移如果使现金低于预留额,就会把预留额全部清零:剩余的现金,以及之后每一笔流入的现金,都按篮子的权重重新分配。只拿走未预留现金或其他资产的紧急转移,会保留这些预留额。在此之前,这种清零只存在于金库对其预留额的读取之中:旧的预留额会随着下一笔流入的现金回来,而 Keeper 调用的先后顺序决定了篮子的构成。

Keeper 的角色

触发,仅此而已。它选择时机,指定每一步的数额,提议兑换路径,并提供最低数额——如果这些数额比金库自身的预言机界限更宽松,或某个数额超出为该股票预留的部分,金库就会将其拒绝。Keeper 可以要求比界限更多,但绝不能更少。自 2026-10-05 起,金库会确保实际到达的数量不低于 Keeper 的最低数额。

Keeper 会把每只股票的预留额全部花完,只有篮子的最后一只股票除外,它在那里留出 n−1 个单位,n 为股票的数量:参见Keeper。

在可选的 Ondo 通道上,Keeper 为每一段向金库提供一份由发行方签名的报价。这样的报价对任何出示它的人都有效,因此自 2026-10-05 起,Ondo 路由器只为工厂合约的金库服务,即协议金库和每个已注册市场的金库,并拒绝其他任何人(NotAVault):其他人无法花掉 Keeper 的报价、让那次转换失败。此外,协议的每一个路由器都拒绝把自己作为一次兑换的接收方,因此它在两次交易之间不持有任何东西。

无论它指定什么,Keeper 都无法挪用资产,无法选择另一个篮子,无法把一只股票的现金转给另一只,也无法放宽界限。

空投

金库的股票只有一个去向:代币的持有者,在每次空投时,按其持仓比例分发。分配依据一条没有人能选择的规则由余额得出——创建者不能,Keeper 也不能。该机制自 2026-10-04 起已写进代码,尚未部署:参见空投。

在本地通道上,金库自己移交它的股票。sendToAirdrop(stocks) 仅限 Keeper 调用,它把列出的每只篮子股票的全部余额发送到工厂合约所指定、并被实时读取的空投合约。金库授权确切的数额,空投合约将其拉取,并计入该市场当前的循环,随后在调用返回之前把授权重新关闭。一只被列出两次或不在篮子中的股票会让调用失败;没有余额的股票会被跳过。自 2026-10-05 起,每只股票都单独进行:余额无法读取或转账被拒绝的股票(例如发行方冻结),会留在金库中并发出一个事件(AirdropSendFailed),其他股票照常发送;当没有任何股票发出时,调用会失败,并说明原因。接入了跨链桥枢纽的金库会拒绝这一调用:它的股票是在 Robinhood Chain 上买入并持有的,由镜像金库以同样的方式,经由每只股票的 LayerZero 适配器发送。

创建者回购,即 buybackAndBurn(...),曾允许创建者卖出国库的股票以回购并销毁其代币,它于 2026-09-27 被放弃,并于 2026-09-28 从代码中移除。

金库可以持有什么

ETH、USDC、USDG,以及其篮子中的股票;此外,在可选的 Ondo 通道上,还有发行方铸造可能退回的 USDon。金库不会买入其他任何东西。这是由代码得出的结论;没有任何测试将其作为不变量进行检查,也没有任何东西能阻止第三方向金库地址发送一个无关的代币。紧急模式会像转移任何其他资产一样把这样的代币转出。

一个装满 USDC 的金库并没有出故障:它处于转运途中。这三种状态都会作为等待下一次空投的国库显示;只有股票会在买入后被分发。

每个市场一个代理合约

自 2026-10-02 起,每个市场的金库都是它自己的代理合约。它随市场一起创建,位于工厂合约当时所指定的金库实现合约前面,并在同一笔交易中完成初始化,带上它的篮子、它的市场,以及工厂合约当时所指定的路由器、预言机和跨链桥枢纽。StockFun 的所有者逐个升级金库,一个市场接一个市场,并立即生效。在工厂合约中指定的新实现合约只会作用于此后创建的市场。

Robinhood Chain 上的镜像金库遵循同样的规则:参见Robinhood 通道。

紧急模式

自 2026-08-29 起,StockFun 的所有者可以把任何资产移出金库,转移到任意地址;自 2026-10-05 起,这种转移立即生效,无需事先公告。它与空投一起,是当前实现合约允许资产离开金库的仅有途径,详见紧急模式。