code-423n4 / 2022-06-nibbl-findings

1 stars 0 forks source link

Gas Optimizations #82

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

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

File: contracts\Test\UpgradedNibblVault.sol:
45:    bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

File: contracts\Utilities\AccessControlMechanism.sol:   
12:     bytes32 public constant FEE_ROLE = keccak256("FEE_ROLE");
13:     bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
14:     bytes32 public constant IMPLEMENTER_ROLE = keccak256("IMPLEMENTER_ROLE");

Conditions for an Require statement that includes the && operator can be broken down into multiple require statements to conserve gas.

File: contracts\Bancor\BancorFormula.sol:
188:         require(_supply > 0 && _connectorBalance > 0 && _connectorWeight > 0 && _connectorWeight <= MAX_WEIGHT);

219:         require(_supply > 0 && _connectorBalance > 0 && _connectorWeight > 0 && _connectorWeight <= MAX_WEIGHT && _sellAmount <= _supply);

The receive function is not implemented

If the intention is for the Ether to be used, the function should call another function, otherwise it should revert

File: contracts\Basket.sol:
114:     receive() external payable {}

File  contracts\NibblVault.sol:
585:     receive() external payable {}

File  contracts\NibblVaultFactory.sol:  
183:     receive() payable external {    }

File: contracts\Proxy\ProxyBasket.sol:
56:     receive() external payable {    }

File: contracts\Proxy\ProxyVault.sol:
56:     receive() external payable {    }

IT COSTS MORE GAS TO INITIALIZE VARIABLES TO ZERO THAN TO LET THE DEFAULT OF ZERO BE APPLIED

File: contracts\Basket.sol:
43:         for (uint256 i = 0; i < _tokens.length; i++) {
70:         for (uint256 i = 0; i < _tokens.length; i++) {
93:         for (uint256 i = 0; i < _tokens.length; i++) {

File: contracts\NibblVault.sol:
506:         for (uint256 i = 0; i < _assetAddresses.length; i++) {
525:         for (uint256 i = 0; i < _assets.length; i++) {
547:         for (uint256 i = 0; i < _assets.length; i++) {

.LENGTH SHOULD NOT BE LOOKED UP IN EVERY LOOP OF A FOR-LOOP

Even memory arrays incur the overhead of bit tests and bit shifts to calculate the array length. Storage array length checks incur an extra Gwarmaccess (100 gas) PER-LOOP.

File: contracts\Basket.sol:
43:         for (uint256 i = 0; i < _tokens.length; i++) {
70:         for (uint256 i = 0; i < _tokens.length; i++) {
93:         for (uint256 i = 0; i < _tokens.length; i++) {

File: contracts\NibblVault.sol:
506:         for (uint256 i = 0; i < _assetAddresses.length; i++) {
525:         for (uint256 i = 0; i < _assets.length; i++) {
547:         for (uint256 i = 0; i < _assets.length; i++) {
mundhrakeshav commented 2 years ago

Duplicate #2, #3, #6, #8, #34