Solidity is a programming language for creating smart contracts on the Ethereum blockchain. Solidity uses fixed-point arithmetic, which means that numbers have a fixed number of decimal places. This can cause precision loss when performing division before multiplication, because the result may be rounded down to the nearest integer. 📉
For example, suppose we have the following expression:
However, solidity cannot store 0.5 as a fixed-point number, so it rounds it down to 0. Then, we multiply 0 by 8, and we get 0. This is a precision loss error, because we lost the fractional part of the result. 😕
To avoid this issue, it is better to perform multiplication before division, as long as the result does not exceed the limit of the data type. For example, we can rewrite the expression as:
$$
This way, we preserve the precision of the result, and we get the correct answer. 😊
Now, let's look at your code snippet:
https://github.com/Cyfrin/2023-12-the-standard/blob/main/contracts/LiquidationPool.sol#L220-L221
This code calculates the cost of an asset in euros, given some parameters. However, it performs division before multiplication, which can lead to precision loss errors. For example, if _portion
is 1, asset.token.dec
is 18, assetPriceUsd
is 100, priceEurUsd
is 100, _hundredPC
is 100, and _collateralRate
is 100, the expected result is 1, but the actual result is 0. 😢
To fix this issue, you can rearrange the expression to perform multiplication before division, as long as the result does not overflow the uint256
type. For example, you can rewrite the code as:
This way, you avoid the precision loss error, and you get the correct result. 😄
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.