Chi Li

Blockchain / Frontend Engineer

Aave Logo
Aave

Aave Liquidation Mechanism

When a position’s Health Factor drops below 1, it becomes eligible for liquidation. The Health Factor is calculated as:

HealthFactor=Total Collateral Value×Weighted Average Liquidation ThresholdTotal Borrow ValueHealth Factor = \frac{\text{Total Collateral Value} \times \text{Weighted Average Liquidation Threshold}}{\text{Total Borrow Value}}

The liquidation threshold is determined through Aave governance and varies for each asset (typically based on its risk profile). For example, if a user deposits $10,000 worth of ETH with an 80% liquidation threshold and borrows $6,000 worth of GHO, their Health Factor would be:

10,000×0.86,000=1.333\frac{10,000 \times 0.8}{6,000} = 1.333

As the Health Factor approaches 1, the risk of liquidation increases.

Liquidation is permissionless — anyone can liquidate an unhealthy position. When liquidation occurs, the liquidator repays either 50% or 100% of the borrower's debt. Additionally, the borrower incurs a liquidation penalty on their collateral.


Calculation Details

When calculating liquidation eligibility, the current Health Factor determines the liquidation ratio:

  • If 0.95 < Health Factor < 1, only 50% of the borrower's debt can be repaid.
  • If Health Factor 0.95, then 100% of the debt can be repaid.

During liquidation, the liquidator repays the borrower’s debt to claim their collateral. Additionally, a liquidation bonus is granted as a reward for the liquidator. So, the borrower's total loss equals:

Collateral Lost=Debt Repaid+Liquidation Bonus\text{Collateral Lost} = \text{Debt Repaid} + \text{Liquidation Bonus}

The liquidator’s profit:

Profit=Liquidation BonusProtocol FeeGas Costs\text{Profit} = \text{Liquidation Bonus} - \text{Protocol Fee} - \text{Gas Costs}

The liquidation bonus varies by asset and is also determined by Aave governance.


Liquidation Execution

As liquidation is permissionless, anyone can trigger it by calling the liquidationCall() function on the Pool contract. Liquidators can monitor on-chain positions for unhealthy Health Factors and execute liquidation when conditions are met.

To perform liquidation, the liquidator must have sufficient assets to repay the borrower's debt. If the borrower has multiple collateral types — e.g., A, B, and C tokens — backing a loan of token D, the liquidator can choose any one collateral type to repay against, as long as its value covers the liquidation amount.

For example: If a borrower has:

  • A token: $20
  • B token: $100
  • C token: $200

Borrowed: $100 of D token

A liquidator can choose to use $100 worth of A token to repay, seize the corresponding A token collateral (plus bonus), and typically picks the collateral with the highest liquidation bonus.


Safety Module

Bad debt is covered by the Safety Module.

In cases where collateral price drops too quickly for liquidators to react, resulting in bad debt, Aave’s Safety Module is designed to cover the shortfall. Token holders can stake AAVE, GHO, or ABPT tokens to secure the protocol.

If a shortfall occurs, staked tokens from the Safety Module are slashed to repay the debt. Stakers receive AAVE rewards as compensation, and the reward parameters are governed by Aave’s DAO.

When staking, users receive staking certificates (stkAAVE / stkABPT) as proof of deposit.


Price Oracle

To verify collateralization and Health Factors, Aave uses USD-based external price feeds from Chainlink Oracles. Chainlink is highly accurate and reliable, and is a preferred choice for many DeFi protocols.

Whenever borrow, repay, or liquidation operations occur, the Pool contract queries the Chainlink Oracle for the latest prices to check if positions qualify for liquidation.


Interest Rate Model

Borrowing Rate

Aave’s interest rate model uses a piecewise function (not a simple linear one). The rate increases slowly until it reaches an Optimal Utilization Rate (e.g., 90%), beyond which it rises sharply. Utilization UU is calculated as:

U=BorrowedBorrowed+Free DepositsU = \frac{\text{Borrowed}}{\text{Borrowed} + \text{Free Deposits}}

Where:

  • Borrowed = funds already loaned out
  • Free Deposits = unused supplied funds

At utilization rates above the optimal point (90%), the borrow rate increases rapidly to discourage over-borrowing and reduce bank-run risk.

Aave’s piecewise rate formula:

