The calculateDustAmount()
function in RToken.sol is designed to compute excess reserve tokens (dust) held beyond obligations and allow their transfer via transferAccruedDust()
. However, due to incorrect calculations other than relying on totalSupply()
being scaled twice, the function always returns zero, rendering the entire dust transfer mechanism non-functional.
This issue results in unclaimed excess funds accumulating indefinitely, preventing any dust from being transferred. While our proposed fix highlights the problem and revives the functionality, further refinements may be needed by the protocol team.
** calculateDustAmount()
**currently uses an incorrect logic to compare contractBalance
(tokens held in RToken.sol) against totalRealBalance
(expected obligations). However, totalSupply()
is already scaled by rayMul()
,
RToken.sol#L199-L205
but it is scaled again within calculateDustAmount()
, leading to a miscalculation.
Additionally, the liquidity buffer (typically 20% of totalLiquidity as frequently calibrated by LendingPool._rebalanceLiquidity()
for desredBuffer
) is ignored, preventing proper dust determination.
Consequently, the current check (that's already exacerbated by the aforementioned double scaling) always evaluates to 0
because contractBalance
is typically just the buffer amount whereas totalRealBalance
references total withdrawable underlying asset, making the dust amount non-existent.
Since calculateDustAmount()
always returns zero, transferAccruedDust()
in RToken.sol:
that's onlyReservePool
is never functional.
Because the returned dust amount is always zero, any attempt to call transferAccruedDust()
reverts with NoDust()
. This effectively renders the dust transfer system useless, allowing any excess reserve tokens to accumulate permanently.
Unclaimed excess reserve tokens: The inability to transfer dust results in the protocol losing access to unaccounted excess reserves, potentially impacting protocol efficiency.
Dead and misleading code: The presence of a non-functional dust transfer mechanism creates confusion and wasted execution paths.
Failed dust retrieval attempts: Any owner-initiated attempts to claim dust will always revert, making transferAccruedDust()
completely unusable.
Manual
Consider implementing the following refactoring (Note: It may not seem the correct fix because contractBalance
is typically 20% of reserve.totalLiquidity
whereas totalRealBalance
is the sacled total supply):
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.