AgentSkillsCN

Aave V4 Risk Premium

当用户询问“风险溢价”、“抵押风险”、“用户风险溢价”、“溢价债务”、“溢价份额”、“抵押品质量”,或需要了解 Aave V4 基于风险的利率体系时,应选用此技能。

SKILL.md
--- frontmatter
name: Aave V4 Risk Premium
description: This skill should be used when the user asks about "risk premium", "collateral risk", "user risk premium", "premium debt", "premium shares", "collateral quality", or needs to understand Aave V4's risk-based interest system.
version: 0.1.0

Aave V4 Risk Premium

Aave V4 introduces a sophisticated Risk Premium system where borrowing costs depend on the quality of collateral used. Higher-quality collateral (like ETH) gets lower rates, while riskier collateral pays more.

Overview

code
┌──────────────────────────────────────────────────────────────┐
│                      RISK PREMIUM                            │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Interest Rate = Base Rate × (1 + User Risk Premium)         │
│                                                              │
│  Example:                                                    │
│  Base Rate = 5%                                              │
│  Risk Premium = 20% (0.20)                                   │
│  User Rate = 5% × 1.20 = 6%                                  │
│                                                              │
│  Collateral Quality Spectrum:                                │
│  ┌────────────────────────────────────────────────────────┐  │
│  │ ETH (CR=0)  ───────────────────────────  SHITCOIN (CR=1000_00)│
│  │ Low Risk                                High Risk       │  │
│  │ Low Premium                             High Premium    │  │
│  └────────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Key Concepts

Collateral Risk (CR)

Each asset has a Collateral Risk value (0 to 1000_00 BPS):

solidity
// Collateral Risk is per-reserve, per-Spoke
struct Reserve {
    // ...
    uint24 collateralRisk;  // 0 = highest quality, 1000_00 = lowest quality
}

// Examples:
// ETH:     CR = 0        (risk-free reference)
// wstETH:  CR = 5_00     (0.05% - very low risk)
// WBTC:    CR = 10_00    (0.10% - low risk)
// USDC:    CR = 0        (stablecoin - no risk premium)
// LINK:    CR = 50_00    (0.50% - moderate risk)
// NewToken: CR = 200_00  (2.00% - higher risk)

User Risk Premium (RP)

The User Risk Premium is a weighted average of Collateral Risk across the user's collateral:

code
RP_u = Σ(CR_i × CollateralValue_i) / Σ(CollateralValue_i)

Where the sum only includes enough collateral to cover the user's debt (sorted by risk, lowest first).

Risk Premium Algorithm

solidity
/// @notice Calculate user's risk premium
/// @dev Covers debt with lowest-risk collateral first
function _calculateUserRiskPremium(address user) internal view returns (uint24) {
    PositionStatus storage status = _positionStatus[user];

    // Get total debt value
    uint256 totalDebtValue = _getTotalDebtValue(user);
    if (totalDebtValue == 0) return 0;

    // Sort collateral by Collateral Risk (ascending)
    CollateralInfo[] memory collaterals = _getCollateralsSortedByRisk(user);

    // Iterate and cover debt with lowest-risk collateral first
    uint256 coveredDebt = 0;
    uint256 weightedRiskSum = 0;
    uint256 weightedValueSum = 0;

    for (uint256 i = 0; i < collaterals.length; i++) {
        uint256 remainingDebt = totalDebtValue - coveredDebt;
        if (remainingDebt == 0) break;

        uint256 collateralValue = collaterals[i].value;
        uint24 collateralRisk = collaterals[i].risk;

        if (remainingDebt >= collateralValue) {
            // Use full collateral
            weightedRiskSum += uint256(collateralRisk) * collateralValue;
            weightedValueSum += collateralValue;
            coveredDebt += collateralValue;
        } else {
            // Use partial collateral (just enough to cover debt)
            weightedRiskSum += uint256(collateralRisk) * remainingDebt;
            weightedValueSum += remainingDebt;
            coveredDebt += remainingDebt;
        }
    }

    // Calculate weighted average
    return uint24(weightedRiskSum / weightedValueSum);
}

Example Calculation

code
User Position:
- Debt: $10,000 USDC
- Collateral:
  - $8,000 ETH (CR = 0)
  - $5,000 LINK (CR = 50_00)
  - $3,000 NewToken (CR = 200_00)

Step 1: Sort by CR (ascending): ETH, LINK, NewToken
Step 2: Cover $10,000 debt:
  - Use $8,000 ETH (covers $8,000)
  - Use $2,000 LINK (covers remaining $2,000)

Step 3: Calculate weighted average:
  RP = (0 × $8,000 + 50_00 × $2,000) / $10,000
  RP = 100_000 / 10,000
  RP = 10_00 (0.10%)

User's borrow rate = Base Rate × (1 + 0.10%)

Premium Accounting

V4 tracks premium debt separately from base debt using shares and offsets:

Premium Structure

solidity
// In Hub (Asset-level)
struct Asset {
    uint256 premiumShares;      // Total premium shares across all Spokes
    uint256 premiumOffsetRay;   // Total premium offset (RAY)
}

// In Spoke (User-level)
struct UserPosition {
    uint256 premiumSharesRay;   // User's premium shares (RAY precision)
    uint256 premiumOffsetRay;   // User's premium offset (RAY)
}

Premium Offset Mechanism

At borrow time, premium shares are created with an offset that makes initial premium debt = 0:

