双重质押智能合约

概览

双重质押合约允许参与者通过持有 sBTC 并可选择质押 STX 来获得提升的 sBTC 奖励。它以周期运行,并在周期内定期快照以根据持有量和质押参与情况计算奖励。

circle-info

有关主网的实时双重质押合约,请查看合约页面 此处arrow-up-right.

在 2025 年 12 月 15 日,双重质押合约将升级为 .dual-stacking-v2_0_2arrow-up-right

去中心化架构

  • 无权限操作:任何人都可以执行关键的周期操作,包括捕获快照、提议/验证比率、计算权重和分配奖励。

  • 仅链上数据:所有参与者数据(sBTC 余额、STX 质押数量)均直接从区块链读取——不需要链下预言机或受信任的数据源。

  • 竞争性比率发现:多个参与者可以提出不同的黄金比率;系统基于数学标准(第 95 百分位)进行验证,而非管理员批准。

  • 透明执行:所有操作在链上执行,结果可验证并有公开事件日志。

  • 自助注册:用户可以自行注册、退出并独立管理其参与。

主要操作

1

初始化

合约使用一个 Stacks 区块高度参数初始化一次,该高度是指定的比特币区块中第一个存在的 Stacks 区块,或在其之后(如果没有任何 STX 区块锚定到该比特币区块)。

2

注册

用户可以自助注册参与并提供自定义奖励地址。DeFi 协议可由管理员用自定义跟踪、质押和奖励地址进行注册。所有参与者可以随时选择退出或更改其地址。

3

快照与周期

任何人都可以触发定期快照,这些快照根据预定义的区块间隔从链上数据捕获参与者的 sBTC 余额和 STX 质押数量。

4

比率计算

在快照完成后,任何人都可以提出黄金比率(最优 STX/sBTC 比率)、统计参与者分布,并验证其提议是否满足第 95 百分位标准以确定最大奖励的基准。

5

权重计算

任何人都可以使用已验证的双重质押公式触发参与者权重计算,对于满足或超过黄金比率的参与者,公式可提供最高 10 倍(可配置)的提升。

6

奖励

任何人都可以在每个周期基于计算出的权重触发奖励分发。管理员可以更新配置,如年化利率(APR)、收益提升倍数、快照长度和每周期快照数量。

7

管理控制

管理员维护协议参数,注册/取消注册具有特殊地址配置的 DeFi 协议,管理白名单和黑名单,并在需要时执行紧急操作。


周期结构

  • 每个周期由固定数量的快照组成(默认 14 次)。

  • 每次快照发生在若干比特币区块之后(默认 150 个区块)。

  • 因此默认的整个周期长度为 2100 个比特币区块(14 次快照 × 150 区块)。

  • 这些默认值可以根据生产环境进行调整(例如,每天 1 次快照并使用相应的区块数量)。

双重质押公式

权重计算:

wi=[Bi(1+Mri)]nw_i = \cfrac{[B_i \cdot (1 + M \cdot \sqrt{r_i})]}{n}

其中:

  • wi = 用户 i 的权重

  • Bi = 用户 i 的 sBTC 余额(跨所有快照的总和)

  • M = 收益提升倍数(默认 9,表示最高提升为 10 倍)

  • ri = min(di/D, 1),比率调整因子

  • di = Si/Bi,用户的个人 STX/sBTC 比率

  • Si = 用户 i 质押的 STX(跨所有快照的总和)

  • D = 黄金比率(所有参与者 STX/sBTC 比率的第 95 百分位)

  • n = 每周期快照次数(默认 14)

奖励分配:

Ri=(wiΣw)TotalRewardsR_i = (\frac{w_i}{Σw}) \cdot Total Rewards

其中:

  • Ri = 用户 i 的奖励

  • Σw = 所有参与者权重之和

  • 总奖励 = min(池余额, 基于 APR 的上限)

关键属性:

  • 具有 di ≥ D 的参与者可获得最大提升 (M+1) ×(默认 10 倍)。

  • 具有 di = 0(未质押 STX)可获得基础奖励(1 倍)。

  • 对于中间值,提升按比率的平方根缩放。

  • 白名单的 DeFi 跟踪地址在无需质押 STX 的情况下自动获得最大提升。

  • 权重除以每周期的快照次数以在周期期间进行规范化。


