The RToken
contract's transfer
function incorrectly scales down the transfer amount twice, leading to users transferring significantly less than intended. This double scaling occurs because the user's balance gives underlying amount as transfer amount, and the transfer
function scales it down before calling the internal _update
function, which also scales it down.
The transfer
function in the RToken
contract has a critical flaw in its scaling logic:
Incorrect Initial Scaling: The transfer
function divides the amount
by the normalized income using rayDiv
. This is the inverse of what should happen. The amount
represents the user's intended transfer amount in underlying asset units. Since the user's amount
is in scaled down form, the amount
needs to be scaled up using rayMul
to get the correct scaled amount to transfer.
Double Scaling in _update
: The _update
function also scales the amount down by the normalized income. Because the amount
has already been incorrectly scaled down in the transfer
function, this second scaling results in a double scaling, drastically reducing the actual transfer amount.
Significant Loss of Funds: Users transfer a fraction of the amount they intend to, leading to a substantial loss of funds. The magnitude of the loss is directly related to the normalized income at the time of transfer.
Inconsistent State Changes: The double scaling can lead to inconsistent accounting within the contract, potentially causing issues with calculations with user balances.
Alice has a scaled balance of 110 RTokens (representing 100 underlying units with a normalized income of 1.1).
Alice wants to transfer 100 underlying units to Bob.
The transfer
function calculates scaledAmount = 100 / 1.1 = 90.91
(approximately). This is incorrect. It should be 100 * 1.1 = 110
.
The _update
function then calculates scaledAmount = 90.91 / 1.1 = 82.65
(approximately). This is the double-scaled amount.
Alice only transfers 82.65 RTokens to Bob, even though she intended to transfer 100.
Use this guide to intergrate foundry into your project: foundry
Create a new file FortisAudits.t.sol
in the test
directory.
Add the following gist code to the file: Gist Code
Run the test using forge test --mt test_FortisAudits_IncorrectTransferScalingInRToken -vvvv
.
Logs before the fix:
Logs after the fix:
The transfer
function should scale the amount
up by the normalized income using rayMul
before calling the super.transfer
function. This will ensure that the correct scaled amount is transferred.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.