Closed sherlock-admin closed 11 months ago
3 comment(s) were left on this issue during the judging contest.
panprog commented:
invalid because it's not possible to rewrite the oracle version and there is no scenario given how the watson thinks this is possible
n33k commented:
invalid, overwriting committed versions will revert on 'if (versionIndex < nextVersionIndexToCommit) revert PythOracleVersionIndexTooLowError();'
polarzero commented:
High. It is hard to determine how much could be lost in this case, however it seems to be valid as a high severity issue, as the process to replicate it is easy and cheap enough, compared to the possible loss of funds for the users.
moneyversed
high
Oracle version data overwrite in
commitRequested
andcommit
due to absence of data lock mechanism for committed versions can result in a keeper intentionally input data for a prior version though a later version is already availableSummary
The
commitRequested
andcommit
functions in thePythOracle.sol
contract allow keepers to update price data for specific versions based on timestamps. A possible vulnerability lies in the logic that determines valid timestamps for which keepers can provide price updates.Vulnerability Detail
In the
PythOracle.sol
contract, the functionscommitRequested
andcommit
enable keepers to update price data based on specific version timestamps. These functions evaluate the legitimacy ofversionToCommit
ororacleVersion
timestamps through constraints defined byGRACE_PERIOD
,MIN_VALID_TIME_AFTER_VERSION
, andMAX_VALID_TIME_AFTER_VERSION
.The checks above are designed to prevent a newer version's publish time from falling within the valid time range of its preceding version. Notwithstanding, the contract lacks mechanisms to stop data overwriting once a particular version's data has been committed.
For instance, even considering the fact that both the interested functions do seem to ensure that the publish times of newer data are strictly after older data (
pythPrice.publishTime <= _lastCommittedPublishTime
), by guarding against data for future versions being backdated, though yet they do not manage to prevent older data from being overwritten by new data with a publish time that is also in the past but more recent than the original. Such an oversight permits a keeper to intentionally input data for a prior version even if a later version is already available, which can result in unauthorized data modification for the older version.Impact
Data tampering: This allows rogue keepers to alter price data for previous versions. Consequently, historical data, which may be integral to users, can be substituted with misleading data. Misrepresented data can cause significant disruptions in the financial domain.
Financial implications: Erroneous or manipulated Oracle data can lead to:
A bad actor can exploit this vulnerability with relative ease:
Keeper privileges: The actor would first need to obtain keeper privileges. Depending on the system's design, this could be relatively easy or hard.
Version manipulation: Once they have these privileges, they would:
GRACE_PERIOD
.commitRequested
orcommit
functions to supply manipulated data against an older version timestamp.GRACE_PERIOD
, the actor ensures that most systems querying the Oracle may still be fetching the older, now tampered, version.Though one might argue that such behavior would be quickly noticed and the malicious keeper would be penalized or blacklisted. However, even a short window of tampered data can wreak havoc in high-frequency trading systems or automated protocols. Further, if the malicious actor possesses a large stake in DeFi protocols or has taken substantial positions in markets, they could benefit immensely from such data manipulation, even if it's for a brief period. Their consequent profits may far outweigh any penalties.
Code Snippet
The vulnerability is located in the
commitRequested
andcommit
functions:PythOracle.sol#L148-L158
Tool used
Manual review.
Recommendation
consider implementing the following changes:
Within the
commitRequested
andcommit
functions, add a check before accepting any data:After data for a version is successfully committed, lock the version:
Implement data overwrite checks: In conjunction with the lock mechanism, ensure that once a version's data is committed, it remains unaltered. The locking mechanism above essentially covers this recommendation.
Logging and monitoring: To ensure transparency and accountability, enhance logging by adding more details about data submissions, such as the sender's address, the version, and the timestamp.
Emit this event every time new data is successfully committed:
Implement monitoring solutions off-chain to track these logs and flag any suspicious patterns or anomalies.
Incorporating these changes will be making
PythOracle.sol
resistant to the described concern and offering more transparency in data submissions.POC
Initialization: Deploy the
PythOracle.sol
contract and, as the trusted admin, initialize the Oracle with the necessary parameters.New version request: As a keeper, call the
request
function to generate a new version timestamp.Wait: Ensure you wait for a duration less than
GRACE_PERIOD
.GRACE_PERIOD
.Malicious data submission: As the same keeper, call the
commitRequested
orcommit
function with a valid, older timestamp that already has data. Provide manipulated data for this version.Querying data: Users querying the Oracle for this version now receive the manipulated data instead of the original data.
Let's modify and create a specific
it
test case in thePythOracle.test.ts
to show this exploit accordingly.Here's how we can incorporate this into the
PythOracle.test.ts
:GRACE_PERIOD
.commit
function with an olderversionIndex
but a more recentpublishTime
.The test then asserts that the
latest
price fetched from the oracle is no longer the original price of the first version but is the manipulated price, thus demonstrating the vulnerability. This clearly outlines how a rogue keeper may manipulate the existing logic to supply deceptive or tampered data for earlier versions. Following these steps will validate and reproduce the intended behavior.