The Oracle's tick cumulative calculation suffers from significant precision loss due to performing division before multiplication in integer arithmetic operations. This implementation can lead to substantial undervaluation of tick cumulative values, potentially affecting pricing and fee calculations.
The current implementation divides first, which can result in the quotient being rounded down to zero, especially when the difference between tick cumulatives is smaller than the observation time delta.
Proof Of Concept
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract OracleTest {
// Function to test precision loss
function test_precisionLoss() public {
uint beforeOrAtTickCumulative = 150000;
uint atOrAfterTickCumulative = 400000;
uint observationTimeDelta = 300000;
uint targetDelta = 250000;
uint tickCumulative_actual = beforeOrAtTickCumulative +
(((atOrAfterTickCumulative - beforeOrAtTickCumulative) / observationTimeDelta) * (targetDelta));
uint tickCumulative_precise = beforeOrAtTickCumulative +
(((atOrAfterTickCumulative - beforeOrAtTickCumulative) * targetDelta) / (observationTimeDelta));
emit TestResult(tickCumulative_actual, tickCumulative_precise);
}
event TestResult(uint tickCumulativeActual, uint tickCumulativePrecise);
}
// In the observeSingle function, modify the return statement to:
return (
beforeOrAt.tickCumulative +
((atOrAfter.tickCumulative - beforeOrAt.tickCumulative) * targetDelta) / observationTimeDelta,
beforeOrAt.secondsPerLiquidityCumulativeX128 +
uint160((uint256(atOrAfter.secondsPerLiquidityCumulativeX128 -
beforeOrAt.secondsPerLiquidityCumulativeX128) * targetDelta) / observationTimeDelta)
);
This modification ensures multiplication is performed before division, preserving precision in the calculation. The fix maintains the same mathematical logic while preventing potential undervaluation of tick cumulative calculations.
Even if this contract is out of scope, as you mentioned:
"If you discover a bug in any contract or library outside of the files listed above that impacts the following contracts, we will consider the issue valid:
Lines of code
https://github.com/ronin-chain/katana-v3-contracts/blob/03c80179e04f40d96f06c451ea494bb18f2a58fc/src/core/libraries/Oracle.sol#L231
Vulnerability details
Issue Details
The Oracle's tick cumulative calculation suffers from significant precision loss due to performing division before multiplication in integer arithmetic operations. This implementation can lead to substantial undervaluation of tick cumulative values, potentially affecting pricing and fee calculations.
Code part
https://github.com/ronin-chain/katana-v3-contracts/blob/03c80179e04f40d96f06c451ea494bb18f2a58fc/src/core/libraries/Oracle.sol#L231
Technical Analysis
Current Implementation
The current implementation divides first, which can result in the quotient being rounded down to zero, especially when the difference between tick cumulatives is smaller than the observation time delta.
Proof Of Concept
Results:
Recommended Solution
This modification ensures multiplication is performed before division, preserving precision in the calculation. The fix maintains the same mathematical logic while preventing potential undervaluation of tick cumulative calculations.
Even if this contract is out of scope, as you mentioned:
"If you discover a bug in any contract or library outside of the files listed above that impacts the following contracts, we will consider the issue valid:
So, this issue does apply.
Audit method
Manual Review
Assessed type
Math