Platform: Code4rena
Start Date: 21/06/2022
Pot Size: $30,000 USDC
Total HM: 12
Participants: 96
Period: 3 days
Judge: HardlyDifficult
Total Solo HM: 5
Id: 140
League: ETH
Rank: 3/96
Findings: 3
Award: $2,424.37
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 Selected for report: reassor
2339.3444 USDC - $2,339.34
https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Utilities/NibblVaultFactoryData.sol#L6 https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVaultFactory.sol#L158-L169 https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L37
User can buy out NFT by initiating the process through initiateBuyout
, then he has to wait BUYOUT_DURATION
which is 5 days and if the buyout will not get rejected he can claim the NFT. During that period bidder cannot cancel the process. The issue is that since NibblVault
is used through proxy it is possible to change its implementation through administrative functionality in NibblVaultFactory
and the timelock for update'ing implementation is only 2 days.
Attack Scenario:
initiateBuyout
vaultImplementation
through proposeNewVaultImplementation
UPDATE_TIME
) uses updateVaultImplementation
and changes the implementationManual Review / VSCode
It is recommended to either implement functionality for bidder to cancel the bid or increase/decrease the UPDATE_TIME
/BUYOUT_DURATION
so the invariant BUYOUT_DURATION < UPDATE_TIME
holds.
#0 - HardlyDifficult
2022-07-03T00:39:48Z
It seems the bidder could be left in a bad state, and updating the thresholds here may be a nice way to maintain expectations. Since this scenario is based on the admin making an undesirable change, this is a Medium risk report.
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0x29A, 0x52, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xkatana, BowTiedWardens, Chom, ElKu, Funen, GalloDaSballo, JC, JMukesh, JohnSmith, Lambda, Limbooo, MadWookie, MiloTruck, Nethermind, Noah3o6, Nyamcil, Picodes, PwnedNoMore, Randyyy, RoiEvenHaim, SmartSek, StErMi, Tadashi, TerrierLover, TomJ, Tomio, Treasure-Seeker, UnusualTurtle, Varun_Verma, Wayne, Waze, _Adam, apostle0x01, asutorufos, berndartmueller, c3phas, catchup, cccz, cloudjunky, codexploder, cryptphi, defsec, delfin454000, dipp, ellahi, exd0tpy, fatherOfBlocks, hansfriese, hyh, joestakey, kebabsec, kenta, masterchief, minhquanym, naps62, oyc_109, pashov, peritoflores, reassor, rfa, robee, sach1r0, saian, sashik_eth, shenwilly, simon135, slywaters, sorrynotsorry, sseefried, unforgiven, xiaoming90, ych18, zuhaibmohd, zzzitron
66.8145 USDC - $66.81
Function NibbleVault.sell
is missing lock
modifier that protects against reentrancy attacks.
NibblVault.sol
:
Manual Review / VSCode
It is recommended to add lock
modifier to sell
function.
Low
Protocol uses proxy pattern for vaults and baskets which requires properly initializing the contracts. The issue is that contract NibblVault
implements function initialize
and contract Basket.sol
implements initialise
. Using different naming convention for critical functionality such as initialization makes it prone to errors and leads to vulnerabilities.
Since openzeppelin
goes with initializer
modifier we recommend using initialize
for Basket.sol
.
NibblVault
uses initialize
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L173Basket
uses initialise
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L23Manual Review / VSCode
It is recommend to change function Basket.initialise
to Basket.initialize
.
Low
Contract NibblVault
charges admin fee in _chargeFee
and _chargeFeeSecondaryCurve
:
if(_adminFeeAmt > 0) { safeTransferETH(_factory, _feeAdmin); //Transfers admin fee to the factory contract }
The check is invalid since there might be edge case (when amount
is very small) that _adminFeeAmt
is positive and _feeAdmin
is equal to 0
. ETH
should be sent when _feeAdmin
is positive.
NibblVault.sol
:
_chargeFee
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L227-L229_chargeFeeSecondaryCurve
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L243-L245Manual Review / VSCode
It is recommended to change the check to:
if(_feeAdmin > 0) { safeTransferETH(_factory, _feeAdmin); //Transfers admin fee to the factory contract }
or even better after gas optimization to:
if(_feeAdmin != 0) { safeTransferETH(_factory, _feeAdmin); //Transfers admin fee to the factory contract }
Low
Multiple contracts do not check for zero addresses which might lead to loss of funds, failed transactions and can break the protocol functionality.
NibblVaultFactory.sol
:
_vaultImplementation
, _feeTo
, _admini
and _basketImplementation
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L23_curator
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L40_curator
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L80_newBasketImplementation
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L99_newFeeAddress
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L123_newVaultImplementation
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L158NibblVault.sol
:
initialize
for _assetAddress
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L176initialize
for _curator
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L178buy
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L300sell
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L362withdrawUnsettledBids
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L454redeem
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L464redeemCuratorFee
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L474updateCurator
for _newCurator
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L485withdrawERC721
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L495withdrawMultipleERC721
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L504withdrawERC20
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L515withdrawMultipleERC20
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L523withdrawERC1155
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L535withdrawMultipleERC1155
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L545safeTransferETH
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L568Basket.sol
:
initialise
for _curator
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L23withdrawERC721
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L35withdrawERC721Unsafe
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L52withdrawERC1155
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L61withdrawETH
for _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L78Manual Review / VSCode
It is recommended to add zero address checks for listed parameters.
Low
Multiple contracts are not implementing events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
NibblVaultFactory.sol
:
proposeNewBasketImplementation
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L99updateBasketImplementation
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L106withdrawAdminFee
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L112proposeNewAdminFeeAddress
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L123updateNewAdminFeeAddress
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L130proposeNewAdminFee
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L140updateNewAdminFee
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L148
8 Missing proposeNewVaultImplementation
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L158updateVaultImplementation
function event - https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L165NibblVault.sol
:
withdrawUnsettledBids
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L454redeem
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L464redeemCuratorFee
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L474updateCurator
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L485withdrawERC721
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L495withdrawERC20
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L515withdrawERC1155
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L535permit
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L552Twav.sol
:
_updateTWAV
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Twav/Twav.sol#L21AccessControlMechanism.sol
:
proposeGrantRole
function event - https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Utilities/AccessControlMechanism.sol#L40-L42Manual Review / VSCode
It is recommended to add missing events to listed functions.
Low
Changing critical addresses such as ownership should be a two-step process where the first transaction (from the old/current address) registers the new address (i.e. grants ownership) and the second transaction (from the new address) replaces the old address with the new one. This gives an opportunity to recover from incorrect addresses mistakenly used in the first step. If not, contract functionality might become inaccessible.
NibblVault.sol
:
curator
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L485-L488Manual Review / VSCode
It is recommended to implement two-step process for changing curator
address.
Non-Critical
Events should index addresses which helps off-chain applications in monitoring the protocol.
Interfaces/INibblVaultFactory.sol:5: event Fractionalise(address assetAddress, uint256 assetTokenID, address proxyVault);
Manual Review / VSCode
It is recommended to add indexing to address
type parameters.
Non-Critical
As different compiler versions have critical behavior specifics if the contract gets accidentally deployed using another compiler version compared to one they tested with, various types of undesired behavior can be introduced.
Utilities/AccessControlMechanism.sol
Interfaces/IAccessControlMechanism.sol
Manual Review / VSCode
Consider locking compiler version, for example pragma solidity 0.8.10.
Non-Critical
Contract NibblVault
implement constant variable primaryReserveRatio
. The variable is constant so it should follow the naming convention for constant variables PRIMARY_RESERVE_RATIO
.
NibblVault.sol
:
Manual Review / VSCode
It is recommended to change name of primaryReserveRatio
to PRIMARY_RESERVE_RATIO
.
Non-Critical
Contracts are missing natspec comments which makes code more difficult to read and prone to errors.
NibblVaultFactory.sol
:
@return
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L29-L38@return
- https://github.com/NibblNFT/nibbl-smartcontracts/blob/49bf364d9e81a554cfdf47ae5cfc3daf52a54ad6/contracts/NibblVaultFactory.sol#L58-L64NibblVault.sol
:
@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L249-L252@param _totalSupply
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L269-L275@param _totalSupply
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L281-L287@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L294-L300@param _totalSupply
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L330-L335@param _totalSupply
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L342-L347@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L355-L362@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L393-L398@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L461-L464@return
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L471-L474Basket.sol
:
@param _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L32-L35@param _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L49-L52@param _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L58-L61@param _to
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L77-L78@param _token
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L84-L85Twav.sol
:
ProxyVault.sol
:
ProxyBasket.sol
:
AccessControlMechanism.sol
:
EIP721Base.sol
:
Manual Review / VSCode
It is recommended to add missing natspec comments.
#0 - HardlyDifficult
2022-07-03T22:56:19Z
#1 - HardlyDifficult
2022-07-04T01:17:16Z
#2 - HardlyDifficult
2022-07-04T18:56:55Z
Great stuff, very clear report
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xf15ers, 0xkatana, 8olidity, ACai, BowTiedWardens, Chandr, Chom, ElKu, Fitraldys, Funen, IgnacioB, JC, Lambda, Limbooo, MiloTruck, Noah3o6, Nyamcil, Picodes, Randyyy, SmartSek, StErMi, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, _Adam, ajtra, c3phas, cRat1st0s, catchup, codexploder, cryptphi, defsec, delfin454000, ellahi, exd0tpy, fatherOfBlocks, hansfriese, joestakey, kebabsec, kenta, m_Rassska, minhquanym, oyc_109, pashov, reassor, rfa, robee, sach1r0, saian, sashik_eth, simon135, slywaters, ych18, ynnad, zuhaibmohd
18.2244 USDC - $18.22
Variable UPDATE_TIME
in NibblVaultFactoryData
cannot be changed and should be set as constant to save gas.
NibblVaultFactoryData.sol
:
Manual Review / VSCode
It is recommended to set UPDATE_TIME
as constant.
Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop.
Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Manual Review / VSCode
It is recommended to cache the array length outside of for loop.
Shortening revert error messages to fit in 32 bytes will decrease gas costs for deployment and gas costs when the revert condition has been met.
NibblVaultFactory.sol:48: require(msg.value >= MIN_INITIAL_RESERVE_BALANCE, "NibblVaultFactory: Initial reserve balance too low"); NibblVaultFactory.sol:49: require(IERC721(_assetAddress).ownerOf(_assetTokenID) == msg.sender, "NibblVaultFactory: Invalid sender"); NibblVaultFactory.sol:107: require(basketUpdateTime != 0 && block.timestamp >= basketUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed"); NibblVaultFactory.sol:131: require(feeToUpdateTime != 0 && block.timestamp >= feeToUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed"); NibblVaultFactory.sol:141: require(_newFee <= MAX_ADMIN_FEE, "NibblVaultFactory: Fee value greater than MAX_ADMIN_FEE"); NibblVaultFactory.sol:149: require(feeAdminUpdateTime != 0 && block.timestamp >= feeAdminUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed"); NibblVaultFactory.sol:166: require(vaultUpdateTime != 0 && block.timestamp >= vaultUpdateTime, "NibblVaultFactory: UPDATE_TIME has not passed");
Manual Review / VSCode
It is recommended to decrease revert messages to maximum 32 bytes.
Usage of custom errors reduces the gas cost.
Contracts that should be using custom errors:
Basket.sol
NibblVaultFactory.sol
NibblVault.sol
Utilities/AccessControlMechanism.sol
Manual Review / VSCode
It is recommended to add custom errors to listed contracts.
Contract NibblVault
packs timestamps to uint32
variables. To set blockTimestamp
value it first runs math operation modulo on block.timestamp
and then casts the result to uint32
. Executing modulo operation in this case is obsolete, uint32
will successfully cast the value to 32bits bits.
NibblVault.sol:303: uint32 _blockTimestamp = uint32(block.timestamp % 2**32); NibblVault.sol:365: uint32 _blockTimestamp = uint32(block.timestamp % 2**32); NibblVault.sol:413: _updateTWAV(_currentValuation, uint32(block.timestamp % 2**32)); NibblVault.sol:445: uint32 _blockTimestamp = uint32(block.timestamp % 2**32);
Manual Review / VSCode
It is recommended to remove % 2**32
math modulo operation.
++i
or --i
costs less gas compared to i++
, i += 1
, i--
or i -= 1
for unsigned integer as pre-increment/pre-decrement is cheaper (about 5 gas per iteration).
Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Manual Review / VSCode
It is recommended to use ++i
or --i
instead of i++
, i += 1
, i--
or i -= 1
to increment value of an unsigned integer variable.
Starting from solidity 0.8.0
there is built-in check for overflows/underflows. This mechanism automatically checks if the variable overflows or underflows and throws an error. Multiple contracts use increments that cannot overflow but consume additional gas for checks.
Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Manual Review / VSCode
It is recommended wrap incrementing with unchecked
block, for example: unchecked { ++i }
or unchecked { --i }
If a variable is not set/initialized, it is assumed to have the default value (0
for uint, false
for bool, address(0)
for addresses). Explicitly initializing it with its default value is an anti-pattern and waste of gas.
Basket.sol:43: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:70: for (uint256 i = 0; i < _tokens.length; i++) { Basket.sol:93: for (uint256 i = 0; i < _tokens.length; i++) { NibblVault.sol:506: for (uint256 i = 0; i < _assetAddresses.length; i++) { NibblVault.sol:525: for (uint256 i = 0; i < _assets.length; i++) { NibblVault.sol:547: for (uint256 i = 0; i < _assets.length; i++) {
Manual Review / VSCode
It is recommended to remove explicit initializations with default values.
When dealing with unsigned integer types, comparisons with != 0
are cheaper than with > 0
.
NibblVault.sol:227: if(_adminFeeAmt > 0) { NibblVault.sol:243: if(_adminFeeAmt > 0) {
Manual Review / VSCode
It is recommended to use != 0
instead of > 0
.
#0 - mundhrakeshav
2022-06-26T17:09:26Z
#2, #3, #6, #7, #8, #9, #15