信任模型

谁能做什么。这是诚实的答案,而不是营销的答案。

自 2026-10-02 起,协议中几乎每一个合约都可升级:StockFun 的所有者可以替换其代码,并立即生效。自 2026-10-05 起,协议的各项数值,从税到空投的循环,也都是所有者的链上设置,同样立即生效:本书给出的数字是它们的默认值,下文连同保持固定的事项一并列出。本书归于某个模块的每一条规则,都是其当前实现合约的规则。不在升级权力范围之内的:代币、流动性锁定合约,以及 Robinhood Chain 上的镜像金库部署器。

没有人能做的事

这些事项依赖于无法升级的合约。无论所有者升级或设置什么,它们都依然成立。

  • 铸造新代币。供应量只在构造函数中铸造一次,而且代币无法升级
  • 未经持有者授权就转移其代币。代币的 setter setRecorder 不会移动任何余额,而它们的救援函数(自 2026-10-05 起)只转移发到代币自身地址的东西
  • 在没有 30 天公开事先公告的情况下撤出一个池子的流动性。锁定合约无法升级,其唯一的出口是下文所述的终止模式,而这 30 天是一个常量,不是一项设置。它的救援函数(自 2026-10-05 起)既触及不到头寸,也触及不到它为接收方保留的手续费份额
  • 更改一个现有池子的 LP 手续费或 tick 间距。每个池子都保留它创建时的这两个数值:它们是池子键的一部分,由锁定合约保存

当前代码所排除的事

在当前的实现合约下,没有人能做这些事,所有者也不例外。每一项都依赖于一个所有者可以升级的模块。

  • 向 StockFun 池子添加流动性。自 2026-10-01 起,只有流动性锁定合约可以
  • 通过费用钱包或金库阻断交易。交易期间只支付国库份额,而自 2026-10-05 起,拒收这一份额的金库会改为被欠下这笔数额;其他份额事后领取
  • 在创建后更改篮子的构成
  • 更改一个现有金库所读取的价格喂价。每个喂价都在预言机初始化时一次性写入,每个金库也保留自己的预言机;喂价的心跳间隔是设置,自 2026-10-06 起,预言机在 Robinhood Chain 上的两项防护也是设置,它们只能暂缓给出价格,绝不会改变价格
  • 将 $STOCKFUN 回购所得的代币发送到销毁地址以外的任何地方
  • 选择谁获得空投,或领取别人的份额。分配依据已记录的持仓按比例得出,并且只有持有者本人可以领取

创建者能做的事

  • 赚取其市场上每笔交易的创建者份额,默认为 2 %,并领取它,自 2026-10-05 起,如果愿意,也可以领取到另一个地址(claimCreatorFeesTo)
  • 设定其市场的防狙击白名单,名单上的地址在最初几个区块内支付正常的税:默认最多 20 个地址,在创建交易中确定,公开,且此后不可更改
  • 像任何人一样买卖自己的代币

他们不获得任何分配,不控制流动性,也无法暂停自己的市场。他们对国库没有任何权力:他们只能像任何持有者一样获得股票。

Keeper 能做的事

在自己选择的时刻、以自己指定的数额、沿自己提议的路径,触发转换。始终处于金库的预言机界限和每只股票的预留额之内,并且从不选择谁获得什么。自 2026-10-01 起,跳过一只股票不再会改变篮子的权重:该股票会把它的份额保留到以后。自 2026-10-05 起,金库会确保实际到达的数量不低于 Keeper 所指定的最低数额。自 2026-10-06 起,Keeper 按照 2026-09-27 的决定,每个空投时间窗口转换一次金库的 ETH:这是 Keeper 自己的规则,金库并不强制执行;金库只记录其 ETH 最近一次转换的时间。

自 2026-10-05 起,它也是唯一能发送跨链批次的一方(bridgeReady);而在 Robinhood Chain 上预先部署一个市场的镜像金库(predeploy),也只有它和 StockFun 的所有者能够做到。在此之前,这两件事对任何人都开放。远端枢纽从批次中得知 Keeper,因此在第一个批次之前,由 StockFun 的所有者预先部署第一个市场的金库,而一个 Keeper 无法为其预先部署金库的市场会被留在它的批次之外。

