{"content":{"title":"现代稳定币 - Liquity V2 是如何构建的","body":"![image.png](https://img.learnblockchain.cn/attachments/2025/03/m1ix3GYu67cd883c1196c.png)\r\n\r\n## 介绍\r\nLiquity V2是一个算法稳定币协议，建立在Liquity V1协议的基础之上，允许用户使用ETH作为抵押品铸造LUSD稳定币。其定义特征包括无利息借款和低抵押比率。\r\n\r\nLiquity V2通过引入新稳定币BOLD来增强LUSD的能力，为用户提供了更强的功能。这些功能包括对新的抵押类型的支持，例如Liquid Staking Tokens (LSTs)，集成的BOLD质押，用户自定义的利率，减少治理的作用，以及一些其他创新，改善协议的灵活性和去中心化。如我们之前文章的[一篇](https://learnblockchain.cn/article/12490)中提到的，现代协议旨在创建更少治理、更无许可的DeFi市场，以促进更大的去中心化。Liquity V2通过最小化对中心化资产（如USDC/USDT）的依赖、减少治理、采用不可变合约，以及实施独特的稳定机制来追求这些目标。\r\n\r\n这些机制值得DeFi开发者理解。为了开始我们对算法稳定币协议的回顾，我们选择Liquity V2作为一个优秀示例。让我们探讨Liquity V2是如何工作的。一起深入了解吧！\r\n\r\n## 高层次评审\r\n\r\nBOLD的基本生命周期与其他稳定币相似：\r\n\r\n1. 借款人 \\- 借款人使用ETH/LST代币作为抵押品借出贷款，铸造BOLD稳定币，并看到其债务不断增加。他们可以偿还债务或由赎回者/清算人偿还。\r\n2. 质押者 – 质押者锁定BOLD代币，并从借款人的不断增加的债务中赚取收益。\r\n3. 赎回者/清算人 – 赎回者和清算人监控借款人的头寸，并通过赎回和清算两种机制以固定价格兑换BOLD代币换取抵押品。\r\n\r\nLiquity V2的锚定稳定机制的核心概念基于用户自行设定的可变借款利率。利率较低的头寸为BOLD质押者产生较少的收益，而如果此类“低利率”头寸较多，则对BOLD（及其价格）的需求 decreases。当价格跌破$1时，将触发“赎回”。这些赎回使BOLD能够以固定价格$1兑换为ETH/LST，提供了一个盈利机会，当价格低于$1时。赎回必须从利率最低的头寸开始，将其从市场上移除：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_ea9803d85f224.png)\r\n\r\n消除这些“低利率”头寸增加了BOLD质押者的收益，这反过来又提高了对BOLD（及其市场价格）的需求。随着BOLD价格的上涨，赎回相关的风险减少，让用户能够以更低的利率借出BOLD。这创造了一个自我强化的循环：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_698c52835b747.png)\r\n\r\n稳定过程在[白皮书](https://liquity.gitbook.io/v2-whitepaper)中有更详细的解释。\r\n\r\nLiquity V2还结合了许多其他机制，例如用于不同操作的孤立池（例如，处理多余金额、煤气补偿和代币再分配）、利率调整频率的限制、“冷却”赎回费用、响应预言机或抵押比率问题的自动关闭抵押分支，以及其他创新特性。\r\n\r\n让我们看看这些是如何构建的。\r\n\r\n## 项目结构\r\n\r\n我们将分析[BOLD代码库](https://github.com/liquity/bold/)，它包含了BOLD稳定币的完整代码（和一个有用的[概述](https://github.com/liquity/bold/tree/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e?tab=readme-ov-file#liquity-v2-overview)）：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_88cfe43f1b8b5.jpg)\r\n\r\nBOLD是一个多抵押协议，每种抵押资产（在部署时硬编码）都有自己专用的合约集。这些合约处理所有与借款相关的逻辑，包括抵押债务头寸（称为Troves）的创建和关闭，以及其分组（批次）、清算和赎回流程、费用管理，以及在不同池之间累积“中间”余额。\r\n\r\n多个抵押分支的组合通过主[CollateralRegistry](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L14)合约来管理，其主要功能是在所有分支间处理赎回过程（清算则在各自的分支内独立进行）。\r\n\r\n每个抵押分支使用自己的抵押资产（ETH或LST）进行操作。它包含TrooveManager合约，负责管理与Troves（包括清算）相关的操作，按排序列表组织。BorrowerOperations合约提供访问给定抵押分支内所有外部函数的接口。\r\n\r\n用户通过存入抵押品和铸造BOLD稳定币来创建、关闭和调整他们的抵押债务头寸（Troves）。他们可以选择自己的借款利率，注意到较低的利率会导致更高的Troves被赎回的风险。已累积的借款利息会复利，并以75/25的比例分配给BOLD质押者和InterestRouter，后者为外部DEX上的BOLD流动性提供者提供奖励。\r\n\r\n如果一个Troves的利率较低，它就会受到赎回约束。如果一个Troves的抵押不足，它就会被清算。这导致一个挑战：清算人需要获取BOLD代币来偿还用户的债务。这种对BOLD代币的需求推高其价格，使得抵押品变得更便宜，从而导致更多的抵押不足头寸。为了解决这个问题，在清算过程中，Liquity V2首先使用质押的BOLD代币。这些代币在市场上并不存在，因此与它们有关的操作不会影响BOLD代币的市场价格。质押的BOLD代币被销毁，而抵押品则添加到“质押”池（StabilityPool）中。因此，BOLD质押者最终会拥有较少的BOLD代币，但应收的抵押品会更多。只有当StabilityPool完全耗尽时，清算人才会转向市场上现有的BOLD代币。这一多步骤清算流程是Liquity V2的一个独特特性。\r\n\r\n这种赎回、清算和质押的结构要求Liquity V2拥有“抵押分支”合约包，其中包括多个用于不同目的的池：质押、代币再分配、抵押 surplus和平米清算人的Gas补偿。我们将在后面详细讨论这些内容。\r\n\r\n现在，让我们继续我们的技术回顾，考察BoldToken合约。\r\n\r\n## BOLD Token\r\n\r\nBOLD代币在[BoldToken.sol](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BoldToken.sol#L19)中实现，并遵循标准的ERC20接口，增加了permit功能。它支持所有标准的ERC20功能，并提供额外功能，包括：\r\n\r\n- `mint()` [函数](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BoldToken.sol#L68-L71)，只能由borrowerOperations或ActivePool合约调用。\r\n- `burn()` [函数](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BoldToken.sol#L73-L76)，只可由collateralRegistry、borrowerOperations、troveManager或stabilityPool合约调用。\r\n- `sendToPool()/returnFromPool()` [函数](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BoldToken.sol#L78-L86)，允许将BOLD代币发送到/从StabilityPool中检索。这只能通过Stability Pool合约调用。\r\n\r\nBOLD代币的实现有意保持与ERC20相关的功能简单，以确保该代币对于日常使用仍然高效和便捷。\r\n\r\n## 抵押分支（branch）\r\n\r\n抵押分支由一组处理单一类型抵押的合约组成。每个抵押分支包括以下组件：\r\n\r\n**•** TroveManager：负责管理用户头寸（Troves）和Troves组（Batches）的合约，同时跟踪每个用户的抵押金额、债务、质押BOLD代币和利率。TM还监督赎回和清算。\r\n\r\n**•** BorrowerOperations：提供管理Troves和Batches的功能的合约，例如创建、更新或删除它们，添加抵押品，提取债务，修改利率，将其分组为Batches，及其他操作。\r\n\r\n**•** ActivePool：存储与Troves和Batches相关的抵押和BOLD代币余额的合约。\r\n\r\n**•** StabilityPool：一个重要的合约，用于存储用户的质押，持有BOLD代币以及从清算中获得的抵押品，并为持有者积累利息。\r\n\r\n**•** 其他合约：\r\n\r\n**◦** DefaultPool：一个在清算过程中持有BOLD代币和抵押品“中间”余额的合约。它临时存储待分配的BOLD和抵押品的“待处理”金额。\r\n\r\n**◦** CollSurplusPool：一个持有清算产生的多余抵押的合约。如果清算后还留有任何多余，Troves的拥有者可以追回该多余部分。\r\n\r\n**◦** GasPool：一个持有借款人贡献的WETH余额的合约，以覆盖其Troves清算的潜在Gas费用。\r\n\r\n首先，我们将审查TroveManager.sol合约，负责管理用户的位置并促进赎回和清算，该协议的主要稳定机制。\r\n\r\n## TroveManager\r\n\r\n由[TroveManager](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L17)合约管理的用户位置被表示为NFT（在TroveNFT.sol中的[示例](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveNFT.sol#L36-L45)）。这些位置适用严格、不可变的[抵押比率限制](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L32-L39)，确保当抵押比率达到指定阈值时，禁止借贷或提取抵押品。\r\n\r\n核心的Trove [结构](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L49-L60)包含抵押、债务和质押的值，分别表示存入的抵押品、借出的债务和在StabilityPool中的质押。涉及Liquity V2中“抵押 <-> BOLD”的操作可以同时影响所有三个值。\r\n\r\nTrove结构还包括其他重要属性，例如最后更新的时间（用于计算应计利息）、annualInterestRate（用户选择）和batchDebtShares — 代表该Trove在名为Batch的更大实体中的份额。一个[Batch](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L64-L76)将多个共享同一利率的Troves分组。Batch为希望不单独管理其利率的Trove所有者提供益处，使他们能够将这一责任委托给批次管理者。批次管理者是一个可信地址，可以为Batch内所有Troves调整利率，并获得批次管理费。在[获取最新的Batch数据的函数](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L950)中可以找到Batch使用实例。这个函数从一个单独的Trove中提取数据，而是使用trove.batchDebtShares来[计算](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L965-L971) Trove的绝对债务及相关的批次管理费用。\r\n\r\n需要提及的另一个重要地方是关于抵押分支关闭的处理（将在稍后讨论）在Trove的利率计算中。如果一个分支被关闭，协议需要[使用](https://github.com/liquity/bold/blob/f0f9a3b4a013893a6503cbb06b6e8bb6c703573f/contracts/src/TroveManager.sol#L1128-L1140)适用于Trove利息积累的正确利息区间。\r\n\r\nTroveManager的主要函数是redeemCollateral()和_liquidate()，但在讨论与借款操作和抵押池有关的其他合约之前，了解这些是非常实际的。\r\n\r\n### “僵尸” Troves\r\n\r\n在Liquity V2中，债务低于MIN_DEBT（[2000](https://github.com/liquity/bold/blob/80ef22e3aceda00b3227b342acaae56e98b172d1/contracts/src/Dependencies/Constants.sol#L24C18-L24C26) BOLD）的Troves成为“僵尸”Troves。因此，最低借款额度设置为MIN_DEBT。\r\n\r\n“僵尸”Troves主要在赎回后产生，它们不会像清算那样“关闭”Troves。从借贷的角度来看，赎回充当了针对“健康”头寸的“清算”。在赎回之后保留Troves确保赎回不会降低TCR。此外，活跃的“小”Troves存在潜在的恶意攻击，即攻击者用微小的债务堵塞排序列表。为了解决这个问题，赎回低于MIN_DEBT的Troves将被标记为无法赎回，移出排序列表，只有当所有者将其债务增至超过MIN_DEBT时，才能再次变得可赎回。有关这些不可赎回Troves的原因在[这里](https://github.com/liquity/bold/tree/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e?tab=readme-ov-file#unredeemable-troves)有详细说明。\r\n\r\n## BorrowerOperations\r\n\r\n接下来要审查的合约是[BorrowerOperations](https://github.com/liquity/bold/blob/f0f9a3b4a013893a6503cbb06b6e8bb6c703573f/contracts/src/BorrowerOperations.sol#L18)，其主要功能涉及Troves和Batches的创建、修改和关闭。Liquity V2提供了广泛的Troves操作功能；在这里我们将关注最重要的方面。\r\n\r\n首先，让我们检查安全关闭机制，控制变量为不可变的[阈值](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L33-L42)：CCR、SCR和MCR，分别代表Critical、Shutdown和Minimal抵押比率：\r\n\r\n- 到达SCR（关闭）抵押比率将使BorrowerOperations切换到关闭模式，限制所有借款操作并仅允许关闭Troves\r\n- 达到CCR（关键）抵押比率时，会禁用部分借款操作（例如，开启、调整或关闭Troves），但仍允许改变利率、偿还债务以及任何改善抵押比率的调整\r\n- MCR（最低）抵押比率用于限制单个Troves（在开启/调整Troves操作中）。\r\n\r\n每次Troves的调整都涉及强制性的[检查](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L1350-L1377)，以确保更改保持单个抵押率ICR > MCR和总分支抵押比率TCR > CCR。\r\n\r\n通过“独立”的[openTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L194)函数或[openTroveAndJoinInterestBatchManager()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L235)来创建Troves，将新Troves添加到Batch。这两者最终调用内部的[_openTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L290-L304)函数。让我们探讨一下这个机制。\r\n\r\n首先，我们需要解释什么是“加权债务”。这些数值经常在Liquity V2中出现（例如，[这里](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L324-L325)）并且是通过应用年利率来评估的债务（例：100$，利率10%=110$，与101$，利率5%=106.05$）。这个值在决定费用和估算Troves“价值”时起着重要作用。它会在债务更改时更新（例如，在Troves创建、调整、利率更新、赎回和清算等过程中），用于计算整个抵押分支的加权平均利率（例如，通过[getNewApproxAvgInterestRateFromTroveChange()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L126)函数）。\r\n\r\n另外一个需要描述的重要组成部分是前端[费用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L327-L328)，线性依赖于池的总平均利率。池中的更高利率对应于更高的前端费用。\r\n\r\n让我们继续创建一个Troves。后续的[检查](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L329)确保这个费用不会超过用户准备支付的金额（滑点保护）。接下来，检查[MIN_DEBT](如上所述)。\r\n\r\n后续步骤包括对“加权”债务的[计算](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L335-L342)和支付批次管理费（如果需要），检查[最低抵押比率](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L344-L346)，和对整个抵押分支的新总抵押比率的[计算](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L348-L349)（这[包含](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L1529-L1544)新债务、抵押和费用进总储备）。\r\n\r\n接下来是“添加”和“删除”管理者的委托。Liquity V2允许第三方Troves管理，委托账户可以执行镜像操作。addManager可以添加抵押品和偿还债务（提高抵押比率），而removeManager可以提取抵押品和借出债务（降低抵押比率）。这个特性便利了Liquity V2与外部头寸管理系统的整合。\r\n\r\n另一个重要步骤是对广泛使用的[mintAggInterestAndAccountForTroveChange()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L208-L215)函数的[调用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L357C25-L357C64)，更新ActivePool中的总债务相关值（包括所有Troves债务和抵押余额的直接和“加权”总和），以及前端费用。\r\n\r\n最后一系列交互遵循检查-效应-交互模式，启用从用户那里[提取抵押品](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L360)放入ActivePool、[铸造](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L363)用户的BOLD代币，以及[转账](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L364)一些WETH到GasPool，以覆盖清算的Gas费用。\r\n\r\n完成内部的Troves开启工作流程后，外部函数可以铸造TrovesNFT，不论是“独立的”或是“加入批量”的Troves。独立Troves铸造的示例在[这里](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L1207-L1215)。对于通过[openTroveAndJoinInterestBatchManager()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L235)加入批量的Troves，Troves 也会[加入](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L279-L285)一个Batch。由于Troves按利率排列，Batch只是使用排序列表中的“头”和“尾”指针（如[insertIntoBatch()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/SortedTroves.sol#L209-L236)函数演示于SortedList.sol中）。\r\n\r\n下一个重要函数是[_adjustTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L548-L553)，其工作原理类似于_openTrove，但可在两个方向上调整抵押和债务，并在现有Troves上处理不同的操作。该函数在addColl()、withdrawColl()和repayBold()函数中使用。\r\n\r\n函数_adjustTrove()以关键的[检查](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L560-L561)开始验证预言机的活跃性和抵押分支的TCR阈值。随后，它包括对Troves管理者的访问控制[检查](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L570-L576)、调整中的[限制检查](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L580-L594)以及[最终的](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L596-L597)债务和抵押的更新。对于在Batch中的Troves需要更复杂的[更新](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L603-L615)。\r\n\r\n过程结束与_openTrove相似，并且[结束](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L666-L667)，通过铸造利息（在每次“触碰”Troves时执行）以及铸造/销毁/转移适当数量的BOLD和抵押代币完成。\r\n\r\n一个独特的函数是[adjustTroveInterestRate()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L498-L498)，用于调整Troves的利率。由于需要[重新计算](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L523)“加权”债务、[收取](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L527-L532)因债务变化的前端费用，并[重新插入](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L539)Troves进排序列表，这在Liquity V2中并不简单。该变更仅适用于独立Troves[而且](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L510) 。\r\n\r\n此外，中间的函数[applyPendingDebt()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L739C14-L739C30)是[应用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L763-L764)利率到Troves债务的。在某些情况下，此操作可以增加“僵尸”Troves的债务，将它们[放回](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L781-L787)排序列表并移除其“僵尸”状态。\r\n\r\n在[closeTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L670)中关闭一个Troves相对简单，这得益于对先前函数的理解。该操作为[结束](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L728-L734)销毁BOLD代币、提取所有剩余抵押并以WETH返回Gas补偿。\r\n\r\nBorrowerOperations中的其他函数处理Troves管理者配置，允许他们管理债务、抵押、利率变化或成为Batch管理者。Liquity V2最小化治理功能，并且BorrowerOperations中没有治理相关的逻辑。\r\n\r\n## ActivePool\r\n\r\n[ActivePool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L16-L22)合约负责持有BOLD和抵押代币的余额，这些余额由Troves管理。从另一种角度看，AP可以被视为一个大型“汇聚”Troves，整合所有Troves的所有抵押和BOLD余额。\r\n\r\n如前所述，ActivePool处理接收和发送抵押和BOLD代币。特别是，关键功能涉及移动抵押和BOLD代币。[sendColl()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L162-L168)函数将铸造外部，例如在[redeemCollateral](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L809-L810)中（将抵押品发送给赎回者）或在清算期间将[多余抵押](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L435)发送到CollSurplusPool。相反，通过[receiveColl()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L184-L191)函数接收抵押。\r\n\r\n## Stability Pool\r\n\r\n[StabilityPool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L128)合约是稳定机制的重要组成部分。这是BOLD持有者质押其BOLD代币以从利率和清算中获得收益的池。如前所述，在清算过程中，首先会燃烧BOLD代币。\r\n\r\n该池发挥双重作用：实现了BOLD质押功能，同时允许用户索取因清算而没收的抵押品。当一个Troves被清算时，其债务实际上被移除，等量的BOLD在Stability Pool中被销毁。同时，没收的抵押品转移到Stability Pool，必须在存款者之间进行再分配。该过程要求合理地降低所有存款者的BOLD余额并增加他们的抵押余额。同样，池中产生的利息也必须在BOLD持有者之间进行分配。\r\n\r\n在DeFi背景下，迭代存款是低效的，因此Liquity V2采用了其[论文](https://github.com/liquity/dev/blob/58a5419086deee09e60a37a3692a2ba3c14293fe/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf)中说明的分配方案。关键思想是，每次 _i_-次清算之后（当BOLD的totalSupply减少，并且Stability Pool中的totalSupply抵押增加时），个别存款的价值可以根据其先前价值和清算的BOLD比例进行更新（amountLiquidated/totalSupply）。简单地说，如果BOLD的totalSupply减少了5%，那么个别的BOLD存款也应该以同样的比例下降。通过从初始的“零时间”存款开始逐次应用这一减少，最终形成了一个迭代计算方案：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_91755eb704f9f.jpg)\r\n\r\n其中 _d₀_ 是在 _i=0_ 时的初始存款， _Qᵢ_ 是第 _i_-次清算期间清算的BOLD数量， _Dᵢ_ 表示第 _i_-次清算时BOLD的totalSupply.\r\n\r\n因此，在每次随后的清算之后，我们可以“复利”比例减少（用红色标记），只保留每个存款的 _d₀_ 值。同样通过保持累积的减少比例（用橙色标记），我们能够通过一次简单的乘法来计算第 _n_-次清算时存款的“当前”价值。\r\n\r\n类似的逻辑应用于没收的清算数额（此处省略详情，但已在论文中解释）。在第 _t_-次清算中获取抵押的最终公式为：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_9f7abf3ba9798.png)\r\n\r\n其中 _d_ **_ₜ_** 为第 _t_-次清算的存款， _S_ **_ₙ_** 和 _S_ **_ₜ_** 为清算金额快照（每个存款的存储和更新），而 _P_ **_ₜ_** 是BOLD“总供应累积差”的累积乘积（如前所述）。\r\n\r\n同样的方法用于计算BOLD产量收益，这会按比例增加质押者的BOLD存款（利用另一个 _B_ 分类在快照中）。\r\n\r\n因此，该系统确保每次清算或收益事件仅更新很少（三个）累加器在StabilityPool的快照中。这些累加器在存款者的余额“触碰”时用于重新计算后续“锚”值。该方案运作以O(1)的复杂性，确保清算和存款相关操作的持续Gas费用。\r\n\r\n计算乘法时，使用值在\\[0，1\\]范围内（如 _1−Q_ **_ᵢ_** _₊₁/D_ **_ᵢ_**）在EVM中存在缺陷。需要对累积乘积进行缩放以保持精度。此外，当池为空时会出现极端情况，导致BOLD的totalSupply为零。这种情况需要通过引入“纪元”进行处理，纪元每次在池完全耗尽时递增。这些操作的累加器存储在 [Snapshots](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L155-L161) 结构中，而“每个存款”的值则维护在 [三个](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L163-L165) 映射中。\r\n\r\n函数 [getDepositorCollGain()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L602-L632) 实现了上述公式，用于计算特定存款人从清算中获得的扣押抵押品收益。它 [使用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L623-L626) Snapshots 的 “S” 部分。如可以观察到，这些计算是直接且节省 Gas 的。第二个函数 [getDepositorYieldGain()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L634-L657) 的操作类似，但 [使用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L648-L651) Snapshots 的 \"B\" 部分。\r\n\r\nprovideToSP() 函数是针对 StabilityPool 的特定存款人的 BOLD “存款” 操作。它 [收集](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L245) 来自 ActivePool 的累计利息，[调用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L249-L250) 上述两个函数以确定 BOLD 收益和扣押抵押品收益，并 [计算](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L252-L255) 应发给存款人的 BOLD 和抵押品金额（如适用）。然后，在 \\_updateDepositAndSnapshots() 函数中，它 [更新](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L781-L794) 存款人的快照累加器，并 [转移](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L269-L273) “in” 或 “out” 代币（BOLD 和抵押品），同时更新池中 BOLD 和抵押品的总金额。“withdraw” 函数 [withdrawFromSP()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/StabilityPool.sol#L301) 遵循相同的逻辑，收集来自 ActivePool 的利息，更新存款人的快照，并将结果金额转移到存款人。\r\n\r\n我们无法审查 StabilityPool 数学的每个方面，涵盖潜在的边缘情况，但这些计算的结果是设计简洁的功能来管理质押者的 BOLD 和抵押品收益。\r\n\r\n## DefaultPool 和 CollSurplusPool\r\n\r\n这两个池充当 “中介” 组件。它们不是 BOLD 稳定机制的核心部分，但处理在赎回和清算中产生的 BOLD 和抵押品金额。这些金额必须重新分配（DefaultPool）或被暂时保留（CollSurplusPool）以供以后取回。\r\n\r\n这些池的实现很直接。[DefaultPool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/DefaultPool.sol#L18) [ool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/DefaultPool.sol#L18) 只是简单地 [追踪](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/DefaultPool.sol#L87-L97) 其 BOLD 债务，持有抵押品，并 [根据需要转移](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/DefaultPool.sol#L65-L73) 给 ActivePool。\r\n\r\n[CollSurplusPool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollSurplusPool.sol#L10) 持有抵押品代币的 [余额](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollSurplusPool.sol#L22)，通过将来自清算的过剩存入 Trove 所有者的余额中来 [增加](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollSurplusPool.sol#L53-L61) 它，并允许所有者 [在稍后认领](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollSurplusPool.sol#L63-L75) 这些资金。\r\n\r\n## 风险管理\r\n\r\n现在，在审查了 “基础” 合约（TroveManager、BorrowerOperations、ActivePool、StabilityPool）以及额外的 DefaultPool 和 CollSurplusPool 后，我们可以研究主要的稳定机制：赎回和清算。\r\n\r\n## 赎回\r\n\r\n赎回是通过 [redeemCollateral()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L714-L733) 函数执行的。该函数代表了在每个 TroveManager 内的 CollateralRegistry 中的 redeemCollateral() 循环中的单一步骤，其中该过程 [跨越](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L144-L156) 多个抵押分支进行执行。\r\n\r\n在特定的抵押分支中，此函数遍历多个 Troves，燃烧 BOLD 债务并赎回抵押品，旨在满足赎回者指定的 [remainingBold](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L742) 数量。该遍历使用按利率排序的 Troves 列表，从利率最低的开始，如白皮书中所述。\r\n\r\n处理的第一个 Trove 是排在排序列表的 [最后](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L749-L751)。选择排序列表中的最后一个 Trove 足以识别出利率最低的 Trove。\r\n\r\n接下来，将在排序的 Troves 上 [启动](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L755-L756) 循环，该循环受到 \\_maxIterations 限制，这是由赎回者定义的参数，旨在防止 “out-of-gas” 错误。在每次迭代中，将使用赎回者提供的 \\_price 计算 Trove 的 [ICR](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L766-L771)（个人抵押比例），确保 Trove 的 ICR 不低于 100%。ICR 的计算简单明了，已在函数 [\\_computeCR()](https://github.com/liquity/bold/blob/9ebcc55a2395b8ff1e8c0d33f8ec7502efbdbf0e/contracts/src/Dependencies/LiquityMath.sol#L78-L89) 中实现。\r\n\r\n如果 Trove 属于一个包含其他 Troves 的批次，则会 [更新](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L773-L781) 批次的利率（仅更新一次，因为批次内的所有 Troves 共享同一利率）。最后，从 Trove 中 [赎回](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L783) 抵押品，通过调用 [\\_redeemCollateralFromTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L652)。在此函数内部，计算出 [赎回费用](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L661-L669)（以抵押品代币计），并更新 Trove 的抵押品和债务金额。如果该 Trove 属于一个批次，则该批次也会被更新。如果 Trove 的最终债务变得微不足道，则该 Trove 将被 [标记](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L674-L691) 为 “僵尸”，并随后从该批次中删除。\r\n\r\n在每次循环迭代结束时，赎回的抵押品总金额和 BOLD 代币移除的总金额会 [更新](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L785-L793)，同时累积赎回过程中的前期和当前债务。\r\n\r\n在足够的 Troves 被赎回后，累计的利息费用会 [铸造](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L807) 到 [Stability Pool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L259-L260)（75%），使 BOLD 质押者受益，并铸造到 [Interest Router](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L256)（25%），以激励外部 DEX 上的 BOLD 池。然后，批次管理费用 [支付](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/ActivePool.sol#L222) 给受影响的批次的管理者。\r\n\r\n最后一步是将 [赎回的抵押品发送](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L810) 给赎回者。\r\n\r\n## 清算\r\n\r\n第二个核心稳定机制是清算。我们来审查内部的 [\\_liquidate()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L224) 函数，它是所有清算的基础。\r\n\r\n首先，我们 [处理](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L240) Trove 中任何未分配的债务和抵押品收益。然后，向清算人提供 Gas [补偿](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L242-L243)。该补偿 [等于](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L326-L328) 正在清算的抵押品的 1/200，最高上限为 2 ETH（常量在这里 [定义](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/Dependencies/Constants.sol#L20-L21)）。\r\n\r\n在 Liquity V2 中，清算优先使用来自 StabilityPool 的 BOLD 余额（在 SP 中燃烧 BOLD，同时将扣押的抵押品转移到其中）。如果 SP 的 BOLD 余额不足，则将使用清算人的 BOLD 代币，抵押品和 BOLD 在 Troves 之间分配。Liquidated Trove 中的任何剩余抵押品被转移给 CollSurplusPool，可以被该 Trove 的所有者认领。\r\n\r\n清算过程首先 [确定](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L245-L251) StabilityPool 和再分配的比例。这些金额是通过 [首先](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L360-L365) 评估 “StabilityPool” 部分，然后评估 “redistribution” [部分](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L367-L379) 来计算（在分配机制回顾中已讨论过）。\r\n\r\n接下来的步骤是使用 [\\_closeTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L258-L265) 函数 [关闭](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L1459) Trove。该 Trove 将从排序列表中 [删除](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L1476-L1499)，并对批次或“僵尸” Troves 进行额外处理，同时更新 totalStakes 值。该 Trove 还会从主 Troves\\[\\] 映射中删除，相关的 TroveNFT 也会被移除。此后，将 [支付](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L267-L277) 批次管理费用（如适用）。\r\n\r\n剩余的抵押品随后被 [发送](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L282-L285) 到 CollSurplusPool，该池积累了多余的抵押品，并使 Trove 所有者能够认领。\r\n\r\n最后，清算过程通过 [移除](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L287-L288) \\_troveId 从与 Trove 管理相关的各种映射中完成。\r\n\r\n## 抵押登记\r\n\r\n现在，我们可以结合抵押分支并审查 [CollateralRegistry](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L14) 合约，该合约将协议的所有抵押分支汇聚在一起。它保存多个（最多 10 个）不变的抵押资产地址及其相应的 [troveManager](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L29-L38) 的配置。\r\n\r\n从多个抵押分支赎回抵押品是 collateralRegistry 合约的主要功能（清算在抵押分支中独立管理）。赎回是在 [redeemCollateral()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L92) 函数中执行的，该函数 [遍历](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L116-L126) 多个 troveManagers，尝试赎回抵押资产。该函数还燃烧相应数量的 BOLD 代币，并更新 baseFee。每个抵押分支分配的赎回金额与该分支的 “weight” 成正比，其中 “weight” 是其 [在整个协议总债务中的比例](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L147)。例如，如果三个分支占总债务的 10%、20% 和 70%，则总可赎回的金额将在各抵押分支之间按 10%、20% 和 70% 的比例分配。此 “赎回路由” 在 [此处](https://github.com/liquity/bold/tree/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e?tab=readme-ov-file#redemption-routing) 描述。\r\n\r\n该合约中的一个重要值是 [baseFee](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L42)，它用于计算赎回发生时适用的赎回费用。该费用在每次进行新的赎回时都会 [变化](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L196-L216)，并取决于被移除抵押品的比例（在下文 “费用” 部分描述）。\r\n\r\n## 费用\r\n\r\n费用在 DeFi 协议中的作用不仅是提供激励，还有助于防止某些危险场景的发生。Liquity V2 使用不同类型的费用。让我们讨论一下它们。\r\n\r\n第一种费用是“前期费用”。该费用以 BOLD 代币形式收取，基于债务进行计算。它适用于每一个增加总债务的操作，包括 [\\_openTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L328)， [\\_adjustTrove()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L626) 和 [adjustTroveInterestRate()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L531)。最后一个操作也需支付前期费用，因为利率变动会改变“加权债务”，而这在许多计算中都会用到。此外，在最后的情况下，前期费用有一段“宽限”期，即 7 [天](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L527-L532)，且只有在此期间内作出变更时，费用才会生效。这一机制保护协议免受“赎回规避”的风险，即借款人在发现赎回风险时可能临时改变利率，或关闭再重新开启其 Trove。\r\n\r\n另一种费用是由特定批次的管理者收取的批次管理费（该费用的大小由管理者自行设定）。它的运作方式类似于 BOLD 利息，根据一个批次中 Troves 的债务计算年利率。我们将不再详细探讨这类费用，因为它相对简单。\r\n\r\n下一项费用是赎回费用，其具有趣味性的放宽方案如下所示：\r\n\r\n![](https://img.learnblockchain.cn/2025/03/09/upload_0d25798413bfd.png)\r\n\r\n橙色线表示 baseFee，用于计算赎回过程中作为费用收取的抵押品金额。每个蓝色条表示一次赎回，它的高度表示赎回的金额。当发生赎回时，该费用会“被推高”，然后再“冷却”直到下次赎回。这种行为在 [函数](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/CollateralRegistry.sol#L195-L216) 中实现。设计这一机制的目的是为了阻止大规模赎回和随之而来的赎回，通过施加更高的费用来抑制此种行为。此外，此费用有一个 [0.5%](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/Dependencies/Constants.sol#L33) 的底线。\r\n\r\n## 实现细节\r\n\r\n像许多其他算法稳定币一样，Liquity V2 依赖于价格预言机（由 Chainlink 提供）来确定当前抵押资产价格。这些预言机在 [PriceFeeds](https://github.com/liquity/bold/tree/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/PriceFeeds) 模块下实现。\r\n\r\nLiquity V2 一个显著的特点是使用“提示”来管理排序列表中的 Troves。所有 Troves 都组织在一个排序列表中，因此将项目插入或重新插入该列表需要多次迭代，这会消耗额外的 Gas。为优化这一过程，用户可以指示协议从被称为“提示”的特定元素开始搜索（具体示例见 [这里](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/BorrowerOperations.sol#L230)）。为了帮助用户提供提示，HintHelpers.sol 合约中还包含了一个特殊的视图函数 [getApproxHint()](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/HintHelpers.sol#L19-L31)。\r\n\r\n我们几乎忘记了 [GasPool](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/GasPool.sol#L18)，但它的作用仅仅是持有 WETH，用于补偿液化者的 Gas，在 TroveManager 中 [这里](https://github.com/liquity/bold/blob/93e53f0b50a276d69288ba9d6e9b9dd38b73ee1e/contracts/src/TroveManager.sol#L325-L328) 可以看到。\r\n\r\n## 结论\r\n\r\nLiquity V2 及其 BOLD 稳定币代表了一个有趣的项目，利用以 ETH 为支撑的资产作为抵押，避免了使用中心化的 USDT/USDC。其稳定机制基于赎回和清算。Liquity V2 稳定逻辑的聪明之处在于将 BOLD 质押、清算和赎回结合成一个单一的机制。在此，燃烧 BOLD 和收回抵押品重新分配 StabilityPool 中的资产，自动平衡用户持有的稳定币和抵押品数量。\r\n\r\nLiquity V2 的突出机制包括：\r\n\r\n**•** 用户设定的借款利率\r\n\r\n**•** 用户 Troves（抵押-债务头寸）按照利率在排序列表中组织\r\n\r\n**•** 当 BOLD 价格低于 $1 时赎回（清算以固定的 1 对 1 像素进行）\r\n\r\n**ᅠ◦** 从利率最低的 Troves 开始，逐步消除这些头寸，从而增加 BOLD 收益和需求\r\n\r\n**•** BOLD 价格高于 $1 时进行清算\r\n\r\n**ᅠ◦** 通过燃烧 BOLD 并将抵押品加入 StabilityPool 来实现，减少 BOLD 收益和需求\r\n\r\n**•** 在 StabilityPool 进行 BOLD 质押，结合借款利率和清算同时产生的收益\r\n\r\n**•** 在赎回中结合多个抵押分支，将赎回金额按 “每个分支”的债务进行分配\r\n\r\nLiquity V2 还具有多种附加功能，如将 Troves 分组为批次，委托 Troves 和批次的管理，Gas 补偿，自动保护抵押率，以及许多其他创新解决方案。\r\n\r\n这个项目无疑值得研究，作为算法稳定币的示范性实现。因此，它被包含在我们的“稳定币”系列文章中。下次再见！\r\n\r\n- MixBytes 是谁？\r\n\r\n[MixBytes](https://mixbytes.io/) 是一支专业的区块链审计和安全研究团队，专注于为 EVM 兼容和 Substrate 的项目提供全面的智能合约审计和技术咨询服务。请加入我们在 [X](https://twitter.com/MixBytes) 上，及时了解最新的行业趋势和见解。\r\n\r\n>- 原文链接： [mixbytes.io/blog/modern-...](https://mixbytes.io/blog/modern-stablecoins-how-they-re-made-liquity-v2)\r\n>- 登链社区 AI 助手，为大家转译优秀英文文章，如有翻译不通的地方，还请包涵～"},"author":{"user":"https://learnblockchain.cn/people/24680","address":null},"history":null,"timestamp":1741523157,"version":1}