In Utils.sol
we have the following method
function calcLiquidityUnits(uint b, uint B, uint t, uint T, uint P) external view returns (uint){
if(P == 0){
return b;
} else {
// units = ((P (t B + T b))/(2 T B)) * slipAdjustment
// P * (part1 + part2) / (part3) * slipAdjustment
uint slipAdjustment = getSlipAdustment(b, B, t, T);
uint part1 = (t * B);
uint part2 = (T * b);
uint part3 = (T * B) * 2;
uint _units = (((P * part1) + part2) / part3);
return (_units * slipAdjustment) / one; // Divide by 10**18
}
}
If we just focus in the last two lines. We can see that we are running a division before a multiplication.
uint _units = (((P * part1) + part2) / part3);
return (_units * slipAdjustment) / one; // Divide by 10**18
Here we can see to examples of the importance of first multiple and then divide
uint _units = (((1 * 3) + 2) / 10); // _units = 0;
return (0 * 100) / 1 // we return 0
uint _units = ((1 * 3) + 2); // _units = 5;
return (5 * 100) / (1 * 10) // we return 50;
Solidity integer division might truncate. As a result, performing multiplication before division can sometimes avoid loss of precision.