yy
medium
In the collateralFactor
function, rounding errors may occur due to the way Solidity handles integer division.
In collateralFactor
function, the function is multiplying and dividing by 1e18 and 1e6 which could lead to rounding errors due to the large discrepancy in scale between these numbers.
Here's an example:
suppose user has a collateral token with 9 decimals, and the balance of this token in the contract is 1 (which represents 0.000000001 token). The code (IERC20Upgradeable(collateral[i].token).balanceOf(address(this)) * 1e18)
would result in 1000000000 (which represents 0.000000001 token in 18 decimals).
However, when the function divide this by (10 ** IERC20MetadataUpgradeable(collateral[i].token).decimals()
), which is 1e9 in this case, the result will be 1 (which should represent 1 token in 18 decimals), not 0.000000001, because Solidity performs integer division and rounds down the result. So, the rounding error here is quite significant.
OR
The final division by totalSupply()
. If totalAssetsUSD * 1e6
is not an exact multiple of totalSupply()
, the result will be rounded down, which could lead to a small inaccuracy.
While these errors may seem small on a per-operation basis, they can add up over many operations and lead to significant discrepancies.
https://github.com/sherlock-audit/2023-05-USSD/blob/main/ussd-contracts/contracts/USSD.sol#L179
Manual Review
If possible, use consistent units across your contract. If you need to deal with different token decimals, consider standardizing everything to 18 decimals (which is the standard for many ERC20 tokens).