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: 55/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
It’s the most gas efficient to make up to 3 event parameters indexed. If there are less than 3 parameters, you need to make all parameters indexed.
- event Refunded(address indexed contributor, uint256 indexed tokenId, uint256 amount); + event Refunded(address indexed contributor, uint256 indexed tokenId, uint256 indexed amount);
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L149
- event ProposalVetoed(uint256 indexed proposalId, address host); + event ProposalVetoed(uint256 indexed proposalId, address host);
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L150
- event ProposalExecuted(uint256 indexed proposalId, address executor, bytes nextProgressData); + event ProposalExecuted(uint256 indexed proposalId, address executor, bytes indexed nextProgressData);
- event PartyVotingSnapshotCreated( address indexed voter, uint40 timestamp, uint96 delegatedVotingPower, uint96 intrinsicVotingPower, bool isDelegated );
 https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernanceNFT.sol#L32
event PartyCardIntrinsicVotingPowerSet(uint256 indexed tokenId, uint256 intrinsicVotingPower);
event SigningThresholdBpsSet( Party indexed party, uint96 oldThresholdBps, uint96 newThresholdBps );
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.
References: https://book.getfoundry.sh/reference/forge-std/compute-create-address
https://twitter.com/transmissions11/status/1518507047943245824
(bool s, bytes memory r) = address(this).call(
authorities[authoritiesLength - 1] = address(this);
? address(this).balance : withdrawTokens[i].balanceOf(address(this));
implementation = address(this);
 https://github.com/code-423n4/2023-10-party/blob/main/contracts/utils/Implementation.sol#L18
It’s better to use a modifier instead of _assertHost
 function. This is also more gas efficient as it does not control with external call.
Modifiers are a way to encapsulate common preconditions or checks and apply them to multiple functions. This can help save gas and reduce code duplication.
function _assertHost() internal view { if (!isHost[msg.sender]) { revert NotAuthorized(); } }
function _assertActiveMember() internal view { VotingPowerSnapshot memory snap = _getLastVotingPowerSnapshotForVoter(msg.sender); // Must have either delegated voting power or intrinsic voting power. if (snap.intrinsicVotingPower == 0 && snap.delegatedVotingPower == 0) { revert NotAuthorized(); } }
function _assertNotGloballyDisabled() internal view { if (_GLOBALS.getBool(LibGlobals.GLOBAL_DISABLE_PARTY_ACTIONS)) { revert OnlyWhenEnabledError(); } }
function _assertAuthority() internal view { if (!isAuthority[msg.sender]) { revert NotAuthorized(); } }
Declaring functions as public costs more gas. Replace them with external wherever possible.
Instances of this issue :
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
function tokenURI(uint256) public view override returns (string memory) { _delegateToRenderer(); return ""; // Just to make the compiler happy. }
function contractURI() external view returns (string memory) { _delegateToRenderer(); return ""; // Just to make the compiler happy. }
Â
You can have further advantages in term of gas cost by simply using named return values as temporary local variable. As an example, the following instance of code block can refactored as follows:
function refund(uint256 tokenId) external returns (uint96 amount) {
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L383
) external view returns (ProposalStatus status, ProposalStateValues memory values) {
 https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L358
) external view returns (uint96 votingPower) {
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L372
) public view returns (uint96 votingPower) {
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L426
) public view returns (uint256 index) {
 https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernance.sol#L595
function accept(uint256 proposalId, uint256 snapIndex) public returns (uint256 totalVotes) {
) private returns (bool completed) {
) private pure returns (ProposalType proposalType, bytes memory offsetProposalData) {
Use a fixed size bytes datatype like bytes4 in place of string.
function tokenURI(uint256) public view override returns (string memory) { _delegateToRenderer(); return ""; // Just to make the compiler happy. }
function contractURI() external view returns (string memory) { _delegateToRenderer(); return ""; // Just to make the compiler happy. }
Â
assert() will consume all remaining gas and should only be used for conditions that are truly impossible to fail.
https://github.com/code-423n4/2023-10-party/blob/main/contracts/party/PartyGovernanceNFT.sol#L499
assert(false); // Will not be reached. }
assert(currentInProgressProposalId == 0);
if (totalVotingPower != 0 && totalVotingPower - mintedVotingPower_ < votingPower_) { unchecked { votingPower_ = totalVotingPower - mintedVotingPower_; } }
 totalVotingPower - mintedVotingPower_
 should be cachedÂ
If the functions are required by an interface, the contract should inherit from that interface and use the override keyword.
function _initProposalImpl(IProposalExecutionEngine impl, bytes memory initData) internal {
937: function _transferVotingPower(address from, address to, uint256 power) internal {
modifier onlyInitialize() {
https://github.com/code-423n4/2023-10-party/blob/main/contracts/utils/Implementation.sol#L29
Â
Â
#0 - c4-pre-sort
2023-11-13T07:49:07Z
ydspa marked the issue as insufficient quality report
#1 - c4-judge
2023-11-19T18:31:00Z
gzeon-c4 marked the issue as grade-b