Skip to content

Latest commit

 

History

History
47 lines (26 loc) · 2.91 KB

045.md

File metadata and controls

47 lines (26 loc) · 2.91 KB

Tangy Coconut Crocodile

Medium

Sequencer set can be updated incorrectly

Summary

The missing check for stakerRankings to determine whether it is "0" in L2Staking.sol:176-178 will unnecessarily update the sequencer set in Sequencer.sol, which will result in incorrect sequencer sets in Sequencer.sol.

Root Cause

When a staker calls the internal function L1Staking.sol::removeStaker(), the _msgRemoveStakers function is executed, sending a message to L2 to inform that the sequencer is removed.

After the staker is removed, the same staker can still be removed from L2 if they are slashed and the slashed sequencer is that same sequencer. Since the L2 sequencer is already removed, or will be removed again, when L2Staking.sol::removeStakers() is called for the second time, the stakerRankings will be "0." Therefore, this check will always pass, unnecessarily updating the sequencer set, even though it shouldn't be updated because the sequencer was already removed during the first removal. This extra, unnecessary update of sequencers will modify the sequencerSets inside Sequencer.sol:86.

Internal pre-conditions

  1. Staker gets removed in L1 or withdraws its stake which sends the removeStakers message to L2
  2. Staker gets slashed and an another removeStakers message is sent to L2

External pre-conditions

none needed

Attack Path

Same as the internal pre-conditions. As long as the pre-conditions are met then the bug will exist without any additional change

Impact

The Sequencer.sol contract is responsible for storing data related to the sequencerSet. The L2 node reads the real-time changes in the contract to update the sequencerSet of the consensus layer. As a result, an incorrect update to the sequencerSet will alter the sequencer sets stored inside Sequencer.sol, leading to inaccurate sequencer sets being maintained in Sequencer.sol.

PoC

None needed

Mitigation

add the stakerRankings[remove[i]] != 0 check to L2Staking.sol:176-178:

if (stakerRankings[remove[i]] <= latestSequencerSetSize && stakerRankings[remove[i]] != 0) {
                updateSequencerSet = true;
 }