周期工作流

双重质押智能合约以周期运行,每个周期划分为多个快照。该流程通过一系列任何人都可执行的无权限操作来确保准确的奖励分配。

1

快照阶段(任何人可执行)

  • capture-snapshot-balances:任何人都可以在每次快照后捕获已注册用户的余额。

  • advance-to-next-snapshot:任何人都可以过渡到下一个快照。

  • finalize-snapshots:任何人都可以在最后一次快照后结束所有快照数据。

2

比率验证阶段(竞争性且无权限)

  • propose-golden-ratio:任何人都可以提出黄金比率。

  • tally-participant-ratios:提议者统计参与者相对于其提出比率的比例情况。

  • validate-ratio:提议者验证其提议——仅当其代表第 95 百分位时才成功。

  • 可以提交多个提议;第一个有效的提议将在该周期内被锁定。

3

权重计算阶段(任何人可执行)

  • calculate-participant-weights:任何人都可以使用双重质押公式计算参与者权重。

  • finalize-weight-computation:任何人都可以完成权重计算。

4

奖励分发阶段(任何人可执行)

  • set-is-distribution-enabled:任何人都可以通过确定可用奖励池来启用奖励分发。

  • distribute-rewards:任何人都可以根据权重向已注册用户分发奖励。

  • finalize-reward-distribution:在所有参与者获得奖励后,任何人都可以完成奖励分发。

5

周期过渡(任何人可执行)

  • advance-to-next-cycle:在所有奖励分发完成后,任何人都可以推进到下一个周期。

注意:所有操作直接从区块链读取数据(sBTC 余额来自 sBTC 代币合约,STX 质押来自原生 Stacks 协议)。不需要链下数据源或受信任的中介。


公开函数

1. 合约初始化

initialize-contract

用初始周期激活合约。

  • 参数:stx-block-height(无符号整数)

  • 断言:

    • 当前比特币区块高度必须 >= 配置的周期起始比特币区块高度。

    • 合约必须处于未激活状态。

    • Stacks 区块高度必须包围配置的比特币区块高度。

  • 效果:

    • 初始化第一个周期的状态变量并将合约标记为激活。

    • 记录周期数据和第一次快照。

update-initialize-block

在合约激活之前更新初始化的比特币区块高度。

  • 参数:new-bitcoin-block-height(无符号整数)

  • 断言:

    • 合约必须处于未激活状态。

    • 调用者必须是管理员。

  • 效果:

    • 更新第一个周期的起始比特币区块高度。

update-cycle-data-before-initialized

在初始化之前更新第一个周期的每周期快照数和每快照区块数。

  • 参数:updated-snapshots-per-cycle(无符号整数),updated-blocks-per-snapshot(无符号整数)

  • 断言:

    • 合约必须处于未激活状态。

    • 调用者必须是管理员。

  • 效果:

    • 设置第一个周期的周期结构。


2. 注册

enroll

为调用者在未来周期中注册以获得奖励。

  • 参数:rewarded-address(可选主体)

  • 断言:

    • 调用者不得已注册。

    • 调用者不得在黑名单中。

    • 调用者必须持有至少最低所需的 sBTC 数量。

  • 效果:

    • 将调用者添加到参与者映射中,并适当设置跟踪、质押和奖励地址。

    • 递增下一周期的参与者计数。

enroll-defi

为 DeFi 协议注册以获得奖励并使用自定义地址(仅管理员)。

  • 参数:

    • defi-contract(主体)

    • tracking-address(主体)

    • rewarded-address(主体)

    • stacking-address(可选主体)

  • 断言:

    • 调用者必须是管理员。

    • DeFi 合约不得已注册。

    • DeFi 合约不得在黑名单中。

  • 效果:

    • 将 DeFi 协议以自定义地址添加到参与者映射中。

    • 递增下一周期的参与者计数。

enroll-defi-batch

批量注册多个 DeFi 协议(仅管理员)。

  • 参数:defi-contracts(最多 900 的主体列表 {...})

  • 断言:

    • 调用者必须是管理员。

  • 效果:

    • 在单个交易中注册多个 DeFi 协议。

opt-out

允许调用者选择退出未来周期的参与。

  • 断言:

    • 调用者必须已注册。

  • 效果:

    • 从参与者映射中移除调用者。

    • 递减下一周期的参与者计数。

