Ajna Protocol是一个去中心化、无需治理或外部价格源的借贷和交易系统,利用桶的设计允许用户以不同的风险比例进行借贷。协议通过称为Fenwick树的数据结构有效地管理多个借贷池,使其能够动态追踪市场价格。Ajna还允许使用ERC721 NFTs作为抵押品,解决了传统借贷机制中价格操控的问题,从而提高了安全性和效率。
“Ajna Protocol 是一个无托管的、点对点、无权限的借贷和交易系统,运行所需的没有治理或外部价格feeds。”没有治理,没有外部价格feed - 非常吸引人!
许多现代 DeFi 协议正在朝着更无权限和无信任的设计发展。虽然经常讨论去中心化,但这一趋势背后有实际的动机:对 DeFi 协议攻击的很大一部分源于预言机价格操控、配置错误和访问控制问题。以“设计”方式减轻这些风险是极具吸引力的。
Ajna 协议是这种方法的一个典范;让我们来看看它吧!
我们的第一站,当然是 白皮书。Ajna 的关键思想是无权限地创建池,其中包含代币对(用于供应和借贷),类似于 Uniswap 的池。每个池被划分为“桶” - 类似于 Uniswap V3 中的价格刻度 (文章) - 每个刻度代表报价和抵押代币之间的固定比率(每单位抵押的报价代币量)。这种设计使得贷方可以选择一个桶,并以他们选择的 LTV(贷款价值比)来提供流动性。在 Ajna 中,贷方必须将他们的存款保持在接近市场价格的位置(将其放置/移动到“更接近”市场价格的桶),因为过高的抵押价格将导致失去存款(报价代币),以换取较少量的抵押代币(反之亦然,对于低估价桶)。让我们参考白皮书中的图片:
Ajna 使用“利用率”来描述一个桶。已利用的桶是指所有“上层”桶(价格高于当前桶)的存款总和少于池中所有借款人的总债务的桶。从利用的桶中,最低价格或“最低利用价格”(LUP)是一个关键指标。换句话说,所有高于 LUP 的存款在实际上都在被借出。
另一个重要的阈值是“最高阈值价格”(HTP),它是最少抵押贷款的阈值价格。用其他的话来解释,“所有高于 HTP 的存款都在为池中的每笔贷款提供流动性”。
从 LUP 到 HTP 的桶范围在 Ajna 中扮演着重要角色。LUP 的移动受到不同桶中存款和债务的增加或减少的影响。HTP 的移动受到最少抵押贷款被清算的影响。因此,LUP 和 HTP 都用于确定借款人的位置是否有资格被清算,以及贷方是否可以提取其存款。
Ajna 中的清算会从桶中移除债务和抵押,并因此移动 LUP 和 HTC 值,使市场向实际市场价格转变。清算会从“坏”桶中移除债务,只留下抵押价格接近市场价值的桶。
最终的清算价格是通过荷兰拍卖确定的,赢家是第一个接受不断降低价格的参与者。当前“正在清算”的存款被冻结,不能被提取。此外,以高于当前清算拍卖中最低价格的价格存入报价代币是被禁止的。
白皮书对此解释得更清楚,但为了简单:所有这些限制、LUP 和 HTC 旨在根据外部市场价格在桶之间创建一个“顺序”流动性的转移。Ajna 协议通过 “收集” 来自 HTP 和 LUP 之间的“稳定”范围以上和以下桶的额外债务和抵押,以“跟随”抵押的市场价格移动 HTC-LUP 桶范围。
Ajna 中的利率是“市场导出”的,而不是预定义或治理的值。它们是基于池的利用率动态确定的,并应用了利率限制。现在,让我们继续谈论实现。
池的部署
像往常一样,我们的第一个短暂停留将是在池的部署工厂。Ajna 有不同类型的池:一个是由 ERC20PoolFactory.sol 部署的,另一个是由 ERC721PoolFactory.sol 部署的。前者是用于 ERC20 代币,后者是用于用作抵押的 NFT。由于 Ajna 不使用外部预言机,并且贷方的位置被存储为 NFT,因此在桶中与 NFT 的处理(而不是常规的 ERC20 代币)比在其他协议中要简单得多。无需在协议内部估计每个 NFT 的价格;这项工作由协议交易者执行,而桶逻辑保持不变。池不会升级,但用于保持代币对池地址的映射是使用常量种子构建的 (这里,或 这里),可以更改以添加新的类型和版本的池。
在 Ajna 中池的部署是简单且完全无权限的,像在 Uniswap 中一样。 这里可以看到,创建池非常简单,唯一的“治理式”结构是 映射和列表,以避免使用相同代币的重复池(也类似于 Uniswap)。
桶和 Fenwick 树
如上所述,Ajna 需要对多个桶进行操作,并且每个桶有独立的债务/抵押值。在没有专门数据结构的 EVM 和智能合约中,对大范围进行操作是不可行的。根据白皮书,Ajna 至少需要:
有一种专门数据结构用于有效计算索引范围内的和:Fenwick 树(也称为二进制索引树 wiki,在 文章 中解释得很好)。这种树允许用 O(logN) 操作计算数组中任何 (i, j] 元素范围的部分和。这些树被用来有效追踪“运行总”和值,我们需要不断计算在随时间变化的数组中某些元素范围的和。
Ajna 使用 两个 Fenwick 树:
这意味着在 Ajna 中所有改变这些部分和或利息因子的操作不仅更新相应的桶信息,还更新整个树。这看起来可能效率不高,但让我们回忆一下,操作数量保持恒定( log 2 N),其中 N 是桶的数量(7388 个桶)。这导致每棵树约 13 次迭代。
Fenwick 树的使用示例可以在 追加 存款、在 LUP 计算 的 findIndexAndSumOfSum() 函数、以及一些其他地方找到。
借贷
Ajna 中借贷操作的实现使用两个主要入口点:ERC20Pool.sol 和 ERC712Pool.sol,包含用于借贷的 drawDebt() 函数( ERC20 和 ERC721 实现)和 addCollateral() 函数( ERC20 和 ERC721 变体)。这些函数仅处理基本检查和代币转移;Ajna 的主要逻辑位于 LenderActions.sol 和 BorrowerActions.sol。...
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!