Platform: Code4rena
Start Date: 26/05/2022
Pot Size: $75,000 USDT
Total HM: 31
Participants: 71
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 18
Id: 126
League: ETH
Rank: 67/71
Findings: 1
Award: $52.07
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, Cityscape, Dravee, ElKu, FSchmoede, Funen, GalloDaSballo, Hawkeye, Kaiziron, MiloTruck, Randyyy, RoiEvenHaim, Ruhum, SecureZeroX, SmartSek, TerrierLover, TomJ, Tomio, WatchPug, Waze, _Adam, asutorufos, c3phas, catchup, cogitoergosumsw, delfin454000, ellahi, fatherOfBlocks, gzeon, hansfriese, horsefacts, jonatascm, minhquanym, oyc_109, pauliax, reassor, robee, sach1r0, saian, sashik_eth, simon135, z3s
52.0655 USDT - $52.07
Using a prefix increment (++i) instead of a postfix increment (i++) saves gas for each loop cycle and so can have a big gas impact when the loop executes on a large number of elements.
There are many examples of this in for loops https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L84 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L126 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L49 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L66 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L148 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L214 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L238 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L257 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L281 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L326 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L71 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L78 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L137 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L140 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L181 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L213 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L217 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L329 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L207 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L286 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L425 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L457 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L463 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L640 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L665 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L720 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L803 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L176 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L199 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L218 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L245 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L282 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L315 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L360 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L383 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L387 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L406 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L555 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L593
Use prefix not postfix to increment in a loop
Solidity does not recognize null as a value, so uint variables are initialized to zero. Setting a uint variable to zero is redundant and can waste gas.
There were many places where an int is initialized to zero https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L84 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L126 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV1.sol#L29 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L49 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L66 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L50 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L148 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L214 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L238 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L257 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L281 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L326 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L71 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L78 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L137 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L181 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L213 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L217 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L227 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L329 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L74 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L75 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L78 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L79 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L80 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L286 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L315 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L360 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L387 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L406 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L420 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L425 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L613 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L803 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L28 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L66 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L67 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L70 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L71 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L72 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L176 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L199 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L218 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L245 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L282
Remove the redundant zero initialization
uint256 i;
instead of uint256 i = 0;
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
One example is
require(msg.sender == poolManager && !isShutdown, "!add");
This can be improved to
require(msg.sender == poolManager); require(!isShutdown, "!add");
Several places had require statements with at least one logical "and". Instead, split into two to save gas https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L261 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L262 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/StashFactory.sol#L87
Use separate require statements instead of concatenating with &&
Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop. This saves gas.
This was found in many places https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L148 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L281 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L217 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L329 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L207 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L286 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L315 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L360 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L457 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L720 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L803 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L176 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L199 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L218 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L245 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L282
Cache the array length before the for loop
Using > 0
uses slightly more gas than using != 0
. Use != 0
when comparing uint variables to zero, which cannot hold values below zero
Locations where this was found include https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L74 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L132 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV1.sol#L111 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV1.sol#L156 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L8 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L45 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L48 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L53 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L58 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L63 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L68 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L73 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L78 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol#L83 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L105 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L131 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L20 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L102 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L122 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L142 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L210 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L234 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L253 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L285 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L68 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L106 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L219 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L100 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L517 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L526 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L541 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L551 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L556 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L562 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L586 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L590 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L137 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L143 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L150 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L180 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L340 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L520 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L626 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L649 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L670 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L679 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L723 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L781 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L89 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L117 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L132 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L138 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L173 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L196 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L215 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L273
Replace > 0
with != 0
to save gas
The value 0xffffffffffffffffffffffffffff
is used but using type(uint112).max
uses less gas than this constant value.
Source https://forum.openzeppelin.com/t/using-the-maximum-integer-in-solidity/3000/13
Found here https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L25
Use type(uint112).max
For loops that use i++ do not need to use safemath for this operation because the loop would run out of gas long before this point. Making this addition operation unsafe using unchecked saves gas.
Sample code to make the for loop increment unsafe
for (uint i = 0; i < length; i = unchecked_inc(i)) { // do something that doesn't change the value of i } function unchecked_inc(uint i) returns (uint) { unchecked { return i + 1; } }
Idea borrowed from https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc#the-increment-in-for-loop-post-condition-can-be-made-unchecked
There are many for loops and that can use this change https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L84 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV3.sol#L126 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L49 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L66 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L148 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L214 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L238 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L257 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L281 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L326 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L71 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L78 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L137 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L181 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/ExtraRewardStashV2.sol#L213 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VoterProxy.sol#L217 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L329 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L286 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L315 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L360 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L387 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L406 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L425 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L803 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L176 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L199 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L218 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L245 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L282
Make the increment in for loops unsafe to save gas
Comparing a value to zero can be done using the iszero
EVM opcode. This can save gas
Source from t11s https://twitter.com/transmissions11/status/1474465495243898885
There are many places where a value is compared to zero https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FullMath.sol#L47 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L51 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L70 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L132 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/Babylonian.sol#L11 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L16 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L98 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L118 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BoringMath.sol#L138 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L172 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L115 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L154 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L233 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L459 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L545 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L791 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L72 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L95 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L153
Use the assembly iszero
evm opcode to compare values to zero
Identifying a function as payable saves gas. Functions that have a modifier like onlyOwner cannot be called by normal users and will not mistakenly receive ETH. These functions can be payable to save gas.
There are many functions that have the onlyOwner modifier in the contracts. Some examples are https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/PoolManager.sol#L27 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/PoolManager.sol#L40 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L24 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/RewardFactory.sol#L29 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L107 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L114 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L118 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/TokenFactory.sol#L19 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/TokenFactory.sol#L23 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeTokenMinter.sol#L32 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeTokenMinter.sol#L36 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeTokenMinter.sol#L41 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeTokenMinter.sol#L77 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/StashFactory.sol#L30 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/StashFactory.sol#L34 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L179 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L185 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L193 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L197 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L201 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L789
Add payable to these functions for gas savings
An internal function can save gas vs. a modifier. A modifier inlines the code of the original function but an internal function does not.
Many modifiers can use this change https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L798 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L137 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L146 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Migrations.sol#L8
Use internal functions in place of modifiers to save gas.
A solidity version before 0.8.X is used in some contracts. The latest release of solidity includes changes that can provide gas savings. The improvements include:
0.8.0
(can be more gas efficient than some library based safemath).0.8.2
, leads to cheaper runtime gas. Especially relevant when the contract has small functions. For example, OpenZeppelin libraries typically have a lot of small helper functions and 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.0.8.3
, storing packed structs, in some cases used an additional storage read operation. After EIP-2929, if the slot was already cold, this means unnecessary stack operations and extra deploy time costs. However, if the slot was already warm, this means additional cost of 100
gas alongside the same unnecessary stack operations and extra deploy time costs.0.8.4
, leads to cheaper deploy time cost and run time cost. Note: the run time cost is only relevant when the revert condition is met. In short, replace revert strings by custom errors.Source https://gist.github.com/hrkrshnn/ee8fabd532058307229d65dcd5836ddc#upgrade-to-at-least-084
Files with older solidity versions: https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/BitMath.sol https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FullMath.sol https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/Babylonian.sol https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Migrations.sol
Use solidity release 0.8.13 with Yul IR pipeline and other improvements for gas savings
The comparison operators >= and <= use more gas than >, <, or ==. Replacing the >= and ≤ operators with a comparison operator that has an opcode in the EVM saves gas
The existing code is https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L329-L336
if (block.timestamp >= periodFinish) { rewardRate = reward.div(duration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); reward = reward.add(leftover); rewardRate = reward.div(duration); }
A simple comparison can be used for gas savings by reversing the logic
if (block.timestamp < periodFinish) { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); reward = reward.add(leftover); rewardRate = reward.div(duration); } else { rewardRate = reward.div(duration); }
Replace the comparison operator and reverse the logic to save gas using the suggestions above
When multiply or dividing by a power of two, it is cheaper to bitshift than to use standard math operations.
There is a divide by 2 operation on these lines https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/helper/FixedPoint.sol#L167 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L428
Bitshift right by one bit instead of dividing by 2 to save gas
Many constant variables are public, but changing the visibility of these variables to private or internal can save gas.
These constants are public https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L59 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L60 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DRewardPool.sol#L64 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L33 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/Booster.sol#L34 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeTokenMinter.sol#L15 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VirtualBalanceRewardPool.sol#L70 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/token/VeToken.sol#L12 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L79 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L82 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VE3DLocker.sol#L99 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/VeAssetDepositor.sol#L21 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L57 https://github.com/code-423n4/2022-05-vetoken/blob/main/contracts/BaseRewardPool.sol#L73
Declare some public variables as private or internal to save gas
The contracts are all written entirely in solidity. Writing contracts with vyper instead of solidity can save gas.
Source https://twitter.com/eiber_david/status/1515737811881807876
Write some or all of the contracts in vyper to save gas
Some contracts are written with solidity 0.8.7. These contracts do not need to import SafeMath because solidity has safemath checks with standard math operators in solidity 0.8.X. Removing this import saves gas on deployment.
Safemath import example in solidity 0.8.7 contract https://github.com/code-423n4/2022-05-vetoken/blob/2d7cd1f6780a9bcc8387dea8fecfbd758462c152/contracts/BaseRewardPool.sol#L42
Remove safemath import in solidity 0.8.X contracts
#0 - GalloDaSballo
2022-07-14T01:45:38Z
Should save 500 - 1000 gas, feels automated and misses the nuance between avoiding storage and memory