AAVE-v3

发布于 2026年1月3日
145 分钟阅读

AAVE v3.3.0解读

一. 概念基础

1.1 什么是Isolation Mode

1.1.1 什么是隔离资产(Isolated Assets)?

在AAVE V3中,“隔离资产”不是指某一种特定的代币(如ETH或USDC),而是指一种特殊的风险配置模式。

简单来说,任何一个常规的资产(如ETH、WBTC、USDC)都可以被协议管理员设置为在“隔离模式”下使用。 当一种资产被标记为“隔离资产”时,它只能被用作独立的、与其他资产风险隔离的抵押品

1.1.2 核心特性

  1. “Isolated assets have limited borrowing power” (隔离资产的借贷能力有限)
    • 为了防止高风险资产崩溃时拖累整个协议,隔离资产有一个预设的、较低的贷款价值比(LTV)。例如,普通模式的ETH LTV可能为80%,而隔离模式的某个高风险代币的LTV可能只有30%或更低。
    • 这意味着,你存入价值100美元的隔离资产,最多只能借出30美元(或其他限额)的其他资产,借款能力被严格限制。
  2. “and other assets cannot be used as collateral.” (其他资产不能作为抵押品)
    • 这是隔离模式最关键的风险隔离设计。你只能使用你指定的那一种(或几种)隔离资产作为抵押品。
    • 你账户里的其他非隔离资产(如普通的USDC、ETH存款)不能被计入抵押品价值,也不能被用于清算。 它们就像被放在一个完全独立的“保险箱”里,不受隔离仓风险的影响。

1.1.3 为什么要设计“隔离模式”?

这是AAVE V3一个重大的创新,主要目的是:

  1. 安全地引入高风险资产:允许用户使用波动性大、流动性相对较差(长尾资产)的代币作为抵押品,而不会将这些高风险传染给协议的核心、稳定的资产池。如果这个隔离资产价格暴跌,其风险被限制在“隔离仓”内。
  2. 保护用户其他资产:对于借款人来说,这提供了更好的风险管理。你可以用一个高风险资产去尝试高杠杆操作,即使这个仓位被清算,你其他的存款和投资仍然是安全的,不会被波及。
  3. 提高资本效率:对于保守用户,他们可以放心地将稳定币存入主池赚取利息,而无需担心这些存款会因为别人炒作某个小币种而被清算。

1.1.4 与普通(交叉抵押)模式的区别

特性普通(交叉抵押)模式隔离模式
抵押品所有被启用作抵押的资产都可以共同作为抵押池。仅限于指定的一种或几种隔离资产
风险所有抵押资产暴露在风险中,一个资产暴跌可能引发连锁清算。风险被隔离。只有隔离仓内的资产有风险。
借贷能力基于所有抵押资产的总价值乘以各自的LTV计算,通常较高。受到严格限制,只有隔离资产的较低LTV。
目的适用于主流、低风险资产,追求资本效率和便利性。适用于尝试高风险资产或进行特定策略,同时保护主账户资产。

1.2 什么是 E Mode

E-Mode是AAVE V3引入的“效率模式”(Efficiency Mode)

特性效率模式 (E-Mode)隔离模式 (Isolation Mode)
设计目标提升资本效率,最大化借款能力。隔离风险,防止高风险资产波及系统。
适用资产价格高度相关的资产,如稳定币之间(USDC/USDT)或同类资产(ETH与stETH)。新上线的、波动性高、风险较高的资产(如某些长尾代币)。
核心机制大幅提高贷款价值比(LTV),允许借出更多资金。严格限制LTV和借贷上限,只能借入指定的稳定币。
风险逻辑因资产价格高度相关,抵押品和债务价值同向波动,清算风险被认为相对可控将高风险资产的债务限制在一个“围栏”内,防止其崩溃时拖累用户的其他资产或整个协议。

1.2.1 E-Mode 如何运作

你可以把E-Mode理解为一个可开关的“高效借贷档位”。当你开启一个特定的E-Mode类别(例如“稳定币E-Mode”)后:

  1. 更高的借款能力:你在此模式下的抵押品会获得一个远高于普通模式的LTV(例如,稳定币的LTV可能从80%提升至90%以上)。
  2. 借贷限制:你只能借入同一E-Mode类别内的资产。例如,在“稳定币E-Mode”下,你抵押USDC只能借出USDT、DAI等其他稳定币,而不能去借ETH。

1.3 APR 和 APY

这是一个非常核心的金融概念。简单来说:

  • APR(年化利率) 告诉你借钱的成本不考虑复利的收益

  • APY(年化收益率) 告诉你考虑复利后的实际收益

  • 特性APR (年化利率)APY (年化收益率)
    中文全称年化百分比利率年化百分比收益率
    核心含义借款的名义成本或贷款的简单利率存款或投资的实际收益,考虑了复利。
    是否包含复利不包含。只基于本金计算。包含。利滚利,收益基于本金+已产生的利息。
    计算复杂度简单,线性计算。复杂,指数计算。
    主要应用场景贷款(如信用卡、房贷、车贷),用于比较借款成本。存款/投资(如储蓄账户、定期存款、加密货币质押),用于比较真实收益。
    数值比较对于同一产品,APY 通常高于或等于 APR复利越频繁(每天、每月),APY 比 APR 高出越多。

