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

stuart_the_minion - The repaying function calculates interest rates with un-updated total debts values #284

Closed
sherlock-admin2 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-admin2
Copy link
Contributor

sherlock-admin2 commented Sep 10, 2024

stuart_the_minion

Medium

The repaying function calculates interest rates with un-updated total debts values

Summary

The Repaying function calculates interest rates with out-of-date total debts value

Vulnerability Detail

The interest rates updating step should be done as post-payment process for all pool operations except for flash loaning. (Check this comment)

Updating interest rates as a post-payment process facilitates reserves accruing borrow index with the latest borrow rate till the next pool operation.

And, as can be seen from the code snippet below, the updateInterestRates() function requires updated debt shares to calculate the borrow and interest.

  function updateInterestRates(
    ... ...
  ) internal {
    ... ...
    vars.totalDebt = _cache.nextDebtShares.rayMul(_cache.nextBorrowIndex); // <-- @audit Should use updated debt shares

    (vars.nextLiquidityRate, vars.nextBorrowRate) = IReserveInterestRateStrategy(_reserve.interestRateStrategyAddress)
      .calculateInterestRates(
        _position,
        _data,
        DataTypes.CalculateInterestRatesParams({
          liquidityAdded: _liquidityAdded,
          liquidityTaken: _liquidityTaken,
          totalDebt: vars.totalDebt,
          reserveFactor: _reserveFactor,
          reserve: _reserveAddress
        })
      );
    ... ...
  }

Meanwhile, the repayDebt() function subtracts debt shares from the total and position debt shares in proportion to the repaid assets amount.

  function repayDebt(
    DataTypes.PositionBalance storage self,
    DataTypes.ReserveSupplies storage supply,
    uint256 amount,
    uint128 index
  ) internal returns (uint256 sharesBurnt) {
    sharesBurnt = amount.rayDiv(index);
    require(sharesBurnt != 0, PoolErrorsLib.INVALID_BURN_AMOUNT);
    self.lastDebtLiquidtyIndex = index;
    self.debtShares -= sharesBurnt;
    supply.debtShares -= sharesBurnt;
  }

Therefore, calling the updateInterestRates() function before repayDebt() means that the un-deducted debt shares value is used to calculate the new interest rate, which will make a position to keep higher borrow rate till the next call.

Impact

The updating borrow interest rate with un-deducted debt shares will accrue the borrow index with the higher borrow rate till the next call.

Thus, a borrower or repayer of the next call will have to pay higher assets than expected, and such over-paying will decrease pool users' incentives.

Code Snippet

pool/logic/BorrowLogic.sol#L139-L152

Tool used

Manual Review

Recommendation

The updateInterestRates() function call should go after repayDebt():

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

    // update balances and total supplies
    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
    );

    ... ...
  }

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 Big Admiral Dove - The repaying function calculates interest rates with un-updated total debts values stuart_the_minion - The repaying function calculates interest rates with un-updated total debts values 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

2 participants