The storeLastReserves
and readLastReserves
functions in the smart contract are handling storage and retrieval of reserve data using a bytes16 reserves, but due to the specific bit manipulation implemented, only 104 bits out of 128 are effectively utilized. This behavior results in a precision loss when storing what should be quadruple precision numbers (bytes16).
The functions are designed to store and read reserve data (quantities that should occupy 128 bits as per the bytes16
data type) but are instead treated as 104-bit values in the assembly code. Specifically, the bit manipulation operations in both storing and reading:
shl(104, shr(152, mload(add(reserves, 32))))
This line shifts the loaded bytes16 reserve right by 152 bits and then left by 104 bits, effectively truncating the last 24 bits of each bytes16 reserve.
mstore(add(reserves, 32), shl(152, shr(104, temp)))
Similar to the storing operation, this code discards the last 24 bits of the loaded data during the bit manipulation process, thereby not using the full precision of the bytes16 data type.
This reduction from 128 bits to 104 bits in handling reserves does not align with the intended use of bytes16 for storing quadruple precision floating-point numbers, leading to a loss of data precision.
Not using the full 128 bits of the bytes16 type, there is a significant loss of precision which could affect the price calculations (reserves, EMA, SMA ...).
Manual review
The bit manipulation logic should be revised to ensure that all 128 bits of the bytes16 data type are stored and retrieved without truncation. This can be achieved by adjusting the shift operations to accommodate the full bit length of the data type.
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.