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
GAS-1: Avoid having ERC20 token balances go to zero, always keep a small amount
Since we know that 0 - 1 writes cost 22K gas, which is a lot. If an address is frequently emptying (and reloading) it’s account balance, this will lead to a lot of zero to one writes, resulting in crazy amount of gas usage
The way it can be implemented in src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenBase_v1.sol
is to add 1 to _accountBits[address] on the first balance increase, what i mean by that is when a user gets his initial _accountBits updated use +1 (as an extra number to prevent 0 - 1 writes) then while withdrawing subtract -1 from his total balance which will accomplish both tasks, preserve the balance solvency and prevent 0 - 1 writes
function balanceOf(addressuser) externalviewreturns (uint) {
GAS-2 : Make constructors Payable
Making the constructor payable saved 200 gas on deployment. This is because non-payable functions have an implicit require(msg.value == 0) inserted in them. Additionally, fewer bytecode at deploy time mean less gas cost due to smaller calldata.
We can make admin specific functions payable to save gas, because the compiler won’t be checking the callvalue of the function.
This will also make the contract smaller and cheaper to deploy as there will be fewer opcodes in the creation and runtime code.
we could make all functions payable to make our codebase hyper gas efficient but that will cause user fund loss, so that is why it usually good idea to just apply this optimization to priviledged functions assuming higher knowledge. Instances
The functions using these modifier across the codebase are better options to use this payable modifier on
onlyCommunityOrTeamMultisig
onlyself
onlyModule
onlyOrchestratorAdmin
onlyModuleRoleAdmin
GAS-4 : Custom errors are cheaper than require statements
Custom errors are cheaper than require statements with strings because of how custom errors are handled. Solidity stores only the first 4 bytes of the hash of the error signature and returns only that. This means during reverting, only 4 bytes needs to be stored in memory. In the case of string messages in require statements, Solidity has to store(in memory) and revert with at least 64 bytes.
GAS-5: Split require statements that have boolean expressions
When we split require statements, we are essentially saying that each statement must be true for the function to continue executing.
If the first statement evaluates to false, the function will revert immediately and the following require statements will not be examined. This will save the gas cost rather than evaluating the next require statement.
GAS-7 : Timestamps and block numbers in storage do not need to be uint256
A timestamp of size uint48 will work for millions of years into the future. A block number increments once every 12 seconds. This should give you a sense of the size of numbers that are sensible.
Please remember the following instructions: for next competition
Users need to clone the repository, make changes, and then upload it to their private repository.
In their report, they should include the link to their private repository.
After that, they will need to invite sponsors to their private repository.
The winner will be chosen based on the average gas savings in tests.
There are some rules to consider: if any test fails due to changes, the submission is invalid. Additionally, if a user employs assembly, the submission is also invalid.
Hats username: @ghost
Twitter username: @imaybeghost
Discord username: @burhan_khaja
wallet: 0x022df5782baf4ec29BB89529de3c89CdA7AF5B7d
Severity: gas-saving
GAS-1: Avoid having ERC20 token balances go to zero, always keep a small amount
Since we know that 0 - 1 writes cost 22K gas, which is a lot. If an address is frequently emptying (and reloading) it’s account balance, this will lead to a lot of zero to one writes, resulting in crazy amount of gas usage
The way it can be implemented in src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenBase_v1.sol
is to add 1 to _accountBits[address] on the first balance increase, what i mean by that is when a user gets his initial _accountBits updated use +1 (as an extra number to prevent 0 - 1 writes) then while withdrawing subtract -1 from his total balance which will accomplish both tasks, preserve the balance solvency and prevent 0 - 1 writes
Instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenBase_v1.sol
Lines 421 to 423 in 09e3a91
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/logicModule/LM_PC_Staking_v1.sol
Line 121 in 6289238
GAS-2 : Make constructors Payable
Making the constructor payable saved 200 gas on deployment. This is because non-payable functions have an implicit require(msg.value == 0) inserted in them. Additionally, fewer bytecode at deploy time mean less gas cost due to smaller calldata.
instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/proxies/InverterProxyAdmin_v1.sol
Line 31 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/factories/ModuleFactory_v1.sol
Line 112 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/tokens/ERC20Issuance_v1.sol
Line 52 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/proxies/InverterTransparentUpgradeableProxy_v1.sol
Line 78 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/orchestrator/Orchestrator_v1.sol
Line 116 in 6289238
GAS-3 : Admin Functions can be
We can make admin specific functions payable to save gas, because the compiler won’t be checking the callvalue of the function.
This will also make the contract smaller and cheaper to deploy as there will be fewer opcodes in the creation and runtime code.
we could make all functions payable to make our codebase hyper gas efficient but that will cause user fund loss, so that is why it usually good idea to just apply this optimization to priviledged functions assuming higher knowledge.
Instances
The functions using these modifier across the codebase are better options to use this payable modifier on
GAS-4 : Custom errors are cheaper than require statements
Custom errors are cheaper than require statements with strings because of how custom errors are handled. Solidity stores only the first 4 bytes of the hash of the error signature and returns only that. This means during reverting, only 4 bytes needs to be stored in memory. In the case of string messages in require statements, Solidity has to store(in memory) and revert with at least 64 bytes.
Instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/script/factories/DeployModuleFactory_v1.s.sol
Line 35 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/script/factories/DeployOrchestratorFactory_v1.s.sol
Line 49 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/formulas/Utils.sol
Line 18 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenUpgradeable_v1.sol
Line 49 in 6289238
GAS-5: Split require statements that have boolean expressions
When we split require statements, we are essentially saying that each statement must be true for the function to continue executing.
If the first statement evaluates to false, the function will revert immediately and the following require statements will not be examined. This will save the gas cost rather than evaluating the next require statement.
Instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/formulas/BancorFormula.sol
Lines 201 to 204 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenBase_v1.sol
Line 395 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/formulas/BancorFormula.sol
Line 246 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/formulas/BancorFormula.sol
Line 299 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/rebasing/abstracts/ElasticReceiptTokenBase_v1.sol
Line 395 in 6289238
GAS-6 : Split revert statements
Similar to splitting require statements, you will usually save some gas by not having a boolean operator in the if statement.
Instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/common/LinkedIdList.sol
Line 44 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/factories/ModuleFactory_v1.sol
Line 84 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/logicModule/LM_PC_KPIRewarder_v1.sol
Line 236 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/bondingCurve/abstracts/BondingCurveBase_v1.sol
Line 394 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/fundingManager/rebasing/FM_Rebasing_v1.sol
Line 71 in 6289238
GAS-7 : Timestamps and block numbers in storage do not need to be uint256
A timestamp of size uint48 will work for millions of years into the future. A block number increments once every 12 seconds. This should give you a sense of the size of numbers that are sensible.
Instances
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/authorizer/role/interfaces/IAUT_EXT_VotingRoles_v1.sol
Line 13 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/authorizer/role/interfaces/IAUT_EXT_VotingRoles_v1.sol
Line 16 in 6289238
Inverter-Network-0xe47e52c4fea05e555920f1dcdcc6fb8eca103eeb/src/modules/authorizer/role/interfaces/IAUT_EXT_VotingRoles_v1.sol
Line 22 in 6289238
The text was updated successfully, but these errors were encountered: