Platform: Code4rena
Start Date: 28/10/2022
Pot Size: $165,500 USDC
Total HM: 2
Participants: 24
Period: 12 days
Judge: GalloDaSballo
Total Solo HM: 1
Id: 177
League: ETH
Rank: 13/24
Findings: 1
Award: $250.77
🌟 Selected for report: 0
🚀 Solo Findings: 0
250.7706 USDC - $250.77
https://github.com/code-423n4/2022-10-zksync/blob/main/ethereum/contracts/zksync/DiamondInit.sol#L25 https://github.com/code-423n4/2022-10-zksync/blob/main/ethereum/contracts/zksync/facets/DiamondCut.sol#L106
As stated in the Github repo documentation, there are 3 steps to a system upgrade in the `DiamondCutFacet.sol'.
proposeDiamondCut
function.approveEmergencyDiamondCutAsSecurityCouncilMember
function.executeDiamondCutProposal
functionThe problem is that the security council members are never added in DiamondInit.sol
initialize
function or anywhere else in the code base. The securityCouncilMembers
mapping is never modified making it impossible to perform upgrades/adding or deleting new diamond cut facets in the correct manner.
https://github.com/code-423n4/2022-10-zksync/blob/main/ethereum/contracts/zksync/DiamondInit.sol#L25
Manual code review
Security council members should be added when the initialize
function is called in DiamondInit.sol
function initialize( Verifier _verifier, address _governor, address _validator, bytes32 _genesisBlockHash, uint64 _genesisIndexRepeatedStorageChanges, bytes32 _genesisBlockCommitment, IAllowList _allowList, VerifierParams calldata _verifierParams, bool _zkPorterIsAvailable, bytes32 _l2BootloaderBytecodeHash, bytes32 _l2DefaultAccountBytecodeHash, + address[] _securityCouncilMembers ) external reentrancyGuardInitializer returns (bytes32) { s.verifier = _verifier; s.governor = _governor; s.validators[_validator] = true; // mapping(address => bool) securityCouncilMembers; + require(_securityCouncilMembers.length > 0, "Add security council"); + for (uint256 i = 0; i < _securityCouncilMembers.length; i++) { + + address councilMember = _securityCouncilMembers[i]; + require(councilMember != address(0), "Zero Address"); + s.diamondCutStorage.securityCouncilMembers[councilMember] = true; + } // We need to initialize the state hash because it is used in the commitment of the next block IExecutor.StoredBlockInfo memory storedBlockZero = IExecutor .StoredBlockInfo( // @audit-info check if this should be Executor.StoredBlockInfo instead of IExecutor.StoredBlockInfo since a Interface should not return any logic 0, _genesisBlockHash, _genesisIndexRepeatedStorageChanges, 0, EMPTY_STRING_KECCAK, DEFAULT_L2_LOGS_TREE_ROOT_HASH, 0, _genesisBlockCommitment ); s.storedBlockHashes[0] = keccak256(abi.encode(storedBlockZero)); s.allowList = _allowList; s.verifierParams = _verifierParams; s.zkPorterIsAvailable = _zkPorterIsAvailable; s.l2BootloaderBytecodeHash = _l2BootloaderBytecodeHash; s.l2DefaultAccountBytecodeHash = _l2DefaultAccountBytecodeHash; return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; }
#0 - c4-judge
2022-11-14T20:20:42Z
GalloDaSballo marked the issue as duplicate of #166
#1 - GalloDaSballo
2022-11-27T20:05:01Z
L
#2 - c4-judge
2022-11-27T20:05:08Z
GalloDaSballo changed the severity to QA (Quality Assurance)
#3 - c4-judge
2022-12-03T19:13:26Z
GalloDaSballo marked the issue as grade-c
#4 - c4-judge
2022-12-08T23:46:56Z
GalloDaSballo marked the issue as grade-b
#5 - GalloDaSballo
2022-12-08T23:47:26Z
With 4 Low Severity finding, am giving it 2 bonus points to award a B