Core Contracts

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

Double rayDiv Application in RToken Transfer Functions Leads to Untransferable Token Remnants

Summary

The RToken contract has a critical accounting issue where tokens are scaled down twice during transfers, leading to untransferable remnants in user wallets.

// In RToken.sol
function transfer(address recipient, uint256 amount) public override returns (bool) {
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
return super.transfer(recipient, scaledAmount);
}
function _update(address from, address to, uint256 amount) internal override {
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
super._update(from, to, scaledAmount);
}

When a user transfers RTokens:

  1. User's balance appears correctly due to rayMul in balanceOf(), he will use this amount to interact with transfer()

  2. transfer() scales down amount by rayDiv

  3. _update() (called by super.transfer()) scales down the already scaled amount again by rayDiv

  4. It will transfer fewer tokens than what the user thought

The same issue exists within transferFrom

Vulnerability Details

Index is 1,1

  1. UserA has 100 RTokens

  2. UserB transfers 100 RTokens, using transfer(userA, 100)

  3. First rayDiv in transfer(): 100 -> 90

  4. Second rayDiv in _update(): 90 -> 81,8

  5. So the actual amount of wallet not scaled will be userA = 8,2 userB = 81,8, scaled userA = 9,02 userB = 89,98, it should be userA = 0 userB = 100

Impact

When a user wants to transfer a certain amount, he will always transfer less because the amount to transfer is scaled down two times.
Very bad UX and token will not work with other protocols as the results from transfer is not what is expected. EIP20 is not respected

Tools Used

Manual

Recommendations

Do not override transfer() and transferFrom() because scaling already happens in _update()

Updates

Lead Judging Commences

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

Give us feedback!