Skip to content

Latest commit

 

History

History
68 lines (49 loc) · 2.21 KB

File metadata and controls

68 lines (49 loc) · 2.21 KB

Jolly Mauve Parakeet

Medium

oracle might be updated with not synced oracle provider

Summary

oracle might be updated with not synced oracle provider

Root Cause

According to readme

Yes - function behavior is defined in the natspec comments and if they pose integration risk we would like to be aware of that.

Only the admin can upgrade oracle, but he might forget to check it or something else.

Both the current and new oracle provider must have the same current

But there is no check that current and new provider have the same current.

    /// @notice Updates the current oracle provider
    /// @dev Both the current and new oracle provider must have the same current
    /// @param newProvider The new oracle provider
    function update(IOracleProvider newProvider) external onlyFactory {
        _updateCurrent(newProvider);
        _updateLatest(newProvider.latest());
    }

packages/perennial-oracle/contracts/Oracle.sol#L42

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

No response

Impact

provider might become out of sync

PoC

No response

Mitigation

Seems like it should look like this

    function _updateCurrent(IOracleProvider newProvider) private {
        // oracle must not already be updating
        if (global.current != global.latest) revert OracleOutOfSyncError();
+        if (oracles[global.current].provider.current() = newProvider.current()) revert OracleOutOfSyncError();

        // if the latest version of the underlying oracle is further ahead than its latest request update its timestamp
        if (global.current != 0) {
            OracleVersion memory latestVersion = oracles[global.current].provider.latest();
            if (latestVersion.timestamp > oracles[global.current].timestamp)
                oracles[global.current].timestamp = uint96(latestVersion.timestamp);
        }

        // add the new oracle registration
        oracles[++global.current] = Epoch(newProvider, uint96(newProvider.current()));
        emit OracleUpdated(newProvider);
    }