Summary
The calculateDustAmount()
scales contractBalance
incorrectly, leading to miscalculations in dust detection.
contractBalance
should not be scaled, as it is already the raw token balance of the contract.
This causes incorrect dust amount detection, potentially leading to incorrect fund management.
Vulnerability Details
function calculateDustAmount() public view returns (uint256) {
@> uint256 contractBalance = IERC20(_assetAddress).balanceOf(address(this)).rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
uint256 currentTotalSupply = totalSupply();
uint256 totalRealBalance = currentTotalSupply.rayMul(ILendingPool(_reservePool).getNormalizedIncome());
return contractBalance <= totalRealBalance ? 0 : contractBalance - totalRealBalance;
}
Incorrect Scaling of contractBalance
contractBalance
represents the raw ERC20 balance of the contract.
Calling .rayDiv(getNormalizedIncome())
incorrectly scales it down, leading to miscalculations.
Comparison Between Mismatched Values
contractBalance
(scaled incorrectly) is compared with totalRealBalance
(properly scaled).
This causes incorrect dust calculations, potentially misreporting the actual dust amount.
This will be damaged with transferAccruedDust().
Impact
transferAccruedDust() doesn't work properly and dust amount will be locked permanently
Tools Used
manual
Recommendations
Remove scaling of contractBalance
function calculateDustAmount() public view returns (uint256) {
// Calculate the actual balance of the underlying asset held by this contract
- uint256 contractBalance = IERC20(_assetAddress).balanceOf(address(this)).rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
+ uint256 contractBalance = IERC20(_assetAddress).balanceOf(address(this));
// Calculate the total real obligations to the token holders
uint256 currentTotalSupply = totalSupply();
// Calculate the total real balance equivalent to the total supply
uint256 totalRealBalance = currentTotalSupply.rayMul(ILendingPool(_reservePool).getNormalizedIncome());
// All balance, that is not tied to rToken are dust (can be donated or is the rest of exponential vs linear)
return contractBalance <= totalRealBalance ? 0 : contractBalance - totalRealBalance;
}