apr-apyapr-apy

1.4 Market forces

1.4.1 borrow,supply interest rate和 utilization rate 和 protocol fee rate 的关系

market-forcesmarket-forces

1.4.2 利用率 Utilization rate

utilization-rateutilization-rate

1.4.3 借款利率 borrow interest rate 和 利用率 utilization rate 的关系

interest-rate-modelinterest-rate-model

有一个理想利用率阈值,如果超过这个阈值(例如图中的百分之80),借款利率会迅速上升。

1.5 Reserve (储备)

DataTypes.ReserveData
Aave V3 配置层的核心结构体。它完整定义了协议中某个储备资产(如 USDC、WETH)的所有关键状态和参数。

struct ReserveConfigurationMap {
  //bit 0-15: LTV
  //bit 16-31: Liq. threshold
  //bit 32-47: Liq. bonus
  //bit 48-55: Decimals
  //bit 56: reserve is active
  //bit 57: reserve is frozen
  //bit 58: borrowing is enabled
  //bit 59: DEPRECATED: stable rate borrowing enabled
  //bit 60: asset is paused
  //bit 61: borrowing in isolation mode is enabled
  //bit 62: siloed borrowing enabled
  //bit 63: flashloaning enabled
  //bit 64-79: reserve factor
  //bit 80-115: borrow cap in whole tokens, borrowCap == 0 => no cap
  //bit 116-151: supply cap in whole tokens, supplyCap == 0 => no cap
  //bit 152-167: liquidation protocol fee
  //bit 168-175: DEPRECATED: eMode category
  //bit 176-211: unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
  //bit 212-251: debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
  //bit 252: virtual accounting is enabled for the reserve
  //bit 253-255 unused

  uint256 data;
}
字段数据类型核心意义与作用
核心会计与状态
configuration
ReserveConfigurationMap
储备资产配置位图。使用位操作存储所有风险参数(如LTV、清算阈值、是否冻结、是否作为抵押品等)。
liquidityIndex
uint128
流动性指数。核心复利因子,用于计算存款人的应计利息(
实际余额 = scaledBalance * index
)。以
ray
(1e27) 为单位,随时间单调递增。
variableBorrowIndex
uint128
可变借款指数。用于计算浮动利率借款人的应计债务(
实际债务 = scaledDebt * index
)。同样以
ray
为单位。
lastUpdateTimestamp
uint40
最后更新时间戳。记录此储备数据最近一次被更新的时间点,是计算两次操作之间应计利息的基础。
virtualUnderlyingBalance
uint128
虚拟底层资产余额。协议内部会计账本记录的理论资产总量,是计算利息和健康的基准。其关系为:
virtual = 实际流动性 + 总债务 + deficit - unbacked
accruedToTreasury
uint128
应计至国库的金额。累积但尚未划转给国库的协议收入(利差),以该储备资产的单位计价。
代币地址与ID
aTokenAddress
address
aToken 合约地址。用户存款时收到的生息代币凭证。
variableDebtTokenAddress
address
可变债务代币地址。用户进行浮动利率借款时产生的债务代币。
__deprecatedStableDebtTokenAddress
address
稳定债务代币地址(已弃用)。自 V3.2.0 移除稳定利率后,此字段仅为保持存储槽兼容而保留。
interestRateStrategyAddress
address
利率策略合约地址。指向计算该资产存款和借款利率的动态逻辑合约。
id
uint16
储备资产ID。在协议内部活跃储备列表中的唯一位置索引。
利率
currentLiquidityRate
uint128
当前流动性利率。基于资金池利用率和利率策略实时更新的年化存款利率,以
ray
为单位。
currentVariableBorrowRate
uint128
当前可变借款利率。实时更新的年化浮动借款利率,以
ray
为单位。

1.6 aToken 和 Variable Debt Tokens

区分Rebase Token(变基代币)和Non-Rebase Token(非变基代币)主要看代币的数量是否会自动变化。

特性aTokensVariable Debt Tokens
代表内容存入的资产累积的利息可变的浮动利率债务
本质生息存款凭证计息债务凭证
代币数量随时间增加,余额自动增长以体现利息收入。随时间增加,余额自动增长以体现应付利息。
价值基础与底层资产 1:1 锚定(1 aUSDC ≈ 1 USDC)。与借入的债务 1:1 锚定
主要功能1. 实时赚取利息; 2. 可随时赎回或转账; 3. 可作为抵押品。1. 实时计算应付利息; 2. 需偿还债务以销毁。
Rebasing机制余额自动增加(利息以代币形式发放)。余额自动增加(应付利息以债务形式累积)。

1.7 计算借款复利 cumulative interest Rates

1.7.1 正常计算

AAVE-v3-计算借款利率AAVE-v3-计算借款利率

