Platform: Code4rena
Start Date: 27/05/2022
Pot Size: $75,000 USDC
Total HM: 20
Participants: 58
Period: 7 days
Judge: GalloDaSballo
Total Solo HM: 15
Id: 131
League: ETH
Rank: 32/58
Findings: 2
Award: $171.81
š Selected for report: 0
š Solo Findings: 0
š Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xNazgul, 0xf15ers, BowTiedWardens, Chom, Funen, Kaiziron, Kumpa, MiloTruck, Picodes, Ruhum, SecureZeroX, Sm4rty, SmartSek, StyxRave, WatchPug, Waze, asutorufos, bardamu, berndartmueller, c3phas, catchup, cccz, codexploder, cryptphi, defsec, delfin454000, dipp, fatherOfBlocks, gzeon, hake, hansfriese, hyh, masterchief, oyc_109, sach1r0, sashik_eth, shenwilly, simon135, unforgiven
113.8755 USDC - $113.88
No check on address zero can cause logic errors and lost of funds https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/InflationManager.sol#L221 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/InflationManager.sol#L221 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/zaps/PoolMigrationZap.sol#L52
Add more comments on burnFees function and natspec comments https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/RewardHandler.sol#L35
Very hard to read code and its very packed together.its so compacted that my vscode visual extension cant read if its state or memory variable https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/RewardHandler.sol#L36-L48 ā-------------------------------------- if (IERC20(token).allowance(address(this), spender) > 0) return; IERC20(token).safeApprove(spender, type(uint256).max); Just space it out to make it more readable https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/RewardHandler.sol#L63
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/zaps/PoolMigrationZap.sol#L52-L66 if allowance is more then zero then it will return nothing and first return something to help a function that calls this function if this allowance is more than zero it will return nothing and it you cant approve anything its dead code
#0 - GalloDaSballo
2022-06-22T14:44:41Z
Agree with observation about address 0 and adding comments. Rest is opinion, and in lack of a suggested refactoring this is a low quality submission
š Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, Chom, Dravee, Fitraldys, Funen, Kaiziron, MiloTruck, Picodes, Randyyy, RoiEvenHaim, SecureZeroX, Sm4rty, SmartSek, StyxRave, Tadashi, Tomio, Waze, asutorufos, berndartmueller, c3phas, catchup, csanuragjain, defsec, delfin454000, djxploit, fatherOfBlocks, gzeon, hake, hansfriese, oyc_109, robee, sach1r0, sashik_eth, scaraven, simon135
57.93 USDC - $57.93
if just reading the constant it still costs gas .to make it less gas make it a smaller bytes10 then bytes32 because 1 char =1 byte each byte less saves gas. bytes32 internal constant _START_BOOST = "startBoost"; bytes32 internal constant _MAX_BOOST = "maxBoost"; bytes32 internal constant _INCREASE_PERIOD = "increasePeriod"; bytes32 internal constant _WITHDRAW_DELAY = "withdrawDelay"; https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/BkdLocker.sol#L21-L24 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/Controller.sol#L25
Use Custom Errors instead of Revert Strings to save Gas Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met) Source Custom Errors in Solidity: Starting from Solidity v0.8.4, there is a convenient and gas-efficient way to explain to users why an operation failed through the use of custom errors. Until now, you could already use strings to give more information about failures (e.g., revert("Insufficient funds.");), but they are rather expensive, especially when it comes to deploy cost, and it is difficult to use dynamic information in them. Custom errors are defined using the error statement, which can be used inside and outside of contracts (including interfaces and libraries). ROLEmanager.sol 28: require(hasRole(Roles.GOVERNANCE, msg.sender), Error.UNAUTHORIZED_ACCESS); 46: require(getRoleMemberCount(Roles.GOVERNANCE) > 1, Error.CANNOT_REVOKE_ROLE); 112: require(role != Roles.GOVERNANCE, Error.CANNOT_REVOKE_ROLE); 113: require(hasRole(role, account), Error.INVALID_ARGUMENT); https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L104 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L125 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/KeeperGauge.sol#L140 https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/Minter.sol#L152
ā----------------------------------------------
In a require statement it saves gas to make !=0 .Uint variable is anything greater or equal to zero it saves gas to make != 0
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/BkdLocker.sol#L91-L94
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L104
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/KeeperGauge.sol#L140
++i costs less gas compared to i++ or i += 1 ++i costs less gas compared to i++ or i += 1 for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled. i++ increments i and returns the initial value of i. Which means: uint i = 1; i++; // == 1 but i == 2 But ++i returns the actual incremented value: uint i = 1; ++i; // == 2 and i == 2 too, so no need for a temporary variable In the first case, the compiler has to create a temporary variable (when used) for returning 1 instead of 2 epoch++ Change to ++epoch https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/KeeperGauge.sol#L59
Same thing with minus - - Use ā i instead of putting multiple assignment to i i = i - 1; https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/BkdLocker.sol#L140
Uint48 after a bool and bool fills the slot of zeros so uint 48 is waste of gas and it will be cheaper to use uint and uint48 like a mix to make it one slot or after the address because address is 160 bits.
If you want the bool then make uint48 into uint256 to save gas.
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L32
Order:
Address -one slot
Bool -one slot
Uint48-one slot
New Order:
Address -160
Uint48-48 1 slot with 48 remaining
Bool -1slot
Saving:20_000 gas
ā------------------------------------------
Make variable uninitialized to save gas for sstore 20_000 and memory 3 gas
Because by default its already zero
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L64
ā------------------------------------
Reduce the size of error messages (Long revert Strings)
Shortening revert strings to fit in 32 bytes will decrease deployment time gas and will decrease runtime gas when the revert condition is met. Revert strings that are longer than 32 bytes require at least one additional mstore, along with additional overhead for computing memory offset, etc.
1 byte for each character
https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/Minter.sol#L152 In the EVM, there is no opcode for >= or <=. When using greater than or equal, two operations are performed: > and =. Using strict comparison operators hence saves gas require(delay >= _MIN_DELAY, Error.DELAY_TOO_SHORT); Instead use Delay != _MIN_DELAY https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/utils/Preparable.sol#L29 ā------------------------------- Events with 3 fields make indexed to save gas https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/interfaces/vendor/ICvxLocker.sol#L51-L53
Dead code it wastes gas in the code storing type It will never call the approve function https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/RewardHandler.sol#L63
#0 - GalloDaSballo
2022-06-19T14:31:13Z
Disagree as below 32 bytes sized variables incur checks for zero-bytes
Valid but without POC can't give it points
Saves 3 gas per instance
3 * 3 = 9
##Ā ++i costs less gas compared to i++ or i += 1 5 gas per instance
This should save more, about 10 gas
##Ā https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/AmmGauge.sol#L32 Packing will save gas but in lack of runtime math I can't quantify impact
Don't believe this is valid
Agree, saves 6 gas at runtime
Total Gas Saved 30