跳到主要内容

StockLend 运作机制

以 USDG 作抵押借出代币化股票,卖入周末溢价,待喂价回归后再买回。本文说明债务为何按两个价格而非一个价格计价,以及买卖双方 仍可能以哪些方式亏损。

一笔空头,按买回来的真实成本计价​

Chainlink 的股票喂价为 24/5。从周五收盘到周日晚间,喂价停留在上一个收盘价,而 token 照常交易,因此溢价可以持续两天而无人套利。 StockLend 将这一现象转化为一个仓位:抵押 USDG,借出股票 token 并卖出,待喂价重开后再买回。

  • 这是自研合约,并非 Morpho。债务按 max(预言机, 池 TWAP) 计价,而非按预言机。
  • 该合约公开、无许可。不设 keeper:清算和买回对任何人开放,并提供奖励。
  • owner 唯一可调的参数是借出上限。其余每个参数均受合约自身限制。
双方的角色

出借方存入股票 token,获得以 USDG 计价的借券费。借款人抵押 USDG,所欠为股票。双方承保的是同一风险的两端:在喂价恢复之前,池价 可能偏离多远。

单一价格的不足​

按预言机计债的借贷市场,是以一个已停止更新的数值为贷款定价。在整个周末,这相当于无偿赠予借款人一个看涨期权:只要 token 价格越过 「预言机 ÷ 质押率」,不还款就严格优于还款,而清算按冻结价以 USDG 向出借方结算。出借方始终无法收回股票。

这并非假设,而是我们掌握数据的上一个周末的实际情况。

那个周末 $289 万成交里有 $193 万发生在 60% 以上的溢价。Chainlink 全程停在 $127.52,周一 02:00 UTC token 已经回到 $129.68。

按 Morpho 模式建立的市场会因设计本身而被掏空,而非因 bug 被掏空——这正是 StockLend 采用自研合约、而非在他人合约上建立 市场的原因。

两个价,和一道钳制​

预言机价是周一将回归的价格,也是收费的基准。池的 TWAP 是买回股票的实际成本。债务按两者中的较高者计价,因此挤兑 发生时,仓位随挤兑变动。

但直接采信池价会导致另一个更严重的错误。集中流动性仓位的尾部是空的:窄区间被买穿之后,将 tick 推至任意位置几乎没有成本,测试中 30 分钟 TWAP 在五分钟内读数达到 53 倍。因此计债价需要钳制。

计债价 = min( max(预言机, 池 TWAP), 预言机 × (1 + 带宽) )

仅有钳制不足​

如果初始保证金低于 维持线 × (1 + 带宽),他人即可将池价推至钳制上限,并在上限处清算健康的贷款。合约不允许此类配置:两个档位 均强制 IM ≥ MM × (1 + 带宽),这也是应用中显示的保证金为非整数值、而非更整的数值的原因。

带宽在每笔贷款中冻结​

一次评审发现了这一缺口:若带宽按当前档位读取,则在开市档按较窄带宽开立的贷款,每晚喂价停更时都会落入闭市带宽,并被 一次其从未为之缴纳保证金的推价清算。带宽、维持线和清算奖励均在开仓时写入贷款,owner 修改参数不影响已存在的贷款。

借款人的费用​

费用在贷款开立时以 USDG 收取,它并非利率,而是溢价的一个分成:α × 溢价 × 股数 × 预言机价。原因在于自适应利率无法应对的 情形——两个小时的周末挤兑,早在利用率曲线作出反应之前就已结束。

项目原因
开仓费(α)溢价的一个分成,一次性预收。溢价按 max(TWAP, spot) 相对预言机计算,借款人自行提供 maxFeeOpen,报价不会在其不知情时变动。
初始保证金开市为一个值,闭市为更高的值。按开仓时的档位收取,且以计债价而非预言机为基准——这正是关键所在。
期限首先由链上交易日历决定,配置的期限为上限。开市时借出的贷款在当天收盘时到期,因此任何人都无法在周四晚间借入一笔零溢价贷款横跨整个周末。闭市时借出的贷款在下次开市后的一段固定时间到期,另设宽限期。
买回上限到期后任何人均可用借款人的抵押品买回股票,但成交价不得超出结算价加一个余量。该余量起初很紧,每小时放宽一个点,因此拉盘的区块只会导致买回失败,而不会掏空借款人——真实的溢价仍会在一天内清除。
借款人的尾部

若到期时喂价仍处于冻结窗口,结算价即为预言机价,上限由此向外增长。最坏情况下,借款人将按预言机价加上完整的滑点上限被 买回。这是确保「上限不能被守候尾部行情的人操纵」所需付出的代价。

