Core Contracts

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

Incorrect amount to burn in RToken::burn leads to accounting inconsistencies

Summary

The function incorrectly burns the underlying asset amount (crvUSD) instead of the properly scaled RToken amount, potentially leading to significant economic vulnerabilities in the protocol.

Vulnerability Details

In the following parts of the burn() function, it does not handle the conversion between RTokens (interest-bearing tokens) and the underlying asset (crvUSD). RTokens represent a claim on an increasing amount of the underlying asset due to accrued interest, which is tracked through the liquidity index. The current implementation ignores this relationship when burning tokens.

_burn(from, amount.toUint128()); // Burns crvUSD amount instead of RToken amount
return (amount, totalSupply(), amount); // Returns unscaled amount instead of scaled in the first return paramter

Impact

  • Incorrect burning of RTokens leads to wrong total supply

  • Mismatch between burned RTokens and transferred underlying assets

  • Broken relationship between RToken supply and underlying asset reserves

  • Over time, the cumulative effect of incorrect burns could lead to protocol insolvency

Tools Used

Manual Code Review

Recommendations

Use amountScaled to burn and correct the first return value:

function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256) {
if (amount == 0) {
return (0, totalSupply(), 0);
}
uint256 userBalance = balanceOf(from);
_userState[from].index = index.toUint128();
if(amount > userBalance){
amount = userBalance;
}
uint256 amountScaled = amount.rayMul(index);
_userState[from].index = index.toUint128();
_burn(from, amount.toUint128());
if (receiverOfUnderlying != address(this)) {
- IERC20(_assetAddress).safeTransfer(receiverOfUnderlying, amount);
+ IERC20(_assetAddress).safeTransfer(receiverOfUnderlying, amountScaled);
}
emit Burn(from, receiverOfUnderlying, amount, index);
- return (amount, totalSupply(), amount);
+ return (amountScaled, totalSupply(), amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 4 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

RToken::burn incorrectly burns amount (asset units) instead of amountScaled (token units), breaking token economics and interest-accrual mechanism

inallhonesty Lead Judge 4 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

RToken::burn incorrectly burns amount (asset units) instead of amountScaled (token units), breaking token economics and interest-accrual mechanism

Support

FAQs

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