Require statements including conditions with the && operator can be broken down in multiple require statements to save gas.
require(version == 1 && _bytecodeHash[1] == bytes1(0), "zf"); // Incorrectly formatted bytecodeHash
Breakdown each condition in a separate require
require(version == 1);
require(_bytecodeHash[1] == bytes1(0), "zf");)
File: ethereum\contracts\bridge\L1ERC20Bridge.sol
82: bytes memory create2Input = abi.encode(address(this), l2ProxyTokenBytecodeHash, _governor);
168: data = abi.encode(data1, data2, data3);
File: ethereum\contracts\zksync\DiamondInit.sol
54: s.storedBlockHashes[0] = keccak256(abi.encode(storedBlockZero));
File: ethereum\contracts\zksync\facets\DiamondCut.sol 27: s.diamondCutStorage.proposedDiamondCutHash = keccak256(abi.encode(_facetCuts, _initAddress));
File:
381: return abi.encode(_block.l2LogsTreeRoot, l2ToL1LogsHash, initialStorageChangesHash, repeatedStorageChangesHash);
https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/bridge/L1ERC20Bridge.sol#L82 https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/bridge/L1ERC20Bridge.sol#L168 https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/zksync/DiamondInit.sol#L54 https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/zksync/facets/DiamondCut.sol#L27 https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/zksync/facets/Executor.sol#L381
Expressions for constant values such as a call to keccak256(), should use immutable rather than constant See https://github.com/ethereum/solidity/issues/9232 issue for a detail description of the issue Similar bug: code-423n4/2021-11-unlock-findings#238
File: ethereum\contracts\common\L2ContractHelper.sol
41: bytes32 constant CREATE2_PREFIX = keccak256("zksyncCreate2");
https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/ethereum/contracts/common/L2ContractHelper.sol#L41 https://github.com/code-423n4/2022-10-zksync/blob/456078b53a6d09636b84522ac8f3e8049e4e3af5/zksync/contracts/L2ContractHelper.sol#L24
When running a function we could pass the function parameters as calldata or memory for variables such as strings, structs,arrays etc. If we are not modifying the passed parameter we should pass it as calldata because calldata is more gas efficient than memory. Let's see an example:
File: zksync\contracts\ExternalDecoder.sol
10: function decodeString(bytes memory _input) external pure returns (string memory result) {
(result) = abi.decode(_input, (string));
12: }