深入探讨DeFi借贷清算机制及其实现原理、风险与用例_AVE:LIQ

这篇文章是三篇系列文章中的第二篇,讨论DeFi借贷协议的工作原理——它们的关键组成部分、公式和用例。在我们之前的文章中,我们回顾了DeFi的核心操作——借贷,以及不同协议如何选择实现这些操作。在这篇文章中,我们将重点介绍我们认为最令人兴奋的DeFi借贷概念之一:清算。过度抵押和坏账

你可能会从我们之前的博客文章中想起,协议用户只能对其提供给协议的抵押品的百分比进行资产借贷。这是有道理的,因为协议需要确保如果你无法偿还债务,它可以从你那里收回其资产。这种资产抵押的过程始于传统金融,例如今天,一个人可以把他们的房子或兰博基尼作为贷款偿还的抵押品。抵押依赖于抵押品价格保持其价值的前提条件——尽管房屋或兰博基尼的价格无法保证,但它们各自的价值相对不太不稳定,而比起ERC20或NFT等资产来说,更为稳定。在大多数DeFi借贷协议中,你的抵押贷款资产必须比你贷款的价值更有价值,也就是所谓的过度抵押。如果借贷协议想要保持财务稳定,只允许过度抵押的贷款是有利的。想象一下,你提供了一些资产作为抵押品,而这些资产的价值突然低于你从协议中借到的资产价值。现在,你的抵押品价值低于你欠协议的债务,你就没有还款的动力。毕竟,在偿还贷款的过程中,你将获救的抵押品现在的价值低于实际偿还贷款所需的金额。这种贷款现在已经无力偿还。每笔无力偿还的贷款对其所在的协议都是有害的。从无力偿还的贷款中产生的债务会在协议中产生不安全因素,毕竟,债务的数量是借出者无法从协议中收回的资产的数量。为了强调这些坏账有多糟糕:如果在协议上出现了类似传统金融「银行挤兑」的情况,最后一批从协议中提取他们的资产的用户将无法这样做。当然,那些有大量坏账的协议对用户的吸引力较小。清算和清算阈值

我们已经确定,当贷款抵押品价值低于借款人带利息的债务价值时,借款人的债务会对其所在的借贷协议的健康状况构成威胁。为了防止低于抵押的持仓增加,协议允许第三方偿还低于抵押的债务。通过偿还低于抵押的债务,这些被称为清算人的第三方有权以折扣的价格要求归还其被覆盖的债务人的抵押品。这个过程被称为清算。你可能会想知道:为什么协议要依赖第三方来清算不健康的持仓?毕竟,协议可以将自动清算机制编码进其代码中。发送清算交易的成本非常高。如果协议自动发送这些昂贵的交易,resultinggascosts将会增加其运营成本,从而削弱其利润。此外,自动清算系统的设计非常困难。协议不仅必须考虑是否应自动清算一个持仓,而且必须考虑何时这样做,并以反映市场波动率的速率进行清算。通过激励专门的第三方来清算这些持仓,这个过程要简单得多。清算本质上不是有利可图的——对于这个过程来说,债务人的抵押品必须价值高于他们欠债的金额。如果清算人没有保证这个过程会有利可图,他们不会清算一个持仓。那么何时一个持仓才能被清算?这个条件由协议决定,是分配给每个资产的清算阈值的函数。在清算阈值方面,时间非常重要。正如我们所知道的那样,如果一个持仓的债务价值超过其抵押价值,清算这些持仓对清算人来说是不赚钱的,协议也会面临坏账。因此,安全的清算阈值为清算人提供足够的时间,在持仓达到无法偿还的状态之前清算它们。现在我们理解了每个参与方保持持仓健康的动机,我们将展示协议实际如何实现这些机制:

Compound:账户流动性

Compound涉及到一个名为AccountLiquidity的参数,计算Compound主合约Comptroller中的LiquidationThreshold。Comptroller有一个名为getAccountLiquidity()的函数,返回有关账户流动性的信息。在内部,此函数调用getHypotheticalAccountLiquidityInternal():