// Code 1
contract Bank {
    // user => debt
    mapping(address => uint256) public debts;
    // user => timestamp of last borrow
    mapping(address => uint256) public timestamps;
    // timestamp => rates (1 = 1e18)
    mapping(uint256 => uint256) public rates;
    function calculateDebt(address user) external view returns (uint256) {
        uint256 debt = debts[user];
        uint256 k = timestamps[user];
        uint256 n = block.timestamp;

        for (uint256 t = k; t < n; t++) {
            debt = debt * rates[t] / 1e18;
        }

        return debt;
    }
}

1.7.2 优化公式来节省gas

计算借款利率2计算借款利率2 计算借款利率3计算借款利率3

// Code 2
contract Bank {
    // user => debt
    mapping(address => uint256) public debts;
    // R(n-1)
    uint256 public cumulativeRates = 1e18;
    // R(k-1)
    // user => cumulative rate when user borrowed
    mapping(address => uint256) public userCumulativeRates;

    function calculateDebt(address user) external view returns (uint256) {
        return debts[user] * cumulativeRates / userCumulativeRates[user];
    }
}

1.7.3 借取款量发生变化

AAVE-v3-计算借款利率4AAVE-v3-计算借款利率4

// Code 3
contract Bank {
    // user => debt
    mapping(address => uint256) public debts;
    // R(n-1)
    uint256 public cumulativeRates = 1e18;

    function calculateDebt(address user) external view returns (uint256) {
        return debts[user] * cumulativeRates / 1e18;
    }

    function updateCumulativeRates() public {}

    function borrow(uint256 amount) external {
        updateCumulativeRates();
        debts[msg.sender] += amount * 1e18 / cumulativeRates;
    }

    function repay(uint256 amount) external {
        updateCumulativeRates();
        debts[msg.sender] -= amount * 1e18 / cumulativeRates;
    }
}

1.8 Liquidity/Borrow Index(流动性/借款索引)Scaled Balance/Debt(缩放余额/债务)

1.8.1 核心关系:全局基准与个人份额

概念性质作用类比
Liquidity/Borrow Index全局变量,每个借贷市场只有一个,随时间不断增长。记录资金池总资产/总债务的复利增长基准线基金的总净值。
Scaled Balance/Debt用户变量,在发生交互时才更新,通常保持不变。记录用户存入或借出的本金,按存入时的索引进行“缩放”后的值你持有的基金份额。
用户实际权益/债务计算结果用户在任意时刻实际拥有或欠款的价值你的基金份额 × 当前基金净值。

1.8.2 核心公式

计算用户 Scaled Balance/Debt (存入/借款时)
Scaled Balance = Underlying Amount Deposited / Liquidity Index at that time
Scaled Debt = Underlying Amount Borrowed / Borrow Index at that time

计算用户实际权益/债务 (查询/赎回/还款时)
User's Actual Balance = User's Scaled Balance × Current Liquidity Index
User's Actual Debt = User's Scaled Debt × Current Borrow Index
  • scaledBalance/Debt:这是系统为用户存储的核心内部记账值。在用户存入资产时确定,后续只有在用户发生新的存取款或借款时才会按比例更新。
  • liquidityIndex(流动性指数):这是一个全局变量,代表资产池自创建以来,单位本金累计产生的复利。它随着时间推移和利息累积而不断单调递增。

代码:

mintScaleToken

这个函数在存款借款时被调用,核心是增加用户的缩放代币余额。

function _mintScaled(
  address caller,
  address onBehalfOf,
  uint256 amount,
  uint256 index
) internal returns (bool) {
  //Scaled Balance 变化量
  uint256 amountScaled = amount.rayDiv(index);
  require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);

  uint256 scaledBalance = super.balanceOf(onBehalfOf);
  
  uint256 balanceIncrease = scaledBalance.rayMul(index) -
    scaledBalance.rayMul(_userState[onBehalfOf].additionalData);

  //每次函数结束时都会用最新的 index 更新它,为下一次计算利息提供基准。
  _userState[onBehalfOf].additionalData = index.toUint128();

  _mint(onBehalfOf, amountScaled.toUint128());

  uint256 amountToMint = amount + balanceIncrease;
  emit Transfer(address(0), onBehalfOf, amountToMint);
  emit Mint(caller, onBehalfOf, amountToMint, balanceIncrease, index);

  return (scaledBalance == 0);
}
  • balanceIncrease
    : 它代表从上一次用户交互到此刻,用户因指数增长而自动产生的应计利息(以实际代币计价)
    • scaledBalance.rayMul(index)
      :用户当前的Scaled Balance按最新指数折算成的最新总权益
    • scaledBalance.rayMul(_userState[user].additionalData)
      :用户当前的Scaled Balance按上次记录的指数折算成的上次权益
    • 两者之差
      最新权益 - 上次权益
      ,就是在这段时间内新产生的利息

