Full Report
Aave is a very common loan protocol in the web3 space. Liquidation is the process of getting back the tokens of a loan in exchange for a discounted rate on the users collateral. For instance, imagine I took out a loan for 1 ETH for 2000 USDC with a threshold of 10% (USDC to ETH is probably around 1800). If I wasn't repaying my interest or the cost of USDC dropped,another user could come in to supply the 1ETH and get 1850 USDC back for this. This keeps the protocol solvant. e-mode (efficiency mode) is an asset that is consistent in price with a pegged value, like USDC. When getting the price of user assets, the program will check to see if the price should be gotten from the default location or the e-mode location. This is done by passing in the collateralPriceSource and debtPriceSource variables. The assumption is that the debtPriceSource should be the price source for the e-mode category. This is imposed by the restriction that if a user is in e-mode, they should only be able to borrow assets that belong to this users e-mode. Can this be violated? If the following situation occurs, this can be violated: E-mode is using a custom oracle. The debt asset that is liquidated has been removed from e-mode. What's the consequence of this? The calculations get messed up on the liquidation process. Because the user being in an e-mode state is checked while adding the tokens, the logic explained above takes a weird turn. It will get the wrong price as a result. The e-mode price returns a nice pegged value, which is much cheaper than using an oracle like chainlink. If USDC was depegged from $1 to $2, then the liquidator would only get half of what they deserve. If it depegged from $1 to $0.5, they would get double they deserve. This is a pretty drastic consequence, especially with large loans. To fix this issue, the e-mode price should only be used if the e-mode flag on both the user and the oracle is set. This felt like a reasonable optimization but the complicated system led to this issue. To me, a single thing stands out: this is a completely crazy situation that the author of this conjured up. However, this is a legit scenario that could happen with an admin acting in a sane manner. Did they see the separation between the user e-mode flag and the oracle e-mode flag and come up with this?
Analysis Summary
# Vulnerability: Aave v3 Incorrect Price Source During E-Mode Liquidation
## CVE Details
- **CVE ID**: N/A (Disclosed via BGD Bug Bounty Program)
- **CVSS Score**: Not officially scored (Estimated High Severity based on potential for bad debt/protocol insolvency)
- **CWE**: CWE-684: Incorrect Provision of Specified Functionality
## Affected Systems
- **Products**: Aave v3 Core
- **Versions**: Versions prior to v3.0.2
- **Configurations**: User must be in Efficiency Mode (e-mode) using a category with a custom oracle, and a debt asset must have been recently removed from that e-mode category.
## Vulnerability Description
The flaw resides in the `LiquidationLogic.executeLiquidationCall` and specifically the `_getConfigurationData` internal function. In Aave v3, "Efficiency Mode" (e-mode) allows higher borrowing power for correlated assets (e.g., stablecoins).
The protocol made a logical assumption that if a user is in e-mode, their debt assets *must* belong to that same e-mode category. Consequently, if the category uses a custom oracle, the code automatically applied that oracle’s price to the debt asset.
However, an edge case exists: if an admin removes an asset from an e-mode category (for instance, due to a depeg or risk shift), a user already holding that debt remains in e-mode. During liquidation, the protocol continues to use the e-mode's "pegged" custom oracle price for the debt instead of the asset's actual market price (e.g., Chainlink feed), because the check for the user's e-mode status takes precedence over checking if the specific asset is still within that category.
## Exploitation
- **Status**: Disclosed via Bug Bounty; No known exploitation in the wild. PoC submitted to Aave team.
- **Complexity**: High (Requires specific admin actions and market conditions).
- **Attack Vector**: Network (Smart Contract Interaction).
## Impact
- **Confidentiality**: None
- **Integrity**: High (Collateral/Debt price calculations are incorrect).
- **Availability**: Low (Can lead to protocol insolvency if liquidations are ignored).
If a debt asset (e.g., USDC) depegs from its e-mode fixed price:
1. **Underpricing**: If the market price is higher than the oracle price, liquidators are under-incentivized, leading to "bad debt."
2. **Overpricing**: If the market price is lower than the oracle price, liquidators receive significantly more collateral than they should, draining value from the borrower and the protocol.
## Remediation
### Patches
- The issue was officially resolved in **Aave v3.0.2**.
- The fix involves validating that the e-mode price source is only used if the specific asset's e-mode category matches the user's e-mode category at the time of liquidation.
### Workarounds
- There are no direct user-side workarounds. Protocol risk managers can mitigate this by ensuring assets are not removed from e-mode categories while significant debt positions remain open, or by updating the e-mode oracle simultaneously.
## Detection
- **Indicators of Compromise**: Liquidation events where the `debtPriceSource` does not match the standard market oracle for the asset.
- **Detection Methods**: Monitor smart contract events for differences between `eModePriceSource` and the default asset price feeds during liquidation calls.
## References
- **Vendor Advisory**: [https://governance.aave.com/t/bgd-bug-bounties-proposal/13077](https://governance.aave.com/t/bgd-bug-bounties-proposal/13077)
- **Technical Breakdown**: [https://stermi.xyz/blog/aave-bug-bounty-wrong-debtprice-in-liquidation-emode](https://stermi.xyz/blog/aave-bug-bounty-wrong-debtprice-in-liquidation-emode)
- **Vulnerable Code**: [https://github.com/aave/aave-v3-core/blob/94e571f3a7465201881a59555314cd550ccfda57](https://github.com/aave/aave-v3-core/blob/94e571f3a7465201881a59555314cd550ccfda57)