It is recommended to add lock modifier to sell function.
2. Confusing intialize vs initialise
Risk
Low
Impact
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.
It is recommend to change function Basket.initialise to Basket.initialize.
3. NibblVault incorrect check
Risk
Low
Impact
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.
It is recommended to add zero address checks for listed parameters.
5. Missing events
Risk
Low
Impact
Multiple contracts are not implementing events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
It is recommended to add missing events to listed functions.
6. Critical address change
Risk
Low
Impact
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.
It is recommended to add indexing to address type parameters.
8. The contracts use unlocked pragma
Risk
Non-Critical
Impact
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.
Proof of Concept
(^0.8.0) Utilities/AccessControlMechanism.sol
(^0.8.0) Interfaces/IAccessControlMechanism.sol
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
Consider locking compiler version, for example pragma solidity 0.8.10.
9. Misleading constant variable name
Risk
Non-Critical
Impact
Contract NibblVault implement constant variable primaryReserveRatio. The variable is constant so it should follow the naming convention for constant variables PRIMARY_RESERVE_RATIO.
1. NibblVault sell is missing reentrancy protection
Impact
Function
NibbleVault.sell
is missinglock
modifier that protects against reentrancy attacks.Proof of Concept
NibblVault.sol
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add
lock
modifier tosell
function.2. Confusing intialize vs initialise
Risk
Low
Impact
Protocol uses proxy pattern for vaults and baskets which requires properly initializing the contracts. The issue is that contract
NibblVault
implements functioninitialize
and contractBasket.sol
implementsinitialise
. Using different naming convention for critical functionality such as initialization makes it prone to errors and leads to vulnerabilities.Since
openzeppelin
goes withinitializer
modifier we recommend usinginitialize
forBasket.sol
.Proof of Concept
NibblVault
usesinitialize
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L173Basket
usesinitialise
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/Basket.sol#L23Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommend to change function
Basket.initialise
toBasket.initialize
.3. NibblVault incorrect check
Risk
Low
Impact
Contract
NibblVault
charges admin fee in_chargeFee
and_chargeFeeSecondaryCurve
:The check is invalid since there might be edge case (when
amount
is very small) that_adminFeeAmt
is positive and_feeAdmin
is equal to0
.ETH
should be sent when_feeAdmin
is positive.Proof of Concept
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-L245Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to change the check to:
or even better after gas optimization to:
4. Missing zero address checks
Risk
Low
Impact
Multiple contracts do not check for zero addresses which might lead to loss of funds, failed transactions and can break the protocol functionality.
Proof of Concept
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#L78Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add zero address checks for listed parameters.
5. Missing events
Risk
Low
Impact
Multiple contracts are not implementing events for critical functions. Lack of events makes it difficult for off-chain applications to monitor the protocol.
Proof of Concept
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 MissingproposeNewVaultImplementation
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-L42Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add missing events to listed functions.
6. Critical address change
Risk
Low
Impact
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.
Proof of Concept
NibblVault.sol
:curator
- https://github.com/code-423n4/2022-06-nibbl/blob/8c3dbd6adf350f35c58b31723d42117765644110/contracts/NibblVault.sol#L485-L488Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to implement two-step process for changing
curator
address.7. Missing indexing for events
Risk
Non-Critical
Impact
Events should index addresses which helps off-chain applications in monitoring the protocol.
Proof of Concept
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add indexing to
address
type parameters.8. The contracts use unlocked pragma
Risk
Non-Critical
Impact
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.
Proof of Concept
Utilities/AccessControlMechanism.sol
Interfaces/IAccessControlMechanism.sol
Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
Consider locking compiler version, for example pragma solidity 0.8.10.
9. Misleading constant variable name
Risk
Non-Critical
Impact
Contract
NibblVault
implement constant variableprimaryReserveRatio
. The variable is constant so it should follow the naming convention for constant variablesPRIMARY_RESERVE_RATIO
.Proof of Concept
NibblVault.sol
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to change name of
primaryReserveRatio
toPRIMARY_RESERVE_RATIO
.10. Missing/incomplete natspec comments
Risk
Non-Critical
Impact
Contracts are missing natspec comments which makes code more difficult to read and prone to errors.
Proof of Concept
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
:Tools Used
Manual Review / VSCode
Recommended Mitigation Steps
It is recommended to add missing natspec comments.