Core Contracts

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

RToken burn() Function Returns Incorrect Values Breaking Integration Assumptions

Summary

The RToken's burn() function returns incorrect values in its return tuple, not matching the expected return signature used by the ReserveLibrary. This creates inconsistencies between what integrating contracts expect to receive and what they actually get.

Vulnerability Details:

The RToken.burn() function returns values but not in the expected format, according the comments it should return

* @return A tuple containing:
* - uint256: The amount of scaled tokens burned
* - uint256: The new total supply after burning
* - uint256: The amount of underlying asset transferred
function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256) {
// ... burn logic ...
return (amount, totalSupply(), amount); // Wrong return values
}

The function should return:

  • First value: amountScaled (scaled amount being burned)

  • Second value: totalSupply

  • Third value: amount (underlying tokens)

But instead returns:

  • First value: amount (raw amount)

  • Second value: totalSupply

  • Third value: amount (same raw amount)

This impacts ReserveLibrary which expects to receive the scaled amount:

(uint256 burnedScaledAmount, uint256 newTotalSupply, uint256 amountUnderlying) = IRToken(
reserve.reserveRTokenAddress
).burn(...)

This propagates to lendingPool.withdraw

Impact:

MEDIUM. This causes:

  1. Wrong values being used in ReserveLibrary calculations

  2. Incorrect tracking of scaled vs unscaled amounts

  3. Potential accounting inconsistencies in the broader protocol

Tools Used:

Manual code review

Recommendations:

Fix return values in RToken.burn():

function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256) {
// ... burn logic ...
uint256 amountScaled = amount.rayDiv(index); // it should be rayDiv
// Return correct values:
return (amountScaled, totalSupply(), amount);
}

This ensures consistency between what the RToken returns and what integrating contracts expect to receive.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RToken::burn returns incorrect underlying asset amount (amount instead of amountScaled), leading to wrong interest rate calculations

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

RToken::burn returns incorrect underlying asset amount (amount instead of amountScaled), leading to wrong interest rate calculations

Support

FAQs

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