Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A2-security - Incorrect Interest Rate Update Leads to Inflated Rates and Potential Protocol Insolvency #405

Closed
sherlock-admin3 opened this issue Sep 10, 2024 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A High severity issue. Reward A payout will be made for this issue

Comments

@sherlock-admin3
Copy link
Contributor

sherlock-admin3 commented Sep 10, 2024

A2-security

High

Incorrect Interest Rate Update Leads to Inflated Rates and Potential Protocol Insolvency

Summary

A vulnerability in the executeRepay function of BorrowLogic.sol causes interest rates to be calculated incorrectly due to updating rates before modifying the debt. This results in inflated interest rates and an overstated liquidity index. leading to insolvency as non-existent debt shares are accounted for, risking the ability of depositors to withdraw their funds even if all debts are settled.

Vulnerability Detail

The executeRepay function in BorrowLogic.sol contains a critical flaw in how it updates interest rates, leading to overestimation of repayment impact:

function executeRepay(...) external returns (DataTypes.SharesType memory payback) {
// ...
reserve.updateInterestRates(totalSupplies, cache, params.asset, IPool(params.pool).getReserveFactor(), payback.assets, 0, params.position, params.data.interestRateData);
payback.shares = balances.repayDebt(totalSupplies, payback.assets, cache.nextBorrowIndex);
// ...
}
  • The issue arises from the sequence of operations:

    • updateInterestRates is called before modifying the cache.nextDebtShares.
    • repayDebt is called after updating interest rates, decreasing totalSupplies.debtShares.

This sequence results in the repaid amount being counted incorrectly in the interest rate calculation:

  • The interest rates are updated based on the old debt amount, not reflecting the repayment The debt is then decreased after the interest rate update, leading to a mismatch.

  • This incorrect ordering leads to an inflated borrowUsageRatio, resulting in higher interest rates than intended after repay operations.

  • Please note that the existence of this bug can be confirmed by comparing the repay logic with the borrow logic in BorrowLogic.sol.

function executeBorrow(...) public returns (DataTypes.SharesType memory borrowed) {
// ...
(isFirstBorrowing, borrowed.shares) = b.borrowDebt(totalSupplies, params.amount, cache.nextBorrowIndex);
cache.nextDebtShares = totalSupplies.debtShares;

reserve.updateInterestRates(totalSupplies, cache, params.asset, IPool(params.pool).getReserveFactor(), 0, params.amount, params.position, params.data.interestRateData);
// ...
}

In the borrow function, cache.nextDebtShares is modified before updating interest rates, and liquidityTaken is considered. This inconsistency between borrow and repay operations further highlights the flaw in the repay logic, regardless of the specific interest module implementation since they call the same function.

  • It's important to note that Zeroland is an Aave fork, and in Aave's implementation, debt shares are burned or minted before calling updateInterestRates(). This approach ensures that interest rate calculations are based on the most up-to-date debt state, avoiding the issues present in the current implementation.

Impact

The flaw in the executeRepay function leads to the overestimation of interest rates due to not reflecting the repayment in the debt amount (higher utilization ratio). This overestimation inflates the liquidity index with non-existent debt shares, causing insolvency. This means if all debts are repaid, there will not be enough liquidity to cover all depositors' withdrawals.

Code Snippet

Tool used

Manual Review

Recommendation

Update the interest rates after modifying the debt in the executeRepay function:

function executeRepay(...) external returns (DataTypes.SharesType memory payback) {
// prev code ....

+  payback.shares = balances.repayDebt(totalSupplies, payback.assets, cache.nextBorrowIndex);
+  cache.nextDebtShares = totalSupplies.debtShares;
  reserve.updateInterestRates(totalSupplies, cache, params.asset, IPool(params.pool).getReserveFactor(), payback.assets, 0, params.position, params.data.interestRateData);

- payback.shares = balances.repayDebt(totalSupplies, payback.assets, cache.nextBorrowIndex);

// same code ...
}

Duplicate of #413

@github-actions github-actions bot added Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A High severity issue. labels Sep 20, 2024
@sherlock-admin3 sherlock-admin3 changed the title Clever Ebony Halibut - Incorrect Interest Rate Update Leads to Inflated Rates and Potential Protocol Insolvency A2-security - Incorrect Interest Rate Update Leads to Inflated Rates and Potential Protocol Insolvency Oct 3, 2024
@sherlock-admin3 sherlock-admin3 added the Reward A payout will be made for this issue label Oct 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label High A High severity issue. Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant