Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: low
Invalid

Index Mismatch in burn Function

Summary

The burn function updates the user's interest index to the parameter index instead of the current borrow index. If index is outdated, this allows the user to accrue interest incorrectly in subsequent interactions.

Vulnerability Details

function burn(
address from,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256, uint256) {
if (from == address(0)) revert InvalidAddress();
if (amount == 0) {
return (0, totalSupply(), 0, 0);
}
uint256 userBalance = balanceOf(from);
uint256 balanceIncrease = 0;
if (_userState[from].index != 0 && _userState[from].index < index) {
uint256 borrowIndex = ILendingPool(_reservePool).getNormalizedDebt();
balanceIncrease = userBalance.rayMul(borrowIndex) - userBalance.rayMul(_userState[from].index);
amount = amount;
}
_userState[from].index = index.toUint128();
if(amount > userBalance){
amount = userBalance;
}
uint256 amountScaled = amount.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
_burn(from, amount.toUint128());
emit Burn(from, amountScaled, index);
return (amount, totalSupply(), amountScaled, balanceIncrease);
}

When burning debt tokens (repaying debt), the contract updates the user's stored interest index to the index parameter passed into the function instead of the current borrow index. This creates a mismatch between the user's index and the protocol's actual state, leading to incorrect interest accrual in future interactions.

  • The borrow index (_usageIndex) tracks cumulative interest. For example:

    • Index starts at 1.0e27 (RAY).

    • After interest accrues, it increases to 1.1e27.

  • A user’s debt grows proportionally to the index increase since their last interaction.

  • When a user repays debt:

    1. Accrue interest up to the current index.

    2. Update the user’s index to the current index.

    3. Reduce their debt based on the updated balance.

The function burn uses the parameter index (which is incorrcet) to update the user’s index. if index is stale, the user’s index won’t reflect the latest interest accrual.

Example:

Current borrow index: 1.2e27.

User’s debt: 100 units (scaled balance: 100 / 1.2 ≈ 83.33).

User’s stored index: 1.1e27 (from a previous interaction).

The borrow index increases to 1.3e27.

The burn function is called with index = 1.2e27 (outdated).

The user’s index is updated to 1.2e27 instead of the current 1.3e27.

Next time the user interacts, their debt is calculated as:

scaledBalance * (currentIndex / userIndex)

If the index later rises to 1.4e27

Debt = 83.33 * (1.4e27 / 1.2e27) = 83.33 * 1.166... ≈ 97.22

But it should be:

Debt = 83.33 * (1.4e27 / 1.3e27) ≈ 83.33 * 1.076989.74

The user’s debt is overstated by **~7.48 tokens **because their index was not updated to the latest value during burning.

Impact

A malicious actor could front-run transactions to manipulate the index parameter, freezing users’ indices at advantageous values. Users will be charged interest for periods when they had already repaid debt, leading to unfair overpayment.

Tools Used

Foundry

Recommendations

function burn(...) external ... {
// Fetch the current index from the Reserve Pool
uint256 currentIndex = ILendingPool(_reservePool).getNormalizedDebt();
// Update user's index to the current index
_userState[from].index = currentIndex.toUint128(); // update here
Updates

Lead Judging Commences

inallhonesty Lead Judge
3 months ago
inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.