Core Contracts

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

`RToken::transfer()` and `RTokne::transferFrom()` will double scale the amount

Summary

The RToken applies index scaling on each mint and burn action, by overwriting the ERC20 _update() function and applying rayDiv. This is to ensure proper deposit interest accrual. The contract also overwrites the transfer() and transferFrom() functions, where it also applies rayDiv to the amount. This leads to double scaling and invalid transfers.

Vulnerability Details

Let's look at the overwritten function:

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/tokens/RToken.sol#L212-L226

function transfer(address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
return super.transfer(recipient, scaledAmount);
}
/**
* @dev Overrides the ERC20 transferFrom function to use scaled amounts
* @param sender The sender address
* @param recipient The recipient address
* @param amount The amount to transfer (in underlying asset units)
*/
function transferFrom(address sender, address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
uint256 scaledAmount = amount.rayDiv(_liquidityIndex);
return super.transferFrom(sender, recipient, scaledAmount);
}

We can see that the amount is initially scaled and passed down to super.transfer/super.transferFrom functions. However, these functions invoke the _update() function as well, which here is overwritten to scale again:

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/tokens/RToken.sol#L307-L311

function _update(address from, address to, uint256 amount) internal override {
// Scale amount by normalized income for all operations (mint, burn, transfer)
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
super._update(from, to, scaledAmount);
}

From the above, we can see that when transfers occur, recipients will receive fewer tokens than intended.

Impact

Improper token transfers.

Tools Used

Manual review.

Recommendations

Remove the rayDiv scaling from the overwritten transfer and transferFrom functions in RToken.

Updates

Lead Judging Commences

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

RToken::transfer and transferFrom double-scale amounts by dividing in both external functions and _update, causing users to transfer significantly less than intended

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

RToken::transfer and transferFrom double-scale amounts by dividing in both external functions and _update, causing users to transfer significantly less than intended

Support

FAQs

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