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

1 stars 0 forks source link

Gas Optimizations #116

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

If a variable is not set/initialized, it is assumed to have the default value (0, false, 0x0 etc. depending on the data type). Explicitly initializing it wastes gas.

I would recommend leaving the initialized variables with the default values on the following lines:

nibbl-smartcontracts/contracts/Basket.sol:43:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:70:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:93:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:506:         for (uint256 i = 0; i < _assetAddresses.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:525:         for (uint256 i = 0; i < _assets.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:547:         for (uint256 i = 0; i < _assets.length; i++) {

Prefix Increments cost less gas than postfix increments ++i costs less gas compared to i++ or i += 1 for unsigned integers, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.

I would changing the increment from postfix to prefix in the following lines:

nibbl-smartcontracts/contracts/Basket.sol:43:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:70:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:93:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:506:         for (uint256 i = 0; i < _assetAddresses.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:525:         for (uint256 i = 0; i < _assets.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:547:         for (uint256 i = 0; i < _assets.length; i++) {

Increments Can be Unchecked In Solidity 0.8+, there’s a default overflow check on unsigned integers. Unchecking this saves gas each iteration but sacrifices code readability. Gas optimizing solutions can be found at https://github.com/ethereum/solidity/issues/10695

I would recommend that the following lines be unchecked to optimize gas costs

nibbl-smartcontracts/contracts/Basket.sol:43:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:70:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/Basket.sol:93:       for (uint256 i = 0; i < _tokens.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:506:         for (uint256 i = 0; i < _assetAddresses.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:525:         for (uint256 i = 0; i < _assets.length; i++) {
nibbl-smartcontracts/contracts/NibblVault.sol:547:         for (uint256 i = 0; i < _assets.length; i++) {
mundhrakeshav commented 2 years ago

Duplicate #15