在空投上,自 2026-10-04 起:开启一个市场的循环(openCycle),把金库的股票发送到空投合约(sendToAirdrop,从 Robinhood Chain 发送时支付 LayerZero 费用),以及归入搁置的股票(assignUnassigned)。它选择时机,从不选择数额、对象、去向或受益人:数额是金库的余额,目的地是协议所指定的合约,而分配依据持仓得出。任何人都可以开启循环或归入搁置的股票,无论由谁调用,结果都一样。在下一个关闭时刻(默认为 13:00 UTC)之后到达的发送,按次日的时间窗口计量。它的每日步骤自 2026-10-05 起已经编写:参见Keeper。自第七个审计循环(2026-10-06)起,它只在一只股票的价值抵得上发送成本时才发送它,这只决定该股票何时发出:等待的部分留在金库中,等待之后的时间窗口。自第九个审计循环起(同一天),它还会指定每次送达在以太坊上获得的 gas,远端枢纽会把这一 gas 保持在 StockFun 的所有者设定的下限和上限之间,并且它会用自己的密钥再次执行卡在以太坊上 LayerZero 端点处的送达,而这件事任何人都可以做:两者都不会改变送达的内容,也不会改变送达的去向。

自 2026-10-05 起,它还会在每个循环中支付 Hook 和锁定合约为拒收的接收方所保留的款项(payTreasury、payOwed),并收取以 LP 手续费创建的池子的 LP 手续费(collectFees)。任何人都可以发出这三个调用,它们只向合约所指定的接收方付款。

它的密钥是热密钥。它从不选择资产的去向。

StockFun 的所有者能做的事

这才是真正需要信任的地方。StockFun 的所有者就是协议所有者:以太坊上工厂合约的所有者,并由远端枢纽镜像到 Robinhood Chain 上。

  • 升级除代币、流动性锁定合约和镜像金库部署器之外的每一个模块,立即生效,无需事先公告。金库逐个升级,一个市场接一个市场,在两条链上都是如此
  • 更改协议的各项数值,立即生效,无需事先公告:税、其分配比例和防狙击、创建费、新市场的形态、转换门槛和金库的价格界限、空投的循环,以及下文列出的其他各项
  • 启动锁定合约的终止模式,并在 30 天后把每个池子的全部流动性(包括 $STOCKFUN 的流动性)回收到任意地址
  • 指定每个代币向其报告转账的持仓记录器。如果报告失败,转账也会失败:这是“一处失败绝不阻断其余部分”这一规则唯一的刻意例外(参见架构),并有两个立即生效的补救手段:setRecorder(0),停止该代币的记录;以及就地升级记录器。自 2026-10-05 起,代币会拒绝一个所绑定的 Uniswap PoolManager 并非其池子所在者的记录器。记录器就地升级,这样会保留它的历史,而且不会在一个正在使用的代币上被替换:自 2026-10-05 起,替换后的记录器从该代币在 Uniswap PoolManager 之外的供应量起步,因此交易会继续进行,而空投不会计量任何在它之前开始的时间窗口;但它会把没有见到变动过的持有者读作在其下一次变动之前什么也没有持有,于是一个跨越这段时间的时间窗口付给他们的会更少,也不会多付给任何人。在 2026-10-05 之前,新的记录器会让每一笔卖出都失败,并破坏此后开启的循环的空投份额
  • 注册篮子,在它们被冻结之前
  • 设置一次性写入的地址,仅此一次
  • 设定 Keeper 和费用钱包。一次领取会支付给领取当时所设定的钱包,因此更改钱包也会改变尚未领取的团队余额或回购余额的去向
  • 更改记录在工厂合约中的官方兑换路由器,即 Hook 借以识别防狙击白名单的那个路由器
  • 让未来的金库指向另一个股票路由器或预言机注册表;现有金库保留原有的
  • 将每只篮子股票映射到其 Robinhood Chain 代币,只能追加
  • 设定每个代币的空投排除名单,适用于此后关闭的时间窗口(setExclusions);在以太坊上登记每只股票的 OFT(registerStockOft)
  • 指定金库发送股票的空投合约(setAirdropDistributor);被替换的空投合约会让它的每一个循环都仍可在原处领取。在 Robinhood Chain 上,指定空投路由,即空投合约和每次送达的 gas(setAirdrop),以及每只股票的适配器(setStockAdapter);自 2026-10-06 起,设定每次送达在以太坊上获得的 gas 的默认值、下限和上限(setAirdropReceiveGas、setAirdropComposeGas)
  • 立即替换未来发送所用的跨链桥适配器(changeAdapter),新适配器所固定的地址必须与当前适配器完全相同:同一个枢纽、工厂合约、现金代币、远端枢纽和目的地。2026-09-29 的安全审计发现,远端枢纽会拒绝新适配器的批次(M-2);2026-10-05,所有者决定维持现状,因此适配器的更换通过就地升级完成,地址不变
  • 暂停转换和跨链,立即生效。暂停中的远端枢纽仍会应用每个批次所携带的角色变更。在空投合约上,暂停会停止发送、循环的开启以及搁置股票的归入,但从不阻止领取
  • 把任何资产从国库、跨链桥枢纽或空投合约中转移到任意地址,立即生效,无需事先公告(emergencyTransfer),在任一条链上,随时都可以;在远端枢纽上,自 2026-10-05 起,还可以记在单个市场名下,在同一次调用中结清该市场的账目(emergencyTransferFromPending、emergencyTransferRecord)
  • 在从空投合约或远端枢纽进行这样一次转移之后,把损失从遭受它的那个循环或市场中核销(writeDownCycle、writeDownUnassigned、writeOffPending、writeOffRecord,自 2026-10-05 起)。一个循环只有在还没有人从中领取过该股票时才能被部分减记,此时每位持有者损失相同的比例;一旦已有持有者获得支付,就只能减记它的全部剩余部分,这部分损失由尚未获得支付的持有者承担,而此后到达该循环的一切会再次在其所有持有者之间按比例分配。没有任何其他市场为此支付;在损失被核销或资产通过任何人都可以调用的 restore 被送回之前,缺失部分的支付会等待,其他支付照常进行:一次领取会支付其他股票。这两个合约计算的都是支撑其账目的资产,从来不是它们的余额:正在前往另一个市场途中的资产绝不会为这笔损失支付,而向它们进行的一笔普通转账不支撑任何东西
  • 转出模块误持的东西(rescue,自 2026-10-05 起):发给不为任何人保管任何东西的模块的 ETH 或代币;Hook 的误入资金,绝不包括它所欠的款项;锁定合约在其保留的手续费份额之外持有的东西,绝不包括它的头寸;BuybackBurner 的 ETH,但只有在任何销毁都无法再花费它时;发到代币自身地址的东西。参见紧急模式
  • 更改空投股票适配器的 LayerZero 配置,无需事先公告,也没有提取上限

