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: 52/110
Findings: 2
Award: $117.70
🌟 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.346 USDC - $82.35
The most recent version of solidity should be used.
All files state “pragma solidity ^0.8;”. 0.8.17 is already available.
All non library and non interface files should use a fixed version of solidity rather than a floating on.
Each event should use three indexed fields if there are three or more fields in the event.
event FractionalV1VaultCreated( IERC721 indexed token, uint256 indexed tokenId, uint256 vaultId, IERC20 vault, uint256 listPrice ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/FractionalizeProposal.sol#L22-L28
event ZoraAuctionCreated( uint256 auctionId, IERC721 token, uint256 tokenId, uint256 startingPrice, uint40 duration, uint40 timeoutTime ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnZoraProposal.sol#L45-L52
event Won(Party party, IERC721 token, uint256 tokenId, uint256 settledPrice); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/BuyCrowdfundBase.sol#L52
event OpenseaOrderListed( IOpenseaExchange.OrderParameters orderParams, bytes32 orderHash, IERC721 token, uint256 tokenId, uint256 listPrice, uint256 expiry ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L63-L70
event OpenseaOrderSold( bytes32 orderHash, IERC721 token, uint256 tokenId, uint256 listPrice ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L71-L76
event OpenseaOrderExpired( bytes32 orderHash, IERC721 token, uint256 tokenId, uint256 expiry ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L77-L82
event OrderValidated( bytes32 orderHash, address indexed offerer, address indexed zone, IOpenseaExchange.OfferItem[] offer, IOpenseaExchange.ConsiderationItem[] consideration, IOpenseaExchange.OrderType orderType, uint256 startTime, uint256 endTime, bytes32 zoneHash, uint256 salt, bytes32 conduitKey, uint256 counter ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L84-L97
event Burned(address contributor, uint256 ethUsed, uint256 ethOwed, uint256 votingPower); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L82
event Contributed(address contributor, uint256 amount, address delegate, uint256 previousTotalContributions); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L83
event DistributionFeeClaimed( ITokenDistributorParty indexed party, address indexed feeRecipient, TokenType tokenType, address token, uint256 amount ); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/ITokenDistributor.sol#L37-L43
Checking against magic numbers should be avoided. Consider using a properly named constant instead.
if (args.feeBps > 1e4) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/TokenDistributor.sol#L335
if (opts.splitBps > 1e4) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L135
if (opts.feeBps > 1e4) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L280
if (opts.passThresholdBps > 1e4) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L283
if (call.data.length >= 4) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L156
Using 9999 instead of 0.9999e4 would be preferable. Needlessly confusing number formats are a source of subtle errors.
return acceptanceRatio >= 0.9999e4; https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L1066
Running “yarn build” results in a number of warnings (see blow). Finished code must compile without warnings and especially without easily avoidable warnings. Many warnings below should be easily avoidable.
yarn run v1.22.19 $ yarn build:sol && yarn build:ts $ forge build --extra-output storageLayout [⠰] Compiling... [⠘] Compiling 126 files with 0.8.17 [⠰] Solc 0.8.17 finished in 18.31s Compiler run successful (with warnings) warning[3628]: Warning: This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function. --> contracts/utils/Proxy.sol:8:1: | 8 | contract Proxy { | ^ (Relevant source part starts here and spans across multiple lines). Note: The payable fallback function is defined here. --> contracts/utils/Proxy.sol:25:5: | 25 | fallback() external payable { | ^ (Relevant source part starts here and spans across multiple lines).
warning[9302]: Warning: Return value of low-level calls not used. --> sol-tests/utils/Implementation.t.sol:24:9: | 24 | address(this).call(abi.encodeCall(this.initialize, ())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning[5740]: Warning: Unreachable code. --> contracts/crowdfund/CrowdfundNFT.sol:52:5: | 52 | {} | ^^
warning[5740]: Warning: Unreachable code. --> contracts/crowdfund/CrowdfundNFT.sol:59:5: | 59 | {} | ^^
warning[5740]: Warning: Unreachable code. --> contracts/crowdfund/CrowdfundNFT.sol:66:5: | 66 | {} | ^^
warning[5740]: Warning: Unreachable code. --> contracts/crowdfund/CrowdfundNFT.sol:73:5: | 73 | {} | ^^
warning[5740]: Warning: Unreachable code. --> contracts/crowdfund/CrowdfundNFT.sol:80:5: | 80 | {} | ^^
warning[5805]: Warning: "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed. --> sol-tests/utils/Implementation.t.sol:24:43: | 24 | address(this).call(abi.encodeCall(this.initialize, ())); | ^^^^
$ tsc -b Done in 19.96s.
=========================================================================
require(msg.sender == address(this)); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/utils/ReadOnlyDelegateCall.sol#L20
require(proposalType != ProposalType.Invalid); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ProposalExecutionEngine.sol#L246
require(uint8(proposalType) < uint8(ProposalType.NumProposalTypes)); https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ProposalExecutionEngine.sol#L247
🌟 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.3505 USDC - $35.35
Pre-increment uses a little less gas.
for (uint256 i; i < hosts.length; i++) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L62
Array length should be cached instead of requesting it over and over in a for loop. The cost per iteration depends on the array type, 100 gas for storage, 3 each for memory and calldata. Caching the value costs only 3 gas.
for (uint256 i; i < hosts.length; i++) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L62
for (uint256 i = 0; i < hadPreciouses.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L52
for (uint256 i = 0; i < calls.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L61
for (uint256 i = 0; i < hadPreciouses.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L78
for (uint256 i = 0; i < infos.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/TokenDistributor.sol#L230
for (uint256 i = 0; i < infos.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/TokenDistributor.sol#L239
for (uint256 i = 0; i < fees.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L291
for (uint256 i = 0; i < contributors.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L180
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L300
for (uint256 i=0; i < opts.hosts.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L306
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/LibProposal.sol#L14
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/LibProposal.sol#L32
Using UINT256(1) for true and UINT256(2) for false costs less gas than using boolean variables.
bool public emergencyExecuteDisabled; https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L197
mapping(address => bool) public isHost; https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L207
Non-const variables should not be initialized to their default value. Just using the default costs less gas. For example use: uint256 abc; Instead of: uint256 abc=0;
for (uint256 i = 0; i < hadPreciouses.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L52
for (uint256 i = 0; i < calls.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L61
for (uint256 i = 0; i < hadPreciouses.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ArbitraryCallsProposal.sol#L78
for (uint256 i = 0; i < infos.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/TokenDistributor.sol#L230
for (uint256 i = 0; i < infos.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/distribution/TokenDistributor.sol#L239
for (uint256 i = 0; i < fees.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/ListOnOpenseaProposal.sol#L291
for (uint256 i = 0; i < contributors.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L180
for (uint256 i = 0; i < numContributions; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L242
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L300
for (uint256 i = 0; i < numContributions; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/crowdfund/Crowdfund.sol#L348
for (uint256 i=0; i < opts.hosts.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L306
uint256 low = 0; https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/party/PartyGovernance.sol#L432
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/LibProposal.sol#L14
for (uint256 i = 0; i < preciousTokens.length; ++i) { https://github.com/PartyDAO/party-contracts-c4/tree/main/contracts/proposals/LibProposal.sol#L32