Closed sherlock-admin closed 1 year ago
Although Chainlink's documentation is not clear here, the assumption is that the roundId within a phase is monotonically increasing and that non-monotonic increases only happen when the phase is updated.
This can be seen in the Chainlink aggregator cod here: https://etherscan.io/address/0xE62B71cf983019BFf55bC83B48601ce8419650CC#code#F8#L682 (note the ++
usage)
Perennial's oracles are designed to handle the non-monotonic increase when the phase changes.
bitsurfer
medium
Perennial
oracleVersion
increasing monotonic, while the Chainlink roundId may not be monotonicSummary
Perennial
oracleVersion
increasing monotonic, while the Chainlink roundId may not be monotonicVulnerability Detail
The Perennial protocol relies on storing historical data and fetching it from Chainlink using an identifier called
oracleVersion
. This oracleVersion is assumed to increase monotonically by 1, similar to theroundId
in Chainlink. However, it has been discovered that this assumption is incorrect.The issue arises from the fact that the
oracleVersion
in Perennial does not consistently increase by 1 for each new round of data fetched from Chainlink. This can lead to incorrect data associations and mismatches between the stored historical data and the corresponding Chainlink rounds.According to Chainlink documentation, https://docs.chain.link/data-feeds/historical-data#roundid-in-aggregator-aggregatorroundid
Here it mention about, the roundId increases may not be monotonic (increase).
Meanwhile, if we look at perennial's code, the
settleVersion
is increasing the oracleVersion (roundId) with 1 (for next settle txn)In cases where the pre-settle version does not match the current oracleVersion, the Perennial protocol will fetch the data using the
atVersion
function. This involves steps of loading, building data and fetching the ChainlinkgetRoundData
with the roundId corresponding to the oracleVersion of the pre-settle version.Impact
Perennial failed to fetch data from Chainlink when roundId is not monotonic increase
Code Snippet
https://github.com/sherlock-audit/2023-05-perennial/blob/main/perennial-mono/packages/perennial/contracts/interfaces/types/PrePosition.sol#L133-L136
Tool used
Manual Review
Recommendation
Implement a more reliable tracking mechanism for the
oracleVersion
, not just assuming it will increase +1 every roundId. Or utilizing a different identifier that ensures the correct association between stored historical data and Chainlink rounds.