升级是这些权力中范围最广的一项:它一次就能触及上面第二份清单中的每一条规则。它与各项设置、终止模式、紧急转移以及股票适配器的配置一起,意味着 StockFun 并非无需信任,也不自称如此。国库由协议看管,同时存在一条由所有者控制的回收路径。

设置

自 2026-10-05 起,协议的各项数值都是 StockFun 所有者的链上设置,在两条链上都是如此。每一项设置在设定它的那笔交易中即生效,没有事先公告,会发出一个事件,并拒绝不可能的数值:超过 100 % 的费率、大于税的分配、池子无法容纳的发射形态。下列数值是默认值,即本书所给出的数值。

设置 默认值 设定位置
每笔交易(买入和卖出)的税 5 % Hook,setTaxSettings
已发射市场上税的各项份额:国库、创建者、团队;其余归回购 2 %、2 %、0.5 %;回购 0.5 % Hook,setTaxSettings
$STOCKFUN 市场上税的各项份额:国库、团队;其余归回购 2 %、2.5 %;回购 0.5 % Hook,setTaxSettings
防狙击:开盘区块的税、每个区块的降幅、持续的区块数 80 %、8 个点、10 个区块 Hook,setTaxSettings
一个市场最大的防狙击白名单 20 个地址 Hook,setTaxSettings
创建费,支付给团队钱包 0.001 ETH 工厂合约,setCreationFee
新市场的长度限制:Ticker、名称、图片 URI、描述 2 至 10、48、256、512 字节 工厂合约,setStringLimits
新市场的形态:供应量、区间 1、tick、tick 间距、LP 手续费 1,000,000,000 枚代币,区间 1 中 700,000,000 枚,tick 195,000 / 171,960 / −887,220,间距 60,无 LP 手续费 工厂合约,setLaunchConfig
锁定头寸所收取的部分(ETH 一侧):市场金库和团队的份额;其余归创建者,在 $STOCKFUN 上归团队 50 %、25 %;创建者 25 % 工厂合约,setLpFeeShares
金库单次转换的最小数额,以及金库相对预言机的价格界限:ETH → USDC 和股票买入 0.1 ETH、50 bps、200 bps 工厂合约,setConversionParams
镜像金库买入时的价格界限 200 bps 远端枢纽,setStockMaxSlippageBps
预言机的心跳间隔:ETH/USD、每只股票 部署脚本中为 1 小时和 1 天 各链的预言机,setEthUsdHeartbeat、setHeartbeat
排序器检查:Chainlink 的 L2 排序器在线状态喂价,以及重启之后的宽限期,在此期间预言机暂缓给出所有价格(自 2026-10-06 起) 关闭:Robinhood Chain 没有这样的喂价,因此部署时关闭这项检查;设置喂价时,宽限期为 3,600 秒 各链的预言机,setSequencerUptimeFeed;在以太坊上关闭
每只股票的预言机暂停检查:当其代币表明其预言机因公司行动而暂停时,暂缓给出其价格(自 2026-10-06 起) 对 Robinhood Chain 上的每只股票开启,在以太坊上关闭 各链的预言机,setOraclePauseCheck,按股票设置
空投的时间窗口:长度、关闭时刻 24 小时、13:00 UTC 空投合约,setCycleSchedule
空投的限额:最大排除名单、一次 assignUnassigned 检查的时间窗口数 16、30 空投合约,setMaxExcluded、setMaxWindowsPerAssign
空投的 LayerZero 端点和来源链 以部署为准 空投合约,setLayerZero
USDG 跨链桥:Curve 上可接受的最差 USDG/USDC 兑换率,以及批次在 Robinhood Chain 上的最后一步中每个批次都需要的那一部分(在第十个审计循环之前,整个步骤只有一个数值,即 1,200,000) 30 bps、200,000 gas UsdgOftAdapter,setSettings
USDG 跨链桥的批次:批次中每个市场给该步骤增加的 gas,以及一个批次最多携带的市场数,由 LayerZero 的消息大小决定(自第十个审计循环起;无论设置如何,最大批次的 gas 都至多为 24,000,000) 400,000 gas、17 个市场 UsdgOftAdapter,setBatchGas
官方跨链桥:其两张票据的 gas,这两张票据的提交成本是下限 以部署为准 ArbitrumCanonicalAdapter,setTicketGas
官方跨链桥:计算存入票据成本所依据的字节数 1,024 ArbitrumCanonicalAdapter,setDepositCalldataLength
远端枢纽上一次 sweep 支付的记录数 64 远端枢纽,setMaxRecordsPerSweep
每次空投送达在以太坊上的 lzReceive gas(在股票 OFT 强制设定的 gas 之上):Keeper 所请求数值的默认值、下限和上限(自 2026-10-06 起) 650,000、200,000、1,500,000 远端枢纽,setAirdropReceiveGas
每次空投送达在空投合约上的 compose gas:默认值、下限和上限(2026-10-06 之前为一个数值 600,000) 1,250,000、600,000、4,000,000 远端枢纽,setAirdropComposeGas;默认值也可通过 setAirdrop 设置
  • 每个池子,从下一笔兑换起。税或防狙击的变更从下一笔兑换起适用于每个池子,包括仍处于防狙击区块内的池子:递减按当时有效的设置、从该池子的发射区块起计算。防狙击收取的税从不低于正常的税。白名单上限在创建市场时适用
  • 形态只适用于新市场。新的供应量、新的区间、新的 tick 间距或新的 LP 手续费适用于此后创建的市场。每个池子保留它创建时的 LP 手续费和 tick 间距,Lens 会逐个市场给出这些数值;$STOCKFUN 的池子采用其发射时有效的数值
  • 对金库实时生效。每个金库在每次转换时读取转换门槛及其价格界限,锁定合约在每次收取时读取 LP 手续费份额
  • 已开启的循环保留其时间窗口。新的空投时间表适用于尚未开启的时间窗口,并重新划分它们,包括搁置的股票仍需检查的那些