1.8.3 举例说明

  1. 存入时刻:你存入1000 USDC,此时流动性索引
    1.0
    • 协议为你计算:
      Scaled Balance = 1000 / 1.0 = 1000
    • 你获得1000个aToken(代表你的缩放余额),同时全局索引开始增长。
  2. 持有期间:你的
    Scaled Balance
    保持为1000不变,但池子的流动性索引因利息累积增长到
    1.05
  3. 赎回时刻:你想取回资金。
    • 协议读取你当前的
      Scaled Balance
      (1000)和当前的
      Liquidity Index
      (1.05)。
    • 计算你的实际权益:
      1000 × 1.05 = 1050 USDC
    • 你赎回1050 USDC,其中50 USDC是自动累积的利息。

1.8.4 设计优点

这种将“不断增长的全局指数”与“相对稳定的个人缩放值”分离的设计,主要有两大精妙之处:

  • 极致优化Gas成本:绝大多数时候,只有全局的
    Index
    需要随着每个区块更新(增长)。所有用户的
    Scaled Balance
    都无需变动。仅在用户与协议交互时,才进行一次性的利息结算(用新旧索引差值计算)。这避免了传统模式中需要为每个用户每个区块更新余额的巨大Gas消耗。
  • 确保公平与精确:所有利息分配都通过公开透明的链上数学公式完成。无论用户何时进出,其应得的利息都能通过索引的差值被精确计算,确保了绝对的公平性。

1.9 Reserve Factor(储备金因子,协议费用)

    vars.currentLiquidityRate = vars
      .currentVariableBorrowRate
      .rayMul(vars.supplyUsageRatio)
      .percentMul(PercentageMath.PERCENTAGE_FACTOR - params.reserveFactor);
  • 公式:流动性存款利率 = R_variable * U_supply * (1 - reserveFactor)

  • reserveFactor
    :协议费用率,从借款利息中扣除一部分作为协议收入,剩余部分才分配给存款人。因此存款利率总是低于借款利率。

1.10 MAX LTV 最大贷款价值比

借款上线:你最多能借出的资产价值占抵押品价值的最大百分比。超过此线则无法新增借款

ltvltv

1.11 Liquidation threshold

当你的借款价值占抵押品价值的比例超过此线,头寸进入可被清算状态

“清算阈值 > 最大LTV”的核心原因

这个设计主要基于两个关键考虑:

  1. 为清算人提供激励:清算发生时,清算人需要垫资偿还你的部分债务,并从你的抵押品中获取一部分作为奖励(包含清算激励)。如果清算触发线(清算阈值)和借款上线(Max LTV)设得太近甚至相同,清算人就没有足够的利润空间来覆盖其交易成本和风险,可能导致无人愿意清算,使协议暴露在风险中。
  2. 避免过度频繁清算:如果刚超过借款上限就立即清算,市场微小的波动就会引发大量清算事件,不仅损害用户体验,还可能在市场剧烈波动时加剧“毒性清算螺旋”。

liquidation-thresholdliquidation-threshold

1.12 Health-factor

health-factorhealth-factor

二. 合约代码

2.1 代码框架

arcarc

2.2 Supply

2.2.1 调用逻辑图

supply代码流程图supply代码流程图

1.

reserve.updateState(reserveCache)

  • 作用:更新储备金的状态,这是利息计算的触发点。它通过计算自上次交互以来经过的区块数量,调用
    _cumulateToLiquidityIndex
    函数,将累积的利息更新到流动性索引(
    liquidityIndex
    )和借款索引(
    variableBorrowIndex
    )中
    。这确保了在存款操作前,所有未计算的复利都已精确计入池子总账中。

2.

ValidationLogic.validateSupply(...)

  • 作用:执行一系列安全检查,确保存款操作合法。主要包括:
    • validateAmount
      :检查存款金额是否大于零。
    • validateSupply
      :检查目标市场是否处于激活(Active)状态,未被冻结(Frozen)或暂停(Paused)。
    • validateSupplyCap
      :检查此次存款后,该资产的总供应量是否会超过协议设定的供应上限(Supply Cap),这是风险控制的重要一环。

3.

reserve.updateInterestRatesAndVirtualBalance(...)

  • 作用:在存款资产入账后,更新资金池的利率。它根据存款后的新资金利用率,通过利率策略合约计算出新的浮动借款利率。同时,它会更新储备金的
    liquidityAdded
    liquidityTaken
    等“虚拟余额”,这些变量主要用于管理跨链流动性,是AAVE V3的核心特性之一。

4. 资产转移与记账

  • IERC20(params.asset).safeTransferFrom
    :将用户的资产从其地址安全地转移到该储备金对应的
    aToken
    合约地址。
  • IAToken(reserveCache.aTokenAddress).mint
    :这是关键记账步骤
    aToken
    合约的
    mint
    函数会:
    1. 根据当前最新的
      nextLiquidityIndex
      (由
      updateState
      计算得出),将用户存入的原始资产金额折算为
      scaledBalance
      。公式为:
      scaledBalance = amount / nextLiquidityIndex
    2. 将折算后的
      scaledBalance
      记在用户名下,并给用户铸造相应数量的
      aToken
      凭证。
    3. 返回一个布尔值
      isFirstSupply
      ,标识此用户是否是首次供应该资产。