solidity
// When borrowing:
function _addPremiumShares(
    UserPosition storage position,
    uint256 drawnShares,
    uint256 riskPremium
) internal {
    // Calculate premium shares = drawn shares × risk premium
    uint256 newPremiumShares = drawnShares.rayMul(riskPremium);

    // Get current premium share value in assets
    uint256 premiumAssetValue = _getPremiumAssetValue(newPremiumShares);

    // Set offset equal to asset value (so premium debt starts at 0)
    position.premiumSharesRay += newPremiumShares;
    position.premiumOffsetRay += premiumAssetValue;
}

Premium Debt Growth

code
Premium Debt = Premium Shares Value - Premium Offset

At borrow time:
  Premium Shares Value = X
  Premium Offset = X
  Premium Debt = X - X = 0

After time passes (interest accrues):
  Premium Shares Value = X × (1 + interest)
  Premium Offset = X (unchanged)
  Premium Debt = X × (1 + interest) - X = X × interest

Premium Delta

When repaying or refreshing premium, a PremiumDelta is used:

solidity
struct PremiumDelta {
    int256 sharesDelta;        // Change in premium shares
    int256 offsetRayDelta;     // Change in premium offset (RAY)
    uint256 restoredPremiumRay; // Premium amount being repaid (RAY)
}

// Example: Full premium repayment
PremiumDelta memory delta = PremiumDelta({
    sharesDelta: -int256(position.premiumSharesRay),
    offsetRayDelta: -int256(position.premiumOffsetRay),
    restoredPremiumRay: premiumDebt.rayMul(WadRayMath.RAY)
});

Risk Premium Updates

When Risk Premium Updates

The User Risk Premium is recalculated when:

  1. Borrow: New premium shares are added
  2. Repay: Premium shares may be reduced
  3. Collateral change: Enabling/disabling affects RP
  4. Price change: Oracle updates affect collateral values
  5. Manual update: updateUserRiskPremium()

Lazy Updates

For gas efficiency, V4 uses lazy updates - the RP isn't continuously updated:

solidity
/// @notice Permissionlessly update user's risk premium
function updateUserRiskPremium(address user) external {
    uint24 newRiskPremium = _calculateUserRiskPremium(user);

    // Refresh premium shares with new risk premium
    _refreshUserPremium(user, newRiskPremium);

    emit UpdateUserRiskPremium(user, newRiskPremium);
}

Forced Updates

Governance can force-update a user's risk premium:

solidity
/// @notice Governor can force update user's risk premium
function forceUpdateUserRiskPremium(address user) external restricted {
    uint24 newRiskPremium = _calculateUserRiskPremium(user);
    _refreshUserPremium(user, newRiskPremium);
}

Interest Model

Total Interest

code
User Borrow Rate = Base Rate × (1 + Risk Premium)

Where:
- Base Rate = f(utilization) [from Hub interest rate strategy]
- Risk Premium = User-specific based on collateral quality

Debt Composition

solidity
// Total Debt = Drawn Debt + Premium Debt

// Drawn Debt = principal + base interest
uint256 drawnDebt = position.drawnShares.rayMul(hub.getDrawnIndex());

// Premium Debt = risk premium interest
uint256 premiumDebt = position.premiumSharesRay.rayMul(hub.getDrawnIndex()) - position.premiumOffsetRay;

uint256 totalDebt = drawnDebt + premiumDebt;

Configuration

Setting Collateral Risk

solidity
struct ReserveConfig {
    uint24 collateralRisk;  // 0-1000_00 BPS
    // ... other fields
}

function updateReserveConfig(
    uint256 reserveId,
    ReserveConfig calldata config
) external restricted {
    Reserve storage reserve = _getReserve(reserveId);
    reserve.collateralRisk = config.collateralRisk;
    // ...
}

Risk Premium Threshold (Hub)

solidity
// Hub can set a max risk premium threshold
uint24 public constant MAX_RISK_PREMIUM_THRESHOLD = type(uint24).max;

// Used in validation
function _validateRiskPremium(uint24 riskPremium) internal view {
    require(riskPremium <= MAX_RISK_PREMIUM_THRESHOLD, ExcessiveRiskPremium());
}

Benefits

code
┌──────────────────────────────────────────────────────────────┐
│                 RISK PREMIUM BENEFITS                        │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  For Protocol:                                               │
│  • Accurately prices risk                                    │
│  • Attracts higher-quality collateral                        │
│  • Reduces systemic risk                                     │
│                                                              │
│  For Suppliers:                                              │
│  • Higher yields from risky collateral borrowers             │
│                                                              │
│  For Borrowers with Good Collateral:                         │
│  • Lower borrowing costs                                     │
│  • Incentive to use ETH/stables as collateral                │
│                                                              │
│  For Borrowers with Risky Collateral:                        │
│  • Fair pricing for risk taken                               │
│  • Still able to borrow (at higher cost)                     │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Events

solidity
event UpdateUserRiskPremium(address indexed user, uint24 riskPremium);
event UpdateReserveCollateralRisk(uint256 indexed reserveId, uint24 collateralRisk);

Reference Files

  • src/spoke/Spoke.sol - Risk premium calculations
  • src/hub/Hub.sol - Premium share accounting
  • src/hub/libraries/Premium.sol - Premium math utilities
  • src/spoke/libraries/UserPositionDebt.sol - User debt calculations
  • docs/overview.md - Risk premium algorithm