opt-out-defi

为 DeFi 协议选择退出参与(仅管理员)。

  • 参数:defi-contract(主体)

  • 断言:

    • 调用者必须是管理员。

    • DeFi 合约必须已注册。

  • 效果:

    • 从参与者映射中移除 DeFi 协议。

opt-out-defi-batch

批量为多个 DeFi 协议选择退出(仅管理员)。

  • 参数:defi-contracts(最多 200 个主体的列表)

  • 断言:

    • 调用者必须是管理员。

  • 效果:

    • 在单个交易中为多个 DeFi 协议选择退出。


3. 参与者地址管理

  • change-reward-address

  • change-reward-address-defi

  • change-stacking-address-defi

  • change-tracking-address-defi

  • change-addresses-defi

  • change-addresses-defi-batch

(每个函数都有参数、适用时的管理员断言,并按原始规范描述更新参与者/DeFi 地址。)


4. 快照与周期

capture-snapshot-balances

在当前快照区块高度为一组参与者捕获快照余额。无权限。

  • 参数:principals(最多 900 个主体的列表)

  • 断言:

    • 合约必须处于激活状态。

    • 当前快照的 Stacks 区块高度必须可用。

  • 效果:

    • 从 sBTC 代币合约读取每个参与者的 sBTC 余额。

    • 从原生 Stacks 协议读取已质押的 STX 数量(包括如启用时的流动质押)。

    • 更新快照总额和参与者持有量。

    • 跟踪质押和跟踪地址。

advance-to-next-snapshot

将合约推进到当前周期的下一个快照。无权限。

  • 参数:new-stx-block-height(无符号整数)

  • 断言:

    • 合约必须处于激活状态。

    • 所有参与者必须已被快照记录。

    • 当前比特币区块高度必须已达到下一个快照区块。

    • 周期不得已结束。

    • Stacks 区块高度必须包围下一个快照的比特币区块高度。

  • 效果:

    • 递增快照索引。

    • 将快照总额汇总到周期总额中。

    • 重置快照计数器。

    • 记录新的快照区块高度。

finalize-snapshots

在最后一次快照完成后为当前周期最终确定所有快照。无权限。

  • 断言:

    • 合约必须处于激活状态。

    • 快照不得已被最终确定。

    • 必须处于周期的最后一次快照。

    • 在最后一次快照中所有参与者必须被快照记录。

  • 效果:

    • 将最终快照总额汇总到周期总额中。

    • 将快照标记为已最终确定。

    • 将最后一次操作状态设置为“concluded”。

    • 启用比率提议阶段。

advance-to-next-cycle

在所有奖励分发完成后将合约推进到下一个周期。无权限。

  • 参数:stx-block-height(无符号整数)

  • 断言:

    • 合约必须处于激活状态。

    • 当前比特币区块高度必须已达到下一个周期。

    • 所有参与者必须已获得奖励。

    • 奖励分发必须已最终确定。

    • Stacks 区块高度必须包围下一个周期的比特币区块高度。

  • 效果:

    • 递增周期 ID。

    • 为新周期重置状态变量。

    • 从下一周期设置更新周期配置。

    • 初始化新周期的第一个快照。


5. 比率计算与验证

propose-golden-ratio

为当前周期提出黄金比率。无权限。

  • 参数:ratio(无符号整数)— 提议的比率按 10^8 缩放

  • 断言:

    • 快照必须已被最终确定。

    • 本周期不得已存在已验证的比率。

    • 调用者不得已为本周期提出过比率。

  • 效果:

    • 记录调用者提议的比率。

    • 初始化参与者统计的跟踪。

    • 将最后一次操作状态设置为“proposed-ratio”。

change-proposed-golden-ratio

在验证之前更改先前提出的黄金比率。

  • 参数:ratio(无符号整数)

  • 断言:

    • 调用者必须已提出比率。

    • 该比率不得已被验证。

  • 效果:

    • 更新提议的比率并重置统计数据。

tally-participant-ratios