5. 抵押品自动配置

  • 如果
    isFirstSupply
    为真,且通过
    validateAutomaticUseAsCollateral
    检查(用户未将此资产在其他市场设置为抵押品、且该资产本身可被用作抵押品),则会自动将该用户的此资产配置为抵押品
    userConfig.setUsingAsCollateral
    ),从而可能提升其借款能力。

2.2.2 计算流动性存款利率

利率计算的核心是 “资金利用率” ,它衡量了池子中存款被借出的比例。

1. 借款利率计算(分段线性模型)

借款利率随利用率上升而增加,在“最优利用率”处拐折,加速上升以抑制过度借贷。

U = 总债务 / (可用流动性 + 总债务)  // 借款资金利用率
U_optimal = 最优利用率(例如80%)
R_base = 基础可变借款利率
R_slope1 = 最优利用率以下的斜率
R_slope2 = 最优利用率以上的斜率

如果 U <= U_optimal:
  可变借款利率 = R_base + (U / U_optimal) * R_slope1
如果 U > U_optimal:
  可变借款利率 = R_base + R_slope1 + [(U - U_optimal) / (1 - U_optimal)] * R_slope2

2. 存款利率计算(派生模型)

存款利率源于借款利息,在扣除协议费用后分配给存款人。

R_variable = 计算出的可变借款利率
U_supply = 总债务 / (可用流动性 + 总债务 + 未备份资产)  // 供应利用率
reserveFactor = 储备金因子(协议费用率,例如10%)

流动性存款利率 = R_variable * U_supply * (1 - reserveFactor)
  • 公式本质存款利率 = 借款利率 × 供应利用率 × (1 - 储备金因子)
  • reserveFactor
    :协议费用率,从借款利息中扣除一部分作为协议收入,剩余部分才分配给存款人。因此存款利率总是低于借款利率。

总结

在AAVE V3.3中:

  1. 计算起点:由市场供需决定的资金利用率
  2. 即时价格:利用率通过分段函数模型产生借款利率,再派生出发放给存款人的存款利率
  3. 长期记录:这两个利率每秒都在影响并累积到流动性索引借款索引中。
  4. 用户收益/债务:你的存款最终收益(
    aToken
    增值)和借款总债务,都通过
    你的缩放余额 * 当前索引
    这个公式由索引精确决定。

2.3 Borrow

2.3.1 borrow代码调用流程图

AAVE-v3-BorrowAAVE-v3-Borrow

2.3.2 函数解释

  1. 入口函数:
    Pool.borrow()
    • 位置
      protocol/pool/Pool.sol
    • 作用:这是用户发起借款调用的主要入口。它首先进行基础参数验证(如资产是否激活、金额有效性、利率模式),然后区分是普通借款还是闪电贷,并路由到对应的执行函数。
  2. 核心逻辑:
    _executeBorrow()
    • 位置
      protocol/libraries/logic/BorrowLogic.sol
    • 作用:这是借款业务逻辑的核心,其执行严格依赖更新后的状态,主要步骤包括:
      • 验证健康因子:调用
        _validateBorrow
        (内部会调用
        ValidationLogic.validateBorrow
        )计算用户新增此笔债务后的预估健康因子,必须大于1(可配置的阈值),否则交易回滚。这是风险控制的核心。
      • 更新利率与指数:调用
        _updateInterestRates
        更新资产的
        currentVariableBorrowRate
        variableBorrowIndex
        这是Scaled Balance系统计息的关键
      • 计算与铸造债务
        • 计算实际收到的金额(可能扣除手续费)。
        • 将实际借款金额按最新
          variableBorrowIndex
          折算为Scaled Debt
          amountScaled = amount.rayDiv(index)
        • 调用
          variableDebtToken.mint()
          ,最终会触发你之前分析的
          _mintScaled
          函数,将
          amountScaled
          记入用户地址,作为其浮动债务的Scaled Balance。
      • 转移资产:将底层代币从储备池转移给用户。
      • 更新状态:更新用户的隔离模式债务(如适用)和整体的健康因子。
  3. 状态更新:
    _updateInterestRates()
    _mintScaled
    • 这是连接“全局利率”与“个人债务”的桥梁。
    • _updateInterestRates
      会调用
      interestRateStrategy.calculateInterestRates()
      ,根据最新的资金利用率,计算出新的
      currentVariableBorrowRate
      currentLiquidityRate
      ,并更新
      variableBorrowIndex
    • 随后,
      _mintScaled
      利用这个刚更新过的、最新的
      index
      ,将用户的借款金额“定格”为Scaled Debt。同时,它也会结算用户已有旧债务自上次操作以来新产生的利息(通过
      balanceIncrease
      计算),并更新用户个人的
      additionalData
      索引快照。
  4. 最终检查:
    _executeBorrow
    收尾
    • 确保资产转账成功。
    • 通过检查
      ReserveData
      中的
      virtualUnderlyingBalance
      (虚拟总账)来确认协议内部会计的一致性。
    • 发出包含所有关键信息的
      Borrow
      事件。

2.4 Repay

2.4.1 repay 流程图

AAVE-v3-repayAAVE-v3-repay

2.4.2 关键步骤详解

根据上面的流程图,以下是各核心环节的详细说明:

  1. 入口函数:
    Pool.repay()
    • 位置
      protocol/pool/Pool.sol
    • 作用:用户或第三方(如清算人)调用此函数来偿还债务。它进行基础验证后,会调用
      RepayLogic.executeRepay
      。注意,在v3.2+版本,由于稳定利率被移除,
      interestRateMode
      参数通常固定为浮动利率(2)。
  2. 核心逻辑:
    _executeRepay()
    • 位置
      protocol/libraries/logic/RepayLogic.sol
    • 作用:这是还款业务逻辑的核心。其目标是精确减少用户的Scaled Debt并处理相关利息。关键步骤包括:
      • 验证与获取债务:确认用户在该资产上有未偿债务,并获取其当前的可变债务代币余额(Scaled Balance形式)。
      • 更新利率与指数:调用
        _updateInterestRates
        更新资产的
        variableBorrowIndex
        等。这是结算截至还款时刻所有应计利息的基础
      • 计算实际还款上限:用户的实际债务总额 =
        scaledBalance * variableBorrowIndex
        。如果传入的
        amount
        type(uint256).max
        ,则表示用户想偿还全部债务;否则,还款金额不能超过实际债务总额。
      • 销毁Scaled债务(核心)
        • 将实际还款金额按最新
          variableBorrowIndex
          折算为应销毁的Scaled Debt
          amountScaled = amount.rayDiv(index)
        • 调用
          variableDebtToken.burn()
          ,最终触发
          _burnScaled
          函数。该函数会:
          1. 结算用户旧债务到此刻新产生的利息(
            balanceIncrease
            )。
          2. 比较
            amount
            (还款额)
            balanceIncrease
            (新利息)
          3. 如果
            amount > balanceIncrease
            ,则超额部分用于销毁本金,发出
            Burn
            事件。
          4. 如果
            amount <= balanceIncrease
            ,则还款额连新利息都未覆盖,用户的净债务反而增加,会发出
            Mint
            事件。这是会计一致性的关键体现。
      • 接收资产:将还款的底层代币从调用者地址转移至储备池。
      • 更新状态:减少用户在隔离模式下的债务(如适用),并调用
        _updateIsolatedDebtIfIsolated
        更新相关状态。最后,重新计算并更新用户的健康因子(通常会因债务减少而改善)。
  3. 最终检查与事件
    • 验证资产转账成功。
    • 检查用户的债务余额是否如预期减少(或清零)。
    • 发出
      Repay
      事件,包含借款人、还款人、资产、金额、是否全额清偿等关键信息。

2.5 Withdraw

2.5.1 withdraw代码调用流程图

AAVE-v3-withdrawAAVE-v3-withdraw

2.5.2 关键函数

  1. 入口函数:
    Pool.withdraw()
    • 位置
      protocol/pool/Pool.sol
    • 作用:用户调用此函数从资金池提取自己存入的资产。它进行基础验证后,会调用
      WithdrawLogic.executeWithdraw
      。注意:用户可以为第三方提取(通过
      to
      参数),但只能提取自己名下的资产。
  2. 核心逻辑:
    _executeWithdraw()
    • 位置
      protocol/libraries/logic/WithdrawLogic.sol
    • 作用:这是提现业务逻辑的核心,在允许用户取出资产的同时,确保协议和用户账户的安全性。关键步骤包括:
      • 获取用户存款余额:通过
        AToken.balanceOf(user)
        获取用户当前的Scaled Balance。
      • 更新利率与指数:调用
        _updateInterestRates
        更新资产的
        liquidityIndex
        currentLiquidityRate
        这确保了用户能提取截至当前区块所产生的全部利息
      • 计算实际可提取金额(核心限制逻辑)
        • 基于用户余额:计算用户的实际存款总额 =
          scaledBalance * liquidityIndex
          。如果传入的
          amount
          type(uint256).max
          ,则表示用户想提取全部存款;否则,提现金额不能超过实际存款总额。
        • 基于池流动性:即使有存款,提现金额也不能超过储备池的可用流动性。可用流动性 =
          虚拟余额(virtualUnderlyingBalance) - 总债务 - 赤字(deficit)
        • 最终可提取金额 =
          min(用户请求金额, 用户存款总额, 池可用流动性)
      • 销毁aToken(核心)
        • 将实际提现金额按最新
          liquidityIndex
          折算为应销毁的Scaled aToken
          amountScaled = amount.rayDiv(index)
        • 调用
          AToken.burn()
          ,最终会触发
          _burnScaled
          函数(与你之前分析的债务代币销毁逻辑类似)。该函数会:
          1. 结算用户存款到此刻新产生的利息(
            balanceIncrease
            )。
          2. 从用户的aToken余额中销毁对应的
            amountScaled
      • 转移资产:将底层代币从储备池转移给接收地址(
        to
        )。
      • 安全验证与状态更新
        • 健康因子检查:这是提现的关键风控。减少抵押品(提现)可能会降低用户的健康因子。协议会验证提现后用户的健康因子仍高于清算阈值(通常为1),否则交易回滚。这是防止用户无意中将自己置于清算风险的重要保护。
        • 更新用户的隔离模式债务状态(如适用)。
        • 更新储备池的
          virtualUnderlyingBalance
          (减少取出的部分)。
  3. 最终检查与事件
    • 验证资产转账成功。
    • 检查实际提取金额大于0(防止边缘情况下的零值操作)。
    • 发出
      Withdraw
      事件,包含用户、接收者、资产、金额等关键信息。

