DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: medium
Valid

Sequencer uptime verification in KeeperProxy disrupts Multi-Chain compatibility

Summary

The L2 Sequencer is hardcoded in the KeeperProxy contract, and there is a check in KeeperProxy::_validatePrice that ensures the Sequencer is up. If it is not, the transaction is reverted. Since the L2 Sequencer is only used for protocols deployed on Ethereum's L2, when Gamma Liquidity deploys on the Avalanche blockchain, critical functions relying on _validatePrice will revert, compromising the proper operation of the protocol.

Vulnerability Details

The Chainlink documentation states the following about the L2 Sequencer:

Optimistic rollup protocols move all execution off the layer 1 (L1) Ethereum chain, complete execution on a layer 2 (L2) chain, and return the results of the L2 execution back to the L1. These protocols have a sequencer that executes and rolls up the L2 transactions by batching multiple transactions into a single transaction.

In other words, the L2 Sequencer should only be used when deploying to Ethereum L2. However, the KeeperProxy contract has the sequencer hardcoded in KeeperProxy::initialize:

Source code: KeeperProxy.sol#L48

function initialize() external initializer {
__Ownable2Step_init();
@> sequencerUptimeFeed = AggregatorV2V3Interface(0xFdB631F5EE196F0ed6FAa767959853A9F217697D);
}

The sequencerUptimeFeed is used in KeeperProxy::_validatePrice to check if the Sequencer is up. If not, the function will revert.

Source code: KeeperProxy.sol#L165

function _validatePrice(address perpVault, MarketPrices memory prices) internal view {
// L2 Sequencer check
(
/*uint80 roundID*/
,
int256 answer,
uint256 startedAt,
/*uint256 updatedAt*/
,
/*uint80 answeredInRound*/
) = AggregatorV2V3Interface(sequencerUptimeFeed).latestRoundData();
@> bool isSequencerUp = answer == 0;
@> require(isSequencerUp, "sequencer is down");
(...)

This means that when the protocol is deployed on Avalanche, the KeeperProxy::_validatePrice function will always revert, preventing crucial functions necessary for the project's operation, such as KeeperProxy::run and KeeperProxy::runNextAction, from executing. These two functions are responsible for opening/closing positions (KeeperProxy::run) and multi-step operations (KeeperProxy::runNextAction).

In the compatibility details provided by the project's developers, they clearly state that the project will be deployed on both Arbitrum and Avalanche.

## Compatibilities
Compatibilities:
Blockchains:
- Arbitrum / Avalanche
Tokens:
- WETH
- WBTC
- LINK
- USDC

Impact

The impact of this vulnerability is medium because it disrupts critical protocol functions on Avalanche, preventing key operations like opening/closing positions and executing multi-step actions. While funds are not directly at risk, the inability to perform essential tasks can lead to operational failures, reducing protocol reliability and user trust. The Likelihood is high since the _validatePrice function will always revert on Avalanche, but the severity can still be considered medium.

Tools Used

Manual Review.

Recommendations

It is recommended to remove the hardcoded Sequencer address from the contract and make it configurable. This can be achieved by adding a parameter in the initialize method to set the Sequencer address or by creating a setSequencerUptimeFeed function callable only by the owner. Additionally, introducing a boolean flag, such as checkSequencer in KeeperProxy::initialize, would allow disabling the Sequencer check in _validatePrice when deployed on Avalanche, ensuring that critical functions operate correctly across different blockchain environments.

Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_Avalanche_has_no_sequencer

Likelihood: High, run and runNextAction will revert. Impact: Low, any deposit will be retrieve thanks to cancelFlow.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!