Platform: Code4rena
Start Date: 12/09/2022
Pot Size: $75,000 USDC
Total HM: 19
Participants: 110
Period: 7 days
Judge: HardlyDifficult
Total Solo HM: 9
Id: 160
League: ETH
Rank: 45/110
Findings: 2
Award: $117.74
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Lambda
Also found by: 0x1f8b, 0x4non, 0x52, 0x5rings, 0xDanielC, 0xNazgul, 0xSmartContract, 0xbepresent, Anth3m, Aymen0909, B2, CRYP70, CertoraInc, Ch_301, Chom, ChristianKuri, CodingNameKiki, Deivitto, Funen, JC, JansenC, Jeiwan, KIntern_NA, MasterCookie, MiloTruck, Olivierdem, PaludoX0, R2, RaymondFam, ReyAdmirado, StevenL, The_GUILD, Tomo, Trust, V_B, __141345__, asutorufos, ayeslick, bin2chen, brgltd, bulej93, c3phas, cccz, ch0bu, cryptphi, csanuragjain, d3e4, delfin454000, djxploit, erictee, fatherOfBlocks, gogo, hansfriese, indijanc, ladboy233, leosathya, lukris02, malinariy, martin, pedr02b2, pfapostol, rvierdiiev, slowmoses, smiling_heretic, tnevler, wagmi
82.3755 USDC - $82.38
Findings: require()/revert() strings longer than 32 bytes cost extra gas
Code: contracts/KoansMarketWrapper.sol - line 67, line 92 Contracts/NounsMarketWrapper.sol - line 65, line 90
Explanation:
Findings: REQUIRE() SHOULD BE USED INSTEAD OF ASSERT()
Code: contracts/CrowdfundNFT.sol - line 166 Contracts/TokenDistributor.sol - line 385, line 411 Contracts/ListOnOpenseaProposal.sol - line 221
Explanation:
Prior to solidity version 0.8.0, hitting an assert consumes the remainder of the transaction’s available gas rather than returning it, as require()/revert() do. assert() should be avoided even past solidity version 0.8.0 as its documentation states that “The assert function creates an error of type Panic(uint256). … Properly functioning code should never create a Panic, not even on invalid external input. If this happens, then there is a bug in your contract which you should fix”.
Mitigation: Use of Custom Errors or require
Findings: _SAFEMINT() SHOULD BE USED RATHER THAN _MINT() WHEREVER POSSIBLE
Code: contracts/Crowdfund.sol - line 451 Contracts/PartyGovernance.sol - line 132
Explanation: _mint() is discouraged in favour of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver. Both OpenZeppelin and solmate have versions of this function
Findings: FUNCTION MISSING COMMENTS
Code: Some functions are missing comments. Can lead to confusion for future devs. / readability.
Explanation: contracts/Crowdfund.sol - line 377, line 443, line 490 Contracts/CrowdfundFactory.sol - line 106 Contracts/crowdfundNFT.sol - line 136, line 149, line 159
(More instances than can count)
Findings: Use of Block.timestamp
Code: contract/crowdfund/BuyCrowdfundBase.sol - line 73, line 159
Explanation: Block timestamps should not be used to be the deciding factor whether the _expiry ends. Miners have the ability to adjust timestamps, rearrange tx orders. Which can be dangerous / allows a user to game the system and _Crowdfund.
Mitigation: Use of Block.number, whereby miners are unable to easily manipulate the block number.
Findings: UNUSED/EMPTY RECEIVE()/FALLBACK() FUNCTION
Code: AuctionCrowdfund.sol - line 144,
Explanation: Empty blocks should be removed or emit something / fallback or receive function
If the intention is for the Ether to be used, the function should call another function, otherwise it should revert (e.g. require(msg.sender == address(weth)))
Findings: USE OF FLOATING PRAGMA Code: contracts * - (contract versions)
Explanation: Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
🌟 Selected for report: CertoraInc
Also found by: 0x1f8b, 0x4non, 0x5rings, 0x85102, 0xNazgul, 0xSmartContract, 0xkatana, Amithuddar, Aymen0909, B2, Bnke0x0, CRYP70, Chom, ChristianKuri, CodingNameKiki, Deivitto, Diraco, Fitraldys, Funen, IgnacioB, JAGADESH, JC, Lambda, LeoS, Matin, Metatron, MiloTruck, Noah3o6, Ocean_Sky, Olivierdem, PaludoX0, RaymondFam, ReyAdmirado, Rohan16, Rolezn, Saintcode_, Sm4rty, SnowMan, StevenL, Tomio, Tomo, V_B, Waze, __141345__, ajtra, asutorufos, aysha, brgltd, bulej93, c3phas, ch0bu, d3e4, delfin454000, dharma09, djxploit, erictee, fatherOfBlocks, francoHacker, gianganhnguyen, gogo, got_targ, ignacio, jag, karanctf, ladboy233, leosathya, lukris02, m_Rassska, malinariy, martin, natzuu, pashov, peanuts, peiw, pfapostol, prasantgupta52, robee, simon135, slowmoses, sryysryy, tnevler
35.3567 USDC - $35.36
Findings: ++I COSTS LESS GAS COMPARED TO I++ OR I += 1 (SAME FOR --I VS I-- OR I -= 1)
Code: contracts/CollectionBuyCrowfund.sol - line 632 Contracts/Crowdfund.sol - line 180
Explanation:
Pre-increments and pre-decrements are cheaper.
For a uint256 i variable, the following is true with the Optimizer enabled at 10k:
Increment:
i += 1 is the most expensive form i++ costs 6 gas less than i += 1 ++i costs 5 gas less than i++ (11 gas less than i += 1)
Findings: AN ARRAY’S LENGTH SHOULD BE CACHED TO SAVE GAS IN FOR-LOOPS
Code: contracts/CollectionBuyCrowfund.sol - line 62 Contracts/Crowdfund.sol - line 180, line 300 Contracts/TokenDistributor.sol - 230 Contracts/PartyGovernance.sol - 306
Explanation:
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack. Caching the array length in the stack saves around 3 gas per iteration.
Findings: It costs more gas to initialize non-constant/non-immutable variables to zero than to let the default of zero be applied
Code: Contracts/Crowdfund.sol - line 247, line 307, line 356 Contracts/TokenDistributor.sol - line 230
Explanation:
Not overwriting the default for stack variables saves 8 gas. Storage and memory variables have larger savings
Findings: X += Y COSTS MORE GAS THAN X = X + Y FOR STATE VARIABLES (or is not a state variable)
Code: contracts/Crowdfund.sol - line 427
Explanation:
Findings: MULTIPLICATION/DIVISION BY TWO SHOULD USE BIT SHIFTING
Code: contracts/PartyGovernance.sol - line 434
Explanation: <x> * 2 is equivalent to <x> << 1 and <x> / 2 is the same as <x> >> 1. The MUL and DIV opcodes cost 5 gas, whereas SHL and SHR only cost 3 gas