You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[G-02] Function ordering via Method ID [22 gas per instance]
Context:
All Contracts
Description:
Contracts most called functions could simply save gas by function ordering via Method ID. Calling a function at runtime will be cheaper if the function is positioned earlier in the order (has a relatively lower Method ID) because 22 gas are added to the cost of a function for every position that came before it. The caller can save on gas if you prioritize most called functions.
Recommendation:
Find a lower method ID name for the most called functions for example Call() vs. Call1() is cheaper by 22 gas
For example, the function IDs in the AlgebraPool.sol contract will be the most used; A lower method ID may be given.
Proof Of Concept:
There’s a way to save a significant amount of gas on deployment using Clones: https://www.youtube.com/watch?v=3Mw-pMmJ7TA .
It is extremely inexpensive to distribute by Cloneing with Create2.
Description:
You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable. Making the constructor payable eliminates the need for an initial check of msg.value == 0 and saves 13 gas on deployment with no security risks.
Code Generator: Skip existence check for external contract if return data is expected. In this case, the ABI decoder will revert if the contract does not exist.
Recommendation:
Consider to upgrade pragma to at least 0.8.10
[G-08] Use Custom Errors rather than revert() / require() strings to save deployment gas [68 gas per instance]
Description:
Custom errors are available from solidity version 0.8.4. Custom errors save ~50 gas each time they’re hitby avoiding having to allocate and store the revert string. Not defining the strings also save deployment gas. https://blog.soliditylang.org/2021/04/21/custom-errors/
Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Description:
If a function modifier or require such as onlyOwner-admin is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2), DUP1(3), ISZERO(3), PUSH2(3), JUMPI(10), PUSH1(3), DUP1(3), REVERT(0), JUMPDEST(1), POP(2) which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost.
Recommendation:
Functions guaranteed to revert when called by normal users can be marked payable (for only onlyowner or admin functions)
Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Recommendation: setFactory require(factory == address(0)); query allows the function to be executed only once and restricts the set property, remove this from the code for gas saving.
If it needs to be run once, add initalize or assign value from Constrcutor
Recommendation:
Using double require instead of operator && can save more gas.
When having a require statement with 2 or more expressions needed, place the expression that cost less gas first.
Current Code:
require(gamma1!=0&&gamma2!=0&&volumeGamma!=0, 'Gammas must be > 0’);
Recommendation Code:
require(gamma1!=0&&gamma2!=0, 'Gammas must be > 0’);
require(volumeGamma!=0, 'Gammas must be > 0’);
The text was updated successfully, but these errors were encountered:
Gas Optimizations List
assembly
to write address storage valuesMethod ID
x += y
costs more gas thanx = x + y
for state variablesaddress(0)
clone
instead ofnew
constructor
topayable
Custom Errors
rather than revert() / require() strings to save deployment gaspayable
setOwner
functionrequire(factory == address(0));
double require
instead of using&&
Total 12 issues
[G-01] Use
assembly
to write address storage values [33 gas per instance]Context:
BuyCrowdfundBase.sol#L127
AlgebraFactory.sol#L87
AlgebraFactory.sol#L94
Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-02] Function ordering via
Method ID
[22 gas per instance]Context:
All Contracts
Description:
Contracts most called functions could simply save gas by function ordering via
Method ID
. Calling a function at runtime will be cheaper if the function is positioned earlier in the order (has a relatively lower Method ID) because22 gas
are added to the cost of a function for every position that came before it. The caller can save on gas if you prioritize most called functions.Recommendation:
Find a lower
method ID
name for the most called functions for example Call() vs. Call1() is cheaper by22 gas
For example, the function IDs in the
AlgebraPool.sol
contract will be the most used; A lower method ID may be given.Proof of Consept:
https://coinsbench.com/advanced-gas-optimizations-tips-for-solidity-85c47f413dc5
AlgebraPool.sol function names can be named and sorted according to METHOD ID
[G-03]
x += y
costs more gas thanx = x + y
for state variables [16 gas per instance]Context:
AlgebraPool.sol#L257
AlgebraPool.sol#L258
AlgebraPool.sol#L811
AlgebraPool.sol#L931
Description:
x += y
costs more gas thanx = x + y
for state variables.Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-04]
Use assembly
to check foraddress(0)
[6 gas per instance]Context:
AlgebraFactory.sol#L62
AlgebraPoolDeployer.sol#L38
Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-05] Deploy the contract with
clone
instead ofnew
Context:
AlgebraFactory.sol#L65
Proof Of Concept:
There’s a way to save a significant amount of gas on deployment using Clones:
https://www.youtube.com/watch?v=3Mw-pMmJ7TA .
It is extremely inexpensive to distribute by Cloneing with Create2.
Gas usage difference between the two? (answer: a new clone is 10x cheaper)
[G-06] Setting the
constructor
topayable
[13 gas per instance]Context:
AlgebraFactory.sol#L50
AlgebraPool.sol#L66
AlgebraPoolDeployer.sol#L31
PoolImmutables.sol#L29
Description:
You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable. Making the constructor payable eliminates the need for an initial check of
msg.value == 0
and saves13 gas
on deployment with no security risks.Recommendation:
Set the constructor to
payable
Proof Of Concept:
https://forum.openzeppelin.com/t/a-collection-of-gas-optimisation-tricks/19966/5?u=pcaversaccio
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-07] Free gas savings for using solidity 0.8.10+
Context:
All Contracts
Description:
Solidity 0.8.10 has a useful change which reduced gas costs of external calls which expect a return value: https://blog.soliditylang.org/2021/11/09/solidity-0.8.10-release-announcement/
Code Generator: Skip existence check for external contract if return data is expected. In this case, the ABI decoder will revert if the contract does not exist.
Recommendation:
Consider to upgrade pragma to at least 0.8.10
[G-08] Use
Custom Errors
rather than revert() / require() strings to save deployment gas [68 gas per instance]Context:
AlgebraPool.sol – 58 instances
AlgebraFactory.sol – 9 instances
AlgebraPoolDeployer.sol – 4 instances
DataStorageOperator.sol – 4 instances
Description:
Custom errors are available from solidity version 0.8.4. Custom errors save ~50 gas each time they’re hitby avoiding having to allocate and store the revert string. Not defining the strings also save deployment gas.
https://blog.soliditylang.org/2021/04/21/custom-errors/
Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-09] Functions guaranteed to revert when callled by normal users can be marked
payable
[24 gas per instance]Context:
AlgebraFactory.sol#L77
AlgebraFactory.sol#L84
AlgebraFactory.sol#L91
AlgebraFactory.sol#L108
AlgebraPoolDeployer.sol#L36
Description:
If a function modifier or require such as onlyOwner-admin is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2), DUP1(3), ISZERO(3), PUSH2(3), JUMPI(10), PUSH1(3), DUP1(3), REVERT(0), JUMPDEST(1), POP(2) which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost.
Recommendation:
Functions guaranteed to revert when called by normal users can be marked payable (for only
onlyowner or admin
functions)Proof Of Concept:
The optimizer was turned on and set to 10000 runs.
Gas Report:
[G-10] Change to
setOwner
function [Save 5606 gas with a simpler design]Context:
AlgebraFactory.sol#L77-L81
Recommendation:
Current Code : (Deployment Gas Cost : 114876)
Recommendation Code : : (Deployment Gas Cost : 109270)
[G-11] Remove to
require(factory == address(0));
Context:
AlgebraPoolDeployer.sol#L38
Recommendation:
setFactory
require(factory == address(0)); query allows the function to be executed only once and restricts the set property, remove this from the code for gas saving.If it needs to be run once, add initalize or assign value from Constrcutor
[G-12] Use
double require
instead of using&&
Context:
AlgebraFactory.sol#L110
Recommendation:
Using double require instead of operator && can save more gas.
When having a require statement with 2 or more expressions needed, place the expression that cost less gas first.
Current Code:
Recommendation Code:
The text was updated successfully, but these errors were encountered: