commitRequested() front-run malicious invalid oralce
Execution of the `commitRequested()` method restricts the `lastCommittedPublishTime` from going backward.\\n```\\n    function commitRequested(uint256 versionIndex, bytes calldata updateData)\\n        public\\n        payable\\n        keep(KEEPER_REWARD_PREMIUM, KEEPER_BUFFER, updateData, "")\\n    {\\n// rest of code\\n\\n      if (pythPrice.publishTime <= lastCommittedPublishTime) revert PythOracleNonIncreasingPublishTimes();\\n        lastCommittedPublishTime = pythPrice.publishTime;\\n// rest of code\\n```\\n\\n`commit()` has a similar limitation and can set `lastCommittedPublishTime`.\\n```\\n    function commit(uint256 versionIndex, uint256 oracleVersion, bytes calldata updateData) external payable {\\n        if (\\n            versionList.length > versionIndex &&                // must be a requested version\\n            versionIndex >= nextVersionIndexToCommit &&         // must be the next (or later) requested version\\n          oracleVersion == versionList[versionIndex]          // must be the corresponding timestamp\\n        ) {\\n            commitRequested(versionIndex, updateData);\\n            return;\\n        }\\n// rest of code\\n      if (pythPrice.publishTime <= lastCommittedPublishTime) revert PythOracleNonIncreasingPublishTimes();\\n      lastCommittedPublishTime = pythPrice.publishTime;\\n// rest of code.\\n```\\n\\nThis leads to a situation where anyone can front-run `commitRequested()` and use his `updateData` to execute `commit()`. In order to satisfy the `commit()` constraint, we need to pass a `commit()` parameter set as follows\\nversionIndex= nextVersionIndexToCommit\\noracleVersion = versionList[versionIndex] - 1 and oralceVersion > _latestVersion\\npythPrice.publishTime >= versionList[versionIndex] - 1 + MIN_VALID_TIME_AFTER_VERSION\\nThis way `lastCommittedPublishTime` will be modified, causing `commitRequested()` to execute with `revert PythOracleNonIncreasingPublishTimes`\\nExample: Given: nextVersionIndexToCommit = 10 versionList[10] = 200\\n_latestVersion = 100\\nwhen:\\nkeeper exexute commitRequested(versionIndex = 10 , VAA{ publishTime = 205})\\nfront-run execute `commit(versionIndex = 10 , oracleVersion = 200-1 , VAA{ publishTime = 205})\\nversionIndex= nextVersionIndexToCommit （pass）\\noracleVersion = versionList[versionIndex] - 1 and oralceVersion > _latestVersion (pass)\\npythPrice.publishTime >= versionList[versionIndex] - 1 + MIN_VALID_TIME_AFTER_VERSION (pass)\\nBy the time the `keeper` submits the next VVA, the price may have passed its expiration date
check `pythPrice` whether valid for `nextVersionIndexToCommit`\\n```\\n    function commit(uint256 versionIndex, uint256 oracleVersion, bytes calldata updateData) external payable {\\n        // Must be before the next requested version to commit, if it exists\\n        // Otherwise, try to commit it as the next request version to commit\\n        if (\\n            versionList.length > versionIndex &&                // must be a requested version\\n            versionIndex >= nextVersionIndexToCommit &&         // must be the next (or later) requested version\\n            oracleVersion == versionList[versionIndex]          // must be the corresponding timestamp\\n        ) {\\n            commitRequested(versionIndex, updateData);\\n            return;\\n        }\\n\\n        PythStructs.Price memory pythPrice = _validateAndGetPrice(oracleVersion, updateData);\\n\\n        // Price must be more recent than that of the most recently committed version\\n        if (pythPrice.publishTime <= lastCommittedPublishTime) revert PythOracleNonIncreasingPublishTimes();\\n        lastCommittedPublishTime = pythPrice.publishTime;\\n\\n        // Oracle version must be more recent than that of the most recently committed version\\n        uint256 minVersion = _latestVersion;\\n        uint256 maxVersion = versionList.length > versionIndex ? versionList[versionIndex] : current();\\n\\n        if (versionIndex < nextVersionIndexToCommit) revert PythOracleVersionIndexTooLowError();\\n        if (versionIndex > nextVersionIndexToCommit && block.timestamp <= versionList[versionIndex - 1] // Add the line below\\n GRACE_PERIOD)\\n            revert PythOracleGracePeriodHasNotExpiredError();\\n        if (oracleVersion <= minVersion || oracleVersion >= maxVersion) revert PythOracleVersionOutsideRangeError();\\n// Add the line below\\n       if (nextVersionIndexToCommit < versionList.length) {\\n// Add the line below\\n           if (\\n// Add the line below\\n               pythPrice.publishTime >= versionList[nextVersionIndexToCommit] // Add the line below\\n MIN_VALID_TIME_AFTER_VERSION &&\\n// Add the line below\\n               pythPrice.publishTime <= versionList[nextVersionIndexToCommit] // Add the line below\\n MAX_VALID_TIME_AFTER_VERSION\\n// Add the line below\\n           ) revert PythOracleUpdateValidForPreviousVersionError();\\n// Add the line below\\n       }\\n\\n\\n        _recordPrice(oracleVersion, pythPrice);\\n        nextVersionIndexToCommit = versionIndex;\\n        _latestVersion = oracleVersion;\\n    }\\n```\\n
If the user can control the oralce invalidation, it can lead to many problems e.g. invalidating `oracle` to one's own detriment, not having to take losses Maliciously destroying other people's profits, etc.
```\\n    function commitRequested(uint256 versionIndex, bytes calldata updateData)\\n        public\\n        payable\\n        keep(KEEPER_REWARD_PREMIUM, KEEPER_BUFFER, updateData, "")\\n    {\\n// rest of code\\n\\n      if (pythPrice.publishTime <= lastCommittedPublishTime) revert PythOracleNonIncreasingPublishTimes();\\n        lastCommittedPublishTime = pythPrice.publishTime;\\n// rest of code\\n```\\n