Skip to content

Latest commit

 

History

History
48 lines (39 loc) · 2.05 KB

File metadata and controls

48 lines (39 loc) · 2.05 KB

Festive Flaxen Raccoon

Medium

No check for stale price in "_parsePrices"

Summary

If there is a problem with Chainlink starting a new round and finding consensus on the new value for the oracle (e.g. Chainlink nodes abandon the oracle, chain congestion, vulnerability/attacks on the chainlink system) consumers of this contract may continue using outdated stale or incorrect data (if oracles are unable to submit no new round is started).

Vulnerability Detail

function _parsePrices( bytes32[] memory ids, bytes calldata data ) internal override returns (PriceRecord[] memory prices) { bytes[] memory verifiedReports = chainlink.verifyBulk{value: msg.value}( abi.decode(data, (bytes[])), abi.encode(feeTokenAddress) ); if (verifiedReports.length != ids.length) revert ChainlinkFactoryInputLengthMismatchError();

    prices = new PriceRecord[](ids.length);
    for (uint256 i = 0; i < verifiedReports.length; i++) {
        (bytes32 feedId, , uint32 observationsTimestamp, uint192 nativeQuantity, , , uint192 price) =
            abi.decode(verifiedReports[i], (bytes32, uint32, uint32, uint192, uint192, uint32, uint192));

        if (feedId != toUnderlyingId[ids[i]]) revert ChainlinkFactoryInvalidFeedIdError(feedId);

        prices[i] = PriceRecord(
            observationsTimestamp,
            Fixed18Lib.from(UFixed18.wrap(price)),
            _commitmentPrice(feedId, nativeQuantity)
        );
    }
}

Impact

stale or wrong price.

Code Snippet

https://github.com/sherlock-audit/2024-08-perennial-v2-update-3/blob/main/perennial-v2/packages/perennial-oracle/contracts/chainlink/ChainlinkFactory.sol#L57

Tool used

Manual Review

Recommendation

(bytes32 feedId, , uint32 observationsTimestamp, uint192 nativeQuantity, , , uint192 price) = abi.decode(verifiedReports[i], (bytes32, uint32, uint32, uint192, uint192, uint32, uint192));

require(price > 0, "Chainlink price <= 0"); require(observationsTimestamp != 0, "Incomplete round"); r