In Solidity, when performing division, the result is always truncated towards zero. This means that any fractional part of the result is discarded. Since Solidity does not support floating-point numbers, this can lead to precision loss, especially in financial calculations where exact amounts are crucial.
The getSharesByPooledEth
and getPooledEthByShares
functions in the provided smart contract perform such division operations:
In these functions, the multiplication is performed first, followed by the division. This order of operations is intentional to minimize precision loss, as multiplication can increase the value before division potentially reduces it. However, even with this approach, some precision loss is inevitable when the result of the division is not a whole number.
For example, if totalShares
is 1000 and totalPooledEther
is 3, calling getSharesByPooledEth(1)
would result in: 333.333
If assets do not balance as expected due to rounding down in the division, this effectively causes value to leak from the system. This could add up to a significant amount over thousands of transactions.
Manual Review
Use a higher base unit like Wei instead of Ether for calculations
Implement a fixed-point arithmetic library for divisions
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.