2.6 Liquidation

2.6.1 close factor

AAVE的Close Factor(关闭因子)是指在一次清算交易中,允许清算人替借款人偿还的最大债务比例,而不是全部清算

核心定义

  • 目的: 防止借款人因市场微小波动而被“全额清算”,增加系统的抗风险能力,并为借款人提供缓冲。
  • 默认值: 在AAVE V2和V3中,Close Factor的默认值是 50%。这意味着在一次清算交易中,清算人最多只能偿还借款人某一笔特定债务的50%。
  • 关键限制:不是针对借款人总债务的比例,而是针对触发清算的每一笔单独的债务资产
  • 满足三个条件才能使用部分清算:如下图

close-factorclose-factor

举例说明(多债务场景)

假设借款人仓位:

  • 抵押品: 价值 $200 的ETH。
  • 债务1: 100 USDC (稳定币)
  • 债务2: 50 DAI (另一种稳定币)
  • 总债务: $150 (100 USDC + 50 DAI)
  • 健康因子暴跌后降至0.95,进入可清算状态。

清算过程(Close Factor = 50%):

  1. 清算人不能直接清算“总债务的50%”(即$75)
  2. 清算人必须选择针对哪一笔具体的债务进行清算。
    • 选择A:清算USDC债务。
      • 可清算的最大USDC债务额度 = 100 USDC * 50% = 50 USDC
      • 清算人偿还50 USDC,并获得相应折扣的ETH抵押品。
      • 清算后:债务1变为 50 USDC,债务2仍为 50 DAI,总债务变为$100。
    • 选择B:清算DAI债务。
      • 可清算的最大DAI债务额度 = 50 DAI * 50% = 25 DAI
      • 清算人偿还25 DAI,并获得相应折扣的ETH抵押品。
      • 清算后:债务1仍为 100 USDC,债务2变为 25 DAI,总债务变为$125。
  3. 在偿还了部分债务后,借款人的健康因子会提升。如果健康因子恢复到1以上,清算就会停止。剩余的债务(包括未被清算的那一笔)仍然由借款人持有,需要继续管理或偿还。

2.6.2 计算清算的抵押物包含了(奖励和协议费用)

liquidationliquidation

collateralAmount = debtToCover * 债务资产价格(debt price) * (1 + 清算奖励率) / 抵押品资产价格(collateral price)

2.6.3 liquidate流程图

AAVE-v3-liquidateAAVE-v3-liquidate

2.6.4 关键步骤详解

根据上面的流程图,以下是各核心环节的详细说明:

  1. 入口函数:

    Pool.liquidationCall()

    • 位置
      protocol/pool/Pool.sol
    • 作用:清算人调用此函数来清算一个不健康的仓位。它进行基础验证后,会调用
      LiquidationLogic.executeLiquidationCall
  2. 核心逻辑:

    _executeLiquidationCall()

    • 位置

      protocol/libraries/logic/LiquidationLogic.sol

    • 作用:这是清算业务逻辑的核心,其目标是以有序的方式减少协议的风险敞口。关键步骤包括:

      • 验证健康因子:使用预言机价格计算用户的当前健康因子(Health Factor)。只有当

        HF < 1
        (或更严格的可配置阈值)时,清算才能进行。这是清算触发的最根本条件。

      • 计算可清算额度

        1. 理论最大债务清算额:根据协议参数(
          CloseFactor
          ,通常为50%),计算单次清算可覆盖的债务上限(
          debtToCover
          )。这防止了仓位被一次性完全清算,给了用户补救时间。
        2. 实际债务清算额:取
          min(清算人指定的debtToCover, 用户总债务, 基于抵押品价值计算的最大允许值)
      • 计算抵押品奖励

        • 这是清算人的盈利来源。根据公式计算清算人应获得的抵押品数量

          collateralAmount = debtToCover * 债务资产价格 * (1 + 清算奖励率) / 抵押品资产价格

        • 清算奖励率(Liquidation Bonus) 是一个关键参数,存储在抵押品资产的

          RserveConfiguration
          中。它激励清算人参与风险处置。

      • 执行资产交换(核心操作)

        • 偿还债务:调用
          _repay
          函数(即还款逻辑),使用清算人的资金偿还用户的指定债务。这会销毁用户的相应
          variableDebtToken
        • 获取抵押品:调用
          _withdraw
          函数(即提现逻辑),但接收者(
          to
          )是清算人
          ,将计算好的抵押品从用户的抵押品余额中扣除并转移给清算人。这本质上是将用户的抵押品
          aToken
          转移给了清算人。
      • 更新状态:更新用户的隔离模式债务状态(如果涉及),并重新计算其健康因子。

  3. 最终验证与事件

    • 健康因子改善验证:必须确保清算操作后,被清算用户的健康因子有所提高。这是清算操作有效的根本证明。
    • 隔离模式规则验证:如果债务资产处于隔离模式,则验证清算人获得的抵押品只能是该债务资产本身,防止风险扩散。
    • 发出
      LiquidationCall
      事件,包含清算人、被清算人、债务资产、清偿金额、抵押品资产、获得抵押品数量以及是否全额清算等关键信息。

