Skip to content
This repository has been archived by the owner on Dec 17, 2023. It is now read-only.

sl1 - getPriceFromChainlink function in PriceOracle.sol does not check if the L2 sequencer is down. #23

Closed
sherlock-admin opened this issue Jun 11, 2023 · 0 comments
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue

Comments

@sherlock-admin
Copy link
Contributor

sherlock-admin commented Jun 11, 2023

sl1

medium

getPriceFromChainlink function in PriceOracle.sol does not check if the L2 sequencer is down.

Summary

When using Chainlink in L2 like arbitrum or optimism, it is important to make sure that prices are not falsly assumed fresh when the sequencer is down. This vulnerability could potentially be exploited by malicious users to gain unfair advantage.

Vulnerability Detail

No check here.

function getPriceFromChainlink(address base, address quote) internal view returns (uint256) {
        (, int256 price,,,) = registry.latestRoundData(base, quote);
        require(price > 0, "invalid price");

        // Extend the decimals to 1e18.
        return uint256(price) * 10 ** (18 - uint256(registry.decimals(base, quote)));
    }

Impact

Could potentially be exploited.

Code Snippet

https://github.com/sherlock-audit/2023-05-ironbank/blob/main/ib-v2/src/protocol/oracle/PriceOracle.sol#L66-L72

Tool used

Manual Review

Recommendation

The mitigation is to use the sequencer uptime feed to monitor the sequencer's online status and prevent consumption of price when the sequencer is offline.
Code from official chainlink docs:

constructor() {
        dataFeed = AggregatorV2V3Interface(
            0xC16679B963CeB52089aD2d95312A5b85E318e9d2
        );
        sequencerUptimeFeed = AggregatorV2V3Interface(
            0x4C4814aa04433e0FB31310379a4D6946D5e1D353
        );
    }

    // Check the sequencer status and return the latest data
    function getLatestData() public view returns (int) {
        // prettier-ignore
        (
            /*uint80 roundID*/,
            int256 answer,
            uint256 startedAt,
            /*uint256 updatedAt*/,
            /*uint80 answeredInRound*/
        ) = sequencerUptimeFeed.latestRoundData();

        // Answer == 0: Sequencer is up
        // Answer == 1: Sequencer is down
        bool isSequencerUp = answer == 0;
        if (!isSequencerUp) {
            revert SequencerDown();
        }

        // Make sure the grace period has passed after the
        // sequencer is back up.
        uint256 timeSinceUp = block.timestamp - startedAt;
        if (timeSinceUp <= GRACE_PERIOD_TIME) {
            revert GracePeriodNotOver();
        }

        // prettier-ignore
        (
            /*uint80 roundID*/,
            int data,
            /*uint startedAt*/,
            /*uint timeStamp*/,
            /*uint80 answeredInRound*/
        ) = dataFeed.latestRoundData();

        return data;
    }

https://docs.chain.link/data-feeds/l2-sequencer-feeds#example-code

Duplicate of #440

@github-actions github-actions bot added Medium A valid Medium severity issue Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label labels Jun 19, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Jun 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate A valid issue that is a duplicate of an issue with `Has Duplicates` label Medium A valid Medium severity issue Reward A payout will be made for this issue
Projects
None yet
Development

No branches or pull requests

1 participant