Open howlbot-integration[bot] opened 3 months ago
Confirming it works as described by the warden: Fixed.safeMulDiv()
for ROUND
rounds up too aggressively because the wrong c_256
value is used to compute the remainder.
Fortunately this does not impact any of the core contracts or live funds. However, the Fixed.sol
library is specifically listed as in-scope for the competition. Under a "Speculation on future code" assumption, there could be a future impact that could put funds at risk.
However: (i) this future code would need to be developed even though we have no expectations for it today; and (ii) funds would need to become at-risk as a result -- but the magnitude of the rounding effect is very small (1 wei) so it is not clear this would necessarily be the case.
Electing to confirm the bug at L severity, pending Judge approval.
No clear impact, will downgrade to Low. Similar judgment: https://github.com/code-423n4/2024-03-abracadabra-money-findings/issues/228#issuecomment-2039290802
thereksfour changed the severity to QA (Quality Assurance)
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/libraries/Fixed.sol#L561-L607
Vulnerability details
Impact
Fixed#safeMulDiv rounds incorrect when rounding mode is set to ROUND and functions closer to CEIL
Proof of Concept
For rounding to be accurate the unmodified divisor must be used to check the remainder of the division. Above we see that c_256 is divided by pow2 before being used to check mm (the remainder). Take the following example of c = 1e18:
pow2 = c & (0 - c) = 1000000000000000000 & (0 - 1000000000000000000) = 524288
c_256 = c_256/524288 = 19073486328125
As we can see the final c_256 is significantly lower than it should be. In this scenario, values greater than 499999999999999999 should be rounded up however, due to the error in implementation, values greater than 9536743164062 will be rounded up. To put that in decimal terms, that is 0.499999999999999999 vs 0.000009536743164062 which is a staggering difference. This effectively turns ROUND into CEIL.
Although safeMulDiv is not used with the ROUND rounding in the in-scope contracts, this math library is used across the entire protocol and will presumably be used during future upgrades as well.
We all know that rounding error, although they seems insignificant have lead to some very nasty exploits in defi. Any future update which utilizes this function to round for distribution of asset, pricing or share evaluation could cause loss of funds. In such situation, the incorrect rounding direction could cause incremental advantage to an attacker who could repeatedly exploit the rounding error to drain funds from the protocol. This risk is exponentially greater due to these contracts being deployed on low cost chains like base and OP.
Tools Used
Forge fuzz testing
Recommended Mitigation Steps
Use c rather than c_256 for checking the round:
Assessed type
Error