Submitted by Trust
The LibBytes library is used to read and store uint128 types compactly for Well functions. The function getBytes32FromBytes()  will fetch a specific index as bytes32.
If the index is out of bounds in the data structure, it returns ZERO_BYTES = bytes32(0). The issue is that the OOB check is incorrect. If index=data.length, the request is also OOB. For example:
data.length=0 -> array is empty, data[0] is undefined.
data.length=32 -> array has one bytes32, data[32] is undefined.
In other words, fetching the last element in the array will return whatever is stored in memory after the bytes structure.
Users of getBytes32FromBytes will receive arbitrary incorrect data. If used to fetch reserves like readUint128, this could easily cause severe damage, like incorrect pricing, or wrong logic that leads to loss of user funds.
The damage is easily demonstrated using the example below:
Calling corruption_POC with the following parameters:
The output bytes32 is:
The 0x20 value is in fact the size of the data2 bytes that resides in memory from the call to getBytes32FromBytes.
Change the logic to:
publiuss (Basin) confirmed, but disagreed with severity and commented:
alcueca (Judge) decreased severity to Medium and commented:
publiuss (Basin) commented:
