zkSync Era - yashar's results

General Information

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

zkSync

Findings Distribution

Researcher Performance

Rank: 16/24

Findings: 1

Award: $565.16

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
edited-by-warden
:robot:_07_group
duplicate-97

Awards

565.1582 USDC - $565.16

External Links

Lines of code

https://github.com/code-423n4/2024-03-zksync/blob/4f0ba34f34a864c354c7e8c47643ed8f4a250e13/code/contracts/ethereum/contracts/state-transition/StateTransitionManager.sol#L166

Vulnerability details

Impact

This bug hampers the StateTransitionManager's ability to manage chain freezing.

Proof of Concept

In StateTransitionManager.sol there are two functions available to freeze and unfreeze a chain:

  1. freezeChain
/// @dev freezes the specified chain function freezeChain(uint256 _chainId) external onlyOwner { IZkSyncStateTransition(stateTransition[_chainId]).freezeDiamond(); }
  1. unfreezeChain
/// @dev freezes the specified chain function unfreezeChain(uint256 _chainId) external onlyOwner { IZkSyncStateTransition(stateTransition[_chainId]).freezeDiamond(); }

The problem is that both functions are calling freezeDiamond() which will freeze the chain. freezeDiamond():

function freezeDiamond() external onlyAdminOrStateTransitionManager { Diamond.DiamondStorage storage diamondStorage = Diamond.getDiamondStorage(); require(!diamondStorage.isFrozen, "a9"); // diamond proxy is frozen already diamondStorage.isFrozen = true; emit Freeze(); }

It means that if a chain gets freezed by StateTransitionManager or the Admin of a chain, StateTransitionManager won't be able to unfreeze the chain again.

Note that the admin of a chainId is able to call unfreezeDiamond directly from the Admin.sol facet, but this does not mitigate the bug in the unfreezeChain function. Despite the admin's capability to unfreeze the chain, the bug persists as the StateTransitionManager should adhere to the invariants by being able to both freeze and unfreeze a chain.

Tools Used

VSCode

diff --git a/StateTransitionManager.sol.orig b/StateTransitionManager.sol
index 0c27439..c74df7a 100644
--- a/StateTransitionManager.sol.orig
+++ b/StateTransitionManager.sol
@@ -161,9 +161,9 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own
         IZkSyncStateTransition(stateTransition[_chainId]).freezeDiamond();
     }
 
-    /// @dev freezes the specified chain
+    /// @dev unfreezes the specified chain
     function unfreezeChain(uint256 _chainId) external onlyOwner {
-        IZkSyncStateTransition(stateTransition[_chainId]).freezeDiamond();
+        IZkSyncStateTransition(stateTransition[_chainId]).unfreezeDiamond();
     }
 
     /// @dev reverts batches on the specified chain

Assessed type

Error

#0 - c4-judge

2024-04-02T17:03:09Z

alex-ppg marked the issue as duplicate of #97

#1 - c4-judge

2024-04-02T17:03:32Z

alex-ppg changed the severity to 3 (High Risk)

#2 - c4-judge

2024-04-29T13:51:53Z

alex-ppg changed the severity to 2 (Med Risk)

#3 - c4-judge

2024-04-29T13:54:00Z

alex-ppg marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter