Platform: Code4rena
Start Date: 07/09/2022
Pot Size: $20,000 CANTO
Total HM: 7
Participants: 65
Period: 1 day
Judge: 0xean
Total Solo HM: 3
Id: 159
League: ETH
Rank: 40/65
Findings: 1
Award: $39.22
π Selected for report: 0
π Solo Findings: 0
π Selected for report: lukris02
Also found by: 0x040, 0x1f8b, 0x52, 0xA5DF, 0xNazgul, 0xSky, Bnke0x0, Bronicle, CertoraInc, Chom, CodingNameKiki, Deivitto, Diraco, Dravee, EthLedger, IgnacioB, JC, JansenC, Jeiwan, R2, RaymondFam, ReyAdmirado, Rolezn, SinceJuly, TomJ, Tomo, Yiko, a12jmx, ajtra, ak1, codexploder, cryptphi, csanuragjain, erictee, fatherOfBlocks, gogo, hake, hansfriese, hickuphh3, ignacio, ontofractal, oyc_109, p_crypt0, pashov, peritoflores, rajatbeladiya, rbserver, rokinot, rvierdiiev, tnevler
242.8216 CANTO - $39.22
Summary: Performing a multiplication after a division should be avoided as precision is lost in the division step.
Details: In order to minimize rounding errors, when performing mathematical operations, it is encouraged to leave the division step at the end of the expression.
Github Permalinks: https://github.com/code-423n4/2022-09-canto/blob/main/src/Swap/BaseV1-periphery.sol#L549-L593
Mitigation:
The current implementation of the computation at lines 581 to 585 can be mathematically written as follows:
which is equivalent to
Note that we can extract $10^{18}$ from the summation because it is constant. Moreover, if multiplying both the denominator and the numerator by $\text{decimals}$, we can do the same. This results in:
Moreover, if one checks that the number of decimals (let's call it $z$, so that $\text{decimals} = 10^{z}$) is less or equal than $18$, the above expression can be simplified to:
With this expression, one can reduce the amount of divisions performed and will most likely have a better rounding precision.
Moreover, at line 592, more simplifications can be done. The expression
can be rewritten as
which in turn equals
having thus
which might be a better implementation of the computations.