我们在这里看到,该函数的主逻辑被限定在一个for循环范围内。这表明计算账户流动性是通过迭代所有市场完成的,其中账户参与。换句话说,在计算账户流动性时,考虑到了用户借贷或作为抵押品的所有资产。从我们之前的博客文章中回想一下,cTokenBalance是用户为抵押而提供的基础资产数量。在这个例子中,我们还可以看到borrowBalance和一些神秘的exchangeRateMantissa,它们都从getAccountSnapshot()返回。在我们之前的博客文章中讨论的一般化exchangeRate变量中,我们写道:「一个任意的利率可以增加铸造的Token数量,如果exchangeRate<1,则可以减少Token数量,如果exchangeRate>1,则可以增加Token数量。」这也适用于exchangeRateMantissa,它表示cToken与基础资产之间的汇率。正如我们在这个例子中看到的,Comptroller在获取了上面提到的三个参数之后,将首先获取当前正在迭代的特定市场的collateralFactor。这个collateralFactor信息是指用户可以根据其抵押品借多少钱的指标。从这个定义中,我们可以假设每个抵押品的存款可以抵押不同的借款金额。之所以这个金额在不同资产之间有所不同,主要是因为每个资产在协议眼中都有自己的「风险」,通常是指资产价值随时间波动的程度。Compound的治理根据市场状况改变抵押因素,但在任何时候,他们的抵押因素不能超过0.9——最多可以借出你存入的抵押品的90%:

然后,我们看到调用oracle.getUnderlyingPrice(asset),它调用一个名为Oracle的外部合约。Oracle是一种有趣的机制,值得一篇专门的博客文章。为了简洁起见,我们现在所解释的是,Oracle是用于在借贷协议中获取某个资产价格的合约,价格通常以协议使用的某种公共货币为基础。现在,我们已经涵盖了影响单个市场健康状况的所有因素,因此我们将写下计算单个市场AccountLiquidity的方程式:

注意:在Compound中,资产的价格以美元计价。这是一个相当长的变量列表,但如果你试着记住我们的「份额Token」文章中的Compound部分,你会发现以下表达式:

简单表示了用户cToken的基础资产价值。此外,borrowBalance_{user}变量,如你在这里所见,是用户借用的资产总余额,包括其中应计利息。现在,我们已经到达了以下备选AccountLiquidity方程式的点:

Maker

另一个设置清算不足抵押头寸阈值的协议是Maker。让我们检查该协议部署用于处理清算的两个合约:·Dog:在迁移到liquidations2.0之后部署的。此处的清算函数为bark()。·Cat:liquidations1.2,bite()。·grab():VAT合约,用作在部署猫合约之前进行清算的方法。让我们看一下bite()中的片段:

以及从bark()中的类似片段:

你可能会注意到两者具有相同的not-unsafe消息。因此,对于每个清算函数,Vault的安全要求都相同,并且可以用以下等式表示:

我们可以使用这个等式来定义一个不等式,以便Vault仍然是安全的:

优化一下:

我们建议我们的读者前往MakerDAO术语表,扩展我们提供的有关Maker生态系统中不同变量名称和术语的信息。或者,你可以相信我们在此概述的内容:?spot_{ilk}在这个不等式中用作抵押品的价格,以DAI计价,除以抵押品的清算比率?ink_{urn}是头寸的抵押品余额?rate_{ilk}是特定抵押品类型的累计债务。当与art_{urn}相乘,这是一个头寸借入的标准化债务金额,我们可以得到以DAI计价的总债务为了简化我们刚刚涵盖的内容,不使用Maker术语,我们将这样表示:

注意:Maker决定将抵押品和债务的价值计价为DAI——协议的稳定币。AAVEV2——健康因子

AAVEV2还定义了自己的阈值HealthFactor。具有H_{f}<1的健康因素值的用户可以被清算。定义如下:

显然,当用户没有债务时,他们的头寸无法被清算,因此健康因子默认为type(uint256).max。否则,健康因子被定义为:

当清算阈值由治理独立定义,目前由Gauntlet代表提供协议的所有风险参数,包括LiquidationThresholds。破产头寸分析

现在我们已经讨论了坏账的概念,接下来我们将提供一个真实世界的例子,以强调其重要性。我们要讨论的头寸是AAVEV2上的以下账户:0x227cAa7eF6D955A92F483dB2BD01172997A1a623。让我们通过在AAVEV2借贷协议上调用getUserAccountData函数来调查其当前情况:

现在让我们分解上面的内容,来看看这个头寸的情况有多糟糕:·总欠债ETH:17.83508595148699ETH·总抵押ETH:0.013596360502551568ETH这就是我们需要了解的所有内容,这个头寸有麻烦了——抵押品的价值只是欠款的一小部分。那么这个头寸是如何陷入困境的呢?为了回答这个问题,我们可以查看该用户在AAVE上执行的最新操作:

