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: 20/96
Findings: 2
Award: $101.35
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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
84.0223 USDC - $84.02
The pragma version used is:
pragma solidity 0.8.10; pragma solidity ^0.8.0;
But recently solidity released a new version with important Bugfixes:
The first one is related to ABI-encoding nested arrays directly from calldata. You can find more information here.
The second bug is triggered in certain inheritance structures and can cause a memory pointer to be interpreted as a calldata pointer or vice-versa. We also have a dedicated blog post about this bug.
Apart from these, there are several minor bug fixes and improvements.
The minimum required version should be 0.8.14
The following methods have a lack checks if the received argument is an address, it's good practice in order to reduce human error to check that the address specified in the constructor or initialize is different than address(0)
.
address(0)
:
The contract NibblVaultFactory
is AccessControl
and Pausable
, so the owner could resign while the contract is paused, causing a Denial of Service. Owner resignation while paused should be avoided.
Affected source code:
encode
instead of encodePacked
for hashigUse of abi.encodePacked
in NibblVaultFactory
is safe, but unnecessary and not recommended. abi.encodePacked
can result in hash collisions when used with two dynamic arguments (string/bytes).
There is also discussion of removing abi.encodePacked
from future versions of Solidity (ethereum/solidity#11593), so using abi.encode
now will ensure compatibility in the future.
Affected source code:
The following code doesn't check the result of the ERC20 calls. ERC20 standard specify that the token can return false if these calls fails, so it's mandatory to check the result of these ERC20 methods.
Reference:
NOTES: The following specifications use syntax from Solidity 0.4.17 (or above) Callers MUST handle false from returns (bool success). Callers MUST NOT assume that false is never returned!
Affected source code for transfer
:
It's possible to lose the ownership under specific circumstances.
Because an human error it's possible to set a new invalid owner. When you want to change the owner's address it's better to propose a new owner, and then accept this ownership with the new wallet.
Affected source code:
The packages used are out of date, it is good practice to use the latest version of these packages:
"@openzeppelin/contracts": "^4.5.0", "@openzeppelin/contracts-upgradeable": "^4.5.0",
Affected source code:
Because to transfer ether the .transfer
method (which is capped at 2300 gas) is used instead of .call
which is limited to the gas provided by the user.
If a contract that has a fallback
method more expensive than 2300 gas, it will be impossible for a contract receive funds from Basket
contract.
Reference:
Affected source code:
If a maximum of time is not used during the update proposal, it is possible that the update will be made at the beginning or during deploy it, and after a few years, the change will be accepted, and users won't be aware of that. It is convenient to use a maximum expiration time of the proposal.
Affected source code:
Token 0
is more or less the owner of the Basket
contract. If this token is transfered to the wrong address, for example address(this)
, this ownership could be losed.
It would be convenient to block the transfer
when the token is 0
and to
is address(this)
(address(0)
it's already checked.).
Affected source code:
Abstract contracts are contracts that have at least one function without its implementation. An instance of an abstract cannot be created.
Reference:
Affected source code:
Wrong token name is used during the initialization of NibblVault.INIT_EIP712
. NibblVault
is used instead of _tokenName
.
Affected source code:
lock
in sell
methodif buy
have lock
, sell
should have it, because the danger is the same.
Affected source code:
#0 - HardlyDifficult
2022-07-03T14:18:14Z
#1 - HardlyDifficult
2022-07-03T14:24:47Z
#2 - HardlyDifficult
2022-07-03T14:30:04Z
#3 - HardlyDifficult
2022-07-04T14:43:29Z
Very good feedback. Recommendations are clear & specific to the Nibbl contracts.
🌟 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
17.3282 USDC - $17.33
Use constant instead of storage for:
UPDATE_TIME
in NibblVaultFactoryData.sol#L6Reduce math operations storing the value in a constant:
2**32
:
Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met)
Starting from Solidity v0.8.4, there is a convenient and gas-efficient way to explain to users why an operation failed through the use of custom errors. Until now, you could already use strings to give more information about failures (e.g., revert("Insufficient funds.");), but they are rather expensive, especially when it comes to deploy cost, and it is difficult to use dynamic information in them.
Custom errors are defined using the error statement, which can be used inside and outside of contracts (including interfaces and libraries).
If it's not possible to use error codes due to the pragma used, it is recommended to reduce the strings to less than 32 bytes.
Affected source code:
Two methods are exposed in the abi for the same value.
getTwavObservations
returns the same value as public twavObservations
:
Remove _defaultAdminRole
var and use DEFAULT_ADMIN_ROLE
:
There are no sense to have an unsafe version of withdrawERC721Unsafe
:
++i
costs less gas compared to i++
or i += 1
++i
costs less gas compared to i++
or i += 1
for unsigned integer, as pre-increment is cheaper (about 5 gas per iteration). This statement is true even with the optimizer enabled.
i++
increments i
and returns the initial value of i
. Which means:
uint i = 1; i++; // == 1 but i == 2
But ++i
returns the actual incremented value:
uint i = 1; ++i; // == 2 and i == 2 too, so no need for a temporary variable
In the first case, the compiler has to create a temporary variable (when used) for returning 1
instead of 2
I suggest using ++i
instead of i++
to increment the value of an uint variable. Same thing for --i
and i--
It is also recommended to not initialize the counter variable and surround the increment with an unchecked
region.
Affected source code:
If a variable is not set/initialized, the default value is assumed (0, false
, 0x0 ... depending on the data type). You are simply wasting gas if you directly initialize it with its default value.
Affected source code:
Move unlocked
close to an address
type and change the value to be a boolean to share the same storage slot:
#0 - mundhrakeshav
2022-06-25T14:03:12Z
Duplicate of #15
#1 - 0x1f8b
2022-06-25T16:03:36Z
Not all of them are included in #15 @mundhrakeshav
#2 - mundhrakeshav
2022-06-25T16:09:55Z
Aah. Storage slot one isn't in #15
#3 - mundhrakeshav
2022-06-29T11:31:54Z