统计有多少参与者的比率高于、低于或等于提议的黄金比率。

  • 参数:principals(最多 900 个主体的列表)

  • 断言:

    • 调用者必须已提出比率。

    • 该比率不得已被验证。

    • 不得已已对所有参与者完成统计。

  • 效果:

    • 计算每个参与者的 STX/sBTC 比率。

    • 跟踪高于、低于和等于提议比率的 sBTC 数量。

    • 递增已计数的参与者数。

validate-ratio

验证所提比率是否代表参与者比率的第 95 百分位。

  • 断言:

    • 调用者必须已提出比率。

    • 必须已对所有参与者完成统计。

    • 该比率不得已被验证。

    • 如果没有任何人质押 STX,比率必须等于 1.0(基线)。

    • 高于该比率的 sBTC 必须 ≤ 总 sBTC 的 5%。

    • 等于或高于该比率的 sBTC 必须 ≥ 总 sBTC 的 5%。

  • 效果:

    • 将该比率标记为已验证。

    • 记录该周期的已验证比率。

    • 将最后一次操作状态设置为“ratio-validated”。

set-max-percentage-above-ratio

更新验证的百分比阈值(仅管理员)。

  • 参数:new-max-percentage-above-ratio(无符号整数)— 默认 500 = 5%

  • 断言:

    • 调用者必须是管理员。

  • 效果:

    • 更新验证阈值。


6. 权重计算

calculate-participant-weights

使用双重质押公式计算参与者权重。无权限。

  • 参数:principals(最多 900 个主体的列表)

  • 断言:

    • 比率必须已被验证。

    • 当前周期的 Stacks 区块高度必须可用。

  • 效果:

    • 检索已验证的黄金比率 D。

    • 对 D 应用最小阈值以防止除以零 D=max(D,108)D = max(D, 10^-8).

    • 对每个参与者,使用以下公式计算权重: wi=[Bi(1+Mri)]nw_i = \cfrac{[B_i \cdot (1 + M \cdot √r_i)]}{n}

    • 将总权重累加到 total-weights-sum 中。

    • 记录每个跟踪地址的单独权重(不是按已注册地址)。

注意:

  • 共享相同跟踪地址的多个已注册地址将共享相同的权重。

  • 可在最多 900 名参与者的批次中调用。

finalize-weight-computation

最终确定权重计算阶段。无权限。

  • 断言:

    • 比率必须已被验证。

    • 权重不得已被最终确定。

    • 必须已为所有参与者计算权重。

  • 效果:

    • 将权重标记为已计算。

    • 将最后一次操作状态设置为“weights-finalized”。

    • 启用奖励分发阶段。


7. 奖励分发

set-is-distribution-enabled

通过确定可用奖励池准备合约进行奖励分发。无权限。

  • 断言:

    • 合约必须处于激活状态。

    • 不得已已启用分发。

    • 权重必须已计算。

  • 效果:

    • 读取合约的 sBTC 余额。

    • 计算要分发的奖励:min(池余额, 基于 APR 的上限)。

    • 上限为: (CPR×totalweightssum)/(M+1)(CPR × total-weights-sum) / (M + 1)

    • 将奖励标记为可分发状态。

    • 将最后一次操作状态设置为“set-can-distribute”。

distribute-rewards

根据已计算的权重向参与者分发奖励。无权限。

  • 参数:principals(最多 900 个主体的列表)

  • 断言:

    • 必须已启用分发。

  • 效果:

    • 计算每个参与者的奖励: (权重 / 总权重) × 总奖励

    • 将 sBTC 奖励转移到奖励地址。

    • 将参与者标记为已奖励。

    • 汇总每个奖励地址的奖励金额。

注意:

  • 可在最多 900 名参与者的批次中调用。

  • 共享相同奖励地址的多个已注册地址将汇总奖励,并且每个跟踪地址只触发一次转账。

finalize-reward-distribution

将当前周期的奖励分发标记为已最终确定。无权限。

  • 断言:

    • 合约必须处于激活状态。

    • 所有参与者必须已获得奖励。

    • 必须已启用分发。

    • 不得已已被最终确定。

  • 效果:

    • 记录最终确定的区块高度。

    • 将最后一次操作状态设置为“finalized”。

    • 启用周期推进。

    • 触发外部 DeFi 协议分发其内部奖励(它们监控此最终确定事件)。


