Core Contracts

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

Missing User State Index Updates in RToken Transfer Functions Leads to Incorrect Interest Accrual

Summary

The RToken contract fails to update the user state indices during token transfers, which leads to incorrect interest calculations for users after token transfers occur. This breaks a core invariant of lending protocols where interest should accrue correctly regardless of token transfers.

Vulnerability Details

In the current implementation:
The RToken contract maintains user state indices in the _userState mapping:

mapping(address => UserState) private _userState;
struct UserState {
uint128 index;
}

This index is properly updated during mints and burns in RToken:

function mint(...) {
// ...
_userState[onBehalfOf].index = index.toUint128();
// ...
}
function burn(...) {
// ...
_userState[from].index = index.toUint128();
// ...
}

However, in the transfer functions (both the transfer and transferFrom), the indices are not updated:

function transfer(address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
uint256 scaledAmount = amount.rayDiv(
ILendingPool(_reservePool).getNormalizedIncome()
);
// @audit Missing: Should update _userState[msg.sender].index and _userState[recipient].index
return super.transfer(recipient, scaledAmount);
}

This causes two critical issues:

  • The sender's remaining tokens will accrue interest from their last index update, not from the transfer time

  • The recipient's received tokens will accrue interest from their existing index (or zero if first time), not from the transfer time

The core issue is that while the transfer amount is properly scaled, the user indices are not updated to reflect the new "checkpoint" time for interest calculations.

This breaks a fundamental invariant that Interest accrual should be accurate regardless of token transfers between users.

PoC

  1. Alice deposits 100 tokens, receiving 100 rTokens (index = 1.0)

  2. After some time, index increases to 1.1 (10% interest accrued)

  3. Alice transfers 50 rTokens to Bob

  4. After more time, index increases to 1.2

  5. Due to missing index updates:

    • Alice's remaining 50 tokens still accrue from index 1.0

    • Bob's 50 tokens accrue from index 0 (or his last stored index)

    • This leads to incorrect balances for both users

Impact

The missing index updates cause:

  • Incorrect interest accrual calculations

  • Users potentially earning more or less interest than they should

  • Breaking of core lending protocol accounting invariants

Tools Used

Manual review

Recommendations

Update the transfer and transferFrom functions to maintain indices:

function transfer(address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
uint256 currentIndex = ILendingPool(_reservePool).getNormalizedIncome();
uint256 scaledAmount = amount.rayDiv(currentIndex);
// Update indices for both parties
_userState[msg.sender].index = currentIndex.toUint128();
_userState[recipient].index = currentIndex.toUint128();
return super.transfer(recipient, scaledAmount);
}

Apply similar changes to transferFrom.

Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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