Platform: Code4rena
Start Date: 31/10/2023
Pot Size: $60,500 USDC
Total HM: 9
Participants: 65
Period: 10 days
Judge: gzeon
Total Solo HM: 2
Id: 301
League: ETH
Rank: 56/65
Findings: 1
Award: $23.81
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xVolcano
Also found by: 0x11singh99, 0xAnah, 0xhacksmithh, 0xhex, 0xta, DavidGiladi, K42, Topmark, arjun16, dharma09, hunter_w3b, lsaudit, pavankv, tabriz, tala7985, ybansal2403
23.8054 USDC - $23.81
Instead of using abi.decode, we can use assembly to decode our desired calldata values directly. This will allow us to avoid decoding calldata values that we will not use.
Instances :
File : contracts/crowdfund/InitialETHCrowdfund.sol 367 : amounts[i] = abi.decode(r, (uint96));
File : contracts/party/PartyGovernance.sol 892 : nextProgressData = abi.decode(resultData, (bytes));
File : contracts/proposals/ProposalExecutionEngine.sol !33 : ProposalEngineOpts memory opts = abi.decode(initializeData, (ProposalEngineOpts));
type(uint120).max or type(uint112).max, etc. it uses more gas in the distribution process and also for each transaction than constant usage.
Reference : https://code4rena.com/reports/2023-08-goodentry#g-20-use-constants-instead-of-typeuintxmax
File : contracts/party/PartyGovernance.sol 187 : uint96 private constant VETO_VALUE = type(uint96).max; 302 : if (govOpts.hosts.length > type(uint8).max) { 359 : return getVotingPowerAt(voter, timestamp, type(uint256).max); 445 : return high == 0 ? type(uint256).max : high - 1; 926 : if (hintIndex != type(uint256).max) { 1083 : if (pv.votes == type(uint96).max) {
File : contracts/proposals/ProposalExecutionEngine.sol 185 : stor.nextProgressDataHash = bytes32(type(uint256).max); 314 : require(uint8(proposalType) <= uint8(type(ProposalType).max));
Expensive operations should always try to be avoided within loops. Such operations include: reading/writing to storage, heavy calculations, external calls, and emitting events. In this instance, an event is being emitted every iteration. Events have a base cost of Glog (375 gas)
per emit and Glogdata (8 gas) * number of bytes in event
. We can avoid incurring those costs each iteration by emitting the event outside of the loop.
File : contracts/crowdfund/InitialETHCrowdfund.sol 341 : emit Refunded(contributor, tokenId, amount);
Instead of using address(this), it is more gas-efficient to pre-calculate and use the hardcoded address. Foundry’s script.sol and solmate’s LibRlp.sol contracts can help achieve this.
Reference : https://code4rena.com/reports/2023-08-goodentry#g-10-use-hardcoded-address-instead-of-addressthis
File : contracts/crowdfund/InitialETHCrowdfund.sol 382 : authorities[authoritiesLength - 1] = address(this);
File : contracts/party/PartyGovernanceNFT.sol 387 : ? address(this).balance 388 : : withdrawTokens[i].balanceOf(address(this));
abi.encode
 pads extra null bytes at the end of the call data which is normally unnecessary. In general, abi.encodePacked
 is more gas-efficient.
File : contracts/party/PartyGovernance.sol 286 : abi.encode(proposalEngineOpts)
Refactoring the if-condition in a way it won’t be containing the || operator will save more gas.
File : contracts/crowdfund/ETHCrowdfundBase.sol 202 : if (msg.sender == contributor || oldDelegate == address(0)) { 348 : if (fundingSplitRecipient_ == address(0) || fundingSplitBps_ == 0) {
File : contracts/party/PartyGovernance.sol 979 : if (newDelegate == address(0) || oldDelegate == address(0)) {
File : contracts/party/PartyGovernanceNFT.sol 328-331 : if ( oldRageQuitTimestamp == ENABLE_RAGEQUIT_PERMANENTLY || oldRageQuitTimestamp == DISABLE_RAGEQUIT_PERMANENTLY ) 359-362 : if ( currentRageQuitTimestamp == DISABLE_RAGEQUIT_PERMANENTLY || currentRageQuitTimestamp < block.timestamp )
Estimated savings: 3 gas
Reference : https://code4rena.com/reports/2023-07-basin#g-13-using-a-positive-conditional-flow-to-save-a-not-opcode
File : contracts/proposals/ProposalStorage.sol 50 : if (!s) {
File : contracts/party/PartyGovernanceNFT.sol 357 : if (!isAuthority_) {
File : contracts/party/PartyGovernance.sol 756 : if (!completed) { 826 : if (!success) { 847 : if (!success) { 889 : if (!success) {
File : contracts/crowdfund/InitialETHCrowdfund.sol 362 : if (!s) {
File : contracts/crowdfund/ETHCrowdfundBase.sol 380 : if (!success) {
#0 - c4-pre-sort
2023-11-13T06:55:55Z
ydspa marked the issue as sufficient quality report
#1 - c4-judge
2023-11-19T18:26:49Z
gzeon-c4 marked the issue as grade-b