保持固定的事项:

  • 终止模式的 30 天事先公告期,即 END_DELAY,它是流动性锁定合约的一个常量,而该合约无法升级
  • 紧急转移的即时性:它没有延迟,任何设置也无法加上延迟
  • 单位和编码:基点、作为持仓记录和空投时间窗口单位的小时、销毁地址、消息格式
  • 接线:价格喂价、以太坊上股票路由器买入所用的池子、USDG OFT、跨链桥的 LayerZero 端点、远端枢纽、Curve 池。它们在部署时固定或一次性写入;更改其中任何一项都意味着指向另一个合约,这需要一次升级

升级

自 2026-10-02 起,除下列合约之外,每个模块都是一个通过 UUPS 升级的代理合约。其构建方式参见架构。

链 由谁升级 模块
以太坊 工厂合约的所有者:每个模块都向工厂合约询问所有者是谁 工厂合约本身、Hook、持仓记录器、每一个 TreasuryVault、预言机、股票路由器、官方兑换路由器、BuybackBurner、Lens、跨链桥枢纽及其适配器、空投合约
Robinhood Chain 远端枢纽的紧急管理员:即最近一个跨链批次所携带的以太坊所有者;在第一个批次之前,则是部署时指定的初始管理员 远端枢纽本身、每一个镜像金库、股票路由器、预言机
  • 立即生效。升级在执行它的那笔交易中即生效:没有时间锁,也没有事先公告,与各项设置和紧急转移一样
  • 经过检查。只有协议所有者可以升级。新的实现合约必须听命于同一个升级授权方,而 Hook 和持仓记录器的新实现合约还必须保留同一个 PoolManager
  • 逐个市场。每个金库都是它自己的代理合约。在工厂合约中指定的新金库实现合约适用于此后创建的市场;现有金库则逐个升级
  • 存储只追加,从不重排。每个模块的存储布局都有记录,一个脚本会在每次升级之前检查它,自 2026-10-05 起检查每个结构体的每一层