看起来一切都很好,直到块13514857,在该块中,用户从AAVE借出了一些资产。让我们看看他们做了什么:

债务人借了700,000MANA,快速查看MANA的美元价格将揭示该价格为:

每个MANA单位0.00032838ETH。通过简单的乘法,我们知道该用户通过以下方式增加了协议的债务:0.00032838*700000=229.866ETH值得一提的是,在该块的USD价格是4417.40美元。请注意上图中发生的存款操作,发生在借款几个小时后的块13517657。让我们看看市场上是否有什么事情动摇了我们用户的信心:

上面是发送到AAVEV2价格Oracle的RPC调用,以获取指定块中1个MANA单位的wei值。如果我们使用这些数据转换上述价格,我们可以看到发生了什么:0.00033625*700000=235.375ETH在短短几个小时内,债务增加了5.5ETH,价值24000美元。由于我们知道这个头寸的故事结局,我们知道它在某个时候是可清算的,因此让我们检查是否有涉及该用户地址的liquidationCall调用:

一旦我们找到第一个清算事件,我们就可以了解为什么用户在借款后不久就存入资产:

在这里,我们可以看到第一次清算发生在块13520838。这次清算发生在用户存入资金之前。然后,在13520838-13522070块之间发生了一系列小的清算,这些清算最终价值相当高:

让我们检查清算人在这些块之间从用户处夺取的所有抵押资产类型:

我们可以看到只有2种资产,DAI和ETH。

以及它们的数量:~50ETH~387663DAI有人可能会问,为什么清算会分成这么小的块?当像这样庞大的头寸被一次性清算时,市场会将这样大量的抵押品收购解释为这些资产类型的卖出信号。请记住:根据协议的清算奖励政策,以折扣购买清算中获得的资产。一次大规模的清算会引发一系列清算,随着卖出压力的上升,其他市场参与者可能也会卖出其资产,导致资产价格进一步「崩盘」,进而导致协议中其他头寸的更多清算。因此,协议通常限制单个清算可以夺取的资产数量。AAVE版本的此限制,作为变量,如下所示:

正如我们所看到的,限制百分比为50%,这意味着只有头寸债务的一半被允许在一次清算中偿还。清算人有动机将其清算拆分成较小的块。如果在清算时市场上没有足够的流动性来提供抵押品资产,那么将清算拆分成较小的块,清算人更有可能获得清算资产,并从他们的清算中获利。此外,如果市场上没有足够的流动性来获取债务资产,则清算人可能需要花费很多费用来获得首先要偿还未充足抵押的用户的债务。最后,想象一下试图清算大量某种Token,而没有拥有那么多。如果你去DEX并尝试交换一些WETH或其他资产以获得这一Token,你可能会遇到非常高的Gas费,这会使你的清算变得无利可图。回到我们的例子,为了检查链中一系列清算之后的头寸参数,我们需要解析从getUserAccountData返回给我们的数据:

然后我们使用cast查询链:

最后解析输出:

在这里,我们看到清算对头寸的影响:几乎没有剩余的抵押品,精确到0.6ETH。但是债务呢?高达45.26716296709878ETH。这个块的MANA价格是多少?

0.000862110734985458ETH。如果你还记得,我们的用户仅仅几个小时前以0.00032838ETH的价格借了MANA。这相当于开了一个股票的空头头寸,而这支股票的价格升了2.65倍。这些清算人在价格下跌到无法获利的程度之前无法及时清算完整个头寸,我们留下了一个破产的头寸。现在,我们可以意识到有效的流动性阈值在防止协议产生坏账方面的重要性。总结

虽然我们不能确定是否有一个方程来定义头寸的流动性阈值,但我们肯定可以看到协议之间的相似之处:·所有协议都将其阈值定义为某种抵押品与债务的函数。·所有协议都给治理留下了一些空间,以便根据市场条件的变化决定每种抵押品风险参数的价值,因为有些资产比其他资产更具有波动性。·所有协议都使用预言机以一种广泛接受的货币对其抵押品和债务价格进行标价。我们已经看到Maker和AAVE选择使用相同的方程来表示头寸的安全性:

原地址

郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。

金智博客

[0:15ms0-5:539ms