Platform: Code4rena
Start Date: 07/03/2024
Pot Size: $250,000 USDC
Total HM: 5
Participants: 24
Period: 21 days
Judge: 0xsomeone
Total Solo HM: 3
Id: 347
League: ETH
Rank: 17/24
Findings: 1
Award: $565.16
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0x11singh99
Also found by: Bauchibred, Dup1337, Topmark, XDZIBECX, bctester, bin2chen, erebus, forgebyola, oakcobalt, rvierdiiev, yashar, zhanmingjing
565.1582 USDC - $565.16
There is a flaw in the contract with chain management logic. Specifically, in the functions freezeChain and unfreezeChain those functions are implemented with identical logic, both invoking the freezeDiamond() method on the IZkSyncStateTransition interface. and This results in an inability to unfreeze a chain once it has been frozen, as the intended mechanism to reverse a freeze operation unfreezeDiamond or equivalent is not called—indeed, it appears absent. the contract fails to provide a mechanism to unfreeze a chain once frozen. This misalignment between the function's name/intent and its actual behavior can lead to irreversible operational consequences.
this vulnerability could lead to the permanent cessation of operations on any chain managed by the contract. and This would disrupt all users and transactions associated with the frozen chain, potentially leading to financial losses,
Attack Scenario:
An attacker or even an admin with malicious intent, or an administrator making an operational mistake, could invoke the freezeChain function to halt all activities on a targeted chain. Due to the flawed implementation, legitimate users or administrators would find themselves unable to revert this state change, effectively locking the chain in a frozen state indefinitely.
i fuzz with scenario and a get this as result
class MockStateTransitionManager: def __init__(self): # Assuming chain states are either 'active' or 'frozen' self.chain_states = {} def freezeChain(self, chain_id): """Freezes the specified chain""" self.chain_states[chain_id] = 'frozen' def unfreezeChain(self, chain_id): """Unfreezes the specified chain - Incorrectly calls freezeChain's logic""" self.chain_states[chain_id] = 'frozen' # This should be 'active' to unfreeze def getChainState(self, chain_id): """Returns the state of the specified chain""" return self.chain_states.get(chain_id, 'active') # Default state is 'active' # Instantiate the mock contract mock_contract = MockStateTransitionManager() # Test the freeze and unfreeze functionality with a fuzzing approach # We'll vary the chain_id over a range to simulate different scenarios # The goal is to confirm if unfreezeChain effectively unfreezes a chain or not chain_states_before = {} chain_states_after_freeze = {} chain_states_after_unfreeze = {} for chain_id in range(1, 11): # Fuzzing with 10 different chain IDs # Initially record the chain state chain_states_before[chain_id] = mock_contract.getChainState(chain_id) # Freeze the chain mock_contract.freezeChain(chain_id) chain_states_after_freeze[chain_id] = mock_contract.getChainState(chain_id) # Attempt to unfreeze the chain mock_contract.unfreezeChain(chain_id) chain_states_after_unfreeze[chain_id] = mock_contract.getChainState(chain_id) (chain_states_before, chain_states_after_freeze, chain_states_after_unfreeze)
manual review
Updating the unfreezeChain function within the StateTransitionManager contract to call this new unfreezeDiamond() method.
Other
#0 - c4-judge
2024-04-02T17:02:06Z
alex-ppg marked the issue as duplicate of #97
#1 - c4-judge
2024-04-29T13:51:53Z
alex-ppg changed the severity to 2 (Med Risk)
#2 - c4-judge
2024-04-29T13:52:57Z
alex-ppg marked the issue as satisfactory