2. Add payable to functions that won't receive ETH
Impact
Marking a function as payable saves gas. Functions that have the onlyOwner modifier cannot be called by normal users and will not mistakenly receive ETH. These functions can be payable to save gas.
But all functions in Permissions.sol that have the onlyGovernor modifier or the onlyGuardian modifier can receive the same gas optimization
Tools Used
Manual analysis
Recommended Mitigation Steps
Add payable to functions with access control for gas savings
3. Split up require statements instead of &&
Impact
Combining require statement conditions with && logic uses unnecessary gas. It is better to split up each part of the logical statement into a separate require statements
1. Use calldata instead of memory for function parameters
Impact
Use calldata instead of memory for function parameters. Having function arguments use calldata instead of memory can save gas.
Proof of Concept
At least two cases exist of function arguments using memory instead of calldata https://github.com/code-423n4/2022-03-volt/blob/main/contracts/refs/OracleRef.sol#L84 https://github.com/code-423n4/2022-03-volt/blob/main/contracts/peg/NonCustodialPSM.sol#L456
Tools Used
Manual analysis
Recommended Mitigation Steps
Change function arguments from memory to calldata
2. Add payable to functions that won't receive ETH
Impact
Marking a function as payable saves gas. Functions that have the onlyOwner modifier cannot be called by normal users and will not mistakenly receive ETH. These functions can be payable to save gas.
Proof of Concept
One function was found with the onlyOwner modifier that can be payable https://github.com/code-423n4/2022-03-volt/blob/main/contracts/oracle/OraclePassThrough.sol#L53
But all functions in Permissions.sol that have the onlyGovernor modifier or the onlyGuardian modifier can receive the same gas optimization
Tools Used
Manual analysis
Recommended Mitigation Steps
Add payable to functions with access control for gas savings
3. Split up require statements instead of &&
Impact
Combining require statement conditions with && logic uses unnecessary gas. It is better to split up each part of the logical statement into a separate require statements
Proof of Concept
One instance of this issue was found https://github.com/code-423n4/2022-03-volt/blob/main/contracts/volt/Volt.sol#L91
Tools Used
Manual analysis
Recommended Mitigation Steps
Use separate require statements instead of concatenating with && to save gas
4. Short require strings save gas
Impact
Strings in solidity are handled in 32 byte chunks. A require string longer than 32 bytes uses more gas. Shortening these strings will save gas.
Proof of Concept
Several cases of this gas optimization were found. These are a few examples, but more may exist
Tools Used
Manual analysis
Recommended Mitigation Steps
Shorten require strings
5. Use Solidity errors instead of require
Impact
Solidity errors introduced in version 0.8.4 can save gas on revert conditions https://blog.soliditylang.org/2021/04/21/custom-errors/ https://twitter.com/PatrickAlphaC/status/1505197417884528640
Proof of Concept
Error messages are not used in the contract, so all require blocks could receive a gas optimization
Tools Used
Manual analysis
Recommended Mitigation Steps
Replace require blocks with new solidity errors from solidity 0.8.4 described in https://blog.soliditylang.org/2021/04/21/custom-errors/