calculateDustAmount function in RToken contract is defined as follows:
Multiple issues are combined, leading to a wrong calculation:
contracBalance is supposed to represent the actual balance of the underlying asset, but represents the scaled amount (i.e, the Rtoken amount). Indeed, balanceOf is overridden by RToken contract and returns the amount of underlying asset by calling super.balanceOf and multiplying by the liquidity index:
This is why calling balanceOf(address(this))and then dividing by the liquidity index is incorrect, as it sequentially unscales and scales, returning the RToken contract balance (not underlying asset).
currentTotalSupply returns the total supply of underlying asset. Indeed, totalSupply is also overridden and returns the total supply of RToken (scaled token), multiplied by the liquidity index to get the total supply of underlying asset (reserve asset). But calculateDustAmount assumes it returns the total supply of scaled token, as it then multiples currentTotalSupply by the liquidity index. The is incorrect as it leads to a double multiplication by the liquidity index.
In consequence, its highly probable that the following code will mostly return 0, given that contractBalance is scaled (Rtoken contract balance) and totalRealBalance has been multiplied by the liquidity index twice:
The impact of this issue is medium, as it leads to incorrect amounts of token transferred when removing accrued dust from RToken contract. This issue will lead to impossibility to remove the dust amount by the owner, especially when the liquidity index has grown over time (because totalRealBalance will be double scaled up with an index greater than 1, while contractBalance will be scaled down).
Manual review
Rectify the implementation of calculateDustAmount to make sure it computes token balances and supply with the right scale:
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.