zkSync v2 contest - datapunk's results

Rely on math, not validators.

General Information

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

zkSync

Findings Distribution

Researcher Performance

Rank: 5/24

Findings: 1

Award: $2,102.32

QA:
grade-a

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: HE1M

Also found by: 0xSmartContract, Rolezn, Tomo, brgltd, cccz, chaduke, ctf_sec, datapunk, jayjonah8, ladboy233, pashov, rbserver

Labels

bug
QA (Quality Assurance)
grade-a
Q-08

Awards

2102.3184 USDC - $2,102.32

External Links

N.1 There is no good way to update a facet's isFreezable except call _removeFunctions then _addFunctions back

Impact

It is expensive to call _removeFunctions and _addFunctions, as it involves a lot of operations.

Proof of Concept

As the protocol becomes more mature, it is natural to freeze specific facets. A function can be created to specifically switch isFreezable of all selectors of a given facet.

Tools Used

VS Code

in Diamond library add:

function _changeFreezability(address _facet, bool _isFreezable) { DiamondStorage storage ds = getDiamondStorage(); uint256 selectorLen = ds.facetToSelectors[_facet].selectors.length; for (init i; i<selectLen; i=i.uncheckedInc()) { bytes4 selector = ds.facetToSelectors[_facet].selectors[i]; ds.selectorToFacet[selector].isFreezable = _isFreezable; } }

N.2 Fix inaccurate comments

Impact

It is confusing when comments are inconsistent with the code, even when the code itself is correct

Proof of Concept

In require(approvedBySecurityCouncil || upgradeNoticePeriodPassed, "a6"); // notice period should expire The code says governor can execute a proposal immediately as long as enough approvals have been gathered. Yet the comment says notice period should expire.

Another example, where comments about _l1Token in L2ERC20Bridge was copied from L2EthBridge, thus inaccurate.

Tools Used

VS Code

fix the comment to match the code


N.3 Fix inaccurate doc

Impact

It is confusing when docs are inconsistent with the code, even when the code itself is correct

Proof of Concept

According to the doc "Several (of none) logs from the L2_TO_L1_MESSENGER with the key == hashedMessage where hashedMessage is a hash of an arbitrary-length message that is sent from L2", however, in the code: (bytes32 hashedMessage, ) = UnsafeBytes.readBytes32(emittedL2Logs, i + 56);. For L2_TO_L1_MESSENGER the key is bytes32(msg.sender) at 24 and value is hashedMessage at 56. So, the code is correct, but the document should be edited.

Tools Used

VS Code

replace key with value.


N.4 Checking require(emittedL2Logs.length % L2_TO_L1_LOG_SERIALIZE_SIZE == 0);

Impact

Proof of Concept

_processL2Logs does extensive checking of l2logs to make sure everything lines up. As a sanity check, the new requirement makes it more explicit about the structure of l2logs.

Tools Used

VS Code

add require(emittedL2Logs.length % L2_TO_L1_LOG_SERIALIZE_SIZE == 0); before Executor.sol#L111

N.5 Align doc with code

Proof of Concept

The doc specifies _processL2Logs processes Several (or none) logs from other addresses with arbitrary parameters.. However the code does not show any trace of such logic.

After communicating with the dev team, it is apparent this paragraph is meant for the next phase of the project, thus should be removed.


N.6 Remove _calculateBlockHash(...) from Executor

_calculateBlockHash is an internal function in Executor, and it is not called in the codebase. Can be removed.


N.7 Missing setter function to set an account as securityCouncilMembers

Impact

A new facet needs to be reployed to add members to securityCouncilMembers

Proof of Concept

As the code stands now, there does not seem to be a setter to set an account as securityCouncilMembers. The emergency approval route is not really needed either since UPGRADE_NOTICE_PERIOD is currently set as 0. However, as these logics are mobilized, a setter will need to be reployed.


N.8 isFacetFreezable and isFunctionFreezable behaves differently for non-existing values

isFacetFreezable returns false for non-exising _facet. isFunctionFreezable reverts for non-existing _selector. The the sake of consistency, they should exhibit similar behavior.


N.9 setVerifierParams does not check the equivalence of old and new paramters before setting values

All other functions in Governance.sol checkes the equivalence of old and new values before changing the exisitng value. setVerifierParams is the only exception. It makes sense to check new check first as well in setVerifierParams.

#0 - GalloDaSballo

2022-11-24T01:13:01Z

N.1 There is no good way to update a facet's isFreezable except call _removeFunctions then _addFunctions back

I will give it NC as I don't actually think you'd need this, you could just either not add it or perhaps set it as freezable to begin with

N.2 Fix inaccurate comments

NC

N.3 Fix inaccurate doc && N.5 Align doc with code

NC

N.4 Checking require(emittedL2Logs.length % L2_TO_L1_LOG_SERIALIZE_SIZE == 0);

R

N.6 Remove _calculateBlockHash(...) from Executor

R

N.7 Missing setter function to set an account as securityCouncilMembers

L

N.8 isFacetFreezable and isFunctionFreezable behaves differently for non-existing values

R

N.9 setVerifierParams does not check the equivalence of old and new paramters before setting values

R

Pretty good

#1 - GalloDaSballo

2022-12-03T00:13:45Z

1L 4R 2NC

#2 - c4-judge

2022-12-03T19:08:41Z

GalloDaSballo marked the issue as grade-a

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