出借方的收益与承担​

存入股票获得份额,费用按份额以 USDG 累计,与所有 staking 合约的做法相同。本金仅在核销时变动。无需关注利率曲线:收入即每笔借款 溢价的 α 分成加上时间费,两者均由自愿进入的借款人支付。

保护到带宽为止​

在钳制上限以下,池价即为出借方的保护——债务随挤兑一同上涨。上限之上则不再如此。超过带宽的那部分溢价显示在屏幕上,却不计入 债务,此时为出借方提供保障的是抵押品,以及喂价终将重开这一事实。若某一标的确实重估超过带宽且不再回归,该笔抵押品将不足。

因此带宽并非安全开关,而是一项产品决策:它是该市场承诺为出借方承担的最大溢价,依据每个标的各自的历史逐一设定。以上述 MSTR 周末为例,覆盖完整的 2.7 倍需要 310% 的初始保证金。

贷款的结束方式​

共有四个出口,均无需由我们执行。repay 由借款人执行。健康度跌破维持线后,任何人均可 liquidate 并获得奖励。贷款到期后,任何人均 可 buyIn 并获得奖励。writeOff 是最后一个出口,也是出借方本金唯一会发生变动的途径。

两个细节源自评审而非设计。抵押品退款采用拉取式,因此某个 USDG 账户被冻结,不会阻塞他人的平仓。此外,在 token 的 oraclePaused() 因公司行动被置位期间,合约完全不执行健康度清算,也不执行核销——喂价在乘数变更期间停留在最后一个有效值上, 依据它行动即是依据一个已知错误的数值行动。

已证明与已测量的结论​

推高价格无法清算有足额抵押的贷款​

这一结论来自算术,而非判断。计债价不可能超过 预言机 × (1 + 带宽);初始保证金不低于 维持线 × (1 + 带宽);带宽在开仓时固定。三者 结合,一笔新贷款的健康度不可能仅因池价而被推至维持线以下——只有喂价实际变动才可能如此。

针对已部署合约运行了三个攻击场景:闭市档按闭市初始保证金开立的贷款、跨过喂价夜间空档的开市档贷款,以及池价实际上涨 22% 时 一笔到期的健康贷款。三次均被拒绝,攻击者每次的净收益均为负——即买穿窄区间再买回的往返成本。

买回不会被无限期阻塞​

确实有人可以在每次 buyIn 之前推高池价,使其 revert。上限每小时增长一个点直至封顶,因此这种每次都需支付一次区间往返成本的 拖延,上界约为一天——而这段时间的时间费归出借方,而非归干扰者。

未能证明:出借优于持有​

我们仅有一个真实挤兑周末的数据,涉及一个标的,且参数正是依据该事件校准的。以唯一的样本进行校准,无法证明校准结果可以泛化。 如实的表述是:该机制在结构上能够承受那次事件;至于手续费在多个周末中能否覆盖这一尾部风险,目前尚无人完成相应的测量。

风险​

带宽之上,池价不再保护出借方​

此处再次强调,因为这是确实会造成亏损的一项:超过带宽后债务不再随价格变动,出借方依靠的是已存入的抵押品,以及喂价重开时该标的 价格回归。

发行方可以暂停 token​

股票 token 是带有全局 pause 的 beacon 代理。转账一旦暂停,市场中的所有操作随之停止——恢复之前任何人都无法还款、清算或买回。 不存在黑名单,但 pause 已足以造成上述影响。

一个市场,一个上限,一次记录在案的事件​

第一个市场的上限是我们愿意承担出错风险的规模,而非对需求的判断。「借出股票 token 用于卖出」的法律定性尚未评估。

一句话

债务按「买回股票的实际成本」计价,上限是该市场承诺为你承担的溢价——超过上限,剩余的保障仅有抵押品,以及喂价终将重开 这一事实。

参考​

角色它决定什么
StockLend一只股票一个市场:存取、借贷、清算、买回、核销
TwoPriceOracle喂价、池 TWAP、钳制后的计债价、当前档位
TradingCalendar24/5 交易时段、夏令时、NYSE 假日,全部由时间戳计算得出——无需任何人输入
池子TWAP 从此处读取,买回也在此处成交
Owner一个 Safe:在合约自身边界内修改参数及上限。不存在 keeper 角色。

地址及上述每个参数的实时值,见应用中各市场各自的页面:hedgehood.io/lending。另见 三种价格和术语。