以下合约无法升级:

  • 代币,即市场代币和 $STOCKFUN:普通的 ERC-20,供应量只铸造一次,没有铸造、销毁、暂停或黑名单功能。它们唯一的 setter setRecorder 及其救援函数归协议所有者使用
  • 流动性锁定合约,正是它的代码把流动性保留在池子中。流动性唯一的出口是终止模式;它的救援函数既触及不到头寸,也触及不到它所保留的份额
  • 镜像金库部署器,位于 Robinhood Chain 上:每一个镜像金库的地址都由它自己的地址推导而来

以太坊上的两个部署器不持有任何状态,它们通过工厂合约被替换,而不是被升级。

终止模式

流动性锁定合约唯一的出口,于 2026-10-02 加入,用于项目关闭的情形。StockFun 的所有者调用 end()。从那时起,不能再发射新的市场,而每个池子都照常交易。三十天后,所有者可以把每个池子的全部流动性回收到任意地址。在终止待生效期间,所有者可以随时取消;已经回收的池子则保持为空。这 30 天是给持有者的事先公告期。详见双头寸发射。

外部依赖

依赖 它可能破坏什么
Paxos / USDG 可以暂停或冻结。通道的现金腿随之停止。自 2026-10-05 起,冻结某一个镜像金库只会停止向该金库的送达:它的份额在远端枢纽上等待,作为欠其市场的款项,其他市场照常获得支付(R2H-2,已关闭)
LayerZero 一条丢失的消息会让资金滞留在途中,直到重放或回收。自 2026-09-28 起,空投封装股票的安全也取决于它
Robinhood Chain 一条年轻的链。一次宕机会冻结所持有的股票。自 2026-10-06 起,当 Chainlink 的排序器在线状态喂价表明排序器宕机或刚刚恢复时,预言机还可以暂缓给出所有价格;在 Chainlink 为 Robinhood Chain 发布这样的喂价之前,这项检查处于关闭状态,而 Chainlink 尚未发布
Chainlink 喂价 一个过期的喂价会阻止需要它的那次转换;自 2026-10-05 起,对于一只股票,只阻止该股票的那一段。自 2026-10-06 起,公司行动也是如此:当一只股票的代币表明其预言机已暂停时,喂价会保持其最后一个数值,而预言机会暂缓给出该股票的价格,因此它的那一段会等待,其现金为它保留,其他股票照常买入。这是预期行为
二级市场流动性 如果池子过浅,Keeper 会分成更小的批次买入,而价格界限(默认为 200 bps)会拒绝仍然无法成交的部分

这些依赖没有一项是隐藏的,也没有一项能把资产从金库中转移到某个地址。

已接受的风险

  • 升级、设置变更和紧急转移都立即生效:持有者不会就它们获得任何事先公告,这与提前 30 天宣布的终止模式不同
  • 每一笔代币转账都依赖于持仓记录器:报告失败会使转账失败。这是“一处失败绝不阻断其余部分”这一规则唯一的刻意例外:如果允许报告失败,持有者就可以让记录漏掉自己的变动,从而增大自己的空投份额。它的补救手段立即生效:在代币上调用 setRecorder(0),或者就地升级记录器
  • 一份被接收方拒收的份额会在 Hook、锁定合约、远端枢纽或空投合约上等待该接收方,而不会让其余部分停止;不记在任何市场名下的紧急转移,会让该资产的支付一直等待,直到它被结清
  • 没有国库会积累资产:一切都会被分发,如果没有人交易,空投可能为零
  • 空投以封装股票的形式在以太坊上支付:它们的价值仅取决于锁定在 Robinhood Chain 上的股票和 LayerZero 配置,而一旦发行方冻结 Stock Tokens,被锁定的股票也将无法动用
  • 一个市场可能永远不会耗尽其第一个流动性区间
  • 在默认的 5 % 税下,在任何价格变动之前,一次往返交易的成本为 9.75 %
  • 在撰写本书时,跨链通道尚未在真实条件下运行过