Skip to content

Latest commit

 

History

History
85 lines (66 loc) · 7.36 KB

tnevler-G.md

File metadata and controls

85 lines (66 loc) · 7.36 KB

Report

Gas Optimizations

[G-1]: The increment in for loop post condition can be made unchecked

Context:

  1. for (uint256 i = 0; i < facetCutsLength; ++i) { L94
  2. for (uint256 i = 0; i < selectorsLength; ++i) { L132
  3. for (uint256 i = 0; i < selectorsLength; ++i) { L153
  4. for (uint256 i = 0; i < selectorsLength; ++i) { L173

Description:

This can save 30-40 gas per loop iteration.

Recommendation:

Example how to fix. Change:

for (uint256 i = 0; i < orders.length; ++i) {
   // Do the thing
}

To:

for (uint256 i = 0; i < orders.length;) {
   // Do the thing
   unchecked { ++i; }
}

[G-2]: If internal function called only once it can be inlined to save gas

Context:

  1. Executor. _getBlockProofPublicInput
  2. Executor._maxU256
  3. Executor._blockPassThroughData
  4. Executor._blockMetaParameters
  5. Executor._blockAuxilaryOutput
  6. Mailbox._L2MessageToLog
  7. L1EthBridge._getDepositL2Calldata
  8. L2ContractHelper.bytecodeLen

Description:

If they are not inlined, they cost an additional 20 to 40 gas because of 2 extra jump instructions and additional stack operations needed for function calls.

[G-3]: No need to cache state variable in local memory if it only use once

Context:

  1. bool isEnabled = isAccessPublic[_target]; L76
  2. bool currentPermission = hasSpecialAccessToCall[_caller][_target][_functionSig]; L129

Recommendation:

Read the state variable from storage.

[G-4]: Use calldata instead of memory

Context:

  1. function _commitOneBlock(StoredBlockInfo memory _previousBlock, CommitBlockInfo calldata _newBlock) L23 (_previousBlock)
  2. function _calculateBlockHash(StoredBlockInfo memory _previousBlock, CommitBlockInfo calldata _newBlock) L80 (_previousBlock)
  3. function _executeOneBlock(StoredBlockInfo memory _storedBlock, uint256 _executedBlockIdx) internal { L190 (_storedBlock)
  4. VerifierParams memory _verifierParams L278
  5. function _hashStoredBlockInfo(StoredBlockInfo memory _storedBlockInfo) internal pure returns (bytes32) { L385
  6. L2Log memory _log, L43
  7. L2Log memory _log, L53
  8. function diamondCut(DiamondCutData memory _diamondCut) internal { L89
  9. bytes4[] memory _selectors, L121
  10. bytes4[] memory _selectors, L145
  11. function _removeFunctions(address _facet, bytes4[] memory _selectors) private { L167 (_selectors)
  12. function _initializeDiamondCut(address _init, bytes memory _calldata) private { L277 (_calldata)
  13. function pushBack(Queue storage _queue, PriorityOperation memory _operation) internal { L54 (_operation)
  14. function _parseL2WithdrawalMessage(bytes memory _l2ToL1message) L260
  15. function _parseL2WithdrawalMessage(bytes memory _message) L214
  16. function sendMessageToL1(bytes memory _message) internal returns (bytes32) { L43
  17. function hashL2Bytecode(bytes memory _bytecode) internal pure returns (bytes32 hashedBytecode) { L47
  18. function bridgeInitialize(address _l1Address, bytes memory _data) external initializer { L43 (_data)
  19. function decodeString(bytes memory _input) external pure returns (string memory result) { L10
  20. function decodeUint8(bytes memory _input) external pure returns (uint8 result) { L15

Description:

If a reference type function parameter is read-only, it is recommended to use calldata instead of memory because this provides significant gas savings. Since Solidity v0.6.9, memory and calldata are allowed in all functions regardless of their visibility type (ie external, public, etc).