Low deposited bean amounts are calculated and minted due to the priority of division over multiplication leading to a precision loss.
Solidity rounds down the result of an integer division, and because of that, it is always recommended to multiply before dividing to avoid that precision loss. In the case of a prior division over multiplication, the final result may face serious precision loss as the first answer would face truncated precision and then multiplied to another integer.
The problem arises in the addUnderlying()
function inside adding a fertilizer that is used to unripe beans and LPs.
This function first calculates the percentToFill
variable that would be used next in the calculation of the deposited bean and LP amounts.
If we look deeply at the function addUnderlying()
we can see the bean calculation procedure is presented as:
we can see there is a hidden division before a multiplication that makes rounding down the whole expression.
The newDepositedBeans
is calculated in the way that it multiplies the previous amount with the percentToFill
that actually has a division inside its heart.
This is bad as the precision loss can be significant, which leads to the minting less newDepositedBeans
than the actual.
At the Proof of Concept part, we can check this behavior precisely.
You can run this code to see the difference between the results:
Thus, we can see that the actual implementation produces fewer deposited beans than the precise method.
Minting less deposited bean amounts than the actual amount due to precision loss
Manual Review
Consider modifying the deposited beans calculation to prevent such precision loss and prioritize the multiplication over division:
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.