8. 管理控制

  • update-admin

  • update-min-sbtc-hold-required-for-enrollment

  • update-snapshot-length

  • update-snapshots-per-cycle

  • update-cycle-data

  • update-bitcoin-blocks-per-year

  • update-APR

  • update-yield-boost-multiplier

  • set-liquid-stacking

  • emergency-withdraw-sbtc

(上述每项都有参数、在适用时仅限管理员的断言,以及原始规范中描述的效果。值得注意的限制包括 APR 边界和倍数边界。)


9. 黑名单管理

  • add-blacklisted

  • add-blacklisted-batch

  • remove-blacklisted

  • remove-blacklisted-batch

(仅管理员操作以管理黑名单;将已注册地址加入黑名单会自动将其选择退出。)


10. DeFi 白名单管理

whitelist-defi-tracking

将 DeFi 跟踪地址添加到白名单(自动给予最大权重提升)。

  • 参数:defi-rewards-contract(主体)

  • 断言:

    • 调用者必须是管理员。

    • 地址不得已在白名单中。

  • 效果:

    • 将跟踪地址添加到白名单。

    • 白名单地址在权重计算中获得最大提升(ri = 1.0)。

    • 在快照期间,白名单地址的 STX 质押记录为 0(它们无需质押 STX 即可获得最大提升)。

remove-whitelisted-defi-tracking

从白名单中移除 DeFi 跟踪地址(仅管理员)。

  • 参数:defi-rewards-contract(主体)

  • 断言:

    • 调用者必须是管理员。

    • 地址必须在白名单中。

  • 效果:

    • 将跟踪地址从白名单中移除。

remove-whitelisted-defi-tracking-batch

批量从白名单中移除 DeFi 跟踪地址(仅管理员)。

  • 参数:defi-rewards-contract(最多 200 个主体的列表)

  • 断言:

    • 调用者必须是管理员。

  • 效果:

    • 从白名单中移除多个跟踪地址。


私有函数

  • update-snapshot-for-new-cycle:重置快照计数器并设置初始快照区块高度。

  • reset-state-for-cycle:应用下一周期配置,重置标志和总额,记录周期数据,更新参与者计数。

  • capture-participant-balances:在快照高度读取 sBTC 和已质押的 STX,更新持有量并汇总总额。

  • calculate-participant-weight:使用双重质押公式按跟踪地址计算权重(整数运算细节见原始规范)。

  • tally-user-ratio:根据提议比率对用户的比率进行分类并累加 sBTC 总额。

  • distribute-reward-user:按跟踪地址转移奖励并更新已奖励状态。

  • remove-participant:删除参与者并递减计数。

  • enroll-defi-one / change-addresses-defi-one:批量操作的辅助函数。

  • is-blacklisted:检查是否在黑名单中。

(私有函数实现所述效果和整数缩放注意事项;有关数学/缩放行为,请参阅上文函数详细信息。)


只读函数

周期信息

  • get-current-cycle-id

  • cycle-data

  • get-cycle-current-state

  • current-overview-data

  • get-yield-cycle-data

  • nr-cycles-year

  • cycle-percentage-rate

快照信息

  • snapshot-data

  • get-stacks-block-height-for-cycle-snapshot

  • get-bitcoin-block-height-for-cycle-snapshot

奖励信息

  • get-reward-distribution-status

  • is-distribution-ready

  • reward-amount-for-cycle-and-address

  • reward-amount-for-cycle-and-reward-address

  • is-distribution-finalized-for-current-cycle

  • get-distribution-finalized-at-height

比率与权重信息

  • get-ratio-data

  • get-weight-computation-status

  • get-participant-weight

参与者信息

  • is-enrolled-in-next-cycle

  • is-enrolled-this-cycle

  • get-is-blacklisted

  • get-is-blacklisted-list

  • get-is-whitelisted-defi

  • get-latest-reward-address

  • get-participant-cycle-info

状态与配置

  • get-last-operation-state

  • get-admin

  • get-is-contract-active

  • get-current-bitcoin-block-height

  • get-minimum-enrollment-amount

  • get-next-action-bitcoin-height

  • get-contract-sbtc-balance

  • get-apr-data

STX 质押查询

  • get-amount-stx-stacked

  • get-amount-stx-stacked-at-block-height

  • get-amount-stacked-at-block-height

  • get-amount-stacked-now

最后更新于

这有帮助吗?