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 #155

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

Gas Optimizations #155

code423n4 opened this issue Jun 24, 2022 · 1 comment
Labels
bug Something isn't working duplicate This issue or pull request already exists G (Gas Optimization)

Comments

@code423n4
Copy link
Contributor

  1. Expressions for constant values such as a call to KECCAK256(), should use IMMUTABLE rather than constant

NibblVault.sol Line 51.
bytes32 private constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

EIP712Base.sol Line 7
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(

AccessControlMechanism.sol Line 12
bytes32 public constant FEE_ROLE = keccak256("FEE_ROLE");

AccessControlMechanism.sol Line 13
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

AccessControlMechanism.sol Line 14
bytes32 public constant IMPLEMENTER_ROLE = keccak256("IMPLEMENTER_ROLE");

  1. Reordering variables save slots.
    NibblVault.sol Line 28. Move the sentence uint32 private constant primaryReserveRatio = 200_000; and uint32 public secondaryReserveRatio; after the sentence address public curator; allow to save 2 slots.

  2. Operators <= or >= cost more gas than operator < or >. Change all <= / >= operators for < / > and remember to increse / decrese in consecuence to maintain the logic (example, a <= b for a < b+1).

NibblVault.sol Line 184
require(_secondaryReserveRatio <= primaryReserveRatio, "NibblVault: Excess initial funds");

NibblVault.sol Line 185
require(_secondaryReserveRatio >= MIN_SECONDARY_RESERVE_RATIO, "NibblVault: secResRatio too low");

NibblVault.sol Line 325
require(_minAmtOut <= _purchaseReturn, "NibblVault: Return too low");

NibblVault.sol Line 351
require(_secondaryReserveBalance - _saleReturn >= MIN_SECONDARY_RESERVE_BALANCE, "NibblVault: Excess sell");

NibblVault.sol Linea 387
require(_saleReturn >= _minAmtOut, "NibblVault: Return too low");

NibblVault.sol Line 404
require(_buyoutBid >= _currentValuation, "NibblVault: Bid too low");

  1. i++ cost more gas than ++i. Change in for-loops i++ for ++i

NibblVault.sol Line 506
for (uint256 i = 0; i < _assetAddresses.length; i++) {

NibblVault.sol Line 525
for (uint256 i = 0; i < _assets.length; i++) {

NibblVault.sol Line 547
for (uint256 i = 0; i < _assets.length; i++) {

  1. Array length should not be looked up in every loop of a for-loop. Storage array length checks incur an extra Gwarmaccess (100 gas) PER-LOOP. Store the array length in a variable and use it in the for loop

NibblVault.sol Line 507. for (uint256 i = 0; i < _assetAddresses.length; i++)
NibblVault.sol Line 525. for (uint256 i = 0; i < _assets.length; i++)
NibblVault.sol Line 547. for (uint256 i = 0; i < _assets.length; i++)
Basket.sol Line 43 for (uint256 i = 0; i < _tokens.length; i++)
Basket.sol Line 70 for (uint256 i = 0; i < _tokens.length; i++)
Basket.sol Line 93 for (uint256 i = 0; i < _tokens.length; i++)

  1. Require strings longer than 32 bytes cost extra gas. Shorten the size of the following strings.

NibblVaultFactory.sol line 48 require(msg.value >= MIN_INITIAL_RESERVE_BALANCE, "NibblVaultFactory: Initial reserve balance too low");

NibblVaultFactory.sol line 49 require(IERC721(_assetAddress).ownerOf(_assetTokenID) == msg.sender, "NibblVaultFactory: Invalid sender");

NibblVaultFactory.sol line 131 require(feeToUpdateTime != 0 && block.timestamp >= feeToUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

NibblVaultFactory.sol line 141 require(_newFee <= MAX_ADMIN_FEE, "NibblVaultFactory: Fee value greater than MAX_ADMIN_FEE");

NibblVaultFactory.sol line 149 require(feeAdminUpdateTime != 0 && block.timestamp >= feeAdminUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

NibblVaultFactory.sol line 166 require(vaultUpdateTime != 0 && block.timestamp >= vaultUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

  1. Require instead of &&. Split of conditions of an require sentence in different requires sentences can save gas.

NibblVaultFactory.sol Line 107 require(basketUpdateTime != 0 && block.timestamp >= basketUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

NibblVaultFactory.sol Line 131 require(feeToUpdateTime != 0 && block.timestamp >= feeToUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

NibblVaultFactory.sol Line 149 require(feeAdminUpdateTime != 0 && block.timestamp >= feeAdminUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

NibblVaultFactory.sol Line 166 require(vaultUpdateTime != 0 && block.timestamp >= vaultUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");

  1. VAR1 += VAR2 is more expensive than VAR1 = VAR1 + VAR2

NibblVault.sol Line 219 feeAccruedCurator += _feeCurator;

NibblVault.sol Line 225 secondaryReserveBalance += _feeCurve;

NibblVault.sol Line 242 feeAccruedCurator += _feeCurator;

NibblVault.sol Line 320 secondaryReserveBalance += _lowerCurveDiff;

NibblVault.sol Line 322 _purchaseReturn += _buyPrimaryCurve(msg.value - _lowerCurveDiff, _totalSupply + _purchaseReturn);

NibblVault.sol Line 383 _saleReturn += _sellSecondaryCurve(_amtIn - _tokensPrimaryCurve, _initialTokenSupply);

NibblVault.sol Line 428 unsettledBids[bidder] += _buyoutValuationDeposit;

NibblVault.sol Line 429 totalUnsettledBids += _buyoutValuationDeposit;

  1. Default value initialization. If a variable is not initialized, it’s assumed to have the default value. Explicity initializing with its default value waste gas.

NibblVault.sol line 506 for (uint256 i = 0; i < _assetAddresses.length; i++)
NibblVault.sol line 525 for (uint256 i = 0; i < _assets.length; i++)
NibblVault.sol line 547 for (uint256 i = 0; i < _assets.length; i++)
Basket.sol line 43 for (uint256 i = 0; i < _tokens.length; i++)
Basket.sol line 70 for (uint256 i = 0; i < _tokens.length; i++)
Basket.sol line 93 for (uint256 i = 0; i < _tokens.length; i++)

  1. i++ should be unchecked when it’s not possible for then to overflow, as is the case for for-loops

NibblVault.sol Line 415 due to condition of 414
NibblVault.sol Line 319 due to condition of 311
NibblVault.sol Line 378 due to condition of 373
NibblVault.sol Line 506 (for statement)
NibblVault.sol Line 525 (for statement)
NibblVault.sol Line 547 (for statement)
Basket.sol line 43 (for statement)
Basket.sol line 70 (for statement)
Basket.sol line 93 (for statement)

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Jun 24, 2022
code423n4 added a commit that referenced this issue Jun 24, 2022
@mundhrakeshav mundhrakeshav added the duplicate This issue or pull request already exists label Jun 26, 2022
@mundhrakeshav
Copy link
Collaborator

Duplicate #2, #3, #6, #7, #8, #82

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists G (Gas Optimization)
Projects
None yet
Development

No branches or pull requests

2 participants