2.7 FlashLoan

2.7.1 代码流程

AAVE-v3-flashLoanAAVE-v3-flashLoan

2.7.2 关键步骤详解

  • 根据上面的流程图,以下是各核心环节的详细说明:

    1. 入口函数:
      Pool.flashLoanSimple()
      • 位置
        protocol/pool/Pool.sol
      • 作用:用户(通常是另一个智能合约)调用此函数发起单资产的闪电贷。它进行基础验证后,会调用
        FlashLoanLogic.executeFlashLoanSimple
        。与多资产闪电贷(
        flashLoan
        )相比,此函数参数更简洁。
    2. 核心逻辑:
      _executeFlashLoan()
      • 位置
        protocol/libraries/logic/FlashLoanLogic.sol
      • 作用:这是闪电贷业务逻辑的核心,严格遵守“先发放,后验证”的模式。关键步骤包括:
        • 计算可贷额度与费用
          • 检查请求金额不超过该资产的可用流动性。可用流动性基于
            virtualUnderlyingBalance
            、总债务等计算得出。
          • 计算闪电贷费用(Premium)
            premium = amount * flashLoanPremiumTotal / 10000
            flashLoanPremiumTotal
            是存储在储备配置中的基数(如5表示0.05%),一部分给协议,一部分给流动性提供者。
        • 转移资产:将
          amount
          数量的底层资产直接转移给接收者合约
          receiver
          )。这是贷款发放。
        • 触发回调:调用接收者合约的
          executeOperation
          函数。这是闪电贷的核心:接收者合约在此函数中自由使用这笔资金(例如进行套利、交换、清算),但必须确保在函数结束前准备好归还资金。
        • 验证归还与收费
          • 在回调结束后,计算合约当前该资产的余额。
          • 验证余额至少达到了
            初始余额 + premium
            。这确保了本金和费用已被归还
          • 如果验证通过,将
            premium
            部分作为费用收取(更新
            accruedToTreasury
            liquidityIndex
            ,将费用分配给协议和流动性提供者)。
    3. 最终验证与事件
      • 验证资产余额恢复(这是最根本的安全检查)。
      • 发出
        FlashLoan
        事件,包含接收者地址、资产、金额、费用以及借款模式(简易模式)等关键信息。

三. 应用

3.1 多头杠杆交易

在AAVE V3上进行多头杠杆交易,核心是通过存入资产作为抵押品,借出更多资金并重复投入,以放大对同一资产或相关资产的价格上涨收益。

longlong

3.2 做空策略

在AAVE上进行做空(Short)策略,核心逻辑是:预期某个代币价格将下跌,通过AAVE借入该代币并立即卖出,等待其价格下跌后,用更少的钱买回并归还,赚取差价。 这与做多相反,是一种从资产价格下跌中获利的策略。

做空做空

3.3 Max Leverage (最大杠杆)

最大杠杆最大杠杆

Max LTV:指某一抵押品能借出的其他资产的最大价值比例。例如,如果ETH的Max LTV为80%,那么存入价值1000ETH,最多可以借出价值1000的ETH,最多可以借出价值800的其他资产

最大杠杆倍数 = 1 / (1 - Max LTV)

这个公式的推导逻辑是:在循环借贷策略中,你初始的1单位本金,通过“抵押→借款→再抵押”的循环,最终持有的总资产价值可以达到这个倍数。

理解最大杠杆时,必须纠正几个关键误解:

  1. 是理论极限,而非安全目标:达到最大杠杆意味着你的抵押率刚好等于Max LTV,此时健康因子为1,处于立刻被清算的边缘。任何微小的不利价格波动或利息累积都会触发清算。
  2. 实际安全杠杆远低于此:任何理性的杠杆操作者都会在健康因子低于1.5甚至2.0时就保持高度警惕,留出充足的安全缓冲。
  3. 依赖特定的风险参数:Max LTV由AAVE社区治理决定,可能因市场风险变化而调整。例如,在极端市场波动时,治理可能临时调低某资产的Max LTV以保护协议,这会导致使用该抵押品的所有杠杆头寸面临更高的清算风险。
最后更新: 2026年1月3日

评论区

发表评论

请先 登录 后再发表评论

请遵守相关法律法规,文明发言。评论将在审核后显示。

评论

还没有评论,来做第一个评论者吧!