PartyDAO contest - martin's results

A protocol for buying, using, and selling NFTs as a group.

General Information

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

PartyDAO

Findings Distribution

Researcher Performance

Rank: 56/110

Findings: 2

Award: $117.69

🌟 Selected for report: 0

🚀 Solo Findings: 0

PartyDAO

QA Report

L-01 Use of floating pragma

L-02 require() should be used instead of assert()

There are 8 instances of this issue:

File: contracts/crowdfund/CrowdfundNFT.sol

166: assert(false); // Will not be reached.

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/CrowdfundNFT.sol

File: contracts/proposals/ListOnZoraProposal.sol

120: assert(step == ZoraStep.ListedOnZora);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol

File: contracts/proposals/ProposalExecutionEngine.sol

142: assert(currentInProgressProposalId == 0);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol

File: contracts/distribution/TokenDistributor.sol

385: assert(tokenType == TokenType.Erc20);

411: assert(tokenType == TokenType.Erc20);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol

File: contracts/proposals/ListOnOpenseaProposal.sol

221: assert(step == ListOnOpenseaStep.ListedOnOpenSea);

302: assert(SEAPORT.validate(orders));

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol

File: contracts/party/PartyGovernance.sol

504: assert(tokenType == ITokenDistributor.TokenType.Erc20);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol

L-03 emit function called early

There are 1 instances of this issue:

File: contracts/party/PartyGovernance.sol

497: emit DistributionCreated(tokenType, token, tokenId);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol

N-01 require()/revert() statements should have descriptive reason strings

There are 2 instances of this issue:

File: contracts/proposals/ProposalExecutionEngine.sol

246: require(proposalType != ProposalType.Invalid);

247: require(uint8(proposalType) < uint8(ProposalType.NumProposalTypes));

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol

N-02 Event is missing indexed fields

Each event should use three indexed fields if there are three or more fields

There are 16 instances of this issue:

File: contracts/proposals/ListOnZoraProposal.sol

45: event ZoraAuctionCreated(

53: event ZoraAuctionExpired(uint256 auctionId, uint256 expiry);

54: event ZoraAuctionSold(uint256 auctionId);

55: event ZoraAuctionFailed(uint256 auctionId);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol

File: contracts/proposals/ProposalExecutionEngine.sol

66: event ProposalEngineImplementationUpgraded(address oldImpl, address newImpl);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol

File: contracts/crowdfund/BuyCrowdfundBase.sol

52: event Won(Party party, IERC721 token, uint256 tokenId, uint256 settledPrice);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/BuyCrowdfundBase.sol

File: contracts/proposals/ListOnOpenseaProposal.sol

63: event OpenseaOrderListed(

71: event OpenseaOrderSold(

77: event OpenseaOrderExpired(

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol

File: contracts/crowdfund/Crowdfund.sol

82: event Burned(address contributor, uint256 ethUsed, uint256 ethOwed, uint256 votingPower);

83: event Contributed(address contributor, uint256 amount, address delegate, uint256 previousTotalContributions);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol

File: contracts/party/PartyGovernance.sol

151: event Proposed(

156: event ProposalAccepted(

162: event PartyInitialized(GovernanceOpts opts, IERC721[] preciousTokens, uint256[] preciousTokenIds);

167: event DistributionCreated(ITokenDistributor.TokenType tokenType, address token, uint256 tokenId);

169: event HostStatusTransferred(address oldHost, address newHost);

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol

N-03 Not using the named return variables anywhere in the function is confusing

There are 3 instances of this issue:

File: contracts/party/PartyGovernanceNFT.sol

70: returns (address owner)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol

File: contracts/proposals/ListOnZoraProposal.sol

82: returns (bytes memory nextProgressData)

172: returns (bool sold)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol

N-04 constants should be defined rather than using magic numbers

There are 7 instances of this issue:

File: contracts/distribution/TokenDistributor.sol

335: if (args.feeBps > 1e4) {

352: uint128 fee = supply * args.feeBps / 1e4;

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol

File: contracts/crowdfund/Crowdfund.sol

129: if (opts.governanceOpts.feeBps > 1e4) {

132: if (opts.governanceOpts.passThresholdBps > 1e4) {

135: if (opts.splitBps > 1e4) {

370: votingPower = ((1e4 - splitBps_) * ethUsed) / 1e4;

374: votingPower += (splitBps_ * totalEthUsed + (1e4 - 1)) / 1e4; // round up

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol

#0 - 0xble

2022-09-26T01:59:58Z

Unhelpful bot report with some suggestions that don't make sense.

PartyDAO

Gas Optimisation Report

G-01 The usage of ++i will cost less gas than i++. The same change can be applied to i-- as well.

There are 1 instances of this issue:

File: contracts/crowdfund/CollectionBuyCrowdfund.sol

62: for (uint256 i; i < hosts.length; i++) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/CollectionBuyCrowdfund.sol

G-02 Not using the named return variables when a function returns wastes deployment gas

There are 5 instances of this issue:

File: contracts/party/PartyGovernanceNFT.sol

70: returns (address owner)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol

File: contracts/proposals/ListOnZoraProposal.sol

82: returns (bytes memory nextProgressData)

172: returns (bool sold)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol

File: contracts/distribution/TokenDistributor.sol

406: returns (bytes32 balanceId)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol

File: contracts/proposals/ListOnOpenseaProposal.sol

127: returns (bytes memory nextProgressData)

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol

G-03 It costs more gas to initialize non-constant/non-immutable variables to zero than to let the default of zero be applied

There are 10 instances of this issue:

File: contracts/proposals/ArbitraryCallsProposal.sol

52: for (uint256 i = 0; i < hadPreciouses.length; ++i) {

61: for (uint256 i = 0; i < calls.length; ++i) {

78: for (uint256 i = 0; i < hadPreciouses.length; ++i) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol

File: contracts/distribution/TokenDistributor.sol

230: for (uint256 i = 0; i < infos.length; ++i) {

239: for (uint256 i = 0; i < infos.length; ++i) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol

File: contracts/proposals/ListOnOpenseaProposal.sol

291: for (uint256 i = 0; i < fees.length; ++i) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol

File: contracts/crowdfund/Crowdfund.sol

180: for (uint256 i = 0; i < contributors.length; ++i) {

242: for (uint256 i = 0; i < numContributions; ++i) {

300: for (uint256 i = 0; i < preciousTokens.length; ++i) {

348: for (uint256 i = 0; i < numContributions; ++i) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol

G-04 <x> += <y> costs more gas than <x> = <x> + <y> for state variables

There are 8 instances of this issue:

File: contracts/distribution/TokenDistributor.sol

381: _storedBalances[balanceId] -= amount;

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol

File: contracts/crowdfund/Crowdfund.sol

243: ethContributed += contributions[i].amount;

352: ethOwed += c.amount;

355: ethUsed += c.amount;

359: ethUsed += partialEthUsed;

374: votingPower += (splitBps_ * totalEthUsed + (1e4 - 1)) / 1e4; // round up

411: totalContributions += amount;

427: lastContribution.amount += amount;

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol

G-05 Using > 0 costs less gas than != 0 when used on a uint

There are 2 instances of this issue:

File: contracts/crowdfund/Crowdfund.sol

144: if (initialBalance > 0) {

471: if (votingPower > 0) {

https://github.com/PartyDAO/party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter