Curved Inky Ram
Medium
The validateSetUserEMode function does not check the user's supplied (collateral) assets against the new eMode category
The validateSetUserEMode function is designed to validate whether a user can switch their Efficiency Mode (eMode) category. eMode allows users to optimize their borrowing power by grouping assets into categories with correlated risk profiles. When a user selects an eMode category, it's expected that both their borrowed assets and collateral assets align with that category to benefit from optimized parameters (like higher Loan-to-Value ratios). The function allows users to change eMode categories without ensuring their supplied collateral assets are compatible.
function validateSetUserEMode( mapping(uint8 => DataTypes.EModeCategory) storage eModeCategories, DataTypes.UserConfigurationMap memory userConfig, uint256 reservesCount, uint8 categoryId ) internal view { DataTypes.EModeCategory storage eModeCategory = eModeCategories[categoryId]; // category is invalid if the liq threshold is not set require( categoryId == 0 || eModeCategory.liquidationThreshold != 0, Errors.INCONSISTENT_EMODE_CATEGORY );
// eMode can always be enabled if the user hasn't supplied anything
if (userConfig.isEmpty()) {
return;
}
// if user is trying to set another category than default we require that
// either the user is not borrowing, or it's borrowing assets of categoryId
if (categoryId != 0) {
unchecked {
for (uint256 i = 0; i < reservesCount; i++) {
if (userConfig.isBorrowing(i)) {
require(
EModeConfiguration.isReserveEnabledOnBitmap(eModeCategory.borrowableBitmap, i),
Errors.NOT_BORROWABLE_IN_EMODE
);
}
}
}
}
}
First, the function checks if the categoryId provided is valid. If categoryId is not zero (the default category), the function ensures that the eMode category has a non-zero liquidationThreshold. If the user has neither supplied nor borrowed any assets, the function allows setting any eMode category because there are no assets to validate against. For users changing to a non-default eMode category, the function checks each reserve (asset) to see if the user is borrowing it. If they are, it verifies that the asset is allowed (borrowable) in the new eMode category by inspecting the borrowableBitmap.
The issue is that the function does not check the user's supplied (collateral) assets against the new eMode category. The benefits of eMode (like higher borrowing power) are predicated on both the user's debt and collateral being within the same risk category. If users can have collateral assets outside the eMode category, they could exploit the system by enjoying higher borrowing power without the corresponding risk mitigation.
Example: User supplies Asset X (not part of eMode Category A) as collateral. Asset X has a lower liquidation threshold or higher risk profile. User changes their eMode to Category A without any checks on their supplied collateral. User borrows Asset Y (part of Category A) and benefits from enhanced borrowing parameters. If Asset X depreciates significantly, the user's position could become undercollateralized. The protocol has higher exposure to risk than intended for that eMode category
No response
No response
No response
No response
No response
Ensure that all assets the user is using as collateral are allowed in the new eMode category.