| name | Aave V3 eModes |
| description | This skill should be used when the user asks about "eMode", "efficiency mode", "correlated assets", "liquid eModes", "collateralBitmap", "borrowableBitmap", "EModeCategory", or needs to understand Aave V3 Efficiency Modes. |
| version | 0.1.0 |
Aave V3 Efficiency Modes (eModes)
eModes allow higher capital efficiency when borrowing correlated assets. Users in an eMode get better LTV and liquidation parameters for assets within that category.
Overview
┌──────────────────────────────────────────────────────────────┐
│ EFFICIENCY MODES │
├──────────────────────────────────────────────────────────────┤
│ │
│ eMode 0 (Default): │
│ • No special treatment │
│ • Uses standard LTV/LT per asset │
│ │
│ eMode 1 (e.g., "Stablecoins"): │
│ • Higher LTV (e.g., 97%) │
│ • Higher LT (e.g., 97.5%) │
│ • Only for correlated assets (USDC, DAI, USDT) │
│ │
│ eMode 2 (e.g., "ETH Correlated"): │
│ • Higher LTV (e.g., 93%) │
│ • For ETH and LSTs (wstETH, rETH, cbETH) │
│ │
└──────────────────────────────────────────────────────────────┘
EModeCategory Structure
struct EModeCategory {
uint16 ltv; // LTV for eMode collaterals
uint16 liquidationThreshold; // LT for eMode collaterals
uint16 liquidationBonus; // LB for eMode liquidations
uint128 collateralBitmap; // Which assets can be collateral in this eMode
uint128 borrowableBitmap; // Which assets can be borrowed in this eMode
string label; // Human-readable label
}
Liquid eModes (V3.2+)
V3.2 introduced "Liquid eModes" with major improvements:
Before V3.2 (Legacy)
- One asset → One eMode
- Assets had a single
eModeCategory in config
- Limited flexibility
After V3.2 (Liquid)
- One asset → Multiple eModes
- Assets can be collateral/borrowable in different eModes
- Controlled via bitmaps
┌──────────────────────────────────────────────────────────────┐
│ LIQUID eMODES │
├──────────────────────────────────────────────────────────────┤
│ │
│ Example Configuration: │
│ │
│ eMode 1: wstETH + weETH + WETH │
│ eMode 2: wstETH + WETH only │
│ eMode 3: weETH + WETH only │
│ eMode 4: WETH + GHO │
│ │
│ User A (holds wstETH & weETH) → enters eMode 1 │
│ User B (holds only wstETH) → enters eMode 2 │
│ User C (WETH collateral, GHO borrow) → enters eMode 4 │
│ │
└──────────────────────────────────────────────────────────────┘
Setting User eMode
// Set user's eMode category
function setUserEMode(uint8 categoryId) external {
EModeLogic.executeSetUserEMode(
_reserves,
_reservesList,
_eModeCategories,
_usersEModeCategory,
_usersConfig[msg.sender],
DataTypes.ExecuteSetUserEModeParams({
reservesCount: _reservesCount,
oracle: ADDRESSES_PROVIDER.getPriceOracle(),
categoryId: categoryId
})
);
}
// Get user's current eMode
function getUserEMode(address user) external view returns (uint256);
Entry/Exit Validation
// To enter an eMode:
// 1. Health factor must remain >= 1 after switch
// 2. All borrowed assets must be borrowable in the new eMode
// To leave an eMode (switch to 0):
// 1. Health factor must remain >= 1 after leaving
// Example validation:
function validateSetUserEMode(
mapping(address => DataTypes.ReserveData) storage reservesData,
mapping(uint256 => address) storage reservesList,
mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories,
DataTypes.UserConfigurationMap memory userConfig,
DataTypes.ExecuteSetUserEModeParams memory params
) external view {
// Check all borrowed assets are borrowable in new eMode
for each borrowed asset {
if (!EModeConfiguration.isReserveEnabledOnBitmap(
eModeCategories[params.categoryId].borrowableBitmap,
reserveId
)) {
revert(Errors.INCONSISTENT_EMODE_CATEGORY);
}
}
// Validate health factor after switch
validateHealthFactor(params.categoryId, ...);
}
Configuring eModes
Creating an eMode
// Via PoolConfigurator
function setEModeCategory(
uint8 categoryId,
uint16 ltv,
uint16 liquidationThreshold,
uint16 liquidationBonus,
string calldata label
) external onlyRiskAdmin;
// Example: Create stablecoin eMode
poolConfigurator.setEModeCategory(
1, // categoryId
9700, // LTV: 97%
9750, // LT: 97.5%
10100, // LB: 1% bonus
"Stablecoins"
);
Setting eMode Collaterals
// Set which assets can be collateral in an eMode
function setAssetCollateralInEMode(
address asset,
uint8 categoryId,
bool collateral
) external onlyRiskAdmin;
// Sets the corresponding bit in collateralBitmap
// Based on asset's reserve.id
Setting eMode Borrowables
// Set which assets can be borrowed in an eMode
function setAssetBorrowableInEMode(
address asset,
uint8 categoryId,
bool borrowable
) external onlyRiskAdmin;
// Sets the corresponding bit in borrowableBitmap
// Based on asset's reserve.id
Querying eMode Data
// Get eMode collateral config (LTV, LT, LB)
function getEModeCategoryCollateralConfig(uint8 id) external view
returns (DataTypes.CollateralConfig memory);
// Get eMode label
function getEModeCategoryLabel(uint8 id) external view returns (string memory);
// Get collateral bitmap
function getEModeCategoryCollateralBitmap(uint8 id) external view returns (uint128);
// Get borrowable bitmap
function getEModeCategoryBorrowableBitmap(uint8 id) external view returns (uint128);
// DEPRECATED: Legacy getter (still works for backwards compatibility)
function getEModeCategoryData(uint8 id) external view
returns (DataTypes.EModeCategoryLegacy memory);
EModeConfiguration Library
library EModeConfiguration {
/// @notice Check if a reserve is enabled in a bitmap
function isReserveEnabledOnBitmap(
uint128 bitmap,
uint256 reserveIndex
) internal pure returns (bool) {
return (bitmap >> reserveIndex) & 1 != 0;
}
/// @notice Set a reserve bit in a bitmap
function setReserveEnabledOnBitmap(
uint128 bitmap,
uint256 reserveIndex,
bool enabled
) internal pure returns (uint128) {
if (enabled) {
return bitmap | uint128(1 << reserveIndex);
} else {
return bitmap & ~uint128(1 << reserveIndex);
}
}
}
eMode in Health Factor Calculation
// In GenericLogic.calculateUserAccountData()
for each collateral asset {
if (EModeConfiguration.isReserveEnabledOnBitmap(
eModeCategories[userEModeCategory].collateralBitmap,
reserveId
)) {
// Use eMode LTV/LT
ltv = eModeCategories[userEModeCategory].ltv;
liquidationThreshold = eModeCategories[userEModeCategory].liquidationThreshold;
} else {
// Use standard asset LTV/LT
ltv = reserve.configuration.getLtv();
liquidationThreshold = reserve.configuration.getLiquidationThreshold();
}
totalCollateralBase += assetValue;
totalCollateralLTV += assetValue * ltv;
totalCollateralLT += assetValue * liquidationThreshold;
}
// Health Factor = totalCollateralLT / totalDebt
eMode Rules Summary
┌──────────────────────────────────────────────────────────────┐
│ eMODE RULES │
├──────────────────────────────────────────────────────────────┤
│ │
│ Collateral: │
│ • Positions can use ANY collateral in any eMode │
│ • eMode LTV/LT only applies to assets in collateralBitmap │
│ • Other collaterals use their standard LTV/LT │
│ │
│ Borrowing: │
│ • Can only borrow assets in the eMode's borrowableBitmap │
│ • For an asset to be borrowable in eMode, it must also │
│ be borrowable outside eMode │
│ │
│ Switching eModes: │
│ • Must maintain HF >= 1 after switch │
│ • All borrowed assets must be borrowable in new eMode │
│ │
│ eMode 0: │
│ • Special "no eMode" category │
│ • No eMode rules apply │
│ • All assets use standard parameters │
│ │
└──────────────────────────────────────────────────────────────┘
Common eMode Use Cases
| eMode | Assets | Use Case |
|---|
| Stablecoins | USDC, DAI, USDT | Stablecoin arbitrage, low-risk leverage |
| ETH Correlated | WETH, wstETH, rETH | LST leverage, yield farming |
| BTC Correlated | WBTC, cbBTC | BTC exposure optimization |
Events
// eMode category creation/update
event EModeCategoryAdded(
uint8 indexed categoryId,
uint256 ltv,
uint256 liquidationThreshold,
uint256 liquidationBonus,
string label
);
// Asset eMode configuration (V3.2+)
event AssetCollateralInEModeChanged(
address indexed asset,
uint8 categoryId,
bool collateral
);
event AssetBorrowableInEModeChanged(
address indexed asset,
uint8 categoryId,
bool borrowable
);
// User eMode change
event UserEModeSet(address indexed user, uint8 categoryId);
Reference Files
src/contracts/protocol/libraries/logic/EModeLogic.sol - eMode logic
src/contracts/protocol/libraries/configuration/EModeConfiguration.sol - Bitmap utilities
src/contracts/protocol/libraries/logic/GenericLogic.sol - Health factor with eModes
src/contracts/protocol/pool/Pool.sol - setUserEMode, getUserEMode
src/contracts/protocol/pool/PoolConfigurator.sol - eMode configuration