Skip to content

Instantly share code, notes, and snippets.

@itsmetechjay
Last active February 26, 2024 17:14
Show Gist options
  • Select an option

  • Save itsmetechjay/57d432101e7d8c98f3a061502aa8f327 to your computer and use it in GitHub Desktop.

Select an option

Save itsmetechjay/57d432101e7d8c98f3a061502aa8f327 to your computer and use it in GitHub Desktop.
Best bot finding from 2023-10-zksync-bot-findings

Winning bot race submission

This is the top-ranked automated findings report, from IllIll-bot bot. All findings in this report will be considered known issues for the purposes of your C4 audit.

Note: There is a section for disputed findings below the usual findings sections

Summary

Medium Risk Issues

Issue Instances
[M‑01] The owner is a single point of failure and a centralization risk 24

Total: 24 instances over 1 issues

Low Risk Issues

Issue Instances
[L‑01] addresses upcast and compared to values larger than a uint160, may result in collisions 1
[L‑02] approve()/safeApprove() may revert if the current approval is not zero 1
[L‑03] receive()/payable fallback() function does not authorize requests 4
[L‑04] require() should be used instead of assert() 4
[L‑05] safeApprove() is deprecated 2
[L‑06] A year is not always 365 days 2
[L‑07] Addition/multiplication in unchecked block is unsafe 9
[L‑08] Code does not follow the best practice of check-effects-interaction 9
[L‑09] Consider implementing two-step procedure for updating protocol addresses 13
[L‑10] Division by zero not prevented 1
[L‑11] Empty receive()/fallback() function 4
[L‑12] External call recipient may consume all transaction gas 6
[L‑13] External calls in an un-bounded for-loop may result in a DOS 2
[L‑14] File allows a version of solidity that is susceptible to an assembly optimizer bug 5
[L‑15] File allows a version of solidity that is susceptible to an assembly storage bug 4
[L‑16] Function called does not exist in the contract interface 1
[L‑17] Function doesn't perform any updates 1
[L‑18] Initialization can be front-run 6
[L‑19] Loss of precision 13
[L‑20] Missing checks for address(0x0) in the constructor/initializer 8
[L‑21] Missing checks for address(0x0) when updating address state variables 4
[L‑22] Missing contract-existence checks before low-level calls 9
[L‑23] Missing contract-existence checks before yul call() 12
[L‑24] Multiplication on the result of a division 2
[L‑25] Numbers downcast to addresses may result in collisions 16
[L‑26] Reviews of the input files to solpp are not the same as reviews of its output 94
[L‑27] Solidity version 0.8.20 may not work on other chains due to PUSH0 94
[L‑28] Some tokens may revert when large transfers are made 2
[L‑29] State variables not capped at reasonable values 4
[L‑30] Subtraction may underflow if multiplication is too large 1
[L‑31] Unsafe downcast 64
[L‑32] Upgradeable contract is missing a __gap[50] storage variable to allow for new storage variables in later versions 2
[L‑33] Use of tx.origin is unsafe in almost every context 3
[L‑34] Use of a single-step ownership transfer 3

Total: 406 instances over 34 issues

Non-critical Issues

Issue Instances
[N‑01] 2**<n> - 1 should be re-written as type(uint<n>).max 6
[N‑02] addresses shouldn't be hard-coded 1
[N‑03] constants should be defined rather than using magic numbers 174
[N‑04] else-block not required 2
[N‑05] if-statement can be converted to a ternary 3
[N‑06] internal functions not called by the contract should be removed 1
[N‑07] public functions not called by the contract should be declared external instead 18
[N‑08] pure function accesses storage 1
[N‑09] require()/revert() statements should have descriptive reason strings 3
[N‑10] Add inline comments for unnamed variables 12
[N‑11] Adding a return statement when the function defines a named return variable, is redundant 1
[N‑12] Array indices should be referenced via enums rather than via numeric literals 39
[N‑13] Assembly block creates dirty bits 2
[N‑14] Assembly blocks should have extensive comments 55
[N‑15] Avoid the use of sensitive terms 56
[N‑16] Cast to bytes or bytes32 for clearer semantic meaning 3
[N‑17] Common functions should be refactored to a common base contract 1
[N‑18] Complex casting 69
[N‑19] Consider adding a block/deny-list 5
[N‑20] Consider adding emergency-stop functionality 3
[N‑21] Consider adding formal verification proofs 1
[N‑22] Consider bounding input array length 18
[N‑23] Consider disallowing transfers to address(this) 1
[N‑24] Consider implementing EIP-5267 to securely describe EIP-712 domains being used 1
[N‑25] Consider moving msg.sender checks to a common authorization modifier 13
[N‑26] Consider splitting long calculations 5
[N‑27] Consider using delete rather than assigning zero/false to clear values 1
[N‑28] Consider using SafeTransferLib.safeTransferETH() or Address.sendValue() for clearer semantic meaning 2
[N‑29] Consider using descriptive constants when passing zero as a function argument 29
[N‑30] Consider using named mappings 36
[N‑31] Constant redefined elsewhere 6
[N‑32] Constants in comparisons should appear on the left side 110
[N‑33] Contract should expose an interface 149
[N‑34] Contract timekeeping will break earlier than the Ethereum network itself will stop working 2
[N‑35] Contracts should have full test coverage 1
[N‑36] Custom errors should be used rather than revert()/require() 272
[N‑37] Duplicated require()/revert() checks should be refactored to a modifier or function 3
[N‑38] Error messages should descriptive, rather that cryptic 138
[N‑39] Event is not properly indexed 4
[N‑40] Events are missing sender information 53
[N‑41] Events may be emitted out of order due to reentrancy 12
[N‑42] Events should use parameters to convey information 2
[N‑43] Events that mark critical parameter changes should contain both the old and the new value 8
[N‑44] Expressions for constant values should use immutable rather than constant 79
[N‑45] High cyclomatic complexity 1
[N‑46] Import declarations should import specific identifiers, rather than the whole file 124
[N‑47] Imports could be organized more systematically 3
[N‑48] Inconsistent method of specifying a floating pragma 1
[N‑49] Interfaces should be defined in separate files from their usage 2
[N‑50] Large multiples of ten should use scientific notation (e.g. 1e6) rather than decimal literals (e.g. 1000000), for readability 2
[N‑51] Large numeric literals should use underscores for readability 19
[N‑52] Large or complicated code bases should implement invariant tests 1
[N‑53] Libraries should be defined in separate files from their usage 2
[N‑54] Long functions should be refactored into multiple, smaller, functions 13
[N‑55] Memory-safe annotation preferred over comment variant 1
[N‑56] Misplaced SPDX identifier 94
[N‑57] Missing checks constructor/initializer assignments 2
[N‑58] Missing checks for state variable assignments 4
[N‑59] Missing event and or timelock for critical parameter change 4
[N‑60] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, for readability 1
[N‑61] Named imports of parent contracts are missing 43
[N‑62] NatSpec: Contract declarations should have @author tags 29
[N‑63] NatSpec: Contract declarations should have @dev tags 57
[N‑64] NatSpec: Contract declarations should have @notice tags 26
[N‑65] NatSpec: Contract declarations should have @title tags 83
[N‑66] NatSpec: Contract declarations should have descriptions 26
[N‑67] NatSpec: Event declarations should have descriptions 24
[N‑68] NatSpec: File is missing NatSpec 22
[N‑69] NatSpec: Function @param tag is missing 538
[N‑70] NatSpec: Function @return tag is missing 250
[N‑71] NatSpec: Function declarations should have @notice tags 182
[N‑72] NatSpec: Function declarations should have descriptions 182
[N‑73] NatSpec: Modifier declarations should have descriptions 7
[N‑74] NatSpec: State variable declarations should have descriptions 13
[N‑75] Non-library/interface files should use fixed compiler versions, not floating ones 35
[N‑76] Not using the named return variables anywhere in the function is confusing 2
[N‑77] Open TODOs 2
[N‑78] Overflows in unchecked blocks 4
[N‑79] Polymorphic functions make security audits more time-consuming and error-prone 5
[N‑80] Setters should prevent re-setting of the same value 15
[N‑81] Style guide: mapping definitions do not follow the Solidity Style Guide 1
[N‑82] Style guide: Contract does not follow the Solidity style guide's suggested layout ordering 16
[N‑83] Style guide: Function names should use lowerCamelCase 2
[N‑84] Style guide: Function ordering does not follow the Solidity style guide 46
[N‑85] Style guide: Lines are too long 121
[N‑86] Style guide: Non-external/public function names should begin with an underscore 5
[N‑87] Style guide: Non-external/public variable names should begin with an underscore 44
[N‑88] Style guide: State and local variables should be named using lowerCamelCase 6
[N‑89] Style guide: Strings should use double quotes rather than single quotes 2
[N‑90] Style guide: Top-level declarations should be separated by at least two lines 1
[N‑91] Style guide: Variable names for constants are improperly named 6
[N‑92] Style guide: Variable names for immutables should use CONSTANT_CASE 6
[N‑93] Typos 20
[N‑94] Unnecessary cast 6
[N‑95] Unused event definition 2
[N‑96] Unused public contract variable 6
[N‑97] Unused file 2
[N‑98] Unused function parameter 3
[N‑99] Unused import 22
[N‑00] Unusual loop variable 1
[N‑01] Use bytes.concat() on bytes instead of abi.encodePacked() for clearer semantic meaning 2
[N‑02] Use bit shifts in an imutable variable rather than long bit masks of a single bit, for readability 1
[N‑03] Use of override is unnecessary 52
[N‑04] Use OpenZeppelin's MerkleProof rather than rolling your own 1
[N‑05] Use the latest solidity (prior to 0.8.20 if on L2s) for deployment 35
[N‑06] Using >/>= without specifying an upper bound is unsafe 1
[N‑07] Variables need not be initialized to zero 36
[N‑08] Visibility should be set explicitly rather than defaulting to internal 14
[N‑09] Vulnerable versions of packages are being used 1

Total: 3681 instances over 109 issues

Gas Optimizations

Issue Instances Total Gas Saved
[G‑01] require() or revert() statements that check input arguments should be at the top of the function 8 -
[G‑02] Enable IR-based code generation 1 -
[G‑03] Inline modifiers that are only used once, to save gas 4 -
[G‑04] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate 1 -
[G‑05] Reduce gas usage by moving to Solidity 0.8.19 or later 94 -
[G‑06] Use uint256(1)/uint256(2) instead of true/false to save gas for changes 3 25650
[G‑07] Using storage instead of memory for state variables saves gas 13 27300
[G‑08] State variables only set in their definitions should be declared constant 3 6291
[G‑09] State variables only set in the constructor should be declared immutable 1 2097
[G‑10] Structs can be packed into fewer storage slots 3 6000
[G‑11] Structs can be packed into fewer storage slots by truncating timestamp bytes 3 6000
[G‑12] State variables can be packed into fewer storage slots by truncating timestamp bytes 1 2000
[G‑13] State variables can be packed into fewer storage slots 1 2000
[G‑14] Avoid updating storage when the value hasn't changed 15 12000
[G‑15] Events should be emitted outside of loops 3 1125
[G‑16] "" has the same value as new bytes(0) but costs less gas 4 1036
[G‑17] Avoid fetching a low-level call's return data by using assembly 4 636
[G‑18] Using calldata instead of memory for read-only arguments in external functions saves gas 12 1440
[G‑19] Using bools for storage incurs overhead 3 300
[G‑20] Avoid transferring amounts of zero in order to save gas 3 300
[G‑21] Using this to access functions results in an external call, wasting gas 1 100
[G‑22] State variables should be cached in stack variables rather than re-reading them from storage 76 7372
[G‑23] Use local variables for emitting 7 679
[G‑24] Storage re-read via storage pointer 4 388
[G‑25] State variable read in a loop 3 291
[G‑26] Use the inputs/results of assignments rather than re-reading state variables 2 194
[G‑27] Use assembly for small keccak256 hashes, in order to save gas 20 1600
[G‑28] ++i/i++ should be unchecked{++i}/unchecked{i++} when it is not possible for them to overflow, as is the case when used in for- and while-loops 9 540
[G‑29] internal functions not called by the contract should be removed to save deployment gas 1 -
[G‑30] Avoid contract existence checks by using low-level calls 2 200
[G‑31] keccak256() should only need to be called on a specific string literal once 5 210
[G‑32] Assigning state variables directly with named struct constructors wastes gas 1 28
[G‑33] Initializers can be marked payable 3 -
[G‑34] Multiple accesses of a mapping/array should use a local variable cache 1 42
[G‑35] Remove or replace unused state variables 4 -
[G‑36] Same cast is done multiple times 2 -
[G‑37] Use assembly to emit events, in order to save gas 39 1482
[G‑38] Add unchecked {} for subtractions where the operands cannot underflow because of a previous require() or if-statement 2 60
[G‑39] Optimize names to save gas 44 968
[G‑40] Usage of uints/ints smaller than 32 bytes (256 bits) incurs overhead 14 308
[G‑41] Functions guaranteed to revert when called by normal users can be marked payable 58 1218
[G‑42] Constructors can be marked payable 11 231
[G‑43] internal/private functions only called once can be inlined to save gas 60 1200
[G‑44] unchecked {} can be used on the division of two uints in order to save gas 7 140
[G‑45] Division by powers of two should use bit shifting 4 80
[G‑46] <x> += <y> costs more gas than <x> = <x> + <y> for basic-typed state variables 3 30
[G‑47] Simple checks for zero can be done using assembly to save gas 14 84
[G‑48] Using > 0 costs more gas than != 0 when used on a uint in a require() statement 6 36
[G‑49] Nesting if-statements is cheaper than using && 5 30
[G‑50] ++i costs less gas than i++, especially when it's used in for-loops (--i/i-- too) 5 25
[G‑51] require()/revert() strings longer than 32 bytes cost extra gas 81 243
[G‑52] >= costs less gas than > 17 51
[G‑53] <array>.length should not be looked up in every loop of a for-loop 8 24
[G‑54] Remove unused local variable 1 -
[G‑55] Stack variable used as a cheaper cache for a state variable is only used once 3 9
[G‑56] Splitting require() statements that use && saves gas 3 9
[G‑57] Use custom errors rather than revert()/require() strings to save gas 272 -
[G‑58] Using constants directly, rather than caching the value, saves gas 31 -
[G‑59] Using msg globals directly, rather than caching the value, saves gas 3 -
[G‑60] Using globals directly is cheaper than assigning them to variables 2 10

Total: 1014 instances over 60 issues with 112057 gas saved

Gas totals are estimates based on data from the Ethereum Yellowpaper. The estimates use the lower bounds of ranges and count two iterations of each for-loop. All values above are runtime, not deployment, values; deployment values are listed in the individual issue descriptions. The table above as well as its gas numbers do not include any of the excluded findings.

Disputed Issues

The issues below may be reported by other bots/wardens, but can be penalized/ignored since either the rule or the specified instances are invalid

Issue Instances
[D‑01] abi.encode() is less efficient than abi.encodepacked() 5
[D‑02] abi.encodePacked() should not be used with dynamic types when passing the result to a hash function such as keccak256() 6
[D‑03] internal functions not called by the contract should be removed 112
[D‑04] selfbalance() is cheaper than address(this).balance 3
[D‑05] All interfaces used within a project should be imported 54
[D‑06] Array is push()ed but not pop()ed 2
[D‑07] Array lengths not checked 49
[D‑08] Assembly blocks should have comments 9
[D‑09] Avoid fetching a low-level call's return data by using assembly 13
[D‑10] Bad bot rules 1
[D‑11] Cast to bytes or bytes32 for clearer semantic meaning 9
[D‑12] Change public function visibility to external to save gas 9
[D‑13] Constant redefined elsewhere 10
[D‑14] Contracts containing only utility functions should be made into libraries 3
[D‑15] Contracts do not work with fee-on-transfer tokens 14
[D‑16] Default bool values are manually reset 8
[D‑17] Duplicated require()/revert() checks should be refactored to a modifier or function 280
[D‑18] Duplicated require()/revert() checks should be refactored to a modifier Or function to save gas 3
[D‑19] Event names should use CamelCase 59
[D‑20] Events that mark critical parameter changes should contain both the old and the new value 57
[D‑21] Functions which are either private or internal should have a preceding _ in their name 107
[D‑22] Getter for public state variables are redundant 2
[D‑23] IERC20 approve() Is Deprecated 1
[D‑24] Inconsistent comment spacing 6
[D‑25] Interfaces should be defined in separate files from their usage 35
[D‑26] It is standard for all external and public functions to be override from an interface 52
[D‑27] It's not standard to end and begin a code object on the same line 76
[D‑28] Lack of unchecked in loops 4
[D‑29] Large approvals may not work with some ERC20 tokens 2
[D‑30] Low level calls with Solidity before 0.8.14 result in an optimiser bug 59
[D‑31] Missing checks for ecrecover() signature malleability 1
[D‑32] Missing checks for state variable assignments 12
[D‑33] Missing contract-existence checks before low-level calls 4
[D‑34] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, for readability 2
[D‑35] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, where appropriate 2
[D‑36] Multiplications of powers 2 of can be replaced by a left shift operation to save gas 25
[D‑37] Must approve or increase allowance first 2
[D‑38] NatSpec: Contract declarations should have @notice tags 64
[D‑39] NatSpec: Function declarations should have @notice tags 217
[D‑40] NatSpec: Invalid comment style 1
[D‑41] Nesting if-statements is cheaper than using && 5
[D‑42] Non-assembly method available 1
[D‑43] Non-library/interface files should use fixed compiler versions, not floating ones 59
[D‑44] Not initializing local variables to zero saves gas 33
[D‑45] Not using the named return variables anywhere in the function is confusing 29
[D‑46] Numeric values having to do with time should use time units for readability 3
[D‑47] Operator += costs more gas than = + for state variables 6
[D‑48] Overly complicated arithmetic 1
[D‑49] Public functions not used internally can be marked as external to save gas 18
[D‑50] Re-org attack 2
[D‑51] Remove or replace unused state variables 2
[D‑52] Save gas with the use of specific import statements 124
[D‑53] Shorten the array rather than copying to a new one 1
[D‑54] State variable read in a loop 3
[D‑55] State variables not capped at reasonable values 4
[D‑56] Storage Write Removal Bug On Conditional Early Termination 60
[D‑57] Style guide: constant/immutable variable names should use capital letters and underscores 50
[D‑58] Style guide: Contract does not follow the Solidity style guide's suggested layout ordering 75
[D‑59] Style guide: Do not use underscore at the end of variable name 1
[D‑60] Style guide: Function Names Not in mixedCase 83
[D‑61] Style guide: Prefer double quotes for string quoting 2
[D‑62] The result of function calls should be cached rather than re-calling the function 6
[D‑63] Timestamp may be manipulation 8
[D‑64] Tokens may be minted to address(0x0) 2
[D‑65] Unnecessary look up in if condition 26
[D‑66] Unsafe downcast 3
[D‑67] Unused event definition 46
[D‑68] Unused struct definition 27
[D‑69] Unused function parameter 43
[D‑70] Unused import 212
[D‑71] Unused local variable 43
[D‑72] Unused modifier 10
[D‑73] Unused named return variables without optimizer waste gas 2
[D‑74] Unusual loop variable 30
[D‑75] Upgradeable contract not initialized 2
[D‑76] Usage of ints/uints smaller than 32 bytes incurs overhead 3
[D‑77] Use != 0 instead of > 0 for unsigned integer comparison 10
[D‑78] Use _safeMint instead of _mint for ERC721 2
[D‑79] Use @inheritdoc rather than using a non-standard annotation 49
[D‑80] Use assembly to write address/contract type storage values 29
[D‑81] Use bytes.concat() on bytes instead of abi.encodePacked() for clearer semantic meaning 10
[D‑82] Use assembly to emit events, in order to save gas 5
[D‑83] Use constants instead of type(uintx).max 12
[D‑84] Use delete instead of setting mapping/state variable to zero, to save gas 2
[D‑85] Use multiple require() and if statements instead of && 10
[D‑86] Use replace and pop instead of the delete keyword to removing an item from an array 4
[D‑87] Using calldata instead of memory for read-only arguments in external functions saves gas 3
[D‑88] Using storage instead of memory for structs/arrays saves gas 2
[D‑89] Using this to access functions results in an external call, wasting gas 3
[D‑90] Using this to access functions results in an external call, wasting gas 2
[D‑91] Using storage instead of memory for structs/arrays saves gas 1
[D‑92] Using bitmap to store bool states can save gas 5
[D‑93] Using named function calls is a much safer 5

Total: 2559 instances over 93 issues

Medium Risk Issues

[M‑01] The owner is a single point of failure and a centralization risk

Having a single EOA as the only owner of contracts is a large centralization risk and a single point of failure. A single private key may be taken in a hack, or the sole holder of the key may become unable to retrieve the key when necessary, or the single owner can become malicious and perform a rug-pull. Consider changing to a multi-signature setup, and or having a role-based authorization model.

There are 24 instances of this issue:

File: cache/solpp-generated-contracts/common/AllowList.sol

51:      function setAccessMode(address _target, AccessMode _accessMode) external onlyOwner {

60:      function setBatchAccessMode(address[] calldata _targets, AccessMode[] calldata _accessModes) external onlyOwner {

85       function setBatchPermissionToCall(
86           address[] calldata _callers,
87           address[] calldata _targets,
88           bytes4[] calldata _functionSigs,
89           bool[] calldata _enables
90:      ) external onlyOwner {

108      function setPermissionToCall(
109          address _caller,
110          address _target,
111          bytes4 _functionSig,
112          bool _enable
113:     ) external onlyOwner {

131:     function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external onlyOwner {

GitHub: 51, 60, 85, 108, 131

File: cache/solpp-generated-contracts/governance/Governance.sol

131:     function scheduleTransparent(Operation calldata _operation, uint256 _delay) external onlyOwner {

144:     function scheduleShadow(bytes32 _id, uint256 _delay) external onlyOwner {

156:     function cancel(bytes32 _id) external onlyOwnerOrSecurityCouncil {

169:     function execute(Operation calldata _operation) external onlyOwnerOrSecurityCouncil {

GitHub: 131, 144, 156, 169

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

54:      function setValidator(address _newValidator) external onlyOwner {

61:      function setExecutionDelay(uint32 _executionDelay) external onlyOwner {

GitHub: 54, 61

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

22:      function setPendingGovernor(address _newPendingGovernor) external onlyGovernor {

46:      function setPendingAdmin(address _newPendingAdmin) external onlyGovernorOrAdmin {

70:      function setValidator(address _validator, bool _active) external onlyGovernorOrAdmin {

77:      function setPorterAvailability(bool _zkPorterIsAvailable) external onlyGovernor {

85:      function setPriorityTxMaxGasLimit(uint256 _newPriorityTxMaxGasLimit) external onlyGovernor {

100:     function executeUpgrade(Diamond.DiamondCutData calldata _diamondCut) external onlyGovernor {

111:     function freezeDiamond() external onlyGovernor {

122:     function unfreezeDiamond() external onlyGovernorOrAdmin {

GitHub: 22, 46, 70, 77, 85, 100, 111, 122

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

84:      function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall {

GitHub: 84

File: cache-zk/solpp-generated-contracts/SystemContext.sol

89:      function setTxOrigin(address _newOrigin) external onlyCallFromBootloader {

95:      function setGasPrice(uint256 _gasPrice) external onlyCallFromBootloader {

314      function setL2Block(
315          uint128 _l2BlockNumber,
316          uint128 _l2BlockTimestamp,
317          bytes32 _expectedPrevL2BlockHash,
318          bool _isFirstInBatch,
319          uint128 _maxVirtualBlocksToCreate
320:     ) external onlyCallFromBootloader {

418      function setNewBatch(
419          bytes32 _prevBatchHash,
420          uint128 _newTimestamp,
421          uint128 _expectedNewNumber,
422          uint256 _baseFee
423:     ) external onlyCallFromBootloader {

GitHub: 89, 95, 314, 418

Low Risk Issues

[L‑01] addresses upcast and compared to values larger than a uint160, may result in collisions

If the value is being compared to an input value in order to reject it, rather than allowing it to be converted to an address, the check will pass if the value is larger than type(uint160).max, even if, when cast, it matches the gating address.

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

97:          return _addr == uint256(uint160(address(ETH_TOKEN_SYSTEM_CONTRACT))) || _addr == 0;

GitHub: 97

[L‑02] approve()/safeApprove() may revert if the current approval is not zero

Calling approve() without first calling approve(0) if the current approval is non-zero will revert with some tokens, such as Tether (USDT). While Tether is known to do this, it applies to other tokens as well, which are trying to protect against this attack vector. safeApprove() itself also implements this protection. Always reset the approval to zero before changing it to a new value (SafeERC20.forceApprove() does this for you), or use safeIncreaseAllowance()/safeDecreaseAllowance()

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

385:                 IERC20(token).safeApprove(paymaster, minAllowance);

GitHub: 385

[L‑03] receive()/payable fallback() function does not authorize requests

Having no access control on the function (e.g. require(msg.sender == address(weth))) means that someone may send Ether to the contract, and have no way to get anything back out, which is a loss of funds. If the concern is having to spend a small amount of gas to check the sender against an immutable address, the code should at least have a function to rescue mistakenly-sent Ether.

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

264:      receive() external payable {}

GitHub: 264

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

231       receive() external payable {
232           // If the contract is called directly, behave like an EOA
233:      }

GitHub: 231

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

14:       fallback() external payable {}

16:       receive() external payable {}

GitHub: 14, 16

[L‑04] require() should be used instead of assert()

Prior to solidity version 0.8.0, hitting an assert consumes the remainder of the transaction's available gas rather than returning it, as require()/revert() do. assert() should be avoided even past solidity version 0.8.0 as its documentation states that "The assert function creates an error of type Panic(uint256). ... Properly functioning code should never create a Panic, not even on invalid external input. If this happens, then there is a bug in your contract which you should fix".

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

89:           assert(L2_TO_L1_LOG_SERIALIZE_SIZE != 2 * 32);

GitHub: 89

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

352:          assert(block.chainid != 1);

GitHub: 352

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

226:          assert(msg.sender != BOOTLOADER_FORMAL_ADDRESS);

GitHub: 226

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

52:           assert(_len != 1);

GitHub: 52

[L‑05] safeApprove() is deprecated

Deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead. The function may currently work, but if a bug is found in this version of OpenZeppelin, and the version that you're forced to upgrade to no longer has this function, you'll encounter unnecessary delays in porting and testing replacement contracts.

There are 2 instances of this issue:

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

384:                  IERC20(token).safeApprove(paymaster, 0);

385:                  IERC20(token).safeApprove(paymaster, minAllowance);

GitHub: 384, 385

[L‑06] A year is not always 365 days

On leap years, the number of days is 366, so calculations during those years will return the wrong value

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/zksync/Config.sol

56:  uint256 constant COMMIT_TIMESTAMP_NOT_OLDER = 365 days;

60:  uint256 constant COMMIT_TIMESTAMP_APPROXIMATION_DELTA = 365 days;

GitHub: 56, 60

[L‑07] Addition/multiplication in unchecked block is unsafe

The additions/multiplications may silently overflow because they're in unchecked blocks with no preceding value checks, which may lead to unexpected results

There are 9 instances of this issue:

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

21:              return _lhs + _rhs;

GitHub: 21

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

107              uint256 listLength = encodedNonce.length +
108                  encodedGasParam.length +
109                  encodedTo.length +
110                  encodedValue.length +
111                  encodedDataLength.length +
112:                 _transaction.data.length +

200              uint256 listLength = encodedFixedLengthParams.length +
201                  encodedDataLength.length +
202:                 _transaction.data.length +

295              uint256 listLength = encodedFixedLengthParams.length +
296                  encodedDataLength.length +
297:                 _transaction.data.length +

GitHub: 107, 200, 295

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

148:             pubdataLen = 4 + _message.length + L2_TO_L1_LOG_SERIALIZE_SIZE;

GitHub: 148

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

66:                  encoded[0] = bytes1(uint8(_len + _offset));

GitHub: 66

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

192              uint256 listLength = encodedNonce.length +
193                  encodedGasParam.length +
194                  encodedTo.length +
195                  encodedValue.length +
196                  encodedDataLength.length +
197:                 _transaction.data.length +

267              uint256 listLength = encodedFixedLengthParams.length +
268                  encodedDataLength.length +
269:                 _transaction.data.length +

339              uint256 listLength = encodedFixedLengthParams.length +
340                  encodedDataLength.length +
341:                 _transaction.data.length +

GitHub: 192, 267, 339

[L‑08] Code does not follow the best practice of check-effects-interaction

Code should follow the best-practice of check-effects-interaction, where state variables are updated before any external calls are made. Doing so prevents a large class of reentrancy bugs.

There are 9 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

/// @audit safeTransferFrom() called prior to this assignment
125          l2Bridge = BridgeInitializationHelper.requestDeployTransaction(
126              zkSync,
127              _deployBridgeProxyFee,
128              l2BridgeProxyBytecodeHash,
129              l2BridgeProxyConstructorData,
130              // No factory deps are needed for L2 bridge proxy, because it is already passed in previous step
131              new bytes[](0)
132:         );

GitHub: 125

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit safeTransferFrom() called prior to this assignment
128          l2Bridge = BridgeInitializationHelper.requestDeployTransaction(
129              zkSync,
130              _deployBridgeProxyFee,
131              l2WethBridgeProxyBytecodeHash,
132              l2WethBridgeProxyConstructorData,
133              // No factory deps are needed for L2 bridge proxy, because it is already passed in the previous step
134              new bytes[](0)
135:         );

/// @audit finalizeEthWithdrawal() called prior to this assignment
267:         isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex] = true;

GitHub: 128, 267

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

/// @audit null() called prior to this assignment
282:         s.totalDepositedAmountPerUser[_depositor] += _amount;

GitHub: 282

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

/// @audit decodeString() called prior to this assignment
98:          availableGetters = getters;

GitHub: 98

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

/// @audit verifyCompressedStateDiffs() called prior to this assignment
334:         chainedLogsHash = bytes32(0);

/// @audit verifyCompressedStateDiffs() called prior to this assignment
335:         numberOfLogsToProcess = 0;

/// @audit verifyCompressedStateDiffs() called prior to this assignment
336:         chainedMessagesHash = bytes32(0);

/// @audit verifyCompressedStateDiffs() called prior to this assignment
337:         chainedL1BytecodesRevealDataHash = bytes32(0);

GitHub: 334, 335, 336, 337

[L‑09] Consider implementing two-step procedure for updating protocol addresses

A copy-paste error or a typo may end up bricking protocol functionality, or sending tokens to an address with no known private key. Consider implementing a two-step procedure for updating protocol addresses, where the recipient is set as pending, and must 'accept' the assignment by making an affirmative call. A straight forward way of doing this would be to have the target contracts implement EIP-165, and to have the 'set' functions ensure that the recipient is of the right interface type.

There are 13 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/AllowList.sol

131      function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external onlyOwner {
132          tokenDeposit[_l1Token].depositLimitation = _depositLimitation;
133          tokenDeposit[_l1Token].depositCap = _depositCap;
134:     }

GitHub: 131

File: cache/solpp-generated-contracts/governance/Governance.sol

251      function updateDelay(uint256 _newDelay) external onlySelf {
252          emit ChangeMinDelay(minDelay, _newDelay);
253          minDelay = _newDelay;
254:     }

258      function updateSecurityCouncil(address _newSecurityCouncil) external onlySelf {
259          emit ChangeSecurityCouncil(securityCouncil, _newSecurityCouncil);
260          securityCouncil = _newSecurityCouncil;
261:     }

GitHub: 251, 258

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

54       function setValidator(address _newValidator) external onlyOwner {
55           address oldValidator = validator;
56           validator = _newValidator;
57           emit NewValidator(oldValidator, _newValidator);
58:      }

61       function setExecutionDelay(uint32 _executionDelay) external onlyOwner {
62           executionDelay = _executionDelay;
63           emit NewExecutionDelay(_executionDelay);
64:      }

GitHub: 54, 61

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

70       function setValidator(address _validator, bool _active) external onlyGovernorOrAdmin {
71           s.validators[_validator] = _active;
72           emit ValidatorStatusUpdate(_validator, _active);
73:      }

77       function setPorterAvailability(bool _zkPorterIsAvailable) external onlyGovernor {
78           // Change the porter availability
79           s.zkPorterIsAvailable = _zkPorterIsAvailable;
80           emit IsPorterAvailableStatusUpdate(_zkPorterIsAvailable);
81:      }

85       function setPriorityTxMaxGasLimit(uint256 _newPriorityTxMaxGasLimit) external onlyGovernor {
86           require(_newPriorityTxMaxGasLimit <= L2_TX_MAX_GAS_LIMIT, "n5");
87   
88           uint256 oldPriorityTxMaxGasLimit = s.priorityTxMaxGasLimit;
89           s.priorityTxMaxGasLimit = _newPriorityTxMaxGasLimit;
90           emit NewPriorityTxMaxGasLimit(oldPriorityTxMaxGasLimit, _newPriorityTxMaxGasLimit);
91:      }

GitHub: 70, 77, 85

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

64       function updateAccountVersion(AccountAbstractionVersion _version) external onlySystemCall {
65           accountInfo[msg.sender].supportedAAVersion = _version;
66   
67           emit AccountVersionUpdated(msg.sender, _version);
68:      }

GitHub: 64

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

84       function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall {
85           IContractDeployer.AccountInfo memory accountInfo = DEPLOYER_SYSTEM_CONTRACT.getAccountInfo(msg.sender);
86   
87           require(_value != 0, "Nonce value cannot be set to 0");
88           // If an account has sequential nonce ordering, we enforce that the previous
89           // nonce has already been used.
90           if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) {
91               require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used");
92           }
93   
94           uint256 addressAsKey = uint256(uint160(msg.sender));
95   
96           nonceValues[addressAsKey][_key] = _value;
97   
98           emit ValueSetUnderNonce(msg.sender, _key, _value);
99:      }

GitHub: 84

File: cache-zk/solpp-generated-contracts/SystemContext.sol

89       function setTxOrigin(address _newOrigin) external onlyCallFromBootloader {
90           origin = _newOrigin;
91:      }

95       function setGasPrice(uint256 _gasPrice) external onlyCallFromBootloader {
96           gasPrice = _gasPrice;
97:      }

418      function setNewBatch(
419          bytes32 _prevBatchHash,
420          uint128 _newTimestamp,
421          uint128 _expectedNewNumber,
422          uint256 _baseFee
423      ) external onlyCallFromBootloader {
424          (uint128 previousBatchNumber, uint128 previousBatchTimestamp) = getBatchNumberAndTimestamp();
425          require(_newTimestamp > previousBatchTimestamp, "Timestamps should be incremental");
426          require(previousBatchNumber + 1 == _expectedNewNumber, "The provided block number is not correct");
427  
428          _ensureBatchConsistentWithL2Block(_newTimestamp);
429  
430          batchHash[previousBatchNumber] = _prevBatchHash;
431  
432          // Setting new block number and timestamp
433          BlockInfo memory newBlockInfo = BlockInfo({number: previousBatchNumber + 1, timestamp: _newTimestamp});
434  
435          currentBatchInfo = newBlockInfo;
436  
437          baseFee = _baseFee;
438  
439          // The correctness of this block hash:
440          SystemContractHelper.toL1(false, bytes32(uint256(SystemLogKey.PREV_BATCH_HASH_KEY)), _prevBatchHash);
441:     }

GitHub: 89, 95, 418

[L‑10] Division by zero not prevented

The divisions below take an input parameter or state variable which does not have any zero-value checks, which may lead to the functions reverting when zero is passed.

There is one instance of this issue:

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

180      /// @return The price of L2 gas in ETH
181      function _deriveL2GasPrice(uint256 _l1GasPrice, uint256 _gasPricePerPubdata) internal pure returns (uint256) {
182          uint256 pubdataPriceETH = L1_GAS_PER_PUBDATA_BYTE * _l1GasPrice;
183:         uint256 minL2GasPriceETH = (pubdataPriceETH + _gasPricePerPubdata - 1) / _gasPricePerPubdata;

GitHub: 180

[L‑11] Empty receive()/fallback() function

If the intention is for Ether sent by a caller to be used for an actual purpose (i.e. the function is not just a WETH withdraw() handler), the function should call another function (e.g. call weth.deposit() and use the token on the caller's behalf) or at least emit an event to track that funds were sent directly to it.

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

264:     receive() external payable {}

GitHub: 264

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

231      receive() external payable {
232          // If the contract is called directly, behave like an EOA
233:     }

GitHub: 231

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

14:      fallback() external payable {}

16:      receive() external payable {}

GitHub: 14, 16

[L‑12] External call recipient may consume all transaction gas

There is no limit specified on the amount of gas used, so the recipient can use up all of the transaction's gas, causing it to revert. Use addr.call{gas: <amount>}("") or this library instead.

There are 6 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

/// @audit `_execute()`
228:             (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);

GitHub: 228

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

/// @audit `bridgeBurn()`
83:          (bool success, ) = msg.sender.call{value: _amount}("");

/// @audit `withdrawTo()`
108:         (bool success, ) = _to.call{value: _amount}("");

GitHub: 83, 108

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

/// @audit `()`
44:              (bool success, ) = address(ETH_TOKEN_SYSTEM_CONTRACT).call(

GitHub: 44

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

/// @audit `sendValue()`
68:          (bool success, ) = recipient.call{value: amount}("");

/// @audit `functionCallWithValue()`
161:         (bool success, bytes memory returndata) = target.call{value: value}(

GitHub: 68, 161

[L‑13] External calls in an un-bounded for-loop may result in a DOS

Consider limiting the number of iterations in for-loops that make external calls

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

228:             (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);

GitHub: 228

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

256:             this.forceDeployOnAddress{value: _deployments[i].value}(_deployments[i], msg.sender);

GitHub: 256

[L‑14] File allows a version of solidity that is susceptible to an assembly optimizer bug

In solidity versions 0.8.13 and 0.8.14, there is an optimizer bug where, if the use of a variable is in a separate assembly block from the block in which it was stored, the mstore operation is optimized out, leading to uninitialized memory. The code currently does not have such a pattern of execution, but it does use mstores in assembly blocks, so it is a risk for future changes. The affected solidity versions should be avoided if at all possible.

There are 5 instances of this issue:

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

401              assembly {
402                  mstore(add(hashedFactoryDeps, mul(add(i, 1), 32)), hashedBytecode)
403:             }

GitHub: 401

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

43           assembly {
44               mstore(0x00, _lhs)
45               mstore(0x20, _rhs)
46               result := keccak256(0x00, 0x40)
47:          }

GitHub: 43

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

18           assembly {
19               // In the first byte we write the encoded length as 0x80 + 0x14 == 0x94.
20               mstore(add(encoded, 0x20), 0x9400000000000000000000000000000000000000000000000000000000000000)
21               // Write address data without stripping zeros.
22               mstore(add(encoded, 0x21), shiftedVal)
23:          }

41                   assembly {
42                       mstore(add(encoded, 0x21), shiftedVal)
43:                  }

76                   assembly {
77                       mstore(add(encoded, 0x21), shiftedVal)
78:                  }

GitHub: 18, 41, 76

[L‑15] File allows a version of solidity that is susceptible to an assembly storage bug

In solidity versions 0.8.13 through 0.8.16, there is a bug involving the use of the Yul functions return() and stop(). The affected solidity versions should be avoided if at all possible.

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

35           assembly {
36               // The pointer to the free memory slot
37               let ptr := mload(0x40)
38               // Copy function signature and arguments from calldata at zero position into memory at pointer position
39               calldatacopy(ptr, 0, calldatasize())
40               // Delegatecall method of the implementation contract returns 0 on error
41               let result := delegatecall(gas(), facetAddress, ptr, calldatasize(), 0, 0)
42               // Get the size of the last return data
43               let size := returndatasize()
44               // Copy the size length of bytes from return data at zero position to pointer position
45               returndatacopy(ptr, 0, size)
46               // Depending on the result value
47               switch result
48               case 0 {
49                   // End execution and revert state changes
50                   revert(ptr, size)
51               }
52               default {
53                   // Return data with length of size at pointers position
54                   return(ptr, size)
55               }
56:          }

GitHub: 35

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

136          assembly {
137              // Copy function signature and arguments from calldata at zero position into memory at pointer position
138              calldatacopy(0, 0, calldatasize())
139              // Call method of the zkSync contract returns 0 on error
140              let result := call(gas(), contractAddress, 0, 0, calldatasize(), 0, 0)
141              // Get the size of the last return data
142              let size := returndatasize()
143              // Copy the size length of bytes from return data at zero position to pointer position
144              returndatacopy(0, 0, size)
145              // Depending on the result value
146              switch result
147              case 0 {
148                  // End execution and revert state changes
149                  revert(0, size)
150              }
151              default {
152                  // Return data with length of size at pointers position
153                  return(0, size)
154              }
155:         }

GitHub: 136

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

33               assembly {
34                   return(0, 0)
35:              }

51               assembly {
52                   return(0, 0)
53:              }

GitHub: 33, 51

[L‑16] Function called does not exist in the contract interface

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

/// @audit safeApprove(address,uint256)
385:                  IERC20(token).safeApprove(paymaster, minAllowance);

GitHub: 385

[L‑17] Function doesn't perform any updates

The function's purpose appears to be to change a configuration value, but no such change is made.

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

191      function setValueForNextFarCall(uint128 _value) internal returns (bool success) {
192          uint256 cleanupMask = UINT128_MASK;
193          address callAddr = SET_CONTEXT_VALUE_CALL_ADDRESS;
194          assembly {
195              // Clearing input params as they are not cleaned by Solidity by default
196              _value := and(_value, cleanupMask)
197              success := call(0, callAddr, _value, 0, 0xFFFF, 0, 0)
198          }
199:     }

GitHub: 191

[L‑18] Initialization can be front-run

The initialize() functions below are not called by another contract atomically after the contract is deployed, so it's possible for a malicious user to call initialize() which, if it's noticed in time, would require the project to re-deploy the contract in order to properly initialize. Consider creating a factory contract, which will new and initialize() each contract atomically.

There are 6 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

85       function initialize(
86           bytes[] calldata _factoryDeps,
87           address _l2TokenBeacon,
88           address _governor,
89           uint256 _deployBridgeImplementationFee,
90           uint256 _deployBridgeProxyFee
91:      ) external payable reentrancyGuardInitializer {

GitHub: 85

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

83       function initialize(
84           bytes[] calldata _factoryDeps,
85           address _l2WethAddress,
86           address _governor,
87           uint256 _deployBridgeImplementationFee,
88           uint256 _deployBridgeProxyFee
89:      ) external payable reentrancyGuardInitializer {

GitHub: 83

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

57:      function initialize(InitializeData calldata _initalizeData) external reentrancyGuardInitializer returns (bytes32) {

GitHub: 57

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

42       function initialize(
43           address _l1Bridge,
44           bytes32 _l2TokenProxyBytecodeHash,
45           address _governor
46:      ) external initializer {

GitHub: 42

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

41:      function initialize(string memory name_, string memory symbol_) external initializer {

GitHub: 41

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

47       function initialize(
48           address _l1Bridge,
49           address _l1WethAddress,
50           address _l2WethAddress
51:      ) external initializer {

GitHub: 47

[L‑19] Loss of precision

Division by large numbers may result in the result being zero, due to solidity not supporting fractions. Consider requiring a minimum amount for the numerator to ensure that it is always larger than the denominator

There are 13 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

27:           uint256 bytecodeLenInWords = _bytecode.length / 32;

GitHub: 27

File: cache/solpp-generated-contracts/zksync/Config.sol

90:   uint256 constant BATCH_OVERHEAD_PUBDATA = BATCH_OVERHEAD_L1_GAS / L1_GAS_PER_PUBDATA_BYTE;

GitHub: 90

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

183:          uint256 minL2GasPriceETH = (pubdataPriceETH + _gasPricePerPubdata - 1) / _gasPricePerPubdata;

GitHub: 183

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

23:               uint256 mapValue = _map.map[_index / 8];

47:               uint256 mapIndex = _index / 8;

GitHub: 23, 47

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

35:               _index /= 2;

GitHub: 35

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

34:           require(l2GasForTxBody / _transaction.gasPerPubdataByteLimit <= PRIORITY_TX_MAX_PUBDATA, "uk");

167:              overheadForGas = (numerator - 1) / denominator;

GitHub: 34, 167

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

61:           return KECCAK_ROUND_GAS_COST * (_length / KECCAK_ROUND_NUMBER_OF_BYTES + 1);

72:           return SHA256_ROUND_GAS_COST * ((_length + 8) / SHA256_ROUND_NUMBER_OF_BYTES + 1);

230:              nodesOnCurrentLevel /= 2;

GitHub: 61, 72, 230

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

175:          deploymentNonce = _rawMinNonce / DEPLOY_NONCE_MULTIPLIER;

GitHub: 175

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

88:           uint256 bytecodeLenInWords = _bytecode.length / 32;

GitHub: 88

[L‑20] Missing checks for address(0x0) in the constructor/initializer

There are 8 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

68:          zkSync = _zkSync;

69:          allowList = _allowList;

GitHub: 68, 69

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

67:          l1WethAddress = _l1WethAddress;

68:          zkSync = _zkSync;

69:          allowList = _allowList;

GitHub: 67, 68, 69

File: cache/solpp-generated-contracts/governance/Governance.sol

48:          securityCouncil = _securityCouncil;

GitHub: 48

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

48:          zkSyncContract = _zkSyncContract;

50:          validator = _validator;

GitHub: 48, 50

[L‑21] Missing checks for address(0x0) when updating address state variables

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

56:          validator = _newValidator;

GitHub: 56

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

26:          s.pendingGovernor = _newPendingGovernor;

50:          s.pendingAdmin = _newPendingAdmin;

GitHub: 26, 50

File: cache-zk/solpp-generated-contracts/SystemContext.sol

90:          origin = _newOrigin;

GitHub: 90

[L‑22] Missing contract-existence checks before low-level calls

Low-level calls return success if there is no code present at the specified address. In addition to the zero-address checks, add a check to verify that <address>.code.length > 0

There are 9 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

243          (, bytes memory data1) = _token.staticcall(abi.encodeCall(IERC20Metadata.name, ()));
244          (, bytes memory data2) = _token.staticcall(abi.encodeCall(IERC20Metadata.symbol, ()));
245          (, bytes memory data3) = _token.staticcall(abi.encodeCall(IERC20Metadata.decimals, ()));
246          data = abi.encode(data1, data2, data3);
247:     }

244          (, bytes memory data2) = _token.staticcall(abi.encodeCall(IERC20Metadata.symbol, ()));
245          (, bytes memory data3) = _token.staticcall(abi.encodeCall(IERC20Metadata.decimals, ()));
246          data = abi.encode(data1, data2, data3);
247:     }

245          (, bytes memory data3) = _token.staticcall(abi.encodeCall(IERC20Metadata.decimals, ()));
246          data = abi.encode(data1, data2, data3);
247:     }

GitHub: 243, 244, 245

File: cache/solpp-generated-contracts/governance/Governance.sol

228              (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);
229              if (!success) {
230                  // Propage an error if the call fails.
231                  assembly {
232                      revert(add(returnData, 0x20), mload(returnData))
233:                 }

GitHub: 228

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

290              (bool success, bytes memory data) = _init.delegatecall(_calldata);
291              if (!success) {
292                  // If the returndata is too small, we still want to produce some meaningful error
293                  if (data.length <= 4) {
294                      revert("I"); // delegatecall failed
295:                 }

GitHub: 290

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

44               (bool success, ) = address(ETH_TOKEN_SYSTEM_CONTRACT).call(
45                   abi.encodeCall(ETH_TOKEN_SYSTEM_CONTRACT.transferFromTo, (msg.sender, to, value))
46               );
47   
48               // If the transfer of ETH fails, we do the most Ethereum-like behaviour in such situation: revert(0,0)
49:              if (!success) {

GitHub: 44

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

161          (bool success, bytes memory returndata) = target.call{value: value}(
162              data
163          );
164          return
165              verifyCallResultFromTarget(
166:                 target,

203          (bool success, bytes memory returndata) = target.staticcall(data);
204          return
205              verifyCallResultFromTarget(
206                  target,
207                  success,
208:                 returndata,

242          (bool success, bytes memory returndata) = target.delegatecall(data);
243          return
244              verifyCallResultFromTarget(
245                  target,
246                  success,
247:                 returndata,

GitHub: 161, 203, 242

[L‑23] Missing contract-existence checks before yul call()

Low-level calls return success if there is no code present at the specified address. In addition to the zero-address checks, add a check to verify that extcodesize() is non-zero.

There are 12 instances of this issue:

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

136          assembly {
137              // Copy function signature and arguments from calldata at zero position into memory at pointer position
138              calldatacopy(0, 0, calldatasize())
139              // Call method of the zkSync contract returns 0 on error
140              let result := call(gas(), contractAddress, 0, 0, calldatasize(), 0, 0)
141              // Get the size of the last return data
142              let size := returndatasize()
143              // Copy the size length of bytes from return data at zero position to pointer position
144              returndatacopy(0, 0, size)
145              // Depending on the result value
146              switch result
147              case 0 {
148                  // End execution and revert state changes
149                  revert(0, size)
150              }
151              default {
152                  // Return data with length of size at pointers position
153                  return(0, size)
154              }
155:         }

GitHub: 136

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

118          assembly {
119              callSuccess := call(gas(), _to, _amount, 0, 0, 0, 0)
120:         }

GitHub: 118

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

150              assembly {
151                  success := call(msgValueSimulator, callAddr, _value, _address, 0xFFFF, forwardMask, 0)
152:             }

137              assembly {
138                  success := call(_address, callAddr, 0, 0, 0xFFFF, 0, 0)
139:             }

205          assembly {
206              // Clearing values before usage in assembly, since Solidity
207              // doesn't do it by default
208              _whoToMimic := and(_whoToMimic, cleanupMask)
209  
210              success := call(_address, callAddr, 0, 0, _whoToMimic, 0, 0)
211:         }

GitHub: 150, 137, 205

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

79           assembly {
80               // Ensuring that the type is bool
81               _isService := and(_isService, 1)
82               // This `success` is always 0, but the method always succeeds
83               // (except for the cases when there is not enough gas)
84               let success := call(_isService, callAddr, _key, _value, 0xFFFF, 0, 0)
85:          }

194          assembly {
195              // Clearing input params as they are not cleaned by Solidity by default
196              _value := and(_value, cleanupMask)
197              success := call(0, callAddr, _value, 0, 0xFFFF, 0, 0)
198:         }

206          assembly {
207              pop(call(initializer, callAddr, value1, 0, 0xFFFF, 0, 0))
208:         }

216          assembly {
217              pop(call(value1, callAddr, value2, 0, 0xFFFF, 0, 0))
218:         }

GitHub: 79, 194, 206, 216

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

111              assembly {
112                  success := call(msgValueSimulator, callAddr, value, to, farCallAbi, forwardMask, 0)
113:             }

102              assembly {
103                  success := call(to, callAddr, 0, 0, farCallAbi, 0, 0)
104:             }

GitHub: 111, 102

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

401          assembly {
402              success := call(gas(), bootloaderAddr, amount, 0, 0, 0, 0)
403:         }

GitHub: 401

[L‑24] Multiplication on the result of a division

Dividing an integer by another integer will often result in loss of precision. When the result is multiplied by another number, the loss of precision is magnified, often to material magnitudes. (X / Z) * Y should be re-written as (X * Y) / Z

There are 2 instances of this issue:

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

61:          return KECCAK_ROUND_GAS_COST * (_length / KECCAK_ROUND_NUMBER_OF_BYTES + 1);

72:          return SHA256_ROUND_GAS_COST * ((_length + 8) / SHA256_ROUND_NUMBER_OF_BYTES + 1);

GitHub: 61, 72

[L‑25] Numbers downcast to addresses may result in collisions

If a number is downcast to an address the upper bytes are truncated, which may mean that more than one value will map to the address

There are 16 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

73:          return address(uint160(uint256(data)));

GitHub: 73

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

94:          address account = address(uint160(_input));

122:         address account = address(uint160(_input));

GitHub: 94, 122

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

63:          bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

149:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

243:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

GitHub: 63, 149, 243

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

108:         newAddress = address(uint160(uint256(hash)));

124:         newAddress = address(uint160(uint256(hash)));

GitHub: 108, 124

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

136:         address to = address(uint160(_transaction.to));

GitHub: 136

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

59:          return balance[address(uint160(_account))];

GitHub: 59

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

34:          to = address(uint160(addressAsUint));

GitHub: 34

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

166:         bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

234:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

305:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

377:             address paymaster = address(uint160(_transaction.paymaster));

408:         if (address(uint160(_transaction.paymaster)) != address(0)) {

GitHub: 166, 234, 305, 377, 408

[L‑26] Reviews of the input files to solpp are not the same as reviews of its output

Looking at what was deployed, there is an issue where the SPDX-License-Identifier is not the first line of the file, even though the audited file had as the first line. This is because of a bug in the deprecated solpp tool in use by the project. Audits should be done of the solpp output, rather than its inputs, in case there are other lurking bugs. I've run this bot on the output of solpp rather than the original templated dot-sol files, which are not strictly Solidity files.

There are 94 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: Apache-2.0

GitHub: 1

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowList.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowListed.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/L2ContractAddresses.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/governance/Governance.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/governance/IGovernance.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: Apache-2.0

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Config.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Storage.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: UNLICENSED

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

1    pragma solidity ^0.8.13;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/Compressor.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/Constants.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/SystemContext.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/INonceHolder.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymasterFlow.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContext.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContextDeprecated.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

1    pragma solidity ^0.8;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/UnsafeBytesCalldata.sol

1    pragma solidity ^0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

1    pragma solidity >=0.8.0;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

1    pragma solidity ^0.8.1;
2    
3:   // SPDX-License-Identifier: MIT

GitHub: 1

[L‑27] Solidity version 0.8.20 may not work on other chains due to PUSH0

The compiler for Solidity 0.8.20 switches the default target EVM version to Shanghai, which includes the new PUSH0 op code. This op code may not yet be implemented on all L2s, so deployment on these chains will fail. To work around this issue, use an earlier EVM version. While the project itself may or may not compile with 0.8.20, other projects with which it integrates, or which extend this project may, and those projects will have problems deploying these contracts/libraries.

There are 94 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowList.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowListed.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/L2ContractAddresses.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/governance/Governance.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/governance/IGovernance.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Config.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Storage.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

1:   pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/Compressor.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/Constants.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/SystemContext.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/INonceHolder.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymasterFlow.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContext.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContextDeprecated.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

1:   pragma solidity ^0.8;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/UnsafeBytesCalldata.sol

1:   pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

1:   pragma solidity >=0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

1:   pragma solidity ^0.8.1;

GitHub: 1

[L‑28] Some tokens may revert when large transfers are made

Tokens such as COMP or UNI will revert when an address' balance reaches type(uint96).max. Ensure that the calls below can be broken up into smaller batches if necessary.

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

/// @audit claimFailedDeposit()
274          require(proofValid, "yn");
275  
276          uint256 amount = depositAmount[_depositSender][_l1Token][_l2TxHash];
277          require(amount > 0, "y1");
278  
279          // Change the total deposited amount by the user
280          _verifyDepositLimit(_l1Token, _depositSender, amount, true);
281  
282          delete depositAmount[_depositSender][_l1Token][_l2TxHash];
283          // Withdraw funds
284:         IERC20(_l1Token).safeTransfer(_depositSender, amount);

/// @audit finalizeWithdrawal()
309  
310          (address l1Receiver, address l1Token, uint256 amount) = _parseL2WithdrawalMessage(l2ToL1Message.data);
311          // Preventing the stack too deep error
312          {
313              bool success = zkSync.proveL2MessageInclusion(_l2BatchNumber, _l2MessageIndex, l2ToL1Message, _merkleProof);
314              require(success, "nq");
315          }
316  
317          isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex] = true;
318          // Withdraw funds
319:         IERC20(l1Token).safeTransfer(l1Receiver, amount);

GitHub: 274, 309

[L‑29] State variables not capped at reasonable values

Consider adding minimum/maximum value checks to ensure that the state variables below can never be used to excessively harm users, including via griefing

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/common/AllowList.sol

133:         tokenDeposit[_l1Token].depositCap = _depositCap;

GitHub: 133

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

62:          executionDelay = _executionDelay;

GitHub: 62

File: cache-zk/solpp-generated-contracts/SystemContext.sol

96:          gasPrice = _gasPrice;

437:         baseFee = _baseFee;

GitHub: 96, 437

[L‑30] Subtraction may underflow if multiplication is too large

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/Compressor.sol

254:         number >>= (256 - (_calldataSlice.length * 8));

GitHub: 254

[L‑31] Unsafe downcast

When a type is downcast to a smaller type, the higher order bits are truncated, effectively applying a modulo to the original value. Without any other checks, this wrapping will lead to unexpected behavior and bugs

There are 64 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

/// @audit uint160 -> uint256
73:           return address(uint160(uint256(data)));

GitHub: 73

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

/// @audit uint32
86:               uint32 timestamp = uint32(block.timestamp);

GitHub: 86

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

/// @audit uint160
158:                  key: bytes32(uint256(uint160(_message.sender))),

/// @audit uint64
297:          uint64 expirationTimestamp = uint64(block.timestamp + PRIORITY_EXPIRATION); // Safe to cast

/// @audit uint160
338:              from: uint256(uint160(_priorityOpParams.sender)),

/// @audit uint160
339:              to: uint256(uint160(_priorityOpParams.contractAddressL2)),

/// @audit uint160
348:              reserved: [_priorityOpParams.valueToMint, uint256(uint160(_priorityOpParams.refundRecipient)), 0, 0],

GitHub: 158, 297, 338, 339, 348

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

/// @audit uint32
30:               result = uint32(mapValue >> bitOffset);

/// @audit uint32
58:               uint32 oldValue = uint32(mapValue >> bitOffset);

GitHub: 30, 58

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

/// @audit uint256 _input -> uint160
94:           address account = address(uint160(_input));

/// @audit uint256 _input -> uint160
122:          address account = address(uint160(_input));

GitHub: 94, 122

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

/// @audit uint160
63:           bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
70:               uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint8
93:               uint256 vInt = uint256(uint8(_transaction.signature[64]));

/// @audit uint256 listLength -> uint64
118:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

/// @audit uint160
149:              bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
166:              uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint8
192:              uint256 vInt = uint256(uint8(_transaction.signature[64]));

/// @audit uint256 listLength -> uint64
209:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

/// @audit uint160
243:              bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
261:              uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint8
287:              uint256 vInt = uint256(uint8(_transaction.signature[64]));

/// @audit uint256 listLength -> uint64
304:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

GitHub: 63, 70, 93, 118, 149, 166, 192, 209, 243, 261, 287, 304

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

/// @audit uint160 -> uint256
108:          newAddress = address(uint160(uint256(hash)));

/// @audit uint160 -> uint256
124:          newAddress = address(uint160(uint256(hash)));

/// @audit uint256 value -> uint128
344:                  SystemContractHelper.setValueForNextFarCall(uint128(value));

GitHub: 108, 124, 344

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

/// @audit uint160
136:          address to = address(uint160(_transaction.to));

GitHub: 136

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

/// @audit uint8
78:           uint8 version = uint8(_bytecodeHash[0]);

GitHub: 78

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

/// @audit uint160
135:              key: bytes32(uint256(uint160(msg.sender))),

GitHub: 135

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

/// @audit uint256 _account -> uint160
59:           return balance[address(uint160(_account))];

GitHub: 59

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

/// @audit uint256 addressAsUint -> uint160
34:           to = address(uint160(addressAsUint));

GitHub: 34

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

/// @audit uint160
70:           uint256 addressAsKey = uint256(uint160(msg.sender));

/// @audit uint160
94:           uint256 addressAsKey = uint256(uint160(msg.sender));

/// @audit uint160
105:          uint256 addressAsKey = uint256(uint160(msg.sender));

/// @audit uint160
113:          uint256 addressAsKey = uint256(uint160(msg.sender));

GitHub: 70, 94, 105, 113

File: cache-zk/solpp-generated-contracts/SystemContext.sol

/// @audit uint128 _blockNumber -> uint32
207:          return keccak256(abi.encodePacked(uint32(_blockNumber)));

/// @audit uint128
221:              bytes32 correctPrevBlockHash = _calculateLegacyL2BlockHash(uint128(_l2BlockNumber - 1));

/// @audit uint128
228:              _setL2BlockHash(uint128(_l2BlockNumber - 1), correctPrevBlockHash);

/// @audit uint256 _number -> uint128
/// @audit uint256 _newTimestamp -> uint128
450:          BlockInfo memory newBlockInfo = BlockInfo({number: uint128(_number), timestamp: uint128(_newTimestamp)});

GitHub: 207, 221, 228, 450, 450

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

/// @audit uint256 dataOffset -> uint32
261:          SystemContractHelper.ptrAddIntoActive(uint32(dataOffset));

/// @audit uint32
263:          uint32 shrinkTo = uint32(msg.data.length - (_data.length + dataOffset));

GitHub: 261, 263

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

/// @audit uint8
/// @audit uint256 _val -> uint8
31:                   encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val));

/// @audit uint8
36:                   encoded[0] = bytes1(uint8(hbs + 0x81));

/// @audit uint8
66:                   encoded[0] = bytes1(uint8(_len + _offset));

/// @audit uint8
71:                   encoded[0] = bytes1(uint8(_offset + hbs + 56));

GitHub: 31, 31, 36, 66, 71

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

/// @audit uint160
357:          return uint160(_address) <= uint160(MAX_SYSTEM_CONTRACT_ADDRESS);

GitHub: 357

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

/// @audit uint32
85:           uint32 dataLength = uint32(Utils.safeCastToU32(data.length));

GitHub: 85

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

/// @audit uint160
166:          bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
173:              uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint256 listLength -> uint64
201:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

/// @audit uint160
234:              bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
251:              uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint256 listLength -> uint64
273:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

/// @audit uint160
305:              bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

/// @audit uint64
323:              uint64 txDataLen = uint64(_transaction.data.length);

/// @audit uint256 listLength -> uint64
345:              encodedListLength = RLPEncoder.encodeListLen(uint64(listLength));

/// @audit uint160
377:              address paymaster = address(uint160(_transaction.paymaster));

/// @audit uint160
408:          if (address(uint160(_transaction.paymaster)) != address(0)) {

GitHub: 166, 173, 201, 234, 251, 273, 305, 323, 345, 377, 408

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

/// @audit uint256 _x -> uint128
25:           return uint128(_x);

/// @audit uint256 _x -> uint32
31:           return uint32(_x);

/// @audit uint256 _x -> uint24
37:           return uint24(_x);

/// @audit uint8
48:               codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

GitHub: 25, 31, 37, 48

[L‑32] Upgradeable contract is missing a __gap[50] storage variable to allow for new storage variables in later versions

See this link for a description of this storage variable. While some contracts may not currently be sub-classed, adding the variable now protects against forgetting to add it in the future.

There are 2 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

13:   contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken {

GitHub: 13

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

23:   contract L2Weth is ERC20PermitUpgradeable, IL2Weth, IL2StandardToken {

GitHub: 23

[L‑33] Use of tx.origin is unsafe in almost every context

According to Vitalik Buterin, contracts should not assume that tx.origin will continue to be usable or meaningful. An example of this is EIP-3074 which explicitly mentions the intention to change its semantics when it's used with new op codes. There have also been calls to remove tx.origin, and there are security issues associated with using it for authorization. For these reasons, it's best to completely avoid the feature.

There are 3 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

197          if (_refundRecipient == address(0)) {
198:             refundRecipient = msg.sender != tx.origin ? AddressAliasHelper.applyL1ToL2Alias(msg.sender) : msg.sender;

GitHub: 197

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

184          if (_refundRecipient == address(0)) {
185:             refundRecipient = msg.sender != tx.origin ? AddressAliasHelper.applyL1ToL2Alias(msg.sender) : msg.sender;

GitHub: 184

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

249          address sender = msg.sender;
250:         if (sender != tx.origin) {

GitHub: 249

[L‑34] Use of a single-step ownership transfer

The existing transferOwnership function immediately transfers ownership to the new addres. Consider implementing a two-step variant, where the 'acceptor' of the ownership must call a separate function in order for the transfer to take effect. This can help to prevent mistakes where the wrong address is used, and ownership is irrecoverably lost.

There are 3 instances of this issue:

File: cache/solpp-generated-contracts/common/AllowList.sol

33       constructor(address _initialOwner) {
34           _transferOwnership(_initialOwner);
35:      }

GitHub: 33

File: cache/solpp-generated-contracts/governance/Governance.sol

43       constructor(address _admin, address _securityCouncil, uint256 _minDelay) {
44           require(_admin != address(0), "Admin should be non zero address");
45   
46           _transferOwnership(_admin);
47   
48           securityCouncil = _securityCouncil;
49           emit ChangeSecurityCouncil(address(0), _securityCouncil);
50   
51           minDelay = _minDelay;
52           emit ChangeMinDelay(0, _minDelay);
53:      }

GitHub: 43

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

46       constructor(address _initialOwner, address _zkSyncContract, uint32 _executionDelay, address _validator) {
47           _transferOwnership(_initialOwner);
48           zkSyncContract = _zkSyncContract;
49           executionDelay = _executionDelay;
50           validator = _validator;
51:      }

GitHub: 46

Non-critical Issues

[N‑01] 2**<n> - 1 should be re-written as type(uint<n>).max

Earlier versions of solidity can use uint<n>(-1) instead. Expressions not including the - 1 can often be re-written to accomodate the change (e.g. by using a > rather than a >=, which will also save some gas)

There are 6 instances of this issue:

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

28:           require(bytecodeLenInWords < 2**16, "pp"); // bytecode length must be less than 2^16 words

GitHub: 28

File: cache-zk/solpp-generated-contracts/Compressor.sol

64:               require(dictionary.length <= 2 ** 16 * 8, "Dictionary is too big");

GitHub: 64

File: cache-zk/solpp-generated-contracts/Constants.sol

75:   uint256 constant MAX_MSG_VALUE = 2 ** 128 - 1;

GitHub: 75

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

30:       uint256 constant DEPLOY_NONCE_MULTIPLIER = 2 ** 128;

33:       uint256 constant MAXIMAL_MIN_NONCE_INCREMENT = 2 ** 32;

GitHub: 30, 33

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

89:           require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words

GitHub: 89

[N‑02] addresses shouldn't be hard-coded

It is often better to declare addresses as immutable, and assign them via constructor arguments. This allows the code to remain the same across deployments on different networks, and avoids recompilation when addresses need to change.

There is one instance of this issue:

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

24:      uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);

GitHub: 24

[N‑03] constants should be defined rather than using magic numbers

Even assembly can benefit from using readable constants instead of hex/numeric literals

There are 174 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

95:          require(_factoryDeps.length == 3, "mk");

331:         require(_l2ToL1message.length == 76, "kk");

GitHub: 95, 331

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

281:         require(_message.length == 96, "Incorrect ETH message with additional data length");

GitHub: 281

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

25:          require(_bytecode.length % 32 == 0, "pq");

27:          uint256 bytecodeLenInWords = _bytecode.length / 32;

28:          require(bytecodeLenInWords < 2**16, "pp"); // bytecode length must be less than 2^16 words

30:          hashedBytecode = sha256(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

32:          hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248)));

34:          hashedBytecode = hashedBytecode | bytes32(bytecodeLenInWords << 224);

52:          codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

GitHub: 25, 27, 28, 30, 32, 34, 52, 52

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

89:          assert(L2_TO_L1_LOG_SERIALIZE_SIZE != 2 * 32);

GitHub: 89

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

27:          require(msg.data.length >= 4 || msg.data.length == 0, "Ut");

GitHub: 27

File: cache/solpp-generated-contracts/zksync/Storage.sol

83:      uint256[7] __DEPRECATED_diamondCutStorage;

GitHub: 83

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

82:          uint256 batchTimestamp = _packedBatchAndL2BlockTimestamp >> 128;

171:             require(processedLogs == 255, "b8");

169:             require(processedLogs == 127, "b7");

GitHub: 82, 171, 169

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

423:         require(_message.length >= 56, "pm");

GitHub: 423

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

56:          uint256[4] reserved;

GitHub: 56

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

293:                 if (data.length <= 4) {

304:             require(data.length == 32, "lp");

GitHub: 293, 304

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

23:              uint256 mapValue = _map.map[_index / 8];

27:              uint256 bitOffset = (_index & 7) * 32;

47:              uint256 mapIndex = _index / 8;

52:              uint256 bitOffset = (_index & 7) * 32;

GitHub: 23, 27, 27, 47, 52, 52

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

27:          require(pathLength < 256, "bt");

GitHub: 27

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

59:          require(_transaction.reserved[3] == 0, "uo");

85:              costForComputation += Math.ceilDiv(_encodingLength * L1_TX_DELTA_544_ENCODING_BYTES, 544);

GitHub: 59, 85

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

48:          emit Initialize(name_, symbol_, 18);

GitHub: 48

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

104:         if (codeHash == 0x00 && NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(account) > 0) {

135:             codeHash != 0x00 &&

GitHub: 104, 135

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

74:              } else if (_transaction.data[0] >= 0x80) {

83:              uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

88:              uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

93:              uint256 vInt = uint256(uint8(_transaction.signature[64]));

94:              require(vInt == 27 || vInt == 28, "Invalid v value");

99:                  vInt += 8 + block.chainid * 2;

170:             } else if (_transaction.data[0] >= 0x80) {

182:             uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

187:             uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

192:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

193:             require(vInt == 27 || vInt == 28, "Invalid v value");

195:             vEncoded = RLPEncoder.encodeUint256(vInt - 27);

265:             } else if (_transaction.data[0] >= 0x80) {

277:             uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

282:             uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

287:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

288:             require(vInt == 27 || vInt == 28, "Invalid v value");

290:             vEncoded = RLPEncoder.encodeUint256(vInt - 27);

GitHub: 74, 83, 88, 88, 93, 94, 94, 99, 170, 182, 187, 187, 192, 193, 193, 195, 265, 277, 282, 282, 287, 288, 288, 290

File: cache-zk/solpp-generated-contracts/Compressor.sol

63:              require(dictionary.length % 8 == 0, "Dictionary length should be a multiple of 8");

64:              require(dictionary.length <= 2 ** 16 * 8, "Dictionary is too big");

66:                  encodedData.length * 4 == _bytecode.length,

71:                  uint256 indexOfEncodedChunk = uint256(encodedData.readUint16(encodedDataPointer)) * 8;

75:                  uint64 realChunk = _bytecode.readUint64(encodedDataPointer * 4);

138:             uint64 enumIndex = stateDiff.readUint64(84);

146:             bytes32 derivedKey = stateDiff.readBytes32(52);

147:             uint256 initValue = stateDiff.readUint256(92);

148:             uint256 finalValue = stateDiff.readUint256(124);

150:             stateDiffPtr += 32;

155:             uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET;

170:             uint64 enumIndex = stateDiff.readUint64(84);

175:             uint256 initValue = stateDiff.readUint256(92);

176:             uint256 finalValue = stateDiff.readUint256(124);

184:             uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET;

210:             dictionary = _rawCompressedData[2:2 + dictionaryLen * 8];

211:             encodedData = _rawCompressedData[2 + dictionaryLen * 8:];

236:             if (_operation == 0 || _operation == 3) {

254:         number >>= (256 - (_calldataSlice.length * 8));

GitHub: 63, 64, 64, 66, 71, 75, 138, 146, 147, 148, 150, 155, 170, 175, 176, 184, 210, 211, 236, 254, 254

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

266:         require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero");

271:             ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0,

275:         require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied");

GitHub: 266, 271, 275

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

143:         if (to == address(DEPLOYER_SYSTEM_CONTRACT) && data.length >= 4) {

144:             bytes4 selector = bytes4(data[:4]);

164:         require(_signature.length == 65, "Signature length is incorrect");

177:         require(v == 27 || v == 28, "v is neither 27 nor 28");

188:         require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s");

GitHub: 143, 144, 164, 177, 177, 188

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

72:          return SHA256_ROUND_GAS_COST * ((_length + 8) / SHA256_ROUND_NUMBER_OF_BYTES + 1);

95:          uint256 gasToPay = keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) + 3 * keccakGasCost(64);

148:             pubdataLen = 4 + _message.length + L2_TO_L1_LOG_SERIALIZE_SIZE;

158:             4 *

159:             keccakGasCost(64) +

181:             pubdataLen = 4 + bytecodeLen;

185:         uint256 gasToPay = pubdataLen * gasPerPubdataBytes + sha256GasCost(bytecodeLen) + keccakGasCost(64);

207:         uint32 numberOfL2ToL1Logs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

209:         calldataPtr += 4;

240:         uint32 numberOfMessages = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

241:         calldataPtr += 4;

244:             uint32 currentMessageLength = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

245:             calldataPtr += 4;

258:         uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

259:         calldataPtr += 4;

263:                 bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])

265:             calldataPtr += 4;

293:         uint24 compressedStateDiffSize = uint24(bytes3(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 3]));

294:         calldataPtr += 3;

307:         uint32 numberOfStateDiffs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

308:         calldataPtr += 4;

GitHub: 72, 95, 95, 148, 158, 159, 181, 185, 207, 209, 240, 241, 244, 245, 258, 259, 263, 265, 293, 294, 307, 308

File: cache-zk/solpp-generated-contracts/SystemContext.sol

46:      uint256 public difficulty = 2500000000000000;

117:         if (blockNumber <= _block || blockNumber - _block > 256) {

390:         uint256 packedTimestamps = (uint256(currentBatchTimestamp) << 128) | currentL2BlockTimestamp;

472:         blockInfo = (uint256(blockNumber) << 128) | uint256(blockTimestamp);

GitHub: 46, 117, 390, 472

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

40:          require(returnData.length == 32, "keccak256 returned invalid data");

49:          require(returnData.length == 32, "sha returned invalid data");

GitHub: 40, 49

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

15:          encoded = new bytes(0x15);

28:              if (_val < 128) {

36:                  encoded[0] = bytes1(uint8(hbs + 0x81));

38:                  uint256 lbs = 31 - hbs;

39:                  uint256 shiftedVal = _val << (lbs * 8);

31:                  encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val));

53:          return _encodeLength(_len, 0x80);

59:          return _encodeLength(_len, 0xc0);

64:              if (_len < 56) {

71:                  encoded[0] = bytes1(uint8(_offset + hbs + 56));

73:                  uint256 lbs = 31 - hbs;

74:                  uint256 shiftedVal = uint256(_len) << (lbs * 8);

89:                  _number >>= 128;

90:                  hbs += 16;

93:                  _number >>= 64;

94:                  hbs += 8;

97:                  _number >>= 32;

98:                  hbs += 4;

101:                 _number >>= 16;

GitHub: 15, 28, 36, 38, 39, 31, 53, 59, 64, 71, 73, 74, 89, 90, 93, 94, 97, 98, 101

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

161:         rawParams |= uint256(_inputMemoryLength) << 32;

162:         rawParams |= uint256(_outputMemoryOffset) << 64;

163:         rawParams |= uint256(_outputMemoryLength) << 96;

164:         rawParams |= uint256(_perPrecompileInterpreted) << 192;

239:         uint256 shifted = (meta << (256 - size - offset));

241:         result = (shifted >> (256 - size));

249:         gasPerPubdataByte = uint32(extractNumberFromMeta(meta, META_GAS_PER_PUBDATA_BYTE_OFFSET, 32));

259:         heapSize = uint32(extractNumberFromMeta(meta, META_HEAP_SIZE_OFFSET, 32));

268:         auxHeapSize = uint32(extractNumberFromMeta(meta, META_AUX_HEAP_SIZE_OFFSET, 32));

276:         shardId = uint8(extractNumberFromMeta(meta, META_SHARD_ID_OFFSET, 8));

285:         callerShardId = uint8(extractNumberFromMeta(meta, META_CALLER_SHARD_ID_OFFSET, 8));

294:         codeShardId = uint8(extractNumberFromMeta(meta, META_CODE_SHARD_ID_OFFSET, 8));

GitHub: 161, 162, 163, 164, 239, 241, 249, 259, 268, 276, 285, 294

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

237:         farCallAbi |= (uint256(memoryPage) << 32);

238:         farCallAbi |= (uint256(dataStart) << 64);

239:         farCallAbi |= (uint256(dataLength) << 96);

259:         farCallAbiWithEmptyFatPtr |= (uint256(gasPassed) << 192);

260:         farCallAbiWithEmptyFatPtr |= (uint256(forwardingMode) << 224);

261:         farCallAbiWithEmptyFatPtr |= (uint256(shardId) << 232);

263:             farCallAbiWithEmptyFatPtr |= (1 << 240);

266:             farCallAbiWithEmptyFatPtr |= (1 << 248);

GitHub: 237, 238, 239, 259, 260, 261, 263, 266

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

59:      uint256[4] reserved;

177:             } else if (_transaction.data[0] >= 0x80) {

255:             } else if (_transaction.data[0] >= 0x80) {

327:             } else if (_transaction.data[0] >= 0x80) {

365:         require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long");

367:         bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]);

370:                 _transaction.paymasterInput.length >= 68,

376:             (address token, uint256 minAllowance) = abi.decode(_transaction.paymasterInput[4:68], (address, uint256));

GitHub: 59, 177, 255, 327, 365, 367, 370, 376, 376

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

42:          codeLength = bytecodeLenInWords(_bytecodeHash) << 5; // _bytecodeHash * 32

48:              codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

54:          return _bytecodeHash[1] == 0x00;

59:          return _bytecodeHash[1] == 0x01;

86:          require(_bytecode.length % 32 == 0, "po");

88:          uint256 bytecodeLenInWords = _bytecode.length / 32;

89:          require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words

93:              0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

95:          hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248)));

97:          hashedBytecode = hashedBytecode | bytes32(bytecodeLenInWords << 224);

GitHub: 42, 48, 48, 54, 59, 86, 88, 89, 93, 95, 97

[N‑04] else-block not required

One level of nesting can be removed by not having an else block when the if-block returns, and if (foo) { return 1; } else { return 2; } becomes if (foo) { return 1; } return 2;. A following else if can become if

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

109          if (timestamp == 0) {
110              return OperationState.Unset;
111          } else if (timestamp == EXECUTED_PROPOSAL_TIMESTAMP) {
112              return OperationState.Done;
113          } else if (timestamp > block.timestamp) {
114              return OperationState.Waiting;
115          } else {
116              return OperationState.Ready;
117:         }

GitHub: 109

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

287          if (success) {
288              return returndata;
289          } else {
290              _revert(returndata, errorMessage);
291:         }

GitHub: 287

[N‑05] if-statement can be converted to a ternary

The code can be made more compact while also increasing readability by converting the following if-statements to ternaries (e.g. foo += (x > y) ? a : b)

There are 3 instances of this issue:

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

104          if (_isValidSignature(txHash, _transaction.signature)) {
105              magic = ACCOUNT_VALIDATION_SUCCESS_MAGIC;
106          } else {
107              magic = bytes4(0);
108:         }

GitHub: 104

File: cache-zk/solpp-generated-contracts/SystemContext.sol

123          } else if (
124              _block >= currentVirtualBlockUpgradeInfo.virtualBlockFinishL2Block &&
125              currentVirtualBlockUpgradeInfo.virtualBlockFinishL2Block > 0
126          ) {
127              hash = _getLatest257L2blockHash(_block);
128          } else {
129              // Important: we do not want this number to ever collide with the L2 block hash (either new or old one) and so
130              // that's why the legacy L2 blocks' hashes are keccak256(abi.encodePacked(uint32(_block))), while these are equivalent to
131              // keccak256(abi.encodePacked(_block))
132              hash = keccak256(abi.encode(_block));
133:         }

GitHub: 123

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

408          if (address(uint160(_transaction.paymaster)) != address(0)) {
409              // Paymaster pays for the fee
410              requiredBalance = _transaction.value;
411          } else {
412              // The user should have enough balance for both the fee and the value of the transaction
413              requiredBalance = _transaction.maxFeePerGas * _transaction.gasLimit + _transaction.value;
414:         }

GitHub: 408

[N‑06] internal functions not called by the contract should be removed

All unused code should be removed

There is one instance of this issue:

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

410:     function _maxU256(uint256 a, uint256 b) internal pure returns (uint256) {

GitHub: 410

[N‑07] public functions not called by the contract should be declared external instead

Contracts are allowed to override their parents' functions and change the visibility from external to public.

There are 18 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

355:      function l2TokenAddress(address _l1Token) public view returns (address) {

GitHub: 355

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

304:      function l2TokenAddress(address _l1Token) public view override returns (address l2Token) {

GitHub: 304

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

69:       function upgrade(ProposedUpgrade calldata _proposedUpgrade) public virtual returns (bytes32) {

GitHub: 69

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

27:       function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) {

GitHub: 27

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

84        function proveL1ToL2TransactionStatus(
85            bytes32 _l2TxHash,
86            uint256 _l2BatchNumber,
87            uint256 _l2MessageIndex,
88            uint16 _l2TxNumberInBatch,
89            bytes32[] calldata _merkleProof,
90            TxStatus _status
91:       ) public view override returns (bool) {

168       function l2TransactionBaseCost(
169           uint256 _gasPrice,
170           uint256 _l2GasLimit,
171           uint256 _l2GasPerPubdataByteLimit
172:      ) public pure returns (uint256) {

GitHub: 84, 168

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

125:      function name() public view override returns (string memory) {

131:      function symbol() public view override returns (string memory) {

137:      function decimals() public view override returns (uint8) {

GitHub: 125, 131, 137

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

112:      function l1TokenAddress(address _l2Token) public view override returns (address l1Token) {

117:      function l2TokenAddress(address _l1Token) public view override returns (address l2Token) {

GitHub: 112, 117

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

42:       function extendedAccountVersion(address _address) public view returns (AccountAbstractionVersion) {

GitHub: 42

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

59:       function getRawNonce(address _address) public view returns (uint256) {

67:       function increaseMinNonce(uint256 _value) public onlySystemCall returns (uint256 oldMinNonce) {

84:       function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall {

104:      function getValueUnderNonce(uint256 _key) public view returns (uint256) {

GitHub: 59, 67, 84, 104

File: cache-zk/solpp-generated-contracts/SystemContext.sol

163:      function getBlockNumber() public view returns (uint128) {

171:      function getBlockTimestamp() public view returns (uint128) {

GitHub: 163, 171

[N‑08] pure function accesses storage

While the compiler currently flags functions like these as being pure, this is a bug which will be fixed in a future version, so it's best to not use pure visibility, in order to not break when this bug is fixed.

There is one instance of this issue:

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

88       function getDiamondStorage() internal pure returns (DiamondStorage storage diamondStorage) {
89           bytes32 position = DIAMOND_STORAGE_POSITION;
90           assembly {
91               diamondStorage.slot := position
92           }
93:      }

GitHub: 88

[N‑09] require()/revert() statements should have descriptive reason strings

There are 3 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

127:         if (availableGetters.ignoreName) revert();

133:         if (availableGetters.ignoreSymbol) revert();

139:         if (availableGetters.ignoreDecimals) revert();

GitHub: 127, 133, 139

[N‑10] Add inline comments for unnamed variables

function foo(address x, address) -> function foo(address x, address /* y */)

There are 12 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

333:          (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_l2ToL1message, 0);

334           require(bytes4(functionSignature) == this.finalizeWithdrawal.selector, "nt");
335   
336:          (l1Receiver, offset) = UnsafeBytes.readAddress(_l2ToL1message, offset);

GitHub: 333, 334

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

283:          (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);

285               bytes4(functionSignature) == IMailbox.finalizeEthWithdrawal.selector,
286               "Incorrect ETH message function selector"
287           );
288   
289           address l1EthReceiver;
290:          (l1EthReceiver, offset) = UnsafeBytes.readAddress(_message, offset);

GitHub: 283, 285

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

38                // Copy function signature and arguments from calldata at zero position into memory at pointer position
39:               calldatacopy(ptr, 0, calldatasize())

GitHub: 38

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

137               // Copy function signature and arguments from calldata at zero position into memory at pointer position
138:              calldatacopy(0, 0, calldatasize())

GitHub: 137

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

425:          (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);

426           require(bytes4(functionSignature) == this.finalizeEthWithdrawal.selector, "is");
427   
428:          (l1Receiver, offset) = UnsafeBytes.readAddress(_message, offset);

GitHub: 425, 426

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

32                // If function was called outside of the bootloader, behave like an EOA.
33                assembly {
34:                   return(0, 0)

50                // If the function was delegate called, behave like an EOA.
51                assembly {
52:                   return(0, 0)

145               // Check that called function is the deployment method,
146               // the others deployer method is not supposed to be called from the default account.
147               isSystemCall =
148                   selector == DEPLOYER_SYSTEM_CONTRACT.create.selector ||
149                   selector == DEPLOYER_SYSTEM_CONTRACT.create2.selector ||
150                   selector == DEPLOYER_SYSTEM_CONTRACT.createAccount.selector ||
151                   selector == DEPLOYER_SYSTEM_CONTRACT.create2Account.selector;
152           }
153:          bool success = EfficientCall.rawCall(gas, to, value, data, isSystemCall);

GitHub: 32, 50, 145

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

117:          return functionCallWithValue(target, data, 0, errorMessage);

GitHub: 117

[N‑11] Adding a return statement when the function defines a named return variable, is redundant

Once the return variable has been assigned (or has its default value), there is no need to explicitly return it at the end of the function, since it's returned automatically.

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

131:         return deploymentNonce;

GitHub: 131

[N‑12] Array indices should be referenced via enums rather than via numeric literals

There are 39 instances of this issue:

see instances
File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

287:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

GitHub: 287

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

241:         s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber;

GitHub: 241

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

57:          require(_transaction.reserved[1] <= type(uint160).max, "uf");

GitHub: 57

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

93:              uint256 vInt = uint256(uint8(_transaction.signature[64]));

265:             } else if (_transaction.data[0] >= 0x80) {

GitHub: 93, 265

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

102:         bytes32 l2BridgeProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[1]);

GitHub: 102

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

43:          require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash

GitHub: 43

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

56:          require(_transaction.reserved[0] == 0, "ue");

GitHub: 56

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

192:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

GitHub: 192

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

78:          uint8 version = uint8(_bytecodeHash[0]);

GitHub: 78

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

101:         bytes32 l2BridgeImplementationBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[0]);

GitHub: 101

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

100:         bytes32 l2WethBridgeImplementationBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[0]);

GitHub: 100

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

42:          uint8 version = uint8(_bytecodeHash[0]);

52:          codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

GitHub: 42, 52

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

144:             bytes4 selector0 = ds.facetToSelectors[_facet].selectors[0];

GitHub: 144

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

58:          require(_transaction.reserved[2] == 0, "ug");

GitHub: 58

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

98:              if (_transaction.reserved[0] != 0) {

GitHub: 98

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

52:          codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

GitHub: 52

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

221:             bytes4 selector0 = ds.facetToSelectors[_facet].selectors[0];

GitHub: 221

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

59:          require(_transaction.reserved[3] == 0, "uo");

GitHub: 59

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

170:             } else if (_transaction.data[0] >= 0x80) {

GitHub: 170

File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

98:          l2TokenProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[2]);

GitHub: 98

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

101:         bytes32 l2WethBridgeProxyBytecodeHash = L2ContractHelper.hashL2Bytecode(_factoryDeps[1]);

GitHub: 101

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

79:          s.storedBatchHashes[0] = keccak256(abi.encode(storedBatchZero));

GitHub: 79

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

74:              } else if (_transaction.data[0] >= 0x80) {

GitHub: 74

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

79:          require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash");

GitHub: 79

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

237:         bytes32 l2ToL1LogsTreeRoot = l2ToL1LogsTreeArray[0];

GitHub: 237

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

36:                  encoded[0] = bytes1(uint8(hbs + 0x81));

31:                  encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val));

71:                  encoded[0] = bytes1(uint8(_offset + hbs + 56));

66:                  encoded[0] = bytes1(uint8(_len + _offset));

GitHub: 36, 31, 71, 66

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

177:             } else if (_transaction.data[0] >= 0x80) {

186:         if (_transaction.reserved[0] != 0) {

255:             } else if (_transaction.data[0] >= 0x80) {

327:             } else if (_transaction.data[0] >= 0x80) {

GitHub: 177, 186, 255, 327

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

48:              codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

54:          return _bytecodeHash[1] == 0x00;

59:          return _bytecodeHash[1] == 0x01;

GitHub: 48, 48, 54, 59

[N‑13] Assembly block creates dirty bits

Writing data to the free memory pointer without later updating the free memory pointer will cause there to be dirty bits at that memory location. Not updating the free memory pointer will make it harder for the optimizer to reason about whether the memory needs to be cleaned, which may lead to worse optimizations. Annotate the block with assembly ("memory-safe") { ... } if the memory's value can be discarded. If the memory needs to be saved, update the free memory pointer in addtion to using the annotation. See this link for other cases where the annotation can be used

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

34   
35           assembly {
36               // The pointer to the free memory slot
37               let ptr := mload(0x40)
38               // Copy function signature and arguments from calldata at zero position into memory at pointer position
39               calldatacopy(ptr, 0, calldatasize())
40               // Delegatecall method of the implementation contract returns 0 on error
41               let result := delegatecall(gas(), facetAddress, ptr, calldatasize(), 0, 0)
42               // Get the size of the last return data
43               let size := returndatasize()
44               // Copy the size length of bytes from return data at zero position to pointer position
45               returndatacopy(ptr, 0, size)
46               // Depending on the result value
47               switch result
48               case 0 {
49                   // End execution and revert state changes
50                   revert(ptr, size)
51               }
52               default {
53                   // Return data with length of size at pointers position
54                   return(ptr, size)
55               }
56:          }

GitHub: 34

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

171          // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask
172          assembly {
173              r := mload(add(_signature, 0x20))
174              s := mload(add(_signature, 0x40))
175              v := and(mload(add(_signature, 0x41)), 0xff)
176:         }

GitHub: 171

[N‑14] Assembly blocks should have extensive comments

Assembly blocks take a lot more time to audit than normal Solidity code, and often have gotchas and side-effects that the Solidity versions of the same code do not. Consider adding more comments explaining what is being done in every step of the assembly code, and describe why assembly is being used instead of Solidity.

There are 55 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

54            assembly {
55                lockSlotOldValue := sload(LOCK_FLAG_ADDRESS)
56                sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED)
57:           }

72            assembly {
73                _status := sload(LOCK_FLAG_ADDRESS)
74:           }

80            assembly {
81                sstore(LOCK_FLAG_ADDRESS, _ENTERED)
82:           }

88            assembly {
89                sstore(LOCK_FLAG_ADDRESS, _NOT_ENTERED)
90:           }

GitHub: 54, 72, 80, 88

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

22            assembly {
23                offset := add(_start, 4)
24                result := mload(add(_bytes, offset))
25:           }

29            assembly {
30                offset := add(_start, 20)
31                result := mload(add(_bytes, offset))
32:           }

36            assembly {
37                offset := add(_start, 32)
38                result := mload(add(_bytes, offset))
39:           }

43            assembly {
44                offset := add(_start, 32)
45                result := mload(add(_bytes, offset))
46:           }

GitHub: 22, 29, 36, 43

File: cache/solpp-generated-contracts/governance/Governance.sol

231                   assembly {
232                       revert(add(returnData, 0x20), mload(returnData))
233:                  }

GitHub: 231

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

118           assembly {
119               callSuccess := call(gas(), _to, _amount, 0, 0, 0, 0)
120:          }

401               assembly {
402                   mstore(add(hashedFactoryDeps, mul(add(i, 1), 32)), hashedBytecode)
403:              }

GitHub: 118, 401

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

90            assembly {
91                diamondStorage.slot := position
92:           }

297                   assembly {
298                       revert(add(data, 0x20), mload(data))
299:                  }

GitHub: 90, 297

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

43            assembly {
44                mstore(0x00, _lhs)
45                mstore(0x20, _rhs)
46                result := keccak256(0x00, 0x40)
47:           }

GitHub: 43

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

72            assembly {
73                sstore(addressAsKey, _hash)
74:           }

83            assembly {
84                codeHash := sload(addressAsKey)
85:           }

GitHub: 72, 83

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

28            assembly {
29                if iszero(success) {
30                    revert(add(returnData, 0x20), mload(returnData))
31                }
32:           }

GitHub: 28

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

33                assembly {
34                    return(0, 0)
35:               }

51                assembly {
52                    return(0, 0)
53:               }

172           assembly {
173               r := mload(add(_signature, 0x20))
174               s := mload(add(_signature, 0x40))
175               v := and(mload(add(_signature, 0x41)), 0xff)
176:          }

GitHub: 33, 51, 172

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

58                assembly {
59                    sstore(_bytecodeHash, 1)
60:               }

69            assembly {
70                marker := sload(_hash)
71:           }

GitHub: 58, 69

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

50                    assembly {
51                        revert(0, 0)
52:                   }

GitHub: 50

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

137               assembly {
138                   success := call(_address, callAddr, 0, 0, 0xFFFF, 0, 0)
139:              }

150               assembly {
151                   success := call(msgValueSimulator, callAddr, _value, _address, 0xFFFF, forwardMask, 0)
152:              }

165           assembly {
166               success := staticcall(_address, callAddr, 0, 0xFFFF, 0, 0)
167:          }

179           assembly {
180               success := delegatecall(_address, callAddr, 0, 0xFFFF, 0, 0)
181:          }

220               assembly {
221                   size := returndatasize()
222:              }

225               assembly {
226                   returndatacopy(add(returnData, 0x20), 0, size)
227:              }

235           assembly {
236               let size := returndatasize()
237               returndatacopy(0, 0, size)
238               revert(0, size)
239:          }

256           assembly {
257               dataOffset := _data.offset
258:          }

GitHub: 137, 150, 165, 179, 220, 225, 235, 256

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

41                    assembly {
42                        mstore(add(encoded, 0x21), shiftedVal)
43:                   }

76                    assembly {
77                        mstore(add(encoded, 0x21), shiftedVal)
78:                   }

GitHub: 41, 76

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

94            assembly {
95                addr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0)
96:           }

105           assembly {
106               pop(staticcall(0, callAddr, 0, 0xFFFF, 0, 0))
107:          }

116           assembly {
117               pop(staticcall(_farCallAbi, callAddr, 0, 0xFFFF, 0, 0))
118:          }

206           assembly {
207               pop(call(initializer, callAddr, value1, 0, 0xFFFF, 0, 0))
208:          }

216           assembly {
217               pop(call(value1, callAddr, value2, 0, 0xFFFF, 0, 0))
218:          }

227           assembly {
228               meta := staticcall(0, callAddr, 0, 0xFFFF, 0, 0)
229:          }

316           assembly {
317               callFlags := staticcall(0, callAddr, 0, 0xFFFF, 0, 0)
318:          }

327           assembly {
328               ptr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0)
329:          }

340           assembly {
341               extraAbiData := staticcall(index, callAddr, 0, 0xFFFF, 0, 0)
342:          }

GitHub: 94, 105, 116, 206, 216, 227, 316, 327, 340

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

82            assembly {
83                dataStart := add(data, 0x20)
84:           }

102               assembly {
103                   success := call(to, callAddr, 0, 0, farCallAbi, 0, 0)
104:              }

111               assembly {
112                   success := call(msgValueSimulator, callAddr, value, to, farCallAbi, forwardMask, 0)
113:              }

134           assembly {
135               size := returndatasize()
136:          }

139           assembly {
140               returndatacopy(add(returnData, 0x20), 0, size)
141:          }

162               assembly {
163                   let size := mload(returnData)
164                   revert(add(returnData, 0x20), size)
165:              }

GitHub: 82, 102, 111, 134, 139, 162

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

401           assembly {
402               success := call(gas(), bootloaderAddr, amount, 0, 0, 0, 0)
403:          }

GitHub: 401

File: cache-zk/solpp-generated-contracts/libraries/UnsafeBytesCalldata.sol

22            assembly {
23                let offset := sub(_bytes.offset, 30)
24                result := calldataload(add(offset, _start))
25:           }

29            assembly {
30                let offset := sub(_bytes.offset, 28)
31                result := calldataload(add(offset, _start))
32:           }

36            assembly {
37                let offset := sub(_bytes.offset, 24)
38                result := calldataload(add(offset, _start))
39:           }

43            assembly {
44                result := calldataload(add(_bytes.offset, _start))
45:           }

49            assembly {
50                result := calldataload(add(_bytes.offset, _start))
51:           }

GitHub: 22, 29, 36, 43, 49

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

302               assembly {
303                   let returndata_size := mload(returndata)
304                   revert(add(32, returndata), returndata_size)
305:              }

GitHub: 302

[N‑15] Avoid the use of sensitive terms

Use alternative variants, e.g. allowlist/denylist instead of whitelist/blacklist

There are 56 instances of this issue:

see instances
File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

344:              paymaster: uint256(0),

352:              paymasterInput: new bytes(0),

GitHub: 344, 352

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

45:           uint256 paymaster;

60:           bytes paymasterInput;

45:           uint256 paymaster;

60:           bytes paymasterInput;

28:       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility

35:       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call

GitHub: 45, 60, 45, 60, 28, 28, 35, 35

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

216       function prepareForPaymaster(
217           bytes32, // _txHash
218           bytes32, // _suggestedSignedHash
219           Transaction calldata _transaction
220:      ) external payable ignoreNonBootloader ignoreInDelegateCall {

210:      /// paid for by a paymaster.

216:      function prepareForPaymaster(

GitHub: 216, 210, 210, 216

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

44        function prepareForPaymaster(
45            bytes32 _txHash,
46            bytes32 _possibleSignedHash,
47:           Transaction calldata _transaction

GitHub: 44

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

14:   bytes4 constant PAYMASTER_VALIDATION_SUCCESS_MAGIC = IPaymaster.validateAndPayForPaymasterTransaction.selector;

30        function validateAndPayForPaymasterTransaction(
31            bytes32 _txHash,
32            bytes32 _suggestedSignedHash,
33            Transaction calldata _transaction
34:       ) external payable returns (bytes4 magic, bytes memory context);

17:       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the

23:       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction

24:       /// if the paymaster agrees to pay for the transaction.

30:       function validateAndPayForPaymasterTransaction(

39:       /// @param _context, the context of the execution, returned by the "validateAndPayForPaymasterTransaction" method.

42:       /// @param _maxRefundedGas, the upper bound on the amout of gas that could be refunded to the paymaster.

GitHub: 14, 30, 17, 23, 23, 24, 24, 30, 39, 39, 42, 42

File: cache-zk/solpp-generated-contracts/interfaces/IPaymasterFlow.sol

10:    * different types of paymaster flows.

GitHub: 10

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

377:              address paymaster = address(uint160(_transaction.paymaster));

69:       bytes paymasterInput;

367:          bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]);

46:       uint256 paymaster;

69:       bytes paymasterInput;

364:      function processPaymasterInput(Transaction calldata _transaction) internal {

367:          bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]);

368:          if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) {

377:              address paymaster = address(uint160(_transaction.paymaster));

379:              uint256 currentAllowance = IERC20(token).allowance(address(this), paymaster);

384:                  IERC20(token).safeApprove(paymaster, 0);

385:                  IERC20(token).safeApprove(paymaster, minAllowance);

387:          } else if (paymasterInputSelector == IPaymasterFlow.general.selector) {

45:       // The transaction's paymaster. If there is no paymaster, it is equal to 0.

46:       uint256 paymaster;

68:       // The input to the paymaster.

69:       bytes paymasterInput;

361:      /// @notice Processes the common paymaster flows, e.g. setting proper allowance

363:      /// the "Paymaster flows" section in the documentation.

364:      function processPaymasterInput(Transaction calldata _transaction) internal {

375:              // the data is needed only for the paymaster, so we ignore it here for the sake of optimization

376:              (address token, uint256 minAllowance) = abi.decode(_transaction.paymasterInput[4:68], (address, uint256));

388:              // Do nothing. general(bytes) paymaster flow means that the paymaster must interpret these bytes on his own.

409:              // Paymaster pays for the fee

GitHub: 377, 69, 367, 46, 69, 364, 367, 368, 368, 377, 379, 384, 385, 387, 387, 45, 46, 68, 69, 361, 363, 363, 364, 375, 375, 376, 388, 409

[N‑16] Cast to bytes or bytes32 for clearer semantic meaning

Using a cast on a single argument, rather than abi.encodePacked() makes the intended operation more clear, leading to less reviewer confusion.

There are 3 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

77:          bytes memory wethMessage = abi.encodePacked(_l1Receiver);

GitHub: 77

File: cache-zk/solpp-generated-contracts/SystemContext.sol

207:         return keccak256(abi.encodePacked(uint32(_blockNumber)));

GitHub: 207

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

135:                 keccak256(abi.encodePacked(_transaction.factoryDeps)),

GitHub: 135

[N‑17] Common functions should be refactored to a common base contract

The functions below have the same implementation as is seen in other files. The functions should be refactored into functions of a common base contract

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

/// @audit seen in /var/tmp/2023-10-zksync/code/contracts/ethereum/cache/solpp-generated-contracts/bridge/L1WethBridge.sol
117       function l2TokenAddress(address _l1Token) public view override returns (address l2Token) {
118           l2Token = _l1Token == l1WethAddress ? l2WethAddress : address(0);
119:      }

GitHub: 117

[N‑18] Complex casting

Consider whether the number of casts is really necessary, or whether using a different type would be more appropriate. Alternatively, add comments to explain in detail why the casts are necessary, and any implicit reasons why the cast does not introduce an overflow.

There are 69 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

31           // Setting the version of the hash
32:          hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248)));

51       function _bytecodeLen(bytes32 _bytecodeHash) private pure returns (uint256 codeLengthInWords) {
52:          codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

72   
73:          return address(uint160(uint256(data)));

GitHub: 31, 51, 51, 72

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

117          // verifier is upgraded.
118:         if (_newVerifier == IVerifier(address(0))) {

236      function _setAllowList(IAllowList _newAllowList) internal {
237:         if (_newAllowList == IAllowList(address(0))) {

GitHub: 117, 236

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

107              key: _l2TxHash,
108:             value: bytes32(uint256(_status))

GitHub: 107

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

53           l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash;
54:          address l2StandardToken = address(new L2StandardERC20{salt: bytes32(0)}());

GitHub: 53

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

93           // according to the spec "If EXTCODEHASH of A is X, then EXTCODEHASH of A + 2**160 is X".
94:          address account = address(uint160(_input));

121          // according to the spec "If EXTCODESIZE of A is X, then EXTCODESIZE of A + 2**160 is X".
122:         address account = address(uint160(_input));

GitHub: 93, 121

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

62   
63:          bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

82           {
83:              uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

87           {
88:              uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

92           {
93:              uint256 vInt = uint256(uint8(_transaction.signature[64]));

148              bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit);
149:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

181          {
182:             uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

186          {
187:             uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

191          {
192:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

242              bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit);
243:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

276          {
277:             uint256 rInt = uint256(bytes32(_transaction.signature[0:32]));

281          {
282:             uint256 sInt = uint256(bytes32(_transaction.signature[32:64]));

286          {
287:             uint256 vInt = uint256(uint8(_transaction.signature[64]));

GitHub: 62, 82, 87, 92, 148, 181, 186, 191, 242, 276, 281, 286

File: cache-zk/solpp-generated-contracts/Compressor.sol

151  
152:             uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr]));

180  
181:             uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr]));

252      function _sliceToUint256(bytes calldata _calldataSlice) internal pure returns (uint256 number) {
253:         number = uint256(bytes32(_calldataSlice));

GitHub: 151, 180, 252

File: cache-zk/solpp-generated-contracts/Constants.sol

38   
39:  address payable constant BOOTLOADER_FORMAL_ADDRESS = payable(address(SYSTEM_CONTRACTS_OFFSET + 0x01));

39   address payable constant BOOTLOADER_FORMAL_ADDRESS = payable(address(SYSTEM_CONTRACTS_OFFSET + 0x01));
40   IAccountCodeStorage constant ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT = IAccountCodeStorage(
41       address(SYSTEM_CONTRACTS_OFFSET + 0x02)
42:  );

42   );
43:  INonceHolder constant NONCE_HOLDER_SYSTEM_CONTRACT = INonceHolder(address(SYSTEM_CONTRACTS_OFFSET + 0x03));

43   INonceHolder constant NONCE_HOLDER_SYSTEM_CONTRACT = INonceHolder(address(SYSTEM_CONTRACTS_OFFSET + 0x03));
44:  IKnownCodesStorage constant KNOWN_CODE_STORAGE_CONTRACT = IKnownCodesStorage(address(SYSTEM_CONTRACTS_OFFSET + 0x04));

44   IKnownCodesStorage constant KNOWN_CODE_STORAGE_CONTRACT = IKnownCodesStorage(address(SYSTEM_CONTRACTS_OFFSET + 0x04));
45   IImmutableSimulator constant IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT = IImmutableSimulator(
46       address(SYSTEM_CONTRACTS_OFFSET + 0x05)
47:  );

47   );
48:  IContractDeployer constant DEPLOYER_SYSTEM_CONTRACT = IContractDeployer(address(SYSTEM_CONTRACTS_OFFSET + 0x06));

52   address constant FORCE_DEPLOYER = address(SYSTEM_CONTRACTS_OFFSET + 0x07);
53:  IL1Messenger constant L1_MESSENGER_CONTRACT = IL1Messenger(address(SYSTEM_CONTRACTS_OFFSET + 0x08));

55   
56:  IEthToken constant ETH_TOKEN_SYSTEM_CONTRACT = IEthToken(address(SYSTEM_CONTRACTS_OFFSET + 0x0a));

59   
60:  ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(payable(address(SYSTEM_CONTRACTS_OFFSET + 0x0b)));

61   
62:  IBootloaderUtilities constant BOOTLOADER_UTILITIES = IBootloaderUtilities(address(SYSTEM_CONTRACTS_OFFSET + 0x0c));

65   
66:  ICompressor constant COMPRESSOR_CONTRACT = ICompressor(address(SYSTEM_CONTRACTS_OFFSET + 0x0e));

67   
68:  IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(address(SYSTEM_CONTRACTS_OFFSET + 0x0f));

GitHub: 38, 39, 42, 43, 44, 47, 52, 55, 59, 61, 65, 67

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

107  
108:         newAddress = address(uint160(uint256(hash)));

123  
124:         newAddress = address(uint160(uint256(hash)));

GitHub: 107, 123

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

135      function _execute(Transaction calldata _transaction) internal {
136:         address to = address(uint160(_transaction.to));

GitHub: 135

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

206          /// Check logs
207:         uint32 numberOfL2ToL1Logs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

239          /// Check messages
240:         uint32 numberOfMessages = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

243          for (uint256 i = 0; i < numberOfMessages; ++i) {
244:             uint32 currentMessageLength = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

257          /// Check bytecodes
258:         uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

261          for (uint256 i = 0; i < numberOfBytecodes; ++i) {
262              uint32 currentBytecodeLength = uint32(
263                  bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])
264:             );

286          require(
287:             uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) ==

292  
293:         uint24 compressedStateDiffSize = uint24(bytes3(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 3]));

295  
296:         uint8 enumerationIndexSize = uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]));

306  
307:         uint32 numberOfStateDiffs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4]));

324          /// Native (VM) L2 to L1 log
325:         SystemContractHelper.toL1(true, bytes32(uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)), l2ToL1LogsTreeRoot);

327              true,
328:             bytes32(uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)),

330          );
331:         SystemContractHelper.toL1(true, bytes32(uint256(SystemLogKey.STATE_DIFF_HASH_KEY)), stateDiffHash);

GitHub: 206, 239, 243, 257, 261, 286, 292, 295, 306, 324, 327, 330

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

58       function balanceOf(uint256 _account) external view override returns (uint256) {
59:          return balance[address(uint160(_account))];

GitHub: 58

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

33   
34:          to = address(uint160(addressAsUint));

GitHub: 33

File: cache-zk/solpp-generated-contracts/SystemContext.sol

393              false,
394:             bytes32(uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)),

439          // The correctness of this block hash:
440:         SystemContractHelper.toL1(false, bytes32(uint256(SystemLogKey.PREV_BATCH_HASH_KEY)), _prevBatchHash);

GitHub: 393, 439

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

35                   encoded = new bytes(hbs + 2);
36:                  encoded[0] = bytes1(uint8(hbs + 0x81));

30                   // Handle zero as a non-value, since stripping zeroes results in an empty byte array
31:                  encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val));

70                   encoded = new bytes(hbs + 2);
71:                  encoded[0] = bytes1(uint8(_offset + hbs + 56));

65                   encoded = new bytes(1);
66:                  encoded[0] = bytes1(uint8(_len + _offset));

GitHub: 35, 30, 30, 70, 65

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

165  
166:         bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

233              bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit);
234:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

304              bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit);
305:             bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to)));

376              (address token, uint256 minAllowance) = abi.decode(_transaction.paymasterInput[4:68], (address, uint256));
377:             address paymaster = address(uint160(_transaction.paymaster));

407      function totalRequiredBalance(Transaction calldata _transaction) internal pure returns (uint256 requiredBalance) {
408:         if (address(uint160(_transaction.paymaster)) != address(0)) {

GitHub: 165, 233, 304, 376, 407

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

47           unchecked {
48:              codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3]));

94           // Setting the version of the hash
95:          hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248)));

GitHub: 47, 47, 94

[N‑19] Consider adding a block/deny-list

Doing so will significantly increase centralization, but will help to prevent hackers from using stolen tokens

There are 5 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

22   contract L2ERC20Bridge is IL2Bridge, Initializable {
23:      /// @dev The address of the L1 bridge counterpart.

GitHub: 22

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

13   contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken {
14       /// @dev Describes whether there is a specific getter in the token.
15       /// @notice Used to explicitly separate which getters the token has and which it does not.
16       /// @notice Different tokens in L1 can implement or not implement getter function as `name`/`symbol`/`decimals`,
17:      /// @notice Our goal is to store all the getters that L1 token implements, and for others, we keep it as an unimplemented method.

GitHub: 13

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

23   contract L2Weth is ERC20PermitUpgradeable, IL2Weth, IL2StandardToken {
24:      /// @dev Address of the L2 WETH Bridge.

GitHub: 23

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

18:  contract BootloaderUtilities is IBootloaderUtilities {

GitHub: 18

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

21:  contract DefaultAccount is IAccount {

GitHub: 21

[N‑20] Consider adding emergency-stop functionality

Adding a way to quickly halt protocol functionality in an emergency, rather than having to pause individual contracts one-by-one, will make in-progress hack mitigation faster and much less stressful.

There are 3 instances of this issue:

File: cache/solpp-generated-contracts/common/AllowList.sol

20:  contract AllowList is IAllowList, Ownable2Step {

GitHub: 20

File: cache/solpp-generated-contracts/governance/Governance.sol

22   contract Governance is IGovernance, Ownable2Step {
23:      /// @notice A constant representing the timestamp for completed operations.

GitHub: 22

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

22:  contract ValidatorTimelock is IExecutor, Ownable2Step {

GitHub: 22

[N‑21] Consider adding formal verification proofs

Consider using formal verification to mathematically prove that your code does what is intended, and does not have any edge cases with unexpected behavior. The solidity compiler itself has this functionality built in

There is one instance of this issue:

File: Various Files

[N‑22] Consider bounding input array length

The functions below take in an unbounded array, and make function calls for entries in the array. While the function will revert if it eventually runs out of gas, it may be a nicer user experience to require() that the length of the array is below some reasonable maximum, so that the user doesn't have to use up a full transaction's gas only to see that the transaction reverts.

There are 18 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/AllowList.sol

64           for (uint256 i = 0; i < targetsLength; i = i.uncheckedInc()) {
65               _setAccessMode(_targets[i], _accessModes[i]);
66:          }

98           for (uint256 i = 0; i < callersLength; i = i.uncheckedInc()) {
99               _setPermissionToCall(_callers[i], _targets[i], _functionSigs[i], _enables[i]);
100:         }

GitHub: 64, 98

File: cache/solpp-generated-contracts/governance/Governance.sol

227          for (uint256 i = 0; i < _calls.length; ++i) {
228              (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data);
229              if (!success) {
230                  // Propage an error if the call fails.
231                  assembly {
232                      revert(add(returnData, 0x20), mload(returnData))
233                  }
234              }
235:         }

GitHub: 227

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

206          for (uint256 i = 0; i < _factoryDeps.length; ++i) {
207              require(
208                  L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]),
209                  "Wrong factory dep hash"
210              );
211:         }

GitHub: 206

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

87               for (uint256 i = 0; i < _newBatchesData.length; ++i) {
88                   committedBatchTimestamp.set(_newBatchesData[i].batchNumber, timestamp);
89:              }

118              for (uint256 i = 0; i < _newBatchesData.length; ++i) {
119                  uint256 commitBatchTimestamp = committedBatchTimestamp.get(_newBatchesData[i].batchNumber);
120  
121                  // Note: if the `commitBatchTimestamp` is zero, that means either:
122                  // * The batch was committed, but not through this contract.
123                  // * The batch wasn't committed at all, so execution will fail in the zkSync contract.
124                  // We allow executing such batches.
125                  require(block.timestamp >= commitBatchTimestamp + delay, "5c"); // The delay is not passed
126:             }

GitHub: 87, 118

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

211          for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) {
212              _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0));
213  
214              s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData);
215              emit BlockCommit(
216                  _lastCommittedBatchData.batchNumber,
217                  _lastCommittedBatchData.batchHash,
218                  _lastCommittedBatchData.commitment
219              );
220:         }

243          for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) {
244              // The upgrade transaction must only be included in the first batch.
245              bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0);
246              _lastCommittedBatchData = _commitOneBatch(
247                  _lastCommittedBatchData,
248                  _newBatchesData[i],
249                  expectedUpgradeTxHash
250              );
251  
252              s.storedBatchHashes[_lastCommittedBatchData.batchNumber] = _hashStoredBatchInfo(_lastCommittedBatchData);
253              emit BlockCommit(
254                  _lastCommittedBatchData.batchNumber,
255                  _lastCommittedBatchData.batchHash,
256                  _lastCommittedBatchData.commitment
257              );
258:         }

295          for (uint256 i = 0; i < nBatches; i = i.uncheckedInc()) {
296              _executeOneBatch(_batchesData[i], i);
297              emit BlockExecution(_batchesData[i].batchNumber, _batchesData[i].batchHash, _batchesData[i].commitment);
298:         }

332          for (uint256 i = 0; i < committedBatchesLength; i = i.uncheckedInc()) {
333              currentTotalBatchesVerified = currentTotalBatchesVerified.uncheckedInc();
334              require(
335                  _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified],
336                  "o1"
337              );
338  
339              bytes32 currentBatchCommitment = _committedBatches[i].commitment;
340              proofPublicInput[i] = _getBatchProofPublicInput(
341                  prevBatchCommitment,
342                  currentBatchCommitment,
343                  verifierParams
344              );
345  
346              prevBatchCommitment = currentBatchCommitment;
347:         }

GitHub: 211, 243, 295, 332

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

397          for (uint256 i = 0; i < factoryDepsLen; i = i.uncheckedInc()) {
398              bytes32 hashedBytecode = L2ContractHelper.hashL2Bytecode(_factoryDeps[i]);
399  
400              // Store the resulting hash sequentially in bytes.
401              assembly {
402                  mstore(add(hashedFactoryDeps, mul(add(i, 1), 32)), hashedBytecode)
403              }
404:         }

GitHub: 397

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

140          for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) {
141              bytes4 selector = _selectors[i];
142              SelectorToFacet memory oldFacet = ds.selectorToFacet[selector];
143              require(oldFacet.facetAddress == address(0), "J"); // facet for this selector already exists
144  
145              _addOneFunction(_facet, selector, _isFacetFreezable);
146:         }

161          for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) {
162              bytes4 selector = _selectors[i];
163              SelectorToFacet memory oldFacet = ds.selectorToFacet[selector];
164              require(oldFacet.facetAddress != address(0), "L"); // it is impossible to replace the facet with zero address
165  
166              _removeOneFunction(oldFacet.facetAddress, selector);
167              // Add facet to the list of facets if the facet address is a new one
168              _saveFacetIfNew(_facet);
169              _addOneFunction(_facet, selector, _isFacetFreezable);
170:         }

181          for (uint256 i = 0; i < selectorsLength; i = i.uncheckedInc()) {
182              bytes4 selector = _selectors[i];
183              SelectorToFacet memory oldFacet = ds.selectorToFacet[selector];
184              require(oldFacet.facetAddress != address(0), "a2"); // Can't delete a non-existent facet
185  
186              _removeOneFunction(oldFacet.facetAddress, selector);
187:         }

GitHub: 140, 161, 181

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

31           for (uint256 i; i < pathLength; i = i.uncheckedInc()) {
32               currentHash = (_index % 2 == 0)
33                   ? _efficientHash(currentHash, _path[i])
34                   : _efficientHash(_path[i], currentHash);
35               _index /= 2;
36:          }

GitHub: 31

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

255          for (uint256 i = 0; i < deploymentsLength; ++i) {
256              this.forceDeployOnAddress{value: _deployments[i].value}(_deployments[i], msg.sender);
257:         }

GitHub: 255

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

40               for (uint256 i = 0; i < immutablesLength; ++i) {
41                   uint256 index = _immutables[i].index;
42                   bytes32 value = _immutables[i].value;
43                   immutableDataStorage[uint256(uint160(_dest))][index] = value;
44:              }

GitHub: 40

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

33               for (uint256 i = 0; i < hashesLen; ++i) {
34                   _markBytecodeAsPublished(_hashes[i], _shouldSendToL1);
35:              }

GitHub: 33

[N‑23] Consider disallowing transfers to address(this)

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

65       function withdraw(
66           address _l1Receiver,
67           address _l2Token,
68           uint256 _amount
69:      ) external override {

GitHub: 65

[N‑24] Consider implementing EIP-5267 to securely describe EIP-712 domains being used

EIP-5267 is a standard which allows for the retrieval and description of EIP-712 hash domains. This allows external tools to allow users to not just view the struct fields being signed, but the fields the domain the signature contains as well. This is especially useful when a project may exist on multiple chains and or in multiple contracts, and allows users/tools to verify that the signature is for the right fork, chain, version, contract, etc.

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

84:      bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)");

GitHub: 84

[N‑25] Consider moving msg.sender checks to a common authorization modifier

There are 13 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

313:         require(msg.sender == l1WethAddress || msg.sender == address(zkSync), "pn");

GitHub: 313

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

33:          require(msg.sender == pendingGovernor, "n4"); // Only proposed by current governor address can claim the governor rights

57:          require(msg.sender == pendingAdmin, "n4"); // Only proposed by current admin address can claim the admin rights

GitHub: 33, 57

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

73:          require(AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge, "mq");

GitHub: 73

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

97           require(
98               AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge,
99               "Only L1 WETH bridge can call this function"
100:         );

122:         require(msg.sender == l2WethAddress, "pd");

GitHub: 97, 122

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

24:          require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER");

GitHub: 24

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

241          require(
242              msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT),
243              "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT"
244:         );

GitHub: 241

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

226:         assert(msg.sender != BOOTLOADER_FORMAL_ADDRESS);

GitHub: 226

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

37:          require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract");

GitHub: 37

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

35           require(
36               msg.sender == MSG_VALUE_SYSTEM_CONTRACT ||
37                   msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) ||
38                   msg.sender == BOOTLOADER_FORMAL_ADDRESS,
39               "Only system contracts with special access can call this method"
40:          );

GitHub: 35

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

91:              require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used");

138:         require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "");

GitHub: 91, 138

[N‑26] Consider splitting long calculations

The longer a string of operations is, the harder it is to understand it. Consider splitting the full calculation into more steps, with more descriptive temporary variable names, and add extensive comments.

There are 5 instances of this issue:

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

107              uint256 listLength = encodedNonce.length +
108                  encodedGasParam.length +
109                  encodedTo.length +
110                  encodedValue.length +
111                  encodedDataLength.length +
112                  _transaction.data.length +
113                  rEncoded.length +
114                  sEncoded.length +
115:                 vEncoded.length;

200              uint256 listLength = encodedFixedLengthParams.length +
201                  encodedDataLength.length +
202                  _transaction.data.length +
203                  encodedAccessListLength.length +
204                  rEncoded.length +
205                  sEncoded.length +
206:                 vEncoded.length;

295              uint256 listLength = encodedFixedLengthParams.length +
296                  encodedDataLength.length +
297                  _transaction.data.length +
298                  encodedAccessListLength.length +
299                  rEncoded.length +
300                  sEncoded.length +
301:                 vEncoded.length;

GitHub: 107, 200, 295

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

155          uint256 gasToPay = pubdataLen *
156              gasPerPubdataBytes +
157              keccakGasCost(L2_TO_L1_LOG_SERIALIZE_SIZE) +
158              4 *
159              keccakGasCost(64) +
160:             gasSpentOnMessageHashing;

GitHub: 155

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

192              uint256 listLength = encodedNonce.length +
193                  encodedGasParam.length +
194                  encodedTo.length +
195                  encodedValue.length +
196                  encodedDataLength.length +
197                  _transaction.data.length +
198:                 encodedChainId.length;

GitHub: 192

[N‑27] Consider using delete rather than assigning zero/false to clear values

The delete keyword more closely matches the semantics of what is being done, and draws more attention to the changing of state, which may lead to a more thorough audit of its associated logic

There is one instance of this issue:

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

126:          diamondStorage.isFrozen = false;

GitHub: 126

[N‑28] Consider using SafeTransferLib.safeTransferETH() or Address.sendValue() for clearer semantic meaning

These Functions indicate their purpose with their name more clearly than using low-level calls.

There are 2 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

83:          (bool success, ) = msg.sender.call{value: _amount}("");

108:         (bool success, ) = _to.call{value: _amount}("");

GitHub: 83, 108

[N‑29] Consider using descriptive constants when passing zero as a function argument

Passing zero as a function argument can sometimes result in a security issue (e.g. passing zero as the slippage parameter). Consider using a constant variable with a descriptive name, so it's clear that the argument is intentionally being used, and for the right reasons.

There are 29 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

131:             new bytes[](0)

200          l2TxHash = zkSync.requestL2Transaction{value: msg.value}(
201              l2Bridge,
202              0, // L2 msg.value
203              l2TxCalldata,
204              _l2TxGasLimit,
205              _l2TxGasPerPubdataByte,
206              new bytes[](0),
207              refundRecipient
208:         );

206:             new bytes[](0),

333:         (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_l2ToL1message, 0);

GitHub: 131, 200, 206, 333

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

134:             new bytes[](0)

193:             new bytes[](0),

209:             (_l1Sender, _l2Receiver, _l1Token, _amount, new bytes(0))

283:         (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);

GitHub: 134, 193, 209, 283

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

43           _zkSync.requestL2Transaction{value: _deployTransactionFee}(
44               L2_DEPLOYER_SYSTEM_CONTRACT_ADDR,
45               0,
46               deployCalldata,
47               DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT,
48               REQUIRED_L2_GAS_PRICE_PER_PUBDATA,
49               _factoryDeps,
50               msg.sender
51:          );

GitHub: 43

File: cache/solpp-generated-contracts/governance/Governance.sol

52:          emit ChangeMinDelay(0, _minDelay);

GitHub: 52

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

350:             signature: new bytes(0),

352:             paymasterInput: new bytes(0),

353:             reservedDynamic: new bytes(0)

425:         (uint32 functionSignature, uint256 offset) = UnsafeBytes.readUint32(_message, 0);

GitHub: 350, 352, 353, 425

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

150          (bool success, bytes memory returndata) = SystemContractsCaller.systemCallWithReturndata(
151              uint32(gasleft()),
152              DEPLOYER_SYSTEM_CONTRACT,
153              0,
154              abi.encodeCall(
155                  IContractDeployer.create2,
156                  (salt, l2TokenProxyBytecodeHash, abi.encode(address(l2TokenBeacon), ""))
157              )
158:         );

GitHub: 150

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

178:         bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0);

273:         bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0);

GitHub: 178, 273

File: cache-zk/solpp-generated-contracts/Compressor.sol

130:         uint256 numberOfInitialWrites = uint256(_compressedStateDiffs.readUint16(0));

209:             uint256 dictionaryLen = uint256(_rawCompressedData.readUint16(0));

GitHub: 130, 209

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

85           SystemContractsCaller.systemCallWithPropagatedRevert(
86               uint32(gasleft()),
87               address(NONCE_HOLDER_SYSTEM_CONTRACT),
88               0,
89               abi.encodeCall(INonceHolder.incrementMinNonceIfEquals, (_transaction.nonce))
90:          );

GitHub: 85

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

28:          value = SystemContractHelper.getExtraAbiData(0);

GitHub: 28

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

267          uint256 farCallAbi = SystemContractsCaller.getFarCallABIWithEmptyFatPointer(
268              gas,
269              // Only rollup is supported for now
270              0,
271              CalldataForwardingMode.ForwardFatPointer,
272              _isConstructor,
273              _isSystem
274:         );

GitHub: 267

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

363          bool precompileCallSuccess = unsafePrecompileCall(
364              0, // The precompile parameters are formal ones. We only need the precompile call to burn gas.
365              _gasToPay
366:         );

GitHub: 363

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

87           uint256 farCallAbi = SystemContractsCaller.getFarCallABI(
88               0,
89               0,
90               dataStart,
91               dataLength,
92               gasLimit,
93               // Only rollup is supported for now
94               0,
95               CalldataForwardingMode.UseHeap,
96               false,
97               true
98:          );

GitHub: 87

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

263:         bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0);

335:         bytes memory encodedAccessListLength = RLPEncoder.encodeListLen(0);

384:                 IERC20(token).safeApprove(paymaster, 0);

GitHub: 263, 335, 384

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

98               functionCallWithValue(
99                   target,
100                  data,
101                  0,
102                  "Address: low-level call failed"
103:             );

117:         return functionCallWithValue(target, data, 0, errorMessage);

GitHub: 98, 117

[N‑30] Consider using named mappings

Consider moving to solidity version 0.8.18 or later, and using named mappings to make it easier to understand the purpose of each mapping

There are 36 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

41:      mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;

45:      mapping(address => mapping(address => mapping(bytes32 => uint256))) internal depositAmount;

56:      mapping(address => uint256) public __DEPRECATED_lastWithdrawalLimitReset;

59:      mapping(address => uint256) public __DEPRECATED_withdrawnAmountInWindow;

63:      mapping(address => mapping(address => uint256)) public totalDepositedAmountPerUser;

GitHub: 41, 41, 45, 45, 45, 56, 59, 63, 63

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

62:      mapping(uint256 => mapping(uint256 => bool)) public isWithdrawalFinalized;

GitHub: 62, 62

File: cache/solpp-generated-contracts/common/AllowList.sol

24:      mapping(address => AccessMode) public getAccessMode;

28:      mapping(address => mapping(address => mapping(bytes4 => bool))) public hasSpecialAccessToCall;

31:      mapping(address => Deposit) public tokenDeposit;

GitHub: 24, 28, 28, 28, 31

File: cache/solpp-generated-contracts/governance/Governance.sol

34:      mapping(bytes32 => uint256) public timestamps;

GitHub: 34

File: cache/solpp-generated-contracts/zksync/Storage.sol

89:      mapping(address => bool) validators;

101:     mapping(uint256 => bytes32) storedBatchHashes;

103:     mapping(uint256 => bytes32) l2LogsRootHashes;

129:     mapping(uint256 => mapping(uint256 => bool)) isEthWithdrawalFinalized;

135:     mapping(address => uint256) totalDepositedAmountPerUser;

GitHub: 89, 101, 103, 129, 129, 135

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

52:          mapping(bytes4 => SelectorToFacet) selectorToFacet;

53:          mapping(address => FacetToSelectors) facetToSelectors;

GitHub: 52, 53

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

11:          mapping(uint256 => uint256) map;

GitHub: 11

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

30:          mapping(uint256 => PriorityOperation) data;

GitHub: 30

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

34:      mapping(address => address) public override l1TokenAddress;

GitHub: 34

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

28:      mapping(address => AccountInfo) internal accountInfo;

GitHub: 28

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

23:      mapping(uint256 => mapping(uint256 => bytes32)) internal immutableDataStorage;

GitHub: 23, 23

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

22:      mapping(address => uint256) internal balance;

GitHub: 22

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

38:      mapping(uint256 => uint256) internal rawNonces;

43:      mapping(uint256 => mapping(uint256 => uint256)) internal nonceValues;

GitHub: 38, 43, 43

File: cache-zk/solpp-generated-contracts/SystemContext.sol

57:      mapping(uint256 => bytes32) internal batchHash;

GitHub: 57

[N‑31] Constant redefined elsewhere

Consider defining in only one contract so that values cannot become out of sync when only one location is updated. A cheap way to store constants in a single location is to create an internal constant in a library. If the variable is a local cache of another contract's value, consider making the cache variable internal or private, which will require external users to query the contract with the source of truth, so that callers don't get out of sync.

There are 6 instances of this issue:

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit seen in cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol 
49:       IAllowList public immutable allowList;

/// @audit seen in cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol 
52:       IZkSync public immutable zkSync;

GitHub: 49, 52

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

/// @audit seen in cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol 
17:       string public constant override getName = "AdminFacet";

GitHub: 17

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

/// @audit seen in cache/solpp-generated-contracts/zksync/facets/Admin.sol 
24:       string public constant override getName = "ExecutorFacet";

GitHub: 24

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

/// @audit seen in cache/solpp-generated-contracts/zksync/facets/Executor.sol 
21:       string public constant override getName = "GettersFacet";

GitHub: 21

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

/// @audit seen in cache/solpp-generated-contracts/zksync/facets/Getters.sol 
43:       string public constant override getName = "MailboxFacet";

GitHub: 43

[N‑32] Constants in comparisons should appear on the left side

Doing so will prevent typo bugs

There are 110 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

95:          require(_factoryDeps.length == 3, "mk");

186:         require(_amount != 0, "2T"); // empty deposit amount

331:         require(_l2ToL1message.length == 76, "kk");

GitHub: 95, 186, 331

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

92:          require(_factoryDeps.length == 2, "Invalid factory deps length provided");

170:         require(_amount != 0, "Amount cannot be zero");

281:         require(_message.length == 96, "Incorrect ETH message with additional data length");

GitHub: 92, 170, 281

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

60:          require(lockSlotOldValue == 0, "1B");

GitHub: 60

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

25:          require(_bytecode.length % 32 == 0, "pq");

29:          require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd

43:          require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash

45:          require(_bytecodeLen(_bytecodeHash) % 2 == 1, "uy"); // Code length in words must be odd

GitHub: 25, 29, 43, 45

File: cache/solpp-generated-contracts/governance/Governance.sol

109:         if (timestamp == 0) {

GitHub: 109

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

169:         if (_l2ProtocolUpgradeTx.txType == 0) {

226:             s.l2SystemContractsUpgradeBatchNumber == 0,

GitHub: 169, 226

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

27:          require(msg.data.length >= 4 || msg.data.length == 0, "Ut");

GitHub: 27, 27

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

171:             require(processedLogs == 255, "b8");

169:             require(processedLogs == 127, "b7");

191:         if (systemContractsUpgradeTxHash == bytes32(0) || s.l2SystemContractsUpgradeBatchNumber != 0) {

238:         require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik");

245:             bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0);

305:         if (batchWhenUpgradeHappened != 0 && batchWhenUpgradeHappened <= newTotalBatchesExecuted) {

352:         assert(block.chainid != 1);

GitHub: 171, 169, 191, 238, 245, 305, 352

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

143:         if (selectorsArrayLen != 0) {

GitHub: 143

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

423:         require(_message.length >= 56, "pm");

GitHub: 423

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

197:         if (selectorsLength == 0) {

220:         if (selectorPosition != 0) {

257:         if (lastSelectorPosition == 0) {

293:                 if (data.length <= 4) {

304:             require(data.length == 32, "lp");

287:             require(_calldata.length == 0, "H"); // Non-empty calldata for zero address

GitHub: 197, 220, 257, 293, 304, 287

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

32:              currentHash = (_index % 2 == 0)

GitHub: 32

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

54:          require(_transaction.paymaster == 0, "uc");

55:          require(_transaction.value == 0, "ud");

56:          require(_transaction.reserved[0] == 0, "ue");

58:          require(_transaction.reserved[2] == 0, "ug");

59:          require(_transaction.reserved[3] == 0, "uo");

60:          require(_transaction.signature.length == 0, "uh");

61:          require(_transaction.paymasterInput.length == 0, "ul");

62:          require(_transaction.reservedDynamic.length == 0, "um");

GitHub: 54, 55, 56, 58, 59, 60, 61, 62

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

75:          require(msg.value == 0, "Value should be 0 for ERC20 bridge");

GitHub: 75

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

104:         if (codeHash == 0x00 && NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(account) > 0) {

135:             codeHash != 0x00 &&

GitHub: 104, 135

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

71:              if (txDataLen != 1) {

74:              } else if (_transaction.data[0] >= 0x80) {

94:              require(vInt == 27 || vInt == 28, "Invalid v value");

98:              if (_transaction.reserved[0] != 0) {

167:             if (txDataLen != 1) {

170:             } else if (_transaction.data[0] >= 0x80) {

193:             require(vInt == 27 || vInt == 28, "Invalid v value");

262:             if (txDataLen != 1) {

265:             } else if (_transaction.data[0] >= 0x80) {

288:             require(vInt == 27 || vInt == 28, "Invalid v value");

GitHub: 71, 74, 94, 94, 98, 167, 170, 193, 193, 262, 265, 288, 288

File: cache-zk/solpp-generated-contracts/Compressor.sol

63:              require(dictionary.length % 8 == 0, "Dictionary length should be a multiple of 8");

139:             if (enumIndex != 0) {

155:             uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET;

171:             if (enumIndex == 0) {

184:             uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET;

236:             if (_operation == 0 || _operation == 3) {

238:             } else if (_operation == 1) {

240:             } else if (_operation == 2) {

GitHub: 63, 139, 155, 171, 184, 236, 236, 238, 240

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

49:          if (ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getRawCodeHash(_address) == 0) {

271:             ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0,

275:         require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied");

353:             require(value == 0, "The value must be zero if we do not call the constructor");

GitHub: 49, 271, 275, 353

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

143:         if (to == address(DEPLOYER_SYSTEM_CONTRACT) && data.length >= 4) {

164:         require(_signature.length == 65, "Signature length is incorrect");

177:         require(v == 27 || v == 28, "v is neither 27 nor 28");

188:         require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s");

GitHub: 143, 164, 177, 177, 188

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

50:          if (getMarker(_bytecodeHash) == 0) {

79:          require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash");

81:          require(Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 1, "Code length in words must be odd");

GitHub: 50, 79, 81

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

32:          isSystemCall = (mask & MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT) != 0;

43:          if (value != 0) {

GitHub: 32, 43

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

87:          require(_value != 0, "Nonce value cannot be set to 0");

90:          if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) {

GitHub: 87, 90

File: cache-zk/solpp-generated-contracts/SystemContext.sol

241:         if (virtualBlockUpgradeInfo.virtualBlockFinishL2Block != 0) {

250:         if (currentVirtualL2BlockInfo.number == 0 && virtualBlockInfo.timestamp == 0) {

262:         } else if (_maxVirtualBlocksToCreate == 0) {

333:         if (currentL2BlockNumber == 0 && currentL2BlockTimestamp == 0) {

346:             require(_maxVirtualBlocksToCreate == 0, "Can not create virtual blocks in the middle of the miniblock");

GitHub: 241, 250, 250, 262, 333, 333, 346

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

40:          require(returnData.length == 32, "keccak256 returned invalid data");

49:          require(returnData.length == 32, "sha returned invalid data");

133:         if (_value == 0) {

GitHub: 40, 49, 133

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

31:                  encoded[0] = (_val == 0) ? bytes1(uint8(128)) : bytes1(uint8(_val));

52:          assert(_len != 1);

GitHub: 31, 52

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

350:         return (callFlags & 2) != 0;

GitHub: 350

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

100:         if (value == 0) {

GitHub: 100

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

97:          return _addr == uint256(uint160(address(ETH_TOKEN_SYSTEM_CONTRACT))) || _addr == 0;

174:             if (txDataLen != 1) {

177:             } else if (_transaction.data[0] >= 0x80) {

186:         if (_transaction.reserved[0] != 0) {

252:             if (txDataLen != 1) {

255:             } else if (_transaction.data[0] >= 0x80) {

324:             if (txDataLen != 1) {

327:             } else if (_transaction.data[0] >= 0x80) {

365:         require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long");

370:                 _transaction.paymasterInput.length >= 68,

GitHub: 97, 174, 177, 186, 252, 255, 324, 327, 365, 370

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

54:          return _bytecodeHash[1] == 0x00;

59:          return _bytecodeHash[1] == 0x01;

86:          require(_bytecode.length % 32 == 0, "po");

90:          require(bytecodeLenInWords % 2 == 1, "pr"); // bytecode length in words must be odd

GitHub: 54, 59, 86, 90

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

265:             if (returndata.length == 0) {

GitHub: 265

[N‑33] Contract should expose an interface

The contracts should expose an interface so that other projects can more easily integrate with it, without having to develop their own non-standard variants.

There are 149 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

85       function initialize(
86           bytes[] calldata _factoryDeps,
87           address _l2TokenBeacon,
88           address _governor,
89           uint256 _deployBridgeImplementationFee,
90           uint256 _deployBridgeProxyFee
91:      ) external payable reentrancyGuardInitializer {

146      function deposit(
147          address _l2Receiver,
148          address _l1Token,
149          uint256 _amount,
150          uint256 _l2TxGasLimit,
151          uint256 _l2TxGasPerPubdataByte
152:     ) external payable returns (bytes32 l2TxHash) {

178      function deposit(
179          address _l2Receiver,
180          address _l1Token,
181          uint256 _amount,
182          uint256 _l2TxGasLimit,
183          uint256 _l2TxGasPerPubdataByte,
184          address _refundRecipient
185:     ) public payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 l2TxHash) {

257      function claimFailedDeposit(
258          address _depositSender,
259          address _l1Token,
260          bytes32 _l2TxHash,
261          uint256 _l2BatchNumber,
262          uint256 _l2MessageIndex,
263          uint16 _l2TxNumberInBatch,
264          bytes32[] calldata _merkleProof
265:     ) external nonReentrant senderCanCallFunction(allowList) {

295      function finalizeWithdrawal(
296          uint256 _l2BatchNumber,
297          uint256 _l2MessageIndex,
298          uint16 _l2TxNumberInBatch,
299          bytes calldata _message,
300          bytes32[] calldata _merkleProof
301:     ) external nonReentrant senderCanCallFunction(allowList) {

355:     function l2TokenAddress(address _l1Token) public view returns (address) {

GitHub: 85, 146, 178, 257, 295, 355

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

83       function initialize(
84           bytes[] calldata _factoryDeps,
85           address _l2WethAddress,
86           address _governor,
87           uint256 _deployBridgeImplementationFee,
88           uint256 _deployBridgeProxyFee
89:      ) external payable reentrancyGuardInitializer {

161      function deposit(
162          address _l2Receiver,
163          address _l1Token,
164          uint256 _amount,
165          uint256 _l2TxGasLimit,
166          uint256 _l2TxGasPerPubdataByte,
167          address _refundRecipient
168:     ) external payable nonReentrant senderCanCallFunction(allowList) returns (bytes32 txHash) {

216      function claimFailedDeposit(
217          address, // _depositSender,
218          address, // _l1Token,
219          bytes32, // _l2TxHash
220          uint256, // _l2BatchNumber,
221          uint256, // _l2MessageIndex,
222          uint16, // _l2TxNumberInBatch,
223          bytes32[] calldata // _merkleProof
224:     ) external pure {

235      function finalizeWithdrawal(
236          uint256 _l2BatchNumber,
237          uint256 _l2MessageIndex,
238          uint16 _l2TxNumberInBatch,
239          bytes calldata _message,
240          bytes32[] calldata _merkleProof
241:     ) external nonReentrant senderCanCallFunction(allowList) {

309:     receive() external payable {

GitHub: 83, 161, 216, 235, 309

File: cache/solpp-generated-contracts/common/AllowList.sol

41:      function canCall(address _caller, address _target, bytes4 _functionSig) external view returns (bool) {

51:      function setAccessMode(address _target, AccessMode _accessMode) external onlyOwner {

60:      function setBatchAccessMode(address[] calldata _targets, AccessMode[] calldata _accessModes) external onlyOwner {

85       function setBatchPermissionToCall(
86           address[] calldata _callers,
87           address[] calldata _targets,
88           bytes4[] calldata _functionSigs,
89           bool[] calldata _enables
90:      ) external onlyOwner {

108      function setPermissionToCall(
109          address _caller,
110          address _target,
111          bytes4 _functionSig,
112          bool _enable
113:     ) external onlyOwner {

131:     function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external onlyOwner {

138:     function getTokenDepositLimitData(address _l1Token) external view returns (Deposit memory) {

GitHub: 41, 51, 60, 85, 108, 131, 138

File: cache/solpp-generated-contracts/governance/Governance.sol

86:      function isOperation(bytes32 _id) public view returns (bool) {

91:      function isOperationPending(bytes32 _id) public view returns (bool) {

97:      function isOperationReady(bytes32 _id) public view returns (bool) {

102:     function isOperationDone(bytes32 _id) public view returns (bool) {

107:     function getOperationState(bytes32 _id) public view returns (OperationState) {

131:     function scheduleTransparent(Operation calldata _operation, uint256 _delay) external onlyOwner {

144:     function scheduleShadow(bytes32 _id, uint256 _delay) external onlyOwner {

156:     function cancel(bytes32 _id) external onlyOwnerOrSecurityCouncil {

169:     function execute(Operation calldata _operation) external onlyOwnerOrSecurityCouncil {

188:     function executeInstant(Operation calldata _operation) external onlySecurityCouncil {

206:     function hashOperation(Operation calldata _operation) public pure returns (bytes32) {

251:     function updateDelay(uint256 _newDelay) external onlySelf {

258:     function updateSecurityCouncil(address _newSecurityCouncil) external onlySelf {

264:     receive() external payable {}

GitHub: 86, 91, 97, 102, 107, 131, 144, 156, 169, 188, 206, 251, 258, 264

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

57:      function initialize(InitializeData calldata _initalizeData) external reentrancyGuardInitializer returns (bytes32) {

GitHub: 57

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

22:      fallback() external payable {

GitHub: 22

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

54:      function setValidator(address _newValidator) external onlyOwner {

61:      function setExecutionDelay(uint32 _executionDelay) external onlyOwner {

73:      function getCommittedBatchTimestamp(uint256 _l2BatchNumber) external view returns (uint256) {

79       function commitBatches(
80           StoredBatchInfo calldata,
81           CommitBatchInfo[] calldata _newBatchesData
82:      ) external onlyValidator {

98:      function revertBatches(uint256) external onlyValidator {

105      function proveBatches(
106          StoredBatchInfo calldata,
107          StoredBatchInfo[] calldata,
108          ProofInput calldata
109:     ) external onlyValidator {

115:     function executeBatches(StoredBatchInfo[] calldata _newBatchesData) external onlyValidator {

GitHub: 54, 61, 73, 79, 98, 105, 115

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

22:      function setPendingGovernor(address _newPendingGovernor) external onlyGovernor {

31:      function acceptGovernor() external {

46:      function setPendingAdmin(address _newPendingAdmin) external onlyGovernorOrAdmin {

55:      function acceptAdmin() external {

70:      function setValidator(address _validator, bool _active) external onlyGovernorOrAdmin {

77:      function setPorterAvailability(bool _zkPorterIsAvailable) external onlyGovernor {

85:      function setPriorityTxMaxGasLimit(uint256 _newPriorityTxMaxGasLimit) external onlyGovernor {

100:     function executeUpgrade(Diamond.DiamondCutData calldata _diamondCut) external onlyGovernor {

111:     function freezeDiamond() external onlyGovernor {

122:     function unfreezeDiamond() external onlyGovernorOrAdmin {

GitHub: 22, 31, 46, 55, 70, 77, 85, 100, 111, 122

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

293:     function executeBatches(StoredBatchInfo[] calldata _batchesData) external nonReentrant onlyValidator {

313      function proveBatches(
314          StoredBatchInfo calldata _prevBatch,
315          StoredBatchInfo[] calldata _committedBatches,
316          ProofInput calldata _proof
317:     ) external nonReentrant onlyValidator {

391:     function revertBatches(uint256 _newLastBatch) external nonReentrant onlyValidator {

GitHub: 293, 313, 391

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

28:      function getVerifier() external view returns (address) {

33:      function getGovernor() external view returns (address) {

38:      function getPendingGovernor() external view returns (address) {

43:      function getTotalBatchesCommitted() external view returns (uint256) {

48:      function getTotalBatchesVerified() external view returns (uint256) {

53:      function getTotalBatchesExecuted() external view returns (uint256) {

58:      function getTotalPriorityTxs() external view returns (uint256) {

65:      function getFirstUnprocessedPriorityTx() external view returns (uint256) {

70:      function getPriorityQueueSize() external view returns (uint256) {

75:      function priorityQueueFrontOperation() external view returns (PriorityOperation memory) {

80:      function isValidator(address _address) external view returns (bool) {

85:      function l2LogsRootHash(uint256 _batchNumber) external view returns (bytes32) {

92:      function storedBatchHash(uint256 _batchNumber) external view returns (bytes32) {

97:      function getL2BootloaderBytecodeHash() external view returns (bytes32) {

102:     function getL2DefaultAccountBytecodeHash() external view returns (bytes32) {

107:     function getVerifierParams() external view returns (VerifierParams memory) {

112:     function getProtocolVersion() external view returns (uint256) {

117:     function getL2SystemContractsUpgradeTxHash() external view returns (bytes32) {

126:     function getL2SystemContractsUpgradeBatchNumber() external view returns (uint256) {

131:     function isDiamondStorageFrozen() external view returns (bool) {

137:     function isFacetFreezable(address _facet) external view returns (bool isFreezable) {

150:     function getPriorityTxMaxGasLimit() external view returns (uint256) {

155:     function getAllowList() external view returns (address) {

160:     function isFunctionFreezable(bytes4 _selector) external view returns (bool) {

169:     function isEthWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool) {

178:     function facets() external view returns (Facet[] memory result) {

193:     function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory) {

199:     function facetAddresses() external view returns (address[] memory) {

205:     function facetAddress(bytes4 _selector) external view returns (address) {

216:     function getTotalBlocksCommitted() external view returns (uint256) {

222:     function getTotalBlocksVerified() external view returns (uint256) {

228:     function getTotalBlocksExecuted() external view returns (uint256) {

236:     function storedBlockHash(uint256 _batchNumber) external view returns (bytes32) {

246:     function getL2SystemContractsUpgradeBlockNumber() external view returns (uint256) {

GitHub: 28, 33, 38, 43, 48, 53, 58, 65, 70, 75, 80, 85, 92, 97, 102, 107, 112, 117, 126, 131, 137, 150, 155, 160, 169, 178, 193, 199, 205, 216, 222, 228, 236, 246

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

51       function proveL2MessageInclusion(
52           uint256 _batchNumber,
53           uint256 _index,
54           L2Message memory _message,
55           bytes32[] calldata _proof
56:      ) public view returns (bool) {

66       function proveL2LogInclusion(
67           uint256 _batchNumber,
68           uint256 _index,
69           L2Log memory _log,
70           bytes32[] calldata _proof
71:      ) external view returns (bool) {

168      function l2TransactionBaseCost(
169          uint256 _gasPrice,
170          uint256 _l2GasLimit,
171          uint256 _l2GasPerPubdataByteLimit
172:     ) public pure returns (uint256) {

238      function requestL2Transaction(
239          address _contractL2,
240          uint256 _l2Value,
241          bytes calldata _calldata,
242          uint256 _l2GasLimit,
243          uint256 _l2GasPerPubdataByteLimit,
244          bytes[] calldata _factoryDeps,
245          address _refundRecipient
246:     ) external payable nonReentrant senderCanCallFunction(s.allowList) returns (bytes32 canonicalTxHash) {

GitHub: 51, 66, 168, 238

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

42       function initialize(
43           address _l1Bridge,
44           bytes32 _l2TokenProxyBytecodeHash,
45           address _governor
46:      ) external initializer {

GitHub: 42

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

48:      function bridgeInitialize(address _l1Address, bytes memory _data) external initializer {

144:     function decodeString(bytes memory _input) external pure returns (string memory result) {

149:     function decodeUint8(bytes memory _input) external pure returns (uint8 result) {

GitHub: 48, 144, 149

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

41:      function initialize(string memory name_, string memory symbol_) external initializer {

54:      function initializeV2(address _l2Bridge, address _l1Address) external reinitializer(2) {

113:     receive() external payable {

GitHub: 41, 54, 113

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

47       function initialize(
48           address _l1Bridge,
49           address _l1WethAddress,
50           address _l2WethAddress
51:      ) external initializer {

121:     receive() external payable {

GitHub: 47, 121

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

23:      function upgrade(address _delegateTo, bytes calldata _calldata) external payable {

GitHub: 23

File: cache-zk/solpp-generated-contracts/Compressor.sol

56       function publishCompressedBytecode(
57           bytes calldata _bytecode,
58           bytes calldata _rawCompressedData
59:      ) external payable onlyCallFromBootloader returns (bytes32 bytecodeHash) {

119      function verifyCompressedStateDiffs(
120          uint256 _numberOfStateDiffs,
121          uint256 _enumerationIndexSize,
122          bytes calldata _stateDiffs,
123          bytes calldata _compressedStateDiffs
124:     ) external payable onlyCallFrom(address(L1_MESSENGER_CONTRACT)) returns (bytes32 stateDiffHash) {

GitHub: 56, 119

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

36:      function getAccountInfo(address _address) external view returns (AccountInfo memory info) {

42:      function extendedAccountVersion(address _address) public view returns (AccountAbstractionVersion) {

64:      function updateAccountVersion(AccountAbstractionVersion _version) external onlySystemCall {

73:      function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external onlySystemCall {

216:     function forceDeployOnAddress(ForceDeployment calldata _deployment, address _sender) external payable onlySelf {

240:     function forceDeployOnAddresses(ForceDeployment[] calldata _deployments) external payable {

GitHub: 36, 42, 64, 73, 216, 240

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

200      function payForTransaction(
201          bytes32, // _txHash
202          bytes32, // _suggestedSignedHash
203          Transaction calldata _transaction
204:     ) external payable ignoreNonBootloader ignoreInDelegateCall {

216      function prepareForPaymaster(
217          bytes32, // _txHash
218          bytes32, // _suggestedSignedHash
219          Transaction calldata _transaction
220:     ) external payable ignoreNonBootloader ignoreInDelegateCall {

224:     fallback() external payable {

231      receive() external payable {
232          // If the contract is called directly, behave like an EOA
233:     }

GitHub: 200, 216, 224, 231

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

14:      fallback() external payable {}

16:      receive() external payable {}

GitHub: 14, 16

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

30:      function markFactoryDeps(bool _shouldSendToL1, bytes32[] calldata _hashes) external onlyCallFromBootloader {

42:      function markBytecodeAsPublished(bytes32 _bytecodeHash) external onlyCompressor {

GitHub: 30, 42

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

77       function sendL2ToL1Log(
78           bool _isService,
79           bytes32 _key,
80           bytes32 _value
81:      ) external onlyCallFromSystemContract returns (uint256 logIdInMerkleTree) {

201      function publishPubdataAndClearState(
202          bytes calldata _totalL2ToL1PubdataAndStateDiffs
203:     ) external onlyCallFromBootloader {

GitHub: 77, 201

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

37:      fallback(bytes calldata _data) external onlySystemCall returns (bytes memory) {

GitHub: 37

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

48:      function getMinNonce(address _address) public view returns (uint256) {

59:      function getRawNonce(address _address) public view returns (uint256) {

67:      function increaseMinNonce(uint256 _value) public onlySystemCall returns (uint256 oldMinNonce) {

84:      function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall {

104:     function getValueUnderNonce(uint256 _key) public view returns (uint256) {

112:     function incrementMinNonceIfEquals(uint256 _expectedNonce) external onlySystemCall {

127:     function getDeploymentNonce(address _address) external view returns (uint256 deploymentNonce) {

137:     function incrementDeploymentNonce(address _address) external onlySystemCall returns (uint256 prevDeploymentNonce) {

149:     function isNonceUsed(address _address, uint256 _nonce) public view returns (bool) {

161:     function validateNonceUsage(address _address, uint256 _key, bool _shouldBeUsed) external view {

GitHub: 48, 59, 67, 84, 104, 112, 127, 137, 149, 161

File: cache-zk/solpp-generated-contracts/SystemContext.sol

89:      function setTxOrigin(address _newOrigin) external onlyCallFromBootloader {

95:      function setGasPrice(uint256 _gasPrice) external onlyCallFromBootloader {

105:     function getBlockHashEVM(uint256 _block) external view returns (bytes32 hash) {

139:     function getBatchHash(uint256 _batchNumber) external view returns (bytes32 hash) {

145:     function getBatchNumberAndTimestamp() public view returns (uint128 batchNumber, uint128 batchTimestamp) {

153:     function getL2BlockNumberAndTimestamp() public view returns (uint128 blockNumber, uint128 blockTimestamp) {

163:     function getBlockNumber() public view returns (uint128) {

171:     function getBlockTimestamp() public view returns (uint128) {

314      function setL2Block(
315          uint128 _l2BlockNumber,
316          uint128 _l2BlockTimestamp,
317          bytes32 _expectedPrevL2BlockHash,
318          bool _isFirstInBatch,
319          uint128 _maxVirtualBlocksToCreate
320:     ) external onlyCallFromBootloader {

375:     function appendTransactionToCurrentL2Block(bytes32 _txHash) external onlyCallFromBootloader {

381:     function publishTimestampDataToL1() external onlyCallFromBootloader {

418      function setNewBatch(
419          bytes32 _prevBatchHash,
420          uint128 _newTimestamp,
421          uint128 _expectedNewNumber,
422          uint256 _baseFee
423:     ) external onlyCallFromBootloader {

445      function unsafeOverrideBatch(
446          uint256 _newTimestamp,
447          uint256 _number,
448          uint256 _baseFee
449:     ) external onlyCallFromBootloader {

456:     function incrementTxNumberInBatch() external onlyCallFromBootloader {

460:     function resetTxNumberInBatch() external onlyCallFromBootloader {

470:     function currentBlockInfo() external view returns (uint256 blockInfo) {

477:     function getBlockNumberAndTimestamp() external view returns (uint256 blockNumber, uint256 blockTimestamp) {

483:     function blockHash(uint256 _blockNumber) external view returns (bytes32 hash) {

GitHub: 89, 95, 105, 139, 145, 153, 163, 171, 314, 375, 381, 418, 445, 456, 460, 470, 477, 483

[N‑34] Contract timekeeping will break earlier than the Ethereum network itself will stop working

When a timestamp is downcast from uint256 to uint32, the value will wrap in the year 2106, and the contracts will break. Other downcasts will have different endpoints. Consider whether your contract is intended to live past the size of the type being used.

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

86:              uint32 timestamp = uint32(block.timestamp);

GitHub: 86

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

297:         uint64 expirationTimestamp = uint64(block.timestamp + PRIORITY_EXPIRATION); // Safe to cast

GitHub: 297

[N‑35] Contracts should have full test coverage

While 100% code coverage does not guarantee that there are no bugs, it often will catch easy-to-find bugs, and will ensure that there are fewer regressions when the code invariably has to be modified. Furthermore, in order to get full coverage, code authors will often have to re-organize their code so that it is more modular, so that each component can be tested separately, which reduces interdependencies between modules and layers, and makes for code that is easier to reason about and audit.

There is one instance of this issue:

File: Various Files

[N‑36] Custom errors should be used rather than revert()/require()

Custom errors are available from solidity version 0.8.4. Custom errors are more easily processed in try-catch blocks, and are easier to re-use and maintain.

There are 272 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

92:           require(_l2TokenBeacon != address(0), "nf");

93:           require(_governor != address(0), "nh");

95:           require(_factoryDeps.length == 3, "mk");

97:           require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");

186:          require(_amount != 0, "2T"); // empty deposit amount

188:          require(amount == _amount, "1T"); // The token has non-standard transfer logic

274:          require(proofValid, "yn");

277:          require(amount > 0, "y1");

302:          require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw");

314:              require(success, "nq");

331:          require(_l2ToL1message.length == 76, "kk");

334:          require(bytes4(functionSignature) == this.finalizeWithdrawal.selector, "nt");

349:              require(totalDepositedAmountPerUser[_l1Token][_depositor] + _amount <= limitData.depositCap, "d1");

GitHub: 92, 93, 95, 97, 186, 188, 274, 277, 302, 314, 331, 334, 349

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

90:           require(_l2WethAddress != address(0), "L2 WETH address cannot be zero");

91:           require(_governor != address(0), "Governor address cannot be zero");

92:           require(_factoryDeps.length == 2, "Invalid factory deps length provided");

93            require(
94                msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee,
95                "Miscalculated deploy transactions fees"
96:           );

169:          require(_l1Token == l1WethAddress, "Invalid L1 token address");

170:          require(_amount != 0, "Amount cannot be zero");

242:          require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "Withdrawal is already finalized");

256:              require(success, "vq");

281:          require(_message.length == 96, "Incorrect ETH message with additional data length");

284           require(
285               bytes4(functionSignature) == IMailbox.finalizeEthWithdrawal.selector,
286               "Incorrect ETH message function selector"
287:          );

291:          require(l1EthReceiver == address(this), "Wrong L1 ETH withdraw receiver");

297:          require(l2Sender == l2Bridge, "The withdrawal was not initiated by L2 bridge");

313:          require(msg.sender == l1WethAddress || msg.sender == address(zkSync), "pn");

GitHub: 90, 91, 92, 93, 169, 170, 242, 256, 281, 284, 291, 297, 313

File: cache/solpp-generated-contracts/common/AllowList.sol

62:           require(targetsLength == _accessModes.length, "yg"); // The size of arrays should be equal

94:           require(callersLength == _targets.length, "yw");

95:           require(callersLength == _functionSigs.length, "yx");

96:           require(callersLength == _enables.length, "yy");

GitHub: 62, 94, 95, 96

File: cache/solpp-generated-contracts/common/AllowListed.sol

15:               require(_allowList.canCall(msg.sender, address(this), msg.sig), "nr");

GitHub: 15

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

60:           require(lockSlotOldValue == 0, "1B");

77:           require(_status == _NOT_ENTERED, "r1");

GitHub: 60, 77

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

25:           require(_bytecode.length % 32 == 0, "pq");

28:           require(bytecodeLenInWords < 2**16, "pp"); // bytecode length must be less than 2^16 words

29:           require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd

43:           require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash

45:           require(_bytecodeLen(_bytecodeHash) % 2 == 1, "uy"); // Code length in words must be odd

GitHub: 25, 28, 29, 43, 45

File: cache/solpp-generated-contracts/governance/Governance.sol

44:           require(_admin != address(0), "Admin should be non zero address");

61:           require(msg.sender == address(this), "Only governance contract itself allowed to call this function");

67:           require(msg.sender == securityCouncil, "Only security council allowed to call this function");

73            require(
74                msg.sender == owner() || msg.sender == securityCouncil,
75                "Only the owner and security council are allowed to call this function"
76:           );

157:          require(isOperationPending(_id), "Operation must be pending");

174:          require(isOperationReady(id), "Operation must be ready before execution");

179:          require(isOperationReady(id), "Operation must be ready after execution");

193:          require(isOperationPending(id), "Operation must be pending before execution");

198:          require(isOperationPending(id), "Operation must be pending after execution");

218:          require(!isOperation(_id), "Operation with this proposal id already exists");

219:          require(_delay >= minDelay, "Proposed delay is less than minimum delay");

242:          require(_predecessorId == bytes32(0) || isOperationDone(_predecessorId), "Predecessor operation not completed");

GitHub: 44, 61, 67, 73, 157, 174, 179, 193, 198, 218, 219, 242

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

74:           require(block.timestamp >= _proposedUpgrade.upgradeTimestamp, "Upgrade is not ready yet");

173:          require(_l2ProtocolUpgradeTx.txType == SYSTEM_UPGRADE_L2_TX_TYPE, "L2 system upgrade tx type is wrong");

187           require(
188               _l2ProtocolUpgradeTx.nonce == _newProtocolVersion,
189               "The new protocol version should be included in the L2 system upgrade tx"
190:          );

203:          require(_factoryDeps.length == _expectedHashes.length, "Wrong number of factory deps");

204:          require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "Factory deps can be at most 32");

207               require(
208                   L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]),
209                   "Wrong factory dep hash"
210:              );

218           require(
219               _newProtocolVersion > previousProtocolVersion,
220               "New protocol version is not greater than the current one"
221:          );

224:          require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized");

225           require(
226               s.l2SystemContractsUpgradeBatchNumber == 0,
227               "The batch number of the previous upgrade has not been cleaned"
228:          );

GitHub: 74, 173, 187, 203, 204, 207, 218, 224, 225

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

58:           require(address(_initalizeData.verifier) != address(0), "vt");

59:           require(_initalizeData.governor != address(0), "vy");

60:           require(_initalizeData.admin != address(0), "hc");

61:           require(_initalizeData.priorityTxMaxGasLimit <= L2_TX_MAX_GAS_LIMIT, "vu");

GitHub: 58, 59, 60, 61

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

16:           require(_chainId == block.chainid, "pr");

27:           require(msg.data.length >= 4 || msg.data.length == 0, "Ut");

32:           require(facetAddress != address(0), "F"); // Proxy has no facet for this selector

33:           require(!diamondStorage.isFrozen || !facet.isFreezable, "q1"); // Facet is frozen

GitHub: 16, 27, 32, 33

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

68:           require(msg.sender == validator, "8h");

125:                  require(block.timestamp >= commitBatchTimestamp + delay, "5c"); // The delay is not passed

GitHub: 68, 125

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

33:           require(msg.sender == pendingGovernor, "n4"); // Only proposed by current governor address can claim the governor rights

57:           require(msg.sender == pendingAdmin, "n4"); // Only proposed by current admin address can claim the admin rights

86:           require(_newPriorityTxMaxGasLimit <= L2_TX_MAX_GAS_LIMIT, "n5");

114:          require(!diamondStorage.isFrozen, "a9"); // diamond proxy is frozen already

125:          require(diamondStorage.isFrozen, "a7"); // diamond proxy is not frozen

GitHub: 33, 57, 86, 114, 125

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

21:           require(msg.sender == s.governor, "1g"); // only by governor

27:           require(msg.sender == s.governor || msg.sender == s.admin, "Only by governor or admin");

33:           require(s.validators[msg.sender], "1h"); // validator is not active

GitHub: 21, 27, 33

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

34:           require(_newBatch.batchNumber == _previousBatch.batchNumber + 1, "f"); // only commit next batch

47:           require(_previousBatch.batchHash == previousBatchHash, "l");

49:           require(expectedPriorityOperationsHash == _newBatch.priorityOperationsHash, "t");

51:           require(expectedNumberOfLayer1Txs == _newBatch.numberOfLayer1Txs, "ta");

83:           require(batchTimestamp == _expectedBatchTimestamp, "tb");

87:           require(_previousBatchTimestamp < batchTimestamp, "h3");

95:           require(block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER <= batchTimestamp, "h1"); // New batch timestamp is too small

96:           require(lastL2BlockTimestamp <= block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA, "h2"); // The last L2 block timestamp is too big

132:              require(!_checkBit(processedLogs, uint8(logKey)), "kp");

137:                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm");

140:                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln");

141:                  require(providedL2ToL1PubdataHash == logValue, "wp");

143:                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb");

146:                  require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc");

149:                  require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv");

152:                  require(logSender == L2_BOOTLOADER_ADDRESS, "bl");

155:                  require(logSender == L2_BOOTLOADER_ADDRESS, "bk");

158:                  require(logSender == L2_BOOTLOADER_ADDRESS, "bu");

159:                  require(_expectedSystemContractUpgradeTxHash == logValue, "ut");

169:              require(processedLogs == 127, "b7");

171:              require(processedLogs == 255, "b8");

186:          require(s.storedBatchHashes[s.totalBatchesCommitted] == _hashStoredBatchInfo(_lastCommittedBatchData), "i"); // incorrect previous batch data

187:          require(_newBatchesData.length > 0, "No batches to commit");

238:          require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik");

277:          require(currentBatchNumber == s.totalBatchesExecuted + _executedBatchIdx + 1, "k"); // Execute batches in order

278           require(
279               _hashStoredBatchInfo(_storedBatch) == s.storedBatchHashes[currentBatchNumber],
280               "exe10" // executing batch should be committed
281:          );

284:          require(priorityOperationsHash == _storedBatch.priorityOperationsHash, "x"); // priority operations hash does not match to expected

302:          require(newTotalBatchesExecuted <= s.totalBatchesVerified, "n"); // Can't execute batches more than committed and proven currently.

329:          require(_hashStoredBatchInfo(_prevBatch) == s.storedBatchHashes[currentTotalBatchesVerified], "t1");

334               require(
335                   _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified],
336                   "o1"
337:              );

348:          require(currentTotalBatchesVerified <= s.totalBatchesCommitted, "q");

361:              require(successVerifyProof, "p"); // Proof verification fail

392:          require(s.totalBatchesCommitted > _newLastBatch, "v1"); // The last committed batch is less than new last batch

393:          require(_newLastBatch >= s.totalBatchesExecuted, "v2"); // Already executed batches cannot be reverted

446:          require(_batch.systemLogs.length <= MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, "pu");

GitHub: 34, 47, 49, 51, 83, 87, 95, 96, 132, 137, 140, 141, 143, 146, 149, 152, 155, 158, 159, 169, 171, 186, 187, 238, 277, 278, 284, 302, 329, 334, 348, 361, 392, 393, 446

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

162:          require(ds.selectorToFacet[_selector].facetAddress != address(0), "g2");

GitHub: 162

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

121:          require(callSuccess, "pz");

131:          require(_batchNumber <= s.totalBatchesExecuted, "xx");

138:          require(hashedLog != L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, "tw");

201:          require(!s.isEthWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "jj");

212:          require(proofValid, "pi"); // Failed to verify that withdrawal was actually initialized on L2

259:          require(_l2GasPerPubdataByteLimit == REQUIRED_L2_GAS_PRICE_PER_PUBDATA, "qp");

281:          require(s.totalDepositedAmountPerUser[_depositor] + _amount <= limitData.depositCap, "d2");

296:          require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "uj");

308:              require(msg.value >= baseCost + _l2Value, "mv"); // The `msg.value` doesn't cover the transaction cost

423:          require(_message.length >= 56, "pm");

426:          require(bytes4(functionSignature) == this.finalizeEthWithdrawal.selector, "is");

GitHub: 121, 131, 138, 201, 212, 259, 281, 296, 308, 423, 426

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

108:              require(selectors.length > 0, "B"); // no functions for diamond cut

134:          require(_facet != address(0), "G"); // facet with zero address cannot be added

143:              require(oldFacet.facetAddress == address(0), "J"); // facet for this selector already exists

158:          require(_facet != address(0), "K"); // cannot replace facet with zero address

164:              require(oldFacet.facetAddress != address(0), "L"); // it is impossible to replace the facet with zero address

178:          require(_facet == address(0), "a1"); // facet address must be zero

184:              require(oldFacet.facetAddress != address(0), "a2"); // Can't delete a non-existent facet

222:              require(_isSelectorFreezable == ds.selectorToFacet[selector0].isFreezable, "J1");

287:              require(_calldata.length == 0, "H"); // Non-empty calldata for zero address

304:              require(data.length == 32, "lp");

305:              require(abi.decode(data, (bytes32)) == DIAMOND_INIT_SUCCESS_RETURN_VALUE, "lp1");

GitHub: 108, 134, 143, 158, 164, 178, 184, 222, 287, 304, 305

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

26:           require(pathLength > 0, "xc");

27:           require(pathLength < 256, "bt");

28:           require(_index < (1 << pathLength), "px");

GitHub: 26, 27, 28

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

67:           require(!_queue.isEmpty(), "D"); // priority queue is empty

75:           require(!_queue.isEmpty(), "s"); // priority queue is empty

GitHub: 67, 75

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

32:           require(l2GasForTxBody <= _priorityTxMaxGasLimit, "ui");

34:           require(l2GasForTxBody / _transaction.gasPerPubdataByteLimit <= PRIORITY_TX_MAX_PUBDATA, "uk");

38            require(
39                getMinimalPriorityTransactionGasLimit(
40                    _encoded.length,
41                    _transaction.factoryDeps.length,
42                    _transaction.gasPerPubdataByteLimit
43                ) <= _transaction.gasLimit,
44                "up"
45:           );

52:           require(_transaction.from <= type(uint16).max, "ua");

53:           require(_transaction.to <= type(uint160).max, "ub");

54:           require(_transaction.paymaster == 0, "uc");

55:           require(_transaction.value == 0, "ud");

56:           require(_transaction.reserved[0] == 0, "ue");

57:           require(_transaction.reserved[1] <= type(uint160).max, "uf");

58:           require(_transaction.reserved[2] == 0, "ug");

59:           require(_transaction.reserved[3] == 0, "uo");

60:           require(_transaction.signature.length == 0, "uh");

61:           require(_transaction.paymasterInput.length == 0, "ul");

62:           require(_transaction.reservedDynamic.length == 0, "um");

119:          require(_totalGasLimit >= overhead, "my"); // provided gas limit doesn't cover transaction overhead

GitHub: 32, 34, 38, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 119

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

47:           require(_l1Bridge != address(0), "bf");

48:           require(_l2TokenProxyBytecodeHash != bytes32(0), "df");

49:           require(_governor != address(0), "sf");

73:           require(AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge, "mq");

75:           require(msg.value == 0, "Value should be 0 for ERC20 bridge");

81:               require(deployedToken == expectedL2Token, "mt");

84:               require(currentL1Token == _l1Token, "gg"); // Double check that the expected value equal to real one

115:          require(l1Token != address(0), "yh");

161:          require(success, "mk");

GitHub: 47, 48, 49, 73, 75, 81, 84, 115, 161

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

49:           require(_l1Address != address(0), "in6"); // Should be non-zero address

103:          require(msg.sender == l2Bridge, "xnt"); // Only L2 bridge can call this method

GitHub: 49, 103

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

55:           require(_l2Bridge != address(0), "L2 bridge address cannot be zero");

56:           require(_l1Address != address(0), "L1 WETH token address cannot be zero");

62:           require(msg.sender == l2Bridge, "permission denied"); // Only L2 bridge can call this method

84:           require(success, "Failed withdrawal");

109:          require(success, "Failed withdrawal");

GitHub: 55, 56, 62, 84, 109

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

52:           require(_l1Bridge != address(0), "L1 WETH bridge address cannot be zero");

53:           require(_l1WethAddress != address(0), "L1 WETH token address cannot be zero");

54:           require(_l2WethAddress != address(0), "L2 WETH token address cannot be zero");

70:           require(_l2Token == l2WethAddress, "Only WETH can be withdrawn");

71:           require(_amount > 0, "Amount cannot be zero");

97            require(
98                AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge,
99                "Only L1 WETH bridge can call this function"
100:          );

102:          require(_l1Token == l1WethAddress, "Only WETH can be deposited");

103:          require(msg.value == _amount, "Amount mismatch");

122:          require(msg.sender == l2WethAddress, "pd");

GitHub: 52, 53, 54, 70, 71, 97, 102, 103, 122

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

28:           require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract");

39:           require(Utils.isContractConstructing(_hash), "Code hash is not for a contract on constructor");

50:           require(Utils.isContractConstructed(_hash), "Code hash is not for a constructed contract");

59:           require(Utils.isContractConstructing(codeHash), "Code hash is not for a contract on constructor");

GitHub: 28, 39, 50, 59

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

94:               require(vInt == 27 || vInt == 28, "Invalid v value");

193:              require(vInt == 27 || vInt == 28, "Invalid v value");

288:              require(vInt == 27 || vInt == 28, "Invalid v value");

GitHub: 94, 193, 288

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

24:           require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER");

26:           require(_delegateTo.code.length > 0, "Delegatee is an EOA");

GitHub: 24, 26

File: cache-zk/solpp-generated-contracts/Compressor.sol

63:               require(dictionary.length % 8 == 0, "Dictionary length should be a multiple of 8");

64:               require(dictionary.length <= 2 ** 16 * 8, "Dictionary is too big");

65                require(
66                    encodedData.length * 4 == _bytecode.length,
67                    "Encoded data length should be 4 times shorter than the original bytecode"
68:               );

72:                   require(indexOfEncodedChunk < dictionary.length, "Encoded chunk index is out of bounds");

77:                   require(encodedChunk == realChunk, "Encoded chunk does not match the original bytecode");

128:          require(_enumerationIndexSize <= MAX_ENUMERATION_INDEX_SIZE, "enumeration index size is too large");

149:              require(derivedKey == _compressedStateDiffs.readBytes32(stateDiffPtr), "iw: initial key mismatch");            

165:          require(numInitialWritesProcessed == numberOfInitialWrites, "Incorrect number of initial storage diffs");

178:              require(enumIndex == compressedEnumIndex, "rw: enum key mismatch");

194:          require(stateDiffPtr == _compressedStateDiffs.length, "Extra data in _compressedStateDiffs");

237:                  require(convertedValue == _finalValue, "transform or no compression: compressed and final mismatch");

239:                  require(_initialValue + convertedValue == _finalValue, "add: initial plus converted not equal to final");

241:                  require(_initialValue - convertedValue == _finalValue, "sub: initial minus converted not equal to final");

GitHub: 63, 64, 65, 72, 77, 128, 149, 165, 178, 194, 237, 239, 241

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

31:           require(msg.sender == address(this), "Callable only by self");

76            require(
77                _nonceOrdering == AccountNonceOrdering.Arbitrary &&
78                    currentInfo.nonceOrdering == AccountNonceOrdering.Sequential,
79                "It is only possible to change from sequential to arbitrary ordering"
80:           );

241           require(
242               msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT),
243               "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT"
244:          );

253:          require(msg.value == sumOfValues, "`value` provided is not equal to the combined `value`s of deployments");

266:          require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero");

267:          require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space");

270           require(
271               ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0,
272               "Code hash is non-zero"
273:          );

275:          require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied");

306:          require(knownCodeMarker > 0, "The code hash is not known");

353:              require(value == 0, "The value must be zero if we do not call the constructor");

GitHub: 31, 76, 241, 253, 266, 267, 270, 275, 306, 353

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

102:          require(totalRequiredBalance <= address(this).balance, "Not enough balance for fee + value");

164:          require(_signature.length == 65, "Signature length is incorrect");

177:          require(v == 27 || v == 28, "v is neither 27 nor 28");

188:          require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s");

206:          require(success, "Failed to pay the fee to the operator");

GitHub: 102, 164, 177, 188, 206

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

37:           require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract");

GitHub: 37

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

23:           require(msg.sender == address(COMPRESSOR_CONTRACT), "Callable only by the compressor");

79:           require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash");

81:           require(Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 1, "Code length in words must be odd");

GitHub: 23, 79, 81

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

208:          require(numberOfL2ToL1Logs <= numberOfL2ToL1Logs, "Too many L2->L1 logs");

221           require(
222               reconstructedChainedLogsHash == chainedLogsHash,
223               "reconstructedChainedLogsHash is not equal to chainedLogsHash"
224:          );

252           require(
253               reconstructedChainedMessagesHash == chainedMessagesHash,
254               "reconstructedChainedMessagesHash is not equal to chainedMessagesHash"
255:          );

276           require(
277               reconstructedChainedL1BytecodesRevealDataHash == chainedL1BytecodesRevealDataHash,
278               "reconstructedChainedL1BytecodesRevealDataHash is not equal to chainedL1BytecodesRevealDataHash"
279:          );

286           require(
287               uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) ==
288                   STATE_DIFF_COMPRESSION_VERSION_NUMBER,
289               "state diff compression version mismatch"
290:          );

305:          require(calldataPtr <= MAX_ALLOWED_PUBDATA_PER_BATCH, "L1 Messenger pubdata is too long");

322:          require(calldataPtr == _totalL2ToL1PubdataAndStateDiffs.length, "Extra data in the totalL2ToL1Pubdata array");

GitHub: 208, 221, 252, 276, 286, 305, 322

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

35            require(
36                msg.sender == MSG_VALUE_SYSTEM_CONTRACT ||
37                    msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) ||
38                    msg.sender == BOOTLOADER_FORMAL_ADDRESS,
39                "Only system contracts with special access can call this method"
40:           );

43:           require(fromBalance >= _amount, "Transfer amount exceeds balance");

GitHub: 35, 43

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

41:           require(to != address(this), "MsgValueSimulator calls itself");

GitHub: 41

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

68:           require(_value <= MAXIMAL_MIN_NONCE_INCREMENT, "The value for incrementing the nonce is too high");

87:           require(_value != 0, "Nonce value cannot be set to 0");

91:               require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used");

117:          require(oldMinNonce == _expectedNonce, "Incorrect nonce");

138:          require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "");

GitHub: 68, 87, 91, 117, 138

File: cache-zk/solpp-generated-contracts/SystemContext.sol

215:          require(_isFirstInBatch, "Upgrade transaction must be first");

218:          require(_l2BlockNumber > 0, "L2 block number is never expected to be zero");

222:              require(correctPrevBlockHash == _expectedPrevL2BlockHash, "The previous L2 block hash is incorrect");

260:              require(_maxVirtualBlocksToCreate > 0, "Can't initialize the first virtual block");

324               require(
325                   _l2BlockTimestamp >= currentBatchTimestamp,
326                   "The timestamp of the L2 block must be greater than or equal to the timestamp of the current batch"
327:              );

328:              require(_maxVirtualBlocksToCreate > 0, "There must be a virtual block created at the start of the batch");

340:              require(!_isFirstInBatch, "Can not reuse L2 block number from the previous batch");

341:              require(currentL2BlockTimestamp == _l2BlockTimestamp, "The timestamp of the same L2 block must be same");

342               require(
343                   _expectedPrevL2BlockHash == _getLatest257L2blockHash(_l2BlockNumber - 1),
344                   "The previous hash of the same L2 block must be same"
345:              );

346:              require(_maxVirtualBlocksToCreate == 0, "Can not create virtual blocks in the middle of the miniblock");

358:              require(_expectedPrevL2BlockHash == pendingL2BlockHash, "The current L2 block hash is incorrect");

359               require(
360                   _l2BlockTimestamp > currentL2BlockTimestamp,
361                   "The timestamp of the new L2 block must be greater than the timestamp of the previous L2 block"
362:              );

386:          require(currentBatchNumber > 0, "The current batch number must be greater than 0");

403           require(
404               _newTimestamp > currentBlockTimestamp,
405               "The timestamp of the batch must be greater than the timestamp of the previous block"
406:          );

425:          require(_newTimestamp > previousBatchTimestamp, "Timestamps should be incremental");

426:          require(previousBatchNumber + 1 == _expectedNewNumber, "The provided block number is not correct");

GitHub: 215, 218, 222, 260, 324, 328, 340, 341, 342, 346, 358, 359, 386, 403, 425, 426

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

18            require(
19                SystemContractHelper.isSystemCall() || SystemContractHelper.isSystemContract(msg.sender),
20                "This method require system call flag"
21:           );

28            require(
29                SystemContractHelper.isSystemContract(msg.sender),
30                "This method require the caller to be system contract"
31:           );

38:           require(msg.sender == caller, "Inappropriate caller");

45:           require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Callable only by the bootloader");

GitHub: 18, 28, 38, 45

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

40:           require(returnData.length == 32, "keccak256 returned invalid data");

49:           require(returnData.length == 32, "sha returned invalid data");

GitHub: 40, 49

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

337:          require(index < 10, "There are only 10 accessible registers");

367:          require(precompileCallSuccess, "Failed to charge gas");

GitHub: 337, 367

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

365:          require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long");

369               require(
370                   _transaction.paymasterInput.length >= 68,
371                   "The approvalBased paymaster input must be at least 68 bytes long"
372:              );

GitHub: 365, 369

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

23:           require(_x <= type(uint128).max, "Overflow");

29:           require(_x <= type(uint32).max, "Overflow");

35:           require(_x <= type(uint24).max, "Overflow");

86:           require(_bytecode.length % 32 == 0, "po");

89:           require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words

90:           require(bytecodeLenInWords % 2 == 1, "pr"); // bytecode length in words must be odd

GitHub: 23, 29, 35, 86, 89, 90

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

63            require(
64                address(this).balance >= amount,
65                "Address: insufficient balance"
66:           );

69            require(
70                success,
71                "Address: unable to send value, recipient may have reverted"
72:           );

157           require(
158               address(this).balance >= value,
159               "Address: insufficient balance for call"
160:          );

268:                  require(isContract(target), "Address: call to non-contract");

GitHub: 63, 69, 157, 268

[N‑37] Duplicated require()/revert() checks should be refactored to a modifier or function

The compiler will inline the function, which will avoid JUMP instructions usually associated with functions

There are 3 instances of this issue:

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

133:          if (availableGetters.ignoreSymbol) revert();

GitHub: 133

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

109:          require(success, "Failed withdrawal");

GitHub: 109

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

193:              require(vInt == 27 || vInt == 28, "Invalid v value");

GitHub: 193

[N‑38] Error messages should descriptive, rather that cryptic

The error message should clearly state how/why something is an error, not just that a specific error state was reached; someone shouldn't have to read the code in order to see how to resolve the problem

There are 138 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

92:          require(_l2TokenBeacon != address(0), "nf");

93:          require(_governor != address(0), "nh");

95:          require(_factoryDeps.length == 3, "mk");

97:          require(msg.value == _deployBridgeImplementationFee + _deployBridgeProxyFee, "fee");

186:         require(_amount != 0, "2T"); // empty deposit amount

188:         require(amount == _amount, "1T"); // The token has non-standard transfer logic

274:         require(proofValid, "yn");

277:         require(amount > 0, "y1");

302:         require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw");

314:             require(success, "nq");

331:         require(_l2ToL1message.length == 76, "kk");

334:         require(bytes4(functionSignature) == this.finalizeWithdrawal.selector, "nt");

349:             require(totalDepositedAmountPerUser[_l1Token][_depositor] + _amount <= limitData.depositCap, "d1");

GitHub: 92, 93, 95, 97, 186, 188, 274, 277, 302, 314, 331, 334, 349

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

256:             require(success, "vq");

313:         require(msg.sender == l1WethAddress || msg.sender == address(zkSync), "pn");

GitHub: 256, 313

File: cache/solpp-generated-contracts/common/AllowList.sol

62:          require(targetsLength == _accessModes.length, "yg"); // The size of arrays should be equal

94:          require(callersLength == _targets.length, "yw");

95:          require(callersLength == _functionSigs.length, "yx");

96:          require(callersLength == _enables.length, "yy");

GitHub: 62, 94, 95, 96

File: cache/solpp-generated-contracts/common/AllowListed.sol

15:              require(_allowList.canCall(msg.sender, address(this), msg.sig), "nr");

GitHub: 15

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

60:          require(lockSlotOldValue == 0, "1B");

77:          require(_status == _NOT_ENTERED, "r1");

GitHub: 60, 77

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

25:          require(_bytecode.length % 32 == 0, "pq");

28:          require(bytecodeLenInWords < 2**16, "pp"); // bytecode length must be less than 2^16 words

29:          require(bytecodeLenInWords % 2 == 1, "ps"); // bytecode length in words must be odd

43:          require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash

45:          require(_bytecodeLen(_bytecodeHash) % 2 == 1, "uy"); // Code length in words must be odd

GitHub: 25, 28, 29, 43, 45

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

58:          require(address(_initalizeData.verifier) != address(0), "vt");

59:          require(_initalizeData.governor != address(0), "vy");

60:          require(_initalizeData.admin != address(0), "hc");

61:          require(_initalizeData.priorityTxMaxGasLimit <= L2_TX_MAX_GAS_LIMIT, "vu");

GitHub: 58, 59, 60, 61

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

16:          require(_chainId == block.chainid, "pr");

27:          require(msg.data.length >= 4 || msg.data.length == 0, "Ut");

32:          require(facetAddress != address(0), "F"); // Proxy has no facet for this selector

33:          require(!diamondStorage.isFrozen || !facet.isFreezable, "q1"); // Facet is frozen

GitHub: 16, 27, 32, 33

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

68:          require(msg.sender == validator, "8h");

125:                 require(block.timestamp >= commitBatchTimestamp + delay, "5c"); // The delay is not passed

GitHub: 68, 125

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

33:          require(msg.sender == pendingGovernor, "n4"); // Only proposed by current governor address can claim the governor rights

57:          require(msg.sender == pendingAdmin, "n4"); // Only proposed by current admin address can claim the admin rights

86:          require(_newPriorityTxMaxGasLimit <= L2_TX_MAX_GAS_LIMIT, "n5");

114:         require(!diamondStorage.isFrozen, "a9"); // diamond proxy is frozen already

125:         require(diamondStorage.isFrozen, "a7"); // diamond proxy is not frozen

GitHub: 33, 57, 86, 114, 125

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

21:          require(msg.sender == s.governor, "1g"); // only by governor

33:          require(s.validators[msg.sender], "1h"); // validator is not active

GitHub: 21, 33

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

34:          require(_newBatch.batchNumber == _previousBatch.batchNumber + 1, "f"); // only commit next batch

47:          require(_previousBatch.batchHash == previousBatchHash, "l");

49:          require(expectedPriorityOperationsHash == _newBatch.priorityOperationsHash, "t");

51:          require(expectedNumberOfLayer1Txs == _newBatch.numberOfLayer1Txs, "ta");

83:          require(batchTimestamp == _expectedBatchTimestamp, "tb");

87:          require(_previousBatchTimestamp < batchTimestamp, "h3");

95:          require(block.timestamp - COMMIT_TIMESTAMP_NOT_OLDER <= batchTimestamp, "h1"); // New batch timestamp is too small

96:          require(lastL2BlockTimestamp <= block.timestamp + COMMIT_TIMESTAMP_APPROXIMATION_DELTA, "h2"); // The last L2 block timestamp is too big

132:             require(!_checkBit(processedLogs, uint8(logKey)), "kp");

158:                 require(logSender == L2_BOOTLOADER_ADDRESS, "bu");

159:                 require(_expectedSystemContractUpgradeTxHash == logValue, "ut");

155:                 require(logSender == L2_BOOTLOADER_ADDRESS, "bk");

152:                 require(logSender == L2_BOOTLOADER_ADDRESS, "bl");

149:                 require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv");

146:                 require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc");

143:                 require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb");

140:                 require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln");

141:                 require(providedL2ToL1PubdataHash == logValue, "wp");

137:                 require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm");

171:             require(processedLogs == 255, "b8");

169:             require(processedLogs == 127, "b7");

186:         require(s.storedBatchHashes[s.totalBatchesCommitted] == _hashStoredBatchInfo(_lastCommittedBatchData), "i"); // incorrect previous batch data

238:         require(s.l2SystemContractsUpgradeBatchNumber == 0, "ik");

277:         require(currentBatchNumber == s.totalBatchesExecuted + _executedBatchIdx + 1, "k"); // Execute batches in order

278          require(
279              _hashStoredBatchInfo(_storedBatch) == s.storedBatchHashes[currentBatchNumber],
280              "exe10" // executing batch should be committed
281:         );

284:         require(priorityOperationsHash == _storedBatch.priorityOperationsHash, "x"); // priority operations hash does not match to expected

302:         require(newTotalBatchesExecuted <= s.totalBatchesVerified, "n"); // Can't execute batches more than committed and proven currently.

329:         require(_hashStoredBatchInfo(_prevBatch) == s.storedBatchHashes[currentTotalBatchesVerified], "t1");

334              require(
335                  _hashStoredBatchInfo(_committedBatches[i]) == s.storedBatchHashes[currentTotalBatchesVerified],
336                  "o1"
337:             );

348:         require(currentTotalBatchesVerified <= s.totalBatchesCommitted, "q");

361:             require(successVerifyProof, "p"); // Proof verification fail

392:         require(s.totalBatchesCommitted > _newLastBatch, "v1"); // The last committed batch is less than new last batch

393:         require(_newLastBatch >= s.totalBatchesExecuted, "v2"); // Already executed batches cannot be reverted

446:         require(_batch.systemLogs.length <= MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, "pu");

GitHub: 34, 47, 49, 51, 83, 87, 95, 96, 132, 158, 159, 155, 152, 149, 146, 143, 140, 141, 137, 171, 169, 186, 238, 277, 278, 284, 302, 329, 334, 348, 361, 392, 393, 446

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

162:         require(ds.selectorToFacet[_selector].facetAddress != address(0), "g2");

GitHub: 162

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

121:         require(callSuccess, "pz");

131:         require(_batchNumber <= s.totalBatchesExecuted, "xx");

138:         require(hashedLog != L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, "tw");

201:         require(!s.isEthWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "jj");

212:         require(proofValid, "pi"); // Failed to verify that withdrawal was actually initialized on L2

259:         require(_l2GasPerPubdataByteLimit == REQUIRED_L2_GAS_PRICE_PER_PUBDATA, "qp");

281:         require(s.totalDepositedAmountPerUser[_depositor] + _amount <= limitData.depositCap, "d2");

296:         require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "uj");

308:             require(msg.value >= baseCost + _l2Value, "mv"); // The `msg.value` doesn't cover the transaction cost

423:         require(_message.length >= 56, "pm");

426:         require(bytes4(functionSignature) == this.finalizeEthWithdrawal.selector, "is");

GitHub: 121, 131, 138, 201, 212, 259, 281, 296, 308, 423, 426

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

108:             require(selectors.length > 0, "B"); // no functions for diamond cut

134:         require(_facet != address(0), "G"); // facet with zero address cannot be added

143:             require(oldFacet.facetAddress == address(0), "J"); // facet for this selector already exists

158:         require(_facet != address(0), "K"); // cannot replace facet with zero address

164:             require(oldFacet.facetAddress != address(0), "L"); // it is impossible to replace the facet with zero address

178:         require(_facet == address(0), "a1"); // facet address must be zero

184:             require(oldFacet.facetAddress != address(0), "a2"); // Can't delete a non-existent facet

222:             require(_isSelectorFreezable == ds.selectorToFacet[selector0].isFreezable, "J1");

304:             require(data.length == 32, "lp");

305:             require(abi.decode(data, (bytes32)) == DIAMOND_INIT_SUCCESS_RETURN_VALUE, "lp1");

287:             require(_calldata.length == 0, "H"); // Non-empty calldata for zero address

GitHub: 108, 134, 143, 158, 164, 178, 184, 222, 304, 305, 287

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

26:          require(pathLength > 0, "xc");

27:          require(pathLength < 256, "bt");

28:          require(_index < (1 << pathLength), "px");

GitHub: 26, 27, 28

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

67:          require(!_queue.isEmpty(), "D"); // priority queue is empty

75:          require(!_queue.isEmpty(), "s"); // priority queue is empty

GitHub: 67, 75

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

32:          require(l2GasForTxBody <= _priorityTxMaxGasLimit, "ui");

34:          require(l2GasForTxBody / _transaction.gasPerPubdataByteLimit <= PRIORITY_TX_MAX_PUBDATA, "uk");

38           require(
39               getMinimalPriorityTransactionGasLimit(
40                   _encoded.length,
41                   _transaction.factoryDeps.length,
42                   _transaction.gasPerPubdataByteLimit
43               ) <= _transaction.gasLimit,
44               "up"
45:          );

52:          require(_transaction.from <= type(uint16).max, "ua");

53:          require(_transaction.to <= type(uint160).max, "ub");

54:          require(_transaction.paymaster == 0, "uc");

55:          require(_transaction.value == 0, "ud");

56:          require(_transaction.reserved[0] == 0, "ue");

57:          require(_transaction.reserved[1] <= type(uint160).max, "uf");

58:          require(_transaction.reserved[2] == 0, "ug");

59:          require(_transaction.reserved[3] == 0, "uo");

60:          require(_transaction.signature.length == 0, "uh");

61:          require(_transaction.paymasterInput.length == 0, "ul");

62:          require(_transaction.reservedDynamic.length == 0, "um");

119:         require(_totalGasLimit >= overhead, "my"); // provided gas limit doesn't cover transaction overhead

GitHub: 32, 34, 38, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 119

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

47:          require(_l1Bridge != address(0), "bf");

48:          require(_l2TokenProxyBytecodeHash != bytes32(0), "df");

49:          require(_governor != address(0), "sf");

73:          require(AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge, "mq");

84:              require(currentL1Token == _l1Token, "gg"); // Double check that the expected value equal to real one

81:              require(deployedToken == expectedL2Token, "mt");

115:         require(l1Token != address(0), "yh");

161:         require(success, "mk");

GitHub: 47, 48, 49, 73, 84, 81, 115, 161

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

49:          require(_l1Address != address(0), "in6"); // Should be non-zero address

103:         require(msg.sender == l2Bridge, "xnt"); // Only L2 bridge can call this method

GitHub: 49, 103

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

122:         require(msg.sender == l2WethAddress, "pd");

GitHub: 122

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

23:          require(_x <= type(uint128).max, "Overflow");

29:          require(_x <= type(uint32).max, "Overflow");

35:          require(_x <= type(uint24).max, "Overflow");

86:          require(_bytecode.length % 32 == 0, "po");

89:          require(bytecodeLenInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words

90:          require(bytecodeLenInWords % 2 == 1, "pr"); // bytecode length in words must be odd

GitHub: 23, 29, 35, 86, 89, 90

[N‑39] Event is not properly indexed

Index event fields make the field more quickly accessible to off-chain tools that parse events. This is especially useful when it comes to filtering based on an address. However, note that each index field costs extra gas during emission, so it's not necessarily best to index the maximum allowed per event (three fields). Where applicable, each event should use three indexed fields if there are three or more fields, and gas usage is not particularly of concern for the events in question. If there are fewer than three applicable fields, all of the applicable fields should be indexed.

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/governance/IGovernance.sol

76:       event ChangeSecurityCouncil(address _securityCouncilBefore, address _securityCouncilAfter);

GitHub: 76

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

32:       event NewValidator(address _oldValidator, address _newValidator);

GitHub: 32

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

144       event NewPriorityRequest(
145           uint256 txId,
146           bytes32 txHash,
147           uint64 expirationTimestamp,
148           L2CanonicalTransaction transaction,
149           bytes[] factoryDeps
150:      );

GitHub: 144

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

25:       event DiamondCut(FacetCut[] facetCuts, address initAddress, bytes initCalldata);

GitHub: 25

[N‑40] Events are missing sender information

When an action is triggered based on a user's action, not being able to filter based on who triggered the action makes event processing a lot more cumbersome. Including the msg.sender the events of these types of action will make events much more useful to end users, especially when msg.sender is not tx.origin.

There are 53 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

321:         emit WithdrawalFinalized(l1Receiver, l1Token, amount);

GitHub: 321

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

269:         emit WithdrawalFinalized(l1WethWithdrawReceiver, l1WethAddress, amount);

314:         emit EthReceived(msg.value);

GitHub: 269, 314

File: cache/solpp-generated-contracts/common/AllowList.sol

75:              emit UpdateAccessMode(_target, accessMode, _accessMode);

123:             emit UpdateCallPermission(_caller, _target, _functionSig, _enable);

GitHub: 75, 123

File: cache/solpp-generated-contracts/governance/Governance.sol

49:          emit ChangeSecurityCouncil(address(0), _securityCouncil);

52:          emit ChangeMinDelay(0, _minDelay);

134:         emit TransparentOperationScheduled(id, _delay, _operation);

146:         emit ShadowOperationScheduled(_id, _delay);

159:         emit OperationCancelled(_id);

182:         emit OperationExecuted(id);

201:         emit OperationExecuted(id);

252:         emit ChangeMinDelay(minDelay, _newDelay);

259:         emit ChangeSecurityCouncil(securityCouncil, _newSecurityCouncil);

GitHub: 49, 52, 134, 146, 159, 182, 201, 252, 259

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

91:          emit NewL2DefaultAccountBytecodeHash(previousDefaultAccountBytecodeHash, _l2DefaultAccountBytecodeHash);

108:         emit NewL2BootloaderBytecodeHash(previousBootloaderBytecodeHash, _l2BootloaderBytecodeHash);

124:         emit NewVerifier(address(oldVerifier), address(_newVerifier));

140:         emit NewVerifierParams(oldVerifierParams, _newVerifierParams);

231:         emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion);

243:         emit NewAllowList(address(oldAllowList), address(_newAllowList));

GitHub: 91, 108, 124, 140, 231, 243

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

45:          emit UpgradeComplete(_proposedUpgrade.newProtocolVersion, txHash, _proposedUpgrade);

GitHub: 45

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

57:          emit NewValidator(oldValidator, _newValidator);

63:          emit NewExecutionDelay(_executionDelay);

GitHub: 57, 63

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

27:          emit NewPendingGovernor(oldPendingGovernor, _newPendingGovernor);

39:          emit NewPendingGovernor(pendingGovernor, address(0));

40:          emit NewGovernor(previousGovernor, pendingGovernor);

51:          emit NewPendingGovernor(oldPendingAdmin, _newPendingAdmin);

63:          emit NewPendingAdmin(pendingAdmin, address(0));

64:          emit NewAdmin(previousAdmin, pendingAdmin);

72:          emit ValidatorStatusUpdate(_validator, _active);

80:          emit IsPorterAvailableStatusUpdate(_zkPorterIsAvailable);

90:          emit NewPriorityTxMaxGasLimit(oldPriorityTxMaxGasLimit, _newPriorityTxMaxGasLimit);

102:         emit ExecuteUpgrade(_diamondCut);

117:         emit Freeze();

128:         emit Unfreeze();

GitHub: 27, 39, 40, 51, 63, 64, 72, 80, 90, 102, 117, 128

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

215              emit BlockCommit(
216                  _lastCommittedBatchData.batchNumber,
217                  _lastCommittedBatchData.batchHash,
218                  _lastCommittedBatchData.commitment
219:             );

253              emit BlockCommit(
254                  _lastCommittedBatchData.batchNumber,
255                  _lastCommittedBatchData.batchHash,
256                  _lastCommittedBatchData.commitment
257:             );

297:             emit BlockExecution(_batchesData[i].batchNumber, _batchesData[i].batchHash, _batchesData[i].commitment);

364:         emit BlocksVerification(s.totalBatchesVerified, currentTotalBatchesVerified);

406:         emit BlocksRevert(s.totalBatchesCommitted, s.totalBatchesVerified, s.totalBatchesExecuted);

GitHub: 215, 253, 297, 364, 406

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

217:         emit EthWithdrawalFinalized(_l1WithdrawReceiver, _amount);

380          emit NewPriorityRequest(
381              _priorityOpParams.txId,
382              canonicalTxHash,
383              _priorityOpParams.expirationTimestamp,
384              transaction,
385              _factoryDeps
386:         );

GitHub: 217, 380

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

122:         emit DiamondCut(facetCuts, initAddress, initCalldata);

GitHub: 122

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

99:          emit BridgeInitialize(_l1Address, decodedName, decodedSymbol, decimals_);

113:         emit BridgeMint(_to, _amount);

122:         emit BridgeBurn(_from, _amount);

GitHub: 99, 113, 122

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

48:          emit Initialize(name_, symbol_, 18);

86:          emit BridgeBurn(_from, _amount);

GitHub: 48, 86

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

123:         emit EthReceived(msg.value);

GitHub: 123

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

62:              emit MarkedAsKnown(_bytecodeHash, _shouldSendToL1);

GitHub: 62

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

117:         emit L2ToL1LogSent(_l2ToL1Log);

188:         emit BytecodeL1PublicationRequested(_bytecodeHash);

GitHub: 117, 188

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

69:          emit Mint(_account, _amount);

GitHub: 69

[N‑41] Events may be emitted out of order due to reentrancy

Ensure that events follow the best practice of check-effects-interaction, and are emitted before external calls

There are 12 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

/// @audit safeTransfer() prior to emission
286:         emit ClaimedFailedDeposit(_depositSender, _l1Token, amount);

/// @audit safeTransfer() prior to emission
321:         emit WithdrawalFinalized(l1Receiver, l1Token, amount);

GitHub: 286, 321

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit safeTransferFrom() prior to emission
197:         emit DepositInitiated(txHash, msg.sender, _l2Receiver, _l1Token, _amount);

/// @audit finalizeEthWithdrawal() prior to emission
269:         emit WithdrawalFinalized(l1WethWithdrawReceiver, l1WethAddress, amount);

GitHub: 197, 269

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

/// @audit bridgeMint() prior to emission
89:          emit FinalizeDeposit(_l1Sender, _l2Receiver, expectedL2Token, _amount);

/// @audit bridgeBurn() prior to emission
120:         emit WithdrawalInitiated(msg.sender, _l1Receiver, _l2Token, _amount);

GitHub: 89, 120

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

/// @audit decodeString() prior to emission
99:          emit BridgeInitialize(_l1Address, decodedName, decodedSymbol, decimals_);

GitHub: 99

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

/// @audit bridgeBurn() prior to emission
82:          emit WithdrawalInitiated(msg.sender, _l1Receiver, l2WethAddress, _amount);

/// @audit bridgeBurn() prior to emission
108:         emit FinalizeDeposit(_l1Sender, _l2Receiver, l2WethAddress, _amount);

GitHub: 82, 108

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

/// @audit requestBytecodeL1Publication() prior to emission
62:              emit MarkedAsKnown(_bytecodeHash, _shouldSendToL1);

GitHub: 62

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

/// @audit sendToL1() prior to emission
81:          emit Withdrawal(msg.sender, _l1Receiver, amount);

/// @audit sendToL1() prior to emission
94:          emit WithdrawalWithMessage(msg.sender, _l1Receiver, amount, _additionalData);

GitHub: 81, 94

[N‑42] Events should use parameters to convey information

For example, rather than using event Paused() and event Unpaused(), use event PauseState(address indexed whoChangedIt, bool wasPaused, bool isNowPaused)

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

59:      event Freeze();

62:      event Unfreeze();

GitHub: 59, 62

[N‑43] Events that mark critical parameter changes should contain both the old and the new value

This should especially be done if the new value is not required to be different from the old value

There are 8 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

/// @audit updateDelay()
252:          emit ChangeMinDelay(minDelay, _newDelay);

/// @audit updateSecurityCouncil()
259:          emit ChangeSecurityCouncil(securityCouncil, _newSecurityCouncil);

GitHub: 252, 259

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

/// @audit setExecutionDelay()
63:           emit NewExecutionDelay(_executionDelay);

GitHub: 63

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

/// @audit setValidator()
72:           emit ValidatorStatusUpdate(_validator, _active);

/// @audit setPorterAvailability()
80:           emit IsPorterAvailableStatusUpdate(_zkPorterIsAvailable);

GitHub: 72, 80

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

/// @audit updateAccountVersion()
67:           emit AccountVersionUpdated(msg.sender, _version);

/// @audit updateNonceOrdering()
85:           emit AccountNonceOrderingUpdated(msg.sender, _nonceOrdering);

GitHub: 67, 85

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

/// @audit setValueUnderNonce()
98:           emit ValueSetUnderNonce(msg.sender, _key, _value);

GitHub: 98

[N‑44] Expressions for constant values should use immutable rather than constant

While it does not save gas for some simple binary expressions because the compiler knows that developers often make this mistake, it's still best to use the right tool for the task at hand. There is a difference between constant variables and immutable variables, and they should each be used in their appropriate contexts. constants should be used for literal values written into the code, and immutable variables should be used for expressions, or values calculated in, or passed into the constructor.

There are 79 instances of this issue:

see instances
File: cache/solpp-generated-contracts/common/L2ContractAddresses.sol

8:   address constant L2_DEPLOYER_SYSTEM_CONTRACT_ADDR = address(0x8006);

17:  address constant L2_FORCE_DEPLOYER_ADDR = address(0x8007);

20:  address constant L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR = address(0x8008);

23:  address constant L2_BOOTLOADER_ADDRESS = address(0x8001);

26:  address constant L2_ETH_TOKEN_SYSTEM_CONTRACT_ADDR = address(0x800a);

29:  address constant L2_KNOWN_CODE_STORAGE_SYSTEM_CONTRACT_ADDR = address(0x8004);

32:  address constant L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR = address(0x800b);

35:  address constant L2_BYTECODE_COMPRESSOR_SYSTEM_CONTRACT_ADDR = address(0x800e);

GitHub: 8, 17, 20, 23, 26, 29, 32, 35

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

14:      bytes32 constant CREATE2_PREFIX = keccak256("zksyncCreate2");

GitHub: 14

File: cache/solpp-generated-contracts/governance/Governance.sol

24:      uint256 internal constant EXECUTED_PROPOSAL_TIMESTAMP = uint256(1);

GitHub: 24

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

24:      uint160 constant offset = uint160(0x1111000000000000000000000000000000001111);

GitHub: 24

File: cache/solpp-generated-contracts/zksync/Config.sol

16:  uint256 constant MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES = 4 + L2_TO_L1_LOG_SERIALIZE_SIZE * 512;

28:  uint256 constant MAX_INITIAL_STORAGE_CHANGES_COMMITMENT_BYTES = 4 + INITIAL_STORAGE_CHANGE_SERIALIZE_SIZE * 4765;

35:  uint256 constant MAX_REPEATED_STORAGE_CHANGES_COMMITMENT_BYTES = 4 + REPEATED_STORAGE_CHANGE_SERIALIZE_SIZE * 7564;

38:  bytes32 constant DEFAULT_L2_LOGS_TREE_ROOT_HASH = bytes32(0);

90:  uint256 constant BATCH_OVERHEAD_PUBDATA = BATCH_OVERHEAD_L1_GAS / L1_GAS_PER_PUBDATA_BYTE;

GitHub: 16, 28, 35, 38, 90

File: cache-zk/solpp-generated-contracts/Constants.sol

27:  address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01);

28:  address constant SHA256_SYSTEM_CONTRACT = address(0x02);

29:  address constant ECADD_SYSTEM_CONTRACT = address(0x06);

30:  address constant ECMUL_SYSTEM_CONTRACT = address(0x07);

37:  uint256 constant CURRENT_MAX_PRECOMPILE_ADDRESS = uint256(uint160(SHA256_SYSTEM_CONTRACT));

39:  address payable constant BOOTLOADER_FORMAL_ADDRESS = payable(address(SYSTEM_CONTRACTS_OFFSET + 0x01));

40   IAccountCodeStorage constant ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT = IAccountCodeStorage(
41       address(SYSTEM_CONTRACTS_OFFSET + 0x02)
42:  );

43:  INonceHolder constant NONCE_HOLDER_SYSTEM_CONTRACT = INonceHolder(address(SYSTEM_CONTRACTS_OFFSET + 0x03));

44:  IKnownCodesStorage constant KNOWN_CODE_STORAGE_CONTRACT = IKnownCodesStorage(address(SYSTEM_CONTRACTS_OFFSET + 0x04));

45   IImmutableSimulator constant IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT = IImmutableSimulator(
46       address(SYSTEM_CONTRACTS_OFFSET + 0x05)
47:  );

48:  IContractDeployer constant DEPLOYER_SYSTEM_CONTRACT = IContractDeployer(address(SYSTEM_CONTRACTS_OFFSET + 0x06));

52:  address constant FORCE_DEPLOYER = address(SYSTEM_CONTRACTS_OFFSET + 0x07);

53:  IL1Messenger constant L1_MESSENGER_CONTRACT = IL1Messenger(address(SYSTEM_CONTRACTS_OFFSET + 0x08));

54:  address constant MSG_VALUE_SYSTEM_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x09);

56:  IEthToken constant ETH_TOKEN_SYSTEM_CONTRACT = IEthToken(address(SYSTEM_CONTRACTS_OFFSET + 0x0a));

58:  address constant KECCAK256_SYSTEM_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x10);

60:  ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(payable(address(SYSTEM_CONTRACTS_OFFSET + 0x0b)));

62:  IBootloaderUtilities constant BOOTLOADER_UTILITIES = IBootloaderUtilities(address(SYSTEM_CONTRACTS_OFFSET + 0x0c));

64:  address constant EVENT_WRITER_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x0d);

66:  ICompressor constant COMPRESSOR_CONTRACT = ICompressor(address(SYSTEM_CONTRACTS_OFFSET + 0x0e));

68:  IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(address(SYSTEM_CONTRACTS_OFFSET + 0x0f));

75:  uint256 constant MAX_MSG_VALUE = 2 ** 128 - 1;

114: uint256 constant COMPRESSED_INITIAL_WRITE_SIZE = DERIVED_KEY_LENGTH + VALUE_LENGTH;

116: uint256 constant COMPRESSED_REPEATED_WRITE_SIZE = ENUM_INDEX_LENGTH + VALUE_LENGTH;

GitHub: 27, 28, 29, 30, 37, 39, 40, 43, 44, 45, 48, 52, 53, 54, 56, 58, 60, 62, 64, 66, 68, 75, 114, 116

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

30:      uint256 constant DEPLOY_NONCE_MULTIPLIER = 2 ** 128;

33:      uint256 constant MAXIMAL_MIN_NONCE_INCREMENT = 2 ** 32;

GitHub: 30, 33

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

9:   bytes4 constant ACCOUNT_VALIDATION_SUCCESS_MAGIC = IAccount.validateTransaction.selector;

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

14:  bytes4 constant PAYMASTER_VALIDATION_SUCCESS_MAGIC = IPaymaster.validateAndPayForPaymasterTransaction.selector;

GitHub: 14

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

14:  address constant TO_L1_CALL_ADDRESS = address((1 << 16) - 1);

15:  address constant CODE_ADDRESS_CALL_ADDRESS = address((1 << 16) - 2);

16:  address constant PRECOMPILE_CALL_ADDRESS = address((1 << 16) - 3);

17:  address constant META_CALL_ADDRESS = address((1 << 16) - 4);

18:  address constant MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 5);

19:  address constant SYSTEM_MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 6);

20:  address constant MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 7);

21:  address constant SYSTEM_MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 8);

22:  address constant RAW_FAR_CALL_CALL_ADDRESS = address((1 << 16) - 9);

23:  address constant RAW_FAR_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 10);

24:  address constant SYSTEM_CALL_CALL_ADDRESS = address((1 << 16) - 11);

25:  address constant SYSTEM_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 12);

26:  address constant SET_CONTEXT_VALUE_CALL_ADDRESS = address((1 << 16) - 13);

27:  address constant SET_PUBDATA_PRICE_CALL_ADDRESS = address((1 << 16) - 14);

28:  address constant INCREMENT_TX_COUNTER_CALL_ADDRESS = address((1 << 16) - 15);

29:  address constant PTR_CALLDATA_CALL_ADDRESS = address((1 << 16) - 16);

30:  address constant CALLFLAGS_CALL_ADDRESS = address((1 << 16) - 17);

31:  address constant PTR_RETURNDATA_CALL_ADDRESS = address((1 << 16) - 18);

32:  address constant EVENT_INITIALIZE_ADDRESS = address((1 << 16) - 19);

33:  address constant EVENT_WRITE_ADDRESS = address((1 << 16) - 20);

34:  address constant LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 21);

35:  address constant LOAD_LATEST_RETURNDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 22);

36:  address constant PTR_ADD_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 23);

37:  address constant PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 24);

38:  address constant PTR_PACK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 25);

39:  address constant MULTIPLICATION_HIGH_ADDRESS = address((1 << 16) - 26);

40:  address constant GET_EXTRA_ABI_DATA_ADDRESS = address((1 << 16) - 27);

43:  uint256 constant META_GAS_PER_PUBDATA_BYTE_OFFSET = 0 * 8;

44:  uint256 constant META_HEAP_SIZE_OFFSET = 8 * 8;

45:  uint256 constant META_AUX_HEAP_SIZE_OFFSET = 12 * 8;

46:  uint256 constant META_SHARD_ID_OFFSET = 28 * 8;

47:  uint256 constant META_CALLER_SHARD_ID_OFFSET = 29 * 8;

48:  uint256 constant META_CODE_SHARD_ID_OFFSET = 30 * 8;

GitHub: 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 43, 44, 45, 46, 47, 48

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

84:      bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)");

86       bytes32 constant EIP712_TRANSACTION_TYPE_HASH =
87           keccak256(
88               "Transaction(uint256 txType,uint256 from,uint256 to,uint256 gasLimit,uint256 gasPerPubdataByteLimit,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 paymaster,uint256 nonce,uint256 value,bytes data,bytes32[] factoryDeps,bytes paymasterInput)"
89:          );

GitHub: 84, 86

[N‑45] High cyclomatic complexity

Consider breaking down these blocks into more manageable units, by splitting things into utility functions, by reducing nesting, and by using early returns

There is one instance of this issue:

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

103      function _processL2Logs(CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash)
104          internal
105          pure
106          returns (
107              uint256 numberOfLayer1Txs,
108              bytes32 chainedPriorityTxsHash,
109              bytes32 previousBatchHash,
110              bytes32 stateDiffHash,
111              bytes32 l2LogsTreeRoot,
112              uint256 packedBatchAndL2BlockTimestamp
113          )
114      {
115          // Copy L2 to L1 logs into memory.
116          bytes memory emittedL2Logs = _newBatch.systemLogs;
117  
118          // Used as bitmap to set/check log processing happens exactly once.
119          // See SystemLogKey enum in Constants.sol for ordering.
120          uint256 processedLogs;
121  
122          bytes32 providedL2ToL1PubdataHash = keccak256(_newBatch.totalL2ToL1Pubdata);
123  
124          // linear traversal of the logs
125          for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) {
126              // Extract the values to be compared to/used such as the log sender, key, and value
127              (address logSender, ) = UnsafeBytes.readAddress(emittedL2Logs, i + L2_LOG_ADDRESS_OFFSET);
128              (uint256 logKey, ) = UnsafeBytes.readUint256(emittedL2Logs, i + L2_LOG_KEY_OFFSET);
129              (bytes32 logValue, ) = UnsafeBytes.readBytes32(emittedL2Logs, i + L2_LOG_VALUE_OFFSET);
130  
131              // Ensure that the log hasn't been processed already
132              require(!_checkBit(processedLogs, uint8(logKey)), "kp");
133              processedLogs = _setBit(processedLogs, uint8(logKey));
134  
135              // Need to check that each log was sent by the correct address.
136              if (logKey == uint256(SystemLogKey.L2_TO_L1_LOGS_TREE_ROOT_KEY)) {
137                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lm");
138                  l2LogsTreeRoot = logValue;
139              } else if (logKey == uint256(SystemLogKey.TOTAL_L2_TO_L1_PUBDATA_KEY)) {
140                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "ln");
141                  require(providedL2ToL1PubdataHash == logValue, "wp");
142              } else if (logKey == uint256(SystemLogKey.STATE_DIFF_HASH_KEY)) {
143                  require(logSender == L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR, "lb");
144                  stateDiffHash = logValue;
145              } else if (logKey == uint256(SystemLogKey.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY)) {
146                  require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sc");
147                  packedBatchAndL2BlockTimestamp = uint256(logValue);
148              } else if (logKey == uint256(SystemLogKey.PREV_BATCH_HASH_KEY)) {
149                  require(logSender == L2_SYSTEM_CONTEXT_SYSTEM_CONTRACT_ADDR, "sv");
150                  previousBatchHash = logValue;
151              } else if (logKey == uint256(SystemLogKey.CHAINED_PRIORITY_TXN_HASH_KEY)) {
152                  require(logSender == L2_BOOTLOADER_ADDRESS, "bl");
153                  chainedPriorityTxsHash = logValue;
154              } else if (logKey == uint256(SystemLogKey.NUMBER_OF_LAYER_1_TXS_KEY)) {
155                  require(logSender == L2_BOOTLOADER_ADDRESS, "bk");
156                  numberOfLayer1Txs = uint256(logValue);
157              } else if (logKey == uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY)) {
158                  require(logSender == L2_BOOTLOADER_ADDRESS, "bu");
159                  require(_expectedSystemContractUpgradeTxHash == logValue, "ut");
160              } else {
161                  revert("ul");
162              }
163          }
164  
165          // We only require 7 logs to be checked, the 8th is if we are expecting a protocol upgrade
166          // Without the protocol upgrade we expect 7 logs: 2^7 - 1 = 127
167          // With the protocol upgrade we expect 8 logs: 2^8 - 1 = 255
168          if (_expectedSystemContractUpgradeTxHash == bytes32(0)) {
169              require(processedLogs == 127, "b7");
170          } else {
171              require(processedLogs == 255, "b8");
172          }
173:     }

GitHub: 103

[N‑46] Import declarations should import specific identifiers, rather than the whole file

Using import declarations of the form import {<identifier_name>} from "some/file.sol" avoids polluting the symbol namespace making flattened files smaller, and speeds up compilation (but does not save any gas)

There are 124 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

7:    import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

8:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

10:   import "./interfaces/IL1BridgeLegacy.sol";

11:   import "./interfaces/IL1Bridge.sol";

12:   import "./interfaces/IL2Bridge.sol";

13:   import "./interfaces/IL2ERC20Bridge.sol";

15:   import "./libraries/BridgeInitializationHelper.sol";

17:   import "../zksync/interfaces/IZkSync.sol";

18:   import "../common/interfaces/IAllowList.sol";

19:   import "../common/AllowListed.sol";

20:   import "../common/libraries/UnsafeBytes.sol";

21:   import "../common/libraries/L2ContractHelper.sol";

22:   import "../common/ReentrancyGuard.sol";

23:   import "../vendor/AddressAliasHelper.sol";

GitHub: 7, 8, 10, 11, 12, 13, 15, 17, 18, 19, 20, 21, 22, 23

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

7:    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

9:    import "./interfaces/IL1Bridge.sol";

10:   import "./interfaces/IL2WethBridge.sol";

11:   import "./interfaces/IL2Bridge.sol";

12:   import "./interfaces/IWETH9.sol";

13:   import "../zksync/interfaces/IZkSync.sol";

14:   import "../common/interfaces/IAllowList.sol";

16:   import "./libraries/BridgeInitializationHelper.sol";

18:   import "../common/AllowListed.sol";

19:   import "../common/libraries/UnsafeBytes.sol";

20:   import "../common/ReentrancyGuard.sol";

21:   import "../common/libraries/L2ContractHelper.sol";

23:   import "../vendor/AddressAliasHelper.sol";

GitHub: 7, 9, 10, 11, 12, 13, 14, 16, 18, 19, 20, 21, 23

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

7:    import "../../zksync/interfaces/IZkSync.sol";

8:    import "../../vendor/AddressAliasHelper.sol";

9:    import "../../common/libraries/L2ContractHelper.sol";

11:   import "../../common/interfaces/IL2ContractDeployer.sol";

GitHub: 7, 8, 9, 11

File: cache/solpp-generated-contracts/common/AllowList.sol

7:    import "@openzeppelin/contracts/access/Ownable2Step.sol";

9:    import "./interfaces/IAllowList.sol";

10:   import "./libraries/UncheckedMath.sol";

GitHub: 7, 9, 10

File: cache/solpp-generated-contracts/common/AllowListed.sol

7:    import "./interfaces/IAllowList.sol";

GitHub: 7

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

7:    import "../zksync/facets/Base.sol";

8:    import "../zksync/interfaces/IMailbox.sol";

9:    import "../zksync/interfaces/IVerifier.sol";

10:   import "../common/libraries/L2ContractHelper.sol";

11:   import "../zksync/libraries/TransactionValidator.sol";

GitHub: 7, 8, 9, 10, 11

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

7:    import "../zksync/libraries/Diamond.sol";

8:    import "./BaseZkSyncUpgrade.sol";

GitHub: 7, 8

File: cache/solpp-generated-contracts/zksync/Storage.sol

7:    import "./../zksync/interfaces/IVerifier.sol";

8:    import "../common/interfaces/IAllowList.sol";

9:    import "./libraries/PriorityQueue.sol";

GitHub: 7, 8, 9

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

7:    import "@openzeppelin/contracts/access/Ownable2Step.sol";

8:    import "./libraries/LibMap.sol";

9:    import "./interfaces/IExecutor.sol";

GitHub: 7, 8, 9

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

7:    import "../interfaces/IAdmin.sol";

8:    import "../libraries/Diamond.sol";

9:    import "../../common/libraries/L2ContractHelper.sol";

11:   import "./Base.sol";

GitHub: 7, 8, 9, 11

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

7:    import "../Storage.sol";

8:    import "../../common/ReentrancyGuard.sol";

9:    import "../../common/AllowListed.sol";

11:   import "@openzeppelin/contracts/access/Ownable.sol";

GitHub: 7, 8, 9, 11

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

7:    import "./Base.sol";

8:    import "../libraries/Diamond.sol";

9:    import "../libraries/PriorityQueue.sol";

10:   import "../../common/libraries/UncheckedMath.sol";

11:   import "../interfaces/IGetters.sol";

12:   import "../interfaces/ILegacyGetters.sol";

GitHub: 7, 8, 9, 10, 11, 12

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

7:    import "./IBase.sol";

GitHub: 7

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

7:    import "../libraries/PriorityQueue.sol";

9:    import "./IBase.sol";

GitHub: 7, 9

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

7:    import "../libraries/PriorityQueue.sol";

8:    import "./IBase.sol";

GitHub: 7, 8

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

8:    import "./IBase.sol";

GitHub: 8

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

7:    import "./IMailbox.sol";

8:    import "./IAdmin.sol";

9:    import "./IExecutor.sol";

10:   import "./IGetters.sol";

GitHub: 7, 8, 9, 10

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

7:    import "@openzeppelin/contracts/utils/math/SafeCast.sol";

8:    import "../../common/libraries/UncheckedMath.sol";

GitHub: 7, 8

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

7:    import "../../common/libraries/UncheckedMath.sol";

GitHub: 7

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

7:    import "@openzeppelin/contracts/utils/math/Math.sol";

9:    import "../interfaces/IMailbox.sol";

10:   import "../Config.sol";

GitHub: 7, 9, 10

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

7:    import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";

8:    import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";

10:   import "./interfaces/IL1Bridge.sol";

11:   import "./interfaces/IL2Bridge.sol";

12:   import "./interfaces/IL2StandardToken.sol";

14:   import "./L2StandardERC20.sol";

15:   import "../vendor/AddressAliasHelper.sol";

GitHub: 7, 8, 10, 11, 12, 14, 15

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

7:    import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";

8:    import "./interfaces/IL2StandardToken.sol";

GitHub: 7, 8

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

7:    import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";

9:    import "./interfaces/IL2Weth.sol";

10:   import "./interfaces/IL2StandardToken.sol";

GitHub: 7, 9, 10

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

7:    import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

9:    import "./interfaces/IL2Bridge.sol";

10:   import "./interfaces/IL2Weth.sol";

11:   import "./interfaces/IL2StandardToken.sol";

14:   import "../vendor/AddressAliasHelper.sol";

GitHub: 7, 9, 10, 11, 14

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

7:    import "./interfaces/IAccountCodeStorage.sol";

8:    import "./libraries/Utils.sol";

GitHub: 7, 8

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

7:    import "./interfaces/IBootloaderUtilities.sol";

8:    import "./libraries/TransactionHelper.sol";

9:    import "./libraries/RLPEncoder.sol";

10:   import "./libraries/EfficientCall.sol";

GitHub: 7, 8, 9, 10

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

7:    import "./interfaces/IAccount.sol";

8:    import "./libraries/TransactionHelper.sol";

9:    import "./libraries/SystemContractHelper.sol";

10:   import "./libraries/EfficientCall.sol";

GitHub: 7, 8, 9, 10

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

7:    import "./interfaces/IImmutableSimulator.sol";

GitHub: 7

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

7:    import "./libraries/Utils.sol";

8:    import "./libraries/EfficientCall.sol";

9:    import "./interfaces/ISystemContract.sol";

GitHub: 7, 8, 9

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

7:    import "./interfaces/INonceHolder.sol";

8:    import "./interfaces/IContractDeployer.sol";

GitHub: 7, 8

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

7:    import "../libraries/TransactionHelper.sol";

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

7:    import "../libraries/TransactionHelper.sol";

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

7:    import "../libraries/TransactionHelper.sol";

GitHub: 7

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

7:    import "./SystemContractHelper.sol";

8:    import "./Utils.sol";

GitHub: 7, 8

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

8:    import "./Utils.sol";

GitHub: 8

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

7:    import "../openzeppelin/token/ERC20/IERC20.sol";

8:    import "../openzeppelin/token/ERC20/utils/SafeERC20.sol";

10:   import "../interfaces/IPaymasterFlow.sol";

11:   import "../interfaces/IContractDeployer.sol";

13:   import "./RLPEncoder.sol";

14:   import "./EfficientCall.sol";

GitHub: 7, 8, 10, 11, 13, 14

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

6:    import "./EfficientCall.sol";

GitHub: 6

[N‑47] Imports could be organized more systematically

The contract's interface should be imported first, followed by each of the interfaces it uses, followed by all other files. The examples below do not follow this layout.

There are 3 instances of this issue:

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

11:  import "../../common/interfaces/IL2ContractDeployer.sol";

GitHub: 11

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

8:   import "../zksync/interfaces/IMailbox.sol";

GitHub: 8

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

18:  import {IAllowList} from "../../common/interfaces/IAllowList.sol";

GitHub: 18

[N‑48] Inconsistent method of specifying a floating pragma

Some files use >=, some use ^. The instances below are examples of the method that has the fewest instances for a specific version. Note that using >= without also specifying <= will lead to failures to compile, or external project incompatability, when the major version changes and there are breaking-changes, so ^ should be preferred regardless of the instance counts

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

1:    pragma solidity >=0.8.0;

GitHub: 1

[N‑49] Interfaces should be defined in separate files from their usage

The interfaces below should be defined in separate files, so that it's easier for future projects to import them, and to avoid duplication later on if they need to be used elsewhere in the project

There are 2 instances of this issue:

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

[N‑50] Large multiples of ten should use scientific notation (e.g. 1e6) rather than decimal literals (e.g. 1000000), for readability

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

20:       uint256 constant DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT = 10000000;

GitHub: 20

File: cache/solpp-generated-contracts/zksync/Config.sol

87:   uint256 constant BATCH_OVERHEAD_L1_GAS = 1000000;

GitHub: 87

[N‑51] Large numeric literals should use underscores for readability

There are 19 instances of this issue:

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

20:      uint256 constant DEPLOY_L2_BRIDGE_COUNTERPART_GAS_LIMIT = 10000000;

GitHub: 20

File: cache/solpp-generated-contracts/zksync/Config.sol

28:  uint256 constant MAX_INITIAL_STORAGE_CHANGES_COMMITMENT_BYTES = 4 + INITIAL_STORAGE_CHANGE_SERIALIZE_SIZE * 4765;

35:  uint256 constant MAX_REPEATED_STORAGE_CHANGES_COMMITMENT_BYTES = 4 + REPEATED_STORAGE_CHANGE_SERIALIZE_SIZE * 7564;

63:  uint256 constant INPUT_MASK = 26959946667150639794667015087019630673637144422540572481103610249215;

66:  uint256 constant L2_TX_MAX_GAS_LIMIT = 80000000;

69:  uint256 constant MAX_PUBDATA_PER_BATCH = 110000;

74:  uint256 constant PRIORITY_TX_MAX_PUBDATA = 99000;

77:  uint256 constant FAIR_L2_GAS_PRICE = 500000000;

84:  uint256 constant BATCH_OVERHEAD_L2_GAS = 1200000;

87:  uint256 constant BATCH_OVERHEAD_L1_GAS = 1000000;

93:  uint256 constant MAX_TRANSACTIONS_IN_BATCH = 1024;

96:  uint256 constant BOOTLOADER_TX_ENCODING_SPACE = 273132;

99:  uint256 constant L1_TX_INTRINSIC_L2_GAS = 167157;

105: uint256 constant L1_TX_MIN_L2_GAS_BASE = 173484;

108: uint256 constant L1_TX_DELTA_544_ENCODING_BYTES = 1656;

111: uint256 constant L1_TX_DELTA_FACTORY_DEPS_L2_GAS = 2473;

GitHub: 28, 35, 63, 66, 69, 74, 77, 84, 87, 93, 96, 99, 105, 108, 111

File: cache-zk/solpp-generated-contracts/Constants.sol

89:  uint256 constant MAX_ALLOWED_PUBDATA_PER_BATCH = 520000;

104: uint256 constant L2_TO_L1_LOGS_MERKLE_TREE_LEAVES = 2048;

GitHub: 89, 104

File: cache-zk/solpp-generated-contracts/SystemContext.sol

46:      uint256 public difficulty = 2500000000000000;

GitHub: 46

[N‑52] Large or complicated code bases should implement invariant tests

Large code bases, or code with lots of inline-assembly, complicated math, or complicated interactions between multiple contracts, should implement invariant fuzzing tests. Invariant fuzzers such as Echidna require the test writer to come up with invariants which should not be violated under any circumstances, and the fuzzer tests various inputs and function calls to ensure that the invariants always hold. Even code with 100% code coverage can still have bugs due to the order of the operations a user performs, and invariant fuzzers, with properly and extensively-written invariants, can close this testing gap significantly.

There is one instance of this issue:

File: Various Files

[N‑53] Libraries should be defined in separate files from their usage

The libraries below should be defined in separate files, so that it's easier for future projects to import them, and to avoid duplication later on if they need to be used elsewhere in the project

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

22:  library PriorityQueue {

GitHub: 22

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

70   library SystemContractsCaller {
71       /// @notice Makes a call with the `isSystem` flag.
72       /// @param gasLimit The gas limit for the call.
73       /// @param to The address to call.
74       /// @param value The value to pass with the transaction.
75       /// @param data The calldata.
76       /// @return success Whether the transaction has been successful.
77:      /// @dev Note, that the `isSystem` flag can only be set when calling system contracts.

GitHub: 70

[N‑54] Long functions should be refactored into multiple, smaller, functions

There are 13 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit 54 lines (46 in the body)
83        function initialize(
84            bytes[] calldata _factoryDeps,
85            address _l2WethAddress,
86            address _governor,
87            uint256 _deployBridgeImplementationFee,
88            uint256 _deployBridgeProxyFee
89:       ) external payable reentrancyGuardInitializer {

GitHub: 83

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

/// @audit 71 lines (58 in the body)
103       function _processL2Logs(CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash)
104           internal
105           pure
106           returns (
107               uint256 numberOfLayer1Txs,
108               bytes32 chainedPriorityTxsHash,
109               bytes32 previousBatchHash,
110               bytes32 stateDiffHash,
111               bytes32 l2LogsTreeRoot,
112:              uint256 packedBatchAndL2BlockTimestamp

/// @audit 54 lines (48 in the body)
313       function proveBatches(
314           StoredBatchInfo calldata _prevBatch,
315           StoredBatchInfo[] calldata _committedBatches,
316           ProofInput calldata _proof
317:      ) external nonReentrant onlyValidator {

GitHub: 103, 313

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

/// @audit 53 lines (51 in the body)
48:       function bridgeInitialize(address _l1Address, bytes memory _data) external initializer {

GitHub: 48

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

/// @audit 91 lines (89 in the body)
46:       function encodeLegacyTransactionHash(Transaction calldata _transaction) internal view returns (bytes32 txHash) {

/// @audit 86 lines (84 in the body)
141:      function encodeEIP2930TransactionHash(Transaction calldata _transaction) internal view returns (bytes32) {

/// @audit 91 lines (89 in the body)
231:      function encodeEIP1559TransactionHash(Transaction calldata _transaction) internal view returns (bytes32) {

GitHub: 46, 141, 231

File: cache-zk/solpp-generated-contracts/Compressor.sol

/// @audit 79 lines (72 in the body)
119       function verifyCompressedStateDiffs(
120           uint256 _numberOfStateDiffs,
121           uint256 _enumerationIndexSize,
122           bytes calldata _stateDiffs,
123           bytes calldata _compressedStateDiffs
124:      ) external payable onlyCallFrom(address(L1_MESSENGER_CONTRACT)) returns (bytes32 stateDiffHash) {

GitHub: 119

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

/// @audit 138 lines (134 in the body)
201       function publishPubdataAndClearState(
202           bytes calldata _totalL2ToL1PubdataAndStateDiffs
203:      ) external onlyCallFromBootloader {

GitHub: 201

File: cache-zk/solpp-generated-contracts/SystemContext.sol

/// @audit 58 lines (50 in the body)
314       function setL2Block(
315           uint128 _l2BlockNumber,
316           uint128 _l2BlockTimestamp,
317           bytes32 _expectedPrevL2BlockHash,
318           bool _isFirstInBatch,
319           uint128 _maxVirtualBlocksToCreate
320:      ) external onlyCallFromBootloader {

GitHub: 314

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

/// @audit 69 lines (67 in the body)
149:      function _encodeHashLegacyTransaction(Transaction calldata _transaction) private view returns (bytes32) {

/// @audit 67 lines (65 in the body)
221:      function _encodeHashEIP2930Transaction(Transaction calldata _transaction) private view returns (bytes32) {

/// @audit 69 lines (67 in the body)
291:      function _encodeHashEIP1559Transaction(Transaction calldata _transaction) private view returns (bytes32) {

GitHub: 149, 221, 291

[N‑55] Memory-safe annotation preferred over comment variant

The memory-safe annotation (assembly ("memory-safe") { ... }), available starting in Solidity version 0.8.13 is preferred over the comment variant, which will be removed in a future breaking release. The comment variant is only meant for externalized library code that needs to work in earlier versions (e.g. SafeTransferLib needs to be able to be used in many different versions).

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

301              /// @solidity memory-safe-assembly
302              assembly {
303                  let returndata_size := mload(returndata)
304                  revert(add(32, returndata), returndata_size)
305:             }

GitHub: 301

[N‑56] Misplaced SPDX identifier

The SPDX identifier should be on the very first line of the file

There are 94 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowList.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/AllowListed.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/L2ContractAddresses.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/governance/Governance.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/governance/IGovernance.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Config.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/Storage.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

1:    pragma solidity ^0.8.13;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/Compressor.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/Constants.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/SystemContext.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/INonceHolder.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/IPaymasterFlow.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContext.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContextDeprecated.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

1:    pragma solidity ^0.8;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/UnsafeBytesCalldata.sol

1:    pragma solidity ^0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

1:    pragma solidity >=0.8.0;

GitHub: 1

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

1:    pragma solidity ^0.8.1;

GitHub: 1

[N‑57] Missing checks constructor/initializer assignments

Consider whether reasonable bounds checks for variables would be useful

There are 2 instances of this issue:

File: cache/solpp-generated-contracts/governance/Governance.sol

51:          minDelay = _minDelay;

GitHub: 51

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

49:          executionDelay = _executionDelay;

GitHub: 49

[N‑58] Missing checks for state variable assignments

Consider whether reasonable bounds checks for variables would be useful

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

62:          executionDelay = _executionDelay;

GitHub: 62

File: cache-zk/solpp-generated-contracts/SystemContext.sol

96:          gasPrice = _gasPrice;

437:         baseFee = _baseFee;

453:         baseFee = _baseFee;

GitHub: 96, 437, 453

[N‑59] Missing event and or timelock for critical parameter change

Events help non-contract tools to track changes, and timelocks prevent users from being surprised by changes

There are 4 instances of this issue:

File: cache/solpp-generated-contracts/common/AllowList.sol

131      function setDepositLimit(address _l1Token, bool _depositLimitation, uint256 _depositCap) external onlyOwner {
132          tokenDeposit[_l1Token].depositLimitation = _depositLimitation;
133          tokenDeposit[_l1Token].depositCap = _depositCap;
134:     }

GitHub: 131

File: cache-zk/solpp-generated-contracts/SystemContext.sol

89       function setTxOrigin(address _newOrigin) external onlyCallFromBootloader {
90           origin = _newOrigin;
91:      }

95       function setGasPrice(uint256 _gasPrice) external onlyCallFromBootloader {
96           gasPrice = _gasPrice;
97:      }

418      function setNewBatch(
419          bytes32 _prevBatchHash,
420          uint128 _newTimestamp,
421          uint128 _expectedNewNumber,
422          uint256 _baseFee
423      ) external onlyCallFromBootloader {
424          (uint128 previousBatchNumber, uint128 previousBatchTimestamp) = getBatchNumberAndTimestamp();
425          require(_newTimestamp > previousBatchTimestamp, "Timestamps should be incremental");
426          require(previousBatchNumber + 1 == _expectedNewNumber, "The provided block number is not correct");
427  
428          _ensureBatchConsistentWithL2Block(_newTimestamp);
429  
430          batchHash[previousBatchNumber] = _prevBatchHash;
431  
432          // Setting new block number and timestamp
433          BlockInfo memory newBlockInfo = BlockInfo({number: previousBatchNumber + 1, timestamp: _newTimestamp});
434  
435          currentBatchInfo = newBlockInfo;
436  
437          baseFee = _baseFee;
438  
439          // The correctness of this block hash:
440          SystemContractHelper.toL1(false, bytes32(uint256(SystemLogKey.PREV_BATCH_HASH_KEY)), _prevBatchHash);
441:     }

GitHub: 89, 95, 418

[N‑60] Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct, for readability

Well-organized data structures make code reviews easier, which may lead to fewer bugs. Consider combining related mappings into mappings to structs, so it's clear what data is related

There is one instance of this issue:

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

38        mapping(uint256 => uint256) internal rawNonces;
39    
40        /// Mapping of values under nonces for accounts.
41        /// The main key of the mapping is the 256-bit address of the account, while the
42        /// inner mapping is a mapping from a nonce to the value stored there.
43:       mapping(uint256 => mapping(uint256 => uint256)) internal nonceValues;

GitHub: 38

[N‑61] Named imports of parent contracts are missing

There are 43 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

/// @audit IL1Bridge
/// @audit IL1BridgeLegacy
/// @audit AllowListed
/// @audit ReentrancyGuard
30:  contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGuard {

GitHub: 30, 30, 30, 30

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit IL1Bridge
/// @audit AllowListed
/// @audit ReentrancyGuard
39:  contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {

GitHub: 39, 39, 39

File: cache/solpp-generated-contracts/common/AllowList.sol

/// @audit IAllowList
/// @audit Ownable2Step
20:  contract AllowList is IAllowList, Ownable2Step {

GitHub: 20, 20

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

/// @audit Base
17:  abstract contract BaseZkSyncUpgrade is Base {

GitHub: 17

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

/// @audit BaseZkSyncUpgrade
12:  contract DefaultUpgrade is BaseZkSyncUpgrade {

GitHub: 12

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

/// @audit IExecutor
/// @audit Ownable2Step
22:  contract ValidatorTimelock is IExecutor, Ownable2Step {

GitHub: 22, 22

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

/// @audit Base
/// @audit IAdmin
16:  contract AdminFacet is Base, IAdmin {

GitHub: 16, 16

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

/// @audit ReentrancyGuard
/// @audit AllowListed
16:  contract Base is ReentrancyGuard, AllowListed {

GitHub: 16, 16

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

/// @audit Base
/// @audit IGetters
/// @audit ILegacyGetters
17:  contract GettersFacet is Base, IGetters, ILegacyGetters {

GitHub: 17, 17, 17

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

/// @audit IBase
11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

/// @audit IBase
11:  interface IGetters is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

/// @audit IBase
13:  interface ILegacyGetters is IBase {

GitHub: 13

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

/// @audit IBase
18:  interface IMailbox is IBase {

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

/// @audit IMailbox
/// @audit IAdmin
/// @audit IExecutor
/// @audit IGetters
12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12, 12, 12, 12

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

/// @audit IL2Bridge
/// @audit Initializable
22:  contract L2ERC20Bridge is IL2Bridge, Initializable {

GitHub: 22, 22

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

/// @audit ERC20PermitUpgradeable
/// @audit IL2StandardToken
13:  contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken {

GitHub: 13, 13

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

/// @audit ERC20PermitUpgradeable
/// @audit IL2Weth
/// @audit IL2StandardToken
23:  contract L2Weth is ERC20PermitUpgradeable, IL2Weth, IL2StandardToken {

GitHub: 23, 23, 23

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

/// @audit IL2Bridge
/// @audit Initializable
23:  contract L2WethBridge is IL2Bridge, Initializable {

GitHub: 23, 23

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

/// @audit IAccountCodeStorage
24:  contract AccountCodeStorage is IAccountCodeStorage {

GitHub: 24

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

/// @audit IBootloaderUtilities
18:  contract BootloaderUtilities is IBootloaderUtilities {

GitHub: 18

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

/// @audit IAccount
21:  contract DefaultAccount is IAccount {

GitHub: 21

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

/// @audit IImmutableSimulator
20:  contract ImmutableSimulator is IImmutableSimulator {

GitHub: 20

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

/// @audit ISystemContract
21:  contract MsgValueSimulator is ISystemContract {

GitHub: 21

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

/// @audit INonceHolder
29:  contract NonceHolder is INonceHolder, ISystemContract {

GitHub: 29

[N‑62] NatSpec: Contract declarations should have @author tags

There are 29 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

7:   interface IL2WethBridge {

GitHub: 7

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

6:   interface IWETH9 {

GitHub: 6

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

27   abstract contract ReentrancyGuard {
28       /// @dev Address of lock flag variable.
29       /// @dev Flag is placed at random memory location to not interfere with Storage contract.
30:      // keccak256("ReentrancyGuard") - 1;

GitHub: 27

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

7    interface IAllowList {
8        /*//////////////////////////////////////////////////////////////
9                                EVENTS
10       //////////////////////////////////////////////////////////////*/
11   
12:      /// @notice Access mode of target contract is changed

GitHub: 7

File: cache/solpp-generated-contracts/governance/IGovernance.sol

7    interface IGovernance {
8        /// @dev This enumeration includes the following states:
9        /// @param Unset Default state, indicating the operation has not been set.
10       /// @param Waiting The operation is scheduled but not yet ready to be executed.
11       /// @param Ready The operation is ready to be executed.
12:      /// @param Done The operation has been successfully executed.

GitHub: 7

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

23:  library AddressAliasHelper {

GitHub: 23

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

6:   interface IBase {

GitHub: 6

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

30   interface IExecutor is IBase {
31       /// @notice Rollup batch stored data
32       /// @param batchNumber Rollup batch number
33       /// @param batchHash Hash of L2 batch
34       /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
35       /// @param numberOfLayer1Txs Number of priority operations to be processed
36       /// @param priorityOperationsHash Hash of all priority operations from this batch
37       /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch
38       /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant
39:      /// @param commitment Verified input for the zkSync circuit

GitHub: 30

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

11   interface IGetters is IBase {
12       /*//////////////////////////////////////////////////////////////
13                               CUSTOM GETTERS
14       //////////////////////////////////////////////////////////////*/
15:  

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

18   interface IMailbox is IBase {
19       /// @dev Structure that includes all fields of the L2 transaction
20       /// @dev The hash of this structure is the "canonical L2 transaction hash" and can be used as a unique identifier of a tx
21       /// @param txType The tx type number, depending on which the L2 transaction can be interpreted differently
22       /// @param from The sender's address. `uint256` type for possible address format changes and maintaining backward compatibility
23       /// @param to The recipient's address. `uint256` type for possible address format changes and maintaining backward compatibility
24       /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an L1 transactions
25       /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata (every piece of data that will be stored on L1 as calldata)
26       /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get the transaction included in a batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
27       /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator to incentivize them to include the transaction in a batch. Analog to the EIP-1559 `maxPriorityFeePerGas` on an L1 transactions
28       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility
29       /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority operation Id.
30       /// @param value The value to pass with the transaction
31       /// @param reserved The fixed-length fields for usage in a future extension of transaction formats
32       /// @param data The calldata that is transmitted for the transaction call
33       /// @param signature An abstract set of bytes that are used for transaction authorization
34       /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
35       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
36:      /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

6:   interface IL2Weth {

GitHub: 6

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

7:   interface IAccountCodeStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

9:   interface IBootloaderUtilities {

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

7:   interface IComplexUpgrader {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

14:  interface ICompressor {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

7    interface IContractDeployer {
8        /// @notice Defines the version of the account abstraction protocol
9        /// that a contract claims to follow.
10       /// - `None` means that the account is just a contract and it should never be interacted
11       /// with as a custom account
12:      /// - `Version1` means that the account follows the first version of the account abstraction protocol

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

7:   interface IEthToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

12:  interface IImmutableSimulator {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

7:   interface IKnownCodesStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

37   interface IL1Messenger {
38       // Possibly in the future we will be able to track the messages sent to L1 with
39:      // some hooks in the VM. For now, it is much easier to track them with L2 events.

GitHub: 37

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

7:   interface IMailbox {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

14   abstract contract ISystemContract {
15       /// @notice Modifier that makes sure that the method
16:      /// can only be called via a system call.

GitHub: 14

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

11   library Address {
12       /**
13        * @dev Returns true if `account` is a contract.
14        *
15        * [IMPORTANT]
16        * ====
17        * It is unsafe to assume that an address for which this function returns
18        * false is an externally-owned account (EOA) and not a contract.
19        *
20        * Among others, `isContract` will return false for the following
21        * types of addresses:
22        *
23        *  - an externally-owned account
24        *  - a contract in construction
25        *  - an address where a contract will be created
26        *  - an address where a contract lived, but was destroyed
27        * ====
28        *
29        * [IMPORTANT]
30        * ====
31        * You shouldn't rely on `isContract` to protect against flash loan attacks!
32        *
33        * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
34        * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
35        * constructor.
36        * ====
37:       */

GitHub: 11

[N‑63] NatSpec: Contract declarations should have @dev tags

@dev is used to explain extra details to developers

There are 57 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

8:   interface IL1Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

8:   interface IL1BridgeLegacy {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

8:   interface IL2Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

8:   interface IL2ERC20Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

7:   interface IL2WethBridge {

GitHub: 7

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

6:   interface IWETH9 {

GitHub: 6

File: cache/solpp-generated-contracts/common/AllowListed.sol

11:  abstract contract AllowListed {

GitHub: 11

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

7    interface IAllowList {
8        /*//////////////////////////////////////////////////////////////
9                                EVENTS
10       //////////////////////////////////////////////////////////////*/
11   
12:      /// @notice Access mode of target contract is changed

GitHub: 7

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

11   interface IL2ContractDeployer {
12       /// @notice A struct that describes a forced deployment on an address.
13       /// @param bytecodeHash The bytecode hash to put on an address.
14       /// @param newAddress The address on which to deploy the bytecodehash to.
15       /// @param callConstructor Whether to run the constructor on the force deployment.
16       /// @param value The `msg.value` with which to initialize a contract.
17:      /// @param input The constructor calldata.

GitHub: 11

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

12   library L2ContractHelper {
13:      /// @dev The prefix used to create CREATE2 addresses.

GitHub: 12

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

12:  library UncheckedMath {

GitHub: 12

File: cache/solpp-generated-contracts/governance/IGovernance.sol

7    interface IGovernance {
8        /// @dev This enumeration includes the following states:
9        /// @param Unset Default state, indicating the operation has not been set.
10       /// @param Waiting The operation is scheduled but not yet ready to be executed.
11       /// @param Ready The operation is ready to be executed.
12:      /// @param Done The operation has been successfully executed.

GitHub: 7

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

17   abstract contract BaseZkSyncUpgrade is Base {
18       /// @notice The struct that represents the upgrade proposal.
19       /// @param l2ProtocolUpgradeTx The system upgrade transaction.
20       /// @param factoryDeps The list of factory deps for the l2ProtocolUpgradeTx.
21       /// @param bootloaderHash The hash of the new bootloader bytecode. If zero, it will not be updated.
22       /// @param defaultAccountHash The hash of the new default account bytecode. If zero, it will not be updated.
23       /// @param verifier The address of the new verifier. If zero, the verifier will not be updated.
24       /// @param verifierParams The new verifier params. If either of its fields is 0, the params will not be updated.
25       /// @param l1ContractsUpgradeCalldata Custom calldata for L1 contracts upgrade, it may be interpreted differently
26       /// in each upgrade. Usually empty.
27       /// @param postUpgradeCalldata Custom calldata for post upgrade hook, it may be interpreted differently in each
28       /// upgrade. Usually empty.
29       /// @param upgradeTimestamp The timestamp after which the upgrade can be executed.
30       /// @param newProtocolVersion The new version number for the protocol after this upgrade. Should be greater than
31       /// the previous protocol version.
32:      /// @param newAllowList The address of the new allowlist contract. If zero, it will not be updated.

GitHub: 17

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

12   contract DefaultUpgrade is BaseZkSyncUpgrade {
13       /// @notice Placeholder function for custom logic for upgrading L1 contract.
14       /// Typically this function will never be used.
15       /// @param _customCallDataForUpgrade Custom data for an upgrade, which may be interpreted differently for each
16:      /// upgrade.

GitHub: 12

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

23:  library AddressAliasHelper {

GitHub: 23

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

12:  contract DiamondProxy {

GitHub: 12

File: cache/solpp-generated-contracts/zksync/facets/Admin.sol

16:  contract AdminFacet is Base, IAdmin {

GitHub: 16

File: cache/solpp-generated-contracts/zksync/facets/Base.sol

16:  contract Base is ReentrancyGuard, AllowListed {

GitHub: 16

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

20:  contract ExecutorFacet is Base, IExecutor {

GitHub: 20

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

17:  contract GettersFacet is Base, IGetters, ILegacyGetters {

GitHub: 17

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

39:  contract MailboxFacet is Base, IMailbox {

GitHub: 39

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

6:   interface IBase {

GitHub: 6

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

30   interface IExecutor is IBase {
31       /// @notice Rollup batch stored data
32       /// @param batchNumber Rollup batch number
33       /// @param batchHash Hash of L2 batch
34       /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
35       /// @param numberOfLayer1Txs Number of priority operations to be processed
36       /// @param priorityOperationsHash Hash of all priority operations from this batch
37       /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch
38       /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant
39:      /// @param commitment Verified input for the zkSync circuit

GitHub: 30

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

11   interface IGetters is IBase {
12       /*//////////////////////////////////////////////////////////////
13                               CUSTOM GETTERS
14       //////////////////////////////////////////////////////////////*/
15:  

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

18   interface IMailbox is IBase {
19       /// @dev Structure that includes all fields of the L2 transaction
20       /// @dev The hash of this structure is the "canonical L2 transaction hash" and can be used as a unique identifier of a tx
21       /// @param txType The tx type number, depending on which the L2 transaction can be interpreted differently
22       /// @param from The sender's address. `uint256` type for possible address format changes and maintaining backward compatibility
23       /// @param to The recipient's address. `uint256` type for possible address format changes and maintaining backward compatibility
24       /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an L1 transactions
25       /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata (every piece of data that will be stored on L1 as calldata)
26       /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get the transaction included in a batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
27       /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator to incentivize them to include the transaction in a batch. Analog to the EIP-1559 `maxPriorityFeePerGas` on an L1 transactions
28       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility
29       /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority operation Id.
30       /// @param value The value to pass with the transaction
31       /// @param reserved The fixed-length fields for usage in a future extension of transaction formats
32       /// @param data The calldata that is transmitted for the transaction call
33       /// @param signature An abstract set of bytes that are used for transaction authorization
34       /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
35       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
36:      /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

13:  library Diamond {

GitHub: 13

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

8    library LibMap {
9:       /// @dev A uint32 map in storage.

GitHub: 8

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

11:  library Merkle {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol

15   library TransactionValidator {
16       /// @dev Used to validate key properties of an L1->L2 transaction
17       /// @param _transaction The transaction to validate
18       /// @param _encoded The abi encoded bytes of the transaction
19:      /// @param _priorityTxMaxGasLimit The max gas limit, generally provided from Storage.sol

GitHub: 15

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

22   contract L2ERC20Bridge is IL2Bridge, Initializable {
23:      /// @dev The address of the L1 bridge counterpart.

GitHub: 22

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

13   contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken {
14       /// @dev Describes whether there is a specific getter in the token.
15       /// @notice Used to explicitly separate which getters the token has and which it does not.
16       /// @notice Different tokens in L1 can implement or not implement getter function as `name`/`symbol`/`decimals`,
17:      /// @notice Our goal is to store all the getters that L1 token implements, and for others, we keep it as an unimplemented method.

GitHub: 13

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

8:   interface IL1Bridge {

GitHub: 8

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

8:   interface IL2Bridge {

GitHub: 8

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

6:   interface IL2Weth {

GitHub: 6

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

18:  contract BootloaderUtilities is IBootloaderUtilities {

GitHub: 18

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

16   contract ComplexUpgrader is IComplexUpgrader {
17       /// @notice Executes an upgrade process by delegating calls to another contract.
18       /// @dev This function allows only the `FORCE_DEPLOYER` to initiate the upgrade.
19       /// If the delegate call fails, the function will revert the transaction, returning the error message
20       /// provided by the delegated contract.
21       /// @param _delegateTo the address of the contract to which the calls will be delegated
22:      /// @param _calldata the calldata to be delegate called in the `_delegateTo` contract

GitHub: 16

File: cache-zk/solpp-generated-contracts/SystemContext.sol

19   contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContract {
20       /// @notice The number of latest L2 blocks to store.
21       /// @dev EVM requires us to be able to query the hashes of previous 256 blocks.
22       /// We could either:
23       /// - Store the latest 256 hashes (and strictly rely that we do not accidentally override the hash of the block 256 blocks ago)
24:      /// - Store the latest 257 blocks's hashes.

GitHub: 19

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

7:   interface IAccountCodeStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

9:   interface IBootloaderUtilities {

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

7:   interface IComplexUpgrader {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

14:  interface ICompressor {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

7    interface IContractDeployer {
8        /// @notice Defines the version of the account abstraction protocol
9        /// that a contract claims to follow.
10       /// - `None` means that the account is just a contract and it should never be interacted
11       /// with as a custom account
12:      /// - `Version1` means that the account follows the first version of the account abstraction protocol

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

7:   interface IEthToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

12:  interface IImmutableSimulator {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

7:   interface IKnownCodesStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

37   interface IL1Messenger {
38       // Possibly in the future we will be able to track the messages sent to L1 with
39:      // some hooks in the VM. For now, it is much easier to track them with L2 events.

GitHub: 37

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

7:   interface IMailbox {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContext.sol

12:  interface ISystemContext {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContextDeprecated.sol

11:  interface ISystemContextDeprecated {

GitHub: 11

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

12:  library RLPEncoder {

GitHub: 12

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

80:  library TransactionHelper {

GitHub: 80

[N‑64] NatSpec: Contract declarations should have @notice tags

@notice is used to explain to end users what the contract does, and the compiler interprets /// or /** comments as this tag if one wasn't explicitly provided

There are 26 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

7:   interface IL2WethBridge {

GitHub: 7

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

6:   interface IWETH9 {

GitHub: 6

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

7    interface IAllowList {
8        /*//////////////////////////////////////////////////////////////
9                                EVENTS
10       //////////////////////////////////////////////////////////////*/
11   
12:      /// @notice Access mode of target contract is changed

GitHub: 7

File: cache/solpp-generated-contracts/governance/IGovernance.sol

7    interface IGovernance {
8        /// @dev This enumeration includes the following states:
9        /// @param Unset Default state, indicating the operation has not been set.
10       /// @param Waiting The operation is scheduled but not yet ready to be executed.
11       /// @param Ready The operation is ready to be executed.
12:      /// @param Done The operation has been successfully executed.

GitHub: 7

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

23:  library AddressAliasHelper {

GitHub: 23

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

6:   interface IBase {

GitHub: 6

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

30   interface IExecutor is IBase {
31       /// @notice Rollup batch stored data
32       /// @param batchNumber Rollup batch number
33       /// @param batchHash Hash of L2 batch
34       /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
35       /// @param numberOfLayer1Txs Number of priority operations to be processed
36       /// @param priorityOperationsHash Hash of all priority operations from this batch
37       /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch
38       /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant
39:      /// @param commitment Verified input for the zkSync circuit

GitHub: 30

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

11   interface IGetters is IBase {
12       /*//////////////////////////////////////////////////////////////
13                               CUSTOM GETTERS
14       //////////////////////////////////////////////////////////////*/
15:  

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

18   interface IMailbox is IBase {
19       /// @dev Structure that includes all fields of the L2 transaction
20       /// @dev The hash of this structure is the "canonical L2 transaction hash" and can be used as a unique identifier of a tx
21       /// @param txType The tx type number, depending on which the L2 transaction can be interpreted differently
22       /// @param from The sender's address. `uint256` type for possible address format changes and maintaining backward compatibility
23       /// @param to The recipient's address. `uint256` type for possible address format changes and maintaining backward compatibility
24       /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an L1 transactions
25       /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata (every piece of data that will be stored on L1 as calldata)
26       /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get the transaction included in a batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
27       /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator to incentivize them to include the transaction in a batch. Analog to the EIP-1559 `maxPriorityFeePerGas` on an L1 transactions
28       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility
29       /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority operation Id.
30       /// @param value The value to pass with the transaction
31       /// @param reserved The fixed-length fields for usage in a future extension of transaction formats
32       /// @param data The calldata that is transmitted for the transaction call
33       /// @param signature An abstract set of bytes that are used for transaction authorization
34       /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
35       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
36:      /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

6:   interface IL2Weth {

GitHub: 6

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

7:   interface IAccountCodeStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

9:   interface IBootloaderUtilities {

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

7:   interface IComplexUpgrader {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

14:  interface ICompressor {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

7    interface IContractDeployer {
8        /// @notice Defines the version of the account abstraction protocol
9        /// that a contract claims to follow.
10       /// - `None` means that the account is just a contract and it should never be interacted
11       /// with as a custom account
12:      /// - `Version1` means that the account follows the first version of the account abstraction protocol

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

7:   interface IEthToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

12:  interface IImmutableSimulator {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

7:   interface IKnownCodesStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

37   interface IL1Messenger {
38       // Possibly in the future we will be able to track the messages sent to L1 with
39:      // some hooks in the VM. For now, it is much easier to track them with L2 events.

GitHub: 37

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

7:   interface IMailbox {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

[N‑65] NatSpec: Contract declarations should have @title tags

There are 83 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

30:  contract L1ERC20Bridge is IL1Bridge, IL1BridgeLegacy, AllowListed, ReentrancyGuard {

GitHub: 30

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

39:  contract L1WethBridge is IL1Bridge, AllowListed, ReentrancyGuard {

GitHub: 39

File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

8:   interface IL1Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

8:   interface IL1BridgeLegacy {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

8:   interface IL2Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

8:   interface IL2ERC20Bridge {

GitHub: 8

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

7:   interface IL2WethBridge {

GitHub: 7

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

6:   interface IWETH9 {

GitHub: 6

File: cache/solpp-generated-contracts/bridge/libraries/BridgeInitializationHelper.sol

16   library BridgeInitializationHelper {
17       /// @dev The L2 gas limit for requesting L1 -> L2 transaction of deploying L2 bridge instance.
18       /// @dev It is big enough to deploy any contract, so we can use the same value for all bridges.
19:      /// NOTE: this constant will be accurately calculated in the future.

GitHub: 16

File: cache/solpp-generated-contracts/common/AllowList.sol

20:  contract AllowList is IAllowList, Ownable2Step {

GitHub: 20

File: cache/solpp-generated-contracts/common/AllowListed.sol

11:  abstract contract AllowListed {

GitHub: 11

File: cache/solpp-generated-contracts/common/ReentrancyGuard.sol

27   abstract contract ReentrancyGuard {
28       /// @dev Address of lock flag variable.
29       /// @dev Flag is placed at random memory location to not interfere with Storage contract.
30:      // keccak256("ReentrancyGuard") - 1;

GitHub: 27

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

7    interface IAllowList {
8        /*//////////////////////////////////////////////////////////////
9                                EVENTS
10       //////////////////////////////////////////////////////////////*/
11   
12:      /// @notice Access mode of target contract is changed

GitHub: 7

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

11   interface IL2ContractDeployer {
12       /// @notice A struct that describes a forced deployment on an address.
13       /// @param bytecodeHash The bytecode hash to put on an address.
14       /// @param newAddress The address on which to deploy the bytecodehash to.
15       /// @param callConstructor Whether to run the constructor on the force deployment.
16       /// @param value The `msg.value` with which to initialize a contract.
17:      /// @param input The constructor calldata.

GitHub: 11

File: cache/solpp-generated-contracts/common/libraries/L2ContractHelper.sol

12   library L2ContractHelper {
13:      /// @dev The prefix used to create CREATE2 addresses.

GitHub: 12

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

12:  library UncheckedMath {

GitHub: 12

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

20:  library UnsafeBytes {

GitHub: 20

File: cache/solpp-generated-contracts/governance/Governance.sol

22   contract Governance is IGovernance, Ownable2Step {
23:      /// @notice A constant representing the timestamp for completed operations.

GitHub: 22

File: cache/solpp-generated-contracts/governance/IGovernance.sol

7    interface IGovernance {
8        /// @dev This enumeration includes the following states:
9        /// @param Unset Default state, indicating the operation has not been set.
10       /// @param Waiting The operation is scheduled but not yet ready to be executed.
11       /// @param Ready The operation is ready to be executed.
12:      /// @param Done The operation has been successfully executed.

GitHub: 7

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

17   abstract contract BaseZkSyncUpgrade is Base {
18       /// @notice The struct that represents the upgrade proposal.
19       /// @param l2ProtocolUpgradeTx The system upgrade transaction.
20       /// @param factoryDeps The list of factory deps for the l2ProtocolUpgradeTx.
21       /// @param bootloaderHash The hash of the new bootloader bytecode. If zero, it will not be updated.
22       /// @param defaultAccountHash The hash of the new default account bytecode. If zero, it will not be updated.
23       /// @param verifier The address of the new verifier. If zero, the verifier will not be updated.
24       /// @param verifierParams The new verifier params. If either of its fields is 0, the params will not be updated.
25       /// @param l1ContractsUpgradeCalldata Custom calldata for L1 contracts upgrade, it may be interpreted differently
26       /// in each upgrade. Usually empty.
27       /// @param postUpgradeCalldata Custom calldata for post upgrade hook, it may be interpreted differently in each
28       /// upgrade. Usually empty.
29       /// @param upgradeTimestamp The timestamp after which the upgrade can be executed.
30       /// @param newProtocolVersion The new version number for the protocol after this upgrade. Should be greater than
31       /// the previous protocol version.
32:      /// @param newAllowList The address of the new allowlist contract. If zero, it will not be updated.

GitHub: 17

File: cache/solpp-generated-contracts/upgrades/DefaultUpgrade.sol

12   contract DefaultUpgrade is BaseZkSyncUpgrade {
13       /// @notice Placeholder function for custom logic for upgrading L1 contract.
14       /// Typically this function will never be used.
15       /// @param _customCallDataForUpgrade Custom data for an upgrade, which may be interpreted differently for each
16:      /// upgrade.

GitHub: 12

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

23:  library AddressAliasHelper {

GitHub: 23

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

21   contract DiamondInit is Base {
22       /// @notice Struct that holds all data needed for initializing zkSync Diamond Proxy.
23       /// @dev We use struct instead of raw parameters in `initialize` function to prevent "Stack too deep" error
24       /// @param _verifier address of Verifier contract
25       /// @param _governor address who can manage critical updates in the contract
26       /// @param _admin address who can manage non-critical updates in the contract
27       /// @param _genesisBatchHash Batch hash of the genesis (initial) batch
28       /// @param _genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for genesis batch
29       /// @param _genesisBatchCommitment The zk-proof commitment for the genesis batch
30       /// @param _allowList The address of the allow list smart contract
31       /// @param _verifierParams Verifier config parameters that describes the circuit to be verified
32       /// @param _zkPorterIsAvailable The availability of zk porter shard
33       /// @param _l2BootloaderBytecodeHash The hash of bootloader L2 bytecode
34       /// @param _l2DefaultAccountBytecodeHash The hash of default account L2 bytecode
35:      /// @param _priorityTxMaxGasLimit maximum number of the L2 gas that a user can request for L1 -> L2 transactions

GitHub: 21

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

22:  contract ValidatorTimelock is IExecutor, Ownable2Step {

GitHub: 22

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

6:   interface IBase {

GitHub: 6

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

30   interface IExecutor is IBase {
31       /// @notice Rollup batch stored data
32       /// @param batchNumber Rollup batch number
33       /// @param batchHash Hash of L2 batch
34       /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
35       /// @param numberOfLayer1Txs Number of priority operations to be processed
36       /// @param priorityOperationsHash Hash of all priority operations from this batch
37       /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch
38       /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant
39:      /// @param commitment Verified input for the zkSync circuit

GitHub: 30

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

11   interface IGetters is IBase {
12       /*//////////////////////////////////////////////////////////////
13                               CUSTOM GETTERS
14       //////////////////////////////////////////////////////////////*/
15:  

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/ILegacyGetters.sol

13:  interface ILegacyGetters is IBase {

GitHub: 13

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

18   interface IMailbox is IBase {
19       /// @dev Structure that includes all fields of the L2 transaction
20       /// @dev The hash of this structure is the "canonical L2 transaction hash" and can be used as a unique identifier of a tx
21       /// @param txType The tx type number, depending on which the L2 transaction can be interpreted differently
22       /// @param from The sender's address. `uint256` type for possible address format changes and maintaining backward compatibility
23       /// @param to The recipient's address. `uint256` type for possible address format changes and maintaining backward compatibility
24       /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an L1 transactions
25       /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata (every piece of data that will be stored on L1 as calldata)
26       /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get the transaction included in a batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
27       /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator to incentivize them to include the transaction in a batch. Analog to the EIP-1559 `maxPriorityFeePerGas` on an L1 transactions
28       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility
29       /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority operation Id.
30       /// @param value The value to pass with the transaction
31       /// @param reserved The fixed-length fields for usage in a future extension of transaction formats
32       /// @param data The calldata that is transmitted for the transaction call
33       /// @param signature An abstract set of bytes that are used for transaction authorization
34       /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
35       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
36:      /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

13:  library Diamond {

GitHub: 13

File: cache/solpp-generated-contracts/zksync/libraries/LibMap.sol

8    library LibMap {
9:       /// @dev A uint32 map in storage.

GitHub: 8

File: cache/solpp-generated-contracts/zksync/libraries/Merkle.sol

11:  library Merkle {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/libraries/PriorityQueue.sol

22:  library PriorityQueue {

GitHub: 22

File: cache-zk/solpp-generated-contracts/bridge/L2ERC20Bridge.sol

22   contract L2ERC20Bridge is IL2Bridge, Initializable {
23:      /// @dev The address of the L1 bridge counterpart.

GitHub: 22

File: cache-zk/solpp-generated-contracts/bridge/L2StandardERC20.sol

13   contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken {
14       /// @dev Describes whether there is a specific getter in the token.
15       /// @notice Used to explicitly separate which getters the token has and which it does not.
16       /// @notice Different tokens in L1 can implement or not implement getter function as `name`/`symbol`/`decimals`,
17:      /// @notice Our goal is to store all the getters that L1 token implements, and for others, we keep it as an unimplemented method.

GitHub: 13

File: cache-zk/solpp-generated-contracts/bridge/L2Weth.sol

23   contract L2Weth is ERC20PermitUpgradeable, IL2Weth, IL2StandardToken {
24:      /// @dev Address of the L2 WETH Bridge.

GitHub: 23

File: cache-zk/solpp-generated-contracts/bridge/L2WethBridge.sol

23   contract L2WethBridge is IL2Bridge, Initializable {
24:      /// @dev Event emitted when ETH is received by the contract.

GitHub: 23

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

8:   interface IL1Bridge {

GitHub: 8

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

8:   interface IL2Bridge {

GitHub: 8

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

6:   interface IL2Weth {

GitHub: 6

File: cache-zk/solpp-generated-contracts/AccountCodeStorage.sol

24:  contract AccountCodeStorage is IAccountCodeStorage {

GitHub: 24

File: cache-zk/solpp-generated-contracts/BootloaderUtilities.sol

18:  contract BootloaderUtilities is IBootloaderUtilities {

GitHub: 18

File: cache-zk/solpp-generated-contracts/ComplexUpgrader.sol

16   contract ComplexUpgrader is IComplexUpgrader {
17       /// @notice Executes an upgrade process by delegating calls to another contract.
18       /// @dev This function allows only the `FORCE_DEPLOYER` to initiate the upgrade.
19       /// If the delegate call fails, the function will revert the transaction, returning the error message
20       /// provided by the delegated contract.
21       /// @param _delegateTo the address of the contract to which the calls will be delegated
22:      /// @param _calldata the calldata to be delegate called in the `_delegateTo` contract

GitHub: 16

File: cache-zk/solpp-generated-contracts/Compressor.sol

36:  contract Compressor is ICompressor, ISystemContract {

GitHub: 36

File: cache-zk/solpp-generated-contracts/ContractDeployer.sol

25   contract ContractDeployer is IContractDeployer, ISystemContract {
26       /// @notice Information about an account contract.
27:      /// @dev For EOA and simple contracts (i.e. not accounts) this value is 0.

GitHub: 25

File: cache-zk/solpp-generated-contracts/DefaultAccount.sol

21:  contract DefaultAccount is IAccount {

GitHub: 21

File: cache-zk/solpp-generated-contracts/EmptyContract.sol

13:  contract EmptyContract {

GitHub: 13

File: cache-zk/solpp-generated-contracts/ImmutableSimulator.sol

20   contract ImmutableSimulator is IImmutableSimulator {
21       /// @dev mapping (contract address) => (index of immutable variable) => value
22:      /// @notice that address uses `uint256` type to leave the option to introduce 32-byte address space in future.

GitHub: 20

File: cache-zk/solpp-generated-contracts/KnownCodesStorage.sol

21:  contract KnownCodesStorage is IKnownCodesStorage, ISystemContract {

GitHub: 21

File: cache-zk/solpp-generated-contracts/L1Messenger.sol

35   contract L1Messenger is IL1Messenger, ISystemContract {
36       /// @notice Sequential hash of logs sent in the current block.
37:      /// @dev Will be reset at the end of the block to zero value.

GitHub: 35

File: cache-zk/solpp-generated-contracts/L2EthToken.sol

20   contract L2EthToken is IEthToken, ISystemContract {
21:      /// @notice The balances of the users.

GitHub: 20

File: cache-zk/solpp-generated-contracts/MsgValueSimulator.sol

21   contract MsgValueSimulator is ISystemContract {
22       /// @notice Extract value, isSystemCall and to from the extraAbi params.
23       /// @dev The contract accepts value, the callee and whether the call should a system one via its ABI params.
24       /// @dev The first ABI param contains the value in the [0..127] bits. The 128th contains
25       /// the flag whether or not the call should be a system one.
26:      /// The second ABI params contains the callee.

GitHub: 21

File: cache-zk/solpp-generated-contracts/NonceHolder.sol

29:  contract NonceHolder is INonceHolder, ISystemContract {

GitHub: 29

File: cache-zk/solpp-generated-contracts/SystemContext.sol

19   contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContract {
20       /// @notice The number of latest L2 blocks to store.
21       /// @dev EVM requires us to be able to query the hashes of previous 256 blocks.
22       /// We could either:
23       /// - Store the latest 256 hashes (and strictly rely that we do not accidentally override the hash of the block 256 blocks ago)
24:      /// - Store the latest 257 blocks's hashes.

GitHub: 19

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

7:   interface IAccountCodeStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

9:   interface IBootloaderUtilities {

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

7:   interface IComplexUpgrader {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

14:  interface ICompressor {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

7    interface IContractDeployer {
8        /// @notice Defines the version of the account abstraction protocol
9        /// that a contract claims to follow.
10       /// - `None` means that the account is just a contract and it should never be interacted
11       /// with as a custom account
12:      /// - `Version1` means that the account follows the first version of the account abstraction protocol

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

7:   interface IEthToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

12:  interface IImmutableSimulator {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

7:   interface IKnownCodesStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

37   interface IL1Messenger {
38       // Possibly in the future we will be able to track the messages sent to L1 with
39:      // some hooks in the VM. For now, it is much easier to track them with L2 events.

GitHub: 37

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

7:   interface IMailbox {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/INonceHolder.sol

15:  interface INonceHolder {

GitHub: 15

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

File: cache-zk/solpp-generated-contracts/interfaces/IPaymasterFlow.sol

14:  interface IPaymasterFlow {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContext.sol

12:  interface ISystemContext {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContextDeprecated.sol

11:  interface ISystemContextDeprecated {

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/ISystemContract.sol

14   abstract contract ISystemContract {
15       /// @notice Modifier that makes sure that the method
16:      /// can only be called via a system call.

GitHub: 14

File: cache-zk/solpp-generated-contracts/libraries/EfficientCall.sol

34   library EfficientCall {
35       /// @notice Call the `keccak256` without copying calldata to memory.
36       /// @param _data The preimage data.
37:      /// @return The `keccak256` hash.

GitHub: 34

File: cache-zk/solpp-generated-contracts/libraries/RLPEncoder.sol

12:  library RLPEncoder {

GitHub: 12

File: cache-zk/solpp-generated-contracts/libraries/SystemContractHelper.sol

70   library SystemContractHelper {
71       /// @notice Send an L2Log to L1.
72       /// @param _isService The `isService` flag.
73       /// @param _key The `key` part of the L2Log.
74       /// @param _value The `value` part of the L2Log.
75       /// @dev The meaning of all these parameters is context-dependent, but they
76:      /// have no intrinsic meaning per se.

GitHub: 70

File: cache-zk/solpp-generated-contracts/libraries/SystemContractsCaller.sol

70   library SystemContractsCaller {
71       /// @notice Makes a call with the `isSystem` flag.
72       /// @param gasLimit The gas limit for the call.
73       /// @param to The address to call.
74       /// @param value The value to pass with the transaction.
75       /// @param data The calldata.
76       /// @return success Whether the transaction has been successful.
77:      /// @dev Note, that the `isSystem` flag can only be set when calling system contracts.

GitHub: 70

File: cache-zk/solpp-generated-contracts/libraries/TransactionHelper.sol

80:  library TransactionHelper {

GitHub: 80

File: cache-zk/solpp-generated-contracts/libraries/UnsafeBytesCalldata.sol

20:  library UnsafeBytesCalldata {

GitHub: 20

File: cache-zk/solpp-generated-contracts/libraries/Utils.sol

13   library Utils {
14:      /// @dev Bit mask of bytecode hash "isConstructor" marker

GitHub: 13

File: cache-zk/solpp-generated-contracts/openzeppelin/utils/Address.sol

11   library Address {
12       /**
13        * @dev Returns true if `account` is a contract.
14        *
15        * [IMPORTANT]
16        * ====
17        * It is unsafe to assume that an address for which this function returns
18        * false is an externally-owned account (EOA) and not a contract.
19        *
20        * Among others, `isContract` will return false for the following
21        * types of addresses:
22        *
23        *  - an externally-owned account
24        *  - a contract in construction
25        *  - an address where a contract will be created
26        *  - an address where a contract lived, but was destroyed
27        * ====
28        *
29        * [IMPORTANT]
30        * ====
31        * You shouldn't rely on `isContract` to protect against flash loan attacks!
32        *
33        * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
34        * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
35        * constructor.
36        * ====
37:       */

GitHub: 11

[N‑66] NatSpec: Contract declarations should have descriptions

e.g. @dev or @notice, and it must appear above the contract definition braces in order to be identified by the compiler as NatSpec

There are 26 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

7:   interface IL2WethBridge {

GitHub: 7

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

6:   interface IWETH9 {

GitHub: 6

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

7    interface IAllowList {
8        /*//////////////////////////////////////////////////////////////
9                                EVENTS
10       //////////////////////////////////////////////////////////////*/
11   
12:      /// @notice Access mode of target contract is changed

GitHub: 7

File: cache/solpp-generated-contracts/governance/IGovernance.sol

7    interface IGovernance {
8        /// @dev This enumeration includes the following states:
9        /// @param Unset Default state, indicating the operation has not been set.
10       /// @param Waiting The operation is scheduled but not yet ready to be executed.
11       /// @param Ready The operation is ready to be executed.
12:      /// @param Done The operation has been successfully executed.

GitHub: 7

File: cache/solpp-generated-contracts/vendor/AddressAliasHelper.sol

23:  library AddressAliasHelper {

GitHub: 23

File: cache/solpp-generated-contracts/zksync/interfaces/IAdmin.sol

11:  interface IAdmin is IBase {

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

6:   interface IBase {

GitHub: 6

File: cache/solpp-generated-contracts/zksync/interfaces/IExecutor.sol

30   interface IExecutor is IBase {
31       /// @notice Rollup batch stored data
32       /// @param batchNumber Rollup batch number
33       /// @param batchHash Hash of L2 batch
34       /// @param indexRepeatedStorageChanges The serial number of the shortcut index that's used as a unique identifier for storage keys that were used twice or more
35       /// @param numberOfLayer1Txs Number of priority operations to be processed
36       /// @param priorityOperationsHash Hash of all priority operations from this batch
37       /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch
38       /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant
39:      /// @param commitment Verified input for the zkSync circuit

GitHub: 30

File: cache/solpp-generated-contracts/zksync/interfaces/IGetters.sol

11   interface IGetters is IBase {
12       /*//////////////////////////////////////////////////////////////
13                               CUSTOM GETTERS
14       //////////////////////////////////////////////////////////////*/
15:  

GitHub: 11

File: cache/solpp-generated-contracts/zksync/interfaces/IMailbox.sol

18   interface IMailbox is IBase {
19       /// @dev Structure that includes all fields of the L2 transaction
20       /// @dev The hash of this structure is the "canonical L2 transaction hash" and can be used as a unique identifier of a tx
21       /// @param txType The tx type number, depending on which the L2 transaction can be interpreted differently
22       /// @param from The sender's address. `uint256` type for possible address format changes and maintaining backward compatibility
23       /// @param to The recipient's address. `uint256` type for possible address format changes and maintaining backward compatibility
24       /// @param gasLimit The L2 gas limit for L2 transaction. Analog to the `gasLimit` on an L1 transactions
25       /// @param gasPerPubdataByteLimit Maximum number of L2 gas that will cost one byte of pubdata (every piece of data that will be stored on L1 as calldata)
26       /// @param maxFeePerGas The absolute maximum sender willing to pay per unit of L2 gas to get the transaction included in a batch. Analog to the EIP-1559 `maxFeePerGas` on an L1 transactions
27       /// @param maxPriorityFeePerGas The additional fee that is paid directly to the validator to incentivize them to include the transaction in a batch. Analog to the EIP-1559 `maxPriorityFeePerGas` on an L1 transactions
28       /// @param paymaster The address of the EIP-4337 paymaster, that will pay fees for the transaction. `uint256` type for possible address format changes and maintaining backward compatibility
29       /// @param nonce The nonce of the transaction. For L1->L2 transactions it is the priority operation Id.
30       /// @param value The value to pass with the transaction
31       /// @param reserved The fixed-length fields for usage in a future extension of transaction formats
32       /// @param data The calldata that is transmitted for the transaction call
33       /// @param signature An abstract set of bytes that are used for transaction authorization
34       /// @param factoryDeps The set of L2 bytecode hashes whose preimages were shown on L1
35       /// @param paymasterInput The arbitrary-length data that is used as a calldata to the paymaster pre-call
36:      /// @param reservedDynamic The arbitrary-length field for usage in a future extension of transaction formats

GitHub: 18

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

12:  interface IZkSync is IMailbox, IAdmin, IExecutor, IGetters {}

GitHub: 12

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

6:   interface IL2Weth {

GitHub: 6

File: cache-zk/solpp-generated-contracts/interfaces/IAccount.sol

11   interface IAccount {
12       /// @notice Called by the bootloader to validate that an account agrees to process the transaction
13       /// (and potentially pay for it).
14       /// @param _txHash The hash of the transaction to be used in the explorer
15       /// @param _suggestedSignedHash The hash of the transaction is signed by EOAs
16       /// @param _transaction The transaction itself
17       /// @return magic The magic value that should be equal to the signature of this function
18       /// if the user agrees to proceed with the transaction.
19       /// @dev The developer should strive to preserve as many steps as possible both for valid
20       /// and invalid transactions as this very method is also used during the gas fee estimation
21:      /// (without some of the necessary data, e.g. signature).

GitHub: 11

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

7:   interface IAccountCodeStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

9:   interface IBootloaderUtilities {

GitHub: 9

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

7:   interface IComplexUpgrader {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

14:  interface ICompressor {

GitHub: 14

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

7    interface IContractDeployer {
8        /// @notice Defines the version of the account abstraction protocol
9        /// that a contract claims to follow.
10       /// - `None` means that the account is just a contract and it should never be interacted
11       /// with as a custom account
12:      /// - `Version1` means that the account follows the first version of the account abstraction protocol

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

7:   interface IEthToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

12:  interface IImmutableSimulator {

GitHub: 12

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

7:   interface IKnownCodesStorage {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

37   interface IL1Messenger {
38       // Possibly in the future we will be able to track the messages sent to L1 with
39:      // some hooks in the VM. For now, it is much easier to track them with L2 events.

GitHub: 37

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

7:   interface IL2StandardToken {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

7:   interface IMailbox {

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IPaymaster.sol

16   interface IPaymaster {
17       /// @dev Called by the bootloader to verify that the paymaster agrees to pay for the
18       /// fee for the transaction. This transaction should also send the necessary amount of funds onto the bootloader
19       /// address.
20       /// @param _txHash The hash of the transaction
21       /// @param _suggestedSignedHash The hash of the transaction that is signed by an EOA
22       /// @param _transaction The transaction itself.
23       /// @return magic The value that should be equal to the signature of the validateAndPayForPaymasterTransaction
24       /// if the paymaster agrees to pay for the transaction.
25       /// @return context The "context" of the transaction: an array of bytes of length at most 1024 bytes, which will be
26       /// passed to the `postTransaction` method of the account.
27       /// @dev The developer should strive to preserve as many steps as possible both for valid
28       /// and invalid transactions as this very method is also used during the gas fee estimation
29:      /// (without some of the necessary data, e.g. signature).

GitHub: 16

[N‑67] NatSpec: Event declarations should have descriptions

There are 24 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

9        event DepositInitiated(
10           bytes32 indexed l2DepositTxHash,
11           address indexed from,
12           address indexed to,
13           address l1Token,
14           uint256 amount
15:      );

17:      event WithdrawalFinalized(address indexed to, address indexed l1Token, uint256 amount);

19:      event ClaimedFailedDeposit(address indexed to, address indexed l1Token, uint256 amount);

GitHub: 9, 17, 19

File: cache/solpp-generated-contracts/zksync/libraries/Diamond.sol

25:      event DiamondCut(FacetCut[] facetCuts, address initAddress, bytes initCalldata);

GitHub: 25

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

9        event FinalizeDeposit(
10           address indexed l1Sender,
11           address indexed l2Receiver,
12           address indexed l2Token,
13           uint256 amount
14:      );

16       event WithdrawalInitiated(
17           address indexed l2Sender,
18           address indexed l1Receiver,
19           address indexed l2Token,
20           uint256 amount
21:      );

GitHub: 9, 16

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

8:       event BridgeInitialize(address indexed l1Token, string name, string symbol, uint8 decimals);

10:      event BridgeMint(address indexed _account, uint256 _amount);

12:      event BridgeBurn(address indexed _account, uint256 _amount);

GitHub: 8, 10, 12

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

7:       event Initialize(string name, string symbol, uint8 decimals);

GitHub: 7

File: cache-zk/solpp-generated-contracts/interfaces/IContractDeployer.sol

35       event ContractDeployed(
36           address indexed deployerAddress,
37           bytes32 indexed bytecodeHash,
38           address indexed contractAddress
39:      );

41:      event AccountNonceOrderingUpdated(address indexed accountAddress, AccountNonceOrdering nonceOrdering);

43:      event AccountVersionUpdated(address indexed accountAddress, AccountAbstractionVersion aaVersion);

GitHub: 35, 41, 43

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

26:      event Mint(address indexed account, uint256 amount);

28:      event Transfer(address indexed from, address indexed to, uint256 value);

30:      event Withdrawal(address indexed _l2Sender, address indexed _l1Receiver, uint256 _amount);

32       event WithdrawalWithMessage(
33           address indexed _l2Sender,
34           address indexed _l1Receiver,
35           uint256 _amount,
36           bytes _additionalData
37:      );

GitHub: 26, 28, 30, 32

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

8:       event MarkedAsKnown(bytes32 indexed bytecodeHash, bool indexed sendBytecodeToL1);

GitHub: 8

File: cache-zk/solpp-generated-contracts/interfaces/IL1Messenger.sol

40:      event L1MessageSent(address indexed _sender, bytes32 indexed _hash, bytes _message);

42:      event L2ToL1LogSent(L2ToL1Log _l2log);

44:      event BytecodeL1PublicationRequested(bytes32 _bytecodeHash);

GitHub: 40, 42, 44

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

8:       event BridgeMint(address indexed _account, uint256 _amount);

10:      event BridgeBurn(address indexed _account, uint256 _amount);

GitHub: 8, 10

File: cache-zk/solpp-generated-contracts/interfaces/INonceHolder.sol

16:      event ValueSetUnderNonce(address indexed accountAddress, uint256 indexed key, uint256 value);

GitHub: 16

[N‑68] NatSpec: File is missing NatSpec

There are 22 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

GitHub: various

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

GitHub: various

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

GitHub: various

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

GitHub: various

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

GitHub: various

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

GitHub: various

File: cache/solpp-generated-contracts/common/AllowListed.sol

GitHub: various

File: cache/solpp-generated-contracts/zksync/interfaces/IBase.sol

GitHub: various

File: cache/solpp-generated-contracts/zksync/interfaces/IZkSync.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2StandardToken.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/bridge/interfaces/IL2Weth.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IAccountCodeStorage.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IBootloaderUtilities.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IComplexUpgrader.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/ICompressor.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IEthToken.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IImmutableSimulator.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IKnownCodesStorage.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IL2StandardToken.sol

GitHub: various

File: cache-zk/solpp-generated-contracts/interfaces/IMailbox.sol

GitHub: various

[N‑69] NatSpec: Function @param tag is missing

There are 538 instances of this issue:

see instances
File: cache/solpp-generated-contracts/bridge/L1ERC20Bridge.sol

/// @audit Missing '@param _zkSync'
/// @audit Missing '@param _allowList'
65       /// @dev Contract is expected to be used as proxy implementation.
66       /// @dev Initialize the implementation to prevent Parity hack.
67:      constructor(IZkSync _zkSync, IAllowList _allowList) reentrancyGuardInitializer {

/// @audit Missing '@param _from'
/// @audit Missing '@param _token'
/// @audit Missing '@param _amount'
216      /// @dev Transfers tokens from the depositor address to the smart contract address
217      /// @return The difference between the contract balance before and after the transferring of funds
218:     function _depositFunds(address _from, IERC20 _token, uint256 _amount) internal returns (uint256) {

/// @audit Missing '@param _l1Sender'
226      /// @dev Generate a calldata for calling the deposit finalization on the L2 bridge contract
227      function _getDepositL2Calldata(
228:         address _l1Sender,

/// @audit Missing '@param _l2Receiver'
226      /// @dev Generate a calldata for calling the deposit finalization on the L2 bridge contract
227      function _getDepositL2Calldata(
228          address _l1Sender,
229:         address _l2Receiver,

/// @audit Missing '@param _l1Token'
226      /// @dev Generate a calldata for calling the deposit finalization on the L2 bridge contract
227      function _getDepositL2Calldata(
228          address _l1Sender,
229          address _l2Receiver,
230:         address _l1Token,

/// @audit Missing '@param _amount'
226      /// @dev Generate a calldata for calling the deposit finalization on the L2 bridge contract
227      function _getDepositL2Calldata(
228          address _l1Sender,
229          address _l2Receiver,
230          address _l1Token,
231:         uint256 _amount

/// @audit Missing '@param _token'
241      /// @dev Receives and parses (name, symbol, decimals) from the token contract
242:     function _getERC20Getters(address _token) internal view returns (bytes memory data) {

/// @audit Missing '@param _l2ToL1message'
324      /// @dev Decode the withdraw message that came from L2
325      function _parseL2WithdrawalMessage(
326:         bytes memory _l2ToL1message

/// @audit Missing '@param _l1Token'
/// @audit Missing '@param _depositor'
/// @audit Missing '@param _amount'
/// @audit Missing '@param _claiming'
341      /// @dev Verify the deposit limit is reached to its cap or not
342:     function _verifyDepositLimit(address _l1Token, address _depositor, uint256 _amount, bool _claiming) internal {

/// @audit Missing '@param _l1Token'
354      /// @return The L2 token address that would be minted for deposit of the given L1 token
355:     function l2TokenAddress(address _l1Token) public view returns (address) {

GitHub: 65, 65, 216, 216, 216, 226, 226, 226, 226, 241, 324, 341, 341, 341, 341, 354

File: cache/solpp-generated-contracts/bridge/L1WethBridge.sol

/// @audit Missing '@param _l1WethAddress'
/// @audit Missing '@param _zkSync'
/// @audit Missing '@param _allowList'
64       /// @dev Contract is expected to be used as proxy implementation.
65       /// @dev Initialize the implementation to prevent Parity hack.
66:      constructor(address payable _l1WethAddress, IZkSync _zkSync, IAllowList _allowList) reentrancyGuardInitializer {

/// @audit Missing '@param _l1Sender'
200      /// @dev Generate a calldata for calling the deposit finalization on the L2 WETH bridge contract
201      function _getDepositL2Calldata(
202:         address _l1Sender,

/// @audit Missing '@param _l2Receiver'
200      /// @dev Generate a calldata for calling the deposit finalization on the L2 WETH bridge contract
201      function _getDepositL2Calldata(
202          address _l1Sender,
203:         address _l2Receiver,

/// @audit Missing '@param _l1Token'
200      /// @dev Generate a calldata for calling the deposit finalization on the L2 WETH bridge contract
201      function _getDepositL2Calldata(
202          address _l1Sender,
203          address _l2Receiver,
204:         address _l1Token,

/// @audit Missing '@param _amount'
200      /// @dev Generate a calldata for calling the deposit finalization on the L2 WETH bridge contract
201      function _getDepositL2Calldata(
202          address _l1Sender,
203          address _l2Receiver,
204          address _l1Token,
205:         uint256 _amount

/// @audit Missing '@param _message'
272      /// @dev Decode the ETH withdraw message with additional data about WETH withdrawal that came from L2EthToken
273      /// contract
274      function _parseL2EthWithdrawalMessage(
275:         bytes memory _message

/// @audit Missing '@param _l1Token'
303      /// @return l2Token Address of an L2 token counterpart.
304:     function l2TokenAddress(address _l1Token) public view override returns (address l2Token) {

GitHub: 64, 64, 64, 200, 200, 200, 200, 272, 303

File: cache/solpp-generated-contracts/bridge/interfaces/IL1Bridge.sol

/// @audit Missing '@param _l2BatchNumber'
/// @audit Missing '@param _l2MessageIndex'
21:      function isWithdrawalFinalized(uint256 _l2BatchNumber, uint256 _l2MessageIndex) external view returns (bool);

/// @audit Missing '@param _l2Receiver'
23       function deposit(
24:          address _l2Receiver,

/// @audit Missing '@param _l1Token'
23       function deposit(
24           address _l2Receiver,
25:          address _l1Token,

/// @audit Missing '@param _amount'
23       function deposit(
24           address _l2Receiver,
25           address _l1Token,
26:          uint256 _amount,

/// @audit Missing '@param _l2TxGasLimit'
23       function deposit(
24           address _l2Receiver,
25           address _l1Token,
26           uint256 _amount,
27:          uint256 _l2TxGasLimit,

/// @audit Missing '@param _l2TxGasPerPubdataByte'
23       function deposit(
24           address _l2Receiver,
25           address _l1Token,
26           uint256 _amount,
27           uint256 _l2TxGasLimit,
28:          uint256 _l2TxGasPerPubdataByte,

/// @audit Missing '@param _refundRecipient'
23       function deposit(
24           address _l2Receiver,
25           address _l1Token,
26           uint256 _amount,
27           uint256 _l2TxGasLimit,
28           uint256 _l2TxGasPerPubdataByte,
29:          address _refundRecipient

/// @audit Missing '@param _depositSender'
32       function claimFailedDeposit(
33:          address _depositSender,

/// @audit Missing '@param _l1Token'
32       function claimFailedDeposit(
33           address _depositSender,
34:          address _l1Token,

/// @audit Missing '@param _l2TxHash'
32       function claimFailedDeposit(
33           address _depositSender,
34           address _l1Token,
35:          bytes32 _l2TxHash,

/// @audit Missing '@param _l2BatchNumber'
32       function claimFailedDeposit(
33           address _depositSender,
34           address _l1Token,
35           bytes32 _l2TxHash,
36:          uint256 _l2BatchNumber,

/// @audit Missing '@param _l2MessageIndex'
32       function claimFailedDeposit(
33           address _depositSender,
34           address _l1Token,
35           bytes32 _l2TxHash,
36           uint256 _l2BatchNumber,
37:          uint256 _l2MessageIndex,

/// @audit Missing '@param _l2TxNumberInBatch'
32       function claimFailedDeposit(
33           address _depositSender,
34           address _l1Token,
35           bytes32 _l2TxHash,
36           uint256 _l2BatchNumber,
37           uint256 _l2MessageIndex,
38:          uint16 _l2TxNumberInBatch,

/// @audit Missing '@param _merkleProof'
32       function claimFailedDeposit(
33           address _depositSender,
34           address _l1Token,
35           bytes32 _l2TxHash,
36           uint256 _l2BatchNumber,
37           uint256 _l2MessageIndex,
38           uint16 _l2TxNumberInBatch,
39:          bytes32[] calldata _merkleProof

/// @audit Missing '@param _l2BatchNumber'
42       function finalizeWithdrawal(
43:          uint256 _l2BatchNumber,

/// @audit Missing '@param _l2MessageIndex'
42       function finalizeWithdrawal(
43           uint256 _l2BatchNumber,
44:          uint256 _l2MessageIndex,

/// @audit Missing '@param _l2TxNumberInBatch'
42       function finalizeWithdrawal(
43           uint256 _l2BatchNumber,
44           uint256 _l2MessageIndex,
45:          uint16 _l2TxNumberInBatch,

/// @audit Missing '@param _message'
42       function finalizeWithdrawal(
43           uint256 _l2BatchNumber,
44           uint256 _l2MessageIndex,
45           uint16 _l2TxNumberInBatch,
46:          bytes calldata _message,

/// @audit Missing '@param _merkleProof'
42       function finalizeWithdrawal(
43           uint256 _l2BatchNumber,
44           uint256 _l2MessageIndex,
45           uint16 _l2TxNumberInBatch,
46           bytes calldata _message,
47:          bytes32[] calldata _merkleProof

/// @audit Missing '@param _l1Token'
50:      function l2TokenAddress(address _l1Token) external view returns (address);

GitHub: 21, 21, 23, 23, 23, 23, 23, 23, 32, 32, 32, 32, 32, 32, 32, 42, 42, 42, 42, 42, 50

File: cache/solpp-generated-contracts/bridge/interfaces/IL1BridgeLegacy.sol

/// @audit Missing '@param _l2Receiver'
9        function deposit(
10:          address _l2Receiver,

/// @audit Missing '@param _l1Token'
9        function deposit(
10           address _l2Receiver,
11:          address _l1Token,

/// @audit Missing '@param _amount'
9        function deposit(
10           address _l2Receiver,
11           address _l1Token,
12:          uint256 _amount,

/// @audit Missing '@param _l2TxGasLimit'
9        function deposit(
10           address _l2Receiver,
11           address _l1Token,
12           uint256 _amount,
13:          uint256 _l2TxGasLimit,

/// @audit Missing '@param _l2TxGasPerPubdataByte'
9        function deposit(
10           address _l2Receiver,
11           address _l1Token,
12           uint256 _amount,
13           uint256 _l2TxGasLimit,
14:          uint256 _l2TxGasPerPubdataByte

GitHub: 9, 9, 9, 9, 9

File: cache/solpp-generated-contracts/bridge/interfaces/IL2Bridge.sol

/// @audit Missing '@param _l1Sender'
9        function finalizeDeposit(
10:          address _l1Sender,

/// @audit Missing '@param _l2Receiver'
9        function finalizeDeposit(
10           address _l1Sender,
11:          address _l2Receiver,

/// @audit Missing '@param _l1Token'
9        function finalizeDeposit(
10           address _l1Sender,
11           address _l2Receiver,
12:          address _l1Token,

/// @audit Missing '@param _amount'
9        function finalizeDeposit(
10           address _l1Sender,
11           address _l2Receiver,
12           address _l1Token,
13:          uint256 _amount,

/// @audit Missing '@param _data'
9        function finalizeDeposit(
10           address _l1Sender,
11           address _l2Receiver,
12           address _l1Token,
13           uint256 _amount,
14:          bytes calldata _data

/// @audit Missing '@param _l1Receiver'
17       function withdraw(
18:          address _l1Receiver,

/// @audit Missing '@param _l2Token'
17       function withdraw(
18           address _l1Receiver,
19:          address _l2Token,

/// @audit Missing '@param _amount'
17       function withdraw(
18           address _l1Receiver,
19           address _l2Token,
20:          uint256 _amount

/// @audit Missing '@param _l2Token'
23:      function l1TokenAddress(address _l2Token) external view returns (address);

/// @audit Missing '@param _l1Token'
25:      function l2TokenAddress(address _l1Token) external view returns (address);

GitHub: 9, 9, 9, 9, 9, 17, 17, 17, 23, 25

File: cache/solpp-generated-contracts/bridge/interfaces/IL2ERC20Bridge.sol

/// @audit Missing '@param _l1Bridge'
9        function initialize(
10:          address _l1Bridge,

/// @audit Missing '@param _l2TokenProxyBytecodeHash'
9        function initialize(
10           address _l1Bridge,
11:          bytes32 _l2TokenProxyBytecodeHash,

/// @audit Missing '@param _governor'
9        function initialize(
10           address _l1Bridge,
11           bytes32 _l2TokenProxyBytecodeHash,
12:          address _governor

GitHub: 9, 9, 9

File: cache/solpp-generated-contracts/bridge/interfaces/IL2WethBridge.sol

/// @audit Missing '@param _l1Bridge'
8        function initialize(
9:           address _l1Bridge,

/// @audit Missing '@param _l1WethAddress'
8        function initialize(
9            address _l1Bridge,
10:          address _l1WethAddress,

/// @audit Missing '@param _l2WethAddress'
8        function initialize(
9            address _l1Bridge,
10           address _l1WethAddress,
11:          address _l2WethAddress

GitHub: 8, 8, 8

File: cache/solpp-generated-contracts/bridge/interfaces/IWETH9.sol

/// @audit Missing '@param wad'
9:       function withdraw(uint256 wad) external;

GitHub: 9

File: cache/solpp-generated-contracts/common/AllowList.sol

/// @audit Missing '@param _initialOwner'
33:      constructor(address _initialOwner) {

/// @audit Missing '@param _target'
/// @audit Missing '@param _accessMode'
69       /// @dev Changes access mode and emit the event if the access was changed
70:      function _setAccessMode(address _target, AccessMode _accessMode) internal {

/// @audit Missing '@param _caller'
/// @audit Missing '@param _target'
/// @audit Missing '@param _functionSig'
/// @audit Missing '@param _enable'
117      /// @dev Changes permission to call and emits the event if the permission was changed
118:     function _setPermissionToCall(address _caller, address _target, bytes4 _functionSig, bool _enable) internal {

GitHub: 33, 69, 69, 117, 117, 117, 117

File: cache/solpp-generated-contracts/common/interfaces/IAllowList.sol

/// @audit Missing '@param _target'
40:      function getAccessMode(address _target) external view returns (AccessMode);

/// @audit Missing '@param _caller'
42       function hasSpecialAccessToCall(
43:          address _caller,

/// @audit Missing '@param _target'
42       function hasSpecialAccessToCall(
43           address _caller,
44:          address _target,

/// @audit Missing '@param _functionSig'
42       function hasSpecialAccessToCall(
43           address _caller,
44           address _target,
45:          bytes4 _functionSig

/// @audit Missing '@param _caller'
48       function canCall(
49:          address _caller,

/// @audit Missing '@param _target'
48       function canCall(
49           address _caller,
50:          address _target,

/// @audit Missing '@param _functionSig'
48       function canCall(
49           address _caller,
50           address _target,
51:          bytes4 _functionSig

/// @audit Missing '@param _l1Token'
54:      function getTokenDepositLimitData(address _l1Token) external view returns (Deposit memory);

/// @audit Missing '@param _targets'
/// @audit Missing '@param _accessMode'
60:      function setBatchAccessMode(address[] calldata _targets, AccessMode[] calldata _accessMode) external;

/// @audit Missing '@param _target'
/// @audit Missing '@param _accessMode'
62:      function setAccessMode(address _target, AccessMode _accessMode) external;

/// @audit Missing '@param _callers'
64       function setBatchPermissionToCall(
65:          address[] calldata _callers,

/// @audit Missing '@param _targets'
64       function setBatchPermissionToCall(
65           address[] calldata _callers,
66:          address[] calldata _targets,

/// @audit Missing '@param _functionSigs'
64       function setBatchPermissionToCall(
65           address[] calldata _callers,
66           address[] calldata _targets,
67:          bytes4[] calldata _functionSigs,

/// @audit Missing '@param _enables'
64       function setBatchPermissionToCall(
65           address[] calldata _callers,
66           address[] calldata _targets,
67           bytes4[] calldata _functionSigs,
68:          bool[] calldata _enables

/// @audit Missing '@param _caller'
71       function setPermissionToCall(
72:          address _caller,

/// @audit Missing '@param _target'
71       function setPermissionToCall(
72           address _caller,
73:          address _target,

/// @audit Missing '@param _functionSig'
71       function setPermissionToCall(
72           address _caller,
73           address _target,
74:          bytes4 _functionSig,

/// @audit Missing '@param _enable'
71       function setPermissionToCall(
72           address _caller,
73           address _target,
74           bytes4 _functionSig,
75:          bool _enable

/// @audit Missing '@param _l1Token'
82       function setDepositLimit(
83:          address _l1Token,

/// @audit Missing '@param _depositLimitation'
82       function setDepositLimit(
83           address _l1Token,
84:          bool _depositLimitation,

/// @audit Missing '@param _depositCap'
82       function setDepositLimit(
83           address _l1Token,
84           bool _depositLimitation,
85:          uint256 _depositCap

GitHub: 40, 42, 42, 42, 48, 48, 48, 54, 60, 60, 62, 62, 64, 64, 64, 64, 71, 71, 71, 71, 82, 82, 82

File: cache/solpp-generated-contracts/common/interfaces/IL2ContractDeployer.sol

/// @audit Missing '@param _deployParams'
26       /// @notice This method is to be used only during an upgrade to set bytecodes on specific addresses.
27:      function forceDeployOnAddresses(ForceDeployment[] calldata _deployParams) external;

GitHub: 26

File: cache/solpp-generated-contracts/common/libraries/UncheckedMath.sol

/// @audit Missing '@param _number'
13:      function uncheckedInc(uint256 _number) internal pure returns (uint256) {

/// @audit Missing '@param _lhs'
/// @audit Missing '@param _rhs'
19:      function uncheckedAdd(uint256 _lhs, uint256 _rhs) internal pure returns (uint256) {

GitHub: 13, 19, 19

File: cache/solpp-generated-contracts/common/libraries/UnsafeBytes.sol

/// @audit Missing '@param _bytes'
/// @audit Missing '@param _start'
21:      function readUint32(bytes memory _bytes, uint256 _start) internal pure returns (uint32 result, uint256 offset) {

/// @audit Missing '@param _bytes'
/// @audit Missing '@param _start'
28:      function readAddress(bytes memory _bytes, uint256 _start) internal pure returns (address result, uint256 offset) {

/// @audit Missing '@param _bytes'
/// @audit Missing '@param _start'
35:      function readUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256 result, uint256 offset) {

/// @audit Missing '@param _bytes'
/// @audit Missing '@param _start'
42:      function readBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32 result, uint256 offset) {

GitHub: 21, 21, 28, 28, 35, 35, 42, 42

File: cache/solpp-generated-contracts/governance/Governance.sol

/// @audit Missing '@param _id'
84       /// @dev Returns whether an id corresponds to a registered operation. This
85       /// includes both Waiting, Ready, and Done operations.
86:      function isOperation(bytes32 _id) public view returns (bool) {

/// @audit Missing '@param _id'
90       /// @dev Returns whether an operation is pending or not. Note that a "pending" operation may also be "ready".
91:      function isOperationPending(bytes32 _id) public view returns (bool) {

/// @audit Missing '@param _id'
96       /// @dev Returns whether an operation is ready for execution. Note that a "ready" operation is also "pending".
97:      function isOperationReady(bytes32 _id) public view returns (bool) {

/// @audit Missing '@param _id'
101      /// @dev Returns whether an operation is done or not.
102:     function isOperationDone(bytes32 _id) public view returns (bool) {

/// @audit Missing '@param _id'
106      /// @dev Returns operation state.
107:     function getOperationState(bytes32 _id) public view returns (OperationState) {

GitHub: 84, 90, 96, 101, 106

File: cache/solpp-generated-contracts/governance/IGovernance.sol

/// @audit Missing '@param _id'
40:      function isOperation(bytes32 _id) external view returns (bool);

/// @audit Missing '@param _id'
42:      function isOperationPending(bytes32 _id) external view returns (bool);

/// @audit Missing '@param _id'
44:      function isOperationReady(bytes32 _id) external view returns (bool);

/// @audit Missing '@param _id'
46:      function isOperationDone(bytes32 _id) external view returns (bool);

/// @audit Missing '@param _id'
48:      function getOperationState(bytes32 _id) external view returns (OperationState);

/// @audit Missing '@param _operation'
/// @audit Missing '@param _delay'
50:      function scheduleTransparent(Operation calldata _operation, uint256 _delay) external;

/// @audit Missing '@param _id'
/// @audit Missing '@param _delay'
52:      function scheduleShadow(bytes32 _id, uint256 _delay) external;

/// @audit Missing '@param _id'
54:      function cancel(bytes32 _id) external;

/// @audit Missing '@param _operation'
56:      function execute(Operation calldata _operation) external;

/// @audit Missing '@param _operation'
58:      function executeInstant(Operation calldata _operation) external;

/// @audit Missing '@param _operation'
60:      function hashOperation(Operation calldata _operation) external pure returns (bytes32);

/// @audit Missing '@param _newDelay'
62:      function updateDelay(uint256 _newDelay) external;

/// @audit Missing '@param _newSecurityCouncil'
64:      function updateSecurityCouncil(address _newSecurityCouncil) external;

GitHub: 40, 42, 44, 46, 48, 50, 50, 52, 52, 54, 56, 58, 60, 62, 64

File: cache/solpp-generated-contracts/upgrades/BaseZkSyncUpgrade.sol

/// @audit Missing '@param _proposedUpgrade'
68       /// @notice The main function that will be provided by the upgrade proxy
69:      function upgrade(ProposedUpgrade calldata _proposedUpgrade) public virtual returns (bytes32) {

/// @audit Missing '@param _factoryDeps'
159      /// @notice Sets the hash of the L2 system contract upgrade transaction for the next batch to be committed
160      /// @dev If the transaction is noop (i.e. its type is 0) it does nothing and returns 0.
161      /// @param _l2ProtocolUpgradeTx The L2 system contract upgrade transaction.
162      /// @return System contracts upgrade transaction hash. Zero if no upgrade transaction is set.
163      function _setL2SystemContractUpgrade(
164          IMailbox.L2CanonicalTransaction calldata _l2ProtocolUpgradeTx,
165:         bytes[] calldata _factoryDeps,

/// @audit Missing '@param _newProtocolVersion'
159      /// @notice Sets the hash of the L2 system contract upgrade transaction for the next batch to be committed
160      /// @dev If the transaction is noop (i.e. its type is 0) it does nothing and returns 0.
161      /// @param _l2ProtocolUpgradeTx The L2 system contract upgrade transaction.
162      /// @return System contracts upgrade transaction hash. Zero if no upgrade transaction is set.
163      function _setL2SystemContractUpgrade(
164          IMailbox.L2CanonicalTransaction calldata _l2ProtocolUpgradeTx,
165          bytes[] calldata _factoryDeps,
166:         uint256 _newProtocolVersion

GitHub: 68, 159, 159

File: cache/solpp-generated-contracts/zksync/DiamondInit.sol

/// @audit Missing '@param _initalizeData'
54       /// @notice zkSync contract initialization
55       /// @return Magic 32 bytes, which indicates that the contract logic is expected to be used as a diamond proxy
56       /// initializer
57:      function initialize(InitializeData calldata _initalizeData) external reentrancyGuardInitializer returns (bytes32) {

GitHub: 54

File: cache/solpp-generated-contracts/zksync/DiamondProxy.sol

/// @audit Missing '@param _chainId'
/// @audit Missing '@param _diamondCut'
13:      constructor(uint256 _chainId, Diamond.DiamondCutData memory _diamondCut) {

GitHub: 13, 13

File: cache/solpp-generated-contracts/zksync/ValidatorTimelock.sol

/// @audit Missing '@param _initialOwner'
/// @audit Missing '@param _zkSyncContract'
/// @audit Missing '@param _executionDelay'
/// @audit Missing '@param _validator'
46:      constructor(address _initialOwner, address _zkSyncContract, uint32 _executionDelay, address _validator) {

/// @audit Missing '@param _newValidator'
53       /// @dev Set new validator address.
54:      function setValidator(address _newValidator) external onlyOwner {

/// @audit Missing '@param _executionDelay'
60       /// @dev Set the delay between committing and executing batches.
61:      function setExecutionDelay(uint32 _executionDelay) external onlyOwner {

/// @audit Missing '@param _l2BatchNumber'
72       /// @dev Returns the timestamp when `_l2BatchNumber` was committed.
73:      function getCommittedBatchTimestamp(uint256 _l2BatchNumber) external view returns (uint256) {

/// @audit Missing '@param _newBatchesData'
77       /// @dev Records the timestamp for all provided committed batches and make
78       /// a call to the zkSync contract with the same calldata.
79       function commitBatches(
80           StoredBatchInfo calldata,
81:          CommitBatchInfo[] calldata _newBatchesData

/// @audit Missing '@param _newBatchesData'
113      /// @dev Check that batches were committed at least X time ago and
114      /// make a call to the zkSync contract with the same calldata.
115:     function executeBatches(StoredBatchInfo[] calldata _newBatchesData) external onlyValidator {

GitHub: 46, 46, 46, 46, 53, 60, 72, 77, 113

File: cache/solpp-generated-contracts/zksync/facets/Executor.sol

/// @audit Missing '@param _previousBatch'
26       /// @dev Process one batch commit using the previous batch StoredBatchInfo
27       /// @dev returns new batch StoredBatchInfo
28       /// @notice Does not change storage
29       function _commitOneBatch(
30:          StoredBatchInfo memory _previousBatch,

/// @audit Missing '@param _newBatch'
26       /// @dev Process one batch commit using the previous batch StoredBatchInfo
27       /// @dev returns new batch StoredBatchInfo
28       /// @notice Does not change storage
29       function _commitOneBatch(
30           StoredBatchInfo memory _previousBatch,
31:          CommitBatchInfo calldata _newBatch,

/// @audit Missing '@param _expectedSystemContractUpgradeTxHash'
26       /// @dev Process one batch commit using the previous batch StoredBatchInfo
27       /// @dev returns new batch StoredBatchInfo
28       /// @notice Does not change storage
29       function _commitOneBatch(
30           StoredBatchInfo memory _previousBatch,
31           CommitBatchInfo calldata _newBatch,
32:          bytes32 _expectedSystemContractUpgradeTxHash

/// @audit Missing '@param _newBatch'
/// @audit Missing '@param _expectedSystemContractUpgradeTxHash'
99       /// @dev Check that L2 logs are proper and batch contain all meta information for them
100      /// @dev The logs processed here should line up such that only one log for each key from the
101      ///      SystemLogKey enum in Constants.sol is processed per new batch.
102      /// @dev Data returned from here will be used to form the batch commitment.
103:     function _processL2Logs(CommitBatchInfo calldata _newBatch, bytes32 _expectedSystemContractUpgradeTxHash)

/// @audit Missing '@param _lastCommittedBatchData'
/// @audit Missing '@param _newBatchesData'
175      /// @notice Commit batch
176      /// @notice 1. Checks timestamp.
177      /// @notice 2. Process L2 logs.
178      /// @notice 3. Store batch commitments.
179:     function commitBatches(StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData)

/// @audit Missing '@param _nPriorityOps'
261      /// @dev Pops the priority operations from the priority queue and returns a rolling hash of operations
262:     function _collectOperationsFromPriorityQueue(uint256 _nPriorityOps) internal returns (bytes32 concatHash) {

/// @audit Missing '@param _storedBatch'
/// @audit Missing '@param _executedBatchIdx'
271      /// @dev Executes one batch
272      /// @dev 1. Processes all pending operations (Complete priority requests)
273      /// @dev 2. Finalizes batch on Ethereum
274      /// @dev _executedBatchIdx is an index in the array of the batches that we want to execute together
275:     function _executeOneBatch(StoredBatchInfo memory _storedBatch, uint256 _executedBatchIdx) internal {

/// @audit Missing '@param _batchesData'
290      /// @notice Execute batches, complete priority operations and process withdrawals.
291      /// @notice 1. Processes all pending operations (Complete priority requests)
292      /// @notice 2. Finalizes batch on Ethereum
293:     function executeBatches(StoredBatchInfo[] calldata _batchesData) external nonReentrant onlyValidator {

/// @audit Missing '@param _prevBatch'
311      /// @notice Batches commitment verification.
312      /// @notice Only verifies batch commitments without any other processing
313      function proveBatches(
314:         StoredBatchInfo calldata _prevBatch,

/// @audit Missing '@param _committedBatches'
311      /// @notice Batches commitment verification.
312      /// @notice Only verifies batch commitments without any other processing
313      function proveBatches(
314          StoredBatchInfo calldata _prevBatch,
315:         StoredBatchInfo[] calldata _committedBatches,

/// @audit Missing '@param _proof'
311      /// @notice Batches commitment verification.
312      /// @notice Only verifies batch commitments without any other processing
313      function proveBatches(
314          StoredBatchInfo calldata _prevBatch,
315          StoredBatchInfo[] calldata _committedBatches,
316:         ProofInput calldata _proof

/// @audit Missing '@param _prevBatchCommitment'
368      /// @dev Gets zk proof public input
369      function _getBatchProofPublicInput(
370:         bytes32 _prevBatchCommitment,

/// @audit Missing '@param _currentBatchCommitment'
368      /// @dev Gets zk proof public input
369      function _getBatchProofPublicInput(
370          bytes32 _prevBatchCommitment,
371:         bytes32 _currentBatchCommitment,

/// @audit Missing '@param _verifierParams'
368      /// @dev Gets zk proof public input
369      function _getBatchProofPublicInput(
370          bytes32 _prevBatchCommitment,
371          bytes32 _currentBatchCommitment,
372:         VerifierParams memory _verifierParams

/// @audit Missing '@param a'
/// @audit Missing '@param b'
409      /// @notice Returns larger of two values
410:     function _maxU256(uint256 a, uint256 b) internal pure returns (uint256) {

/// @audit Missing '@param _newBatchData'
/// @audit Missing '@param _stateDiffHash'
414      /// @dev Creates batch commitment from its data
415:     function _createBatchCommitment(CommitBatchInfo calldata _newBatchData, bytes32 _stateDiffHash)

/// @audit Missing '@param _batch'
427:     function _batchPassThroughData(CommitBatchInfo calldata _batch) internal pure returns (bytes memory) {

/// @audit Missing '@param _batch'
/// @audit Missing '@param _stateDiffHash'
441:     function _batchAuxiliaryOutput(CommitBatchInfo calldata _batch, bytes32 _stateDiffHash)

/// @audit Missing '@param _storedBatchInfo'
459      /// @notice Returns the keccak hash of the ABI-encoded StoredBatchInfo
460:     function _hashStoredBatchInfo(StoredBatchInfo memory _storedBatchInfo) internal pure returns (bytes32) {

/// @audit Missing '@param _bitMap'
/// @audit Missing '@param _index'
464      /// @notice Returns true if the bit at index {_index} is 1
465:     function _checkBit(uint256 _bitMap, uint8 _index) internal pure returns (bool) {

/// @audit Missing '@param _bitMap'
/// @audit Missing '@param _index'
469      /// @notice Sets the given bit in {_num} at index {_index} to 1.
470:     function _setBit(uint256 _bitMap, uint8 _index) internal pure returns (uint256) {

GitHub: 26, 26, 26, 99, 99, 175, 175, 261, 271, 271, 290, 311, 311, 311, 368, 368, 368, 409, 409, 414, 414, 427, 441, 441, 459, 464, 464, 469, 469

File: cache/solpp-generated-contracts/zksync/facets/Getters.sol

/// @audit Missing '@param _address'
79       /// @return Whether the address has a validator access
80:      function isValidator(address _address) external view returns (bool) {

/// @audit Missing '@param _batchNumber'
84       /// @return Merkle root of the tree with L2 logs for the selected batch
85:      function l2LogsRootHash(uint256 _batchNumber) external view returns (bytes32) {

/// @audit Missing '@param _batchNumber'
89       /// @notice For unfinalized (non executed) batches may change
90       /// @dev returns zero for non-committed batches
91       /// @return The hash of committed L2 batch.
92:      function storedBatchHash(uint256 _batchNumber) external view returns (bytes32) {

/// @audit Missing '@param _facet'
136      /// @return isFreezable Whether the facet can be frozen by the governor or always accessible
137:     function isFacetFreezable(address _facet) external view returns (bool isFreezable) {

/// @audit Missing '@param _selector'
159      /// @return Whether the selector can be frozen by the governor or always accessible
160:     function isFunctionFreezable(bytes4 _selector) external view returns (bool) {

/// @audit Missing '@param _facet'
192      /// @return NON-sorted array with function selectors supported by a specific facet
193:     function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory) {

/// @audit Missing '@param _selector'
204      /// @return Facet address associated with a selector. Zero if the selector is not added to the diamond
205:     function facetAddress(bytes4 _selector) external view returns (address) {

/// @audit Missing '@param _batchNumber'
232      /// @notice For unfinalized (non executed) batches may change
233      /// @dev It is a *deprecated* method, please use `storedBatchHash` instead.
234      /// @dev returns zero for non-committed batches
235      /// @return The hash of committed L2 batch.
236:     function storedBlockHash(uint256 _batchNumber) external view returns (bytes32) {

GitHub: 79, 84, 89, 136, 159, 192, 204, 232

File: cache/solpp-generated-contracts/zksync/facets/Mailbox.sol

/// @audit Missing '@param _to'
/// @audit Missing '@param _amount'
113      /// @notice Transfer ether from the contract to the receiver
114      /// @dev Reverts only if the transfer call failed
115:     function _withdrawFunds(address _to, uint256 _amount) internal {

/// @audit Missing '@param _batchNumber'
124      /// @dev Prove that a specific L2 log was sent in a specific L2 batch number
125      function _proveL2LogInclusion(
126:         uint256 _batchNumber,

/// @audit Missing '@param _index'
124      /// @dev Prove that a specific L2 log was sent in a specific L2 batch number
125      function _proveL2LogInclusion(
126          uint256 _batchNumber,
127:         uint256 _index,

/// @audit Missing '@param _log'
124      /// @dev Prove that a specific L2 log was sent in a specific L2 batch number
125      function _proveL2LogInclusion(
126          uint256 _batchNumber,
127          uint256 _index,
128:         L2Log memory _log,

/// @audit Missing '@param _proof'
124      /// @dev Prove that a specific L2 log was sent in a specific L2 batch number
125      function _proveL2LogInclusion(
126          uint256 _batchNumber,
127          uint256 _index,
128          L2Log memory _log,
129:         bytes32[] calldata _proof

/// @audit Missing '@param _message'
150      /// @dev Convert arbitrary-length message to the raw l2 log
151:     function _L2MessageToLog(L2Message memory _message) internal pure returns (L2Log memory) {

/// @audit Missing '@param _depositor'
/// @audit Missing '@param _amount'
277:     function _verifyDepositLimit(address _depositor, uint256 _amount) internal {

/// @audit Missing '@param _sender'
285      function _requestL2Transaction(
286:         address _sender,

/// @audit Missing '@param _contractAddressL2'
285      function _requestL2Transaction(
286          address _sender,
287:         address _contractAddressL2,

/// @audit Missing '@param _l2Value'
285      function _requestL2Transaction(
286          address _sender,
287          address _contractAddressL2,
288:         uint256 _l2Value,

/// @audit Missing '@param _calldata'
285      function _requestL2Transaction(
286          address _sender,
287          address _contractAddressL2,
288          uint256 _l2Value,
289:         bytes calldata _calldata,

/// @audit Missing '@param _l2GasLimit'
285      function _requestL2Transaction(
286          address _sender,
287          address _contractAddressL2,
288          uint256 _l2Value,
289          bytes calldata _calldata,
290:         uint256 _l2GasLimit,

/// @audit Missing '@param _l2GasPerPubdataByteLimit'
285      function _requestL2Transaction(
286          address _sender,
28
@vladbochok
Copy link

Regarding M-01. This is not true, the admin role is not an EOA, but a multisig and is a matter of configuration to the different environments - localhost, testnet and mainnet. So we dispute that this is an issue at all. Moreover, the upgradability is intended training wheels for the current state of L2 protocols.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment