Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gas Optimizations #151

Open
code423n4 opened this issue Jun 3, 2022 · 1 comment
Open

Gas Optimizations #151

code423n4 opened this issue Jun 3, 2022 · 1 comment
Labels
bug Something isn't working G (Gas Optimization) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

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

https://github.com/code-423n4/2022-05-backd/blob/8121e5244ca29f87b0763d05a69e7fc654d14f45/protocol/contracts/tokenomics/InflationManager.sol#L25-L28

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

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Jun 3, 2022
code423n4 added a commit that referenced this issue Jun 3, 2022
@chase-manning chase-manning added sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) labels Jun 6, 2022
@GalloDaSballo
Copy link
Collaborator

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.

Disagree as below 32 bytes sized variables incur checks for zero-bytes

Use Custom Errors instead of Revert Strings to save Gas

Valid but without POC can't give it points

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

Saves 3 gas per instance

3 * 3 = 9

## ++i costs less gas compared to i++ or i += 1
5 gas per instance

Same thing with minus - -

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

Make variable uninitialized to save gas for sstore 20_000 and memory 3 gas

Don't believe this is valid

Reduce the size of error messages (Long revert Strings)

Agree, saves 6 gas at runtime

Total Gas Saved
30

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

3 participants