Rborrow={Rintercept+UUoptimal×Rslope1,UUoptimalRintercept+Rslope1+UUoptimal1Uoptimal×Rslope2,U>UoptimalR_{\text{borrow}} = \begin{cases} R_{\text{intercept}} + \frac{U}{U_{\text{optimal}}} \times R_{\text{slope1}}, & U \le U_{\text{optimal}} \\ R_{\text{intercept}} + R_{\text{slope1}} + \frac{U - U_{\text{optimal}}}{1 - U_{\text{optimal}}} \times R_{\text{slope2}}, & U > U_{\text{optimal}} \end{cases}

Where:

  • RborrowR_{\text{borrow}}: Current borrow rate
  • RinterceptR_{\text{intercept}}: Base rate (set by governance)
  • Rslope1R_{\text{slope1}}: Rate slope before optimal utilization
  • Rslope2R_{\text{slope2}}: Rate slope after optimal utilization

Diagram:

The chart illustrates the rate behavior before and after the optimal utilization point (e.g. 90%).

Use Case

Given:

Rintercept=0R_{\text{intercept}} = 0 Rslope1=0.04R_{\text{slope1}} = 0.04 Rslope2=0.75R_{\text{slope2}} = 0.75 Uoptimal=0.80U_{\text{optimal}} = 0.80
  • If U=20%U = 20\%
Rborrow=0+2080×0.04=0.01R_{\text{borrow}} = 0 + \frac{20}{80} \times 0.04 = 0.01

Borrow rate = 1%

  • If U=90%U = 90\%
Rborrow=0+0.04+0.900.8010.80×0.75=0.04+0.100.20×0.75=0.04+0.375=0.415R_{\text{borrow}} = 0 + 0.04 + \frac{0.90-0.80}{1-0.80} \times 0.75 = 0.04 + \frac{0.10}{0.20} \times 0.75 = 0.04 + 0.375 = 0.415

Borrow rate = 41.5%


Supply Rate

Once the borrow rate is calculated, the supply rate is derived simply by multiplying the borrow rate by utilization:

Rdeposits=Rborrow×UR_{\text{deposits}} = R_{\text{borrow}} \times U

This ensures all borrower-paid interest is fairly distributed to depositors (excluding protocol fees).

Example:

  • 10 users deposit 1 ETH each (total 10 ETH)
  • 5 ETH is borrowed at a 20% interest rate (U=50%U=50\%)
  • 5 ETH borrowed generates 1 ETH in interest
  • 1 ETH interest divided across 10 ETH → each ETH earns 0.1 ETH → 10% supply rate

Formula check:

10%=20%×50%10\% = 20\% \times 50\%

AToken

When a user deposits tokens, they receive aTokens (e.g. aETH) representing interest-bearing positions. aTokens are pegged 1:1 to the underlying asset. They allow users to freely transfer yield-bearing positions without withdrawing the actual asset — similar to Uniswap v3 position NFTs.

aToken Interest Accumulation

Aave updates aToken balances in real time by overriding the ERC20 balanceOf() function:

  1. Fetches user’s raw stored balance from a mapping
  2. Multiplies it by the Liquidity Index
  3. Returns the updated balance

The Liquidity Index increments every time a transaction affecting reserves occurs: supply, borrow, repay, withdraw, liquidate.

  • Index starts at 1.0
  • It increases cumulatively over time
Indexa,n=Indexa,n1×(1+r×t)\text{Index}_{a,n} = \text{Index}_{a,n-1} \times (1 + r \times t)

Use Case

Assuming historical annual interest rates:

MonthAnnual Rate
Month 112%
Month 26%
Month 38%

Liquidity Index Calculation:

MonthLiquidity Index
End of Month 11×(1+0.12/12)=1.011 \times (1 + 0.12/12) = 1.01
End of Month 21.01×(1+0.06/12)=1.01051.01 \times (1 + 0.06/12) = 1.0105
End of Month 31.0105×(1+0.08/12)=1.01131.0105 \times (1 + 0.08/12) = 1.0113

If a user deposits 10 ETH at the start:

MonthBalance
End of Month 110×1.01=10.110 \times 1.01 = 10.1 ETH
End of Month 210.1×1.0105=10.2010510.1 \times 1.0105 = 10.20105 ETH
End of Month 310.20105×1.0113=10.3134510.20105 \times 1.0113 = 10.31345 ETH

Code Architecture

Smart Contract System Diagram:

Pool

The core contract for every Aave market. Each token market (e.g. ETH, USDC) has its own Pool contract, responsible for:

  • supply() → mints aTokens
  • withdraw() → burns aTokens
  • borrow(), repay(), liquidate(), etc.

PoolAddressesProvider

Handles the configuration for the Pool contract:

  • Manages ACL roles
  • Links to the active Price Oracle
  • Supports Pool contract upgrades (upgradeable proxy pattern)

PoolAddressesProviderRegistry

Maps Pools to their corresponding PoolAddressesProvider using a mapping structure.

ACLManager

Access control contract based on OpenZeppelin’s AccessControl — defines multiple roles for protocol administration and risk management.


References