PartyDAO contest - Tomo'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: 58/110

Findings: 2

Award: $117.69

🌟 Selected for report: 0

🚀 Solo Findings: 0

QA

✅ L-1: require() should be used instead of assert()

📝 Description

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

💡 Recommendation

You should change from assert() to require()

🔍 Findings:

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L385 assert(tokenType == TokenType.Erc20);

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L411 assert(tokenType == TokenType.Erc20);

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L504 assert(tokenType == ITokenDistributor.TokenType.Erc20);

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L179 assert(false); // Will not be reached.

party-contracts-c4/blob/main/contracts/proposals/FractionalizeProposal.sol#L67 assert(vault.balanceOf(address(this)) == supply);

party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol#L221 assert(step == ListOnOpenseaStep.ListedOnOpenSea);

party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol#L302 assert(SEAPORT.validate(orders));

party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol#L120 assert(step == ZoraStep.ListedOnZora);

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L142 assert(currentInProgressProposalId == 0);

party-contracts-c4/blob/main/contracts/utils/ReadOnlyDelegateCall.sol#L30 assert(false);

✅ N-1: Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

📝 Description

Expressions for constant values such as a call to keccak256(), should use immutable rather than constant

💡 Recommendation

You should use immutable instead of constant

🔍 Findings:

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L80 uint256 private constant _STORAGE_SLOT = uint256(keccak256('ProposalExecutionEngine.Storage'));

party-contracts-c4/blob/main/contracts/proposals/ProposalStorage.sol#L19 uint256 private constant SHARED_STORAGE_SLOT = uint256(keccak256("ProposalStorage.SharedProposalStorage"));

✅ N-2: Non-library/interface files should use fixed compiler versions, not floating ones

📝 Description

Non-library/interface files should use fixed compiler versions, not floating ones

💡 Recommendation

Delete the floating keyword ^.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/AuctionCrowdfund.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/crowdfund/BuyCrowdfund.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/crowdfund/BuyCrowdfundBase.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/crowdfund/CrowdfundFactory.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/distribution/ITokenDistributor.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/distribution/ITokenDistributorParty.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/gatekeepers/IGateKeeper.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/globals/IGlobals.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/party/IPartyFactory.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/party/Party.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/party/PartyFactory.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/FractionalizeProposal.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/IProposalExecutionEngine.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/ProposalStorage.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/vendor/FractionalV1.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/vendor/IOpenseaConduitController.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/proposals/vendor/IOpenseaExchange.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/renderers/DummyERC721Renderer.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/renderers/IERC721Renderer.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/ERC1155Receiver.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/ERC721Receiver.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/IERC1155.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/IERC20.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/IERC721.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/tokens/IERC721Receiver.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/utils/EIP165.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/utils/Implementation.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/utils/Proxy.sol#L2 pragma solidity ^0.8;

party-contracts-c4/blob/main/contracts/utils/ReadOnlyDelegateCall.sol#L2 pragma solidity ^0.8;

✅ N-3: Variable names that consist of all capital letters should be reserved for constant/immutable variables

📝 Description

Variable names that consist of all capital letters should be reserved for constant/immutable variables

💡 Recommendation

Variables that are not constant/immutable should be declared in lower case

🔍 Findings:

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L189 uint256 constant private UINT40_HIGH_BIT = 1 << 39;

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L190 uint96 constant private VETO_VALUE = uint96(int96(-1));

✅ N-4: Open Todos

📝 Description

Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment

💡 Recommendation

Delete TODO keyword

🔍 Findings:

party-contracts-c4/blob/main/contracts/renderers/DummyERC721Renderer.sol#L8 // TODO: make this human readable

Gas Optimization

✅ G-1: Don't Initialize Variables with Default Value

📝 Description

Uninitialized variables are assigned with the types default value. Explicitly initializing a variable with it's default value costs unnecesary gas. Not overwriting the default for stack variables saves 8 gas. Storage and memory variables have larger savings

💡 Recommendation

Delete useless variable declarations to save gas.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L180 for (uint256 i = 0; i < contributors.length; ++i) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L242 for (uint256 i = 0; i < numContributions; ++i) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L300 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L348 for (uint256 i = 0; i < numContributions; ++i) {

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L230 for (uint256 i = 0; i < infos.length; ++i) {

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L239 for (uint256 i = 0; i < infos.length; ++i) {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L306 for (uint256 i=0; i < opts.hosts.length; ++i) {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L432 uint256 low = 0;

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L52 for (uint256 i = 0; i < hadPreciouses.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L61 for (uint256 i = 0; i < calls.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L78 for (uint256 i = 0; i < hadPreciouses.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/LibProposal.sol#L14 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/LibProposal.sol#L32 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol#L291 for (uint256 i = 0; i < fees.length; ++i) {

✅ G-2: Cache Array Length Outside of Loop

📝 Description

Caching the array length outside a loop saves reading it on each iteration, as long as the array's length is not changed during the loop. You save 3 gas by not reading array.length - 3 gas per instance - 27 gas saved

💡 Recommendation

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L62 for (uint256 i; i < hosts.length; i++) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L180 for (uint256 i = 0; i < contributors.length; ++i) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L300 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L230 for (uint256 i = 0; i < infos.length; ++i) {

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L239 for (uint256 i = 0; i < infos.length; ++i) {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L306 for (uint256 i=0; i < opts.hosts.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L52 for (uint256 i = 0; i < hadPreciouses.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L61 for (uint256 i = 0; i < calls.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L78 for (uint256 i = 0; i < hadPreciouses.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/LibProposal.sol#L14 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/LibProposal.sol#L32 for (uint256 i = 0; i < preciousTokens.length; ++i) {

party-contracts-c4/blob/main/contracts/proposals/ListOnOpenseaProposal.sol#L291 for (uint256 i = 0; i < fees.length; ++i) {

✅ G-3: Use != 0 instead of > 0 for Unsigned Integer Comparison

📝 Description

Use != 0 when comparing uint variables to zero, which cannot hold values below zero

💡 Recommendation

You should change from > 0 to !=0.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L144 if (initialBalance > 0) {

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L471 if (votingPower > 0) {

✅ G-4: Use Shift Right/Left instead of Division/Multiplication if possible

📝 Description

A division/multiplication by any number x being a power of 2 can be calculated by shifting log2(x) to the right/left. While the DIV opcode uses 5 gas, the SHR opcode only uses 3 gas. urthermore, Solidity's division operation also includes a division-by-0 prevention which is bypassed using shifting.

💡 Recommendation

You should change multiplication and division by powers of two to bit shift.

🔍 Findings:

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L434 uint256 mid = (low + high) / 2;

✅ G-5: Use assembly balance ETH

📝 Description

You can save 159 gas per instance if using assembly to check for balance of address

💡 Recommendation

Please follow this link to make corrections

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L143 uint96 initialBalance = address(this).balance.safeCastUint256ToUint96();

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L199 // We cannot use address(this).balance - msg.value as the previous

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L111 currentTokenBalance: address(this).balance,

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L501 { value: address(this).balance }(this, feeRecipient, feeBps);

✅ G-6: Use assembly to hash

📝 Description

See this issue You can save about 5000 gas per instance in deploying contracrt. You can save about 80 gas per instance if using assembly to execute the function.

💡 Recommendation

Please follow this link to make corrections

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L331 mstore(opts, keccak256(add(mload(opts), 0x20), mul(mload(mload(opts)), 32)))

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L333 h := keccak256(opts, 0xC0)

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L397 keccak256(info, 0xe0),

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L405 bytes32 dataHash = keccak256(proposal.proposalData);

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L412 proposalHash := keccak256(proposal, 0x60)

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L1114 mstore(0x00, keccak256(

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L1118 mstore(0x20, keccak256(

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L1122 h := keccak256(0x00, 0x40)

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L121 bytes32 resultHash = keccak256(r);

party-contracts-c4/blob/main/contracts/proposals/ListOnZoraProposal.sol#L184 bytes32 errHash = keccak256(errData);

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L80 uint256 private constant _STORAGE_SLOT = uint256(keccak256('ProposalExecutionEngine.Storage'));

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L145 keccak256(params.progressData),

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L150 bytes32 progressDataHash = keccak256(params.progressData);

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L178 stor.nextProgressDataHash = keccak256(nextProgressData);

party-contracts-c4/blob/main/contracts/proposals/ProposalStorage.sol#L19 uint256 private constant SHARED_STORAGE_SLOT = uint256(keccak256("ProposalStorage.SharedProposalStorage"));

✅ G-7: Empty blocks should be removed or emit something

📝 Description

The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting.

💡 Recommendation

Empty blocks should be removed or emit something (The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/AuctionCrowdfund.sol#L144 receive() external payable {}

party-contracts-c4/blob/main/contracts/party/Party.sol#L47 receive() external payable {}

✅ G-8: Functions guaranteed to revert when called by normal users can be marked payable

📝 Description

See this issue If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost Saves 2400 gas per instance in deploying contracrt. Saves about 20 gas per instance if using assembly to executing the function.

💡 Recommendation

You should add the keyword payable to those functions.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/AuctionCrowdfund.sol#L113 onlyConstructor

party-contracts-c4/blob/main/contracts/crowdfund/AuctionCrowdfund.sol#L149 function bid() external onlyDelegateCall {

party-contracts-c4/blob/main/contracts/crowdfund/AuctionCrowdfund.sol#L198 onlyDelegateCall

party-contracts-c4/blob/main/contracts/crowdfund/BuyCrowdfund.sol#L71 onlyConstructor

party-contracts-c4/blob/main/contracts/crowdfund/BuyCrowdfundBase.sol#L99 onlyDelegateCall

party-contracts-c4/blob/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L86 onlyConstructor

party-contracts-c4/blob/main/contracts/crowdfund/CollectionBuyCrowdfund.sol#L121 onlyHost(governanceOpts.hosts)

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L305 onlyPartyDao

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L306 onlyIfEmergencyActionsAllowed

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L319 onlyPartyDao

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L320 onlyIfEmergencyActionsAllowed

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L327 function disableEmergencyActions() onlyPartyDao external {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L27 function transferMultiSig(address newMultiSig) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L59 function setBytes32(uint256 key, bytes32 value) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L63 function setUint256(uint256 key, uint256 value) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L67 function setAddress(uint256 key, address value) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L71 function setIncludesBytes32(uint256 key, bytes32 value, bool isIncluded) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L75 function setIncludesUint256(uint256 key, uint256 value, bool isIncluded) external onlyMultisig {

party-contracts-c4/blob/main/contracts/globals/Globals.sol#L79 function setIncludesAddress(uint256 key, address value, bool isIncluded) external onlyMultisig {

party-contracts-c4/blob/main/contracts/party/Party.sol#L35 onlyConstructor

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L451 function delegateVotingPower(address delegate) external onlyDelegateCall {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L458 function abdicate(address newPartyHost) external onlyHost onlyDelegateCall {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L489 onlyActiveMember

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L490 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L528 onlyActiveMember

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L529 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L564 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L616 function veto(uint256 proposalId) external onlyHost onlyDelegateCall {

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L663 onlyActiveMember

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L664 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L724 onlyActiveMember

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L725 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L790 onlyPartyDao

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L791 onlyWhenEmergencyExecuteAllowed

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L792 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L800 function disableEmergencyExecute() external onlyPartyDaoOrHost onlyDelegateCall {

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L126 onlyMinter

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L127 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L139 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L150 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L161 onlyDelegateCall

party-contracts-c4/blob/main/contracts/party/PartyGovernanceNFT.sol#L169 function abdicate() external onlyMinter onlyDelegateCall {

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L102 onlyDelegateCall

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L118 onlyDelegateCall

party-contracts-c4/blob/main/contracts/proposals/ProposalExecutionEngine.sol#L185 onlyDelegateCall

✅ G-9: Use x=x+y instad of x+=y

📝 Description

You can save about 35 gas per instance if you change from x+=y**** to x=x+y This works equally well for subtraction, multiplication and division.

💡 Recommendation

You should change from x+=y to x=x+y.

🔍 Findings:

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L243 ethContributed += contributions[i].amount;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L352 ethOwed += c.amount;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L355 ethUsed += c.amount;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L359 ethUsed += partialEthUsed;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L374 votingPower += (splitBps_ * totalEthUsed + (1e4 - 1)) / 1e4; // round up

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L411 totalContributions += amount;

party-contracts-c4/blob/main/contracts/crowdfund/Crowdfund.sol#L427 lastContribution.amount += amount;

party-contracts-c4/blob/main/contracts/distribution/TokenDistributor.sol#L381 _storedBalances[balanceId] -= amount;

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L595 values.votes += votingPower;

party-contracts-c4/blob/main/contracts/party/PartyGovernance.sol#L959 newDelegateDelegatedVotingPower -= oldSnap.intrinsicVotingPower;

party-contracts-c4/blob/main/contracts/proposals/ArbitraryCallsProposal.sol#L72 ethAvailable -= calls[i].value;

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