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: 38/110
Findings: 2
Award: $118.64
🌟 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.3385 USDC - $82.34
approve()
and safeApprove()
should be replaced with safeIncreaseAllowance()
/ safeDecreaseAllowance()
approve()
& safeApprove()
are deprecated and subject to a known front-running attack. Consider using safeIncreaseAllowance()
& safeDecreaseAllowance()
instead.
contracts/proposals/FractionalizeProposal.sol:L53 data.token.approve(address(VAULT_FACTORY), data.tokenId); contracts/proposals/ListOnZoraProposal.sol:L143 token.approve(address(ZORA), tokenId); contracts/proposals/ListOnOpenseaProposal.sol:L256 token.approve(conduit, tokenId); contracts/proposals/ListOnOpenseaProposal.sol:L367 token.approve(address(0), tokenId);
require()
should be used instead of assert()
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”.
contracts/distribution/TokenDistributor.sol:L385 assert(tokenType == TokenType.Erc20); contracts/distribution/TokenDistributor.sol:L411 assert(tokenType == TokenType.Erc20); contracts/utils/ReadOnlyDelegateCall.sol:L30 assert(false); contracts/party/PartyGovernance.sol:L504 assert(tokenType == ITokenDistributor.TokenType.Erc20); contracts/party/PartyGovernanceNFT.sol:L179 assert(false); // Will not be reached. contracts/proposals/FractionalizeProposal.sol:L67 assert(vault.balanceOf(address(this)) == supply); contracts/proposals/ListOnZoraProposal.sol:L120 assert(step == ZoraStep.ListedOnZora); contracts/proposals/ListOnOpenseaProposal.sol:L221 assert(step == ListOnOpenseaStep.ListedOnOpenSea); contracts/proposals/ListOnOpenseaProposal.sol:L302 assert(SEAPORT.validate(orders)); contracts/proposals/ProposalExecutionEngine.sol:L142 assert(currentInProgressProposalId == 0); contracts/crowdfund/CrowdfundNFT.sol:L166 assert(false); // Will not be reached.
While floating pragmas make sense for libraries to allow them to be included with multiple different versions of applications, it may be a security risk for application implementations.
A known vulnerable compiler version may accidentally be selected or security tools might fall-back to an older compiler version ending up checking a different EVM compilation that is ultimately deployed on the blockchain.
It is recommended to pin to a concrete compiler version.
contracts/distribution/ITokenDistributorParty.sol:L2 pragma solidity ^0.8; contracts/distribution/ITokenDistributor.sol:L2 pragma solidity ^0.8; contracts/distribution/TokenDistributor.sol:L2 pragma solidity ^0.8; contracts/utils/Proxy.sol:L2 pragma solidity ^0.8; contracts/utils/LibSafeCast.sol:L2 pragma solidity ^0.8; contracts/utils/ReadOnlyDelegateCall.sol:L2 pragma solidity ^0.8; contracts/utils/LibAddress.sol:L2 pragma solidity ^0.8; contracts/utils/LibERC20Compat.sol:L2 pragma solidity ^0.8; contracts/utils/Implementation.sol:L2 pragma solidity ^0.8; contracts/utils/LibRawResult.sol:L2 pragma solidity ^0.8; contracts/utils/LibSafeERC721.sol:L2 pragma solidity ^0.8; contracts/utils/EIP165.sol:L2 pragma solidity ^0.8; contracts/globals/IGlobals.sol:L2 pragma solidity ^0.8; contracts/globals/Globals.sol:L2 pragma solidity ^0.8; contracts/party/Party.sol:L2 pragma solidity ^0.8; contracts/party/PartyGovernance.sol:L2 pragma solidity ^0.8; contracts/party/PartyFactory.sol:L2 pragma solidity ^0.8; contracts/party/IPartyFactory.sol:L2 pragma solidity ^0.8; contracts/party/PartyGovernanceNFT.sol:L2 pragma solidity ^0.8; contracts/renderers/DummyERC721Renderer.sol:L2 pragma solidity ^0.8; contracts/gatekeepers/IGateKeeper.sol:L2 pragma solidity ^0.8; contracts/proposals/FractionalizeProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ProposalStorage.sol:L2 pragma solidity ^0.8; contracts/proposals/ListOnZoraProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ArbitraryCallsProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/LibProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/IProposalExecutionEngine.sol:L2 pragma solidity ^0.8; contracts/proposals/ListOnOpenseaProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ProposalExecutionEngine.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/FractionalV1.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/IOpenseaExchange.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/IOpenseaConduitController.sol:L2 pragma solidity ^0.8; contracts/market-wrapper/IMarketWrapper.sol:L2 pragma solidity ^0.8; contracts/vendor/markets/IZoraAuctionHouse.sol:L2 pragma solidity ^0.8; contracts/tokens/ERC721Receiver.sol:L2 pragma solidity ^0.8; contracts/tokens/ERC1155Receiver.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC721.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC1155.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC20.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC721Receiver.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CrowdfundNFT.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CollectionBuyCrowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CrowdfundFactory.sol:L2 pragma solidity ^0.8; contracts/crowdfund/BuyCrowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/Crowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/BuyCrowdfundBase.sol:L2 pragma solidity ^0.8; contracts/crowdfund/AuctionCrowdfund.sol:L2 pragma solidity ^0.8;
require()
/revert()
statements should have descriptive strings.Consider adding descriptive strings in require()
/revert()
.
contracts/utils/ReadOnlyDelegateCall.sol:L20 require(msg.sender == address(this)); contracts/proposals/ProposalExecutionEngine.sol:L246 require(proposalType != ProposalType.Invalid); contracts/proposals/ProposalExecutionEngine.sol:L247 require(uint8(proposalType) < uint8(ProposalType.NumProposalTypes));
_safemint()
should be used rather than _mint()
wherever possible_mint()
is discouraged in favor of _safeMint()
which ensures that the recipient is either an EOA or implements IERC721Receiver
. Both OpenZeppelin and solmate have versions of this function
contracts/party/PartyGovernanceNFT.sol:L132 _mint(owner, tokenId); contracts/crowdfund/CrowdfundNFT.sol:L141 function _mint(address owner) internal returns (uint256 tokenId) contracts/crowdfund/Crowdfund.sol:L439 _mint(contributor);
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
contracts/globals/Globals.sol:L59 function setBytes32(uint256 key, bytes32 value) external onlyMultisig { contracts/globals/Globals.sol:L63 function setUint256(uint256 key, uint256 value) external onlyMultisig { contracts/globals/Globals.sol:L67 function setAddress(uint256 key, address value) external onlyMultisig { contracts/globals/Globals.sol:L71 function setIncludesBytes32(uint256 key, bytes32 value, bool isIncluded) external onlyMultisig { contracts/globals/Globals.sol:L75 function setIncludesUint256(uint256 key, uint256 value, bool isIncluded) external onlyMultisig { contracts/globals/Globals.sol:L79 function setIncludesAddress(uint256 key, address value, bool isIncluded) external onlyMultisig {
ERC20 operations can be unsafe due to different implementations and vulnerabilities in the standard.
It is therefore recommended to always either use OpenZeppelin's SafeERC20 library or at least to wrap each operation in a require statement.
contracts/party/PartyGovernanceNFT.sol:L143 super.transferFrom(owner, to, tokenId); contracts/crowdfund/Crowdfund.sol:L301 preciousTokens[i].transferFrom(address(this), address(party_), preciousTokenIds[i]);
Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment.
contracts/renderers/DummyERC721Renderer.sol:L8 // TODO: make this human readable
#0 - 0xble
2022-09-26T00:18:17Z
Bot report
🌟 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
36.3024 USDC - $36.30
abi.encode()
is less efficient than abi.encodePacked()
Consider using abi.encodePacked()
instead for efficieny.
contracts/utils/ReadOnlyDelegateCall.sol:L23 abi.encode(s, r).rawRevert(); contracts/renderers/DummyERC721Renderer.sol:L9 return string(abi.encode(address(this), tokenId)); contracts/proposals/ListOnZoraProposal.sol:L115 return abi.encode(ZoraStep.ListedOnZora, ZoraProgressData({ contracts/proposals/ListOnOpenseaProposal.sol:L164 return abi.encode(ListOnOpenseaStep.ListedOnZora, ZoraProgressData({ contracts/proposals/ListOnOpenseaProposal.sol:L219 return abi.encode(ListOnOpenseaStep.ListedOnOpenSea, orderHash, expiry);
// Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27 Use uint256(1)
and uint256(2)
for true/false to avoid a Gwarmaccess (100 gas), and to avoid Gsset (20000 gas) when changing from ‘false’ to ‘true’, after having been ‘true’ in the past
contracts/distribution/TokenDistributor.sol:L30 mapping(uint256 => bool) hasPartyTokenClaimed; contracts/distribution/TokenDistributor.sol:L62 bool public emergencyActionsDisabled; contracts/utils/LibERC20Compat.sol:L26 if (abi.decode(r, (bool))) { contracts/globals/Globals.sol:L12 mapping(uint256 => mapping(bytes32 => bool)) private _includedWordValues; contracts/party/PartyGovernance.sol:L148 mapping (address => bool) hasVoted; contracts/party/PartyGovernance.sol:L197 bool public emergencyExecuteDisabled; contracts/party/PartyGovernance.sol:L207 mapping(address => bool) public isHost; contracts/crowdfund/Crowdfund.sol:L106 bool private _splitRecipientHasBurned;
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.
contracts/distribution/TokenDistributor.sol:L230 for (uint256 i = 0; i < infos.length; ++i) { contracts/distribution/TokenDistributor.sol:L239 for (uint256 i = 0; i < infos.length; ++i) { contracts/party/PartyGovernance.sol:L306 for (uint256 i=0; i < opts.hosts.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L52 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L61 for (uint256 i = 0; i < calls.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L78 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/LibProposal.sol:L14 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/LibProposal.sol:L32 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/ListOnOpenseaProposal.sol:L291 for (uint256 i = 0; i < fees.length; ++i) { contracts/crowdfund/CollectionBuyCrowdfund.sol:L62 for (uint256 i; i < hosts.length; i++) { contracts/crowdfund/Crowdfund.sol:L180 for (uint256 i = 0; i < contributors.length; ++i) { contracts/crowdfund/Crowdfund.sol:L300 for (uint256 i = 0; i < preciousTokens.length; ++i) {
revert()
/require()
string to save gasCustom errors are available from solidity version 0.8.4, it saves around 50 gas each time they are hit by avoiding having to allocate and store the revert string.
contracts/crowdfund/CrowdfundNFT.sol:L29 revert('ALWAYS FAILING');
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.
contracts/party/Party.sol:L28 constructor(IGlobals globals) PartyGovernanceNFT(globals) {} contracts/party/Party.sol:L47 receive() external payable {} contracts/crowdfund/CrowdfundNFT.sol:L52 {} contracts/crowdfund/CrowdfundNFT.sol:L59 {} contracts/crowdfund/CrowdfundNFT.sol:L66 {} contracts/crowdfund/CrowdfundNFT.sol:L73 {} contracts/crowdfund/CrowdfundNFT.sol:L80 {} contracts/crowdfund/CollectionBuyCrowdfund.sol:L77 constructor(IGlobals globals) BuyCrowdfundBase(globals) {} contracts/crowdfund/BuyCrowdfund.sol:L62 constructor(IGlobals globals) BuyCrowdfundBase(globals) {} contracts/crowdfund/BuyCrowdfundBase.sol:L67 constructor(IGlobals globals) Crowdfund(globals) {} contracts/crowdfund/AuctionCrowdfund.sol:L104 constructor(IGlobals globals) Crowdfund(globals) {} contracts/crowdfund/AuctionCrowdfund.sol:L144 receive() external payable {}
Use a solidity version of at least 0.8.2 to get simple compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value.
contracts/distribution/ITokenDistributorParty.sol:L2 pragma solidity ^0.8; contracts/distribution/ITokenDistributor.sol:L2 pragma solidity ^0.8; contracts/distribution/TokenDistributor.sol:L2 pragma solidity ^0.8; contracts/utils/Proxy.sol:L2 pragma solidity ^0.8; contracts/utils/LibSafeCast.sol:L2 pragma solidity ^0.8; contracts/utils/ReadOnlyDelegateCall.sol:L2 pragma solidity ^0.8; contracts/utils/LibAddress.sol:L2 pragma solidity ^0.8; contracts/utils/LibERC20Compat.sol:L2 pragma solidity ^0.8; contracts/utils/Implementation.sol:L2 pragma solidity ^0.8; contracts/utils/LibRawResult.sol:L2 pragma solidity ^0.8; contracts/utils/LibSafeERC721.sol:L2 pragma solidity ^0.8; contracts/utils/EIP165.sol:L2 pragma solidity ^0.8; contracts/globals/IGlobals.sol:L2 pragma solidity ^0.8; contracts/globals/Globals.sol:L2 pragma solidity ^0.8; contracts/party/Party.sol:L2 pragma solidity ^0.8; contracts/party/PartyGovernance.sol:L2 pragma solidity ^0.8; contracts/party/PartyFactory.sol:L2 pragma solidity ^0.8; contracts/party/IPartyFactory.sol:L2 pragma solidity ^0.8; contracts/party/PartyGovernanceNFT.sol:L2 pragma solidity ^0.8; contracts/renderers/DummyERC721Renderer.sol:L2 pragma solidity ^0.8; contracts/gatekeepers/IGateKeeper.sol:L2 pragma solidity ^0.8; contracts/proposals/FractionalizeProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ProposalStorage.sol:L2 pragma solidity ^0.8; contracts/proposals/ListOnZoraProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ArbitraryCallsProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/LibProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/IProposalExecutionEngine.sol:L2 pragma solidity ^0.8; contracts/proposals/ListOnOpenseaProposal.sol:L2 pragma solidity ^0.8; contracts/proposals/ProposalExecutionEngine.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/FractionalV1.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/IOpenseaExchange.sol:L2 pragma solidity ^0.8; contracts/proposals/vendor/IOpenseaConduitController.sol:L2 pragma solidity ^0.8; contracts/market-wrapper/IMarketWrapper.sol:L2 pragma solidity ^0.8; contracts/vendor/markets/IZoraAuctionHouse.sol:L2 pragma solidity ^0.8; contracts/tokens/ERC721Receiver.sol:L2 pragma solidity ^0.8; contracts/tokens/ERC1155Receiver.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC721.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC1155.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC20.sol:L2 pragma solidity ^0.8; contracts/tokens/IERC721Receiver.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CrowdfundNFT.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CollectionBuyCrowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/CrowdfundFactory.sol:L2 pragma solidity ^0.8; contracts/crowdfund/BuyCrowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/Crowdfund.sol:L2 pragma solidity ^0.8; contracts/crowdfund/BuyCrowdfundBase.sol:L2 pragma solidity ^0.8; contracts/crowdfund/AuctionCrowdfund.sol:L2 pragma solidity ^0.8;
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.
contracts/distribution/TokenDistributor.sol:L327 function disableEmergencyActions() onlyPartyDao external { contracts/globals/Globals.sol:L27 function transferMultiSig(address newMultiSig) external onlyMultisig { contracts/globals/Globals.sol:L59 function setBytes32(uint256 key, bytes32 value) external onlyMultisig { contracts/globals/Globals.sol:L63 function setUint256(uint256 key, uint256 value) external onlyMultisig { contracts/globals/Globals.sol:L67 function setAddress(uint256 key, address value) external onlyMultisig { contracts/globals/Globals.sol:L71 function setIncludesBytes32(uint256 key, bytes32 value, bool isIncluded) external onlyMultisig { contracts/globals/Globals.sol:L75 function setIncludesUint256(uint256 key, uint256 value, bool isIncluded) external onlyMultisig { contracts/globals/Globals.sol:L79 function setIncludesAddress(uint256 key, address value, bool isIncluded) external onlyMultisig { contracts/party/PartyGovernance.sol:L451 function delegateVotingPower(address delegate) external onlyDelegateCall { contracts/party/PartyGovernance.sol:L458 function abdicate(address newPartyHost) external onlyHost onlyDelegateCall { contracts/party/PartyGovernance.sol:L616 function veto(uint256 proposalId) external onlyHost onlyDelegateCall { contracts/party/PartyGovernance.sol:L800 function disableEmergencyExecute() external onlyPartyDaoOrHost onlyDelegateCall { contracts/party/PartyGovernanceNFT.sol:L169 function abdicate() external onlyMinter onlyDelegateCall { contracts/crowdfund/AuctionCrowdfund.sol:L149 function bid() external onlyDelegateCall {
X += Y
costs more gas than X = X + Y
for state variables.Consider changing X += Y
to X = X + Y
to save gas.
contracts/party/PartyGovernance.sol:L595 values.votes += votingPower; contracts/crowdfund/Crowdfund.sol:L243 ethContributed += contributions[i].amount; contracts/crowdfund/Crowdfund.sol:L352 ethOwed += c.amount; contracts/crowdfund/Crowdfund.sol:L355 ethUsed += c.amount; contracts/crowdfund/Crowdfund.sol:L359 ethUsed += partialEthUsed; contracts/crowdfund/Crowdfund.sol:L374 votingPower += (splitBps_ * totalEthUsed + (1e4 - 1)) / 1e4; // round up contracts/crowdfund/Crowdfund.sol:L411 totalContributions += amount; contracts/crowdfund/Crowdfund.sol:L427 lastContribution.amount += amount;
Saves 6 gas per loop.
contracts/crowdfund/CollectionBuyCrowdfund.sol:L62 for (uint256 i; i < hosts.length; i++) {
Explicit initialization with zero is not required for variable declaration because uints are 0 by default. Removing this will reduce contract size and save a bit of gas.
contracts/distribution/TokenDistributor.sol:L230 for (uint256 i = 0; i < infos.length; ++i) { contracts/distribution/TokenDistributor.sol:L239 for (uint256 i = 0; i < infos.length; ++i) { contracts/party/PartyGovernance.sol:L432 uint256 low = 0; contracts/proposals/ArbitraryCallsProposal.sol:L52 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L61 for (uint256 i = 0; i < calls.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L78 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/LibProposal.sol:L14 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/LibProposal.sol:L32 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/ListOnOpenseaProposal.sol:L291 for (uint256 i = 0; i < fees.length; ++i) { contracts/crowdfund/Crowdfund.sol:L180 for (uint256 i = 0; i < contributors.length; ++i) { contracts/crowdfund/Crowdfund.sol:L242 for (uint256 i = 0; i < numContributions; ++i) { contracts/crowdfund/Crowdfund.sol:L300 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/crowdfund/Crowdfund.sol:L348 for (uint256 i = 0; i < numContributions; ++i) {
++i
/i++
should be unchecked{++i}
/unchecked{i++}
when it is not possible for them to overflow, as is the case when used in for- and while-loops.The unchecked
keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop.
contracts/distribution/TokenDistributor.sol:L230 for (uint256 i = 0; i < infos.length; ++i) { contracts/distribution/TokenDistributor.sol:L239 for (uint256 i = 0; i < infos.length; ++i) { contracts/party/PartyGovernance.sol:L306 for (uint256 i=0; i < opts.hosts.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L52 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L61 for (uint256 i = 0; i < calls.length; ++i) { contracts/proposals/ArbitraryCallsProposal.sol:L78 for (uint256 i = 0; i < hadPreciouses.length; ++i) { contracts/proposals/LibProposal.sol:L14 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/LibProposal.sol:L32 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/proposals/ListOnOpenseaProposal.sol:L291 for (uint256 i = 0; i < fees.length; ++i) { contracts/crowdfund/CollectionBuyCrowdfund.sol:L62 for (uint256 i; i < hosts.length; i++) { contracts/crowdfund/Crowdfund.sol:L180 for (uint256 i = 0; i < contributors.length; ++i) { contracts/crowdfund/Crowdfund.sol:L242 for (uint256 i = 0; i < numContributions; ++i) { contracts/crowdfund/Crowdfund.sol:L300 for (uint256 i = 0; i < preciousTokens.length; ++i) { contracts/crowdfund/Crowdfund.sol:L348 for (uint256 i = 0; i < numContributions; ++i) {
#0 - 0xble
2022-09-26T00:09:42Z
Obviously a bot report